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.