diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index 021f32fd3..0a985368d 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -433,7 +433,6 @@ class ResourceManager : public ResourceRecordHandler LogState m_State; Serialiser *m_pSerialiser; - private: bool m_InFrame; // very coarse lock, protects EVERYTHING. This could certainly be improved and it may be a bottleneck diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 965f84cce..aeb5650e9 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -402,7 +402,26 @@ WrappedVulkan::~WrappedVulkan() } #endif - // VKTODOMED clean up replay resources here? + // should only have one swapchain, since we are only handling the simple case + // of one device, etc for now. + RDCASSERT(m_SwapChainInfo.size() == 1); + for(auto it = m_SwapChainInfo.begin(); it != m_SwapChainInfo.end(); ++it) + { + for(size_t i=0; i < it->second.images.size(); i++) + { + // only in the replay app are these 'real' images to be destroyed + if(RenderDoc::Inst().IsReplayApp()) + { + // go through our wrapped functions, since the resources need to be deregistered + vkDestroyImage(GetDev(), it->second.images[i].im); + vkFreeMemory(GetDev(), it->second.images[i].mem); + } + } + } + m_SwapChainInfo.clear(); + + m_ResourceManager->Shutdown(); + delete m_ResourceManager; } const char * WrappedVulkan::GetChunkName(uint32_t idx) @@ -694,6 +713,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice( #undef FETCH_DEVICE_FUNCPTR } + // VKTODOLOW not handling multiple devices per physical devices + RDCASSERT(m_PhysicalReplayData[i].dev == VK_NULL_HANDLE); m_PhysicalReplayData[i].dev = device; m_PhysicalReplayData[i].qFamilyIdx = qFamilyIdx; @@ -5533,6 +5554,115 @@ bool WrappedVulkan::ReleaseResource(VkResource res) { // VKTODOHIGH: release resource with device from resource record + // VKTODOLOW - this will break if we have multiple devices and resources from each, + // but that will likely break other things too. + VkDevice dev = GetDev(); + const VkLayerDispatchTable *vt = device_dispatch_table(dev); + + switch(res.Namespace) + { + case eResWSISwapChain: + RDCERR("Should be no swapchain objects created on replay"); + break; + + case eResUnknown: + case eResSpecial: + case eResCmdBufferBake: + // virtual object - nothing to do + break; + + case eResPhysicalDevice: + case eResQueue: + case eResDescriptorSet: + // nothing to do - destroyed with parent object + break; + + case eResInstance: + { + VkInstance instance = (VkInstance)res.handle; + dispatch_key key = get_dispatch_key(instance); + instance_dispatch_table(instance)->DestroyInstance(instance); + destroy_instance_dispatch_table(key); + break; + } + case eResDevice: + vt->DestroyDevice((VkDevice)res.handle); + break; + case eResDeviceMemory: + vt->FreeMemory(dev, (VkDeviceMemory)res.handle); + break; + case eResBuffer: + vt->DestroyBuffer(dev, (VkBuffer)res.handle); + break; + case eResBufferView: + vt->DestroyBufferView(dev, (VkBufferView)res.handle); + break; + case eResImage: + vt->DestroyImage(dev, (VkImage)res.handle); + break; + case eResImageView: + vt->DestroyImageView(dev, (VkImageView)res.handle); + break; + case eResAttachmentView: + vt->DestroyAttachmentView(dev, (VkAttachmentView)res.handle); + break; + case eResFramebuffer: + vt->DestroyFramebuffer(dev, (VkFramebuffer)res.handle); + break; + case eResRenderPass: + vt->DestroyRenderPass(dev, (VkRenderPass)res.handle); + break; + case eResShaderModule: + vt->DestroyShaderModule(dev, (VkShaderModule)res.handle); + break; + case eResShader: + vt->DestroyShader(dev, (VkShader)res.handle); + break; + case eResPipelineCache: + vt->DestroyPipelineCache(dev, (VkPipelineCache)res.handle); + break; + case eResPipelineLayout: + vt->DestroyPipelineLayout(dev, (VkPipelineLayout)res.handle); + break; + case eResPipeline: + vt->DestroyPipeline(dev, (VkPipeline)res.handle); + break; + case eResSampler: + vt->DestroySampler(dev, (VkSampler)res.handle); + break; + case eResDescriptorPool: + vt->DestroyDescriptorPool(dev, (VkDescriptorPool)res.handle); + break; + case eResDescriptorSetLayout: + vt->DestroyDescriptorSetLayout(dev, (VkDescriptorSetLayout)res.handle); + break; + case eResViewportState: + vt->DestroyDynamicViewportState(dev, (VkDynamicViewportState)res.handle); + break; + case eResRasterState: + vt->DestroyDynamicViewportState(dev, (VkDynamicViewportState)res.handle); + break; + case eResColorBlendState: + vt->DestroyDynamicColorBlendState(dev, (VkDynamicColorBlendState)res.handle); + break; + case eResDepthStencilState: + vt->DestroyDynamicDepthStencilState(dev, (VkDynamicDepthStencilState)res.handle); + break; + case eResCmdPool: + vt->DestroyCommandPool(dev, (VkCmdPool)res.handle); + break; + case eResCmdBuffer: + vt->DestroyCommandBuffer(dev, (VkCmdBuffer)res.handle); + break; + case eResFence: + // VKTODOLOW + //vt->DestroyFence(dev, (VkFence)res.handle); + break; + case eResSemaphore: + vt->DestroySemaphore(dev, (VkSemaphore)res.handle); + break; + } + return true; } diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index b4642cd2e..c8efe97e0 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -65,7 +65,35 @@ class VulkanResourceManager : public ResourceManagersecond.resource); + Serialiser::FreeAlignedBuffer(it->second.blob); + if(!m_InitialContents.empty()) + m_InitialContents.erase(m_InitialContents.begin()); + } + + // have to do this here since we want to do it in reverse order + for(auto it = m_LiveResourceMap.end(); it != m_LiveResourceMap.begin();) + { + // decrement it first since the initial value at .end() is invalid + --it; + ResourceTypeRelease(it->second); + } + m_LiveResourceMap.clear(); + + for(auto it = m_InframeResourceMap.end(); it != m_InframeResourceMap.begin();) + { + // decrement it first since the initial value at .end() is invalid + --it; + ResourceTypeRelease(it->second); + } + m_InframeResourceMap.clear(); + + RDCASSERT(m_ResourceRecords.empty()); + + m_Inst = NULL; } inline void RemoveResourceRecord(ResourceId id) @@ -97,6 +125,9 @@ class VulkanResourceManager : public ResourceManagersecond); + auto origit = m_OriginalIDs.find(it->second); + if(origit != m_OriginalIDs.end()) + EraseLiveResource(origit->second); m_CurrentResourceIds.erase(res); } } diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 117ee0271..404501bf9 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -521,8 +521,6 @@ void VulkanReplay::InitDebugData() vkr = vt->CreateSampler(dev, &sampInfo, &m_DebugData.m_PointSampler); RDCASSERT(vkr == VK_SUCCESS); - // VKTODOMED all of this is leaking - VkPipelineCacheCreateInfo cacheInfo = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, NULL, 0, NULL, 0 }; vkr = vt->CreatePipelineCache(dev, &cacheInfo, &m_DebugData.m_PipelineCache); diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 17bb8c0ed..89c35687c 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -32,7 +32,7 @@ enum VkNamespace { eResUnknown = 0, eResSpecial, - eResGPU, + eResPhysicalDevice, eResInstance, eResDevice, eResQueue, @@ -55,7 +55,6 @@ enum VkNamespace eResDescriptorSet, eResViewportState, eResRasterState, - eResMSAAState, eResColorBlendState, eResDepthStencilState, eResCmdPool, @@ -63,9 +62,6 @@ enum VkNamespace eResCmdBufferBake, eResFence, eResSemaphore, - eResEvent, - eResWaitEvent, - eResQueryPool, eResWSISwapChain, }; @@ -97,7 +93,7 @@ struct VkResource } }; -inline VkResource MakeRes(VkPhysicalDevice o) { return VkResource(eResGPU, (uint64_t)o); } +inline VkResource MakeRes(VkPhysicalDevice o) { return VkResource(eResPhysicalDevice, (uint64_t)o); } inline VkResource MakeRes(VkInstance o) { return VkResource(eResInstance, (uint64_t)o); } inline VkResource MakeRes(VkDevice o) { return VkResource(eResDevice, (uint64_t)o); } inline VkResource MakeRes(VkQueue o) { return VkResource(eResQueue, (uint64_t)o); } @@ -126,8 +122,6 @@ inline VkResource MakeRes(VkDynamicColorBlendState o) { return VkResource(eResCo inline VkResource MakeRes(VkDynamicDepthStencilState o) { return VkResource(eResDepthStencilState, o.handle); } inline VkResource MakeRes(VkFence o) { return VkResource(eResFence, o.handle); } inline VkResource MakeRes(VkSemaphore o) { return VkResource(eResSemaphore, o.handle); } -inline VkResource MakeRes(VkEvent o) { return VkResource(eResEvent, o.handle); } -inline VkResource MakeRes(VkQueryPool o) { return VkResource(eResQueryPool, o.handle); } inline VkResource MakeRes(VkSwapChainWSI o) { return VkResource(eResWSISwapChain, o.handle); }