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.
This commit is contained in:
Jorijn van der Graaf 2026-10-18 01:12:21 +02:00
commit 6f5b192078
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB

View file

@ -74,8 +74,12 @@ void ComputeShader::Load(const std::filesystem::path& spvPath, DescriptorHeapVul
}, },
.layout = layout, .layout = layout,
}; };
Device::CheckVkResult(vkCreateComputePipelines( const VkResult created = vkCreateComputePipelines(
Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline)); 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; return;
} }
@ -106,8 +110,10 @@ void ComputeShader::Load(const std::filesystem::path& spvPath, DescriptorHeapVul
}, },
.layout = VK_NULL_HANDLE, .layout = VK_NULL_HANDLE,
}; };
Device::CheckVkResult(vkCreateComputePipelines( const VkResult created = vkCreateComputePipelines(
Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline)); Device::device, Device::pipelineCache, 1, &info, nullptr, &pipeline);
vkDestroyShaderModule(Device::device, shader.shader, nullptr);
Device::CheckVkResult(created);
} }
void ComputeShader::Dispatch(VkCommandBuffer cmd, void ComputeShader::Dispatch(VkCommandBuffer cmd,