1# Shader Module Compilation 2 3ANGLE converts application shaders into Vulkan [VkShaderModules][VkShaderModule] through a series 4of steps: 5 61. **ANGLE Internal Translation**: The initial calls to `glCompileShader` are passed to the [ANGLE 7shader translator][translator]. The translator compiles application shaders into SPIR-V, after 8transforming GLSL to conform to the [GL_KHR_vulkan_glsl][GL_KHR_vulkan_glsl] extension spec with 9some additional workarounds and emulation. We emulate OpenGL's different depth range, viewport y 10flipping, default uniforms, and emulate a number of extensions among others. For more info see 11[TranslatorVulkan.cpp][TranslatorVulkan.cpp]. After initial compilation, the SPIR-V blobs are not 12complete. The translator initially assigns resources and in/out variables arbitrary descriptor set, 13binding and location indices. The correct values are determined at link time. For the sake of 14transform feedback, some additional code is generated to be removed or modified during SPIR-V 15transformation. 16 17 The translator outputs some feature code conditional to Vulkan specialization constants, which are 18resolved at draw-time. For example, for emulating Dithering and Android surface rotation. 19 201. **Link Time**: During a call to `glLinkProgram` the Vulkan back-end can know the necessary 21locations and properties to write to connect the shader stage interfaces. However, some draw-time 22information is still necessary to finalize the SPIR-V; for example whether "early fragment tests" 23can be enabled. As an optimization, the SPIR-V is transformed with arbitrary settings and a Vulkan 24pipeline object is created in an attempt to warm the Vulkan pipeline cache. 25 261. **Draw-Time SPIR-V Transformation and Pipeline Creation**: Once the application records a draw 27call, a transformation pass is done on the generated SPIR-V to update the arbitrary descriptor set, 28binding and location indices set in step 1. Additionally, component and various transform feedback 29decorations are added, inactive varyings are removed, early fragment tests are enabled or disabled, 30debug info is removed and pre-rotation is applied. At this time, `VkShaderModule`s are created (and 31cached). The appropriate specialization constants are then resolved and the `VkPipeline` object is 32created (see details [here](PipelineCreation)). Note that we currently don't use 33[SPIRV-Tools][SPIRV-Tools] to perform any SPIR-V optimization. This could be something to improve on 34in the future. 35 36See the below diagram for a high-level view of the shader translation flow: 37 38<!-- Generated from https://bramp.github.io/js-sequence-diagrams/ 39 Note: remove whitespace in - -> arrows. 40participant App 41participant "ANGLE Front-end" 42participant "Vulkan Back-end" 43participant "ANGLE Translator" 44participant "Link-Time SPIR-V Transformer" 45 46App->"ANGLE Front-end": glCompileShader (VS) 47"ANGLE Front-end"->"Vulkan Back-end": ShaderVk::compile 48"Vulkan Back-end"->"ANGLE Translator": sh::Compile 49"ANGLE Translator"- ->"ANGLE Front-end": return SPIR-V 50 51Note right of "ANGLE Front-end": SPIR-V is using bogus\ndecorations to be\ncorrected at link time. 52 53Note right of App: Same for FS, GS, etc... 54 55App->"ANGLE Front-end": glCreateProgram (...) 56App->"ANGLE Front-end": glAttachShader (...) 57App->"ANGLE Front-end": glLinkProgram 58"ANGLE Front-end"->"Vulkan Back-end": ProgramVk::link 59 60Note right of "Vulkan Back-end": ProgramVk inits uniforms,\nlayouts, and descriptors. 61 62"Vulkan Back-end"->"Link-Time SPIR-V Transformer": SpvGetShaderSpirvCode 63"Link-Time SPIR-V Transformer"- ->"Vulkan Back-end": retrieve SPIR-V and determine decorations 64"Vulkan Back-end"- ->"ANGLE Front-end": return success 65 66Note right of App: App execution continues... 67 68App->"ANGLE Front-end": glDrawArrays (any draw) 69"ANGLE Front-end"->"Vulkan Back-end": ContextVk::drawArrays 70 71"Vulkan Back-end"->"Link-Time SPIR-V Transformer": SpvTransformSpirvCode 72"Link-Time SPIR-V Transformer"- ->"Vulkan Back-end": return transformed SPIR-V 73 74Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nrecord the draw. 75 76"Vulkan Back-end"- ->"ANGLE Front-end": return success 77--> 78 79 80 81[GL_KHR_vulkan_glsl]: https://github.com/KhronosGroup/GLSL/blob/main/extensions/khr/GL_KHR_vulkan_glsl.txt 82[SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools 83[translator]: https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/compiler/translator/ 84[TranslatorVulkan.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/compiler/translator/TranslatorVulkan.cpp 85[VkShaderModule]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkShaderModule.html 86[PipelineCreation]: PipelineCreation.md 87