From c7883e3a71967575c6e9fb3dfab17b29837c7cc4 Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Thu, 23 Oct 2025 10:48:28 -0400 Subject: [PATCH] radeonsi/vcn: Check and override primary_ref_frame The primary_ref_frame is used to load CDF data and has to match between VCN and the header. Unless the default CDF tables are used, VCN currently always assumes the CDF data will be loaded from reference_frame_index (for VCN4) or lsm_reference_frame_index[0] (for VCN5). This may cause conflict with the application provided primary_ref_frame. Check to make sure the primary_ref_frame is the same frame as the used reference, and override it if necessary. Reviewed-by: Ruijing Dong Part-of: --- src/gallium/drivers/radeonsi/radeon_vcn_enc.c | 11 +++++++++++ src/gallium/drivers/radeonsi/radeon_vcn_enc.h | 1 + src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c index 9b7e7a5cddf..066103747b6 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c @@ -1035,6 +1035,17 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc, 0xffffffff : pic->dpb_ref_frame_idx[pic->ref_list0[0]]; enc_pic->enc_params.reconstructed_picture_index = pic->dpb_curr_pic; + /* primary_ref_frame can be NONE (7), otherwise it must have the same DPB + * index as the first ref pic. */ + if (pic->primary_ref_frame == 7 || + pic->ref_list0[0] == PIPE_H2645_LIST_REF_INVALID_ENTRY) + enc_pic->av1.primary_ref_frame = 7; + else if (pic->dpb_ref_frame_idx[pic->primary_ref_frame] == + pic->dpb_ref_frame_idx[pic->ref_list0[0]]) + enc_pic->av1.primary_ref_frame = pic->primary_ref_frame; + else + enc_pic->av1.primary_ref_frame = pic->ref_list0[0]; + if (sscreen->info.vcn_ip_version >= VCN_5_0_0) { bool allow_unidir = pic->rc[0].rate_ctrl_method == PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h index ae4027ca75e..1c234f75d43 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h @@ -86,6 +86,7 @@ struct radeon_enc_pic { struct pipe_av1_enc_picture_desc *desc; uint32_t coded_width; uint32_t coded_height; + uint32_t primary_ref_frame; bool compound; bool skip_mode_allowed; } av1; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c index 141e549a63a..9a8a8e35c9d 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c @@ -143,6 +143,7 @@ static void radeon_enc_cdf_default_table(struct radeon_encoder *enc) bool use_cdf_default = enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_KEY || enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_INTRA_ONLY || enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_SWITCH || + enc->enc_pic.av1.primary_ref_frame == 7 /* PRIMARY_REF_NONE */ || (enc->enc_pic.enable_error_resilient_mode); enc->enc_pic.av1_cdf_default_table.use_cdf_default = use_cdf_default ? 1 : 0; @@ -447,7 +448,7 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, struct radeo if (!frame_is_intra && !error_resilient_mode) /* primary_ref_frame */ - radeon_bs_code_fixed_bits(bs, av1->primary_ref_frame, 3); + radeon_bs_code_fixed_bits(bs, enc->enc_pic.av1.primary_ref_frame, 3); if ((enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_SWITCH) && (enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_KEY || !av1->show_frame))