diff --git a/docs/features.txt b/docs/features.txt index abe6dc7aa30..15ae417a632 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -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) diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index 91523cedd56..513336d1192 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -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; diff --git a/src/nouveau/vulkan/nvk_image.h b/src/nouveau/vulkan/nvk_image.h index f5dec2cb694..7bd269bdd42 100644 --- a/src/nouveau/vulkan/nvk_image.h +++ b/src/nouveau/vulkan/nvk_image.h @@ -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); diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index efe43bb55a6..ac9222abf25 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -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, };