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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user