mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-10 12:45:46 +00:00
Vulkan: Fix resource leaks present at shutdown and mode changes
Infrequent, but still happened.
This commit is contained in:
parent
1286c309e3
commit
4a8766cec4
@ -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()
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,8 @@ Renderer::~Renderer()
|
|||||||
{
|
{
|
||||||
g_Config.bRunning = false;
|
g_Config.bRunning = false;
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
DestroyScreenshotResources();
|
||||||
|
DestroyShaders();
|
||||||
DestroySemaphores();
|
DestroySemaphores();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user