• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Vulkan-compatible
8GLSL. Vulkan-compatible GLSL matches the [GL_KHR_vulkan_glsl][GL_KHR_vulkan_glsl] extension spec
9with some additional workarounds and emulation. We emulate OpenGL's different depth range, viewport
10y flipping, default uniforms, and OpenGL
11[line segment rasterization](OpenGLLineSegmentRasterization.md). For more info see
12[TranslatorVulkan.cpp][TranslatorVulkan.cpp]. After initial compilation the shaders are not
13complete. The translator initially assigns resources and in/out variables arbitrary descriptor set,
14binding and location indices. The correct values are determined at link time. For the sake of
15transform feedback, some markers are left in the shader for link-time substitution.
16
17  The translator outputs some feature code conditional to Vulkan specialization constants, which are
18resolved at draw-time. For example,
19[Bresenham line rasterization](OpenGLLineSegmentRasterization.md) emulation.
20
211. **Link-Time Compilation and Transformation**: During a call to `glLinkProgram` the Vulkan
22back-end can know the necessary locations and properties to write to connect the shader stage
23interfaces. We get the completed shader source using ANGLE's
24[GlslangWrapperVk][GlslangWrapperVk.cpp] helper class. At this time, we use Khronos'
25[glslang][glslang] to convert the Vulkan-compatible GLSL into SPIR-V. A transformation pass is done
26on the generated SPIR-V to update the arbitrary descriptor set, binding and location indices set in
27step 1. Additionally, component and various transform feedback decorations are added and inactive
28varyings are removed from the shader interface. We currently don't generate `VkShaderModules` at
29this time, but that could be a future optimization.
30
311. **Draw-time Pipeline Creation**: Once the application records a draw call, the SPIR-V is compiled
32into `VkShaderModule`s. The appropriate specialization constants are then resolved and the
33`VkPipeline` object is created.  Note that we currently don't use [SPIRV-Tools][SPIRV-Tools] to
34perform any SPIR-V optimization. This could be something to improve on in 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 "GlslangWrapperVk"
45participant "Glslang"
46
47App->"ANGLE Front-end": glCompileShader (VS)
48"ANGLE Front-end"->"Vulkan Back-end": ShaderVk::compile
49"Vulkan Back-end"->"ANGLE Translator": sh::Compile
50"ANGLE Translator"- ->"ANGLE Front-end": return Vulkan-compatible GLSL
51
52Note right of "ANGLE Front-end": Source is using bogus\nVulkan qualifiers to be\ncorrected at link time.
53
54Note right of App: Same for FS, GS, etc...
55
56App->"ANGLE Front-end": glCreateProgram (...)
57App->"ANGLE Front-end": glAttachShader (...)
58App->"ANGLE Front-end": glLinkProgram
59"ANGLE Front-end"->"Vulkan Back-end": ProgramVk::link
60
61Note right of "Vulkan Back-end": ProgramVk inits uniforms,\nlayouts, and descriptors.
62
63"Vulkan Back-end"->GlslangWrapperVk: GlslangWrapperVk::GetShaderSpirvCode
64GlslangWrapperVk->Glslang: GlslangToSpv
65Glslang- ->GlslangWrapperVk: Return SPIR-V
66
67Note right of GlslangWrapperVk: Transform SPIR-V
68
69GlslangWrapperVk- ->"Vulkan Back-end": return transformed SPIR-V
70"Vulkan Back-end"- ->"ANGLE Front-end": return success
71
72Note right of App: App execution continues...
73
74App->"ANGLE Front-end": glDrawArrays (any draw)
75"ANGLE Front-end"->"Vulkan Back-end": ContextVk::drawArrays
76
77Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nrecord the draw.
78
79"Vulkan Back-end"- ->"ANGLE Front-end": return success
80-->
81
82![Vulkan Shader Translation Flow](https://raw.githubusercontent.com/google/angle/master/src/libANGLE/renderer/vulkan/doc/img/VulkanShaderTranslation.svg?sanitize=true)
83
84[GL_KHR_vulkan_glsl]: https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt
85[glslang]: https://github.com/KhronosGroup/glslang
86[GlslangWrapperVk.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/libANGLE/renderer/vulkan/GlslangWrapperVk.cpp
87[SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools
88[translator]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/compiler/translator/
89[TranslatorVulkan.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/compiler/translator/TranslatorVulkan.cpp
90[VkShaderModule]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkShaderModule.html
91