blurrypiano / littleVulkanEngine

Code repo for video tutorial series teaching Vulkan and computer graphics
MIT License
829 stars 147 forks source link

Destroy shaderModule after create pipeLine #29

Closed SoftStoneDevelop closed 2 years ago

SoftStoneDevelop commented 2 years ago

In tutorial shader modules destroed after create Graphics Pipelines(https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules). What a reason why in this code we destroed in destructor?

Why not like this:


void LvePipeline::createGraphicsPipeline(
        const std::string& vertFilepath,
        const std::string& fragFilepath,
        const PipelineConfigInfo& configInfo
    ) {

        //... skip the code that is not relevant to the question

        VkShaderModule vertShaderModule = createShaderModule(vertCode);
        VkShaderModule fragShaderModule = createShaderModule(fragCode);

               //... skip the code that is not relevant to the question

        if (vkCreateGraphicsPipelines(
            lveDevice.device(),
            VK_NULL_HANDLE,
            1,
            &pipelineInfo,
            nullptr,
            &graphicsPipeline
        ) != VK_SUCCESS)
        {
            throw std::runtime_error("failed to create graphics pipeline");
        }

        vkDestroyShaderModule(lveDevice.device(), vertShaderModule, nullptr);
        vkDestroyShaderModule(lveDevice.device(), fragShaderModule, nullptr);
    }

Or have a reason for store modules in class LvePipeline?

therpgmaster commented 2 years ago

As far as I know, when binding a VkPipline all the shader modules must be present, so we can't destroy them until we destroy the pipeline. And obviously the pipeline should be kept alive until rendering stops, or until we swap it for a new one

SoftStoneDevelop commented 2 years ago

"The compilation and linking of the SPIR-V bytecode to machine code for execution by the GPU doesn't happen until the graphics pipeline is created."

I think this means - when we call vkCreateGraphicsPipelines shader byte code SPIR-V link to mashine code and means also shader module and code SPIR-V not nedeed anymore. The pipeline encapsulates all the code it needs from shader module(by description it is just a wrapper) on creation step pipeline.

Also vkDestroyShaderModule(lveDevice.device(), vertShaderModule, nullptr); not included pipeline pointer as argement. Which is strange if we assume that the pipeline uses it.

I checked code - this work.

harrynowl commented 2 years ago

The pipeline does not depend on the shader modules and they can safely be cleaned up whilst the pipeline still exists. Please see this reference which states the following:

A shader module can be destroyed while pipelines created using its shaders are still in use.

You may choose to retain the VkShaderModule objects if it's likely you'll recreate the pipeline (where you should also use a VkPipelineCache), otherwise you can discard them once the pipeline(s) using the VkShaderModule are created such as the code snipped provided in the original post.