Understanding endInvocationInterlockARB in GLSL
This article explains the purpose and behavior of the
endInvocationInterlockARB function within OpenGL's
GL_ARB_fragment_shader_interlock extension. It covers how
this built-in GLSL function completes a synchronized critical section,
releases hardware execution locks, and optimizes fragment shader
throughput during operations like custom blending and order-independent
transparency.
In modern GPU rendering, fragments covering the exact same pixel or
sample location execute concurrently by default. This concurrency causes
race conditions when reading from, modifying, and writing back to memory
buffers or custom framebuffers. The
GL_ARB_fragment_shader_interlock extension introduces
critical sections to resolve these hazards, and
endInvocationInterlockARB serves as the explicit boundary
that closes this synchronized execution zone.
The primary function of endInvocationInterlockARB is to
release the per-pixel or per-sample mutual exclusion lock acquired
earlier in the shader by beginInvocationInterlockARB. Once
a fragment shader invocation executes
endInvocationInterlockARB, it notifies the GPU hardware
that it has finished its serialized operations. This action allows the
next waiting fragment invocation that maps to the same screen-space
coordinates to enter the critical section and execute its own
synchronized instructions.
Calling endInvocationInterlockARB transitions the
invocation back to regular parallel execution. Any instructions placed
after this call run concurrently with other invocations without ordering
guarantees. This design is critical for GPU performance. Serializing
code reduces GPU parallelism, so developers should keep the block
between beginInvocationInterlockARB and
endInvocationInterlockARB as brief as possible, containing
only the dependent read-modify-write logic. Any heavy mathematical
calculations, lighting evaluations, or texture fetches that do not
depend on the shared state should be kept outside these boundaries.
GLSL enforces strict control flow requirements regarding the
placement of endInvocationInterlockARB. A shader invocation
must execute endInvocationInterlockARB at most once, and
only after beginInvocationInterlockARB has already been
executed within the same dynamic control path. Calling it inside
non-uniform conditional branches or loops that cause divergence between
invocations can lead to undefined behavior or hardware deadlocks.