diff --git a/src/amd/common/ac_vcn_enc.h b/src/amd/common/ac_vcn_enc.h index 8615f898cd1..ebff3a55b1b 100644 --- a/src/amd/common/ac_vcn_enc.h +++ b/src/amd/common/ac_vcn_enc.h @@ -312,6 +312,10 @@ typedef struct rvcn_enc_rate_ctl_layer_init_s { } rvcn_enc_rate_ctl_layer_init_t; typedef struct rvcn_enc_rate_ctl_per_picture_s { + uint32_t qp; + uint32_t min_qp_app; + uint32_t max_qp_app; + uint32_t max_au_size; uint32_t qp_i; uint32_t qp_p; uint32_t qp_b; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c index d9b1beefac5..3d3462cb28d 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c @@ -261,6 +261,10 @@ static void radeon_vcn_enc_h264_get_rc_param(struct radeon_encoder *enc, frame_rate_num); } enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl[0].vbv_buf_lv; + enc->enc_pic.rc_per_pic.qp = pic->quant_i_frames; + enc->enc_pic.rc_per_pic.min_qp_app = pic->rate_ctrl[0].min_qp; + enc->enc_pic.rc_per_pic.max_qp_app = pic->rate_ctrl[0].max_qp ? + pic->rate_ctrl[0].max_qp : 51; enc->enc_pic.rc_per_pic.qp_i = pic->quant_i_frames; enc->enc_pic.rc_per_pic.qp_p = pic->quant_p_frames; enc->enc_pic.rc_per_pic.qp_b = pic->quant_b_frames; @@ -291,6 +295,7 @@ static void radeon_vcn_enc_h264_get_rc_param(struct radeon_encoder *enc, default: enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; } + enc->enc_pic.rc_per_pic.max_au_size = pic->rate_ctrl[0].max_au_size; enc->enc_pic.rc_per_pic.max_au_size_i = pic->rate_ctrl[0].max_au_size; enc->enc_pic.rc_per_pic.max_au_size_p = pic->rate_ctrl[0].max_au_size; enc->enc_pic.rc_per_pic.max_au_size_b = pic->rate_ctrl[0].max_au_size; @@ -513,6 +518,9 @@ static void radeon_vcn_enc_hevc_get_rc_param(struct radeon_encoder *enc, frame_rate_den, frame_rate_num); enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv; + enc->enc_pic.rc_per_pic.qp = pic->rc.quant_i_frames; + enc->enc_pic.rc_per_pic.min_qp_app = pic->rc.min_qp; + enc->enc_pic.rc_per_pic.max_qp_app = pic->rc.max_qp ? pic->rc.max_qp : 51; enc->enc_pic.rc_per_pic.qp_i = pic->rc.quant_i_frames; enc->enc_pic.rc_per_pic.qp_p = pic->rc.quant_p_frames; enc->enc_pic.rc_per_pic.min_qp_i = pic->rc.min_qp; @@ -539,6 +547,7 @@ static void radeon_vcn_enc_hevc_get_rc_param(struct radeon_encoder *enc, default: enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; } + enc->enc_pic.rc_per_pic.max_au_size = pic->rc.max_au_size; enc->enc_pic.rc_per_pic.max_au_size_i = pic->rc.max_au_size; enc->enc_pic.rc_per_pic.max_au_size_p = pic->rc.max_au_size; } @@ -737,6 +746,9 @@ static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc, frame_rate_num); } enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc[0].vbv_buf_lv; + enc->enc_pic.rc_per_pic.qp = pic->rc[0].qp; + enc->enc_pic.rc_per_pic.min_qp_app = pic->rc[0].min_qp ? pic->rc[0].min_qp : 1; + enc->enc_pic.rc_per_pic.max_qp_app = pic->rc[0].max_qp ? pic->rc[0].max_qp : 255; enc->enc_pic.rc_per_pic.qp_i = pic->rc[0].qp; enc->enc_pic.rc_per_pic.qp_p = pic->rc[0].qp_inter; min_qp = pic->rc[0].min_qp ? pic->rc[0].min_qp : 1; @@ -764,6 +776,7 @@ static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc, default: enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; } + enc->enc_pic.rc_per_pic.max_au_size = pic->rc[0].max_au_size; enc->enc_pic.rc_per_pic.max_au_size_i = pic->rc[0].max_au_size; enc->enc_pic.rc_per_pic.max_au_size_p = pic->rc[0].max_au_size; } @@ -1333,14 +1346,28 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, goto error; } - if (sscreen->info.vcn_ip_version >= VCN_4_0_0) + enc->enc_pic.use_rc_per_pic_ex = false; + + if (sscreen->info.vcn_ip_version >= VCN_4_0_0) { + if (sscreen->info.vcn_enc_minor_version >= 1) + enc->enc_pic.use_rc_per_pic_ex = true; radeon_enc_4_0_init(enc); - else if (sscreen->info.vcn_ip_version >= VCN_3_0_0) + } + else if (sscreen->info.vcn_ip_version >= VCN_3_0_0) { + if (sscreen->info.vcn_enc_minor_version >= 24) + enc->enc_pic.use_rc_per_pic_ex = true; radeon_enc_3_0_init(enc); - else if (sscreen->info.vcn_ip_version >= VCN_2_0_0) + } + else if (sscreen->info.vcn_ip_version >= VCN_2_0_0) { + if (sscreen->info.vcn_enc_minor_version >= 18) + enc->enc_pic.use_rc_per_pic_ex = true; radeon_enc_2_0_init(enc); - else + } + else { + if (sscreen->info.vcn_enc_minor_version >= 15) + enc->enc_pic.use_rc_per_pic_ex = true; radeon_enc_1_2_init(enc); + } return &enc->base; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h index 2c173057086..7fa80e3e97e 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h @@ -107,6 +107,7 @@ struct radeon_enc_pic { bool sample_adaptive_offset_enabled_flag; bool pcm_enabled_flag; bool sps_temporal_mvp_enabled_flag; + bool use_rc_per_pic_ex; struct { struct { diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c index 6df548cdcc4..20efe2ad650 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c @@ -25,7 +25,7 @@ #define RENCODE_IB_PARAM_LAYER_SELECT 0x00000005 #define RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x00000006 #define RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x00000007 -#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x0000001d +#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x00000008 #define RENCODE_IB_PARAM_QUALITY_PARAMS 0x00000009 #define RENCODE_IB_PARAM_SLICE_HEADER 0x0000000a #define RENCODE_IB_PARAM_ENCODE_PARAMS 0x0000000b @@ -33,6 +33,7 @@ #define RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x0000000d #define RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER 0x0000000e #define RENCODE_IB_PARAM_FEEDBACK_BUFFER 0x00000010 +#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PIC_EX 0x0000001d #define RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU 0x00000020 #define RENCODE_IB_PARAM_QP_MAP 0x00000021 #define RENCODE_IB_PARAM_ENCODE_STATISTICS 0x00000024 @@ -1188,6 +1189,19 @@ static void radeon_enc_intra_refresh(struct radeon_encoder *enc) } static void radeon_enc_rc_per_pic(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(enc->cmd.rc_per_pic); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_app); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_app); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enabled_filler_data); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.skip_frame_enable); + RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enforce_hrd); + RADEON_ENC_END(); +} + +static void radeon_enc_rc_per_pic_ex(struct radeon_encoder *enc) { enc->enc_pic.rc_per_pic.reserved_0xff = 0xFFFFFFFF; @@ -1579,7 +1593,10 @@ void radeon_enc_1_2_init(struct radeon_encoder *enc) enc->bitstream = radeon_enc_bitstream; enc->feedback = radeon_enc_feedback; enc->intra_refresh = radeon_enc_intra_refresh; - enc->rc_per_pic = radeon_enc_rc_per_pic; + if (enc->enc_pic.use_rc_per_pic_ex == true) + enc->rc_per_pic = radeon_enc_rc_per_pic_ex; + else + enc->rc_per_pic = radeon_enc_rc_per_pic; enc->encode_params = radeon_enc_encode_params; enc->op_init = radeon_enc_op_init; enc->op_close = radeon_enc_op_close; @@ -1621,7 +1638,10 @@ void radeon_enc_1_2_init(struct radeon_encoder *enc) enc->cmd.layer_select = RENCODE_IB_PARAM_LAYER_SELECT; enc->cmd.rc_session_init = RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT; enc->cmd.rc_layer_init = RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT; - enc->cmd.rc_per_pic = RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE; + if (enc->enc_pic.use_rc_per_pic_ex == true) + enc->cmd.rc_per_pic = RENCODE_IB_PARAM_RATE_CONTROL_PER_PIC_EX; + else + enc->cmd.rc_per_pic = RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE; enc->cmd.quality_params = RENCODE_IB_PARAM_QUALITY_PARAMS; enc->cmd.nalu = RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU; enc->cmd.slice_header = RENCODE_IB_PARAM_SLICE_HEADER;