From 4149bf2c9ce4e9e1a8457da8a497cdb137eaad7c Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 15 Oct 2020 11:32:34 -0400 Subject: Fix Vk leak (#1579) * #include an absolute path didn't work - because paths were taken to always be relative. * Handle scope of VkShaderModule. * Fix tabbing issue. --- tools/gfx/vulkan/render-vk.cpp | 58 +++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index b312d4b23..397d657a4 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -132,19 +132,19 @@ public: class BufferResourceImpl: public BufferResource { - public: + public: typedef BufferResource Parent; BufferResourceImpl(Resource::Usage initialUsage, const BufferResource::Desc& desc, VKRenderer* renderer): Parent(desc), - m_renderer(renderer), + m_renderer(renderer), m_initialUsage(initialUsage) - { - assert(renderer); - } + { + assert(renderer); + } Resource::Usage m_initialUsage; - VKRenderer* m_renderer; + VKRenderer* m_renderer; Buffer m_buffer; Buffer m_uploadBuffer; List m_readBuffer; ///< Stores the contents when a map read is performed @@ -244,11 +244,27 @@ public: class ShaderProgramImpl: public ShaderProgram { - public: + public: - ShaderProgramImpl(PipelineType pipelineType): + ShaderProgramImpl(const VulkanApi& api, PipelineType pipelineType): + m_api(&api), m_pipelineType(pipelineType) - {} + { + for (auto& shaderModule : m_modules) shaderModule = VK_NULL_HANDLE; + } + + ~ShaderProgramImpl() + { + for (auto shaderModule : m_modules) + { + if (shaderModule != VK_NULL_HANDLE) + { + m_api->vkDestroyShaderModule(m_api->m_device, shaderModule, nullptr); + } + } + } + + const VulkanApi* m_api; PipelineType m_pipelineType; @@ -256,7 +272,8 @@ public: VkPipelineShaderStageCreateInfo m_vertex; VkPipelineShaderStageCreateInfo m_fragment; - List m_buffers[2]; //< To keep storage of code in scope + List m_buffers[2]; //< To keep storage of code in scope + VkShaderModule m_modules[2]; }; class DescriptorSetLayoutImpl : public DescriptorSetLayout @@ -431,10 +448,13 @@ public: VkBool32 handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg); + /// Note that the outShaderModule value should be cleaned up when no longer needed by caller + /// via vkShaderModuleDestroy() VkPipelineShaderStageCreateInfo compileEntryPoint( ShaderProgram::KernelDesc const& kernelDesc, VkShaderStageFlagBits stage, - List& bufferOut); + List& outBuffer, + VkShaderModule& outShaderModule); static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData); @@ -875,7 +895,8 @@ VkBool32 VKRenderer::handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugRepo VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( ShaderProgram::KernelDesc const& kernelDesc, VkShaderStageFlagBits stage, - List& bufferOut) + List& outBuffer, + VkShaderModule& outShaderModule) { char const* dataBegin = (char const*) kernelDesc.codeBegin; char const* dataEnd = (char const*) kernelDesc.codeEnd; @@ -884,9 +905,9 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( // will free the memory after a compile request is closed. size_t codeSize = dataEnd - dataBegin; - bufferOut.insertRange(0, dataBegin, codeSize); + outBuffer.insertRange(0, dataBegin, codeSize); - char* codeBegin = bufferOut.getBuffer(); + char* codeBegin = outBuffer.getBuffer(); VkShaderModuleCreateInfo moduleCreateInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; moduleCreateInfo.pCode = (uint32_t*)codeBegin; @@ -894,6 +915,7 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( VkShaderModule module; SLANG_VK_CHECK(m_api.vkCreateShaderModule(m_device, &moduleCreateInfo, nullptr, &module)); + outShaderModule = module; VkPipelineShaderStageCreateInfo shaderStageCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; shaderStageCreateInfo.stage = stage; @@ -2819,19 +2841,19 @@ void VKRenderer::setDescriptorSet(PipelineType pipelineType, PipelineLayout* lay Result VKRenderer::createProgram(const ShaderProgram::Desc& desc, ShaderProgram** outProgram) { - RefPtr impl = new ShaderProgramImpl(desc.pipelineType); + RefPtr impl = new ShaderProgramImpl(m_api, desc.pipelineType); if( desc.pipelineType == PipelineType::Compute) { auto computeKernel = desc.findKernel(StageType::Compute); - impl->m_compute = compileEntryPoint(*computeKernel, VK_SHADER_STAGE_COMPUTE_BIT, impl->m_buffers[0]); + impl->m_compute = compileEntryPoint(*computeKernel, VK_SHADER_STAGE_COMPUTE_BIT, impl->m_buffers[0], impl->m_modules[0]); } else { auto vertexKernel = desc.findKernel(StageType::Vertex); auto fragmentKernel = desc.findKernel(StageType::Fragment); - impl->m_vertex = compileEntryPoint(*vertexKernel, VK_SHADER_STAGE_VERTEX_BIT, impl->m_buffers[0]); - impl->m_fragment = compileEntryPoint(*fragmentKernel, VK_SHADER_STAGE_FRAGMENT_BIT, impl->m_buffers[1]); + impl->m_vertex = compileEntryPoint(*vertexKernel, VK_SHADER_STAGE_VERTEX_BIT, impl->m_buffers[0], impl->m_modules[0]); + impl->m_fragment = compileEntryPoint(*fragmentKernel, VK_SHADER_STAGE_FRAGMENT_BIT, impl->m_buffers[1], impl->m_modules[1]); } *outProgram = impl.detach(); return SLANG_OK; -- cgit v1.2.3