From 306c6e12a59be20bad8838f33382975d379d7db4 Mon Sep 17 00:00:00 2001 From: Ruijing Dong Date: Wed, 19 Apr 2023 14:04:14 -0400 Subject: [PATCH] frontends/va: define va av1 encoding caps by having va av1 caps enabled, av1 vaapi encoding is enabled. Reviewed-by: Sil Vilerino Reviewed-by: Boyuan Zhang Signed-off-by: Ruijing Dong Part-of: --- src/gallium/drivers/radeonsi/si_get.c | 79 +++++++++++++++++++++++++++--- src/gallium/frontends/va/config.c | 78 ++++++++++++++++++++++++++--- src/gallium/frontends/va/picture.c | 18 ++++++- src/gallium/frontends/va/picture_av1_enc.c | 3 ++ src/gallium/frontends/va/va_private.h | 3 ++ src/gallium/include/pipe/p_video_enums.h | 28 +++++++++-- 6 files changed, 193 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index a943614..eab7ae2 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -601,7 +601,8 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil (sscreen->info.family >= CHIP_RAVEN || si_vce_is_fw_version_supported(sscreen))) || (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN && (sscreen->info.family >= CHIP_RAVEN || si_radeon_uvd_enc_supported(sscreen))) || - (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10 && sscreen->info.family >= CHIP_RENOIR))); + (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10 && sscreen->info.family >= CHIP_RENOIR) || + (profile == PIPE_VIDEO_PROFILE_AV1_MAIN && (sscreen->info.family >= CHIP_GFX1100)))); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MIN_WIDTH: @@ -699,6 +700,71 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil } else return 0; + case PIPE_VIDEO_CAP_ENC_AV1_FEATURE: + if (sscreen->info.family >= CHIP_GFX1100) { + union pipe_av1_enc_cap_features attrib; + attrib.value = 0; + + attrib.bits.support_128x128_superblock = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_filter_intra = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_intra_edge_filter = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_interintra_compound = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_masked_compound = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_warped_motion = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_palette_mode = PIPE_ENC_FEATURE_SUPPORTED; + attrib.bits.support_dual_filter = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_jnt_comp = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_ref_frame_mvs = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_superres = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_restoration = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_allow_intrabc = PIPE_ENC_FEATURE_NOT_SUPPORTED; + attrib.bits.support_cdef_channel_strength = PIPE_ENC_FEATURE_SUPPORTED; + + return attrib.value; + } else + return 0; + + case PIPE_VIDEO_CAP_ENC_AV1_FEATURE_EXT1: + if (sscreen->info.family >= CHIP_GFX1100) { + union pipe_av1_enc_cap_features_ext1 attrib_ext1; + attrib_ext1.value = 0; + attrib_ext1.bits.interpolation_filter = PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_EIGHT_TAP | + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_EIGHT_TAP_SMOOTH | + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_EIGHT_TAP_SHARP | + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_BILINEAR | + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_SWITCHABLE; + attrib_ext1.bits.min_segid_block_size_accepted = 0; + attrib_ext1.bits.segment_feature_support = 0; + + return attrib_ext1.value; + } else + return 0; + + case PIPE_VIDEO_CAP_ENC_AV1_FEATURE_EXT2: + if (sscreen->info.family >= CHIP_GFX1100) { + union pipe_av1_enc_cap_features_ext2 attrib_ext2; + attrib_ext2.value = 0; + + attrib_ext2.bits.tile_size_bytes_minus1 = 1; + attrib_ext2.bits.obu_size_bytes_minus1 = 1; + /** + * tx_mode supported. + * (tx_mode_support & 0x01) == 1: ONLY_4X4 is supported, 0: not. + * (tx_mode_support & 0x02) == 1: TX_MODE_LARGEST is supported, 0: not. + * (tx_mode_support & 0x04) == 1: TX_MODE_SELECT is supported, 0: not. + */ + attrib_ext2.bits.tx_mode_support = PIPE_VIDEO_CAP_ENC_AV1_TX_MODE_SELECT; + attrib_ext2.bits.max_tile_num_minus1 = 31; + + return attrib_ext2.value; + } else + return 0; + case PIPE_VIDEO_CAP_ENC_SUPPORTS_TILE: + if (sscreen->info.family >= CHIP_GFX1100 && profile == PIPE_VIDEO_PROFILE_AV1_MAIN) + return 1; + else + return 0; + default: return 0; } @@ -916,12 +982,13 @@ static bool si_vid_is_format_supported(struct pipe_screen *screen, enum pipe_for } } - /* support 10 bit input for encoding on some of the chips with vcn 2.0 and up */ - if (profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH && - entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - sscreen->info.family >= CHIP_RENOIR) { + if ((entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) && + (((profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH) && + (sscreen->info.family >= CHIP_RENOIR)) || + ((profile == PIPE_VIDEO_PROFILE_AV1_MAIN) && + (sscreen->info.family >= CHIP_GFX1100)))) return (format == PIPE_FORMAT_P010 || format == PIPE_FORMAT_NV12); - } + /* we can only handle this one with UVD */ if (profile != PIPE_VIDEO_PROFILE_UNKNOWN) diff --git a/src/gallium/frontends/va/config.c b/src/gallium/frontends/va/config.c index 1b3a487..180b1b1 100644 --- a/src/gallium/frontends/va/config.c +++ b/src/gallium/frontends/va/config.c @@ -235,8 +235,10 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en break; case VAConfigAttribEncPackedHeaders: value = VA_ENC_PACKED_HEADER_NONE; - if (u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_HEVC) + if ((u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_HEVC)) value |= VA_ENC_PACKED_HEADER_SEQUENCE; + else if (u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_AV1) + value |= (VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE); break; case VAConfigAttribEncMaxSlices: { @@ -391,6 +393,70 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = h265_enc_pred_direction; } break; #endif +#if VA_CHECK_VERSION(1, 16, 0) + case VAConfigAttribEncAV1: + { + union pipe_av1_enc_cap_features features; + features.value = 0; + + int support = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_AV1_FEATURE); + if (support <= 0) + value = VA_ATTRIB_NOT_SUPPORTED; + else { + VAConfigAttribValEncAV1 attrib; + features.value = support; + attrib.value = features.value; + value = attrib.value; + } + } break; + case VAConfigAttribEncAV1Ext1: + { + union pipe_av1_enc_cap_features_ext1 features_ext1; + features_ext1.value = 0; + int support = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_AV1_FEATURE_EXT1); + if (support <= 0) + value = VA_ATTRIB_NOT_SUPPORTED; + else { + VAConfigAttribValEncAV1Ext1 attrib; + features_ext1.value = support; + attrib.value = features_ext1.value; + value = attrib.value; + } + + } break; + case VAConfigAttribEncAV1Ext2: + { + union pipe_av1_enc_cap_features_ext2 features_ext2; + features_ext2.value = 0; + + int support = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_AV1_FEATURE_EXT2); + if (support <= 0) + value = VA_ATTRIB_NOT_SUPPORTED; + else { + VAConfigAttribValEncAV1Ext2 attrib; + features_ext2.value = support; + attrib.value = features_ext2.value; + value = attrib.value; + } + + } break; + case VAConfigAttribEncTileSupport: + { + int encode_tile_support = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_SUPPORTS_TILE); + if (encode_tile_support <= 0) + value = VA_ATTRIB_NOT_SUPPORTED; + else + value = encode_tile_support; + } break; +#endif default: value = VA_ATTRIB_NOT_SUPPORTED; break; @@ -549,11 +615,11 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin } } if (attrib_list[i].type == VAConfigAttribEncPackedHeaders) { - if ((attrib_list[i].value > 1) || - (attrib_list[i].value && - u_reduce_video_profile(ProfileToPipe(profile)) != - PIPE_VIDEO_FORMAT_HEVC) || - (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE)) { + if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE || + (((attrib_list[i].value != 1) || u_reduce_video_profile(ProfileToPipe(profile)) + != PIPE_VIDEO_FORMAT_HEVC) && + ((attrib_list[i].value != 3) || u_reduce_video_profile(ProfileToPipe(profile)) + != PIPE_VIDEO_FORMAT_AV1))) { FREE(config); return VA_STATUS_ERROR_INVALID_VALUE; } diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index 90b8fd5..e7d4454 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -432,10 +432,11 @@ handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameter status = vlVaHandleVAEncMiscParameterTypeRateControlHEVC(context, misc); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncMiscParameterTypeRateControlAV1(context, misc); break; - +#endif default: break; } @@ -457,9 +458,11 @@ handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBu status = vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(context, misc); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncMiscParameterTypeFrameRateAV1(context, misc); break; +#endif default: break; } @@ -501,9 +504,11 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl status = vlVaHandleVAEncSequenceParameterBufferTypeHEVC(drv, context, buf); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncSequenceParameterBufferTypeAV1(drv, context, buf); break; +#endif default: break; @@ -526,9 +531,11 @@ handleVAEncMiscParameterTypeQualityLevel(vlVaContext *context, VAEncMiscParamete status = vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(context, misc); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncMiscParameterTypeQualityLevelAV1(context, misc); break; +#endif default: break; @@ -551,8 +558,11 @@ handleVAEncMiscParameterTypeMaxFrameSize(vlVaContext *context, VAEncMiscParamete status = vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(context, misc); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncMiscParameterTypeMaxFrameSizeAV1(context, misc); + break; +#endif default: break; @@ -574,9 +584,11 @@ handleVAEncMiscParameterTypeHRD(vlVaContext *context, VAEncMiscParameterBuffer * status = vlVaHandleVAEncMiscParameterTypeHRDHEVC(context, misc); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncMiscParameterTypeHRDAV1(context, misc); break; +#endif default: break; @@ -638,9 +650,11 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV status = vlVaHandleVAEncPictureParameterBufferTypeHEVC(drv, context, buf); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncPictureParameterBufferTypeAV1(drv, context, buf); break; +#endif default: break; @@ -707,9 +721,11 @@ handleVAEncPackedHeaderDataBufferType(vlVaContext *context, vlVaBuffer *buf) status = vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(context, buf); break; +#if VA_CHECK_VERSION(1, 16, 0) case PIPE_VIDEO_FORMAT_AV1: status = vlVaHandleVAEncPackedHeaderDataBufferTypeAV1(context, buf); break; +#endif default: break; diff --git a/src/gallium/frontends/va/picture_av1_enc.c b/src/gallium/frontends/va/picture_av1_enc.c index 165d3c6..0acec99 100644 --- a/src/gallium/frontends/va/picture_av1_enc.c +++ b/src/gallium/frontends/va/picture_av1_enc.c @@ -30,6 +30,8 @@ #include "va_private.h" #include "util/vl_vlc.h" +#if VA_CHECK_VERSION(1, 16, 0) + #define AV1_SELECT_SCREEN_CONTENT_TOOLS (2) #define AV1_SELECT_INTEGER_MV (2) #define AV1_PRIMARY_REF_NON (7) @@ -698,3 +700,4 @@ void getEncParamPresetAV1(vlVaContext *context) } } +#endif /* VA_CHECK_VERSION(1, 16, 0) */ diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index dac0779..891a7c5 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -554,6 +554,8 @@ VAStatus vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlV VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeHRDHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); + +#if VA_CHECK_VERSION(1, 16, 0) VAStatus vlVaHandleVAEncSequenceParameterBufferTypeAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeRateControlAV1(vlVaContext *context, VAEncMiscParameterBuffer *buf); @@ -562,4 +564,5 @@ VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateAV1(vlVaContext *context, VAEn VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelAV1(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeMaxFrameSizeAV1(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeHRDAV1(vlVaContext *context, VAEncMiscParameterBuffer *buf); +#endif #endif //VA_PRIVATE_H diff --git a/src/gallium/include/pipe/p_video_enums.h b/src/gallium/include/pipe/p_video_enums.h index c547f92..d4cbfa6 100644 --- a/src/gallium/include/pipe/p_video_enums.h +++ b/src/gallium/include/pipe/p_video_enums.h @@ -129,10 +129,33 @@ enum pipe_video_cap when it has reached its maximum async depth capacity */ PIPE_VIDEO_CAP_ENC_SUPPORTS_ASYNC_OPERATION = 33, - PIPE_VIDEO_CAP_MIN_WIDTH = 34, PIPE_VIDEO_CAP_MIN_HEIGHT = 35, - PIPE_VIDEO_CAP_ENC_RATE_CONTROL_QVBR = 36 + PIPE_VIDEO_CAP_ENC_RATE_CONTROL_QVBR = 36, + /* + AV1 encoding features list + */ + PIPE_VIDEO_CAP_ENC_AV1_FEATURE = 37, + PIPE_VIDEO_CAP_ENC_AV1_FEATURE_EXT1 = 38, + PIPE_VIDEO_CAP_ENC_AV1_FEATURE_EXT2 = 39, + PIPE_VIDEO_CAP_ENC_SUPPORTS_TILE = 40, +}; + +enum pipe_video_av1_enc_filter_mode +{ + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_EIGHT_TAP = (1 << 0), + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_EIGHT_TAP_SMOOTH = (1 << 1), + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_EIGHT_TAP_SHARP = (1 << 2), + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_BILINEAR = (1 << 3), + PIPE_VIDEO_CAP_ENC_AV1_INTERPOLATION_FILTER_SWITCHABLE = (1 << 4), + +}; + +enum pipe_video_av1_enc_tx_mode +{ + PIPE_VIDEO_CAP_ENC_AV1_TX_MODE_ONLY_4X4 = (1 << 0), + PIPE_VIDEO_CAP_ENC_AV1_TX_MODE_LARGEST = (1 << 1), + PIPE_VIDEO_CAP_ENC_AV1_TX_MODE_SELECT = (1 << 2), }; /* To be used with PIPE_VIDEO_CAP_VPP_ORIENTATION_MODES and for VPP state*/ @@ -188,7 +211,6 @@ enum pipe_video_cap_slice_structure PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_MULTI_ROWS = 0x00000020, }; - enum pipe_video_entrypoint { PIPE_VIDEO_ENTRYPOINT_UNKNOWN, -- 2.7.4