From 04a2e2ad2a636fea2cdff09da8b7c174dcc6391f Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 21 Oct 2015 13:11:57 +0200 Subject: [PATCH] Add (slightly hacky) clearing of init contents after capture * This eliminates most of the leaking on capture - other than this it's mostly the leaking serialisation which isn't a huge deal (this could be ~900MB-1GB a capture. --- ReleaseNotes.md | 1 - renderdoc/core/resource_manager.h | 29 ++++++++++++------- .../driver/vulkan/wrappers/vk_misc_funcs.cpp | 5 +++- .../driver/vulkan/wrappers/vk_wsi_funcs.cpp | 8 +++++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index b9830a9dc..20b3aa847 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -31,7 +31,6 @@ On capture: * Memory maps are not intercepted, so any modifications are saved by reading back from the mapped pointer, even if it is uncached/write combined. * Image contents are saved out by copying aliasing their backing memory to a buffer, so will not be GPU-portable. * Captures will not be GPU-portable where memory indices etc change. -* Memory leaks each time a new capture is created. * Unsupported or untested features: * Subpasses * Nested command buffer execution diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index a3a540768..49a368b86 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -406,6 +406,9 @@ class ResourceManager : public ResourceRecordHandler // Serialise in which resources need initial contents and set them up. void CreateInitialContents(); + + // Free any initial contents that are prepared (for after capture is complete) + void FreeInitialContents(); // Apply the initial contents for the resources that need them, used at the start of a frame void ApplyInitialContents(); @@ -509,15 +512,8 @@ void ResourceManager::Shutdow if(!m_InframeResourceMap.empty()) m_InframeResourceMap.erase(m_InframeResourceMap.begin()); } - - while(!m_InitialContents.empty()) - { - auto it = m_InitialContents.begin(); - ResourceTypeRelease(it->second.resource); - Serialiser::FreeAlignedBuffer(it->second.blob); - if(!m_InitialContents.empty()) - m_InitialContents.erase(m_InitialContents.begin()); - } + + FreeInitialContents(); RDCASSERT(m_ResourceRecords.empty()); } @@ -762,6 +758,19 @@ void ResourceManager::Seriali } } +template +void ResourceManager::FreeInitialContents() +{ + while(!m_InitialContents.empty()) + { + auto it = m_InitialContents.begin(); + ResourceTypeRelease(it->second.resource); + Serialiser::FreeAlignedBuffer(it->second.blob); + if(!m_InitialContents.empty()) + m_InitialContents.erase(m_InitialContents.begin()); + } +} + template void ResourceManager::CreateInitialContents() { @@ -1285,5 +1294,3 @@ ResourceId ResourceManager::G RDCASSERT(m_LiveIDs.find(id) != m_LiveIDs.end()); return m_LiveIDs[id]; } - - diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index 0ce814899..c3ebeb247 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -91,6 +91,9 @@ void WrappedVulkan::vkDestroyCommandBuffer(VkDevice device, VkCmdBuffer obj) ObjDisp(device)->DestroyCommandBuffer(Unwrap(device), unwrapped); } +// VKTODOHIGH huge hack, see WrappedVulkan::vkQueuePresentKHR +bool releasingInitContents = false; + bool WrappedVulkan::ReleaseResource(WrappedVkRes *res) { if(res == NULL) return true; @@ -98,7 +101,7 @@ bool WrappedVulkan::ReleaseResource(WrappedVkRes *res) // VKTODOHIGH: Device-associated resources must be released before the device is // shutdown. This needs a rethink while writing - really everything should be cleaned // up explicitly by us or the app. - if(m_State >= WRITING) return true; + if(m_State >= WRITING && !releasingInitContents) return true; // VKTODOHIGH: release resource with device from resource record diff --git a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp index 10cfa2db9..fac27f11e 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp @@ -959,6 +959,14 @@ VkResult WrappedVulkan::vkQueuePresentKHR( GetResourceManager()->ClearReferencedResources(); + // VKTODOHIGH This is a huuuge hack while the shutdown order is all + // messed up and normal calls to WrappedVulkan::ReleaseResource are + // ignored while WRITING to avoid shutdown problems. + extern bool releasingInitContents; + releasingInitContents = true; + GetResourceManager()->FreeInitialContents(); + releasingInitContents = false; + GetResourceManager()->FlushPendingDirty(); } }