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
This commit is contained in:
Jeroen Bakker
2025-05-13 13:15:46 +02:00
parent 1d21d496f2
commit 8326285c2d
6 changed files with 27 additions and 6 deletions

View File

@@ -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)
{

View File

@@ -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_);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -76,6 +76,7 @@ template<typename Item> class TimelineResources : Vector<std::pair<TimelineValue
*/
class VKDiscardPool {
friend class VKDevice;
friend class VKBackend;
private:
TimelineResources<std::pair<VkImage, VmaAllocation>> 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();
};