From 31ced4c5ad2efcbaf70357c2ef42eeae15caafcb Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 20 Apr 2023 10:38:49 -0700 Subject: [PATCH] dzn: Support aniso-with-point-mip samplers Also rework the sampler translation logic to take advantage of the fact that the D3D12 filter types are bitfields. No need to loop over a sparse enum space like we were doing. Part-of: --- src/microsoft/vulkan/dzn_device.c | 2 +- src/microsoft/vulkan/dzn_private.h | 3 +- src/microsoft/vulkan/dzn_util.c | 77 ++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 43 deletions(-) diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c index 1e022c3..860f3ca 100644 --- a/src/microsoft/vulkan/dzn_device.c +++ b/src/microsoft/vulkan/dzn_device.c @@ -3245,7 +3245,7 @@ dzn_sampler_create(struct dzn_device *device, /* TODO: have a sampler pool to allocate shader-invisible descs which we * can copy to the desc_set when UpdateDescriptorSets() is called. */ - sampler->desc.Filter = dzn_translate_sampler_filter(pCreateInfo); + sampler->desc.Filter = dzn_translate_sampler_filter(pdev, pCreateInfo); sampler->desc.AddressU = dzn_sampler_translate_addr_mode(pCreateInfo->addressModeU); sampler->desc.AddressV = dzn_sampler_translate_addr_mode(pCreateInfo->addressModeV); sampler->desc.AddressW = dzn_sampler_translate_addr_mode(pCreateInfo->addressModeW); diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 3a93b5d..56f0970 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -1197,7 +1197,8 @@ struct dzn_sampler { DXGI_FORMAT dzn_pipe_to_dxgi_format(enum pipe_format in); DXGI_FORMAT dzn_get_typeless_dxgi_format(DXGI_FORMAT in); -D3D12_FILTER dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info); +D3D12_FILTER dzn_translate_sampler_filter(const struct dzn_physical_device *pdev, + const VkSamplerCreateInfo *create_info); D3D12_COMPARISON_FUNC dzn_translate_compare_op(VkCompareOp in); void dzn_translate_viewport(D3D12_VIEWPORT *out, const VkViewport *in); void dzn_translate_rect(D3D12_RECT *out, const VkRect2D *in); diff --git a/src/microsoft/vulkan/dzn_util.c b/src/microsoft/vulkan/dzn_util.c index e8fe29e..cd0591e 100644 --- a/src/microsoft/vulkan/dzn_util.c +++ b/src/microsoft/vulkan/dzn_util.c @@ -208,54 +208,49 @@ dzn_get_typeless_dxgi_format(DXGI_FORMAT in) return in; } -struct dzn_sampler_filter_info { - VkFilter min, mag; - VkSamplerMipmapMode mipmap; -}; - -#define FILTER(__min, __mag, __mipmap) \ -{ \ - .min = VK_FILTER_ ## __min, \ - .mag = VK_FILTER_ ## __mag, \ - .mipmap = VK_SAMPLER_MIPMAP_MODE_ ## __mipmap, \ +static D3D12_FILTER_TYPE +translate_filter_type(VkFilter type) +{ + switch (type) { + case VK_FILTER_NEAREST: return D3D12_FILTER_TYPE_POINT; + case VK_FILTER_LINEAR: return D3D12_FILTER_TYPE_LINEAR; + default: + assert(!"Unsupported filter mode"); + return D3D12_FILTER_TYPE_POINT; + } } -static const struct dzn_sampler_filter_info filter_table[] = { - [D3D12_FILTER_MIN_MAG_MIP_POINT] = FILTER(NEAREST, NEAREST, NEAREST), - [D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR] = FILTER(NEAREST, NEAREST, LINEAR), - [D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT] = FILTER(NEAREST, LINEAR, NEAREST), - [D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR] = FILTER(NEAREST, LINEAR, LINEAR), - [D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT] = FILTER(LINEAR, NEAREST, NEAREST), - [D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR] = FILTER(LINEAR, NEAREST, LINEAR), - [D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT] = FILTER(LINEAR, LINEAR, NEAREST), - [D3D12_FILTER_MIN_MAG_MIP_LINEAR] = FILTER(LINEAR, LINEAR, LINEAR), -}; +static D3D12_FILTER_TYPE +translate_mip_filter_type(VkSamplerMipmapMode type) +{ + switch (type) { + case VK_SAMPLER_MIPMAP_MODE_NEAREST: return D3D12_FILTER_TYPE_POINT; + case VK_SAMPLER_MIPMAP_MODE_LINEAR: return D3D12_FILTER_TYPE_LINEAR; + default: + assert(!"Unsupported filter mode"); + return D3D12_FILTER_TYPE_POINT; + } +} D3D12_FILTER -dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info) +dzn_translate_sampler_filter(const struct dzn_physical_device *pdev, + const VkSamplerCreateInfo *create_info) { - D3D12_FILTER filter = (D3D12_FILTER)0; - - if (!create_info->anisotropyEnable) { - unsigned i; - for (i = 0; i < ARRAY_SIZE(filter_table); i++) { - if (create_info->minFilter == filter_table[i].min && - create_info->magFilter == filter_table[i].mag && - create_info->mipmapMode == filter_table[i].mipmap) { - filter = (D3D12_FILTER)i; - break; - } - } - - assert(i < ARRAY_SIZE(filter_table)); - } else { - filter = D3D12_FILTER_ANISOTROPIC; + D3D12_FILTER_REDUCTION_TYPE reduction = create_info->compareEnable ? + D3D12_FILTER_REDUCTION_TYPE_COMPARISON : D3D12_FILTER_REDUCTION_TYPE_STANDARD; + + if (create_info->anisotropyEnable) { + if (create_info->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST && + pdev->options19.AnisoFilterWithPointMipSupported) + return D3D12_ENCODE_MIN_MAG_ANISOTROPIC_MIP_POINT_FILTER(reduction); + return D3D12_ENCODE_ANISOTROPIC_FILTER(reduction); } - if (create_info->compareEnable) - filter = (D3D12_FILTER)(filter + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT); - - return filter; + return D3D12_ENCODE_BASIC_FILTER( + translate_filter_type(create_info->minFilter), + translate_filter_type(create_info->magFilter), + translate_mip_filter_type(create_info->mipmapMode), + reduction); } D3D12_COMPARISON_FUNC -- 2.7.4