ANGLE converts application shaders into Vulkan VkShaderModules through a series of steps:
ANGLE Internal Translation: The initial calls to glCompileShader
are passed to the ANGLE shader translator. The translator compiles application shaders into Vulkan-compatible GLSL. Vulkan-compatible GLSL matches the 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. After initial compilation the shaders are not complete. They are templated with markers that are filled in later at link time.
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 GlslangWrapperVk helper class. We still cannot generate VkShaderModules
since some ANGLE features like OpenGL line rasterization emulation depend on draw-time information.
Draw-time SPIR-V Generation: Once the application records a draw call we use Khronos' glslang to convert the Vulkan-compatible GLSL into SPIR-V. The SPIR-V is then compiled into VkShaderModules
. For details please see GlslangWrapperVk.cpp. The VkShaderModules
are then used by VkPipelines
with the appropriate specialization constant values. Note that we currently don't use 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: