nouveau/nvk: Enable VK_KHR_sampler_ycbcr

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Mohamed Ahmed 2023-07-05 01:46:06 +03:00 committed by Marge Bot
parent e311b24b79
commit 2b85ccacf0
4 changed files with 104 additions and 11 deletions

View file

@ -441,7 +441,7 @@ Vulkan 1.1 -- all DONE: anv, lvp, radv, tu, vn
VK_KHR_maintenance3 DONE (anv, dzn, hasvk, lvp, nvk, radv, tu, v3dv, vn)
VK_KHR_multiview DONE (anv, dzn, hasvk, lvp, nvk, radv, tu, v3dv, vn)
VK_KHR_relaxed_block_layout DONE (anv, dzn, hasvk, lvp, nvk, radv, tu, v3dv, vn)
VK_KHR_sampler_ycbcr_conversion DONE (anv, hasvk, radv, tu, v3dv, vn)
VK_KHR_sampler_ycbcr_conversion DONE (anv, hasvk, nvk, radv, tu, v3dv, vn)
VK_KHR_shader_draw_parameters DONE (anv, dzn, hasvk, lvp, nvk, radv, tu, vn)
VK_KHR_storage_buffer_storage_class DONE (anv, dzn, hasvk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_KHR_variable_pointers DONE (anv, hasvk, lvp, panvk, radv, tu, v3dv, vn)
@ -497,7 +497,7 @@ Vulkan 1.3 -- all DONE: anv, radv, tu, lvp, vn
VK_EXT_texel_buffer_alignment DONE (anv, hasvk, lvp, radv, tu, v3dv, vn)
VK_EXT_texture_compression_astc_hdr DONE (vn)
VK_EXT_tooling_info DONE (anv, hasvk, tu, v3dv, vn)
VK_EXT_ycbcr_2plane_444_formats DONE (vn)
VK_EXT_ycbcr_2plane_444_formats DONE (nvk, vn)
Khronos extensions that are not part of any Vulkan version:
@ -607,7 +607,7 @@ Khronos extensions that are not part of any Vulkan version:
VK_EXT_transform_feedback DONE (anv, hasvk, lvp, nvk, radv, tu, vn)
VK_EXT_vertex_attribute_divisor DONE (anv, dzn, hasvk, lvp, nvk, panvk, radv, tu, v3dv, vn)
VK_EXT_vertex_input_dynamic_state DONE (anv, lvp, nvk, radv, tu)
VK_EXT_ycbcr_image_arrays DONE (anv, hasvk, radv)
VK_EXT_ycbcr_image_arrays DONE (anv, hasvk, nvk, radv)
VK_ANDROID_external_memory_android_hardware_buffer DONE (anv, radv, vn)
VK_ANDROID_native_buffer DONE (anv, radv, tu, v3dv, vn)
VK_GOOGLE_decorate_string DONE (anv, hasvk, lvp, radv)

View file

@ -11,9 +11,9 @@
#include "clb097.h"
#include "clb197.h"
VkFormatFeatureFlags2
nvk_get_image_format_features(struct nvk_physical_device *pdev,
VkFormat vk_format, VkImageTiling tiling)
static VkFormatFeatureFlags2
nvk_get_image_plane_format_features(struct nvk_physical_device *pdev,
VkFormat vk_format, VkImageTiling tiling)
{
VkFormatFeatureFlags2 features = 0;
@ -74,6 +74,44 @@ nvk_get_image_format_features(struct nvk_physical_device *pdev,
return features;
}
VkFormatFeatureFlags2
nvk_get_image_format_features(struct nvk_physical_device *pdev,
VkFormat vk_format, VkImageTiling tiling)
{
const struct vk_format_ycbcr_info *ycbcr_info =
vk_format_get_ycbcr_info(vk_format);
if (ycbcr_info == NULL)
return nvk_get_image_plane_format_features(pdev, vk_format, tiling);
/* For multi-plane, we get the feature flags of each plane separately,
* then take their intersection as the overall format feature flags
*/
VkFormatFeatureFlags2 features = ~0ull;
bool cosited_chroma = false;
for (uint8_t plane = 0; plane < ycbcr_info->n_planes; plane++) {
const struct vk_format_ycbcr_plane *plane_info = &ycbcr_info->planes[plane];
features &= nvk_get_image_plane_format_features(pdev, plane_info->format,
tiling);
if (plane_info->denominator_scales[0] > 1 ||
plane_info->denominator_scales[1] > 1)
cosited_chroma = true;
}
if (features == 0)
return 0;
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT |
VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT |
VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT;
if (ycbcr_info->n_planes > 1)
features |= VK_FORMAT_FEATURE_DISJOINT_BIT;
if (cosited_chroma)
features |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
return features;
}
static VkFormatFeatureFlags2KHR
vk_image_usage_to_format_features(VkImageUsageFlagBits usage_flag)
{
@ -124,6 +162,11 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
pImageFormatInfo->type != VK_IMAGE_TYPE_2D)
return VK_ERROR_FORMAT_NOT_SUPPORTED;
const struct vk_format_ycbcr_info *ycbcr_info =
vk_format_get_ycbcr_info(pImageFormatInfo->format);
if (ycbcr_info && pImageFormatInfo->type != VK_IMAGE_TYPE_2D)
return VK_ERROR_FORMAT_NOT_SUPPORTED;
VkExtent3D maxExtent;
uint32_t maxMipLevels;
uint32_t maxArraySize;
@ -137,12 +180,17 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
break;
case VK_IMAGE_TYPE_2D:
maxExtent = (VkExtent3D) { 16384, 16384, 1 };
maxMipLevels = 15;
maxArraySize = 2048;
sampleCounts = VK_SAMPLE_COUNT_1_BIT |
VK_SAMPLE_COUNT_2_BIT |
VK_SAMPLE_COUNT_4_BIT |
VK_SAMPLE_COUNT_8_BIT;
if(ycbcr_info) {
maxMipLevels = 1;
sampleCounts = VK_SAMPLE_COUNT_1_BIT;
} else {
maxMipLevels = 15;
sampleCounts = VK_SAMPLE_COUNT_1_BIT |
VK_SAMPLE_COUNT_2_BIT |
VK_SAMPLE_COUNT_4_BIT |
VK_SAMPLE_COUNT_8_BIT;
}
break;
case VK_IMAGE_TYPE_3D:
maxExtent = (VkExtent3D) { 2048, 2048, 2048 };
@ -230,6 +278,32 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
}
}
const unsigned plane_count =
vk_format_get_plane_count(pImageFormatInfo->format);
if (pImageFormatInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT) {
/* From the Vulkan 1.2.149 spec, VkImageCreateInfo:
*
* If format is a multi-planar format, and if imageCreateFormatFeatures
* (as defined in Image Creation Limits) does not contain
* VK_FORMAT_FEATURE_2_DISJOINT_BIT, then flags must not contain
* VK_IMAGE_CREATE_DISJOINT_BIT.
*/
if (plane_count > 1 &&
!(features & VK_FORMAT_FEATURE_2_DISJOINT_BIT))
return VK_ERROR_FORMAT_NOT_SUPPORTED;
/* From the Vulkan 1.2.149 spec, VkImageCreateInfo:
*
* If format is not a multi-planar format, and flags does not include
* VK_IMAGE_CREATE_ALIAS_BIT, flags must not contain
* VK_IMAGE_CREATE_DISJOINT_BIT.
*/
if (plane_count == 1 &&
!(pImageFormatInfo->flags & VK_IMAGE_CREATE_ALIAS_BIT))
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
pImageFormatProperties->imageFormatProperties = (VkImageFormatProperties) {
.maxExtent = maxExtent,
.maxMipLevels = maxMipLevels,
@ -255,6 +329,11 @@ nvk_GetPhysicalDeviceImageFormatProperties2(
p->externalMemoryProperties = *ext_mem_props;
break;
}
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: {
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = (void *) s;
ycbcr_props->combinedImageSamplerDescriptorCount = plane_count;
break;
}
default:
nvk_debug_ignored_stype(s->sType);
break;

View file

@ -10,6 +10,10 @@
struct nvk_physical_device;
static VkFormatFeatureFlags2
nvk_get_image_plane_format_features(struct nvk_physical_device *pdev,
VkFormat vk_format, VkImageTiling tiling);
VkFormatFeatureFlags2
nvk_get_image_format_features(struct nvk_physical_device *pdevice,
VkFormat format, VkImageTiling tiling);

View file

@ -358,6 +358,7 @@ nvk_get_device_extensions(const struct nv_device_info *info,
.KHR_push_descriptor = true,
.KHR_relaxed_block_layout = true,
.KHR_sampler_mirror_clamp_to_edge = true,
.KHR_sampler_ycbcr_conversion = true,
.KHR_separate_depth_stencil_layouts = true,
.KHR_shader_draw_parameters = true,
.KHR_shader_non_semantic_info = true,
@ -399,6 +400,8 @@ nvk_get_device_extensions(const struct nv_device_info *info,
.EXT_transform_feedback = true,
.EXT_vertex_attribute_divisor = true,
.EXT_vertex_input_dynamic_state = true,
.EXT_ycbcr_2plane_444_formats = true,
.EXT_ycbcr_image_arrays = true,
};
}
@ -462,6 +465,7 @@ nvk_get_device_features(const struct nv_device_info *info,
.multiviewGeometryShader = true,
.multiviewTessellationShader = true,
.shaderDrawParameters = true,
.samplerYcbcrConversion = true,
/* Vulkan 1.2 */
.samplerMirrorClampToEdge = true,
@ -593,6 +597,12 @@ nvk_get_device_features(const struct nv_device_info *info,
/* VK_EXT_vertex_input_dynamic_state */
.vertexInputDynamicState = true,
/* VK_EXT_ycbcr_2plane_444_formats */
.ycbcr2plane444Formats = true,
/* VK_EXT_ycbcr_image_arrays */
.ycbcrImageArrays = true,
/* VALVE_mutable_descriptor_type */
.mutableDescriptorType = true,
};