From cba60f79538fe142c1cb9fc426e348fbfe13424d Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Fri, 2 Feb 2024 11:45:43 -0500 Subject: [PATCH] vk: rt: add workaround for holes in geometry Once upon a time, there were some BLASes. There were the BLASes for dynamic geometry, that were to be used every frame to draw very dynamic things, like sprites and beams. They were initialized at the very begining of the renderer's lifetime, and were expected to live happily for the entire process duration. However, an evil NewMap appeared. It didn't care abount anything or anyone, so when it came, it just cleared all the allocators, and allowed other BLASes to be allocated into the same space as dynamic BLASes were already given. This made BLASes live on top of each other, use each others toys and make them fight. They weren't happy. So we just kill them and creat them again from scratch, when the evil NewMap comes. The end. Fixes #729 --- ref/vk/vk_ray_accel.c | 5 ++++- ref/vk/vk_ray_model.c | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ref/vk/vk_ray_accel.c b/ref/vk/vk_ray_accel.c index 6e9fe2f06..39e422507 100644 --- a/ref/vk/vk_ray_accel.c +++ b/ref/vk/vk_ray_accel.c @@ -33,7 +33,7 @@ static struct { // Stores AS built data. Lifetime similar to render buffer: // - some portion lives for entire map lifetime // - some portion lives only for a single frame (may have several frames in flight) - // TODO: unify this with render buffer + // TODO: unify this with render buffer -- really? // Needs: AS_STORAGE_BIT, SHADER_DEVICE_ADDRESS_BIT vk_buffer_t accels_buffer; struct alo_pool_s *accels_buffer_alloc; @@ -330,6 +330,7 @@ vk_resource_t RT_VkAccelPrepareTlas(vk_combuf_t *combuf) { .srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, // | VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, .buffer = g_accel.accels_buffer.buffer, + // FIXME this is completely wrong. Offset ans size are BLAS-specifig .offset = instance_offset * sizeof(VkAccelerationStructureInstanceKHR), .size = g_ray_model_state.frame.instances_count * sizeof(VkAccelerationStructureInstanceKHR), }}; @@ -349,6 +350,7 @@ vk_resource_t RT_VkAccelPrepareTlas(vk_combuf_t *combuf) { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, + // FIXME also incorrect -- here we must barrier on tlas_geom_buffer, not accels_buffer .buffer = g_accel.accels_buffer.buffer, .offset = 0, .size = VK_WHOLE_SIZE, @@ -430,6 +432,7 @@ void RT_VkAccelNewMap(void) { g_accel.frame.scratch_offset = 0; + // FIXME this clears up memory before its users are deallocated (e.g. dynamic models BLASes) if (g_accel.accels_buffer_alloc) aloPoolDestroy(g_accel.accels_buffer_alloc); g_accel.accels_buffer_alloc = aloPoolCreate(MAX_ACCELS_BUFFER, expected_accels, accels_alignment); diff --git a/ref/vk/vk_ray_model.c b/ref/vk/vk_ray_model.c index 9977b3f19..eb9ef03ed 100644 --- a/ref/vk/vk_ray_model.c +++ b/ref/vk/vk_ray_model.c @@ -141,6 +141,14 @@ uint32_t R_VkMaterialModeFromRenderType(vk_render_type_e render_type) { void RT_RayModel_Clear(void) { R_DEBuffer_Init(&g_ray_model_state.kusochki_alloc, MAX_KUSOCHKI / 2, MAX_KUSOCHKI / 2); + + // FIXME + // This is a dirty workaround for sub-part memory management in this little project + // Accel backing buffer gets cleared on NewMap. Therefore, we need to recreate BLASes for dynamic + // models, even though they might have lived for the entire process lifetime. + // See #729 + RT_DynamicModelShutdown(); + RT_DynamicModelInit(); } void XVK_RayModel_ClearForNextFrame( void ) {