Commit df5ae9f6 by Jamie Madill

Vulkan: Write design doc explaining SPIR-V generation.

The two-pass approach first uses ANGLE's shader translator followed by glslang. The doc explains it in more detail with links. Bug: angleproject:3345 Change-Id: I04fd31993e3cd62ac409f2696e18f7ec39e5c6ce Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1560252Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent a95940c6
...@@ -63,3 +63,86 @@ Note that the current design of the transition table stores transitions in an un ...@@ -63,3 +63,86 @@ Note that the current design of the transition table stores transitions in an un
applications map from one state to many this will slow down the transition time. This could be applications map from one state to many this will slow down the transition time. This could be
improved in the future using a faster look up. For instance we could keep a sorted transition table improved in the future using a faster look up. For instance we could keep a sorted transition table
or use a small hash map for transitions. or use a small hash map for transitions.
### Shader Module Compilation
ANGLE converts application shaders into Vulkan [VkShaderModules][VkShaderModule] through a series
of steps:
1. **ANGLE Internal Translation**: The initial calls to `glCompileShader` are passed to the [ANGLE
shader translator][translator]. The translator compiles application shaders into Vulkan-compatible
GLSL. Vulkan-compatible GLSL matches the [GL_KHR_vulkan_glsl][GL_KHR_vulkan_glsl] extension spec
with some additional workarounds and emulation. We emulate OpenGL's different depth range, viewport
y flipping, default uniforms, and OpenGL line segment rasterization. For more info see
[TranslatorVulkan.cpp][TranslatorVulkan.cpp]. After initial compilation the shaders are not
complete. They are templated with markers that are filled in later at link time.
1. **Link-Time Translation**: During a call to `glLinkProgram` the Vulkan back-end can know the
necessary locations and properties to write to connect the shader stage interfaces. We get the
completed shader source using ANGLE's [GlslangWrapper][GlslangWrapper.cpp] helper class. We still
cannot generate `VkShaderModules` since some ANGLE features like OpenGL line rasterization emulation
depend on draw-time information.
1. **Draw-time SPIR-V Generation**: Once the application records a draw call we use Khronos'
[glslang][glslang] to convert the Vulkan-compatible GLSL into SPIR-V with the correct draw-time
defines. The SPIR-V is then compiled into `VkShaderModules`. For details please see
[GlslangWrapper.cpp][GlslangWrapper.cpp]. The `VkShaderModules` are then used by `VkPipelines`. Note
that we currently don't use [SPIRV-Tools][SPIRV-Tools] to perform any SPIR-V optimization. This
could be something to improve on in the future.
See the below diagram for a high-level view of the shader translation flow:
<!-- Generated from https://bramp.github.io/js-sequence-diagrams/
participant App
participant "ANGLE Front-end"
participant "Vulkan Back-end"
participant "ANGLE Translator"
participant "GlslangWrapper"
participant "Glslang"
App->"ANGLE Front-end": glCompileShader (VS)
"ANGLE Front-end"->"Vulkan Back-end": ShaderVk::compile
"Vulkan Back-end"->"ANGLE Translator": sh::Compile
"ANGLE Translator"- ->"ANGLE Front-end": return Vulkan-compatible GLSL
Note right of "ANGLE Front-end": Source is templated\nwith markers to be\nfilled at link time.
Note right of App: Same for FS, GS, etc...
App->"ANGLE Front-end": glCreateProgram (...)
App->"ANGLE Front-end": glAttachShader (...)
App->"ANGLE Front-end": glLinkProgram
"ANGLE Front-end"->"Vulkan Back-end": ProgramVk::link
Note right of "Vulkan Back-end": ProgramVk inits uniforms,\nlayouts, and descriptors.
"Vulkan Back-end"->GlslangWrapper: GlslangWrapper::GetShaderSource
GlslangWrapper- ->"Vulkan Back-end": return filled-in sources
Note right of "Vulkan Back-end": Source is templated with\ndefines to be resolved at\ndraw time.
"Vulkan Back-end"- ->"ANGLE Front-end": return success
Note right of App: App execution continues...
App->"ANGLE Front-end": glDrawArrays (any draw)
"ANGLE Front-end"->"Vulkan Back-end": ContextVk::drawArrays
"Vulkan Back-end"->GlslangWrapper: GlslangWrapper::GetShaderCode (with defines)
GlslangWrapper->Glslang: GlslangToSpv
Glslang- ->"Vulkan Back-end": Return SPIR-V
Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nrecord the draw.
"Vulkan Back-end"- ->"ANGLE Front-end": return success
-->
![Vulkan Shader Translation Flow](https://raw.githubusercontent.com/google/angle/master/src/libANGLE/renderer/vulkan/doc/img/VulkanShaderTranslation.svg?sanitize=true)
[VkShaderModule]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkShaderModule.html
[translator]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/compiler/translator/
[GL_KHR_vulkan_glsl]: https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt
[TranslatorVulkan.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/compiler/translator/TranslatorVulkan.cpp
[glslang]: https://github.com/KhronosGroup/glslang
[GlslangWrapper.cpp]: https://chromium.googlesource.com/angle/angle/+/refs/heads/master/src/libANGLE/renderer/vulkan/GlslangWrapper.cpp
[SPIRV-Tools]: https://github.com/KhronosGroup/SPIRV-Tools
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" width="1185" height="1229" xmlns:xlink="http://www.w3.org/1999/xlink"><source><![CDATA[participant App
participant "ANGLE Front-end"
participant "Vulkan Back-end"
participant "ANGLE Translator"
participant "GlslangWrapper"
participant "Glslang"
App->"ANGLE Front-end": glCompileShader (VS)
"ANGLE Front-end"->"Vulkan Back-end": ShaderVk::compile
"Vulkan Back-end"->"ANGLE Translator": sh::Compile
"ANGLE Translator"-->"ANGLE Front-end": return Vulkan-compatible GLSL
Note right of "ANGLE Front-end": Source is templated\nwith markers to be\nfilled at link time.
Note right of App: Same for FS, GS, etc...
App->"ANGLE Front-end": glCreateProgram (...)
App->"ANGLE Front-end": glAttachShader (...)
App->"ANGLE Front-end": glLinkProgram
"ANGLE Front-end"->"Vulkan Back-end": ProgramVk::link
Note right of "Vulkan Back-end": ProgramVk inits uniforms,\nlayouts, and descriptors.
"Vulkan Back-end"->GlslangWrapper: GlslangWrapper::GetShaderSource
GlslangWrapper-->"Vulkan Back-end": return filled-in sources
Note right of "Vulkan Back-end": Source is templated with\ndefines to be resolved at\ndraw time.
"Vulkan Back-end"-->"ANGLE Front-end": return success
Note right of App: App execution continues...
App->"ANGLE Front-end": glDrawArrays (any draw)
"ANGLE Front-end"->"Vulkan Back-end": ContextVk::drawArrays
"Vulkan Back-end"->GlslangWrapper: GlslangWrapper::GetShaderCode (with defines)
GlslangWrapper->Glslang: GlslangToSpv
Glslang-->"Vulkan Back-end": Return SPIR-V
Note right of "Vulkan Back-end": We init VkShaderModules\nand VkPipeline then\nrecord the draw.
"Vulkan Back-end"-->"ANGLE Front-end": return success
]]></source><desc></desc><defs><marker viewBox="0 0 5 5" markerWidth="5" markerHeight="5" orient="auto" refX="5" refY="2.5" id="markerArrowBlock"><path d="M 0 0 L 5 2.5 L 0 5 z"></path></marker><marker viewBox="0 0 9.6 16" markerWidth="4" markerHeight="16" orient="auto" refX="9.6" refY="8" id="markerArrowOpen"><path d="M 9.6,8 1.92,16 0,13.7 5.76,8 0,2.286 1.92,0 9.6,8 z"></path></marker></defs><g class="title"></g><g class="actor"><rect x="10" y="20" width="47.59375" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="21" y="45" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="20">App</tspan></text></g><g class="actor"><rect x="10" y="1170.359375" width="47.59375" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="21" y="1195.359375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="20">App</tspan></text></g><line x1="33.796875" x2="33.796875" y1="59" y2="1170.359375" stroke="#000000" fill="none" style="stroke-width: 2;"></line><g class="actor"><rect x="237.0390625" y="20" width="152.953125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="248.0390625" y="45" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="247.0390625">ANGLE Front-end</tspan></text></g><g class="actor"><rect x="237.0390625" y="1170.359375" width="152.953125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="248.0390625" y="1195.359375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="247.0390625">ANGLE Front-end</tspan></text></g><line x1="313.515625" x2="313.515625" y1="59" y2="1170.359375" stroke="#000000" fill="none" style="stroke-width: 2;"></line><g class="actor"><rect x="462.9765625" y="20" width="152.953125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="473.9765625" y="45" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="472.9765625">Vulkan Back-end</tspan></text></g><g class="actor"><rect x="462.9765625" y="1170.359375" width="152.953125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="473.9765625" y="1195.359375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="472.9765625">Vulkan Back-end</tspan></text></g><line x1="539.453125" x2="539.453125" y1="59" y2="1170.359375" stroke="#000000" fill="none" style="stroke-width: 2;"></line><g class="actor"><rect x="728.3984375" y="20" width="161.953125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="739.3984375" y="45" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="738.3984375">ANGLE Translator</tspan></text></g><g class="actor"><rect x="728.3984375" y="1170.359375" width="161.953125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="739.3984375" y="1195.359375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="738.3984375">ANGLE Translator</tspan></text></g><line x1="809.375" x2="809.375" y1="59" y2="1170.359375" stroke="#000000" fill="none" style="stroke-width: 2;"></line><g class="actor"><rect x="910.3515625" y="20" width="143.359375" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="920.3515625" y="45" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="920.3515625">GlslangWrapper</tspan></text></g><g class="actor"><rect x="910.3515625" y="1170.359375" width="143.359375" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="920.3515625" y="1195.359375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="920.3515625">GlslangWrapper</tspan></text></g><line x1="982.03125" x2="982.03125" y1="59" y2="1170.359375" stroke="#000000" fill="none" style="stroke-width: 2;"></line><g class="actor"><rect x="1073.7109375" y="20" width="81.78125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="1083.7109375" y="45" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="1083.7109375">Glslang</tspan></text></g><g class="actor"><rect x="1073.7109375" y="1170.359375" width="81.78125" height="39" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="1083.7109375" y="1195.359375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="1083.7109375">Glslang</tspan></text></g><line x1="1114.6015625" x2="1114.6015625" y1="59" y2="1170.359375" stroke="#000000" fill="none" style="stroke-width: 2;"></line><g class="signal"><text x="85.6875" y="89.5" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="85.6875">glCompileShader (VS)</tspan></text><line x1="33.796875" x2="313.515625" y1="98" y2="98" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="351.609375" y="128.5" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="351.609375">ShaderVk::compile</tspan></text><line x1="313.515625" x2="539.453125" y1="137" y2="137" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="625.9296875" y="167.5" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="625.9296875">sh::Compile</tspan></text><line x1="539.453125" x2="809.375" y1="176" y2="176" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="433.890625" y="206.5" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="433.890625">return Vulkan-compatible GLSL</tspan></text><line x1="809.375" x2="313.515625" y1="215" y2="215" stroke="#000000" fill="none" style="stroke-width: 2; stroke-dasharray: 6, 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="note"><rect x="333.515625" y="235" width="185.9375" height="67.390625" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="338.515625" y="255" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="338.515625">Source is templated</tspan><tspan dy="1.2em" x="338.515625">with markers to be</tspan><tspan dy="1.2em" x="338.515625">filled at link time.</tspan></text></g><g class="note"><rect x="53.796875" y="322.390625" width="212.328125" height="29" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="58.796875" y="342.390625" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="58.796875">Same for FS, GS, etc...</tspan></text></g><g class="signal"><text x="81.2890625" y="381.890625" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="81.2890625">glCreateProgram (...)</tspan></text><line x1="33.796875" x2="313.515625" y1="390.390625" y2="390.390625" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="85.6875" y="420.890625" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="85.6875">glAttachShader (...)</tspan></text><line x1="33.796875" x2="313.515625" y1="429.390625" y2="429.390625" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="116.375" y="459.890625" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="116.375">glLinkProgram</tspan></text><line x1="33.796875" x2="313.515625" y1="468.390625" y2="468.390625" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="360.40625" y="498.890625" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="360.40625">ProgramVk::link</tspan></text><line x1="313.515625" x2="539.453125" y1="507.390625" y2="507.390625" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="note"><rect x="559.453125" y="527.390625" width="229.921875" height="48.1875" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="564.453125" y="547.390625" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="564.453125">ProgramVk inits uniforms,</tspan><tspan dy="1.2em" x="564.453125">layouts, and descriptors.</tspan></text></g><g class="signal"><text x="624.2890625" y="606.078125" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="624.2890625">GlslangWrapper::GetShaderSource</tspan></text><line x1="539.453125" x2="982.03125" y1="614.578125" y2="614.578125" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="655.1796875" y="645.078125" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="655.1796875">return filled-in sources</tspan></text><line x1="982.03125" x2="539.453125" y1="653.578125" y2="653.578125" stroke="#000000" fill="none" style="stroke-width: 2; stroke-dasharray: 6, 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="note"><rect x="559.453125" y="673.578125" width="229.921875" height="67.390625" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="564.453125" y="693.578125" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="564.453125">Source is templated with</tspan><tspan dy="1.2em" x="564.453125">defines to be resolved at</tspan><tspan dy="1.2em" x="564.453125">draw time.</tspan></text></g><g class="signal"><text x="364.90625" y="771.46875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="364.90625">return success</tspan></text><line x1="539.453125" x2="313.515625" y1="779.96875" y2="779.96875" stroke="#000000" fill="none" style="stroke-width: 2; stroke-dasharray: 6, 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="note"><rect x="53.796875" y="799.96875" width="239.71875" height="29" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="59.796875" y="819.96875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="58.796875">App execution continues...</tspan></text></g><g class="signal"><text x="72.4921875" y="859.46875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="72.4921875">glDrawArrays (any draw)</tspan></text><line x1="33.796875" x2="313.515625" y1="867.96875" y2="867.96875" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="334.1171875" y="898.46875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="334.1171875">ContextVk::drawArrays</tspan></text><line x1="313.515625" x2="539.453125" y1="906.96875" y2="906.96875" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="567.2109375" y="937.46875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="567.2109375">GlslangWrapper::GetShaderCode (with defines)</tspan></text><line x1="539.453125" x2="982.03125" y1="945.96875" y2="945.96875" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="995.43359375" y="976.46875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="995.43359375">GlslangToSpv</tspan></text><line x1="982.03125" x2="1114.6015625" y1="984.96875" y2="984.96875" stroke="#000000" fill="none" style="stroke-width: 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="signal"><text x="769.24609375" y="1015.46875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="769.24609375">Return SPIR-V</tspan></text><line x1="1114.6015625" x2="539.453125" y1="1023.96875" y2="1023.96875" stroke="#000000" fill="none" style="stroke-width: 2; stroke-dasharray: 6, 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g><g class="note"><rect x="559.453125" y="1043.96875" width="212.328125" height="67.390625" stroke="#000000" fill="#ffffff" style="stroke-width: 2;"></rect><text x="564.453125" y="1063.96875" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="564.453125">We init VkShaderModules</tspan><tspan dy="1.2em" x="564.453125">and VkPipeline then</tspan><tspan dy="1.2em" x="564.453125">record the draw.</tspan></text></g><g class="signal"><text x="364.90625" y="1141.859375" style="font-size: 16px; font-family: &quot;Andale Mono&quot;, monospace;"><tspan x="364.90625">return success</tspan></text><line x1="539.453125" x2="313.515625" y1="1150.359375" y2="1150.359375" stroke="#000000" fill="none" style="stroke-width: 2; stroke-dasharray: 6, 2; marker-end: url(&quot;#markerArrowBlock&quot;);"></line></g></svg>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment