• 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 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 OpenGL
11[line segment rasterization](OpenGLLineSegmentRasterization.md) among others. For more info see
12[TranslatorVulkan.cpp][TranslatorVulkan.cpp]. After initial compilation, the SPIR-V blobs 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 additional code is generated to be removed or modified during SPIR-V
16transformation.
17
18   The translator outputs some feature code conditional to Vulkan specialization constants, which are
19resolved at draw-time. For example,
20[Bresenham line rasterization](OpenGLLineSegmentRasterization.md) emulation.
21
221. **Link Time**: During a call to `glLinkProgram` the Vulkan back-end can know the necessary
23locations and properties to write to connect the shader stage interfaces. However, some draw-time
24information is still necessary to finalize the SPIR-V; for example whether "early fragment tests"
25can be enabled. As an optimization, the SPIR-V is transformed with arbitrary settings and a Vulkan
26pipeline object is created in an attempt to warm the Vulkan pipeline cache.
27
281. **Draw-Time SPIR-V Transformation and Pipeline Creation**: Once the application records a draw
29call, a transformation pass is done on the generated SPIR-V to update the arbitrary descriptor set,
30binding and location indices set in step 1. Additionally, component and various transform feedback
31decorations are added, inactive varyings are removed, early fragment tests are enabled or disabled,
32debug info is removed and pre-rotation is applied. At this time, `VkShaderModule`s are created (and
33cached). The appropriate specialization constants are then resolved and the `VkPipeline` object is
34created.  Note that we currently don't use [SPIRV-Tools][SPIRV-Tools] to perform any SPIR-V
35optimization. This could be something to improve on in the future.
36
37See the below diagram for a high-level view of the shader translation flow:
38
39<!-- Generated from https://bramp.github.io/js-sequence-diagrams/
40     Note: remove whitespace in - -> arrows.
41participant App
42participant "ANGLE Front-end"
43participant "Vulkan Back-end"
44participant "ANGLE Translator"
45participant "Link-Time SPIR-V Transformer"
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 SPIR-V
51
52Note right of "ANGLE Front-end": SPIR-V is using bogus\ndecorations 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"->"Link-Time SPIR-V Transformer": GlslangWrapperVk::GetShaderCode
64"Link-Time SPIR-V Transformer"- ->"Vulkan Back-end": retrieve SPIR-V and determine decorations
65"Vulkan Back-end"- ->"ANGLE Front-end": return success
66
67Note right of App: App execution continues...
68
69App->"ANGLE Front-end": glDrawArrays (any draw)
70"ANGLE Front-end"->"Vulkan Back-end": ContextVk::drawArrays
71
72"Vulkan Back-end"->"Link-Time SPIR-V Transformer": GlslangWrapperVk::TransformSpirV
73"Link-Time SPIR-V Transformer"- ->"Vulkan Back-end": return transformed SPIR-V
74
75Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nrecord the draw.
76
77"Vulkan Back-end"- ->"ANGLE Front-end": return success
78-->
79
80![Vulkan Shader Translation Flow](https://raw.githubusercontent.com/google/angle/main/src/libANGLE/renderer/vulkan/doc/img/VulkanShaderTranslation.svg?sanitize=true)
81
82[GL_KHR_vulkan_glsl]: https://github.com/KhronosGroup/GLSL/blob/main/extensions/khr/GL_KHR_vulkan_glsl.txt
83[GlslangWrapperVk.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/libANGLE/renderer/vulkan/GlslangWrapperVk.cpp
84[SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools
85[translator]: https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/compiler/translator/
86[TranslatorVulkan.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/compiler/translator/TranslatorVulkan.cpp
87[VkShaderModule]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkShaderModule.html
88