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

  1. Shader Invocations: Fragments that do not pass the depth and stencil buffers will never execute the fragment shader, saving computational resources on occluded geometry.
  2. 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.
  3. Restrictions: The shader must not conditionally override depth in a way that contradicts early testing; writing to gl_FragDepth while using EarlyFragmentTests is either restricted or strictly validated depending on the graphics API specification in use (such as Vulkan or OpenGL).