From 6f5b192078f692d745347cd42d920c8214c130d6 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Sun, 18 Oct 2026 01:12:21 +0200 Subject: [PATCH] fix(compute): destroy the shader module once its pipeline exists ComputeShader::Load built a VulkanShader on the stack and let it go with its VkShaderModule still alive: nothing in the library destroys one. A process that loads the UI shaders once never noticed; one that creates a window again and again (an app that hides and re-shows its window) leaked five modules per window. Vulkan allows destroying the module as soon as the pipeline is created, so Load does, on success and on failure alike. --- implementations/Crafter.Graphics-ComputeShader.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/implementations/Crafter.Graphics-ComputeShader.cpp b/implementations/Crafter.Graphics-ComputeShader.cpp index 3af554b..f1daa93 100644 --- a/implementations/Crafter.Graphics-ComputeShader.cpp +++ b/implementations/Crafter.Graphics-ComputeShader.cpp @@ -74,8 +74,12 @@ void ComputeShader::Load(const std::filesystem::path& spvPath, DescriptorHeapVul }, .layout = layout, }; - Device::CheckVkResult(vkCreateComputePipelines( - Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline)); + const VkResult created = vkCreateComputePipelines( + Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline); + // The module is only an input to pipeline creation; VulkanShader does + // not destroy it, so it is released here either way. + vkDestroyShaderModule(Device::device, shader.shader, nullptr); + Device::CheckVkResult(created); return; } @@ -106,8 +110,10 @@ void ComputeShader::Load(const std::filesystem::path& spvPath, DescriptorHeapVul }, .layout = VK_NULL_HANDLE, }; - Device::CheckVkResult(vkCreateComputePipelines( - Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline)); + const VkResult created = vkCreateComputePipelines( + Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline); + vkDestroyShaderModule(Device::device, shader.shader, nullptr); + Device::CheckVkResult(created); } void ComputeShader::Dispatch(VkCommandBuffer cmd,