diff options
| author | Hyunjun Ko <zzoon@igalia.com> | 2025-09-10 18:41:13 +0200 |
|---|---|---|
| committer | Marge Bot <marge-bot@fdo.invalid> | 2025-10-13 12:06:24 +0000 |
| commit | 29aacd79045aa0e2164ef0afaddeed62b70596f6 (patch) | |
| tree | 94fbe272a80fe20977edc083420de3831f23229e | |
| parent | 8473d8c2dd086057d99d1655372f2e191ca9843d (diff) | |
anv/video: Make the query result for video profiles and formats more
precisely.
This way we could provide more correct infomation to applications.
Signed-off-by: Hyunjun Ko <zzoon@igalia.com>
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37762>
| -rw-r--r-- | src/intel/vulkan/anv_video.c | 236 |
1 files changed, 171 insertions, 65 deletions
diff --git a/src/intel/vulkan/anv_video.c b/src/intel/vulkan/anv_video.c index f3a4bddab5c..1e1054d28e9 100644 --- a/src/intel/vulkan/anv_video.c +++ b/src/intel/vulkan/anv_video.c @@ -68,6 +68,117 @@ anv_DestroyVideoSessionKHR(VkDevice _device, vk_free2(&device->vk.alloc, pAllocator, vid); } +static VkResult +video_profile_supported(struct anv_physical_device *pdevice, + const VkVideoProfileInfoKHR *profile) +{ + VkResult result = vk_video_is_profile_supported(profile); + if (result != VK_SUCCESS) + return result; + + /* ANV doesn't support different luma and chroma bit depths for all codecs. */ + if (profile->lumaBitDepth != profile->chromaBitDepth) + return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; + + /* ANV doesn't support 12 bit for all codecs for the moment */ + if (profile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) + return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; + + if (profile->chromaSubsampling != VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR) + return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; + + switch (profile->videoCodecOperation) { + + case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: + case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR: { + if (profile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) + return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; + break; + } + case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: + case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR: { + const struct VkVideoDecodeH265ProfileInfoKHR *h265_dec_profile = + vk_find_struct_const(profile->pNext, + VIDEO_DECODE_H265_PROFILE_INFO_KHR); + + const struct VkVideoEncodeH265ProfileInfoKHR *h265_enc_profile = + vk_find_struct_const(profile->pNext, + VIDEO_ENCODE_H265_PROFILE_INFO_KHR); + + StdVideoH265ProfileIdc profile_idc = h265_dec_profile ? + h265_dec_profile->stdProfileIdc : h265_enc_profile->stdProfileIdc; + + /* No hardware supports the scc extension profile */ + if (profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN && + profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10 && + profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE && + profile_idc != STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS) + return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; + + /* Skylake only supports the main profile */ + if (profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN && + profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE && + pdevice->info.platform <= INTEL_PLATFORM_SKL) + return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; + + /* Gfx10 and under don't support the range extension profile */ + if (profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN && + profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10 && + profile_idc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE && + pdevice->info.ver <= 10) + return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; + + if (profile_idc == STD_VIDEO_H265_PROFILE_IDC_MAIN || + profile_idc == STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE) { + if (profile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) + return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR; + } + + break; + } + case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR: { + const struct VkVideoDecodeAV1ProfileInfoKHR *av1_profile = + vk_find_struct_const(profile->pNext, VIDEO_DECODE_AV1_PROFILE_INFO_KHR); + + if (av1_profile->stdProfile != STD_VIDEO_AV1_PROFILE_MAIN) + return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; + + /* ANV doesn't support filmgrain under Gen20 */ + if (av1_profile->filmGrainSupport && pdevice->info.ver < 20) + return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; + + break; + } + case VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR: { + const struct VkVideoDecodeVP9ProfileInfoKHR *vp9_profile = + vk_find_struct_const(profile->pNext, VIDEO_DECODE_VP9_PROFILE_INFO_KHR); + + if (vp9_profile->stdProfile != STD_VIDEO_VP9_PROFILE_0 && + vp9_profile->stdProfile != STD_VIDEO_VP9_PROFILE_2) + return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; + + /* Check the profile compatiblity with chroma/luma subsampling */ + if (vp9_profile->stdProfile == STD_VIDEO_VP9_PROFILE_0 && + profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) + return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; + + if (vp9_profile->stdProfile == STD_VIDEO_VP9_PROFILE_2 && + profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) + return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; + + break; + } + case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR: { + return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR; + } + default: + UNREACHABLE("unknown codec\n"); + break; + } + + return VK_SUCCESS; +} + VkResult anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, const VkVideoProfileInfoKHR *pVideoProfile, @@ -75,6 +186,10 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, { ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); + VkResult res = video_profile_supported(pdevice, pVideoProfile); + if (res != VK_SUCCESS) + return res; + pCapabilities->minBitstreamBufferOffsetAlignment = 32; pCapabilities->minBitstreamBufferSizeAlignment = 1; pCapabilities->pictureAccessGranularity.width = ANV_MB_WIDTH; @@ -91,21 +206,11 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, if (dec_caps) dec_caps->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR; - /* H264 allows different luma and chroma bit depths */ - if (pVideoProfile->lumaBitDepth != pVideoProfile->chromaBitDepth) - return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; - - if (pVideoProfile->chromaSubsampling != VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR) - return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; - switch (pVideoProfile->videoCodecOperation) { case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: { struct VkVideoDecodeH264CapabilitiesKHR *ext = (struct VkVideoDecodeH264CapabilitiesKHR *) vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H264_CAPABILITIES_KHR); - if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) - return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; - pCapabilities->maxDpbSlots = ANV_VIDEO_H264_MAX_DPB_SLOTS; pCapabilities->maxActiveReferencePictures = ANV_VIDEO_H264_MAX_NUM_REF_FRAME; pCapabilities->pictureAccessGranularity.width = ANV_MB_WIDTH; @@ -121,17 +226,6 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, break; } case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR: { - - const struct VkVideoDecodeAV1ProfileInfoKHR *av1_profile = - vk_find_struct_const(pVideoProfile->pNext, VIDEO_DECODE_AV1_PROFILE_INFO_KHR); - - if (av1_profile->stdProfile != STD_VIDEO_AV1_PROFILE_MAIN) - return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; - - if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR && - pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) - return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; - struct VkVideoDecodeAV1CapabilitiesKHR *ext = (struct VkVideoDecodeAV1CapabilitiesKHR *) vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_AV1_CAPABILITIES_KHR); @@ -148,34 +242,6 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, struct VkVideoDecodeH265CapabilitiesKHR *ext = (struct VkVideoDecodeH265CapabilitiesKHR *) vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H265_CAPABILITIES_KHR); - const struct VkVideoDecodeH265ProfileInfoKHR *h265_profile = - vk_find_struct_const(pVideoProfile->pNext, - VIDEO_DECODE_H265_PROFILE_INFO_KHR); - - /* No hardware supports the scc extension profile */ - if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN && - h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10 && - h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE && - h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS) - return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; - - /* Skylake only supports the main profile */ - if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN && - h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE && - pdevice->info.platform <= INTEL_PLATFORM_SKL) - return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; - - /* Gfx10 and under don't support the range extension profile */ - if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN && - h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10 && - h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE && - pdevice->info.ver <= 10) - return VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR; - - if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR && - pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) - return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; - pCapabilities->pictureAccessGranularity.width = ANV_MAX_H265_CTB_SIZE; pCapabilities->pictureAccessGranularity.height = ANV_MAX_H265_CTB_SIZE; pCapabilities->minCodedExtent.width = ANV_MAX_H265_CTB_SIZE; @@ -193,10 +259,6 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, struct VkVideoDecodeVP9CapabilitiesKHR *ext = (struct VkVideoDecodeVP9CapabilitiesKHR *) vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_VP9_CAPABILITIES_KHR); - if (pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR && - pVideoProfile->lumaBitDepth != VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) - return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; - pCapabilities->maxDpbSlots = STD_VIDEO_VP9_NUM_REF_FRAMES + 4; pCapabilities->maxActiveReferencePictures = STD_VIDEO_VP9_REFS_PER_FRAME; pCapabilities->pictureAccessGranularity.width = 8; @@ -333,6 +395,8 @@ anv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pVideoFormatPropertyCount, VkVideoFormatPropertiesKHR *pVideoFormatProperties) { + ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); + VK_OUTARRAY_MAKE_TYPED(VkVideoFormatPropertiesKHR, out, pVideoFormatProperties, pVideoFormatPropertyCount); @@ -348,47 +412,89 @@ anv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice, const bool decode_dst = !!(pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR); + VkImageUsageFlags supportedImageUsage = pVideoFormatInfo->imageUsage; + VkImageCreateFlags supportedImageCreateFlags = 0; + + if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR || + pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) + { + supportedImageUsage |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT); + + supportedImageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT | + VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR; + } + if (prof_list) { for (unsigned i = 0; i < prof_list->profileCount; i++) { const VkVideoProfileInfoKHR *profile = &prof_list->pProfiles[i]; - if (profile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR || - profile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) { + /* Spec says: + * If any of the video profiles specified via + * VkVideoProfileListInfoKHR::pProfiles are not supported, + * then this command returns one of the video-profile-specific + * error codes. + */ + VkResult res = video_profile_supported(pdevice, profile); + if (res != VK_SUCCESS) + return res; + + const VkImageUsageFlags dpb_output_coincide_usage = + VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | + VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR; + + const bool decode_dpb_only = + (pVideoFormatInfo->imageUsage & dpb_output_coincide_usage) == + VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR; + const bool decode_dst_only = + (pVideoFormatInfo->imageUsage & dpb_output_coincide_usage) == + VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR; + + /* Decoder supports only + * VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR. + * + * So we need to set both usages. + */ + if (decode_dpb_only || decode_dst_only) + supportedImageUsage |= dpb_output_coincide_usage; + + if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) { vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p) { p->format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; - p->imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + p->imageCreateFlags = supportedImageCreateFlags; p->imageType = VK_IMAGE_TYPE_2D; p->imageTiling = VK_IMAGE_TILING_OPTIMAL; - p->imageUsageFlags = pVideoFormatInfo->imageUsage; + p->imageUsageFlags = supportedImageUsage; } if (!decode_dst) { vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p) { p->format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; - p->imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + p->imageCreateFlags = supportedImageCreateFlags; p->imageType = VK_IMAGE_TYPE_2D; p->imageTiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; - p->imageUsageFlags = pVideoFormatInfo->imageUsage; + p->imageUsageFlags = supportedImageUsage; } } } - if (profile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR || - profile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) { + if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) { vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p) { p->format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16; - p->imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + p->imageCreateFlags = supportedImageCreateFlags; p->imageType = VK_IMAGE_TYPE_2D; p->imageTiling = VK_IMAGE_TILING_OPTIMAL; - p->imageUsageFlags = pVideoFormatInfo->imageUsage; + p->imageUsageFlags = supportedImageUsage; } if (!decode_dst) { vk_outarray_append_typed(VkVideoFormatPropertiesKHR, &out, p) { p->format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16; - p->imageCreateFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + p->imageCreateFlags = supportedImageCreateFlags; p->imageType = VK_IMAGE_TYPE_2D; p->imageTiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; - p->imageUsageFlags = pVideoFormatInfo->imageUsage; + p->imageUsageFlags = supportedImageUsage; } } } |