#pragma once
#include "backend/rhi.h"
#include <cassert>
#include <cstring>
struct Arena {
rhi::Buffer buffer;
u64 cursor = 0;
};
inline u64 alloc_from_arena(Arena &a, u64 size, u64 alignment) {
auto align_up = [](u64 v, u64 a) { return (v + a - 1) & ~(a - 1); };
u64 offset = align_up(a.cursor, alignment ? alignment : 1);
// TODO: replace with a growing arena. For now overflow is a hard error.
assert(offset + size <= a.buffer.desc.size && "Arena overflow");
if (offset + size > a.buffer.desc.size) {
return UINT64_MAX;
}
a.cursor = offset + size;
return offset;
}
inline void reset_arena(Arena &a) {
a.cursor = 0;
}
static bool create_arena(rhi::Device &dev, Arena &out, rhi::BufferDesc desc, rhi::BufferViewDesc view_desc) {
(void)view_desc;
if (!rhi::create_buffer(dev, desc, out.buffer)) {
return false;
}
out.cursor = 0;
return true;
}
static void destroy_arena(rhi::Device &dev, Arena &arena) {
rhi::destroy_buffer(dev, arena.buffer);
arena = {};
}
inline u64 stage_to_arena(Arena &arena, const void *src, u64 size) {
u64 offset = alloc_from_arena(arena, size, 16);
if (offset == UINT64_MAX) {
return UINT64_MAX;
}
memcpy(static_cast<u8 *>(arena.buffer.mapped) + offset, src, size);
return offset;
}