mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-24 04:08:10 +02:00
radv/video: Use new video codec caps
Reviewed-by: Ruijing Dong <ruijing.dong@amd.com> Reviewed-by: Benjamin Cheng <benjamin.cheng@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35431>
This commit is contained in:
parent
4487162a7a
commit
280cb489ae
5 changed files with 256 additions and 404 deletions
|
|
@ -789,19 +789,25 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
|
|||
.KHR_video_maintenance1 = pdev->video_decode_enabled || pdev->video_encode_enabled,
|
||||
.KHR_video_maintenance2 = pdev->video_decode_enabled || pdev->video_encode_enabled,
|
||||
.KHR_video_queue = pdev->video_decode_enabled || pdev->video_encode_enabled,
|
||||
.KHR_video_decode_av1 = (pdev->info.vcn_ip_version >= VCN_3_0_0 && pdev->info.vcn_ip_version != VCN_3_0_33 &&
|
||||
VIDEO_CODEC_AV1DEC && pdev->video_decode_enabled),
|
||||
.KHR_video_decode_av1 =
|
||||
VIDEO_CODEC_AV1DEC && pdev->video_decode_enabled && pdev->info.video_caps.dec[AC_VIDEO_CODEC_AV1].supported,
|
||||
.KHR_video_decode_queue = pdev->video_decode_enabled,
|
||||
.KHR_video_decode_h264 = VIDEO_CODEC_H264DEC && pdev->video_decode_enabled,
|
||||
.KHR_video_decode_h265 = pdev->info.family >= CHIP_TONGA && VIDEO_CODEC_H265DEC && pdev->video_decode_enabled,
|
||||
.KHR_video_decode_vp9 =
|
||||
(radv_video_decode_vp9_supported(pdev) && VIDEO_CODEC_VP9DEC && pdev->video_decode_enabled),
|
||||
.KHR_video_encode_h264 = VIDEO_CODEC_H264ENC && pdev->video_encode_enabled,
|
||||
.KHR_video_encode_h265 = VIDEO_CODEC_H265ENC && pdev->video_encode_enabled,
|
||||
.KHR_video_decode_h264 =
|
||||
VIDEO_CODEC_H264DEC && pdev->video_decode_enabled && pdev->info.video_caps.dec[AC_VIDEO_CODEC_AVC].supported,
|
||||
.KHR_video_decode_h265 =
|
||||
VIDEO_CODEC_H265DEC && pdev->video_decode_enabled && pdev->info.video_caps.dec[AC_VIDEO_CODEC_HEVC].supported,
|
||||
.KHR_video_decode_vp9 = VIDEO_CODEC_VP9DEC && pdev->video_decode_enabled &&
|
||||
pdev->info.video_caps.dec[AC_VIDEO_CODEC_VP9].supported &&
|
||||
pdev->info.video_caps.dec[AC_VIDEO_CODEC_VP9].vp9.uncompressed_header_offset,
|
||||
.KHR_video_encode_h264 =
|
||||
VIDEO_CODEC_H264ENC && pdev->video_encode_enabled && pdev->info.video_caps.enc[AC_VIDEO_CODEC_AVC].supported,
|
||||
.KHR_video_encode_h265 =
|
||||
VIDEO_CODEC_H265ENC && pdev->video_encode_enabled && pdev->info.video_caps.enc[AC_VIDEO_CODEC_HEVC].supported,
|
||||
.KHR_video_encode_av1 =
|
||||
(radv_video_encode_av1_supported(pdev) && VIDEO_CODEC_AV1ENC && pdev->video_encode_enabled),
|
||||
VIDEO_CODEC_AV1ENC && pdev->video_encode_enabled && pdev->info.video_caps.enc[AC_VIDEO_CODEC_AV1].supported,
|
||||
.KHR_video_encode_intra_refresh = pdev->video_encode_enabled,
|
||||
.KHR_video_encode_quantization_map = pdev->video_encode_enabled && radv_video_encode_qp_map_supported(pdev),
|
||||
.KHR_video_encode_quantization_map =
|
||||
pdev->video_encode_enabled && pdev->info.video_caps.enc[AC_VIDEO_CODEC_AVC].qp_map,
|
||||
.KHR_video_encode_queue = pdev->video_encode_enabled,
|
||||
.KHR_vulkan_memory_model = true,
|
||||
.KHR_workgroup_memory_explicit_layout = true,
|
||||
|
|
@ -950,7 +956,7 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
|
|||
.VALVE_mutable_descriptor_type = true,
|
||||
.VALVE_shader_mixed_float_dot_product = pdev->info.compiler_info.has_accelerated_dot_product,
|
||||
.VALVE_video_encode_rgb_conversion =
|
||||
pdev->video_encode_enabled && pdev->info.vcn_ip_version >= VCN_2_0_0 && pdev->info.vcn_ip_version != VCN_2_2_0,
|
||||
pdev->video_encode_enabled && pdev->info.video_caps.enc[AC_VIDEO_CODEC_AVC].efc,
|
||||
};
|
||||
*out_ext = ext;
|
||||
}
|
||||
|
|
@ -3010,22 +3016,22 @@ radv_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, ui
|
|||
VkQueueFamilyVideoPropertiesKHR *prop = (VkQueueFamilyVideoPropertiesKHR *)ext;
|
||||
prop->videoCodecOperations = 0;
|
||||
if (pQueueFamilyProperties[i].queueFamilyProperties.queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
|
||||
if (VIDEO_CODEC_H264DEC)
|
||||
if (VIDEO_CODEC_H264DEC && pdev->info.video_caps.dec[AC_VIDEO_CODEC_AVC].supported)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR;
|
||||
if (VIDEO_CODEC_H265DEC)
|
||||
if (VIDEO_CODEC_H265DEC && pdev->info.video_caps.dec[AC_VIDEO_CODEC_HEVC].supported)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
|
||||
if (VIDEO_CODEC_AV1DEC && pdev->info.vcn_ip_version >= VCN_3_0_0 &&
|
||||
pdev->info.vcn_ip_version != VCN_3_0_33)
|
||||
if (VIDEO_CODEC_AV1DEC && pdev->info.video_caps.dec[AC_VIDEO_CODEC_AV1].supported)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR;
|
||||
if (VIDEO_CODEC_VP9DEC)
|
||||
if (VIDEO_CODEC_VP9DEC && pdev->info.video_caps.dec[AC_VIDEO_CODEC_VP9].supported &&
|
||||
pdev->info.video_caps.dec[AC_VIDEO_CODEC_VP9].vp9.uncompressed_header_offset)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR;
|
||||
}
|
||||
if (pQueueFamilyProperties[i].queueFamilyProperties.queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) {
|
||||
if (VIDEO_CODEC_H264ENC)
|
||||
if (VIDEO_CODEC_H264ENC && pdev->info.video_caps.enc[AC_VIDEO_CODEC_AVC].supported)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR;
|
||||
if (VIDEO_CODEC_H265ENC)
|
||||
if (VIDEO_CODEC_H265ENC && pdev->info.video_caps.enc[AC_VIDEO_CODEC_HEVC].supported)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR;
|
||||
if (VIDEO_CODEC_AV1ENC && radv_video_encode_av1_supported(pdev))
|
||||
if (VIDEO_CODEC_AV1ENC && pdev->info.video_caps.enc[AC_VIDEO_CODEC_AV1].supported)
|
||||
prop->videoCodecOperations |= VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2367,7 +2367,8 @@ radv_GetQueryPoolResults(VkDevice _device, VkQueryPool queryPool, uint32_t first
|
|||
break;
|
||||
}
|
||||
case VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR: {
|
||||
const bool write_memory = radv_video_write_memory_supported(pdev) == RADV_VIDEO_WRITE_MEMORY_SUPPORT_FULL;
|
||||
const bool write_memory =
|
||||
pdev->info.video_caps.queue[AMD_IP_VCN_ENC].write_memory == AC_VIDEO_WRITE_MEMORY_SUPPORT_FULL;
|
||||
uint32_t *src32 = (uint32_t *)src;
|
||||
uint32_t ready_idx = write_memory ? RADV_ENC_FEEDBACK_STATUS_IDX : 1;
|
||||
uint32_t value;
|
||||
|
|
|
|||
|
|
@ -45,34 +45,6 @@ set_reg(struct radv_cmd_buffer *cmd_buffer, unsigned reg, uint32_t val)
|
|||
radeon_end();
|
||||
}
|
||||
|
||||
bool
|
||||
radv_check_vcn_fw_version(const struct radv_physical_device *pdev, uint32_t dec, uint32_t enc, uint32_t rev)
|
||||
{
|
||||
return pdev->info.vcn_dec_version > dec || pdev->info.vcn_enc_minor_version > enc ||
|
||||
(pdev->info.vcn_dec_version == dec && pdev->info.vcn_enc_minor_version == enc &&
|
||||
pdev->info.vcn_fw_revision >= rev);
|
||||
}
|
||||
|
||||
static bool
|
||||
radv_enable_tier3(struct radv_physical_device *pdev, VkVideoCodecOperationFlagBitsKHR operation)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version < VCN_5_0_0)
|
||||
return false;
|
||||
|
||||
if (operation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR)
|
||||
return radv_check_vcn_fw_version(pdev, 9, 9, 14);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
radv_enable_tier2(struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_3_0_0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
radv_video_get_db_alignment(struct radv_physical_device *pdev, int width, bool is_h265_main_10_or_av1)
|
||||
{
|
||||
|
|
@ -124,12 +96,12 @@ radv_vcn_write_memory(struct radv_cmd_buffer *cmd_buffer, uint64_t va, unsigned
|
|||
struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
struct rvcn_sq_var sq;
|
||||
struct radv_cmd_stream *cs = cmd_buffer->cs;
|
||||
enum radv_video_write_memory_support support = radv_video_write_memory_supported(pdev);
|
||||
enum ac_video_write_memory_support support = pdev->info.video_caps.queue[cs->hw_ip].write_memory;
|
||||
|
||||
if (support == RADV_VIDEO_WRITE_MEMORY_SUPPORT_NONE)
|
||||
if (support == AC_VIDEO_WRITE_MEMORY_SUPPORT_NONE)
|
||||
return;
|
||||
|
||||
if (support == RADV_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS) {
|
||||
if (support == AC_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS) {
|
||||
fprintf(stderr, "radv: VCN WRITE_MEMORY requires PCIe atomics support. Expect issues "
|
||||
"if PCIe atomics are not enabled on current device.\n");
|
||||
}
|
||||
|
|
@ -165,12 +137,7 @@ radv_vcn_write_memory(struct radv_cmd_buffer *cmd_buffer, uint64_t va, unsigned
|
|||
void
|
||||
radv_init_physical_device_decoder(struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_4_0_0)
|
||||
pdev->vid_decode_ip = AMD_IP_VCN_UNIFIED;
|
||||
else if (radv_has_uvd(pdev))
|
||||
pdev->vid_decode_ip = AMD_IP_UVD;
|
||||
else
|
||||
pdev->vid_decode_ip = AMD_IP_VCN_DEC;
|
||||
pdev->vid_decode_ip = pdev->info.video_caps.dec[AC_VIDEO_CODEC_AVC].ip_type;
|
||||
|
||||
switch (pdev->info.vcn_ip_version) {
|
||||
case VCN_1_0_0:
|
||||
|
|
@ -220,7 +187,9 @@ radv_probe_video_decode(struct radv_physical_device *pdev)
|
|||
return;
|
||||
|
||||
/* WRITE_MEMORY is needed for SetEvent and is required to pass CTS */
|
||||
pdev->video_decode_enabled = radv_video_write_memory_supported(pdev);
|
||||
enum amd_ip_type decode_ip = pdev->info.video_caps.dec[AC_VIDEO_CODEC_AVC].ip_type;
|
||||
pdev->video_decode_enabled =
|
||||
pdev->info.video_caps.queue[decode_ip].write_memory != AC_VIDEO_WRITE_MEMORY_SUPPORT_NONE;
|
||||
|
||||
if (instance->experimental_flags & RADV_EXPERIMENTAL_VIDEO_DECODE) {
|
||||
pdev->video_decode_enabled = true;
|
||||
|
|
@ -463,6 +432,9 @@ radv_video_is_profile_supported(struct radv_physical_device *pdev, const VkVideo
|
|||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
struct ac_video_dec_codec_caps *dec_caps;
|
||||
struct ac_video_enc_codec_caps *enc_caps;
|
||||
|
||||
switch (pVideoProfile->videoCodecOperation) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: {
|
||||
const struct VkVideoDecodeH264ProfileInfoKHR *h264_profile =
|
||||
|
|
@ -479,12 +451,13 @@ radv_video_is_profile_supported(struct radv_physical_device *pdev, const VkVideo
|
|||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: {
|
||||
const bool have_10bit = pdev->info.family >= CHIP_STONEY;
|
||||
const struct VkVideoDecodeH265ProfileInfoKHR *h265_profile =
|
||||
vk_find_struct_const(pVideoProfile->pNext, VIDEO_DECODE_H265_PROFILE_INFO_KHR);
|
||||
|
||||
dec_caps = &pdev->info.video_caps.dec[AC_VIDEO_CODEC_HEVC];
|
||||
|
||||
if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN &&
|
||||
(!have_10bit || h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10) &&
|
||||
(!dec_caps->hevc.main10 || h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10) &&
|
||||
h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE)
|
||||
return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
|
||||
|
||||
|
|
@ -494,12 +467,13 @@ radv_video_is_profile_supported(struct radv_physical_device *pdev, const VkVideo
|
|||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR: {
|
||||
const bool have_12bit = pdev->info.vcn_ip_version >= VCN_5_0_0 || pdev->info.vcn_ip_version == VCN_4_0_0;
|
||||
const struct VkVideoDecodeAV1ProfileInfoKHR *av1_profile =
|
||||
vk_find_struct_const(pVideoProfile->pNext, VIDEO_DECODE_AV1_PROFILE_INFO_KHR);
|
||||
|
||||
dec_caps = &pdev->info.video_caps.dec[AC_VIDEO_CODEC_AV1];
|
||||
|
||||
if (av1_profile->stdProfile != STD_VIDEO_AV1_PROFILE_MAIN &&
|
||||
(!have_12bit || av1_profile->stdProfile != STD_VIDEO_AV1_PROFILE_PROFESSIONAL))
|
||||
(!dec_caps->av1.profile2 || av1_profile->stdProfile != STD_VIDEO_AV1_PROFILE_PROFESSIONAL))
|
||||
return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
|
||||
|
||||
if (pVideoProfile->chromaSubsampling != VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR &&
|
||||
|
|
@ -535,12 +509,13 @@ radv_video_is_profile_supported(struct radv_physical_device *pdev, const VkVideo
|
|||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR: {
|
||||
const bool have_10bit = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_2;
|
||||
const struct VkVideoEncodeH265ProfileInfoKHR *h265_profile =
|
||||
vk_find_struct_const(pVideoProfile->pNext, VIDEO_ENCODE_H265_PROFILE_INFO_KHR);
|
||||
|
||||
enc_caps = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_HEVC];
|
||||
|
||||
if (h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN &&
|
||||
(!have_10bit || h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10) &&
|
||||
(!enc_caps->hevc.main10 || h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_10) &&
|
||||
h265_profile->stdProfileIdc != STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE)
|
||||
return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR;
|
||||
|
||||
|
|
@ -571,17 +546,34 @@ radv_video_is_profile_supported(struct radv_physical_device *pdev, const VkVideo
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
radv_video_get_qp_map_texel_size(VkVideoCodecOperationFlagBitsKHR codec)
|
||||
void
|
||||
radv_video_get_caps(struct radv_physical_device *pdev, VkVideoCodecOperationFlagBitsKHR op,
|
||||
struct ac_video_dec_codec_caps **dec, struct ac_video_enc_codec_caps **enc)
|
||||
{
|
||||
switch (codec) {
|
||||
switch (op) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
*dec = &pdev->info.video_caps.dec[AC_VIDEO_CODEC_AVC];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
|
||||
*dec = &pdev->info.video_caps.dec[AC_VIDEO_CODEC_HEVC];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
|
||||
*dec = &pdev->info.video_caps.dec[AC_VIDEO_CODEC_AV1];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
|
||||
return 16;
|
||||
*enc = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_AVC];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
|
||||
*enc = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_HEVC];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR:
|
||||
*dec = &pdev->info.video_caps.dec[AC_VIDEO_CODEC_VP9];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:
|
||||
return 64;
|
||||
*enc = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_AV1];
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("Unsupported video codec operation");
|
||||
UNREACHABLE("unsupported operation");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -590,93 +582,43 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
VkVideoCapabilitiesKHR *pCapabilities)
|
||||
{
|
||||
VK_FROM_HANDLE(radv_physical_device, pdev, physicalDevice);
|
||||
const struct video_codec_cap *cap = NULL;
|
||||
bool is_encode = false;
|
||||
struct ac_video_dec_codec_caps *dcap = NULL;
|
||||
struct ac_video_enc_codec_caps *ecap = NULL;
|
||||
struct VkVideoDecodeCapabilitiesKHR *dec_caps = NULL;
|
||||
struct VkVideoEncodeCapabilitiesKHR *enc_caps = NULL;
|
||||
|
||||
VkResult res = radv_video_is_profile_supported(pdev, pVideoProfile);
|
||||
if (res != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
switch (pVideoProfile->videoCodecOperation) {
|
||||
#ifndef _WIN32
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
cap = &pdev->info.dec_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
|
||||
cap = &pdev->info.dec_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
|
||||
cap = &pdev->info.dec_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
|
||||
cap = &pdev->info.enc_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC];
|
||||
is_encode = true;
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
|
||||
cap = &pdev->info.enc_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC];
|
||||
is_encode = true;
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR:
|
||||
cap = &pdev->info.dec_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9];
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:
|
||||
cap = &pdev->info.enc_caps.codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1];
|
||||
is_encode = true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
UNREACHABLE("unsupported operation");
|
||||
}
|
||||
|
||||
if (cap && !cap->valid)
|
||||
cap = NULL;
|
||||
|
||||
if (cap) {
|
||||
pCapabilities->maxCodedExtent.width = cap->max_width;
|
||||
pCapabilities->maxCodedExtent.height = cap->max_height;
|
||||
} else {
|
||||
switch (pVideoProfile->videoCodecOperation) {
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
|
||||
pCapabilities->maxCodedExtent.width = (pdev->info.family < CHIP_TONGA) ? 2048 : 4096;
|
||||
pCapabilities->maxCodedExtent.height = (pdev->info.family < CHIP_TONGA) ? 1152 : 4096;
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
|
||||
pCapabilities->maxCodedExtent.width =
|
||||
(pdev->info.family < CHIP_RENOIR) ? ((pdev->info.family < CHIP_TONGA) ? 2048 : 4096) : 8192;
|
||||
pCapabilities->maxCodedExtent.height =
|
||||
(pdev->info.family < CHIP_RENOIR) ? ((pdev->info.family < CHIP_TONGA) ? 1152 : 4096) : 4352;
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR:
|
||||
pCapabilities->maxCodedExtent.width =
|
||||
(pdev->info.family < CHIP_RENOIR) ? ((pdev->info.family < CHIP_TONGA) ? 2048 : 4096) : 8192;
|
||||
pCapabilities->maxCodedExtent.height =
|
||||
(pdev->info.family < CHIP_RENOIR) ? ((pdev->info.family < CHIP_TONGA) ? 1152 : 4096) : 4352;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
radv_video_get_caps(pdev, pVideoProfile->videoCodecOperation, &dcap, &ecap);
|
||||
|
||||
pCapabilities->flags = 0;
|
||||
pCapabilities->pictureAccessGranularity.width = VK_VIDEO_H264_MACROBLOCK_WIDTH;
|
||||
pCapabilities->pictureAccessGranularity.height = VK_VIDEO_H264_MACROBLOCK_HEIGHT;
|
||||
pCapabilities->minCodedExtent.width = 64;
|
||||
pCapabilities->minCodedExtent.height = 64;
|
||||
|
||||
struct VkVideoDecodeCapabilitiesKHR *dec_caps = NULL;
|
||||
struct VkVideoEncodeCapabilitiesKHR *enc_caps = NULL;
|
||||
if (!is_encode) {
|
||||
if (dcap) {
|
||||
pCapabilities->minBitstreamBufferOffsetAlignment = dcap->bitstream_address_alignment;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = dcap->bitstream_size_alignment;
|
||||
pCapabilities->pictureAccessGranularity.width = VK_VIDEO_H264_MACROBLOCK_WIDTH;
|
||||
pCapabilities->pictureAccessGranularity.height = VK_VIDEO_H264_MACROBLOCK_HEIGHT;
|
||||
pCapabilities->minCodedExtent.width = dcap->min_width;
|
||||
pCapabilities->minCodedExtent.height = dcap->min_height;
|
||||
pCapabilities->maxCodedExtent.width = dcap->max_width;
|
||||
pCapabilities->maxCodedExtent.height = dcap->max_height;
|
||||
pCapabilities->maxDpbSlots = dcap->max_dpb_slots;
|
||||
pCapabilities->maxActiveReferencePictures = dcap->max_active_refs;
|
||||
|
||||
if (dcap->tiers & (AC_VIDEO_DEC_TIER2 | AC_VIDEO_DEC_TIER3))
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
|
||||
dec_caps =
|
||||
(struct VkVideoDecodeCapabilitiesKHR *)vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_CAPABILITIES_KHR);
|
||||
|
||||
if (dec_caps) {
|
||||
dec_caps->flags = VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR;
|
||||
if (radv_enable_tier3(pdev, pVideoProfile->videoCodecOperation))
|
||||
if (dcap->tiers & AC_VIDEO_DEC_TIER3)
|
||||
dec_caps->flags |= VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
|
||||
}
|
||||
pCapabilities->minBitstreamBufferOffsetAlignment = 128;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = 128;
|
||||
} else {
|
||||
enc_caps = vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_CAPABILITIES_KHR);
|
||||
struct VkVideoEncodeIntraRefreshCapabilitiesKHR *intra_refresh_caps =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_INTRA_REFRESH_CAPABILITIES_KHR);
|
||||
struct VkVideoEncodeQuantizationMapCapabilitiesKHR *qp_map_caps =
|
||||
|
|
@ -684,21 +626,39 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
struct VkVideoEncodeRgbConversionCapabilitiesVALVE *rgb_caps =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_RGB_CONVERSION_CAPABILITIES_VALVE);
|
||||
|
||||
pCapabilities->minBitstreamBufferOffsetAlignment = ecap->bitstream_address_alignment;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = ecap->bitstream_size_alignment;
|
||||
pCapabilities->pictureAccessGranularity.width = ecap->width_alignment;
|
||||
pCapabilities->pictureAccessGranularity.height = ecap->height_alignment;
|
||||
pCapabilities->minCodedExtent.width = ecap->min_width;
|
||||
pCapabilities->minCodedExtent.height = ecap->min_height;
|
||||
pCapabilities->maxCodedExtent.width = ecap->max_width;
|
||||
pCapabilities->maxCodedExtent.height = ecap->max_height;
|
||||
pCapabilities->maxDpbSlots = ecap->max_dpb_slots;
|
||||
pCapabilities->maxActiveReferencePictures = ecap->max_active_refs;
|
||||
|
||||
if (ecap->separate_refs)
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
|
||||
enc_caps = vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_CAPABILITIES_KHR);
|
||||
|
||||
if (enc_caps) {
|
||||
enc_caps->flags = 0;
|
||||
enc_caps->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
|
||||
enc_caps->maxRateControlLayers = RADV_ENC_MAX_RATE_LAYER;
|
||||
enc_caps->maxBitrate = 1000000000;
|
||||
enc_caps->maxQualityLevels = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_4 ? 4 : 3;
|
||||
enc_caps->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
|
||||
if (ecap->qp_map)
|
||||
enc_caps->flags |= VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
if (ecap->rc.cbr)
|
||||
enc_caps->rateControlModes |= VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR;
|
||||
if (ecap->rc.vbr)
|
||||
enc_caps->rateControlModes |= VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR;
|
||||
enc_caps->maxRateControlLayers = ecap->max_temporal_layers;
|
||||
enc_caps->maxBitrate = ecap->max_bitrate;
|
||||
enc_caps->maxQualityLevels = ecap->quality_levels;
|
||||
enc_caps->encodeInputPictureGranularity = pCapabilities->pictureAccessGranularity;
|
||||
enc_caps->supportedEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR;
|
||||
|
||||
if (radv_video_encode_qp_map_supported(pdev))
|
||||
enc_caps->flags |= VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
}
|
||||
|
||||
if (intra_refresh_caps) {
|
||||
intra_refresh_caps->intraRefreshModes = VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_BASED_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_ROW_BASED_BIT_KHR |
|
||||
|
|
@ -708,11 +668,12 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
intra_refresh_caps->partitionIndependentIntraRefreshRegions = true;
|
||||
intra_refresh_caps->nonRectangularIntraRefreshRegions = false;
|
||||
}
|
||||
|
||||
if (qp_map_caps) {
|
||||
const uint32_t qp_map_texel_size = radv_video_get_qp_map_texel_size(pVideoProfile->videoCodecOperation);
|
||||
qp_map_caps->maxQuantizationMapExtent.width = pCapabilities->maxCodedExtent.width / qp_map_texel_size;
|
||||
qp_map_caps->maxQuantizationMapExtent.height = pCapabilities->maxCodedExtent.height / qp_map_texel_size;
|
||||
qp_map_caps->maxQuantizationMapExtent.width = pCapabilities->maxCodedExtent.width / ecap->qp_map_texel_size;
|
||||
qp_map_caps->maxQuantizationMapExtent.height = pCapabilities->maxCodedExtent.height / ecap->qp_map_texel_size;
|
||||
}
|
||||
|
||||
if (rgb_caps) {
|
||||
rgb_caps->rgbModels = VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_709_BIT_VALVE |
|
||||
VK_VIDEO_ENCODE_RGB_MODEL_CONVERSION_YCBCR_2020_BIT_VALVE;
|
||||
|
|
@ -722,10 +683,6 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
rgb_caps->yChromaOffsets = VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_MIDPOINT_BIT_VALVE |
|
||||
VK_VIDEO_ENCODE_RGB_CHROMA_OFFSET_COSITED_EVEN_BIT_VALVE;
|
||||
}
|
||||
pCapabilities->minBitstreamBufferOffsetAlignment = 256;
|
||||
pCapabilities->minBitstreamBufferSizeAlignment = 8;
|
||||
if (pdev->info.vcn_ip_version >= VCN_5_0_0)
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
}
|
||||
|
||||
switch (pVideoProfile->videoCodecOperation) {
|
||||
|
|
@ -733,15 +690,9 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
struct VkVideoDecodeH264CapabilitiesKHR *ext =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H264_CAPABILITIES_KHR);
|
||||
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_H264_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures = RADV_VIDEO_H264_MAX_NUM_REF_FRAME;
|
||||
|
||||
/* for h264 on navi21+ separate dpb images should work */
|
||||
if (radv_enable_tier2(pdev))
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
ext->fieldOffsetGranularity.x = 0;
|
||||
ext->fieldOffsetGranularity.y = 0;
|
||||
ext->maxLevelIdc = STD_VIDEO_H264_LEVEL_IDC_5_1;
|
||||
ext->maxLevelIdc = dcap->max_level;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION;
|
||||
break;
|
||||
|
|
@ -750,12 +701,7 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
struct VkVideoDecodeH265CapabilitiesKHR *ext =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_H265_CAPABILITIES_KHR);
|
||||
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_H265_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures = RADV_VIDEO_H265_MAX_NUM_REF_FRAME;
|
||||
/* for h265 on navi21+ separate dpb images should work */
|
||||
if (radv_enable_tier2(pdev))
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
ext->maxLevelIdc = STD_VIDEO_H265_LEVEL_IDC_5_1;
|
||||
ext->maxLevelIdc = dcap->max_level;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION;
|
||||
break;
|
||||
|
|
@ -763,37 +709,24 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR: {
|
||||
struct VkVideoDecodeAV1CapabilitiesKHR *ext =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_AV1_CAPABILITIES_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_PROFESSIONAL)
|
||||
if (av1_profile->stdProfile == STD_VIDEO_AV1_PROFILE_PROFESSIONAL && !dcap->av1.profile2_tier3)
|
||||
dec_caps->flags &= ~VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR;
|
||||
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_AV1_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures = RADV_VIDEO_AV1_MAX_NUM_REF_FRAME;
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
|
||||
ext->maxLevel = STD_VIDEO_AV1_LEVEL_6_1; /* For VCN3/4, the only h/w currently with AV1 decode support */
|
||||
ext->maxLevel = dcap->max_level;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_DECODE_SPEC_VERSION;
|
||||
pCapabilities->minCodedExtent.width = 16;
|
||||
pCapabilities->minCodedExtent.height = 16;
|
||||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR: {
|
||||
struct VkVideoDecodeVP9CapabilitiesKHR *ext =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_DECODE_VP9_CAPABILITIES_KHR);
|
||||
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_VP9_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures = RADV_VIDEO_VP9_MAX_NUM_REF_FRAME;
|
||||
if (pdev->info.vcn_ip_version >= VCN_3_0_0)
|
||||
pCapabilities->flags |= VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
|
||||
ext->maxLevel = STD_VIDEO_VP9_LEVEL_6_2;
|
||||
ext->maxLevel = dcap->max_level;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_VP9_DECODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_VP9_DECODE_SPEC_VERSION;
|
||||
pCapabilities->minCodedExtent.width = 16;
|
||||
pCapabilities->minCodedExtent.height = 16;
|
||||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR: {
|
||||
|
|
@ -805,15 +738,15 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
ext->flags = VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_KHR;
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_3)
|
||||
if (ecap->avc.b_l0_refs)
|
||||
ext->flags |= VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR;
|
||||
|
||||
ext->maxLevelIdc = cap ? cap->max_level : 0;
|
||||
ext->maxSliceCount = 128;
|
||||
ext->maxPPictureL0ReferenceCount = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_3 ? 2 : 1;
|
||||
ext->maxBPictureL0ReferenceCount = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_3 ? 1 : 0;
|
||||
ext->maxL1ReferenceCount = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_3 ? 1 : 0;
|
||||
ext->maxTemporalLayerCount = 4;
|
||||
ext->maxLevelIdc = ecap->max_level;
|
||||
ext->maxSliceCount = ecap->max_slices;
|
||||
ext->maxPPictureL0ReferenceCount = ecap->avc.p_l0_refs;
|
||||
ext->maxBPictureL0ReferenceCount = ecap->avc.b_l0_refs;
|
||||
ext->maxL1ReferenceCount = ecap->avc.l1_refs;
|
||||
ext->maxTemporalLayerCount = ecap->max_temporal_layers;
|
||||
ext->expectDyadicTemporalLayerPattern = false;
|
||||
ext->minQp = 0;
|
||||
ext->maxQp = 51;
|
||||
|
|
@ -822,18 +755,13 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
ext->stdSyntaxFlags = VK_VIDEO_ENCODE_H264_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H264_STD_ENTROPY_CODING_MODE_FLAG_UNSET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H264_STD_ENTROPY_CODING_MODE_FLAG_SET_BIT_KHR;
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_3)
|
||||
if (ecap->avc.l1_refs)
|
||||
ext->stdSyntaxFlags |= VK_VIDEO_ENCODE_H264_STD_WEIGHTED_BIPRED_IDC_IMPLICIT_BIT_KHR;
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5)
|
||||
if (ecap->avc.transform_8x8)
|
||||
ext->stdSyntaxFlags |= VK_VIDEO_ENCODE_H264_STD_TRANSFORM_8X8_MODE_FLAG_SET_BIT_KHR;
|
||||
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION;
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_H264_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures =
|
||||
MAX2(ext->maxPPictureL0ReferenceCount, ext->maxBPictureL0ReferenceCount + ext->maxL1ReferenceCount);
|
||||
pCapabilities->minCodedExtent.width = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 96 : 128;
|
||||
pCapabilities->minCodedExtent.height = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 32 : 128;
|
||||
|
||||
if (qp_map_caps) {
|
||||
qp_map_caps->minQpDelta = -51;
|
||||
|
|
@ -847,31 +775,27 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
struct VkVideoEncodeH265QuantizationMapCapabilitiesKHR *qp_map_caps =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_H265_QUANTIZATION_MAP_CAPABILITIES_KHR);
|
||||
|
||||
pCapabilities->pictureAccessGranularity.width = VK_VIDEO_H265_CTU_MAX_WIDTH;
|
||||
if (enc_caps) {
|
||||
enc_caps->encodeInputPictureGranularity = pCapabilities->pictureAccessGranularity;
|
||||
/* VCN1 can't enable rate control modes or qp maps due to missing cu_qp_delta FW interface. */
|
||||
if (pdev->enc_hw_ver == RADV_VIDEO_ENC_HW_1_2) {
|
||||
enc_caps->rateControlModes = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR;
|
||||
enc_caps->flags &= ~VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
}
|
||||
if (enc_caps && !ecap->hevc.cu_qp_delta) {
|
||||
enc_caps->flags &= ~VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR;
|
||||
enc_caps->rateControlModes &=
|
||||
~(VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR | VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR);
|
||||
}
|
||||
|
||||
ext->flags = VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_KHR;
|
||||
ext->maxLevelIdc = cap ? cap->max_level : 0;
|
||||
ext->maxSliceSegmentCount = 128;
|
||||
ext->maxLevelIdc = ecap->max_level;
|
||||
ext->maxSliceSegmentCount = ecap->max_slices;
|
||||
ext->maxTiles.width = 1;
|
||||
ext->maxTiles.height = 1;
|
||||
ext->ctbSizes = VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR;
|
||||
ext->transformBlockSizes =
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_KHR | VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_KHR | VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR;
|
||||
ext->maxPPictureL0ReferenceCount = 1;
|
||||
ext->maxBPictureL0ReferenceCount = 0;
|
||||
ext->maxL1ReferenceCount = 0;
|
||||
ext->maxSubLayerCount = 4;
|
||||
ext->maxPPictureL0ReferenceCount = ecap->hevc.p_l0_refs;
|
||||
ext->maxBPictureL0ReferenceCount = ecap->hevc.b_l0_refs;
|
||||
ext->maxL1ReferenceCount = ecap->hevc.l1_refs;
|
||||
ext->maxSubLayerCount = ecap->max_temporal_layers;
|
||||
ext->expectDyadicTemporalSubLayerPattern = false;
|
||||
ext->minQp = 0;
|
||||
ext->maxQp = 51;
|
||||
|
|
@ -879,22 +803,16 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
ext->requiresGopRemainingFrames = false;
|
||||
ext->stdSyntaxFlags = VK_VIDEO_ENCODE_H265_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_STD_DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_SET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_STD_ENTROPY_CODING_SYNC_ENABLED_FLAG_SET_BIT_KHR;
|
||||
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_2)
|
||||
if (ecap->hevc.sao)
|
||||
ext->stdSyntaxFlags |= VK_VIDEO_ENCODE_H265_STD_SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG_SET_BIT_KHR;
|
||||
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_3)
|
||||
if (ecap->hevc.transform_skip)
|
||||
ext->stdSyntaxFlags |= VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_SET_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_UNSET_BIT_KHR;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION;
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_H265_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures =
|
||||
MAX2(ext->maxPPictureL0ReferenceCount, ext->maxBPictureL0ReferenceCount + ext->maxL1ReferenceCount);
|
||||
pCapabilities->minCodedExtent.width = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 384 : 130;
|
||||
pCapabilities->minCodedExtent.height = 128;
|
||||
|
||||
if (qp_map_caps) {
|
||||
qp_map_caps->minQpDelta = -51;
|
||||
|
|
@ -908,64 +826,53 @@ radv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice, cons
|
|||
struct VkVideoEncodeAV1QuantizationMapCapabilitiesKHR *qp_map_caps =
|
||||
vk_find_struct(pCapabilities->pNext, VIDEO_ENCODE_AV1_QUANTIZATION_MAP_CAPABILITIES_KHR);
|
||||
|
||||
pCapabilities->maxDpbSlots = RADV_VIDEO_AV1_MAX_DPB_SLOTS;
|
||||
pCapabilities->maxActiveReferencePictures = RADV_VIDEO_AV1_MAX_NUM_REF_FRAME;
|
||||
strcpy(pCapabilities->stdHeaderVersion.extensionName, VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_EXTENSION_NAME);
|
||||
pCapabilities->stdHeaderVersion.specVersion = VK_STD_VULKAN_VIDEO_CODEC_AV1_ENCODE_SPEC_VERSION;
|
||||
ext->flags = VK_VIDEO_ENCODE_AV1_CAPABILITY_PER_RATE_CONTROL_GROUP_MIN_MAX_Q_INDEX_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_AV1_CAPABILITY_GENERATE_OBU_EXTENSION_HEADER_BIT_KHR |
|
||||
VK_VIDEO_ENCODE_AV1_CAPABILITY_FRAME_SIZE_OVERRIDE_BIT_KHR;
|
||||
ext->maxLevel = STD_VIDEO_AV1_LEVEL_6_0;
|
||||
ext->codedPictureAlignment.width = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 8 : 64;
|
||||
ext->codedPictureAlignment.height = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 2 : 16;
|
||||
pCapabilities->pictureAccessGranularity = ext->codedPictureAlignment;
|
||||
if (enc_caps)
|
||||
enc_caps->encodeInputPictureGranularity = pCapabilities->pictureAccessGranularity;
|
||||
ext->maxTiles.width = 2;
|
||||
ext->maxTiles.height = 16;
|
||||
ext->minTileSize.width = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 256 : 128;
|
||||
ext->minTileSize.height = 64;
|
||||
ext->maxLevel = ecap->max_level;
|
||||
ext->codedPictureAlignment.width = ecap->width_alignment;
|
||||
ext->codedPictureAlignment.height = ecap->height_alignment;
|
||||
ext->maxTiles.width = ecap->av1.max_tile_cols;
|
||||
ext->maxTiles.height = ecap->av1.max_tile_rows;
|
||||
ext->minTileSize.width = ecap->av1.min_tile_width;
|
||||
ext->minTileSize.height = ecap->av1.min_tile_height;
|
||||
ext->maxTileSize.width = 4096;
|
||||
ext->maxTileSize.height = 4096;
|
||||
ext->superblockSizes = VK_VIDEO_ENCODE_AV1_SUPERBLOCK_SIZE_64_BIT_KHR;
|
||||
ext->maxSingleReferenceCount = 1;
|
||||
ext->maxSingleReferenceCount = ecap->av1.single_refs;
|
||||
ext->singleReferenceNameMask =
|
||||
(1 << (STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME - STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME));
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5) {
|
||||
ext->maxUnidirectionalCompoundReferenceCount = 2;
|
||||
ext->maxUnidirectionalCompoundGroup1ReferenceCount = 2;
|
||||
ext->maxUnidirectionalCompoundReferenceCount = ecap->av1.unidir_refs;
|
||||
ext->maxUnidirectionalCompoundGroup1ReferenceCount = ecap->av1.unidir_refs;
|
||||
ext->unidirectionalCompoundReferenceNameMask = 0;
|
||||
if (ext->maxUnidirectionalCompoundReferenceCount) {
|
||||
ext->unidirectionalCompoundReferenceNameMask =
|
||||
(1 << (STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME - STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME)) |
|
||||
(1 << (STD_VIDEO_AV1_REFERENCE_NAME_GOLDEN_FRAME - STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME));
|
||||
ext->maxBidirectionalCompoundReferenceCount = 2;
|
||||
ext->maxBidirectionalCompoundGroup1ReferenceCount = 1;
|
||||
ext->maxBidirectionalCompoundGroup2ReferenceCount = 1;
|
||||
}
|
||||
ext->maxBidirectionalCompoundReferenceCount = ecap->av1.bidir_refs;
|
||||
ext->maxBidirectionalCompoundGroup1ReferenceCount = ecap->av1.bidir_g1_refs;
|
||||
ext->maxBidirectionalCompoundGroup2ReferenceCount = ecap->av1.bidir_g2_refs;
|
||||
ext->bidirectionalCompoundReferenceNameMask = 0;
|
||||
if (ext->maxBidirectionalCompoundReferenceCount) {
|
||||
ext->bidirectionalCompoundReferenceNameMask =
|
||||
(1 << (STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME - STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME)) |
|
||||
(1 << (STD_VIDEO_AV1_REFERENCE_NAME_ALTREF_FRAME - STD_VIDEO_AV1_REFERENCE_NAME_LAST_FRAME));
|
||||
} else {
|
||||
ext->maxUnidirectionalCompoundReferenceCount = 0;
|
||||
ext->maxUnidirectionalCompoundGroup1ReferenceCount = 0;
|
||||
ext->unidirectionalCompoundReferenceNameMask = 0;
|
||||
ext->maxBidirectionalCompoundReferenceCount = 0;
|
||||
ext->maxBidirectionalCompoundGroup1ReferenceCount = 0;
|
||||
ext->maxBidirectionalCompoundGroup2ReferenceCount = 0;
|
||||
ext->bidirectionalCompoundReferenceNameMask = 0;
|
||||
}
|
||||
ext->maxTemporalLayerCount = 4;
|
||||
ext->maxTemporalLayerCount = ecap->max_temporal_layers;
|
||||
ext->maxSpatialLayerCount = 1;
|
||||
ext->maxOperatingPoints = 4;
|
||||
ext->maxOperatingPoints = ecap->max_temporal_layers;
|
||||
ext->minQIndex = 1;
|
||||
ext->maxQIndex = 255;
|
||||
ext->prefersGopRemainingFrames = false;
|
||||
ext->requiresGopRemainingFrames = false;
|
||||
ext->stdSyntaxFlags = 0;
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5) {
|
||||
ext->stdSyntaxFlags |=
|
||||
VK_VIDEO_ENCODE_AV1_STD_SKIP_MODE_PRESENT_UNSET_BIT_KHR | VK_VIDEO_ENCODE_AV1_STD_DELTA_Q_BIT_KHR;
|
||||
}
|
||||
pCapabilities->minCodedExtent.width = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? 320 : 128;
|
||||
pCapabilities->minCodedExtent.height = 128;
|
||||
if (ecap->av1.delta_q)
|
||||
ext->stdSyntaxFlags |= VK_VIDEO_ENCODE_AV1_STD_DELTA_Q_BIT_KHR;
|
||||
if (ecap->av1.skip_mode_present)
|
||||
ext->stdSyntaxFlags |= VK_VIDEO_ENCODE_AV1_STD_SKIP_MODE_PRESENT_UNSET_BIT_KHR;
|
||||
|
||||
if (qp_map_caps) {
|
||||
qp_map_caps->minQIndexDelta = -255;
|
||||
|
|
@ -1012,63 +919,66 @@ radv_GetPhysicalDeviceVideoFormatPropertiesKHR(VkPhysicalDevice physicalDevice,
|
|||
uint32_t qp_map_texel_size = 0;
|
||||
const struct VkVideoProfileListInfoKHR *prof_list =
|
||||
vk_find_struct_const(pVideoFormatInfo->pNext, VIDEO_PROFILE_LIST_INFO_KHR);
|
||||
if (prof_list) {
|
||||
for (unsigned i = 0; i < prof_list->profileCount; i++) {
|
||||
const VkVideoProfileInfoKHR *profile = &prof_list->pProfiles[i];
|
||||
const VkVideoEncodeProfileRgbConversionInfoVALVE *rgbProfile =
|
||||
vk_find_struct_const(profile, VIDEO_ENCODE_PROFILE_RGB_CONVERSION_INFO_VALVE);
|
||||
bool rgb = rgbProfile && rgbProfile->performEncodeRgbConversion &&
|
||||
(pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
|
||||
assert(prof_list);
|
||||
|
||||
/* "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 = radv_video_is_profile_supported(pdev, profile);
|
||||
if (res != VK_SUCCESS)
|
||||
return res;
|
||||
for (unsigned i = 0; i < prof_list->profileCount; i++) {
|
||||
const VkVideoProfileInfoKHR *profile = &prof_list->pProfiles[i];
|
||||
const VkVideoEncodeProfileRgbConversionInfoVALVE *rgbProfile =
|
||||
vk_find_struct_const(profile, VIDEO_ENCODE_PROFILE_RGB_CONVERSION_INFO_VALVE);
|
||||
bool rgb = rgbProfile && rgbProfile->performEncodeRgbConversion &&
|
||||
(pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
|
||||
struct ac_video_dec_codec_caps *dcap = NULL;
|
||||
struct ac_video_enc_codec_caps *ecap = NULL;
|
||||
|
||||
VkFormat profile_formats[2] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
|
||||
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR) {
|
||||
const uint32_t profile_qp_map_texel_size = radv_video_get_qp_map_texel_size(profile->videoCodecOperation);
|
||||
/* "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 = radv_video_is_profile_supported(pdev, profile);
|
||||
if (res != VK_SUCCESS)
|
||||
return res;
|
||||
|
||||
/* All profiles must share the same qp_map texel size. */
|
||||
if (qp_map_texel_size != 0 && qp_map_texel_size != profile_qp_map_texel_size)
|
||||
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
|
||||
radv_video_get_caps(pdev, profile->videoCodecOperation, &dcap, &ecap);
|
||||
|
||||
qp_map_texel_size = profile_qp_map_texel_size;
|
||||
VkFormat profile_formats[2] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
|
||||
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR) {
|
||||
/* All profiles must share the same qp_map texel size. */
|
||||
if (qp_map_texel_size != 0 && qp_map_texel_size != ecap->qp_map_texel_size)
|
||||
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
|
||||
|
||||
profile_formats[0] = pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5 ? VK_FORMAT_R16_SINT : VK_FORMAT_R32_SINT;
|
||||
} else if (rgb) {
|
||||
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) {
|
||||
profile_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
profile_formats[1] = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
} else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) {
|
||||
profile_formats[0] = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
profile_formats[1] = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||
}
|
||||
} else {
|
||||
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
|
||||
qp_map_texel_size = ecap->qp_map_texel_size;
|
||||
if (ecap->qp_map_formats.r16_sint)
|
||||
profile_formats[0] = VK_FORMAT_R16_SINT;
|
||||
else if (ecap->qp_map_formats.r32_sint)
|
||||
profile_formats[0] = VK_FORMAT_R32_SINT;
|
||||
} else if (rgb) {
|
||||
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) {
|
||||
profile_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
profile_formats[1] = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
} else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) {
|
||||
profile_formats[0] = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
profile_formats[1] = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||
}
|
||||
} else {
|
||||
union ac_video_format_caps fmts = dcap ? dcap->formats : ecap->formats;
|
||||
if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) {
|
||||
if (fmts.nv12)
|
||||
profile_formats[0] = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
|
||||
} else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) {
|
||||
if (fmts.p010)
|
||||
profile_formats[0] = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
|
||||
else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR)
|
||||
} else if (profile->lumaBitDepth == VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) {
|
||||
if (fmts.p012)
|
||||
profile_formats[0] = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
/* All profiles must share the same format. */
|
||||
if (formats[j] != VK_FORMAT_UNDEFINED && formats[j] != profile_formats[j])
|
||||
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
|
||||
|
||||
formats[j] = profile_formats[j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* On AMD, we need a codec specified for qp map as the extents differ. */
|
||||
if (pVideoFormatInfo->imageUsage & VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR)
|
||||
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
|
||||
|
||||
formats[0] = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
/* All profiles must share the same format. */
|
||||
if (formats[j] != VK_FORMAT_UNDEFINED && formats[j] != profile_formats[j])
|
||||
return VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR;
|
||||
|
||||
formats[j] = profile_formats[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (formats[0] == VK_FORMAT_UNDEFINED)
|
||||
|
|
@ -1821,7 +1731,7 @@ get_av1_param(struct radv_video_session *vid, struct vk_video_session_parameters
|
|||
av1->ref_frame_id_list[i] = 0x7f;
|
||||
|
||||
uint16_t used_slots = 1 << av1->cur_id;
|
||||
int idxs[RADV_VIDEO_AV1_MAX_DPB_SLOTS];
|
||||
int idxs[STD_VIDEO_AV1_NUM_REF_FRAMES + 1];
|
||||
unsigned i = 0;
|
||||
for (i = 0; i < frame_info->referenceSlotCount; i++) {
|
||||
int idx = frame_info->pReferenceSlots[i].slotIndex;
|
||||
|
|
@ -2013,15 +1923,12 @@ fill_surface(struct radv_cmd_buffer *cmd_buf, struct radv_image *img, uint32_t s
|
|||
static enum ac_video_dec_tier
|
||||
select_tier(struct radv_device *device, struct radv_video_session *vid, const struct VkVideoDecodeInfoKHR *frame_info)
|
||||
{
|
||||
struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
struct radv_image_view *dst_iv = radv_image_view_from_handle(frame_info->dstPictureResource.imageViewBinding);
|
||||
struct radv_image_plane *luma = &dst_iv->image->planes[0];
|
||||
|
||||
if (vid->dec->tiers & AC_VIDEO_DEC_TIER3 && radv_enable_tier3(pdev, vid->vk.op)) {
|
||||
if (vid->dec->tiers & AC_VIDEO_DEC_TIER3) {
|
||||
VkImageUsageFlags coincide = VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR;
|
||||
if (luma->surface.is_linear || (dst_iv->image->vk.usage & coincide) != coincide)
|
||||
return AC_VIDEO_DEC_TIER2;
|
||||
else
|
||||
if (!luma->surface.is_linear && (dst_iv->image->vk.usage & coincide) == coincide)
|
||||
return AC_VIDEO_DEC_TIER3;
|
||||
}
|
||||
|
||||
|
|
@ -2206,18 +2113,3 @@ radv_video_get_uvd_dpb_image(struct radv_physical_device *pdev, const struct VkV
|
|||
image->size = MAX2(image->size, ac_video_dec_dpb_size(&pdev->info, ¶m));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
radv_video_decode_vp9_supported(const struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_5_0_0)
|
||||
return radv_check_vcn_fw_version(pdev, 9, 7, 18);
|
||||
else if (pdev->info.vcn_ip_version >= VCN_4_0_0)
|
||||
return radv_check_vcn_fw_version(pdev, 9, 23, 13);
|
||||
else if (pdev->info.vcn_ip_version >= VCN_3_0_0)
|
||||
return radv_check_vcn_fw_version(pdev, 4, 33, 7);
|
||||
else if (pdev->info.vcn_ip_version >= VCN_2_0_0)
|
||||
return radv_check_vcn_fw_version(pdev, 8, 24, 4);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,19 +57,6 @@ struct radv_video_session {
|
|||
uint32_t enc_wa_flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* WRITE_MEMORY support in FW.
|
||||
*
|
||||
* none: Not supported at all. Old VCN FW and all UVD.
|
||||
* pcie_atomics: Supported, relies on PCIe atomics.
|
||||
* full: Supported, works also without PCIe atomics.
|
||||
*/
|
||||
enum radv_video_write_memory_support {
|
||||
RADV_VIDEO_WRITE_MEMORY_SUPPORT_NONE = 0,
|
||||
RADV_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS,
|
||||
RADV_VIDEO_WRITE_MEMORY_SUPPORT_FULL,
|
||||
};
|
||||
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(radv_video_session, vk.base, VkVideoSessionKHR, VK_OBJECT_TYPE_VIDEO_SESSION_KHR)
|
||||
|
||||
void radv_init_physical_device_decoder(struct radv_physical_device *pdev);
|
||||
|
|
@ -96,11 +83,7 @@ void radv_video_get_uvd_dpb_image(struct radv_physical_device *pdev,
|
|||
const struct VkVideoProfileListInfoKHR *profile_list, struct radv_image *image);
|
||||
void radv_video_get_enc_dpb_image(struct radv_device *device, const struct VkVideoProfileListInfoKHR *profile_list,
|
||||
struct radv_image *image, struct radv_image_create_info *create_info);
|
||||
bool radv_video_decode_vp9_supported(const struct radv_physical_device *pdev);
|
||||
bool radv_video_encode_av1_supported(const struct radv_physical_device *pdev);
|
||||
bool radv_video_encode_qp_map_supported(const struct radv_physical_device *pdev);
|
||||
enum radv_video_write_memory_support radv_video_write_memory_supported(const struct radv_physical_device *pdev);
|
||||
uint32_t radv_video_get_qp_map_texel_size(VkVideoCodecOperationFlagBitsKHR codec);
|
||||
bool radv_check_vcn_fw_version(const struct radv_physical_device *pdev, uint32_t dec, uint32_t enc, uint32_t rev);
|
||||
void radv_video_get_caps(struct radv_physical_device *pdev, VkVideoCodecOperationFlagBitsKHR op,
|
||||
struct ac_video_dec_codec_caps **dec, struct ac_video_enc_codec_caps **enc);
|
||||
|
||||
#endif /* RADV_VIDEO_H */
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ radv_probe_video_encode(struct radv_physical_device *pdev)
|
|||
return;
|
||||
|
||||
/* WRITE_MEMORY is needed for SetEvent and is required to pass CTS */
|
||||
if (radv_video_write_memory_supported(pdev)) {
|
||||
if (pdev->info.video_caps.queue[AMD_IP_VCN_ENC].write_memory != AC_VIDEO_WRITE_MEMORY_SUPPORT_NONE) {
|
||||
pdev->video_encode_enabled = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -3090,7 +3090,8 @@ radv_vcn_encode_video(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInf
|
|||
|
||||
if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_2) {
|
||||
radv_vcn_sq_tail(cs, &cmd_buffer->video.sq);
|
||||
if (feedback_query_va && radv_video_write_memory_supported(pdev) == RADV_VIDEO_WRITE_MEMORY_SUPPORT_FULL)
|
||||
if (feedback_query_va &&
|
||||
pdev->info.video_caps.queue[AMD_IP_VCN_ENC].write_memory == AC_VIDEO_WRITE_MEMORY_SUPPORT_FULL)
|
||||
radv_vcn_write_memory(cmd_buffer, feedback_query_va + RADV_ENC_FEEDBACK_STATUS_IDX * sizeof(uint32_t), 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -3417,14 +3418,15 @@ void
|
|||
radv_video_patch_encode_session_parameters(struct radv_device *device, struct vk_video_session_parameters *params)
|
||||
{
|
||||
struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
struct ac_video_enc_codec_caps *caps;
|
||||
|
||||
switch (params->op) {
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
|
||||
caps = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_AVC];
|
||||
for (unsigned i = 0; i < params->h264_enc.h264_pps_count; i++) {
|
||||
params->h264_enc.h264_pps[i].base.pic_init_qp_minus26 = 0;
|
||||
params->h264_enc.h264_pps[i].base.pic_init_qs_minus26 = 0;
|
||||
if (pdev->enc_hw_ver < RADV_VIDEO_ENC_HW_5 ||
|
||||
!params->h264_enc.h264_pps[i].base.flags.entropy_coding_mode_flag)
|
||||
if (!caps->avc.transform_8x8 || !params->h264_enc.h264_pps[i].base.flags.entropy_coding_mode_flag)
|
||||
params->h264_enc.h264_pps[i].base.flags.transform_8x8_mode_flag = 0;
|
||||
|
||||
params->h264_enc.h264_pps[i].base.num_ref_idx_l0_default_active_minus1 = 0;
|
||||
|
|
@ -3432,12 +3434,16 @@ radv_video_patch_encode_session_parameters(struct radv_device *device, struct vk
|
|||
}
|
||||
break;
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR: {
|
||||
caps = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_HEVC];
|
||||
for (unsigned i = 0; i < params->h265_enc.h265_sps_count; i++) {
|
||||
VkExtent2D extent = {
|
||||
.width = params->h265_enc.h265_sps[i].base.pic_width_in_luma_samples,
|
||||
.height = params->h265_enc.h265_sps[i].base.pic_height_in_luma_samples,
|
||||
};
|
||||
VkExtent2D aligned_extent = radv_enc_aligned_coded_extent(pdev, params->op, extent);
|
||||
VkExtent2D aligned_extent = {
|
||||
.width = align(extent.width, caps->width_alignment),
|
||||
.height = align(extent.height, caps->height_alignment),
|
||||
};
|
||||
|
||||
/* Override the unaligned pic_{width,height} and make up for it with conformance window
|
||||
* cropping */
|
||||
|
|
@ -3450,25 +3456,22 @@ radv_video_patch_encode_session_parameters(struct radv_device *device, struct vk
|
|||
params->h265_enc.h265_sps[i].base.conf_win_bottom_offset += (aligned_extent.height - extent.height) / 2;
|
||||
}
|
||||
|
||||
/* VCN supports only the following block sizes (resulting in 64x64 CTBs with any coding
|
||||
* block size) */
|
||||
params->h265_enc.h265_sps[i].base.log2_min_luma_coding_block_size_minus3 = 0;
|
||||
params->h265_enc.h265_sps[i].base.log2_diff_max_min_luma_coding_block_size = 3;
|
||||
params->h265_enc.h265_sps[i].base.log2_min_luma_transform_block_size_minus2 = 0;
|
||||
params->h265_enc.h265_sps[i].base.log2_diff_max_min_luma_transform_block_size = 3;
|
||||
params->h265_enc.h265_sps[i].base.log2_min_luma_coding_block_size_minus3 =
|
||||
caps->hevc.log2_min_luma_coding_block_size_minus3;
|
||||
params->h265_enc.h265_sps[i].base.log2_diff_max_min_luma_coding_block_size =
|
||||
caps->hevc.log2_diff_max_min_luma_coding_block_size;
|
||||
params->h265_enc.h265_sps[i].base.log2_min_luma_transform_block_size_minus2 =
|
||||
caps->hevc.log2_min_luma_transform_block_size_minus2;
|
||||
params->h265_enc.h265_sps[i].base.log2_diff_max_min_luma_transform_block_size =
|
||||
caps->hevc.log2_diff_max_min_luma_transform_block_size;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < params->h265_enc.h265_pps_count; i++) {
|
||||
/* cu_qp_delta needs to be enabled if rate control is enabled. VCN2 and newer can also enable
|
||||
* it with rate control disabled. Since we don't know what rate control will be used, we
|
||||
* need to always force enable it.
|
||||
* On VCN1 rate control modes are disabled.
|
||||
*/
|
||||
params->h265_enc.h265_pps[i].base.flags.cu_qp_delta_enabled_flag = !!(pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_2);
|
||||
params->h265_enc.h265_pps[i].base.flags.cu_qp_delta_enabled_flag = caps->hevc.cu_qp_delta ? 1 : 0;
|
||||
params->h265_enc.h265_pps[i].base.diff_cu_qp_delta_depth = 0;
|
||||
params->h265_enc.h265_pps[i].base.init_qp_minus26 = 0;
|
||||
params->h265_enc.h265_pps[i].base.flags.dependent_slice_segments_enabled_flag = 1;
|
||||
if (pdev->enc_hw_ver < RADV_VIDEO_ENC_HW_3)
|
||||
if (!caps->hevc.transform_skip)
|
||||
params->h265_enc.h265_pps[i].base.flags.transform_skip_enabled_flag = 0;
|
||||
|
||||
params->h265_enc.h265_pps[i].base.num_ref_idx_l0_default_active_minus1 = 0;
|
||||
|
|
@ -3477,12 +3480,16 @@ radv_video_patch_encode_session_parameters(struct radv_device *device, struct vk
|
|||
break;
|
||||
}
|
||||
case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR: {
|
||||
caps = &pdev->info.video_caps.enc[AC_VIDEO_CODEC_AV1];
|
||||
/* If the resolution isn't aligned, we need to override it. */
|
||||
VkExtent2D extent = {
|
||||
.width = params->av1_enc.seq_hdr.base.max_frame_width_minus_1 + 1,
|
||||
.height = params->av1_enc.seq_hdr.base.max_frame_height_minus_1 + 1,
|
||||
};
|
||||
VkExtent2D aligned_extent = radv_enc_aligned_coded_extent(pdev, params->op, extent);
|
||||
VkExtent2D aligned_extent = {
|
||||
.width = align(extent.width, caps->width_alignment),
|
||||
.height = align(extent.height, caps->height_alignment),
|
||||
};
|
||||
params->av1_enc.seq_hdr.base.max_frame_width_minus_1 = aligned_extent.width - 1;
|
||||
params->av1_enc.seq_hdr.base.max_frame_height_minus_1 = aligned_extent.height - 1;
|
||||
|
||||
|
|
@ -3651,9 +3658,10 @@ radv_video_get_encode_session_memory_requirements(struct radv_device *device, st
|
|||
|
||||
if (vid->vk.flags & VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR &&
|
||||
pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_5) {
|
||||
const uint32_t texel_size = radv_video_get_qp_map_texel_size(vid->vk.op);
|
||||
const uint32_t map_width = DIV_ROUND_UP(vid->vk.max_coded.width, texel_size);
|
||||
const uint32_t map_height = DIV_ROUND_UP(vid->vk.max_coded.height, texel_size);
|
||||
struct ac_video_enc_codec_caps *caps;
|
||||
radv_video_get_caps(pdev, vid->vk.op, NULL, &caps);
|
||||
const uint32_t map_width = DIV_ROUND_UP(vid->vk.max_coded.width, caps->qp_map_texel_size);
|
||||
const uint32_t map_height = DIV_ROUND_UP(vid->vk.max_coded.height, caps->qp_map_texel_size);
|
||||
|
||||
vk_outarray_append_typed(VkVideoSessionMemoryRequirementsKHR, &out, m)
|
||||
{
|
||||
|
|
@ -3726,41 +3734,3 @@ radv_video_get_enc_dpb_image(struct radv_device *device, const struct VkVideoPro
|
|||
}
|
||||
image->alignment = ENC_ALIGNMENT;
|
||||
}
|
||||
|
||||
bool
|
||||
radv_video_encode_av1_supported(const struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_5_0_0) {
|
||||
return true;
|
||||
} else if (pdev->info.vcn_ip_version >= VCN_4_0_0) {
|
||||
return pdev->info.vcn_ip_version != VCN_4_0_3 && pdev->info.vcn_enc_minor_version >= 20;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
radv_video_encode_qp_map_supported(const struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_5_0_0)
|
||||
return radv_check_vcn_fw_version(pdev, 9, 9, 28);
|
||||
return true;
|
||||
}
|
||||
|
||||
enum radv_video_write_memory_support
|
||||
radv_video_write_memory_supported(const struct radv_physical_device *pdev)
|
||||
{
|
||||
if (pdev->info.vcn_ip_version >= VCN_5_0_0) {
|
||||
return RADV_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS;
|
||||
} else if (pdev->info.vcn_ip_version >= VCN_4_0_0) {
|
||||
if (pdev->info.vcn_enc_minor_version >= 22)
|
||||
return RADV_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS;
|
||||
} else if (pdev->info.vcn_ip_version >= VCN_3_0_0) {
|
||||
if (pdev->info.vcn_enc_minor_version >= 33)
|
||||
return RADV_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS;
|
||||
} else if (pdev->info.vcn_ip_version >= VCN_2_0_0) {
|
||||
if (pdev->info.vcn_enc_minor_version >= 24)
|
||||
return RADV_VIDEO_WRITE_MEMORY_SUPPORT_PCIE_ATOMICS;
|
||||
}
|
||||
return RADV_VIDEO_WRITE_MEMORY_SUPPORT_NONE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue