How sparseTextureGatherARB Works in GLSL
The sparseTextureGatherARB function is a specialized
GLSL built-in provided by the GL_ARB_sparse_texture and
GL_ARB_sparse_texture2 extensions that samples a 2x2
footprint of neighboring texels from a sparse virtual texture. Unlike
standard texture gathering, it accounts for partially committed or
unallocated virtual memory pages by returning an execution status code
alongside the texel data. This article explains how the function fetches
these neighboring components, how residency is validated, and how to
safely handle partially resident data.
The Mechanics of Texture Gathering
In standard OpenGL, textureGather retrieves the four
specific texels that would otherwise be blended during bilinear
interpolation for a given texture coordinate. Rather than filtering the
samples into a single color, it returns a four-component vector
(vec4) containing one specific component (defaulting to the
red channel) from each of the four neighboring texels:
- x: Texel at coordinate \([i, j+1]\)
- y: Texel at coordinate \([i+1, j+1]\)
- z: Texel at coordinate \([i+1, j]\)
- w: Texel at coordinate \([i, j]\)
sparseTextureGatherARB performs this exact spatial
lookup, but adapts the output mechanism to support sparse virtual
textures, where large regions of the texture might not be backed by
physical GPU memory.
Signature and Residency Return Value
Because a sparse texture might reference uncommitted pages,
sparseTextureGatherARB cannot return the texel data
directly as the function's return value. Instead, the function returns
an integer residency code, while the four fetched texels are written to
an out parameter.
A typical GLSL declaration looks like this:
int sparseTextureGatherARB(
sampler2D sampler,
vec2 P,
out vec4 texels,
[int comp]
);The function accepts the sampler, the lookup coordinate
P, the out vector to receive the four texel
values, and an optional component selector comp (0 for red,
1 for green, 2 for blue, 3 for alpha).
Evaluating Page Residency
When sparseTextureGatherARB executes, the GPU checks the
page table for the physical pages corresponding to all four texel
addresses.
- Full Residency: If all four texels lie within
committed memory pages, the function writes their respective values into
the
texelsvector and returns a residency code that evaluates to true. - Partial or Complete Absence: If any of the four neighboring texels fall on an unallocated (uncommitted) virtual page, the returned residency code marks the fetch as incomplete. Any texel falling on an uncommitted page will return an implementation-dependent value (commonly zero), while committed texels among the four still receive their real values.
To evaluate whether the retrieved data is safe to use, pass the
returned integer code into the built-in
sparseTexelsResidentARB function:
vec4 gatheredTexels;
int code = sparseTextureGatherARB(sparseSampler, uv, gatheredTexels, 0);
if (sparseTexelsResidentARB(code)) {
// All 4 neighboring texels are resident in physical memory
processGatheredData(gatheredTexels);
} else {
// At least one texel was uncommitted; handle missing data or fallback
handleUnresidentTexels(gatheredTexels);
}Use Cases and Edge Cases
Because sparseTextureGatherARB retrieves a multi-texel
footprint across arbitrary texel boundaries, the footprint frequently
straddles the boundary between a committed page and an uncommitted
page.
In custom filtering, shadow mapping, or screen-space ambient
occlusion algorithms, using sparseTextureGatherARB reduces
texture lookup instructions by 75% compared to individual fetches.
However, developers must account for the fact that
sparseTexelsResidentARB(code) returns false if
even a single sample out of the four is missing. When the residency test
fails, shaders typically request a lower-detail mipmap level (which is
more likely to be fully resident) or fall back to procedural default
values.