diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 531327f53a..f78cf9953f 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -46,6 +46,7 @@ FramebufferManager::~FramebufferManager() DestroyReadbackRenderPasses(); DestroyPokeVertexBuffer(); + DestroyPokeShaders(); } bool FramebufferManager::Initialize() @@ -207,6 +208,12 @@ void FramebufferManager::DestroyEFBRenderPass() m_efb_load_render_pass = VK_NULL_HANDLE; } + if (m_efb_clear_render_pass != VK_NULL_HANDLE) + { + vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_efb_clear_render_pass, nullptr); + m_efb_clear_render_pass = VK_NULL_HANDLE; + } + if (m_depth_resolve_render_pass != VK_NULL_HANDLE) { vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_depth_resolve_render_pass, nullptr); @@ -352,6 +359,18 @@ void FramebufferManager::DestroyEFBFramebuffer() m_efb_framebuffer = VK_NULL_HANDLE; } + if (m_efb_convert_framebuffer != VK_NULL_HANDLE) + { + vkDestroyFramebuffer(g_vulkan_context->GetDevice(), m_efb_convert_framebuffer, nullptr); + m_efb_convert_framebuffer = VK_NULL_HANDLE; + } + + if (m_depth_resolve_framebuffer != VK_NULL_HANDLE) + { + vkDestroyFramebuffer(g_vulkan_context->GetDevice(), m_depth_resolve_framebuffer, nullptr); + m_depth_resolve_framebuffer = VK_NULL_HANDLE; + } + m_efb_color_texture.reset(); m_efb_convert_color_texture.reset(); m_efb_depth_texture.reset(); @@ -899,9 +918,15 @@ bool FramebufferManager::CreateReadbackRenderPasses() void FramebufferManager::DestroyReadbackRenderPasses() { if (m_copy_color_render_pass != VK_NULL_HANDLE) + { vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_color_render_pass, nullptr); + m_copy_color_render_pass = VK_NULL_HANDLE; + } if (m_copy_depth_render_pass != VK_NULL_HANDLE) + { vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_depth_render_pass, nullptr); + m_copy_depth_render_pass = VK_NULL_HANDLE; + } } bool FramebufferManager::CompileReadbackShaders() @@ -1238,6 +1263,7 @@ bool FramebufferManager::CreatePokeVertexBuffer() void FramebufferManager::DestroyPokeVertexBuffer() { + m_poke_vertex_stream_buffer.reset(); } bool FramebufferManager::CompilePokeShaders() diff --git a/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp b/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp index 638edd5213..f67ed33b28 100644 --- a/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp +++ b/Source/Core/VideoBackends/Vulkan/PaletteTextureConverter.cpp @@ -41,6 +41,9 @@ PaletteTextureConverter::~PaletteTextureConverter() if (m_palette_buffer_view != VK_NULL_HANDLE) vkDestroyBufferView(g_vulkan_context->GetDevice(), m_palette_buffer_view, nullptr); + if (m_pipeline_layout != VK_NULL_HANDLE) + vkDestroyPipelineLayout(g_vulkan_context->GetDevice(), m_pipeline_layout, nullptr); + if (m_palette_set_layout != VK_NULL_HANDLE) vkDestroyDescriptorSetLayout(g_vulkan_context->GetDevice(), m_palette_set_layout, nullptr); } diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index c6837ef7f8..9865dc2a0f 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -61,6 +61,8 @@ Renderer::~Renderer() { g_Config.bRunning = false; UpdateActiveConfig(); + DestroyScreenshotResources(); + DestroyShaders(); DestroySemaphores(); } diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp index e3b989c34e..4b83a76b59 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp @@ -41,6 +41,7 @@ TextureCache::~TextureCache() vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_initialize_render_pass, nullptr); if (m_update_render_pass != VK_NULL_HANDLE) vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_update_render_pass, nullptr); + TextureCache::DeleteShaders(); } bool TextureCache::Initialize(StateTracker* state_tracker) @@ -725,20 +726,25 @@ bool TextureCache::CompileShaders() void TextureCache::DeleteShaders() { - auto DestroyShader = [this](VkShaderModule& shader) { - if (shader != VK_NULL_HANDLE) - { - vkDestroyShaderModule(g_vulkan_context->GetDevice(), shader, nullptr); - shader = VK_NULL_HANDLE; - } - }; - - // Since this can be called by the base class we need to wait for idle. - g_command_buffer_mgr->WaitForGPUIdle(); - - DestroyShader(m_copy_shader); - DestroyShader(m_efb_color_to_tex_shader); - DestroyShader(m_efb_depth_to_tex_shader); + // It is safe to destroy shader modules after they are consumed by creating a pipeline. + // Therefore, no matter where this function is called from, it won't cause an issue due to + // pending commands, although at the time of writing should only be called at the end of + // a frame. See Vulkan spec, section 2.3.1. Object Lifetime. + if (m_copy_shader != VK_NULL_HANDLE) + { + vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_copy_shader, nullptr); + m_copy_shader = VK_NULL_HANDLE; + } + if (m_efb_color_to_tex_shader != VK_NULL_HANDLE) + { + vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_efb_color_to_tex_shader, nullptr); + m_efb_color_to_tex_shader = VK_NULL_HANDLE; + } + if (m_efb_depth_to_tex_shader != VK_NULL_HANDLE) + { + vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_efb_depth_to_tex_shader, nullptr); + m_efb_depth_to_tex_shader = VK_NULL_HANDLE; + } } } // namespace Vulkan