1 /************************************************************************** 2 * 3 * Copyright 2020 Advanced Micro Devices, Inc. 4 * 5 * SPDX-License-Identifier: MIT 6 * 7 **************************************************************************/ 8 9 #include <stdio.h> 10 11 #include "pipe/p_video_codec.h" 12 13 #include "util/u_video.h" 14 15 #include "si_pipe.h" 16 #include "radeon_video.h" 17 #include "radeon_vcn_enc.h" 18 19 #define RENCODE_FW_INTERFACE_MAJOR_VERSION 1 20 #define RENCODE_FW_INTERFACE_MINOR_VERSION 30 21 radeon_enc_session_info(struct radeon_encoder * enc)22static void radeon_enc_session_info(struct radeon_encoder *enc) 23 { 24 RADEON_ENC_BEGIN(enc->cmd.session_info); 25 RADEON_ENC_CS(enc->enc_pic.session_info.interface_version); 26 RADEON_ENC_READWRITE(enc->si->res->buf, enc->si->res->domains, 0x0); 27 RADEON_ENC_CS(0); /* padding 0, not used for vcn3 */ 28 RADEON_ENC_END(); 29 } 30 radeon_enc_spec_misc(struct radeon_encoder * enc)31static void radeon_enc_spec_misc(struct radeon_encoder *enc) 32 { 33 RADEON_ENC_BEGIN(enc->cmd.spec_misc_h264); 34 RADEON_ENC_CS(enc->enc_pic.spec_misc.constrained_intra_pred_flag); 35 RADEON_ENC_CS(enc->enc_pic.spec_misc.cabac_enable); 36 RADEON_ENC_CS(enc->enc_pic.spec_misc.cabac_init_idc); 37 RADEON_ENC_CS(enc->enc_pic.spec_misc.half_pel_enabled); 38 RADEON_ENC_CS(enc->enc_pic.spec_misc.quarter_pel_enabled); 39 RADEON_ENC_CS(enc->enc_pic.spec_misc.profile_idc); 40 RADEON_ENC_CS(enc->enc_pic.spec_misc.level_idc); 41 RADEON_ENC_CS(enc->enc_pic.spec_misc.b_picture_enabled); 42 RADEON_ENC_CS(enc->enc_pic.spec_misc.weighted_bipred_idc); 43 RADEON_ENC_END(); 44 } 45 radeon_enc_spec_misc_hevc(struct radeon_encoder * enc)46static void radeon_enc_spec_misc_hevc(struct radeon_encoder *enc) 47 { 48 RADEON_ENC_BEGIN(enc->cmd.spec_misc_hevc); 49 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); 50 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.amp_disabled); 51 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled); 52 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag); 53 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cabac_init_flag); 54 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.half_pel_enabled); 55 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.quarter_pel_enabled); 56 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.transform_skip_disabled); 57 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cu_qp_delta_enabled_flag); 58 RADEON_ENC_END(); 59 } 60 radeon_enc_encode_params_h264(struct radeon_encoder * enc)61static void radeon_enc_encode_params_h264(struct radeon_encoder *enc) 62 { 63 RADEON_ENC_BEGIN(enc->cmd.enc_params_h264); 64 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.input_picture_structure); 65 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.input_pic_order_cnt); 66 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.interlaced_mode); 67 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture0.pic_type); 68 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture0.is_long_term); 69 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture0.picture_structure); 70 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture0.pic_order_cnt); 71 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.l0_reference_picture1_index); 72 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture1.pic_type); 73 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture1.is_long_term); 74 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture1.picture_structure); 75 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l0_reference_picture1.pic_order_cnt); 76 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.l1_reference_picture0_index); 77 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l1_reference_picture0.pic_type); 78 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l1_reference_picture0.is_long_term); 79 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l1_reference_picture0.picture_structure); 80 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.picture_info_l1_reference_picture0.pic_order_cnt); 81 RADEON_ENC_CS(enc->enc_pic.h264_enc_params.is_reference); 82 RADEON_ENC_END(); 83 } 84 radeon_enc_quality_params(struct radeon_encoder * enc)85static void radeon_enc_quality_params(struct radeon_encoder *enc) 86 { 87 RADEON_ENC_BEGIN(enc->cmd.quality_params); 88 RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode); 89 RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_sensitivity); 90 RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_min_idr_interval); 91 RADEON_ENC_CS(enc->enc_pic.quality_params.two_pass_search_center_map_mode); 92 RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_strength); 93 RADEON_ENC_END(); 94 } 95 radeon_enc_rc_per_pic_ex(struct radeon_encoder * enc)96static void radeon_enc_rc_per_pic_ex(struct radeon_encoder *enc) 97 { 98 RADEON_ENC_BEGIN(enc->cmd.rc_per_pic); 99 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_i); 100 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_p); 101 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_b); 102 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_i); 103 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_i); 104 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_p); 105 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_p); 106 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_b); 107 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_b); 108 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size_i); 109 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size_p); 110 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size_b); 111 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enabled_filler_data); 112 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.skip_frame_enable); 113 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enforce_hrd); 114 RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qvbr_quality_level); 115 RADEON_ENC_END(); 116 } 117 radeon_enc_ref_swizzle_mode(struct radeon_encoder * enc)118static uint32_t radeon_enc_ref_swizzle_mode(struct radeon_encoder *enc) 119 { 120 /* return RENCODE_REC_SWIZZLE_MODE_LINEAR; for debugging purpose */ 121 if (enc->enc_pic.bit_depth_luma_minus8 != 0) 122 return RENCODE_REC_SWIZZLE_MODE_8x8_1D_THIN_12_24BPP; 123 else 124 return RENCODE_REC_SWIZZLE_MODE_256B_S; 125 } 126 radeon_enc_ctx(struct radeon_encoder * enc)127static void radeon_enc_ctx(struct radeon_encoder *enc) 128 { 129 enc->enc_pic.ctx_buf.swizzle_mode = radeon_enc_ref_swizzle_mode(enc); 130 enc->enc_pic.ctx_buf.two_pass_search_center_map_offset = 0; 131 132 RADEON_ENC_BEGIN(enc->cmd.ctx); 133 RADEON_ENC_READWRITE(enc->dpb->res->buf, enc->dpb->res->domains, 0); 134 RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode); 135 RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch); 136 RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch); 137 RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures); 138 139 for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { 140 RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset); 141 RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset); 142 } 143 144 RADEON_ENC_CS(enc->enc_pic.ctx_buf.colloc_buffer_offset); 145 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_luma_pitch); 146 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_chroma_pitch); 147 148 for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { 149 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].luma_offset); 150 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].chroma_offset); 151 } 152 153 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.red_offset); 154 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.green_offset); 155 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.blue_offset); 156 157 RADEON_ENC_CS(enc->enc_pic.ctx_buf.two_pass_search_center_map_offset); 158 RADEON_ENC_CS(0x00000000); 159 RADEON_ENC_CS(0x00000000); 160 RADEON_ENC_END(); 161 } 162 radeon_enc_session_init(struct radeon_encoder * enc)163static void radeon_enc_session_init(struct radeon_encoder *enc) 164 { 165 if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { 166 enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_H264; 167 enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 16); 168 } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { 169 enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_HEVC; 170 enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 64); 171 } 172 enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16); 173 174 enc->enc_pic.session_init.padding_width = 175 (enc->enc_pic.crop_left + enc->enc_pic.crop_right) * 2; 176 enc->enc_pic.session_init.padding_height = 177 (enc->enc_pic.crop_top + enc->enc_pic.crop_bottom) * 2; 178 179 enc->enc_pic.session_init.slice_output_enabled = 0; 180 enc->enc_pic.session_init.display_remote = 0; 181 enc->enc_pic.session_init.pre_encode_mode = enc->enc_pic.quality_modes.pre_encode_mode; 182 enc->enc_pic.session_init.pre_encode_chroma_enabled = !!(enc->enc_pic.quality_modes.pre_encode_mode); 183 184 RADEON_ENC_BEGIN(enc->cmd.session_init); 185 RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); 186 RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); 187 RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); 188 RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); 189 RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); 190 RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); 191 RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); 192 RADEON_ENC_CS(enc->enc_pic.session_init.slice_output_enabled); 193 RADEON_ENC_CS(enc->enc_pic.session_init.display_remote); 194 RADEON_ENC_END(); 195 } 196 radeon_enc_3_0_init(struct radeon_encoder * enc)197void radeon_enc_3_0_init(struct radeon_encoder *enc) 198 { 199 radeon_enc_2_0_init(enc); 200 201 enc->session_info = radeon_enc_session_info; 202 enc->session_init = radeon_enc_session_init; 203 enc->ctx = radeon_enc_ctx; 204 enc->quality_params = radeon_enc_quality_params; 205 if (enc->enc_pic.use_rc_per_pic_ex) 206 enc->rc_per_pic = radeon_enc_rc_per_pic_ex; 207 208 if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { 209 enc->spec_misc = radeon_enc_spec_misc; 210 enc->encode_params_codec_spec = radeon_enc_encode_params_h264; 211 } 212 213 if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { 214 enc->spec_misc = radeon_enc_spec_misc_hevc; 215 } 216 217 enc->enc_pic.session_info.interface_version = 218 ((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) | 219 (RENCODE_FW_INTERFACE_MINOR_VERSION << RENCODE_IF_MINOR_VERSION_SHIFT)); 220 } 221