mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d: Implement sampler min/max reduction filtering.
This commit is contained in:
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
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -45,19 +45,19 @@ filter minimum linear linear point
|
||||
|
||||
[test]
|
||||
draw quad
|
||||
todo(d3d12) probe (36, 20) f32(.25, .00, 0, 1)
|
||||
todo(d3d12) probe (20, 36) f32(.00, .25, 0, 1)
|
||||
todo(d3d12) probe (36, 36) f32(.25, .25, 0, 1)
|
||||
todo(d3d12) probe (52, 36) f32(.50, .25, 0, 1)
|
||||
todo(d3d12) probe (36, 52) f32(.25, .50, 0, 1)
|
||||
todo(mvk) probe (36, 20) f32(.25, .00, 0, 1)
|
||||
todo(mvk) probe (20, 36) f32(.00, .25, 0, 1)
|
||||
todo(mvk) probe (36, 36) f32(.25, .25, 0, 1)
|
||||
todo(mvk) probe (52, 36) f32(.50, .25, 0, 1)
|
||||
todo(mvk) probe (36, 52) f32(.25, .50, 0, 1)
|
||||
|
||||
[sampler 0]
|
||||
filter maximum linear linear point
|
||||
|
||||
[test]
|
||||
draw quad
|
||||
todo(d3d12) probe (36, 20) f32(.50, .25, 0, 1)
|
||||
todo(d3d12) probe (20, 36) f32(.25, .50, 0, 1)
|
||||
todo(d3d12) probe (36, 36) f32(.50, .50, 0, 1)
|
||||
todo(d3d12) probe (52, 36) f32(.75, .50, 0, 1)
|
||||
todo(d3d12) probe (36, 52) f32(.50, .75, 0, 1)
|
||||
todo(mvk) probe (36, 20) f32(.50, .25, 0, 1)
|
||||
todo(mvk) probe (20, 36) f32(.25, .50, 0, 1)
|
||||
todo(mvk) probe (36, 36) f32(.50, .50, 0, 1)
|
||||
todo(mvk) probe (52, 36) f32(.75, .50, 0, 1)
|
||||
todo(mvk) probe (36, 52) f32(.50, .75, 0, 1)
|
||||
|
||||
Reference in New Issue
Block a user