From feaad639fb03e84b342919d2049caa78a62c152e Mon Sep 17 00:00:00 2001 From: Triang3l Date: Mon, 4 Jul 2022 11:27:51 +0300 Subject: [PATCH] [Vulkan] Destroy all RTs before VulkanRenderTargetCache is destroyed --- src/xenia/gpu/render_target_cache.cc | 10 +++++++++- src/xenia/gpu/render_target_cache.h | 4 ++++ src/xenia/gpu/vulkan/vulkan_render_target_cache.cc | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/render_target_cache.cc b/src/xenia/gpu/render_target_cache.cc index b3bca4290..0b6c2d134 100644 --- a/src/xenia/gpu/render_target_cache.cc +++ b/src/xenia/gpu/render_target_cache.cc @@ -374,8 +374,14 @@ void RenderTargetCache::InitializeCommon() { RenderTargetKey(), RenderTargetKey())); } -void RenderTargetCache::ShutdownCommon() { +void RenderTargetCache::DestroyAllRenderTargets(bool shutting_down) { ownership_ranges_.clear(); + if (!shutting_down) { + ownership_ranges_.emplace( + std::piecewise_construct, std::forward_as_tuple(uint32_t(0)), + std::forward_as_tuple(xenos::kEdramTileCount, RenderTargetKey(), + RenderTargetKey(), RenderTargetKey())); + } for (const auto& render_target_pair : render_targets_) { if (render_target_pair.second) { @@ -385,6 +391,8 @@ void RenderTargetCache::ShutdownCommon() { render_targets_.clear(); } +void RenderTargetCache::ShutdownCommon() { DestroyAllRenderTargets(true); } + void RenderTargetCache::ClearCache() { // Keep only render targets currently owning any EDRAM data. if (!render_targets_.empty()) { diff --git a/src/xenia/gpu/render_target_cache.h b/src/xenia/gpu/render_target_cache.h index d794f66e7..48cfecd59 100644 --- a/src/xenia/gpu/render_target_cache.h +++ b/src/xenia/gpu/render_target_cache.h @@ -193,6 +193,10 @@ class RenderTargetCache { // Call last in implementation-specific initialization (when things like path // are initialized by the implementation). void InitializeCommon(); + // May be called from the destructor, or from the implementation shutdown to + // destroy all render targets before destroying what they depend on in the + // implementation. + void DestroyAllRenderTargets(bool shutting_down); // Call last in implementation-specific shutdown, also callable from the // destructor. void ShutdownCommon(); diff --git a/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc b/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc index 46e261ac5..ed6ec1c41 100644 --- a/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc @@ -661,6 +661,12 @@ void VulkanRenderTargetCache::Shutdown(bool from_destructor) { const ui::vulkan::VulkanProvider::DeviceFunctions& dfn = provider.dfn(); VkDevice device = provider.device(); + // Destroy all render targets before the descriptor set pool is destroyed - + // may happen if shutting down the VulkanRenderTargetCache by destroying it, + // so ShutdownCommon is called by the RenderTargetCache destructor, when it's + // already too late. + DestroyAllRenderTargets(true); + for (const auto& dump_pipeline_pair : dump_pipelines_) { // May be null to prevent recreation attempts. if (dump_pipeline_pair.second != VK_NULL_HANDLE) {