From 8326285c2dede132999de33738b18b47686fee6f Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 13 May 2025 13:15:46 +0200 Subject: [PATCH] Fix #138775: Vulkan: Separate discard pile for rendering When using motion blur GPU materials and its resources can be freed when still in use. This fix adds a workaround to store these resources temporarily in a render discard pile. When rendering is finished (or between frames) the resources are moved to the regular discard pile. Pull Request: https://projects.blender.org/blender/blender/pulls/138809 --- source/blender/gpu/vulkan/vk_backend.cc | 13 ++++++++++++- source/blender/gpu/vulkan/vk_device.cc | 1 + source/blender/gpu/vulkan/vk_device.hh | 2 ++ source/blender/gpu/vulkan/vk_device_submission.cc | 7 ++++--- source/blender/gpu/vulkan/vk_resource_pool.cc | 7 ++++++- source/blender/gpu/vulkan/vk_resource_pool.hh | 3 ++- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index b3c26a47b19..7fdb3764d85 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -592,9 +592,20 @@ void VKBackend::render_end() device.orphaned_data.destroy_discarded_resources(device); } } + + if (BLI_thread_is_main() && !G.is_rendering) { + device.orphaned_data.move_data(device.orphaned_data_render, + device.orphaned_data.timeline_ + 1); + } } -void VKBackend::render_step(bool /*force_resource_release*/) {} +void VKBackend::render_step(bool force_resource_release) +{ + if (force_resource_release) { + device.orphaned_data.move_data(device.orphaned_data_render, + device.orphaned_data.timeline_ + 1); + } +} void VKBackend::capabilities_init(VKDevice &device) { diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index d8aecf313cd..f6f8f1d536a 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -55,6 +55,7 @@ void VKDevice::deinit() pipelines.write_to_disk(); pipelines.free_data(); descriptor_set_layouts_.deinit(); + orphaned_data_render.deinit(*this); orphaned_data.deinit(*this); vmaDestroyPool(mem_allocator_, vma_pools.external_memory); vmaDestroyAllocator(mem_allocator_); diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index f7331bfbb26..6d7150a8205 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -217,6 +217,8 @@ class VKDevice : public NonCopyable { public: render_graph::VKResourceStateTracker resources; VKDiscardPool orphaned_data; + /** Discard pool for resources that could still be used during rendering. */ + VKDiscardPool orphaned_data_render; VKPipelinePool pipelines; /** Buffer to bind to unbound resource locations. */ VKBuffer dummy_buffer; diff --git a/source/blender/gpu/vulkan/vk_device_submission.cc b/source/blender/gpu/vulkan/vk_device_submission.cc index fcff6b9a749..50a4bb84d29 100644 --- a/source/blender/gpu/vulkan/vk_device_submission.cc +++ b/source/blender/gpu/vulkan/vk_device_submission.cc @@ -60,9 +60,10 @@ TimelineValue VKDevice::render_graph_submit(render_graph::VKRenderGraph *render_ } TimelineValue timeline = submit_task->timeline = submit_to_device ? ++timeline_value_ : timeline_value_ + 1; - orphaned_data.timeline_ = timeline + 1; - orphaned_data.move_data(context_discard_pool, timeline); - + if (submit_to_device) { + orphaned_data.timeline_ = timeline + 1; + orphaned_data.move_data(context_discard_pool, timeline); + } BLI_thread_queue_push(submitted_render_graphs_, submit_task); submit_task = nullptr; diff --git a/source/blender/gpu/vulkan/vk_resource_pool.cc b/source/blender/gpu/vulkan/vk_resource_pool.cc index 804c2fa00f1..2bf54431a4f 100644 --- a/source/blender/gpu/vulkan/vk_resource_pool.cc +++ b/source/blender/gpu/vulkan/vk_resource_pool.cc @@ -173,7 +173,12 @@ VKDiscardPool &VKDiscardPool::discard_pool_get() } VKDevice &device = VKBackend::get().device; - return device.orphaned_data; + if (G.is_rendering) { + return device.orphaned_data_render; + } + else { + return device.orphaned_data; + } } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_resource_pool.hh b/source/blender/gpu/vulkan/vk_resource_pool.hh index c786ab561b0..7da403b8594 100644 --- a/source/blender/gpu/vulkan/vk_resource_pool.hh +++ b/source/blender/gpu/vulkan/vk_resource_pool.hh @@ -76,6 +76,7 @@ template class TimelineResources : Vector> images_; @@ -123,7 +124,7 @@ class VKDiscardPool { * Returns the discard pool for the current thread. * * When active thread has a context it uses the context discard pool. - * Otherwise the device discard pool is used. + * Otherwise a device discard pool is used. */ static VKDiscardPool &discard_pool_get(); };