Prefer to read without ads? Become a member — from $10/month — and support the work. Already a member? Log in to read ad-free on this device.

10.14 Texture Gather

Bilinear filtering returns a single weighted average of a 2×2 texel neighborhood, but some algorithms need the four texels themselves. Percentage-closer filtering of shadow maps is the classic example: it compares each of the four depths against a reference and averages the comparison results, not the depths. Custom and higher-order filters likewise want the raw neighborhood. tex2Dgather() provides exactly that—for the same 2×2 footprint a bilinear fetch would use, it returns the four texels of one channel as a float4, skipping the blend. It is the CUDA counterpart of OpenGL’s textureGather and Direct3D’s Gather, and is defined for 2D textures only.

Gather needs no special allocation—any 2D texture backed by a CUDA array supports it. The call adds a channel index comp (0 through 3, selecting which channel of an RGBA texture to gather; 0 for a single-channel texture). The four texels come back in a fixed order: writing the footprint’s origin texel as (c0,r0), the components (.x, .y, .z, .w) hold the texels at offsets (0,1), (1,1), (1,0), (0,0)—that is, (c0,r0+1), (c0+1,r0+1), (c0+1,r0), (c0,r0)—the same winding OpenGL and Direct3D use.

The microdemo tex2d_gather.cu makes both the footprint and the ordering visible. It fills a 4×4 texture so that each texel (col,row) holds a distinct value, row*4 + col, then gathers at several points and decodes each returned value back to its (col,row):

  gather (2.0,2.0):  .x=(1,2)=9   .y=(2,2)=10  .z=(2,1)=6   .w=(1,1)=5   footprint OK
  gather (3.0,2.0):  .x=(2,2)=10  .y=(3,2)=11  .z=(3,1)=7   .w=(2,1)=6   footprint OK
  gather (2.0,3.0):  .x=(1,3)=13  .y=(2,3)=14  .z=(2,2)=10  .w=(1,2)=9   footprint OK
  gather (1.0,1.0):  .x=(0,1)=4   .y=(1,1)=5   .z=(1,0)=1   .w=(0,0)=0   footprint OK

Each row lists the four footprint texels the coordinate selected, in the (.x, .y, .z, .w) order above, and the demo confirms the returned set is exactly that 2×2 neighborhood.