radv: Use TRUNC_COORD on samplers
authorJoshua Ashton <joshua@froggi.es>
Tue, 25 Feb 2020 19:24:15 +0000 (19:24 +0000)
committerMarge Bot <eric+marge@anholt.net>
Thu, 23 Apr 2020 09:57:08 +0000 (09:57 +0000)
The default behaviour (0) is: "round-nearest-even to n.6 and drop fraction when point sampling" whereas the Vulkan spec simply wants us to floor it (1) "truncate when point sampling".

See 15.6.1 in the Vulkan spec.
https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#textures-normalized-operations

The Direct3D spec also mandates this (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#7.18.7%20Point%20Sample%20Addressing)

This fixes some point-sampling texture precision issues in some Direct3D 9 titles such as Guild Wars 2 and htoL#NiQ: The Firefly Diary that are not present on other vendors.

Fixes dEQP-VK.pipeline.sampler.exact_sampling.*

https://github.com/Joshua-Ashton/d9vk/issues/450
https://github.com/doitsujin/dxvk/issues/1433

CC: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3951>

src/amd/vulkan/radv_device.c

index 8e4fc861722f6fc1c8aa12b2a5a38ab24056dda4..4bfcbb1c0babed66dcddfec0f97a5a1e0ed0f5e6 100644 (file)
@@ -7054,6 +7054,7 @@ radv_init_sampler(struct radv_device *device,
                           device->physical_device->rad_info.chip_class == GFX9;
        unsigned filter_mode = V_008F30_SQ_IMG_FILTER_MODE_BLEND;
        unsigned depth_compare_func = V_008F30_SQ_TEX_DEPTH_COMPARE_NEVER;
+       bool trunc_coord = pCreateInfo->minFilter == VK_FILTER_NEAREST && pCreateInfo->magFilter == VK_FILTER_NEAREST;
 
        const struct VkSamplerReductionModeCreateInfo *sampler_reduction =
                vk_find_struct_const(pCreateInfo->pNext,
@@ -7074,7 +7075,8 @@ radv_init_sampler(struct radv_device *device,
                             S_008F30_ANISO_BIAS(max_aniso_ratio) |
                             S_008F30_DISABLE_CUBE_WRAP(0) |
                             S_008F30_COMPAT_MODE(compat_mode) |
-                            S_008F30_FILTER_MODE(filter_mode));
+                            S_008F30_FILTER_MODE(filter_mode) |
+                            S_008F30_TRUNC_COORD(trunc_coord));
        sampler->state[1] = (S_008F34_MIN_LOD(S_FIXED(CLAMP(pCreateInfo->minLod, 0, 15), 8)) |
                             S_008F34_MAX_LOD(S_FIXED(CLAMP(pCreateInfo->maxLod, 0, 15), 8)) |
                             S_008F34_PERF_MIP(max_aniso_ratio ? max_aniso_ratio + 6 : 0));