diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c index 7a42948fa88..15073b71a57 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c @@ -535,8 +535,9 @@ static void radeon_enc_rec_offset(rvcn_enc_reconstructed_picture_t *recon, static int setup_dpb(struct radeon_encoder *enc) { - uint32_t rec_alignment = (u_reduce_video_profile(enc->base.profile) - == PIPE_VIDEO_FORMAT_MPEG4_AVC) ? 16 : 64; + bool is_h264 = u_reduce_video_profile(enc->base.profile) + == PIPE_VIDEO_FORMAT_MPEG4_AVC; + uint32_t rec_alignment = is_h264 ? 16 : 64; uint32_t aligned_width = align(enc->base.width, rec_alignment); uint32_t aligned_height = align(enc->base.height, rec_alignment); uint32_t aligned_chroma_height = align(aligned_height / 2, rec_alignment); @@ -561,6 +562,22 @@ static int setup_dpb(struct radeon_encoder *enc) enc_pic->ctx_buf.pre_encode_picture_chroma_pitch = pitch; offset = 0; + if (enc_pic->quality_modes.pre_encode_mode) { + uint32_t pre_size = ALIGN_TO((aligned_width >> 2), rec_alignment) * + ALIGN_TO((aligned_height >> 2), rec_alignment); + uint32_t full_size = ALIGN_TO(aligned_width, rec_alignment) * + ALIGN_TO(aligned_height, rec_alignment); + pre_size = align(pre_size, 4); + full_size = align(full_size, 4); + + enc_pic->ctx_buf.two_pass_search_center_map_offset = offset; + if (is_h264) + offset += align((pre_size * 4 + full_size) * sizeof(uint32_t), enc->alignment); + else + offset += align((pre_size * 52 + full_size) * sizeof(uint32_t), enc->alignment); + } else + enc_pic->ctx_buf.two_pass_search_center_map_offset = 0; + for (i = 0; i < num_reconstructed_pictures; i++) { radeon_enc_rec_offset(&enc_pic->ctx_buf.reconstructed_pictures[i], &offset, luma_size, chroma_size); diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h index 0971fd55f69..5b0646d31bc 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h @@ -309,6 +309,8 @@ typedef struct rvcn_enc_hevc_spec_misc_s { uint32_t cabac_init_flag; uint32_t half_pel_enabled; uint32_t quarter_pel_enabled; + uint32_t transform_skip_discarded; + uint32_t cu_qp_delta_enabled_flag; } rvcn_enc_hevc_spec_misc_t; typedef struct rvcn_enc_rate_ctl_session_init_s { @@ -342,6 +344,7 @@ typedef struct rvcn_enc_quality_params_s { uint32_t scene_change_sensitivity; uint32_t scene_change_min_idr_interval; uint32_t two_pass_search_center_map_mode; + uint32_t vbaq_strength; } rvcn_enc_quality_params_t; typedef struct rvcn_enc_direct_output_nalu_s { 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 9ca28cca3b8..2e690a59dad 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c @@ -242,7 +242,8 @@ static void radeon_enc_quality_params(struct radeon_encoder *enc) enc->enc_pic.quality_params.vbaq_mode = enc->enc_pic.quality_modes.vbaq_mode; enc->enc_pic.quality_params.scene_change_sensitivity = 0; enc->enc_pic.quality_params.scene_change_min_idr_interval = 0; - enc->enc_pic.quality_params.two_pass_search_center_map_mode = 0; + enc->enc_pic.quality_params.two_pass_search_center_map_mode = + (enc->enc_pic.quality_modes.pre_encode_mode) ? 1 : 0; RADEON_ENC_BEGIN(enc->cmd.quality_params); RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode); @@ -1504,7 +1505,6 @@ void radeon_enc_1_2_init(struct radeon_encoder *enc) enc->op_init_rc = radeon_enc_op_init_rc; enc->op_init_rc_vbv = radeon_enc_op_init_rc_vbv; enc->op_preset = radeon_enc_op_preset; - enc->encode_params = radeon_enc_encode_params; enc->session_init = radeon_enc_session_init; enc->encode_statistics = radeon_enc_encode_statistics; enc->nalu_aud = radeon_enc_nalu_aud; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c index 0ca223ffc5c..3d285fd0f71 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c @@ -84,6 +84,24 @@ static void radeon_enc_op_preset(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_quality_params(struct radeon_encoder *enc) +{ + enc->enc_pic.quality_params.vbaq_mode = enc->enc_pic.quality_modes.vbaq_mode; + enc->enc_pic.quality_params.scene_change_sensitivity = 0; + enc->enc_pic.quality_params.scene_change_min_idr_interval = 0; + enc->enc_pic.quality_params.two_pass_search_center_map_mode = + (enc->enc_pic.quality_modes.pre_encode_mode) ? 1 : 0; + enc->enc_pic.quality_params.vbaq_strength = 0; + + RADEON_ENC_BEGIN(enc->cmd.quality_params); + RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode); + RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_sensitivity); + RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_min_idr_interval); + RADEON_ENC_CS(enc->enc_pic.quality_params.two_pass_search_center_map_mode); + RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_strength); + RADEON_ENC_END(); +} + static void radeon_enc_slice_header_hevc(struct radeon_encoder *enc) { uint32_t instruction[RENCODE_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = {0}; @@ -506,6 +524,7 @@ void radeon_enc_2_0_init(struct radeon_encoder *enc) enc->output_format = radeon_enc_output_format; enc->ctx = radeon_enc_ctx; enc->op_preset = radeon_enc_op_preset; + enc->quality_params = radeon_enc_quality_params; if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { enc->deblocking_filter = radeon_enc_loop_filter_hevc; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c index 763c5df5646..cd78079dd4e 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c @@ -60,19 +60,21 @@ static void radeon_enc_spec_misc(struct radeon_encoder *enc) RADEON_ENC_END(); } -static void radeon_enc_quality_params(struct radeon_encoder *enc) +static void radeon_enc_spec_misc_hevc(struct radeon_encoder *enc) { - enc->enc_pic.quality_params.vbaq_mode = enc->enc_pic.quality_modes.vbaq_mode; - enc->enc_pic.quality_params.scene_change_sensitivity = 0; - enc->enc_pic.quality_params.scene_change_min_idr_interval = 0; - enc->enc_pic.quality_params.two_pass_search_center_map_mode = 0; + enc->enc_pic.hevc_spec_misc.transform_skip_discarded = 0; + enc->enc_pic.hevc_spec_misc.cu_qp_delta_enabled_flag = 0; - RADEON_ENC_BEGIN(enc->cmd.quality_params); - RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode); - RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_sensitivity); - RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_min_idr_interval); - RADEON_ENC_CS(enc->enc_pic.quality_params.two_pass_search_center_map_mode); - RADEON_ENC_CS(0); + RADEON_ENC_BEGIN(enc->cmd.spec_misc_hevc); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.amp_disabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cabac_init_flag); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.half_pel_enabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.quarter_pel_enabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.transform_skip_discarded); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cu_qp_delta_enabled_flag); RADEON_ENC_END(); } @@ -240,7 +242,6 @@ void radeon_enc_3_0_init(struct radeon_encoder *enc) radeon_enc_2_0_init(enc); enc->session_init = radeon_enc_session_init; - enc->quality_params = radeon_enc_quality_params; enc->ctx = radeon_enc_ctx; if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { @@ -248,8 +249,10 @@ void radeon_enc_3_0_init(struct radeon_encoder *enc) enc->encode_params_codec_spec = radeon_enc_encode_params_h264; } - if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { + enc->spec_misc = radeon_enc_spec_misc_hevc; enc->nalu_pps = radeon_enc_nalu_pps_hevc; + } enc->enc_pic.session_info.interface_version = ((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) |