From 1dd7aa92965e0b81a8245934a4add51ecb4ad900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Palandri?= Date: Tue, 26 May 2020 19:45:11 -0700 Subject: [PATCH] vulkan low-memory-mode --- renderdoc/common/wrapped_pool.h | 2 +- renderdoc/core/resource_manager.h | 4 +++- renderdoc/driver/vulkan/vk_core.cpp | 4 ++++ renderdoc/driver/vulkan/vk_manager.cpp | 5 ++++ renderdoc/driver/vulkan/vk_manager.h | 8 +++++++ renderdoc/driver/vulkan/vk_resources.cpp | 5 ++++ renderdoc/driver/vulkan/vk_resources.h | 1 + .../driver/vulkan/wrappers/vk_queue_funcs.cpp | 23 ++++++++++++++++--- .../vulkan/wrappers/vk_resource_funcs.cpp | 12 +++++----- 9 files changed, 53 insertions(+), 11 deletions(-) diff --git a/renderdoc/common/wrapped_pool.h b/renderdoc/common/wrapped_pool.h index e75667ecd..98dbbcd15 100644 --- a/renderdoc/common/wrapped_pool.h +++ b/renderdoc/common/wrapped_pool.h @@ -243,7 +243,7 @@ private: static PoolType m_Pool; \ void *operator new(size_t sz) { return m_Pool.Allocate(); } \ void operator delete(void *p) { m_Pool.Deallocate(p); } \ - static bool IsAlloc(void *p) { return m_Pool.IsAlloc(p); } + static bool IsAlloc(const void *p) { return m_Pool.IsAlloc(p); } #if ENABLED(INCLUDE_TYPE_NAMES) #define DECL_TYPENAME(a) \ template <> \ diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index 502440521..c6badf70d 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -1200,6 +1200,7 @@ void ResourceManager::PrepareInitialContents() RDCDEBUG("Preparing up to %u potentially dirty resources", (uint32_t)m_DirtyResources.size()); uint32_t prepared = 0; + uint32_t postponed = 0; float num = float(m_DirtyResources.size()); float idx = 0.0f; @@ -1229,6 +1230,7 @@ void ResourceManager::PrepareInitialContents() m_PostponedResourceIDs.insert(id); // Set empty contents here, it'll be prepared on serialization. SetInitialContents(id, InitialContentData()); + postponed++; continue; } @@ -1241,7 +1243,7 @@ void ResourceManager::PrepareInitialContents() Prepare_InitialState(res); } - RDCDEBUG("Prepared %u dirty resources", prepared); + RDCDEBUG("Prepared %u dirty resources, postponed %u", prepared, postponed); } template diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 52c361015..1a53d68ff 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1536,6 +1536,8 @@ void WrappedVulkan::StartFrameCapture(void *dev, void *wnd) m_CaptureTimer.Restart(); + GetResourceManager()->ResetCaptureStartTime(); + m_AppControlledCapture = true; m_SubmitCounter = 0; @@ -2037,6 +2039,8 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) m_CmdBufferRecords.clear(); + GetResourceManager()->ResetLastWriteTimes(); + GetResourceManager()->MarkUnwrittenResources(); GetResourceManager()->ClearReferencedMemory(); diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index b84ec5e31..94ffa3079 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -946,3 +946,8 @@ bool VulkanResourceManager::ResourceTypeRelease(WrappedVkRes *res) { return m_Core->ReleaseResource(res); } + +bool VulkanResourceManager::IsResourceTrackedForPersistency(WrappedVkRes *const &res) +{ + return IsPostponableRes(res); +} diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 032d15b44..e63f741e3 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -453,6 +453,14 @@ public: } } + bool IsResourceTrackedForPersistency(WrappedVkRes *const &res); + + void MarkDirtyWithWriteReference(ResourceId id) + { + MarkResourceFrameReferenced(id, eFrameRef_ReadBeforeWrite); + MarkDirtyResource(id); + } + private: bool ResourceTypeRelease(WrappedVkRes *res); diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index 29f5f988f..ef4b3309e 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -67,6 +67,11 @@ bool IsDispatchableRes(WrappedVkRes *ptr) WrappedVkCommandBuffer::IsAlloc(ptr)); } +bool IsPostponableRes(const WrappedVkRes *ptr) +{ + return (WrappedVkDeviceMemory::IsAlloc(ptr) || WrappedVkImage::IsAlloc(ptr)); +} + VkResourceType IdentifyTypeByPtr(WrappedVkRes *ptr) { if(WrappedVkPhysicalDevice::IsAlloc(ptr)) diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 1a804bcfb..7257e9dfc 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -833,6 +833,7 @@ inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan } bool IsDispatchableRes(WrappedVkRes *ptr); +bool IsPostponableRes(const WrappedVkRes *ptr); VkResourceType IdentifyTypeByPtr(WrappedVkRes *ptr); #define UNKNOWN_PREV_IMG_LAYOUT ((VkImageLayout)0xffffffff) diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index 5511fb829..6c170f8c6 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -891,6 +891,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, SCOPED_READLOCK(m_CapTransitionLock); bool capframe = IsActiveCapturing(m_State); + bool backframe = IsBackgroundCapturing(m_State); std::set refdIDs; @@ -909,7 +910,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) { if(GetResourceManager()->HasCurrentResource(*it)) - GetResourceManager()->MarkDirtyResource(*it); + GetResourceManager()->MarkDirtyWithWriteReference(*it); } // with EXT_descriptor_indexing a binding might have been updated after @@ -930,7 +931,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, refit->second.second == eFrameRef_ReadBeforeWrite) { if(GetResourceManager()->HasCurrentResource(refit->first)) - GetResourceManager()->MarkDirtyResource(refit->first); + GetResourceManager()->MarkDirtyWithWriteReference(refit->first); } } } @@ -1009,6 +1010,22 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, } } + if(backframe) + { + rdcarray maps; + { + SCOPED_LOCK(m_CoherentMapsLock); + maps = m_CoherentMaps; + } + + for(auto it = maps.begin(); it != maps.end(); ++it) + { + VkResourceRecord *record = *it; + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), + eFrameRef_ReadBeforeWrite); + } + } + if(capframe) { GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); @@ -1091,7 +1108,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, state.mapFlushed = false; } - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + GetResourceManager()->MarkDirtyWithWriteReference(record->GetResourceID()); } else { diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 9e410a877..26da51b81 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -704,7 +704,7 @@ void WrappedVulkan::vkUnmapMemory(VkDevice device, VkDeviceMemory mem) capframe = IsActiveCapturing(m_State); if(!capframe) - GetResourceManager()->MarkDirtyResource(id); + GetResourceManager()->MarkDirtyWithWriteReference(id); } SCOPED_LOCK(state.mrLock); @@ -885,7 +885,7 @@ VkResult WrappedVulkan::vkFlushMappedMemoryRanges(VkDevice device, uint32_t memR } else { - GetResourceManager()->MarkDirtyResource(memid); + GetResourceManager()->MarkDirtyWithWriteReference(memid); } } } @@ -1009,7 +1009,7 @@ VkResult WrappedVulkan::vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkD record->memSize, eFrameRef_ReadBeforeWrite); // the memory is immediately dirty because we have no way of tracking writes to it - GetResourceManager()->MarkDirtyResource(GetResID(memory)); + GetResourceManager()->MarkDirtyWithWriteReference(GetResID(memory)); } } @@ -1314,7 +1314,7 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo // buffers are always bound opaquely and in arbitrary divisions, sparse residency // only means not all the buffer needs to be bound, which is not that interesting for // our purposes. We just need to make sure sparse buffers are dirty. - GetResourceManager()->MarkDirtyResource(id); + GetResourceManager()->MarkDirtyWithWriteReference(id); } if(isSparse || isExternal) @@ -1793,7 +1793,7 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo * // not be valid to map from/into if the image isn't in GENERAL layout). if(isSparse || isExternal || isLinear) { - GetResourceManager()->MarkDirtyResource(id); + GetResourceManager()->MarkDirtyWithWriteReference(id); // for external images, try creating a non-external version and take the worst case of // memory requirements, in case the non-external one (as we will replay it) needs more @@ -2129,7 +2129,7 @@ VkResult WrappedVulkan::vkBindBufferMemory2(VkDevice device, uint32_t bindInfoCo eFrameRef_ReadBeforeWrite); // the memory is immediately dirty because we have no way of tracking writes to it - GetResourceManager()->MarkDirtyResource(GetResID(pBindInfos[i].memory)); + GetResourceManager()->MarkDirtyWithWriteReference(GetResID(pBindInfos[i].memory)); } } }