From 587b9c5dae6567d282a199e795bf7136ca838829 Mon Sep 17 00:00:00 2001 From: Boyuan Zhang Date: Fri, 1 Mar 2019 21:14:06 -0500 Subject: [PATCH] radeon/vcn: implement vcn 2.0 encode Signed-off-by: Boyuan Zhang Acked-by: Bas Nieuwenhuizen --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 5 +- src/gallium/drivers/radeon/radeon_vcn_enc.h | 2 + .../drivers/radeon/radeon_vcn_enc_1_2.c | 5 +- .../drivers/radeon/radeon_vcn_enc_2_0.c | 213 +++++++++++++++++- 4 files changed, 220 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index cb60cb30d74..afdc2a9f5cd 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -410,7 +410,10 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, goto error; } - radeon_enc_1_2_init(enc); + if (sscreen->info.family <= CHIP_RAVEN) + radeon_enc_1_2_init(enc); + else + radeon_enc_2_0_init(enc); return &enc->base; diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h index 51c2836d92d..ed4571269b2 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h @@ -461,6 +461,8 @@ struct radeon_encoder { void (*op_init_rc_vbv)(struct radeon_encoder *enc); void (*op_speed)(struct radeon_encoder *enc); void (*encode_headers)(struct radeon_encoder *enc); + void (*input_format)(struct radeon_encoder *enc); + void (*output_format)(struct radeon_encoder *enc); unsigned stream_handle; diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index d1dcfb1d7f9..a69feae8975 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -1112,7 +1112,7 @@ static void radeon_enc_headers_hevc(struct radeon_encoder *enc) enc->nalu_sps(enc); } enc->slice_header(enc); - enc->encode_params_codec_spec(enc); + enc->encode_params(enc); } static void encode(struct radeon_encoder *enc) @@ -1174,6 +1174,7 @@ void radeon_enc_1_2_init(struct radeon_encoder *enc) enc->nalu_sps = radeon_enc_nalu_sps; enc->nalu_pps = radeon_enc_nalu_pps; enc->slice_header = radeon_enc_slice_header; + enc->encode_params = radeon_enc_encode_params; enc->encode_params_codec_spec = radeon_enc_encode_params_h264; enc->encode_headers = radeon_enc_headers_h264; } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { @@ -1186,7 +1187,7 @@ void radeon_enc_1_2_init(struct radeon_encoder *enc) enc->nalu_vps = radeon_enc_nalu_vps; enc->nalu_aud = radeon_enc_nalu_aud_hevc; enc->slice_header = radeon_enc_slice_header_hevc; - enc->encode_params_codec_spec = radeon_enc_encode_params_hevc; + enc->encode_params = radeon_enc_encode_params_hevc; enc->encode_headers = radeon_enc_headers_hevc; } } diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_2_0.c b/src/gallium/drivers/radeon/radeon_vcn_enc_2_0.c index ae12ba1f01f..81686ee1e82 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_2_0.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_2_0.c @@ -66,12 +66,221 @@ #define RENCODE_H264_IB_PARAM_ENCODE_PARAMS 0x00200003 #define RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER 0x00200004 +static void radeon_enc_quality_params(struct radeon_encoder *enc) +{ + enc->enc_pic.quality_params.vbaq_mode = 0; + enc->enc_pic.quality_params.scene_change_sensitivity = 0; + enc->enc_pic.quality_params.scene_change_min_idr_interval = 0; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_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_END(); +} + +static void radeon_enc_loop_filter_hevc(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_HEVC_IB_PARAM_LOOP_FILTER); + RADEON_ENC_CS(enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled); + RADEON_ENC_CS(enc->enc_pic.hevc_deblock.deblocking_filter_disabled); + RADEON_ENC_CS(enc->enc_pic.hevc_deblock.beta_offset_div2); + RADEON_ENC_CS(enc->enc_pic.hevc_deblock.tc_offset_div2); + RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cb_qp_offset); + RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cr_qp_offset); + RADEON_ENC_CS(1); + RADEON_ENC_END(); +} + +static void radeon_enc_nalu_sps_hevc(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + int i; + + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(enc, 0x00000001, 32); + radeon_enc_code_fixed_bits(enc, 0x4201, 16); + radeon_enc_byte_align(enc); + radeon_enc_set_emulation_prevention(enc, true); + radeon_enc_code_fixed_bits(enc, 0x0, 4); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 2); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_profile_idc, 5); + radeon_enc_code_fixed_bits(enc, 0x60000000, 32); + radeon_enc_code_fixed_bits(enc, 0xb0000000, 32); + radeon_enc_code_fixed_bits(enc, 0x0, 16); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 8); + + for (i = 0; i < (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) ; i++) + radeon_enc_code_fixed_bits(enc, 0x0, 2); + + if ((enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) > 0) { + for (i = (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i < 8; i++) + radeon_enc_code_fixed_bits(enc, 0x0, 2); + } + + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, enc->enc_pic.chroma_format_idc); + radeon_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_width); + radeon_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_height); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_luma_minus8); + radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_chroma_minus8); + radeon_enc_code_ue(enc, enc->enc_pic.log2_max_poc - 4); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); + //Only support CTBSize 64 + radeon_enc_code_ue(enc, 6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3)); + radeon_enc_code_ue(enc, enc->enc_pic.log2_min_transform_block_size_minus2); + radeon_enc_code_ue(enc, enc->enc_pic.log2_diff_max_min_transform_block_size); + radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_inter); + radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_intra); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.sample_adaptive_offset_enabled_flag, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.pcm_enabled_flag, 1); + + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, 0); + radeon_enc_code_ue(enc, 0); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled, 1); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + radeon_enc_byte_align(enc); + radeon_enc_flush_headers(enc); + *size_in_bytes = (enc->bits_output + 7) / 8; + RADEON_ENC_END(); +} + +static void radeon_enc_nalu_pps_hevc(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(enc, 0x00000001, 32); + radeon_enc_code_fixed_bits(enc, 0x4401, 16); + radeon_enc_byte_align(enc); + radeon_enc_set_emulation_prevention(enc, true); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 4); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_se(enc, 0x0); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.cb_qp_offset); + radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.cr_qp_offset); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 2); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.deblocking_filter_disabled, 1); + + if (!enc->enc_pic.hevc_deblock.deblocking_filter_disabled) { + radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.beta_offset_div2); + radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.tc_offset_div2); + } + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_ue(enc, enc->enc_pic.log2_parallel_merge_level_minus2); + radeon_enc_code_fixed_bits(enc, 0x0, 2); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + radeon_enc_byte_align(enc); + radeon_enc_flush_headers(enc); + *size_in_bytes = (enc->bits_output + 7) / 8; + RADEON_ENC_END(); +} + +static void radeon_enc_input_format(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_INPUT_FORMAT); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_END(); +} + +static void radeon_enc_output_format(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_OUTPUT_FORMAT); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_CS(0); + RADEON_ENC_END(); +} + static void encode(struct radeon_encoder *enc) { - /* TODO */ + enc->session_info(enc); + enc->total_task_size = 0; + enc->task_info(enc, enc->need_feedback); + + enc->encode_headers(enc); + enc->ctx(enc); + enc->bitstream(enc); + enc->feedback(enc); + enc->intra_refresh(enc); + enc->input_format(enc); + enc->output_format(enc); + + enc->op_speed(enc); + enc->op_enc(enc); + *enc->p_task_size = (enc->total_task_size); } void radeon_enc_2_0_init(struct radeon_encoder *enc) { - /* TODO */ + radeon_enc_1_2_init(enc); + enc->encode = encode; + enc->quality_params = radeon_enc_quality_params; + enc->input_format = radeon_enc_input_format; + enc->output_format = radeon_enc_output_format; + + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { + enc->deblocking_filter = radeon_enc_loop_filter_hevc; + enc->nalu_sps = radeon_enc_nalu_sps_hevc; + enc->nalu_pps = radeon_enc_nalu_pps_hevc; + } } -- 2.30.2