Shaders

Code file for this section is 11-init_shaders.cpp

Compiling GLSL Shaders into SPIR-V

The low-level shader code representation for Vulkan is SPIR-V. The sample programs compile shader programs written in GLSL into SPIR-V by running a utility called glslangValidator.

The shader source code is in the <sample name>.vert and <sample name>.frag files and part of the build process is to run glslangValidator on each of them to generate a header file in build/ShaderHeaders that contains a struct holding the raw SPIR-V representation of the shader. The samples then include these header files when creating their shader modules.

Look at the 11-init_shaders.vert file to find the shader source for the vertex shader and notice that the fragment shader source is provided in 11-init_shaders.frag

Also notice that these are simple shaders. The vertex shader simply passes the color through to its output and transforms the incoming position with the MVP transform that we saw in previous sections. The fragment shader is even simpler and just passes the color through.

In this simple sample, there are only two shader stages: the vertex and fragment stages, stored in that order in info.shaderStages.

Creating Vulkan Shader Modules

The compiled shader code is given to Vulkan by creating a VkShaderModule and storing it in a VkPipelineShaderStageCreateInfo structure that is used in another sample later as part of creating the overall graphics pipeline.

VkShaderModuleCreateInfo moduleCreateInfo;
moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleCreateInfo.pNext = NULL;
moduleCreateInfo.flags = 0;
moduleCreateInfo.codeSize = vtx_spv.size() * sizeof(unsigned int);
moduleCreateInfo.pCode = vtx_spv.data();
res = vkCreateShaderModule(info.device, &moduleCreateInfo, NULL,
                           &info.shaderStages[0].module);

Note that the code resulting from the GLSL to SPIR-V conversion is used to create the shader module. The same procedure is used to create a vkShaderModule for the fragment shader, which is stored in info.shaderStages[1].module.

Some additional initialization of the creation info for the pipeline shader stage is also performed at this time:

info.shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
info.shaderStages[0].pNext = NULL;
info.shaderStages[0].pSpecializationInfo = NULL;
info.shaderStages[0].flags = 0;
info.shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
info.shaderStages[0].pName = "main";

At this point, the shaders are ready to go.

Render Pass Index Framebuffers