fixed vulkan buffer cleanup

This commit is contained in:
Matthew 2025-03-19 22:24:38 +11:00
parent 10f4b8a852
commit 00b9d26131
5 changed files with 83 additions and 22 deletions

View File

@ -52,16 +52,10 @@ static void RunCycle(Arena *arena, GameInput *inputs, u32 i_count)
FinishFrame();
//if (renderer.frame_state.prev_buffer_count > 0)
//FreeBuffers(renderer.frame_state.prev_buffers, renderer.frame_state.prev_buffer_count);
FreeBuffers(&vertex_buffer, 1);
FreeBuffers(&index_buffer, 1);
ArenaFree(arena);
u32 buffer_count = 2;
renderer.frame_state.prev_buffers = ArenaAlloc(arena, sizeof(RenderBuffer) * buffer_count);
renderer.frame_state.prev_buffers[0] = vertex_buffer;
renderer.frame_state.prev_buffers[1] = index_buffer;
renderer.frame_state.prev_buffer_count = buffer_count;
}
static void DrawRect(GUIContext *ctx, Vec2 p0, Vec2 p1, Vec4 col)

View File

@ -17,7 +17,7 @@ void DestroyRenderer()
static u32 GetFrameIndex()
{
return renderer.frame_state.frame_cnt % renderer.vk.sc.img_count;
return renderer.frame_state.frame_cnt % FRAME_OVERLAP;
}
static VkCommandBuffer GetFrameCmdBuf()
@ -40,6 +40,16 @@ static VkSemaphore GetFrameSwapSem()
return renderer.vk.frame.swapchain_sems[GetFrameIndex()];
}
static u32 *GetFrameBufferCount()
{
return &renderer.vk.frame.buffer_counts[GetFrameIndex()];
}
static RenderBuffer *GetFrameRenderBuffers()
{
return renderer.vk.frame.buffer_destroy_queues[GetFrameIndex()];
}
static void BeginRendering()
{
VkCommandBuffer cmd = GetFrameCmdBuf();
@ -111,6 +121,15 @@ b32 BeginFrame()
if (success)
{
u32 *buf_count = GetFrameBufferCount();
if (*buf_count > 0)
{
RenderBuffer *buffers = GetFrameRenderBuffers();
for (u32 i = 0; i < *buf_count; i++)
vmaDestroyBuffer(renderer.vk.alloc, buffers[i].buffer, buffers[i].alloc);
*buf_count = 0;
}
result = vkResetFences(device, 1, fence);
if (result != VK_SUCCESS)
{
@ -324,6 +343,7 @@ b32 FinishFrame()
}
}
renderer.frame_state.prev_frame = renderer.frame_state.frame_cnt;
renderer.frame_state.frame_cnt++;
return success;
@ -344,11 +364,16 @@ static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count)
{
VkDevice device = renderer.vk.device;
VmaAllocator alloc = renderer.vk.alloc;
u32 frame_index = renderer.frame_state.begin_rendering ? renderer.frame_state.frame_cnt : renderer.frame_state.prev_frame;
frame_index = frame_index % FRAME_OVERLAP;
u32 *buf_count = &renderer.vk.frame.buffer_counts[frame_index];
// TODO: make this better at some point
for (u32 i = 0; i < buffer_count; i++)
{
vmaDestroyBuffer(alloc, buffers[i].buffer, buffers[i].alloc);
renderer.vk.frame.buffer_destroy_queues[frame_index][*buf_count] = buffers[i];
*buf_count += 1;
}
}
@ -1187,8 +1212,10 @@ static b32 CreateFrameStructures()
renderer.vk.frame.swapchain_sems = ArenaAlloc(renderer.perm_arena, sizeof(VkSemaphore) * img_count);
renderer.vk.frame.render_sems = ArenaAlloc(renderer.perm_arena, sizeof(VkSemaphore) * img_count);
renderer.vk.frame.render_fences = ArenaAlloc(renderer.perm_arena, sizeof(VkFence) * img_count);
renderer.vk.frame.buffer_destroy_queues = ArenaAlloc(renderer.perm_arena, sizeof(RenderBuffer *) * FRAME_OVERLAP);
renderer.vk.frame.buffer_counts = ArenaAlloc(renderer.perm_arena, sizeof(u32) * FRAME_OVERLAP);
for (u32 i = 0; i < renderer.vk.sc.img_count; i++)
for (u32 i = 0; i < FRAME_OVERLAP; i++)
{
VkResult result;
VkDevice device = renderer.vk.device;
@ -1214,6 +1241,8 @@ static b32 CreateFrameStructures()
result = vkCreateSemaphore(device, &semaphore_create_info, NULL, &data->swapchain_sems[i]);
if (result != VK_SUCCESS)
success = false;
renderer.vk.frame.buffer_destroy_queues[i] = ArenaAlloc(renderer.perm_arena, sizeof(RenderBuffer) * 64);
}
return success;
@ -1418,8 +1447,12 @@ static VkFormat GetImageFormat()
static b32 CreateDescriptors()
{
b32 success = true;
renderer.vk.pipe.bindings = ArenaAlloc(renderer.perm_arena, sizeof(DescBindings) * DESC_TYPE_MAX);
VkDevice device = renderer.vk.device;
VkResult result;
DescBindings *bindings = renderer.vk.pipe.bindings;
result = vkCreateDescriptorPool(device, &desc_pool_info, NULL, &renderer.vk.pipe.pool);
if (result != VK_SUCCESS)
@ -1451,6 +1484,20 @@ static b32 CreateDescriptors()
if (result != VK_SUCCESS)
success = false;
for (u32 i = 0; i < DESC_TYPE_MAX; i++)
{
bindings[i].free = ArenaAlloc(renderer.perm_arena, sizeof(u16) * DESC_MAX_BINDINGS);
bindings[i].used = ArenaAlloc(renderer.perm_arena, sizeof(u16) * DESC_MAX_BINDINGS);
u16 free_count = 0;
for (i32 j = DESC_MAX_BINDINGS-1; j >= 0; j--)
{
bindings[i].free[j] = free_count++;
}
bindings[i].free_count = free_count;
}
return success;
}
@ -1613,13 +1660,19 @@ static void DestroyVulkan()
vkFreeCommandBuffers(device, imm.pool, 1, &imm.cmd);
vkDestroyCommandPool(device, imm.pool, NULL);
for (u32 i = 0; i < sc.img_count; i++)
for (u32 i = 0; i < FRAME_OVERLAP; i++)
{
vkDestroySemaphore(device, data.render_sems[i], NULL);
vkDestroySemaphore(device, data.swapchain_sems[i], NULL);
vkDestroyFence(device, data.render_fences[i], NULL);
vkFreeCommandBuffers(device, data.pools[i], 1, &data.buffers[i]);
vkDestroyCommandPool(device, data.pools[i], NULL);
if (data.buffer_counts[i] > 0)
{
for (u32 j = 0; j < data.buffer_counts[i]; j++)
vmaDestroyBuffer(renderer.vk.alloc, data.buffer_destroy_queues[i][j].buffer, data.buffer_destroy_queues[i][j].alloc);
}
}
vmaDestroyAllocator(renderer.vk.alloc);
@ -1633,6 +1686,9 @@ static void DestroyVulkan()
#endif
vkDestroyInstance(renderer.vk.inst, NULL);
ArenaFree(renderer.arena);
ArenaFree(renderer.perm_arena);
}
void VkInfo(const char *str)

View File

@ -187,7 +187,9 @@ typedef struct
typedef struct
{
u16 *free;
u16 free_count;
u16 *used;
u16 used_count;
} DescBindings;
typedef struct
@ -213,6 +215,8 @@ typedef struct
VkSemaphore *swapchain_sems;
VkSemaphore *render_sems;
VkFence *render_fences;
RenderBuffer **buffer_destroy_queues;
u32 *buffer_counts;
} FrameStructures;
typedef struct
@ -249,6 +253,7 @@ typedef struct {
typedef struct {
u32 img_ix;
u64 frame_cnt;
u64 prev_frame;
b8 begin_rendering;
PipelineHandle last_pipeline;
RenderBuffer *prev_buffers;

View File

@ -159,25 +159,25 @@ void static inline WriteBit(BitWriter *bw, u32 v)
FlushBits(bw);
}
void static inline HMScan1(HMNode *nodes, u32 symbol)
void static inline HMScan1(HMNode *nodes, u8 symbol)
{
nodes[symbol].freq += 1;
}
void static inline HMScan2(HMNode *nodes, u32 symbol1, u32 symbol2)
void static inline HMScan2(HMNode *nodes, u8 symbol1, u8 symbol2)
{
nodes[symbol1].freq += 1;
nodes[symbol2].freq += 1;
}
void static inline HMScan3(HMNode *nodes, u32 symbol1, u32 symbol2, u32 symbol3)
void static inline HMScan3(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3)
{
nodes[symbol1].freq += 1;
nodes[symbol2].freq += 1;
nodes[symbol3].freq += 1;
}
void static inline HMScan4(HMNode *nodes, u32 symbol1, u32 symbol2, u32 symbol3, u32 symbol4)
void static inline HMScan4(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3, u8 symbol4)
{
nodes[symbol1].freq += 1;
nodes[symbol2].freq += 1;
@ -228,10 +228,12 @@ void static inline HMBuildTable(HMNode *nodes)
}
}
// TODO: also finish this trash
HMQuicksort(nodes, 0, num_symbols);
}
b32 CompressData(u8* data, u32 len)
b32 HMCompressData(u8 *data, u32 len, u8 *out)
{
b32 success = true;
@ -242,5 +244,9 @@ b32 CompressData(u8* data, u32 len)
.pos = 24,
};
// TODO: finish this trash
u32 iterations;
return success;
}

View File

@ -61,14 +61,14 @@ i32 i32Clamp(i32 v, i32 min, i32 max);
u32 u32Clamp(u32 v, u32 min, u32 max);
// Compression
b32 CompressData(u8* data, u32 len);
b32 HMCompressData(u8 *data, u32 len, u8 *out);
u32 static inline ReadBit(BitWriter *bw);
void static inline RefillBits(BitWriter *bw);
void static inline FlushBits(BitWriter *bw);
void static inline WriteBit(BitWriter *bw, u32 v);
void static inline HMScan1(HMNode *nodes, u32 symbol);
void static inline HMScan2(HMNode *nodes, u32 symbol1, u32 symbol2);
void static inline HMScan3(HMNode *nodes, u32 symbol1, u32 symbol2, u32 symbol3);
void static inline HMScan4(HMNode *nodes, u32 symbol1, u32 symbol2, u32 symbol3, u32 symbol4);
void static inline HMScan1(HMNode *nodes, u8 symbol);
void static inline HMScan2(HMNode *nodes, u8 symbol1, u8 symbol2);
void static inline HMScan3(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3);
void static inline HMScan4(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3, u8 symbol4);
void static inline HMBuildTable(HMNode *nodes);
void static inline HMQuicksort(HMNode *nodes, u32 low, u32 high);