From 24ccc232032e7b9b2ff665ce10e8cc2bdadb821d Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Mon, 28 Oct 2024 20:42:10 +0000 Subject: [PATCH] Fix resources getting deleted prematurely in vkutil::ResourcePool ResourcePool wasn't waiting for resources to expire before deleting them. Instead of deleting them on the spot, let them sit in the pool until they expire. Also add a cleanExcessExpiredResources() method that the renderContext can call every frame at the same time it's deleting other expired Vulkan resources. Diffs= 7a9e69314d Fix resources getting deleted prematurely in vkutil::ResourcePool (#8411) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- .../renderer/vulkan/vkutil_resource_pool.hpp | 27 ++++++++++++------- .../src/vulkan/render_context_vulkan_impl.cpp | 3 +++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/.rive_head b/.rive_head index 5e152b45..36e9f287 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -5cde9010629994ed13d6b05a1bead5f89f3182c7 +7a9e69314dcad3069d04f866b5dece40873023e0 diff --git a/renderer/include/rive/renderer/vulkan/vkutil_resource_pool.hpp b/renderer/include/rive/renderer/vulkan/vkutil_resource_pool.hpp index ed4748c9..c3b3e892 100644 --- a/renderer/include/rive/renderer/vulkan/vkutil_resource_pool.hpp +++ b/renderer/include/rive/renderer/vulkan/vkutil_resource_pool.hpp @@ -73,6 +73,7 @@ class ResourcePool : public RefCnt> resource = ref_rcp(m_releasedResources.front().resource.release()); m_releasedResources.pop_front(); resource->reset(); + cleanExcessExpiredResources(); } else { @@ -89,18 +90,24 @@ class ResourcePool : public RefCnt> assert(mutableResource->debugging_refcnt() == 0); assert(mutableResource->m_pool.get() == this); - if (m_releasedResources.size() < MaxResourcesInPool) + // Recycle the resource! + m_releasedResources.emplace_back( + mutableResource, + m_factory.vulkanContext()->currentFrameIdx()); + // Do this last in case it deletes our "this". + mutableResource->m_pool = nullptr; + + cleanExcessExpiredResources(); + } + + void cleanExcessExpiredResources() + { + while (m_releasedResources.size() > MaxResourcesInPool && + m_factory.vulkanContext()->currentFrameIdx() >= + m_releasedResources.front().expirationFrameIdx) { - // Recycle the resource! - m_releasedResources.emplace_back( - mutableResource, - m_factory.vulkanContext()->currentFrameIdx()); - // Do this last in case it deletes our "this". - mutableResource->m_pool = nullptr; - return; + m_releasedResources.pop_front(); } - - delete resource; } protected: diff --git a/renderer/src/vulkan/render_context_vulkan_impl.cpp b/renderer/src/vulkan/render_context_vulkan_impl.cpp index 28292cb0..ec6a67a6 100644 --- a/renderer/src/vulkan/render_context_vulkan_impl.cpp +++ b/renderer/src/vulkan/render_context_vulkan_impl.cpp @@ -2137,6 +2137,9 @@ void RenderContextVulkanImpl::prepareToMapBuffers() // buffers. m_vk->onNewFrameBegun(); + // Clean expired resources in our pool of descriptor set pools. + m_descriptorSetPoolPool->cleanExcessExpiredResources(); + // Synchronize buffer sizes in the buffer rings. m_flushUniformBufferRing.synchronizeSizeAt(m_bufferRingIdx); m_imageDrawUniformBufferRing.synchronizeSizeAt(m_bufferRingIdx);