There is content that relies on gather to have RTE semantics similar to LINEAR filtering, fwiw, and failing that leads to broken graphics. AMD's CACAO demo is a good example of this. The specification also states that GATHER picks the same samples that would be selected from a LINEAR filter operation.
This effect is observable on a GPU which supports sparse residency, since you can construct a test that requires the rounding for LINEAR and GATHER to work the same way when querying residency status on the edge of a page.
I think this can be understood to mean that GATHER should round, similar to LINEAR. NVIDIA has this behavior by default, and on RADV we modify the SGPR to force sub-texel rounding for GATHER.
If Turnip cannot pick the rounding on instruction time, the suggestion I think is to just force D3D-style rounding on samplers in DXVK/vkd3d-proton mode. If that cannot be done, we'll need an extension to control this behavior.
Adreno supports toggling between these two types of behavior through a register flag.
Turnip change is in Mesa's MR33987. Only change needed in vkd3d would be making PointSamplingAddressesNeverRoundUp also true for Turnip.
I think vkd3d-proton is reporting the correct property as-is.
Mesa change landed. Since Turnip now uses round-to-even when calculating unnormalized texture coordinates, my understanding is that PointSamplingAddressesNeverRoundUp should not be exposed for Turnip. That change is in PR https://github.com/HansKristian-Work/vkd3d-proton/pull/2431.
Software information
The
test_sampler_roundingunit test has a few subtests that fail on Turnip. The tests are run on a 2x1 texture where the left pixel is transparent and the right pixel is opaque.Gather
Two subtests (indices 2 and 3) covering gather operation fail because of how the selected texels are determined. With unnormalized texture coordinates, my understanding is that D3D will subtract
0.5fbefore converting those coordinates to16.8fixed-point values. After the conversion the integer part will be used as the base texel position in a given coordinate axis.Vulkan's texel selection (16.6.1) for gather operation doesn't require conversion to fixed-point. Turnip behaves accordingly.
The two subtests essentially check when the gathered texels will shift from including both left and right pixels to including only the right pixel. For D3D, because of the rounding-to-nearest behavior during conversion to
16.8fixed-point, this would happen already for coordinate values that are close but still less than1.5. On Turnip, this will happen when the unnormalized coordinate is1.5or larger, which matches the existinguse_warp_devicecodepath.Linear filtering
This subtest (index 1) fails on Turnip because of Adreno's sampler behavior when performing linear filtering (16.8.3). The fraction parts of the unnormalized and shift-adjusted values are used as weights by which each texel is multiplied.
Examining the output values with Turnip, Adreno sampler does seem to use conversion of weight values to
16.8fixed-point in order to compute the linear sample value, but unlike D3D's float-to-fixed-point conversion it floors the value when converting it to integer, instead of rounding it. Vulkan doesn't require rounding (3.10.2).System information