summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/TextureCache.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2016-10-01 22:22:14 +1000
committerStenzek <stenzek@gmail.com>2016-10-03 19:11:47 +1000
commit4a8766cec4432f2e8bd31a973f44c020a69bd2c2 (patch)
tree926cbc6c9508c911c295e98260f91fc2a9885183 /Source/Core/VideoBackends/Vulkan/TextureCache.cpp
parent1286c309e3a7b9a7a28b6128e68ab06f1502864c (diff)
Vulkan: Fix resource leaks present at shutdown and mode changes
Infrequent, but still happened.
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/TextureCache.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/TextureCache.cpp34
1 files changed, 20 insertions, 14 deletions
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