Vulkan: Fix resource leaks present at shutdown and mode changes

Infrequent, but still happened.
This commit is contained in:
Stenzek 2016-10-01 22:22:14 +10:00
parent 1286c309e3
commit 4a8766cec4
4 changed files with 51 additions and 14 deletions

View File

@ -46,6 +46,7 @@ FramebufferManager::~FramebufferManager()
DestroyReadbackRenderPasses(); DestroyReadbackRenderPasses();
DestroyPokeVertexBuffer(); DestroyPokeVertexBuffer();
DestroyPokeShaders();
} }
bool FramebufferManager::Initialize() bool FramebufferManager::Initialize()
@ -207,6 +208,12 @@ void FramebufferManager::DestroyEFBRenderPass()
m_efb_load_render_pass = VK_NULL_HANDLE; 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) if (m_depth_resolve_render_pass != VK_NULL_HANDLE)
{ {
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_depth_resolve_render_pass, nullptr); vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_depth_resolve_render_pass, nullptr);
@ -352,6 +359,18 @@ void FramebufferManager::DestroyEFBFramebuffer()
m_efb_framebuffer = VK_NULL_HANDLE; 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_color_texture.reset();
m_efb_convert_color_texture.reset(); m_efb_convert_color_texture.reset();
m_efb_depth_texture.reset(); m_efb_depth_texture.reset();
@ -899,9 +918,15 @@ bool FramebufferManager::CreateReadbackRenderPasses()
void FramebufferManager::DestroyReadbackRenderPasses() void FramebufferManager::DestroyReadbackRenderPasses()
{ {
if (m_copy_color_render_pass != VK_NULL_HANDLE) if (m_copy_color_render_pass != VK_NULL_HANDLE)
{
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_color_render_pass, nullptr); 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) if (m_copy_depth_render_pass != VK_NULL_HANDLE)
{
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_depth_render_pass, nullptr); vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_depth_render_pass, nullptr);
m_copy_depth_render_pass = VK_NULL_HANDLE;
}
} }
bool FramebufferManager::CompileReadbackShaders() bool FramebufferManager::CompileReadbackShaders()
@ -1238,6 +1263,7 @@ bool FramebufferManager::CreatePokeVertexBuffer()
void FramebufferManager::DestroyPokeVertexBuffer() void FramebufferManager::DestroyPokeVertexBuffer()
{ {
m_poke_vertex_stream_buffer.reset();
} }
bool FramebufferManager::CompilePokeShaders() bool FramebufferManager::CompilePokeShaders()

View File

@ -41,6 +41,9 @@ PaletteTextureConverter::~PaletteTextureConverter()
if (m_palette_buffer_view != VK_NULL_HANDLE) if (m_palette_buffer_view != VK_NULL_HANDLE)
vkDestroyBufferView(g_vulkan_context->GetDevice(), m_palette_buffer_view, nullptr); 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) if (m_palette_set_layout != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(g_vulkan_context->GetDevice(), m_palette_set_layout, nullptr); vkDestroyDescriptorSetLayout(g_vulkan_context->GetDevice(), m_palette_set_layout, nullptr);
} }

View File

@ -61,6 +61,8 @@ Renderer::~Renderer()
{ {
g_Config.bRunning = false; g_Config.bRunning = false;
UpdateActiveConfig(); UpdateActiveConfig();
DestroyScreenshotResources();
DestroyShaders();
DestroySemaphores(); DestroySemaphores();
} }

View File

@ -41,6 +41,7 @@ TextureCache::~TextureCache()
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_initialize_render_pass, nullptr); vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_initialize_render_pass, nullptr);
if (m_update_render_pass != VK_NULL_HANDLE) if (m_update_render_pass != VK_NULL_HANDLE)
vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_update_render_pass, nullptr); vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_update_render_pass, nullptr);
TextureCache::DeleteShaders();
} }
bool TextureCache::Initialize(StateTracker* state_tracker) bool TextureCache::Initialize(StateTracker* state_tracker)
@ -725,20 +726,25 @@ bool TextureCache::CompileShaders()
void TextureCache::DeleteShaders() void TextureCache::DeleteShaders()
{ {
auto DestroyShader = [this](VkShaderModule& shader) { // It is safe to destroy shader modules after they are consumed by creating a pipeline.
if (shader != VK_NULL_HANDLE) // 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
vkDestroyShaderModule(g_vulkan_context->GetDevice(), shader, nullptr); // a frame. See Vulkan spec, section 2.3.1. Object Lifetime.
shader = VK_NULL_HANDLE; if (m_copy_shader != VK_NULL_HANDLE)
} {
}; vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_copy_shader, nullptr);
m_copy_shader = VK_NULL_HANDLE;
// Since this can be called by the base class we need to wait for idle. }
g_command_buffer_mgr->WaitForGPUIdle(); if (m_efb_color_to_tex_shader != VK_NULL_HANDLE)
{
DestroyShader(m_copy_shader); vkDestroyShaderModule(g_vulkan_context->GetDevice(), m_efb_color_to_tex_shader, nullptr);
DestroyShader(m_efb_color_to_tex_shader); m_efb_color_to_tex_shader = VK_NULL_HANDLE;
DestroyShader(m_efb_depth_to_tex_shader); }
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 } // namespace Vulkan