How subgroupQuadSwapDiagonal Works in GLSL
The GLSL intrinsic subgroupQuadSwapDiagonal() exchanges
data between diagonally opposing invocations inside a four-invocation
subgroup quad. In modern GPU architectures, invocations are often
grouped into 2x2 execution quads to compute derivatives and manage
texture sampling. This function allows a thread to read a variable
evaluated by its diagonal neighbor within the same quad without
requiring shared memory or explicit barrier synchronization,
significantly speeding up cross-lane data exchange.
Quad Organization and Lane Mapping
A subgroup quad consists of four invocations arranged in a 2x2
matrix, defined by local quad indices 0, 1,
2, and 3. In standard row-major arrangement,
the quad is laid out as follows:
- Lane 0: Top-left coordinate
(x, y) - Lane 1: Top-right coordinate
(x + 1, y) - Lane 2: Bottom-left coordinate
(x, y + 1) - Lane 3: Bottom-right coordinate
(x + 1, y + 1)
The Diagonal Swap Mechanism
subgroupQuadSwapDiagonal() performs an exchange across
the diagonal axes. When called, the target lane index for invocation
\(i\) is calculated using a bitwise XOR
operation with 3 (0b11):
- Lane 0 reads the value from Lane 3 (\(0 \oplus 3 = 3\))
- Lane 3 reads the value from Lane 0 (\(3 \oplus 3 = 0\))
- Lane 1 reads the value from Lane 2 (\(1 \oplus 3 = 2\))
- Lane 2 reads the value from Lane 1 (\(2 \oplus 3 = 1\))
Because both the horizontal bit (bit 0) and the vertical bit (bit 1)
are inverted simultaneously, the operation acts as a composite of
subgroupQuadSwapHorizontal() and
subgroupQuadSwapVertical().
Hardware Execution and Requirements
Under the hood, GPU hardware uses shuffle registers to transfer data
across execution lanes within the SIMD warp or wavefront. Because quads
execute concurrently in lockstep,
subgroupQuadSwapDiagonal() does not require memory
barriers, write flushes, or cache access.
To use this function, the extension
GL_KHR_shader_subgroup_quad must be enabled in the shader.
In compute or mesh shaders, developers must ensure that the thread
dispatch dimensions map to coherent 2x2 invocation clusters. In fragment
shaders, threads are naturally dispatched in 2x2 quads corresponding to
screen-space pixel coordinates.
Use Cases
This operation is primarily used in screen-space processing algorithms, including:
- Custom Derivatives: Computing diagonal finite differences \(\frac{\partial^2 f}{\partial x \partial y}\) to approximate surface curvature.
- Anti-Aliasing and Filtering: Performing 2x2 tent filters, edge-detecting bilateral filters, or normal comparisons with minimal register overhead.
- Quad-Level Reductions: Gathering maximum, minimum, or average values across all four quad members in fewer shuffle cycles than standard linear reductions.