SPIR-V Execution Mode for early_fragment_tests
This article identifies the specific SPIR-V execution mode that
corresponds to the GLSL layout(early_fragment_tests) in;
layout qualifier, explaining how it is represented in the SPIR-V binary
and how it alters standard GPU pipeline operations. It also covers the
functional implications of enforcing early fragment testing, including
its impact on depth testing, stencil operations, and fragment shader
invocations.
The GLSL declaration layout(early_fragment_tests) in;
directly maps to the SPIR-V execution mode
EarlyFragmentTests.
In SPIR-V, execution modes define the operational constraints and
behaviors of an entry point within an execution model. When translating
a GLSL fragment shader with early fragment tests enabled, the compiler
generates an OpExecutionMode instruction targeting the
fragment shader's entry point:
OpExecutionMode %entry_point EarlyFragmentTests
Purpose and Pipeline Behavior
Under the standard graphics pipeline model, the fragment shader
executes before per-fragment operations such as depth and stencil
testing. While modern GPUs often perform proprietary optimizations (like
hardware early-Z) to discard fragments before shading, these
optimizations are automatically disabled if the fragment shader writes
to depth (gl_FragDepth), modifies stencil values, or
includes side effects like arbitrary image or buffer writes.
Declaring EarlyFragmentTests explicitly forces depth and
stencil testing to occur strictly before the execution of the fragment
shader. If a fragment fails the depth or stencil test, the fragment
shader invocation is discarded completely.
Technical Implications
- Shader Invocations: Fragments that do not pass the depth and stencil buffers will never execute the fragment shader, saving computational resources on occluded geometry.
- Side Effects: Any operations with side effects—such as storage buffer writes (SSBOs), atomic operations, or image load/store functions—will only run for fragments that have already survived the depth and stencil tests.
- Restrictions: The shader must not conditionally
override depth in a way that contradicts early testing; writing to
gl_FragDepthwhile usingEarlyFragmentTestsis either restricted or strictly validated depending on the graphics API specification in use (such as Vulkan or OpenGL).