From 91c4e02e96fcf39287fb1e2e8a0cdaf964742499 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Sun, 22 May 2022 15:05:15 +0300 Subject: [PATCH] [Vulkan] Implement ClearCaches and don't do it for pipelines --- .../gpu/vulkan/vulkan_command_processor.cc | 20 +++++------- .../gpu/vulkan/vulkan_command_processor.h | 2 ++ src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc | 31 +++++++------------ src/xenia/gpu/vulkan/vulkan_pipeline_cache.h | 4 +-- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index 6dd91def7..ce0ee1576 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -70,6 +70,11 @@ VulkanCommandProcessor::VulkanCommandProcessor( VulkanCommandProcessor::~VulkanCommandProcessor() = default; +void VulkanCommandProcessor::ClearCaches() { + CommandProcessor::ClearCaches(); + cache_clear_requested_ = true; +} + void VulkanCommandProcessor::TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) { shared_memory_->MemoryInvalidationCallback(base_ptr, length, true); @@ -2295,21 +2300,10 @@ bool VulkanCommandProcessor::EndSubmission(bool is_swap) { texture_cache_->ClearCache(); - pipeline_cache_->ClearCache(); - render_target_cache_->ClearCache(); - for (const auto& pipeline_layout_pair : pipeline_layouts_) { - dfn.vkDestroyPipelineLayout( - device, pipeline_layout_pair.second.GetPipelineLayout(), nullptr); - } - pipeline_layouts_.clear(); - for (const auto& descriptor_set_layout_pair : - descriptor_set_layouts_textures_) { - dfn.vkDestroyDescriptorSetLayout( - device, descriptor_set_layout_pair.second, nullptr); - } - descriptor_set_layouts_textures_.clear(); + // Not clearing the pipeline layouts and the descriptor set layouts as + // they're referenced by pipelines, which are not destroyed. primitive_processor_->ClearCache(); diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.h b/src/xenia/gpu/vulkan/vulkan_command_processor.h index 3158db0b6..8390b67e2 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.h +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.h @@ -62,6 +62,8 @@ class VulkanCommandProcessor : public CommandProcessor { kernel::KernelState* kernel_state); ~VulkanCommandProcessor(); + void ClearCaches() override; + void TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) override; void RestoreEdramSnapshot(const void* snapshot) override; diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc index 433c42aeb..0a8a88f62 100644 --- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc @@ -64,24 +64,6 @@ void VulkanPipelineCache::Shutdown() { const ui::vulkan::VulkanProvider::DeviceFunctions& dfn = provider.dfn(); VkDevice device = provider.device(); - ClearCache(); - - for (const auto& geometry_shader_pair : geometry_shaders_) { - if (geometry_shader_pair.second != VK_NULL_HANDLE) { - dfn.vkDestroyShaderModule(device, geometry_shader_pair.second, nullptr); - } - } - geometry_shaders_.clear(); - - shader_translator_.reset(); -} - -void VulkanPipelineCache::ClearCache() { - const ui::vulkan::VulkanProvider& provider = - command_processor_.GetVulkanProvider(); - const ui::vulkan::VulkanProvider::DeviceFunctions& dfn = provider.dfn(); - VkDevice device = provider.device(); - // Destroy all pipelines. last_pipeline_ = nullptr; for (const auto& pipeline_pair : pipelines_) { @@ -91,13 +73,24 @@ void VulkanPipelineCache::ClearCache() { } pipelines_.clear(); - // Destroy all shaders. + // Destroy all internal shaders. + for (const auto& geometry_shader_pair : geometry_shaders_) { + if (geometry_shader_pair.second != VK_NULL_HANDLE) { + dfn.vkDestroyShaderModule(device, geometry_shader_pair.second, nullptr); + } + } + geometry_shaders_.clear(); + + // Destroy all translated shaders. for (auto it : shaders_) { delete it.second; } shaders_.clear(); texture_binding_layout_map_.clear(); texture_binding_layouts_.clear(); + + // Shut down shader translation. + shader_translator_.reset(); } VulkanShader* VulkanPipelineCache::LoadShader(xenos::ShaderType shader_type, diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h index 58f53cff4..819bd6e16 100644 --- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h +++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h @@ -58,7 +58,6 @@ class VulkanPipelineCache { bool Initialize(); void Shutdown(); - void ClearCache(); VulkanShader* LoadShader(xenos::ShaderType shader_type, const uint32_t* host_address, uint32_t dword_count); @@ -198,7 +197,8 @@ class VulkanPipelineCache { struct Pipeline { VkPipeline pipeline = VK_NULL_HANDLE; - // Owned by VulkanCommandProcessor, valid until ClearCache. + // The layouts are owned by the VulkanCommandProcessor, and must not be + // destroyed by it while the pipeline cache is active. const PipelineLayoutProvider* pipeline_layout; Pipeline(const PipelineLayoutProvider* pipeline_layout_provider) : pipeline_layout(pipeline_layout_provider) {}