diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 5468c30000f..3ab23a65d19 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -120,6 +120,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .EXT_index_type_uint8 = true, .EXT_post_depth_coverage = true, .EXT_private_data = true, + .EXT_sampler_filter_minmax = true, .EXT_shader_stencil_export = true, .EXT_shader_viewport_index_layer = true, .EXT_transform_feedback = true, @@ -1673,6 +1674,9 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSampler( { LVP_FROM_HANDLE(lvp_device, device, _device); struct lvp_sampler *sampler; + const VkSamplerReductionModeCreateInfo *reduction_mode_create_info = + vk_find_struct_const(pCreateInfo->pNext, + SAMPLER_REDUCTION_MODE_CREATE_INFO); assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); @@ -1684,6 +1688,11 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSampler( vk_object_base_init(&device->vk, &sampler->base, VK_OBJECT_TYPE_SAMPLER); sampler->create_info = *pCreateInfo; + + sampler->reduction_mode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + if (reduction_mode_create_info) + sampler->reduction_mode = reduction_mode_create_info->reductionMode; + *pSampler = lvp_sampler_to_handle(sampler); return VK_SUCCESS; diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 1f1c7cc1645..3a2870b52b9 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -761,6 +761,7 @@ static void fill_sampler(struct pipe_sampler_state *ss, ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE; ss->compare_func = samp->create_info.compareOp; ss->seamless_cube_map = true; + ss->reduction_mode = samp->reduction_mode; switch (samp->create_info.borderColor) { case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: diff --git a/src/gallium/frontends/lavapipe/lvp_formats.c b/src/gallium/frontends/lavapipe/lvp_formats.c index 5c6581e2505..2f467ecbe4b 100644 --- a/src/gallium/frontends/lavapipe/lvp_formats.c +++ b/src/gallium/frontends/lavapipe/lvp_formats.c @@ -158,6 +158,35 @@ enum pipe_format vk_format_to_pipe(VkFormat format) return format_to_vk_table[format]; } +static bool lvp_is_filter_minmax_format_supported(VkFormat format) +{ + /* From the Vulkan spec 1.1.71: + * + * "The following formats must support the + * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with + * VK_IMAGE_TILING_OPTIMAL, if they support + * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT." + */ + /* TODO: enable more formats. */ + switch (format) { + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return true; + default: + return false; + } +} + static void lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device, VkFormat format, @@ -179,6 +208,8 @@ lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_d VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; + if (lvp_is_filter_minmax_format_supported(format)) + out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT; out_properties->bufferFeatures = 0; return; } @@ -214,6 +245,8 @@ lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_d features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; if (!util_format_is_pure_integer(pformat)) features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + if (lvp_is_filter_minmax_format_supported(format)) + features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT; } if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat, diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index 4e54f9c7295..72532c955ac 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -382,6 +382,7 @@ struct lvp_render_pass { struct lvp_sampler { struct vk_object_base base; VkSamplerCreateInfo create_info; + VkSamplerReductionMode reduction_mode; uint32_t state[4]; };