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.

  1. Full Residency: If all four texels lie within committed memory pages, the function writes their respective values into the texels vector and returns a residency code that evaluates to true.
  2. 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.