How GLSL Discard Terminates Fragment Processing

In OpenGL Shading Language (GLSL), the discard keyword provides a mechanism to unconditionally abandon the processing of the current fragment during the execution of a fragment shader. This article explains the functional mechanics of the discard statement, how it halts data output to the framebuffer, its underlying behavior within GPU execution pipelines, and its performance implications regarding depth testing.

When the execution flow of a fragment shader encounters the discard statement, the current fragment is permanently eliminated from the rendering pipeline. The graphics pipeline ensures that no fragment outputs—such as color values, depth values, or stencil modifications—are committed to the bound framebuffer attachments. From the logical perspective of the rendering output, the fragment simply ceases to exist, leaving previously rendered pixels or the background color unaltered.

At the hardware execution level, "immediate termination" behaves with specific nuances due to the Single Instruction, Multiple Threads (SIMT) architecture of modern GPUs. GPUs execute fragment shaders in parallel groups of threads, commonly referred to as warps or wavefronts (typically 32 to 64 threads). When one thread in a warp hits a discard instruction:

  1. Output Masking: The GPU marks the executing thread as inactive for subsequent memory writes. Even if execution continues, the results generated by that thread are discarded and will never be written to render targets.
  2. Lockstep Execution: Because threads within a warp execute instructions in lockstep, the physical thread may continue executing dummy or masked instructions alongside active neighbor threads until the entire warp finishes, unless all threads in that warp have hit a discard or reached an exit point.
  3. Derivative Calculations: Downstream operations that depend on neighboring fragment information, such as implicit level-of-detail (LoD) texture fetches using finite differences (dFdx and dFdy), can be disrupted if discarded fragments terminate abruptly. Hardware often maintains discarded fragments as "helper invocations" to provide valid data for neighboring active pixels requiring partial derivative computations.

The presence of a discard keyword within a fragment shader also alters pre-fragment pipeline stages, most notably Early Depth Testing (Early-Z). Normally, GPUs test and write depth before running the fragment shader to eliminate occluded pixels early. Because the GPU cannot predict whether a fragment will evaluate a conditional branch leading to discard, Early-Z writes are generally disabled. The pipeline must delay depth and stencil writes until the fragment shader finishes to avoid leaving "holes" in the depth buffer from fragments that are ultimately dropped.

In summary, the GLSL discard statement stops a fragment from producing any visible impact on the framebuffer by masking all subsequent pipeline outputs, converting the thread to an inactive or helper state within its warp, and deferring standard depth and stencil operations until execution concludes.