gpu_arena.h

cross platform rendering playground

src/core/gpu_arena.h

1.3 KB
#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;
}