transient gpu buffers

This commit is contained in:
jacob 2025-10-21 16:30:27 -05:00
parent 69a8f2e1a3
commit 5d2662e567
6 changed files with 139 additions and 143 deletions

View File

@ -106,56 +106,45 @@ GPU_Resource *GPU_GetCommonNoise(void)
//////////////////////////////// ////////////////////////////////
//~ Transient buffer operations //~ Transient buffer operations
GPU_TransientBuffer *GPU_AcquireTransientBuffer_(u64 reserve, GPU_QueueKind queue_kind, u32 max_in_flight, u32 element_size, u32 element_align) GPU_TransientBuffer GPU_AcquireTransientBuffer(GPU_QueueKind queue_kind, u32 element_size)
{ {
element_size = MaxU32(element_size, 1); GPU_TransientBuffer tbuff = ZI;
element_align = MaxU32(element_align, 1); tbuff.element_size = MaxU32(element_size, 1);
max_in_flight = MaxU32(max_in_flight, 1); tbuff.queue_kind = queue_kind;
GPU_TransientBuffer *tbuff = 0;
{
Arena *arena = AcquireArena(reserve);
tbuff = PushStruct(arena, GPU_TransientBuffer);
tbuff->arena = arena;
}
tbuff->queue_kind = queue_kind;
tbuff->submitted_resources = PushStructs(tbuff->arena, GPU_SubmittedTransientBufferResource, max_in_flight);
tbuff->max_in_flight = max_in_flight;
for (u32 i = 0; i < max_in_flight; ++i)
{
/* Init free list */
StackPush(tbuff->first_free, &tbuff->submitted_resources[i]);
}
PushAlign(tbuff->arena, element_align);
tbuff->elements_start_pos = tbuff->arena->pos;
tbuff->element_size = element_size;
tbuff->element_align = element_align;
return tbuff; return tbuff;
} }
void GPU_ReleaseTransientBuffer(GPU_TransientBuffer *tbuff) void GPU_ReleaseTransientBuffer(GPU_TransientBuffer *tbuff)
{ {
GPU_SharedUtilState *g = &GPU_shared_util_state;
Fence *queue_fence = GPU_FenceFromQueue(tbuff->queue_kind); Fence *queue_fence = GPU_FenceFromQueue(tbuff->queue_kind);
i64 queue_fence_value = FetchFence(queue_fence); i64 queue_fence_value = FetchFence(queue_fence);
YieldOnFence(queue_fence, queue_fence_value); YieldOnFence(queue_fence, queue_fence_value);
for (GPU_SubmittedTransientBufferResource *submitted = tbuff->first_submitted; if (tbuff->first_submitted)
{
for (GPU_SubmittedResourceNode *submitted = tbuff->first_submitted;
submitted; submitted;
submitted = submitted->next) submitted = submitted->next)
{ {
GPU_ReleaseResource(submitted->resource, GPU_ReleaseFlag_None); GPU_ReleaseResource(submitted->resource, GPU_ReleaseFlag_None);
} }
ReleaseArena(tbuff->arena); Lock lock = LockE(&g->submitted_transient_buffers_mutex);
{
tbuff->last_submitted->next = g->first_free_submitted_transient_buffer;
g->first_free_submitted_transient_buffer = tbuff->first_submitted;
}
Unlock(&lock);
}
} }
GPU_Resource *GPU_UploadTransientBuffer(GPU_TransientBuffer *tbuff) GPU_Resource *GPU_UploadTransientBuffer(GPU_TransientBuffer *tbuff, void *src, u64 src_size)
{ {
GPU_SharedUtilState *g = &GPU_shared_util_state;
GPU_Resource *resource = 0; GPU_Resource *resource = 0;
u32 element_count = (tbuff->arena->pos - tbuff->elements_start_pos) / tbuff->element_size; u64 element_count = src_size / tbuff->element_size;
Fence *queue_fence = GPU_FenceFromQueue(tbuff->queue_kind); Fence *queue_fence = GPU_FenceFromQueue(tbuff->queue_kind);
i64 queue_fence_value = FetchFence(queue_fence); i64 queue_fence_value = FetchFence(queue_fence);
@ -165,38 +154,41 @@ GPU_Resource *GPU_UploadTransientBuffer(GPU_TransientBuffer *tbuff)
Panic(Lit("GPU transient buffer uploaded without a reset")); Panic(Lit("GPU transient buffer uploaded without a reset"));
} }
/* Grab resource */ /* Grab resource node */
GPU_SubmittedTransientBufferResource *upload = 0; GPU_SubmittedResourceNode *upload = 0;
{ {
GPU_SubmittedTransientBufferResource *submitted = tbuff->first_submitted; if (tbuff->first_submitted && tbuff->first_submitted->fence_target <= queue_fence_value)
if (submitted && submitted->fence_target <= queue_fence_value)
{ {
upload = submitted; upload = tbuff->first_submitted;
QueuePop(tbuff->first_submitted, tbuff->last_submitted); QueuePop(tbuff->first_submitted, tbuff->last_submitted);
} }
else if (tbuff->first_free) if (!upload)
{ {
/* Resource in upload, create new */ Lock lock = LockE(&g->submitted_transient_buffers_mutex);
upload = tbuff->first_free; {
StackPop(tbuff->first_free); upload = g->first_free_submitted_transient_buffer;
if (upload)
{
g->first_free_submitted_transient_buffer = upload->next;
StackPop(g->first_free_submitted_transient_buffer);
} }
else }
Unlock(&lock);
}
if (!upload)
{ {
/* Resource in use and max_in_flight reached, wait for availability */ Arena *perm = PermArena();
Assert(submitted != 0); upload = PushStruct(perm, GPU_SubmittedResourceNode);
YieldOnFence(queue_fence, submitted->fence_target);
queue_fence_value = FetchFence(queue_fence);
upload = submitted;
QueuePop(tbuff->first_submitted, tbuff->last_submitted);
} }
} }
/* Create gpu resource */
{
if (upload->resource) if (upload->resource)
{ {
GPU_ReleaseResource(upload->resource, GPU_ReleaseFlag_Reuse); GPU_ReleaseResource(upload->resource, GPU_ReleaseFlag_Reuse);
upload->resource = 0; upload->resource = 0;
} }
GPU_ResourceDesc desc = ZI; GPU_ResourceDesc desc = ZI;
desc.kind = GPU_ResourceKind_Buffer; desc.kind = GPU_ResourceKind_Buffer;
desc.flags = GPU_ResourceFlag_None; desc.flags = GPU_ResourceFlag_None;
@ -204,33 +196,34 @@ GPU_Resource *GPU_UploadTransientBuffer(GPU_TransientBuffer *tbuff)
desc.buffer.count = element_count; desc.buffer.count = element_count;
desc.buffer.stride = tbuff->element_size; desc.buffer.stride = tbuff->element_size;
upload->resource = GPU_AcquireResource(desc); upload->resource = GPU_AcquireResource(desc);
}
/* Fill gpu resource */
{ {
__profn("Copy to transfer buffer"); __profn("Copy to transfer buffer");
GPU_Mapped m = GPU_Map(upload->resource); GPU_Mapped m = GPU_Map(upload->resource);
CopyBytes(m.mem, ArenaBase(tbuff->arena) + tbuff->elements_start_pos, tbuff->element_size * element_count); CopyBytes(m.mem, src, src_size);
GPU_Unmap(m); GPU_Unmap(m);
} }
tbuff->uploaded = upload; tbuff->uploaded = upload;
tbuff->uploaded_element_count = element_count;
return upload->resource; return upload->resource;
} }
GPU_Resource *GPU_UploadTransientBufferFromArena(GPU_TransientBuffer *tbuff, Arena *arena)
{
u32 element_count = arena->pos / tbuff->element_size;
GPU_Resource *result = GPU_UploadTransientBuffer(tbuff, ArenaBase(arena), tbuff->element_size * element_count);
return result;
}
void GPU_ResetTransientBuffer(GPU_TransientBuffer *tbuff, i64 queue_fence_target) void GPU_ResetTransientBuffer(GPU_TransientBuffer *tbuff, i64 queue_fence_target)
{ {
PopTo(tbuff->arena, tbuff->elements_start_pos); GPU_SubmittedResourceNode *uploaded = tbuff->uploaded;
GPU_SubmittedTransientBufferResource *use = tbuff->uploaded; if (uploaded)
if (use)
{ {
use->fence_target = queue_fence_target; uploaded->fence_target = queue_fence_target;
QueuePush(tbuff->first_submitted, tbuff->last_submitted, use); QueuePush(tbuff->first_submitted, tbuff->last_submitted, uploaded);
tbuff->uploaded = 0; tbuff->uploaded = 0;
} }
} }
Arena *GPU_ArenaFromTransientBuffer(GPU_TransientBuffer *tbuff)
{
return tbuff->arena;
}

View File

@ -1,30 +1,25 @@
//////////////////////////////// ////////////////////////////////
//~ Transient buffer types //~ Transient buffer types
Struct(GPU_SubmittedTransientBufferResource) Struct(GPU_SubmittedResourceNode)
{ {
GPU_SubmittedTransientBufferResource *next; GPU_SubmittedResourceNode *next;
i64 fence_target; /* Once the buffer's queue reaches the target, the resource can be freed or reused */ /* Set during transient upload */
GPU_Resource *resource; GPU_Resource *resource;
/* Set during transient reset */
i64 fence_target; /* Once the buffer's queue reaches the target, the resource can be freed or reused */
}; };
Struct(GPU_TransientBuffer) Struct(GPU_TransientBuffer)
{ {
Arena *arena;
GPU_QueueKind queue_kind; GPU_QueueKind queue_kind;
u64 elements_start_pos;
u32 element_size; u32 element_size;
u32 element_align;
GPU_SubmittedTransientBufferResource *submitted_resources; /* Pool of submitted resource structs */ GPU_SubmittedResourceNode *uploaded;
GPU_SubmittedResourceNode *first_submitted;
u32 uploaded_element_count; GPU_SubmittedResourceNode *last_submitted;
GPU_SubmittedTransientBufferResource *uploaded;
GPU_SubmittedTransientBufferResource *first_submitted;
GPU_SubmittedTransientBufferResource *last_submitted;
GPU_SubmittedTransientBufferResource *first_free;
u32 max_in_flight; u32 max_in_flight;
}; };
@ -38,6 +33,10 @@ Struct(GPU_SharedUtilState)
GPU_Resource *pt_sampler; GPU_Resource *pt_sampler;
GPU_Resource *quad_indices; GPU_Resource *quad_indices;
GPU_Resource *noise; GPU_Resource *noise;
/* Transient buffer pool */
Mutex submitted_transient_buffers_mutex;
GPU_SubmittedResourceNode *first_free_submitted_transient_buffer;
} extern GPU_shared_util_state; } extern GPU_shared_util_state;
//////////////////////////////// ////////////////////////////////
@ -55,11 +54,9 @@ GPU_Resource *GPU_GetCommonNoise(void);
//////////////////////////////// ////////////////////////////////
//~ Transient buffer operations //~ Transient buffer operations
GPU_TransientBuffer *GPU_AcquireTransientBuffer_(u64 reserve, GPU_QueueKind queue_kind, u32 max_in_flight, u32 element_size, u32 element_align); GPU_TransientBuffer GPU_AcquireTransientBuffer(GPU_QueueKind queue_kind, u32 element_size);
#define GPU_AcquireTransientBuffer(reserve, queue_kind, max_in_flight, type) GPU_AcquireTransientBuffer_((reserve), (queue_kind), (max_in_flight), sizeof(type), alignof(type))
void GPU_ReleaseTransientBuffer(GPU_TransientBuffer *tbuff); void GPU_ReleaseTransientBuffer(GPU_TransientBuffer *tbuff);
GPU_Resource *GPU_UploadTransientBuffer(GPU_TransientBuffer *tbuff); GPU_Resource *GPU_UploadTransientBuffer(GPU_TransientBuffer *tbuff, void *src, u64 src_size);
GPU_Resource *GPU_UploadTransientBufferFromArena(GPU_TransientBuffer *tbuff, Arena *arena);
void GPU_ResetTransientBuffer(GPU_TransientBuffer *tbuff, i64 queue_fence_target); void GPU_ResetTransientBuffer(GPU_TransientBuffer *tbuff, i64 queue_fence_target);
Arena *GPU_ArenaFromTransientBuffer(GPU_TransientBuffer *tbuff);

View File

@ -455,19 +455,19 @@ void UpdateUser(P_Window *window)
UI_PushParent(pp_root_box); UI_PushParent(pp_root_box);
//- Init render data buffers //- Init render data buffers
if (!g->material_instances_tbuff) if (!g->material_instances_arena)
{ {
g->material_instances_tbuff = GPU_AcquireTransientBuffer(Gibi(64), GPU_QueueKind_Direct, 8, MaterialInstance); g->material_instances_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(MaterialInstance));
g->ui_rect_instances_tbuff = GPU_AcquireTransientBuffer(Gibi(64), GPU_QueueKind_Direct, 8, UiRectInstance); g->ui_rect_instances_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(UiRectInstance));
g->ui_shape_verts_tbuff = GPU_AcquireTransientBuffer(Gibi(64), GPU_QueueKind_Direct, 8, UiShapeVert); g->ui_shape_verts_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(UiShapeVert));
g->ui_shape_indices_tbuff = GPU_AcquireTransientBuffer(Gibi(64), GPU_QueueKind_Direct, 8, u32); g->ui_shape_indices_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(u32));
g->grids_tbuff = GPU_AcquireTransientBuffer(Gibi(64), GPU_QueueKind_Direct, 8, MaterialGrid); g->grids_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(MaterialGrid));
g->material_instances_arena = AcquireArena(Gibi(64));
g->ui_rect_instances_arena = AcquireArena(Gibi(64));
g->ui_shape_verts_arena = AcquireArena(Gibi(64));
g->ui_shape_indices_arena = AcquireArena(Gibi(64));
g->grids_arena = AcquireArena(Gibi(64));
} }
Arena *material_instances_arena = GPU_ArenaFromTransientBuffer(g->material_instances_tbuff);
Arena *ui_rect_instances_arena = GPU_ArenaFromTransientBuffer(g->ui_rect_instances_tbuff);
Arena *ui_shape_verts_arena = GPU_ArenaFromTransientBuffer(g->ui_shape_verts_tbuff);
Arena *ui_shape_indices_arena = GPU_ArenaFromTransientBuffer(g->ui_shape_indices_tbuff);
Arena *grids_arena = GPU_ArenaFromTransientBuffer(g->grids_tbuff);
//- Pull latest local sim snapshot //- Pull latest local sim snapshot
@ -987,7 +987,7 @@ void UpdateUser(P_Window *window)
u32 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f); u32 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f);
u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 1.f); u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 1.f);
MaterialGrid *grid = PushStruct(grids_arena, MaterialGrid); MaterialGrid *grid = PushStruct(g->grids_arena, MaterialGrid);
*grid = DefaultMaterialGrid; *grid = DefaultMaterialGrid;
grid->line_thickness = thickness; grid->line_thickness = thickness;
grid->line_spacing = spacing; grid->line_spacing = spacing;
@ -998,12 +998,9 @@ void UpdateUser(P_Window *window)
grid->x_srgb = ColorRed; grid->x_srgb = ColorRed;
grid->y_srgb = ColorGreen; grid->y_srgb = ColorGreen;
MaterialInstance *mat = PushStruct(material_instances_arena, MaterialInstance); MaterialInstance *mat = PushStruct(g->material_instances_arena, MaterialInstance);
*mat = DefaultMaterialInstance; *mat = DefaultMaterialInstance;
// TODO mat->grid_id = grid - (MaterialGrid *)ArenaBase(g->grids_arena);
// BROKE
// FIXME
mat->grid_id = grid - (MaterialGrid *)ArenaBase(grids_arena);
mat->xf = XformFromRect(RectFromVec2(pos, size)); mat->xf = XformFromRect(RectFromVec2(pos, size));
} }
@ -1222,7 +1219,7 @@ void UpdateUser(P_Window *window)
Vec3 emittance = ent->sprite_emittance; Vec3 emittance = ent->sprite_emittance;
u32 tint = ent->sprite_tint; u32 tint = ent->sprite_tint;
S_Frame frame = S_FrameFromIndex(sheet, ent->animation_frame); S_Frame frame = S_FrameFromIndex(sheet, ent->animation_frame);
MaterialInstance *mat = PushStruct(material_instances_arena, MaterialInstance); MaterialInstance *mat = PushStruct(g->material_instances_arena, MaterialInstance);
*mat = DefaultMaterialInstance; *mat = DefaultMaterialInstance;
mat->xf = sprite_xform; mat->xf = sprite_xform;
mat->tex = GPU_Texture2DRidFromResource(texture->gpu_texture); mat->tex = GPU_Texture2DRidFromResource(texture->gpu_texture);
@ -1257,7 +1254,7 @@ void UpdateUser(P_Window *window)
Vec2I32 world_tile_index = WorldTileIndexFromLocalTileIndex(chunk_index, local_tile_index); Vec2I32 world_tile_index = WorldTileIndexFromLocalTileIndex(chunk_index, local_tile_index);
Vec2 pos = PosFromWorldTileIndex(world_tile_index); Vec2 pos = PosFromWorldTileIndex(world_tile_index);
Xform tile_xf = XformFromRect(RectFromVec2(pos, VEC2(tile_size, tile_size))); Xform tile_xf = XformFromRect(RectFromVec2(pos, VEC2(tile_size, tile_size)));
MaterialInstance *mat = PushStruct(material_instances_arena, MaterialInstance); MaterialInstance *mat = PushStruct(g->material_instances_arena, MaterialInstance);
*mat = DefaultMaterialInstance; *mat = DefaultMaterialInstance;
mat->xf = tile_xf; mat->xf = tile_xf;
mat->tex = GPU_Texture2DRidFromResource(tile_texture->gpu_texture); mat->tex = GPU_Texture2DRidFromResource(tile_texture->gpu_texture);
@ -2283,11 +2280,11 @@ void UpdateUser(P_Window *window)
} }
/* Upload transient buffers */ /* Upload transient buffers */
GPU_Resource *material_instances_buffer = GPU_UploadTransientBuffer(g->material_instances_tbuff); GPU_Resource *material_instances_buffer = GPU_UploadTransientBufferFromArena(&g->material_instances_tbuff, g->material_instances_arena);
GPU_Resource *ui_rect_instances_buffer = GPU_UploadTransientBuffer(g->ui_rect_instances_tbuff); GPU_Resource *ui_rect_instances_buffer = GPU_UploadTransientBufferFromArena(&g->ui_rect_instances_tbuff, g->ui_rect_instances_arena);
GPU_Resource *ui_shape_verts_buffer = GPU_UploadTransientBuffer(g->ui_shape_verts_tbuff); GPU_Resource *ui_shape_verts_buffer = GPU_UploadTransientBufferFromArena(&g->ui_shape_verts_tbuff, g->ui_shape_verts_arena);
GPU_Resource *ui_shape_indices_buffer = GPU_UploadTransientBuffer(g->ui_shape_indices_tbuff); GPU_Resource *ui_shape_indices_buffer = GPU_UploadTransientBufferFromArena(&g->ui_shape_indices_tbuff, g->ui_shape_indices_arena);
GPU_Resource *grids_buffer = GPU_UploadTransientBuffer(g->grids_tbuff); GPU_Resource *grids_buffer = GPU_UploadTransientBufferFromArena(&g->grids_tbuff, g->grids_arena);
u64 material_instances_count = GPU_GetBufferCount(material_instances_buffer); u64 material_instances_count = GPU_GetBufferCount(material_instances_buffer);
u64 ui_rect_instances_count = GPU_GetBufferCount(ui_rect_instances_buffer); u64 ui_rect_instances_count = GPU_GetBufferCount(ui_rect_instances_buffer);
u64 ui_shape_verts_count = GPU_GetBufferCount(ui_shape_verts_buffer); u64 ui_shape_verts_count = GPU_GetBufferCount(ui_shape_verts_buffer);
@ -2531,12 +2528,17 @@ void UpdateUser(P_Window *window)
} }
g->gpu_render_fence_target = GPU_EndCommandList(cl); g->gpu_render_fence_target = GPU_EndCommandList(cl);
/* Reset transients */ /* Reset render data */
GPU_ResetTransientBuffer(g->material_instances_tbuff, g->gpu_render_fence_target); GPU_ResetTransientBuffer(&g->material_instances_tbuff, g->gpu_render_fence_target);
GPU_ResetTransientBuffer(g->ui_rect_instances_tbuff, g->gpu_render_fence_target); GPU_ResetTransientBuffer(&g->ui_rect_instances_tbuff, g->gpu_render_fence_target);
GPU_ResetTransientBuffer(g->ui_shape_verts_tbuff, g->gpu_render_fence_target); GPU_ResetTransientBuffer(&g->ui_shape_verts_tbuff, g->gpu_render_fence_target);
GPU_ResetTransientBuffer(g->ui_shape_indices_tbuff, g->gpu_render_fence_target); GPU_ResetTransientBuffer(&g->ui_shape_indices_tbuff, g->gpu_render_fence_target);
GPU_ResetTransientBuffer(g->grids_tbuff, g->gpu_render_fence_target); GPU_ResetTransientBuffer(&g->grids_tbuff, g->gpu_render_fence_target);
ResetArena(g->material_instances_arena);
ResetArena(g->ui_rect_instances_arena);
ResetArena(g->ui_shape_verts_arena);
ResetArena(g->ui_shape_indices_arena);
ResetArena(g->grids_arena);
} }
/* Render UI */ /* Render UI */

View File

@ -181,12 +181,17 @@ Struct(SharedUserState)
GPU_Resource *shade_target; GPU_Resource *shade_target;
GPU_Resource *ui_target; GPU_Resource *ui_target;
//- Render transient buffers //- Renderer transient buffers
GPU_TransientBuffer *material_instances_tbuff; GPU_TransientBuffer material_instances_tbuff;
GPU_TransientBuffer *ui_rect_instances_tbuff; GPU_TransientBuffer ui_rect_instances_tbuff;
GPU_TransientBuffer *ui_shape_verts_tbuff; GPU_TransientBuffer ui_shape_verts_tbuff;
GPU_TransientBuffer *ui_shape_indices_tbuff; GPU_TransientBuffer ui_shape_indices_tbuff;
GPU_TransientBuffer *grids_tbuff; GPU_TransientBuffer grids_tbuff;
Arena *material_instances_arena;
Arena *ui_rect_instances_arena;
Arena *ui_shape_verts_arena;
Arena *ui_shape_indices_arena;
Arena *grids_arena;
//- Renderer state //- Renderer state
RandState frame_rand; RandState frame_rand;

View File

@ -406,26 +406,20 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
//- Build render data //- Build render data
/* Init transient buffers */ /* Init transient buffers */
if (!g->draw_rects_tbuff) if (!g->draw_rects_arena)
{ {
g->draw_rects_tbuff = GPU_AcquireTransientBuffer(Gibi(64), GPU_QueueKind_Direct, 8, UI_RectInstance); g->draw_rects_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(UI_RectInstance));
g->draw_rects_arena = AcquireArena(Gibi(64));
} }
Arena *draw_rects_arena = GPU_ArenaFromTransientBuffer(g->draw_rects_tbuff);
GPU_QueueKind render_queue = GPU_QueueKind_Direct; GPU_QueueKind render_queue = GPU_QueueKind_Direct;
Fence *render_fence = GPU_FenceFromQueue(render_queue); Fence *render_fence = GPU_FenceFromQueue(render_queue);
/* Init render state */
if (!draw_rects_arena)
{
draw_rects_arena = AcquireArena(Gibi(64));
}
/* Build rect instance data */ /* Build rect instance data */
for (u64 box_index = 0; box_index < boxes_count; ++box_index) for (u64 box_index = 0; box_index < boxes_count; ++box_index)
{ {
UI_Box *box = boxes_pre[box_index]; UI_Box *box = boxes_pre[box_index];
UI_RectInstance *rect = PushStruct(draw_rects_arena, UI_RectInstance); UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
rect->flags = box->flags; rect->flags = box->flags;
rect->p0 = box->p0; rect->p0 = box->p0;
@ -459,7 +453,7 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
} }
/* Upload transient buffers */ /* Upload transient buffers */
GPU_Resource *draw_rects_buffer = GPU_UploadTransientBuffer(g->draw_rects_tbuff); GPU_Resource *draw_rects_buffer = GPU_UploadTransientBufferFromArena(&g->draw_rects_tbuff, g->draw_rects_arena);
u32 draw_rects_count = GPU_GetBufferCount(draw_rects_buffer); u32 draw_rects_count = GPU_GetBufferCount(draw_rects_buffer);
/* Build command list */ /* Build command list */
@ -499,8 +493,9 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
} }
g->render_fence_target = GPU_EndCommandList(cl); g->render_fence_target = GPU_EndCommandList(cl);
/* Reset transient buffers */ /* Reset render data */
GPU_ResetTransientBuffer(g->draw_rects_tbuff, g->render_fence_target); GPU_ResetTransientBuffer(&g->draw_rects_tbuff, g->render_fence_target);
ResetArena(g->draw_rects_arena);
EndScratch(scratch); EndScratch(scratch);
return g->render_target; return g->render_target;

View File

@ -107,7 +107,11 @@ Struct(UI_SharedState)
//- Render state //- Render state
GPU_Resource *render_target; GPU_Resource *render_target;
i64 render_fence_target; i64 render_fence_target;
GPU_TransientBuffer *draw_rects_tbuff;
GPU_TransientBuffer draw_rects_tbuff;
Arena *draw_rects_arena;
} extern UI_shared_state; } extern UI_shared_state;
//////////////////////////////// ////////////////////////////////