vkd3d: Implement sampler min/max reduction filtering.

This commit is contained in:
Conor McCarthy
2023-08-18 00:17:02 +10:00
committed by Henri Verbeet
parent dc7cdec9a5
commit cb8da3125b
Notes: Henri Verbeet 2025-11-26 17:14:34 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1846
4 changed files with 62 additions and 14 deletions

View File

@@ -109,6 +109,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(EXT_FRAGMENT_SHADER_INTERLOCK, EXT_fragment_shader_interlock),
VK_EXTENSION(EXT_MUTABLE_DESCRIPTOR_TYPE, EXT_mutable_descriptor_type),
VK_EXTENSION(EXT_ROBUSTNESS_2, EXT_robustness2),
VK_EXTENSION(EXT_SAMPLER_FILTER_MINMAX, EXT_sampler_filter_minmax),
VK_EXTENSION(EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION, EXT_shader_demote_to_helper_invocation),
VK_EXTENSION(EXT_SHADER_STENCIL_EXPORT, EXT_shader_stencil_export),
VK_EXTENSION(EXT_SHADER_VIEWPORT_INDEX_LAYER, EXT_shader_viewport_index_layer),
@@ -835,6 +836,7 @@ struct vkd3d_physical_device_info
/* properties */
VkPhysicalDeviceDescriptorIndexingPropertiesEXT descriptor_indexing_properties;
VkPhysicalDeviceMaintenance3Properties maintenance3_properties;
VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT filter_minmax_properties;
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties;
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties;
@@ -900,6 +902,8 @@ static void vkd3d_chain_physical_device_info_structures(struct vkd3d_physical_de
vk_prepend_struct(&info->properties2, &info->maintenance3_properties);
if (vulkan_info->EXT_descriptor_indexing)
vk_prepend_struct(&info->properties2, &info->descriptor_indexing_properties);
if (vulkan_info->EXT_sampler_filter_minmax)
vk_prepend_struct(&info->properties2, &info->filter_minmax_properties);
if (vulkan_info->EXT_texel_buffer_alignment)
vk_prepend_struct(&info->properties2, &info->texel_buffer_alignment_properties);
if (vulkan_info->EXT_transform_feedback)
@@ -936,6 +940,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
info->maintenance3_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
info->descriptor_indexing_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
info->filter_minmax_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT;
info->texel_buffer_alignment_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT;
info->xfb_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
info->vertex_divisor_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
@@ -1017,6 +1022,7 @@ static void vkd3d_trace_physical_device_limits(const struct vkd3d_physical_devic
const VkPhysicalDeviceLimits *limits = &info->properties2.properties.limits;
const VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing;
const VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment;
const VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *minmax;
const VkPhysicalDeviceMaintenance3Properties *maintenance3;
const VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb;
@@ -1196,6 +1202,11 @@ static void vkd3d_trace_physical_device_limits(const struct vkd3d_physical_devic
TRACE(" maxPerSetDescriptors: %u.\n", maintenance3->maxPerSetDescriptors);
TRACE(" maxMemoryAllocationSize: %#"PRIx64".\n", maintenance3->maxMemoryAllocationSize);
minmax = &info->filter_minmax_properties;
TRACE(" VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT:\n");
TRACE(" filterMinmaxSingleComponentFormats: %#x.\n", minmax->filterMinmaxSingleComponentFormats);
TRACE(" filterMinmaxImageComponentMapping: %#x.\n", minmax->filterMinmaxImageComponentMapping);
buffer_alignment = &info->texel_buffer_alignment_properties;
TRACE(" VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT:\n");
TRACE(" storageTexelBufferOffsetAlignmentBytes: %#"PRIx64".\n",
@@ -1866,6 +1877,12 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
physical_device_info->formats4444_features.formatA4B4G4R4 = VK_FALSE;
if (!vulkan_info->EXT_sampler_filter_minmax)
WARN("Sampler min/max reduction filtering is not supported.\n");
else if (!physical_device_info->filter_minmax_properties.filterMinmaxSingleComponentFormats
|| !physical_device_info->filter_minmax_properties.filterMinmaxImageComponentMapping)
WARN("Sampler min/max reduction filtering is only partially supported.");
vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties;
if (get_spec_version(vk_extensions, vk_extension_count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3)

View File

@@ -3661,6 +3661,24 @@ bool vkd3d_create_raw_buffer_view(struct d3d12_device *device,
}
/* samplers */
static VkSamplerReductionModeEXT vk_reduction_mode_from_d3d12(D3D12_FILTER_REDUCTION_TYPE mode)
{
switch (mode)
{
case D3D12_FILTER_REDUCTION_TYPE_STANDARD:
case D3D12_FILTER_REDUCTION_TYPE_COMPARISON:
return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
case D3D12_FILTER_REDUCTION_TYPE_MINIMUM:
return VK_SAMPLER_REDUCTION_MODE_MIN;
case D3D12_FILTER_REDUCTION_TYPE_MAXIMUM:
return VK_SAMPLER_REDUCTION_MODE_MAX;
default:
FIXME("Unhandled reduction mode %#x.\n", mode);
return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
}
}
static VkFilter vk_filter_from_d3d12(D3D12_FILTER_TYPE type)
{
switch (type)
@@ -3734,16 +3752,13 @@ static VkResult d3d12_create_sampler(struct d3d12_device *device, D3D12_FILTER f
D3D12_COMPARISON_FUNC comparison_func, D3D12_STATIC_BORDER_COLOR border_colour,
float min_lod, float max_lod, VkSampler *vk_sampler)
{
VkSamplerReductionModeCreateInfoEXT reduction_desc;
const struct vkd3d_vk_device_procs *vk_procs;
struct VkSamplerCreateInfo sampler_desc;
VkResult vr;
vk_procs = &device->vk_procs;
if (D3D12_DECODE_FILTER_REDUCTION(filter) == D3D12_FILTER_REDUCTION_TYPE_MINIMUM
|| D3D12_DECODE_FILTER_REDUCTION(filter) == D3D12_FILTER_REDUCTION_TYPE_MAXIMUM)
FIXME("Min/max reduction mode not supported.\n");
sampler_desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_desc.pNext = NULL;
sampler_desc.flags = 0;
@@ -3767,6 +3782,21 @@ static VkResult d3d12_create_sampler(struct d3d12_device *device, D3D12_FILTER f
|| address_w == D3D12_TEXTURE_ADDRESS_MODE_BORDER)
sampler_desc.borderColor = vk_border_colour_from_d3d12(border_colour);
reduction_desc.reductionMode = vk_reduction_mode_from_d3d12(D3D12_DECODE_FILTER_REDUCTION(filter));
if (reduction_desc.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE)
{
if (device->vk_info.EXT_sampler_filter_minmax)
{
reduction_desc.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT;
reduction_desc.pNext = NULL;
vk_prepend_struct(&sampler_desc, &reduction_desc);
}
else
{
FIXME("Sampler min/max reduction filtering is not supported by the device.\n");
}
}
if ((vr = VK_CALL(vkCreateSampler(device->vk_device, &sampler_desc, NULL, vk_sampler))) < 0)
WARN("Failed to create Vulkan sampler, vr %d.\n", vr);

View File

@@ -144,6 +144,7 @@ struct vkd3d_vulkan_info
bool EXT_fragment_shader_interlock;
bool EXT_mutable_descriptor_type;
bool EXT_robustness2;
bool EXT_sampler_filter_minmax;
bool EXT_shader_demote_to_helper_invocation;
bool EXT_shader_stencil_export;
bool EXT_shader_viewport_index_layer;