diff --git a/src/gallium/drivers/radeonsi/meson.build b/src/gallium/drivers/radeonsi/meson.build index 0a29c3d0fd1..dafb411cceb 100644 --- a/src/gallium/drivers/radeonsi/meson.build +++ b/src/gallium/drivers/radeonsi/meson.build @@ -84,7 +84,6 @@ files_libradeonsi = files( 'radeon_uvd_enc_1_1.c', 'radeon_vce.c', 'radeon_vce.h', - 'radeon_vce_52.c', 'radeon_vcn.h', 'radeon_vcn.c', 'radeon_vcn_dec.c', diff --git a/src/gallium/drivers/radeonsi/radeon_vce.c b/src/gallium/drivers/radeonsi/radeon_vce.c index ff43a780c52..f9b6ff1712a 100644 --- a/src/gallium/drivers/radeonsi/radeon_vce.c +++ b/src/gallium/drivers/radeonsi/radeon_vce.c @@ -10,6 +10,7 @@ #include "pipe/p_video_codec.h" #include "radeon_video.h" +#include "radeon_bitstream.h" #include "radeonsi/si_pipe.h" #include "util/u_memory.h" #include "util/u_video.h" @@ -17,49 +18,326 @@ #include -#define FW_52_0_3 ((52 << 24) | (0 << 16) | (3 << 8)) -#define FW_52_4_3 ((52 << 24) | (4 << 16) | (3 << 8)) -#define FW_52_8_3 ((52 << 24) | (8 << 16) | (3 << 8)) -#define FW_53 (53 << 24) +#define REF_LIST_MODIFICATION_OP_END 0 +#define REF_LIST_MODIFICATION_OP_SHORT_TERM_SUBTRACT 1 +#define REF_LIST_MODIFICATION_OP_LONG_TERM 2 +#define REF_LIST_MODIFICATION_OP_VIEW_ADD 3 -/** - * flush commands to the hardware - */ -static void flush(struct rvce_encoder *enc, unsigned flags, struct pipe_fence_handle **fence) +#define INTRAREFRESH_METHOD_BAR_BASED 6 + +static void task_info(struct rvce_encoder *enc, uint32_t op, uint32_t fb_idx) { - enc->ws->cs_flush(&enc->cs, flags, fence); + RVCE_BEGIN(0x00000002); // task info + enc->enc_pic.ti.task_operation = op; + enc->enc_pic.ti.reference_picture_dependency = 0; + enc->enc_pic.ti.feedback_index = fb_idx; + enc->enc_pic.ti.video_bitstream_ring_index = 0; + RVCE_CS(enc->enc_pic.ti.offset_of_next_task_info); + RVCE_CS(enc->enc_pic.ti.task_operation); + RVCE_CS(enc->enc_pic.ti.reference_picture_dependency); + RVCE_CS(enc->enc_pic.ti.collocate_flag_dependency); + RVCE_CS(enc->enc_pic.ti.feedback_index); + RVCE_CS(enc->enc_pic.ti.video_bitstream_ring_index); + RVCE_END(); } -#if 0 -static void dump_feedback(struct rvce_encoder *enc, struct rvid_buffer *fb) +static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { - uint32_t *ptr = enc->ws->buffer_map(fb->res->buf, &enc->cs, PIPE_MAP_READ_WRITE); - unsigned i = 0; - fprintf(stderr, "\n"); - fprintf(stderr, "encStatus:\t\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encHasBitstream:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encHasAudioBitstream:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encBitstreamOffset:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encBitstreamSize:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encAudioBitstreamOffset:\t%08x\n", ptr[i++]); - fprintf(stderr, "encAudioBitstreamSize:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encExtrabytes:\t\t\t%08x\n", ptr[i++]); - fprintf(stderr, "encAudioExtrabytes:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "videoTimeStamp:\t\t\t%08x\n", ptr[i++]); - fprintf(stderr, "audioTimeStamp:\t\t\t%08x\n", ptr[i++]); - fprintf(stderr, "videoOutputType:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "attributeFlags:\t\t\t%08x\n", ptr[i++]); - fprintf(stderr, "seiPrivatePackageOffset:\t%08x\n", ptr[i++]); - fprintf(stderr, "seiPrivatePackageSize:\t\t%08x\n", ptr[i++]); - fprintf(stderr, "\n"); - enc->ws->buffer_unmap(fb->res->buf); + enc->enc_pic.rc.rc_method = pic->rate_ctrl[0].rate_ctrl_method; + enc->enc_pic.rc.target_bitrate = pic->rate_ctrl[0].target_bitrate; + enc->enc_pic.rc.peak_bitrate = pic->rate_ctrl[0].peak_bitrate; + enc->enc_pic.rc.quant_i_frames = pic->quant_i_frames; + enc->enc_pic.rc.quant_p_frames = pic->quant_p_frames; + enc->enc_pic.rc.quant_b_frames = pic->quant_b_frames; + enc->enc_pic.rc.gop_size = pic->gop_size; + enc->enc_pic.rc.frame_rate_num = pic->rate_ctrl[0].frame_rate_num; + enc->enc_pic.rc.frame_rate_den = pic->rate_ctrl[0].frame_rate_den; + enc->enc_pic.rc.min_qp = pic->rate_ctrl[0].min_qp; + enc->enc_pic.rc.max_qp = pic->rate_ctrl[0].max_qp ? pic->rate_ctrl[0].max_qp : 51; + enc->enc_pic.rc.max_au_size = pic->rate_ctrl[0].max_au_size; + enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl[0].vbv_buffer_size; + enc->enc_pic.rc.vbv_buf_lv = pic->rate_ctrl[0].vbv_buf_lv; + enc->enc_pic.rc.fill_data_enable = pic->rate_ctrl[0].fill_data_enable; + enc->enc_pic.rc.enforce_hrd = pic->rate_ctrl[0].enforce_hrd; + enc->enc_pic.rc.target_bits_picture = + enc->pic.rate_ctrl[0].target_bitrate * + ((float)enc->pic.rate_ctrl[0].frame_rate_den / + enc->pic.rate_ctrl[0].frame_rate_num); + enc->enc_pic.rc.peak_bits_picture_integer = + enc->pic.rate_ctrl[0].peak_bitrate * + ((float)enc->pic.rate_ctrl[0].frame_rate_den / + enc->pic.rate_ctrl[0].frame_rate_num); + enc->enc_pic.rc.peak_bits_picture_fraction = + (((enc->pic.rate_ctrl[0].peak_bitrate * + (uint64_t)enc->pic.rate_ctrl[0].frame_rate_den) % + enc->pic.rate_ctrl[0].frame_rate_num) << 32) / + enc->pic.rate_ctrl[0].frame_rate_num; +} + +static void get_motion_estimation_param(struct rvce_encoder *enc, + struct pipe_h264_enc_picture_desc *pic) +{ + enc->enc_pic.me.enc_ime_decimation_search = 1; + enc->enc_pic.me.motion_est_half_pixel = 1; + enc->enc_pic.me.motion_est_quarter_pixel = 1; + enc->enc_pic.me.disable_favor_pmv_point = 0; + enc->enc_pic.me.lsmvert = 2; + enc->enc_pic.me.disable_16x16_frame1 = 0; + enc->enc_pic.me.disable_satd = 0; + enc->enc_pic.me.enc_ime_skip_x = 0; + enc->enc_pic.me.enc_ime_skip_y = 0; + enc->enc_pic.me.enc_ime2_search_range_x = 4; + enc->enc_pic.me.enc_ime2_search_range_y = 4; + enc->enc_pic.me.parallel_mode_speedup_enable = 0; + enc->enc_pic.me.fme0_enc_disable_sub_mode = 0; + enc->enc_pic.me.fme1_enc_disable_sub_mode = 0; + enc->enc_pic.me.ime_sw_speedup_enable = 0; + + switch (pic->quality_modes.preset_mode) { + case 0: /* SPEED */ + enc->enc_pic.me.force_zero_point_center = 0; + enc->enc_pic.me.enc_search_range_x = 16; + enc->enc_pic.me.enc_search_range_y = 16; + enc->enc_pic.me.enc_search1_range_x = 16; + enc->enc_pic.me.enc_search1_range_y = 16; + enc->enc_pic.me.enable_amd = 0; + enc->enc_pic.me.enc_disable_sub_mode = 126; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0; + break; + case 1: /* BALANCED */ + enc->enc_pic.me.force_zero_point_center = 0; + enc->enc_pic.me.enc_search_range_x = 16; + enc->enc_pic.me.enc_search_range_y = 16; + enc->enc_pic.me.enc_search1_range_x = 16; + enc->enc_pic.me.enc_search1_range_y = 16; + enc->enc_pic.me.enable_amd = 0; + enc->enc_pic.me.enc_disable_sub_mode = 120; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = 1; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = 1; + break; + case 2: /* QUALITY */ + default: + enc->enc_pic.me.force_zero_point_center = 1; + enc->enc_pic.me.enc_search_range_x = 36; + enc->enc_pic.me.enc_search_range_y = 36; + enc->enc_pic.me.enc_search1_range_x = 36; + enc->enc_pic.me.enc_search1_range_y = 36; + enc->enc_pic.me.enable_amd = 1; + enc->enc_pic.me.enc_disable_sub_mode = 0; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0; + break; + } +} + +static void get_pic_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + uint32_t num_mbs_total, num_mbs_in_slice; + + num_mbs_total = DIV_ROUND_UP(enc->base.width, 16) * DIV_ROUND_UP(enc->base.height, 16); + + if (pic->num_slice_descriptors <= 1) { + num_mbs_in_slice = num_mbs_total; + } else { + bool use_app_config = true; + num_mbs_in_slice = pic->slices_descriptors[0].num_macroblocks; + + /* All slices must have equal size */ + for (unsigned i = 1; i < pic->num_slice_descriptors - 1; i++) { + if (num_mbs_in_slice != pic->slices_descriptors[i].num_macroblocks) + use_app_config = false; + } + /* Except last one can be smaller */ + if (pic->slices_descriptors[pic->num_slice_descriptors - 1].num_macroblocks > num_mbs_in_slice) + use_app_config = false; + + if (!use_app_config) { + assert(num_mbs_total >= pic->num_slice_descriptors); + num_mbs_in_slice = + (num_mbs_total + pic->num_slice_descriptors - 1) / pic->num_slice_descriptors; + } + } + + if (pic->seq.enc_frame_cropping_flag) { + enc->enc_pic.pc.enc_crop_left_offset = pic->seq.enc_frame_crop_left_offset; + enc->enc_pic.pc.enc_crop_right_offset = pic->seq.enc_frame_crop_right_offset; + enc->enc_pic.pc.enc_crop_top_offset = pic->seq.enc_frame_crop_top_offset; + enc->enc_pic.pc.enc_crop_bottom_offset = pic->seq.enc_frame_crop_bottom_offset; + } + enc->enc_pic.pc.enc_num_mbs_per_slice = num_mbs_in_slice; + enc->enc_pic.pc.enc_number_of_reference_frames = 1; + enc->enc_pic.pc.enc_max_num_ref_frames = pic->seq.max_num_ref_frames; + enc->enc_pic.pc.enc_num_default_active_ref_l0 = pic->pic_ctrl.num_ref_idx_l0_default_active_minus1 + 1; + enc->enc_pic.pc.enc_num_default_active_ref_l1 = pic->pic_ctrl.num_ref_idx_l1_default_active_minus1 + 1; + enc->enc_pic.pc.enc_slice_mode = 1; + enc->enc_pic.pc.enc_use_constrained_intra_pred = pic->pic_ctrl.constrained_intra_pred_flag; + enc->enc_pic.pc.enc_cabac_enable = pic->pic_ctrl.enc_cabac_enable; + enc->enc_pic.pc.enc_cabac_idc = pic->pic_ctrl.enc_cabac_init_idc; + enc->enc_pic.pc.enc_constraint_set_flags = pic->seq.enc_constraint_set_flags << 2; + enc->enc_pic.pc.enc_loop_filter_disable = !!pic->dbk.disable_deblocking_filter_idc; + enc->enc_pic.pc.enc_lf_beta_offset = pic->dbk.beta_offset_div2; + enc->enc_pic.pc.enc_lf_alpha_c0_offset = pic->dbk.alpha_c0_offset_div2; + enc->enc_pic.pc.enc_pic_order_cnt_type = pic->seq.pic_order_cnt_type; + enc->enc_pic.pc.log2_max_pic_order_cnt_lsb_minus4 = pic->seq.log2_max_pic_order_cnt_lsb_minus4; +} + +static void get_task_info_param(struct rvce_encoder *enc) +{ + enc->enc_pic.ti.offset_of_next_task_info = 0xffffffff; +} + +static void get_feedback_buffer_param(struct rvce_encoder *enc, struct pipe_enc_feedback_metadata* metadata) +{ + enc->enc_pic.fb.feedback_ring_size = 0x00000001; +} + +static void get_config_ext_param(struct rvce_encoder *enc) +{ + enc->enc_pic.ce.enc_enable_perf_logging = 0x00000003; +} + +static void get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + int i; + + get_rate_control_param(enc, pic); + get_motion_estimation_param(enc, pic); + get_pic_control_param(enc, pic); + get_task_info_param(enc); + get_feedback_buffer_param(enc, NULL); + get_config_ext_param(enc); + + enc->enc_pic.picture_type = pic->picture_type; + enc->enc_pic.frame_num = pic->frame_num; + enc->enc_pic.frame_num_cnt = pic->frame_num_cnt - 1; + enc->enc_pic.p_remain = pic->p_remain; + enc->enc_pic.i_remain = pic->i_remain; + enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; + enc->enc_pic.not_referenced = pic->not_referenced; + enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = enc->fw_version >= 52 ? 0x01000201 : 0; + enc->enc_pic.eo.enc_idr_pic_id = pic->idr_pic_id; + enc->enc_pic.ec.enc_vbaq_mode = + pic->rate_ctrl[0].rate_ctrl_method != PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE && + pic->quality_modes.vbaq_mode; + if (pic->intra_refresh.mode != PIPE_VIDEO_ENC_INTRA_REFRESH_NONE) { + enc->enc_pic.eo.enable_intra_refresh = 1; + enc->enc_pic.pc.enc_force_intra_refresh = INTRAREFRESH_METHOD_BAR_BASED; + enc->enc_pic.pc.enc_intra_refresh_num_mbs_per_slot = pic->intra_refresh.region_size; + } else { + enc->enc_pic.eo.enable_intra_refresh = 0; + } + + enc->enc_pic.eo.num_ref_idx_active_override_flag = pic->slice.num_ref_idx_active_override_flag; + enc->enc_pic.eo.num_ref_idx_l0_active_minus1 = pic->slice.num_ref_idx_l0_active_minus1; + enc->enc_pic.eo.num_ref_idx_l1_active_minus1 = pic->slice.num_ref_idx_l1_active_minus1; + + i = 0; + if (pic->slice.ref_pic_list_modification_flag_l0) { + for (; i < MIN2(4, pic->slice.num_ref_list0_mod_operations); i++) { + struct pipe_h264_ref_list_mod_entry *entry = &pic->slice.ref_list0_mod_operations[i]; + switch (entry->modification_of_pic_nums_idc) { + case 0: + enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_SHORT_TERM_SUBTRACT; + enc->enc_pic.eo.enc_ref_list_modification_num[i] = entry->abs_diff_pic_num_minus1; + break; + case 2: + enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_LONG_TERM; + enc->enc_pic.eo.enc_ref_list_modification_num[i] = entry->long_term_pic_num; + break; + case 5: + enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_VIEW_ADD; + enc->enc_pic.eo.enc_ref_list_modification_num[i] = entry->abs_diff_pic_num_minus1; + break; + default: + case 3: + enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_END; + break; + } + } + } + if (i < 4) + enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_END; + + i = 0; + if (pic->pic_ctrl.nal_unit_type == PIPE_H264_NAL_IDR_SLICE) { + enc->enc_pic.eo.enc_decoded_picture_marking_op[i++] = pic->slice.long_term_reference_flag ? 6 : 0; + } else if (pic->slice.adaptive_ref_pic_marking_mode_flag) { + for (; i < MIN2(4, pic->slice.num_ref_pic_marking_operations); i++) { + struct pipe_h264_ref_pic_marking_entry *entry = &pic->slice.ref_pic_marking_operations[i]; + enc->enc_pic.eo.enc_decoded_picture_marking_op[i] = entry->memory_management_control_operation; + switch (entry->memory_management_control_operation) { + case 1: + enc->enc_pic.eo.enc_decoded_picture_marking_num[i] = entry->difference_of_pic_nums_minus1; + break; + case 2: + enc->enc_pic.eo.enc_decoded_picture_marking_num[i] = entry->long_term_pic_num; + break; + case 3: + enc->enc_pic.eo.enc_decoded_picture_marking_num[i] = entry->difference_of_pic_nums_minus1; + enc->enc_pic.eo.enc_decoded_picture_marking_idx[i] = entry->long_term_frame_idx; + break; + case 4: + enc->enc_pic.eo.enc_decoded_picture_marking_idx[i] = entry->max_long_term_frame_idx_plus1; + break; + case 6: + enc->enc_pic.eo.enc_decoded_picture_marking_idx[i] = entry->long_term_frame_idx; + break; + default: + break; + } + } + } + if (i < 4) + enc->enc_pic.eo.enc_decoded_picture_marking_op[i] = 0; + + enc->enc_pic.eo.cur_dpb_idx = pic->dpb_curr_pic; + + enc->enc_pic.eo.l0_dpb_idx = pic->ref_list0[0]; + + enc->enc_pic.eo.l1_dpb_idx = PIPE_H2645_LIST_REF_INVALID_ENTRY; + enc->enc_pic.eo.l1_luma_offset = 0xffffffff; + enc->enc_pic.eo.l1_chroma_offset = 0xffffffff; +} + +static void create(struct rvce_encoder *enc) +{ + struct si_screen *sscreen = (struct si_screen *)enc->screen; + task_info(enc, 0x00000000, 0); + + RVCE_BEGIN(0x01000001); // create cmd + RVCE_CS(enc->enc_pic.ec.enc_use_circular_buffer); + RVCE_CS(enc->pic.seq.profile_idc); // encProfile + RVCE_CS(enc->pic.seq.level_idc); // encLevel + RVCE_CS(enc->enc_pic.ec.enc_pic_struct_restriction); + RVCE_CS(align(enc->base.width, 16)); // encImageWidth + RVCE_CS(align(enc->base.height, 16)); // encImageHeight + + if (sscreen->info.gfx_level < GFX9) { + RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encRefPicLumaPitch + RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encRefPicChromaPitch + RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16) / 8); // encRefYHeightInQw + } else { + RVCE_CS(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe); // encRefPicLumaPitch + RVCE_CS(enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe); // encRefPicChromaPitch + RVCE_CS(align(enc->luma->u.gfx9.surf_height, 16) / 8); // encRefYHeightInQw + } + + RVCE_CS(enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants); + + if (enc->fw_version >= 52) { + RVCE_CS(enc->enc_pic.ec.enc_pre_encode_context_buffer_offset); + RVCE_CS(enc->enc_pic.ec.enc_pre_encode_input_luma_buffer_offset); + RVCE_CS(enc->enc_pic.ec.enc_pre_encode_input_chroma_buffer_offset); + RVCE_CS(enc->enc_pic.ec.enc_pre_encode_mode_chromaflag_vbaqmode_scenechangesensitivity); + } + RVCE_END(); } -#endif /** * Calculate the offsets into the DPB */ -void si_vce_frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_offset, +static void frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_offset, signed *chroma_offset) { struct si_screen *sscreen = (struct si_screen *)enc->screen; @@ -81,6 +359,477 @@ void si_vce_frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_o *chroma_offset = *luma_offset + pitch * vpitch; } +static void encode(struct rvce_encoder *enc) +{ + struct si_screen *sscreen = (struct si_screen *)enc->screen; + signed luma_offset, chroma_offset; + int i; + + task_info(enc, 0x00000003, 0); + + RVCE_BEGIN(0x05000001); // context buffer + RVCE_READWRITE(enc->dpb.res->buf, enc->dpb.res->domains, 0); // encodeContextAddressHi/Lo + RVCE_END(); + + RVCE_BEGIN(0x05000004); // video bitstream buffer + RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, enc->bs_offset); // videoBitstreamRingAddressHi/Lo + RVCE_CS(enc->bs_size); // videoBitstreamRingSize + RVCE_END(); + + if (enc->dual_pipe) { + unsigned aux_offset = 0; + RVCE_BEGIN(0x05000002); // auxiliary buffer + for (i = 0; i < 8; ++i) { + RVCE_CS(aux_offset); + aux_offset += RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE; + } + for (i = 0; i < 8; ++i) + RVCE_CS(RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE); + RVCE_END(); + } + + RVCE_BEGIN(0x03000001); // encode + RVCE_CS(enc->enc_pic.eo.insert_headers); + RVCE_CS(enc->enc_pic.eo.picture_structure); + RVCE_CS(enc->bs_size - enc->bs_offset); // allowedMaxBitstreamSize + RVCE_CS(enc->enc_pic.eo.force_refresh_map); + RVCE_CS(enc->enc_pic.eo.insert_aud); + RVCE_CS(enc->enc_pic.eo.end_of_sequence); + RVCE_CS(enc->enc_pic.eo.end_of_stream); + + if (sscreen->info.gfx_level < GFX9) { + RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, + (uint64_t)enc->luma->u.legacy.level[0].offset_256B * 256); // inputPictureLumaAddressHi/Lo + RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, + (uint64_t)enc->chroma->u.legacy.level[0].offset_256B * 256); // inputPictureChromaAddressHi/Lo + RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch + RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch + RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch + } else { + RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, + enc->luma->u.gfx9.surf_offset); // inputPictureLumaAddressHi/Lo + RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, + enc->chroma->u.gfx9.surf_offset); // inputPictureChromaAddressHi/Lo + RVCE_CS(align(enc->luma->u.gfx9.surf_height, 16)); // encInputFrameYPitch + RVCE_CS(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe); // encInputPicLumaPitch + RVCE_CS(enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe); // encInputPicChromaPitch + enc->enc_pic.eo.enc_input_pic_swizzle_mode = enc->luma->u.gfx9.swizzle_mode; + } + + enc->enc_pic.eo.enc_disable_two_pipe_mode = enc->fw_version >= 50 ? !enc->dual_pipe : 0; + RVCE_CS(enc->enc_pic.eo.enc_input_pic_addr_array_disable2pipe_disablemboffload); + RVCE_CS(enc->enc_pic.eo.enc_input_pic_tile_config); + RVCE_CS(enc->enc_pic.picture_type); // encPicType + RVCE_CS(enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR); // encIdrFlag + RVCE_CS(enc->enc_pic.eo.enc_idr_pic_id); + RVCE_CS(enc->enc_pic.eo.enc_mgs_key_pic); + RVCE_CS(!enc->enc_pic.not_referenced); + RVCE_CS(enc->enc_pic.eo.enc_temporal_layer_index); + RVCE_CS(enc->enc_pic.eo.num_ref_idx_active_override_flag); + RVCE_CS(enc->enc_pic.eo.num_ref_idx_l0_active_minus1); + RVCE_CS(enc->enc_pic.eo.num_ref_idx_l1_active_minus1); + + for (i = 0; i < 4; ++i) { + RVCE_CS(enc->enc_pic.eo.enc_ref_list_modification_op[i]); + RVCE_CS(enc->enc_pic.eo.enc_ref_list_modification_num[i]); + } + + for (i = 0; i < 4; ++i) { + RVCE_CS(enc->enc_pic.eo.enc_decoded_picture_marking_op[i]); + RVCE_CS(enc->enc_pic.eo.enc_decoded_picture_marking_num[i]); + RVCE_CS(enc->enc_pic.eo.enc_decoded_picture_marking_idx[i]); + } + + for (i = 0; i < 4; ++i) { + RVCE_CS(enc->enc_pic.eo.enc_decoded_ref_base_picture_marking_op[i]); + RVCE_CS(enc->enc_pic.eo.enc_decoded_ref_base_picture_marking_num[i]); + } + + // encReferencePictureL0[0] + if (enc->enc_pic.eo.l0_dpb_idx != PIPE_H2645_LIST_REF_INVALID_ENTRY) { + frame_offset(enc, enc->enc_pic.eo.l0_dpb_idx, &luma_offset, &chroma_offset); + enc->enc_pic.eo.l0_luma_offset = luma_offset; + enc->enc_pic.eo.l0_chroma_offset = chroma_offset; + } else { + enc->enc_pic.eo.l0_luma_offset = 0xffffffff; + enc->enc_pic.eo.l0_chroma_offset = 0xffffffff; + } + RVCE_CS(0x00000000); // pictureStructure + RVCE_CS(enc->enc_pic.eo.l0_enc_pic_type); + RVCE_CS(enc->enc_pic.eo.l0_frame_number); + RVCE_CS(enc->enc_pic.eo.l0_picture_order_count); + RVCE_CS(enc->enc_pic.eo.l0_luma_offset); + RVCE_CS(enc->enc_pic.eo.l0_chroma_offset); + + // encReferencePictureL0[1] + enc->enc_pic.eo.l0_picture_structure = 0x00000000; + enc->enc_pic.eo.l0_enc_pic_type = 0x00000000; + enc->enc_pic.eo.l0_frame_number = 0x00000000; + enc->enc_pic.eo.l0_picture_order_count = 0x00000000; + enc->enc_pic.eo.l0_luma_offset = 0xffffffff; + enc->enc_pic.eo.l0_chroma_offset = 0xffffffff; + RVCE_CS(enc->enc_pic.eo.l0_picture_structure); + RVCE_CS(enc->enc_pic.eo.l0_enc_pic_type); + RVCE_CS(enc->enc_pic.eo.l0_frame_number); + RVCE_CS(enc->enc_pic.eo.l0_picture_order_count); + RVCE_CS(enc->enc_pic.eo.l0_luma_offset); + RVCE_CS(enc->enc_pic.eo.l0_chroma_offset); + + // encReferencePictureL1[0] + RVCE_CS(0x00000000); // pictureStructure + RVCE_CS(enc->enc_pic.eo.l1_enc_pic_type); + RVCE_CS(enc->enc_pic.eo.l1_frame_number); + RVCE_CS(enc->enc_pic.eo.l1_picture_order_count); + RVCE_CS(enc->enc_pic.eo.l1_luma_offset); + RVCE_CS(enc->enc_pic.eo.l1_chroma_offset); + + frame_offset(enc, enc->enc_pic.eo.cur_dpb_idx, &luma_offset, &chroma_offset); + RVCE_CS(luma_offset); + RVCE_CS(chroma_offset); + RVCE_CS(enc->enc_pic.eo.enc_coloc_buffer_offset); + RVCE_CS(enc->enc_pic.eo.enc_reconstructed_ref_base_picture_luma_offset); + RVCE_CS(enc->enc_pic.eo.enc_reconstructed_ref_base_picture_chroma_offset); + RVCE_CS(enc->enc_pic.eo.enc_reference_ref_base_picture_luma_offset); + RVCE_CS(enc->enc_pic.eo.enc_reference_ref_base_picture_chroma_offset); + RVCE_CS(enc->enc_pic.frame_num_cnt); + RVCE_CS(enc->enc_pic.frame_num); + RVCE_CS(enc->enc_pic.pic_order_cnt); + RVCE_CS(enc->enc_pic.i_remain); + RVCE_CS(enc->enc_pic.p_remain); + RVCE_CS(enc->enc_pic.eo.num_b_pic_remain_in_rcgop); + RVCE_CS(enc->enc_pic.eo.num_ir_pic_remain_in_rcgop); + RVCE_CS(enc->enc_pic.eo.enable_intra_refresh); + + if (enc->fw_version >= 52) { + RVCE_CS(enc->enc_pic.eo.aq_variance_en); + RVCE_CS(enc->enc_pic.eo.aq_block_size); + RVCE_CS(enc->enc_pic.eo.aq_mb_variance_sel); + RVCE_CS(enc->enc_pic.eo.aq_frame_variance_sel); + RVCE_CS(enc->enc_pic.eo.aq_param_a); + RVCE_CS(enc->enc_pic.eo.aq_param_b); + RVCE_CS(enc->enc_pic.eo.aq_param_c); + RVCE_CS(enc->enc_pic.eo.aq_param_d); + RVCE_CS(enc->enc_pic.eo.aq_param_e); + RVCE_CS(enc->enc_pic.eo.context_in_sfb); + } + RVCE_END(); +} + +static void rate_control(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x04000005); // rate control + RVCE_CS(enc->enc_pic.rc.rc_method); + RVCE_CS(enc->enc_pic.rc.target_bitrate); + RVCE_CS(enc->enc_pic.rc.peak_bitrate); + RVCE_CS(enc->enc_pic.rc.frame_rate_num); + RVCE_CS(enc->enc_pic.rc.gop_size); + RVCE_CS(enc->enc_pic.rc.quant_i_frames); + RVCE_CS(enc->enc_pic.rc.quant_p_frames); + RVCE_CS(enc->enc_pic.rc.quant_b_frames); + RVCE_CS(enc->enc_pic.rc.vbv_buffer_size); + RVCE_CS(enc->enc_pic.rc.frame_rate_den); + RVCE_CS(enc->enc_pic.rc.vbv_buf_lv); + RVCE_CS(enc->enc_pic.rc.max_au_size); + RVCE_CS(enc->enc_pic.rc.qp_initial_mode); + RVCE_CS(enc->enc_pic.rc.target_bits_picture); + RVCE_CS(enc->enc_pic.rc.peak_bits_picture_integer); + RVCE_CS(enc->enc_pic.rc.peak_bits_picture_fraction); + RVCE_CS(enc->enc_pic.rc.min_qp); + RVCE_CS(enc->enc_pic.rc.max_qp); + RVCE_CS(enc->enc_pic.rc.skip_frame_enable); + RVCE_CS(enc->enc_pic.rc.fill_data_enable); + RVCE_CS(enc->enc_pic.rc.enforce_hrd); + RVCE_CS(enc->enc_pic.rc.b_pics_delta_qp); + RVCE_CS(enc->enc_pic.rc.ref_b_pics_delta_qp); + RVCE_CS(enc->enc_pic.rc.rc_reinit_disable); + if (enc->fw_version >= 50) { + RVCE_CS(enc->enc_pic.rc.enc_lcvbr_init_qp_flag); + RVCE_CS(enc->enc_pic.rc.lcvbrsatd_based_nonlinear_bit_budget_flag); + } + RVCE_END(); +} + +static void config_extension(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x04000001); // config extension + RVCE_CS(enc->enc_pic.ce.enc_enable_perf_logging); + RVCE_END(); +} + +static void feedback(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x05000005); // feedback buffer + RVCE_WRITE(enc->fb->res->buf, enc->fb->res->domains, 0x0); // feedbackRingAddressHi/Lo + RVCE_CS(enc->enc_pic.fb.feedback_ring_size); + RVCE_END(); +} + +static void destroy(struct rvce_encoder *enc) +{ + task_info(enc, 0x00000001, 0); + + feedback(enc); + + RVCE_BEGIN(0x02000001); // destroy + RVCE_END(); +} + +static void motion_estimation(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x04000007); // motion estimation + RVCE_CS(enc->enc_pic.me.enc_ime_decimation_search); + RVCE_CS(enc->enc_pic.me.motion_est_half_pixel); + RVCE_CS(enc->enc_pic.me.motion_est_quarter_pixel); + RVCE_CS(enc->enc_pic.me.disable_favor_pmv_point); + RVCE_CS(enc->enc_pic.me.force_zero_point_center); + RVCE_CS(enc->enc_pic.me.lsmvert); + RVCE_CS(enc->enc_pic.me.enc_search_range_x); + RVCE_CS(enc->enc_pic.me.enc_search_range_y); + RVCE_CS(enc->enc_pic.me.enc_search1_range_x); + RVCE_CS(enc->enc_pic.me.enc_search1_range_y); + RVCE_CS(enc->enc_pic.me.disable_16x16_frame1); + RVCE_CS(enc->enc_pic.me.disable_satd); + RVCE_CS(enc->enc_pic.me.enable_amd); + RVCE_CS(enc->enc_pic.me.enc_disable_sub_mode); + RVCE_CS(enc->enc_pic.me.enc_ime_skip_x); + RVCE_CS(enc->enc_pic.me.enc_ime_skip_y); + RVCE_CS(enc->enc_pic.me.enc_en_ime_overw_dis_subm); + RVCE_CS(enc->enc_pic.me.enc_ime_overw_dis_subm_no); + RVCE_CS(enc->enc_pic.me.enc_ime2_search_range_x); + RVCE_CS(enc->enc_pic.me.enc_ime2_search_range_y); + RVCE_CS(enc->enc_pic.me.parallel_mode_speedup_enable); + RVCE_CS(enc->enc_pic.me.fme0_enc_disable_sub_mode); + RVCE_CS(enc->enc_pic.me.fme1_enc_disable_sub_mode); + RVCE_CS(enc->enc_pic.me.ime_sw_speedup_enable); + RVCE_END(); +} + +static void pic_control(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x04000002); // pic control + RVCE_CS(enc->enc_pic.pc.enc_use_constrained_intra_pred); + RVCE_CS(enc->enc_pic.pc.enc_cabac_enable); + RVCE_CS(enc->enc_pic.pc.enc_cabac_idc); + RVCE_CS(enc->enc_pic.pc.enc_loop_filter_disable); + RVCE_CS(enc->enc_pic.pc.enc_lf_beta_offset); + RVCE_CS(enc->enc_pic.pc.enc_lf_alpha_c0_offset); + RVCE_CS(enc->enc_pic.pc.enc_crop_left_offset); + RVCE_CS(enc->enc_pic.pc.enc_crop_right_offset); + RVCE_CS(enc->enc_pic.pc.enc_crop_top_offset); + RVCE_CS(enc->enc_pic.pc.enc_crop_bottom_offset); + RVCE_CS(enc->enc_pic.pc.enc_num_mbs_per_slice); + RVCE_CS(enc->enc_pic.pc.enc_intra_refresh_num_mbs_per_slot); + RVCE_CS(enc->enc_pic.pc.enc_force_intra_refresh); + RVCE_CS(enc->enc_pic.pc.enc_force_imb_period); + RVCE_CS(enc->enc_pic.pc.enc_pic_order_cnt_type); + RVCE_CS(enc->enc_pic.pc.log2_max_pic_order_cnt_lsb_minus4); + RVCE_CS(enc->enc_pic.pc.enc_sps_id); + RVCE_CS(enc->enc_pic.pc.enc_pps_id); + RVCE_CS(enc->enc_pic.pc.enc_constraint_set_flags); + RVCE_CS(enc->enc_pic.pc.enc_b_pic_pattern); + RVCE_CS(enc->enc_pic.pc.weight_pred_mode_b_picture); + RVCE_CS(enc->enc_pic.pc.enc_number_of_reference_frames); + RVCE_CS(enc->enc_pic.pc.enc_max_num_ref_frames); + RVCE_CS(enc->enc_pic.pc.enc_num_default_active_ref_l0); + RVCE_CS(enc->enc_pic.pc.enc_num_default_active_ref_l1); + RVCE_CS(enc->enc_pic.pc.enc_slice_mode); + RVCE_CS(enc->enc_pic.pc.enc_max_slice_size); + RVCE_END(); +} + +static void rdo(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x04000008); // rdo + RVCE_CS(enc->enc_pic.rdo.enc_disable_tbe_pred_i_frame); + RVCE_CS(enc->enc_pic.rdo.enc_disable_tbe_pred_p_frame); + RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_y); + RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_uv); + RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_y); + RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_uv); + RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_y_1); + RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_uv_1); + RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_y_1); + RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_uv_1); + RVCE_CS(enc->enc_pic.rdo.enc_16x16_cost_adj); + RVCE_CS(enc->enc_pic.rdo.enc_skip_cost_adj); + RVCE_CS(enc->enc_pic.rdo.enc_force_16x16_skip); + RVCE_CS(enc->enc_pic.rdo.enc_disable_threshold_calc_a); + RVCE_CS(enc->enc_pic.rdo.enc_luma_coeff_cost); + RVCE_CS(enc->enc_pic.rdo.enc_luma_mb_coeff_cost); + RVCE_CS(enc->enc_pic.rdo.enc_chroma_coeff_cost); + RVCE_END(); +} + +static void config(struct rvce_encoder *enc) +{ + task_info(enc, 0x00000002, 0xffffffff); + rate_control(enc); + config_extension(enc); + motion_estimation(enc); + rdo(enc); + pic_control(enc); +} + +static void session(struct rvce_encoder *enc) +{ + RVCE_BEGIN(0x00000001); // session cmd + RVCE_CS(enc->stream_handle); + RVCE_END(); +} + +static unsigned int write_sps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out) +{ + struct pipe_h264_enc_seq_param *sps = &enc->pic.seq; + struct radeon_bitstream bs; + + radeon_bs_reset(&bs, out, NULL); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, nal_byte, 8); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_fixed_bits(&bs, sps->profile_idc, 8); + radeon_bs_code_fixed_bits(&bs, sps->enc_constraint_set_flags, 6); + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* reserved_zero_2bits */ + radeon_bs_code_fixed_bits(&bs, sps->level_idc, 8); + radeon_bs_code_ue(&bs, 0x0); /* seq_parameter_set_id */ + + if (sps->profile_idc == 100 || sps->profile_idc == 110 || + sps->profile_idc == 122 || sps->profile_idc == 244 || + sps->profile_idc == 44 || sps->profile_idc == 83 || + sps->profile_idc == 86 || sps->profile_idc == 118 || + sps->profile_idc == 128 || sps->profile_idc == 138) { + radeon_bs_code_ue(&bs, 0x1); /* chroma_format_idc */ + radeon_bs_code_ue(&bs, 0x0); /* bit_depth_luma_minus8 */ + radeon_bs_code_ue(&bs, 0x0); /* bit_depth_chroma_minus8 */ + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* qpprime_y_zero_transform_bypass_flag + seq_scaling_matrix_present_flag */ + } + + radeon_bs_code_ue(&bs, 3); /* log2_max_frame_num_minus4 */ + radeon_bs_code_ue(&bs, sps->pic_order_cnt_type); + + if (sps->pic_order_cnt_type == 0) + radeon_bs_code_ue(&bs, sps->log2_max_pic_order_cnt_lsb_minus4); + + radeon_bs_code_ue(&bs, sps->max_num_ref_frames); + radeon_bs_code_fixed_bits(&bs, sps->gaps_in_frame_num_value_allowed_flag, 1); + radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.width, 16) - 1); + radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.height, 16) - 1); + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* frame_mbs_only_flag */ + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* direct_8x8_inference_flag */ + + radeon_bs_code_fixed_bits(&bs, sps->enc_frame_cropping_flag, 1); + if (sps->enc_frame_cropping_flag) { + radeon_bs_code_ue(&bs, sps->enc_frame_crop_left_offset); + radeon_bs_code_ue(&bs, sps->enc_frame_crop_right_offset); + radeon_bs_code_ue(&bs, sps->enc_frame_crop_top_offset); + radeon_bs_code_ue(&bs, sps->enc_frame_crop_bottom_offset); + } + + radeon_bs_code_fixed_bits(&bs, sps->vui_parameters_present_flag, 1); + if (sps->vui_parameters_present_flag) { + radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.aspect_ratio_info_present_flag), 1); + if (sps->vui_flags.aspect_ratio_info_present_flag) { + radeon_bs_code_fixed_bits(&bs, (sps->aspect_ratio_idc), 8); + if (sps->aspect_ratio_idc == PIPE_H2645_EXTENDED_SAR) { + radeon_bs_code_fixed_bits(&bs, (sps->sar_width), 16); + radeon_bs_code_fixed_bits(&bs, (sps->sar_height), 16); + } + } + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.overscan_info_present_flag, 1); + if (sps->vui_flags.overscan_info_present_flag) + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.overscan_appropriate_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.video_signal_type_present_flag, 1); + if (sps->vui_flags.video_signal_type_present_flag) { + radeon_bs_code_fixed_bits(&bs, sps->video_format, 3); + radeon_bs_code_fixed_bits(&bs, sps->video_full_range_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.colour_description_present_flag, 1); + if (sps->vui_flags.colour_description_present_flag) { + radeon_bs_code_fixed_bits(&bs, sps->colour_primaries, 8); + radeon_bs_code_fixed_bits(&bs, sps->transfer_characteristics, 8); + radeon_bs_code_fixed_bits(&bs, sps->matrix_coefficients, 8); + } + } + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.chroma_loc_info_present_flag, 1); + if (sps->vui_flags.chroma_loc_info_present_flag) { + radeon_bs_code_ue(&bs, sps->chroma_sample_loc_type_top_field); + radeon_bs_code_ue(&bs, sps->chroma_sample_loc_type_bottom_field); + } + radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.timing_info_present_flag), 1); + if (sps->vui_flags.timing_info_present_flag) { + radeon_bs_code_fixed_bits(&bs, (sps->num_units_in_tick), 32); + radeon_bs_code_fixed_bits(&bs, (sps->time_scale), 32); + radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.fixed_frame_rate_flag), 1); + } + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.nal_hrd_parameters_present_flag, 1); + if (sps->vui_flags.nal_hrd_parameters_present_flag) + radeon_bs_h264_hrd_parameters(&bs, &sps->nal_hrd_parameters); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.vcl_hrd_parameters_present_flag, 1); + if (sps->vui_flags.vcl_hrd_parameters_present_flag) + radeon_bs_h264_hrd_parameters(&bs, &sps->vcl_hrd_parameters); + if (sps->vui_flags.nal_hrd_parameters_present_flag || sps->vui_flags.vcl_hrd_parameters_present_flag) + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.low_delay_hrd_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.pic_struct_present_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.bitstream_restriction_flag, 1); + if (sps->vui_flags.bitstream_restriction_flag) { + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* motion_vectors_over_pic_boundaries_flag */ + radeon_bs_code_ue(&bs, 0x2); /* max_bytes_per_pic_denom */ + radeon_bs_code_ue(&bs, 0x1); /* max_bits_per_mb_denom */ + radeon_bs_code_ue(&bs, 0x10); /* log2_max_mv_length_horizontal */ + radeon_bs_code_ue(&bs, 0x10); /* log2_max_mv_length_vertical */ + radeon_bs_code_ue(&bs, sps->max_num_reorder_frames); + radeon_bs_code_ue(&bs, sps->max_dec_frame_buffering); + } + } + + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); + + return bs.bits_output / 8; +} + +static unsigned int write_pps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out) +{ + struct radeon_bitstream bs; + + radeon_bs_reset(&bs, out, NULL); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, nal_byte, 8); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_ue(&bs, 0x0); /* pic_parameter_set_id */ + radeon_bs_code_ue(&bs, 0x0); /* seq_parameter_set_id */ + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.pc.enc_cabac_enable, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* bottom_field_pic_order_in_frame_present_flag */ + radeon_bs_code_ue(&bs, 0x0); /* num_slice_groups_minus_1 */ + radeon_bs_code_ue(&bs, enc->enc_pic.pc.enc_num_default_active_ref_l0 - 1); + radeon_bs_code_ue(&bs, enc->enc_pic.pc.enc_num_default_active_ref_l1 - 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* weighted_pred_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* weighted_bipred_idc */ + radeon_bs_code_se(&bs, 0x0); /* pic_init_qp_minus26 */ + radeon_bs_code_se(&bs, 0x0); /* pic_init_qs_minus26 */ + radeon_bs_code_se(&bs, 0x0); /* chroma_qp_index_offset */ + bool deblocking_filter_present_flag = + enc->enc_pic.pc.enc_loop_filter_disable || + enc->enc_pic.pc.enc_lf_beta_offset || + enc->enc_pic.pc.enc_lf_alpha_c0_offset; + radeon_bs_code_fixed_bits(&bs, deblocking_filter_present_flag, 1); + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.pc.enc_use_constrained_intra_pred, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* redundant_pic_cnt_present_flag */ + + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); + + return bs.bits_output / 8; +} + +/** + * flush commands to the hardware + */ +static void flush(struct rvce_encoder *enc, unsigned flags, struct pipe_fence_handle **fence) +{ + enc->ws->cs_flush(&enc->cs, flags, fence); +} + /** * destroy this video encoder */ @@ -91,8 +840,8 @@ static void rvce_destroy(struct pipe_video_codec *encoder) struct rvid_buffer fb; si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING); enc->fb = &fb; - enc->session(enc); - enc->destroy(enc); + session(enc); + destroy(enc); flush(enc, PIPE_FLUSH_ASYNC, NULL); si_vid_destroy_buffer(&fb); } @@ -141,7 +890,7 @@ static void rvce_begin_frame(struct pipe_video_codec *encoder, struct pipe_video enc->pic.rate_ctrl[0].frame_rate_den != pic->rate_ctrl[0].frame_rate_den; enc->pic = *pic; - enc->si_get_pic_param(enc, pic); + get_param(enc, pic); enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma); enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma); @@ -168,19 +917,18 @@ static void rvce_begin_frame(struct pipe_video_codec *encoder, struct pipe_video enc->stream_handle = si_vid_alloc_stream_handle(); si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING); enc->fb = &fb; - enc->session(enc); - enc->create(enc); - enc->config(enc); - enc->feedback(enc); + session(enc); + create(enc); + config(enc); + feedback(enc); flush(enc, PIPE_FLUSH_ASYNC, NULL); - // dump_feedback(enc, &fb); si_vid_destroy_buffer(&fb); need_rate_control = false; } if (need_rate_control) { - enc->session(enc); - enc->config(enc); + session(enc); + config(enc); flush(enc, PIPE_FLUSH_ASYNC, NULL); } } @@ -229,10 +977,10 @@ static void *si_vce_encode_headers(struct rvce_encoder *enc) switch (header->type) { case PIPE_H264_NAL_SPS: - size = si_vce_write_sps(enc, nal_byte, ptr + offset); + size = write_sps(enc, nal_byte, ptr + offset); break; case PIPE_H264_NAL_PPS: - size = si_vce_write_pps(enc, nal_byte, ptr + offset); + size = write_pps(enc, nal_byte, ptr + offset); break; default: assert(header->buffer); @@ -275,10 +1023,9 @@ static void rvce_encode_bitstream(struct pipe_video_codec *encoder, enc->fb->user_data = si_vce_encode_headers(enc); - if (!radeon_emitted(&enc->cs, 0)) - enc->session(enc); - enc->encode(enc); - enc->feedback(enc); + session(enc); + encode(enc); + feedback(enc); } static int rvce_end_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, @@ -332,7 +1079,6 @@ static void rvce_get_feedback(struct pipe_video_codec *encoder, void *feedback, metadata->codec_unit_metadata[0].flags = 0; } - // dump_feedback(enc, fb); si_vid_destroy_buffer(fb); FREE(fb); } @@ -415,7 +1161,6 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context, } enc->fw_version = (sscreen->info.vce_fw_version & (0xff << 24)) >> 24; - si_vce_52_init(enc); return &enc->base; diff --git a/src/gallium/drivers/radeonsi/radeon_vce.h b/src/gallium/drivers/radeonsi/radeon_vce.h index 71961c23ba4..70abb7b3ebb 100644 --- a/src/gallium/drivers/radeonsi/radeon_vce.h +++ b/src/gallium/drivers/radeonsi/radeon_vce.h @@ -282,42 +282,21 @@ struct rvce_h264_enc_pic { struct rvce_enc_create ec; struct rvce_config_ext ce; - unsigned quant_i_frames; - unsigned quant_p_frames; - unsigned quant_b_frames; - enum pipe_h2645_enc_picture_type picture_type; unsigned frame_num; unsigned frame_num_cnt; unsigned p_remain; unsigned i_remain; - unsigned idr_pic_id; unsigned pic_order_cnt; unsigned addrmode_arraymode_disrdo_distwoinstants; bool not_referenced; - bool is_idr; }; /* VCE encoder representation */ struct rvce_encoder { struct pipe_video_codec base; - /* version specific packets */ - void (*session)(struct rvce_encoder *enc); - void (*create)(struct rvce_encoder *enc); - void (*feedback)(struct rvce_encoder *enc); - void (*rate_control)(struct rvce_encoder *enc); - void (*config_extension)(struct rvce_encoder *enc); - void (*pic_control)(struct rvce_encoder *enc); - void (*motion_estimation)(struct rvce_encoder *enc); - void (*rdo)(struct rvce_encoder *enc); - void (*config)(struct rvce_encoder *enc); - void (*encode)(struct rvce_encoder *enc); - void (*destroy)(struct rvce_encoder *enc); - void (*task_info)(struct rvce_encoder *enc, uint32_t op, uint32_t fb_idx); - void (*si_get_pic_param)(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic); - unsigned stream_handle; struct pipe_screen *screen; @@ -357,13 +336,6 @@ struct rvce_feedback_data { struct rvce_output_unit_segment segments[]; }; -unsigned int si_vce_write_sps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out); -unsigned int si_vce_write_pps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out); - -/* CPB handling functions */ -void si_vce_frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_offset, - signed *chroma_offset); - struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context, const struct pipe_video_codec *templat, struct radeon_winsys *ws, @@ -374,7 +346,4 @@ bool si_vce_is_fw_version_supported(struct si_screen *sscreen); void si_vce_add_buffer(struct rvce_encoder *enc, struct pb_buffer_lean *buf, unsigned usage, enum radeon_bo_domain domain, signed offset); -/* init vce fw 52 specific callbacks */ -void si_vce_52_init(struct rvce_encoder *enc); - #endif diff --git a/src/gallium/drivers/radeonsi/radeon_vce_52.c b/src/gallium/drivers/radeonsi/radeon_vce_52.c deleted file mode 100644 index 65a11653303..00000000000 --- a/src/gallium/drivers/radeonsi/radeon_vce_52.c +++ /dev/null @@ -1,815 +0,0 @@ -/************************************************************************** - * - * Copyright 2015 Advanced Micro Devices, Inc. - * - * SPDX-License-Identifier: MIT - * - **************************************************************************/ - -#include "pipe/p_video_codec.h" -#include "radeon_vce.h" -#include "radeon_video.h" -#include "radeon_bitstream.h" -#include "radeonsi/si_pipe.h" -#include "util/u_memory.h" -#include "util/u_video.h" -#include "vl/vl_video_buffer.h" - -#include - -#define REF_LIST_MODIFICATION_OP_END 0 -#define REF_LIST_MODIFICATION_OP_SHORT_TERM_SUBTRACT 1 -#define REF_LIST_MODIFICATION_OP_LONG_TERM 2 -#define REF_LIST_MODIFICATION_OP_VIEW_ADD 3 - -#define INTRAREFRESH_METHOD_BAR_BASED 6 - -static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) -{ - enc->enc_pic.rc.rc_method = pic->rate_ctrl[0].rate_ctrl_method; - enc->enc_pic.rc.target_bitrate = pic->rate_ctrl[0].target_bitrate; - enc->enc_pic.rc.peak_bitrate = pic->rate_ctrl[0].peak_bitrate; - enc->enc_pic.rc.quant_i_frames = pic->quant_i_frames; - enc->enc_pic.rc.quant_p_frames = pic->quant_p_frames; - enc->enc_pic.rc.quant_b_frames = pic->quant_b_frames; - enc->enc_pic.rc.gop_size = pic->gop_size; - enc->enc_pic.rc.frame_rate_num = pic->rate_ctrl[0].frame_rate_num; - enc->enc_pic.rc.frame_rate_den = pic->rate_ctrl[0].frame_rate_den; - enc->enc_pic.rc.min_qp = pic->rate_ctrl[0].min_qp; - enc->enc_pic.rc.max_qp = pic->rate_ctrl[0].max_qp ? pic->rate_ctrl[0].max_qp : 51; - enc->enc_pic.rc.max_au_size = pic->rate_ctrl[0].max_au_size; - enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl[0].vbv_buffer_size; - enc->enc_pic.rc.vbv_buf_lv = pic->rate_ctrl[0].vbv_buf_lv; - enc->enc_pic.rc.fill_data_enable = pic->rate_ctrl[0].fill_data_enable; - enc->enc_pic.rc.enforce_hrd = pic->rate_ctrl[0].enforce_hrd; - enc->enc_pic.rc.target_bits_picture = - enc->pic.rate_ctrl[0].target_bitrate * - ((float)enc->pic.rate_ctrl[0].frame_rate_den / - enc->pic.rate_ctrl[0].frame_rate_num); - enc->enc_pic.rc.peak_bits_picture_integer = - enc->pic.rate_ctrl[0].peak_bitrate * - ((float)enc->pic.rate_ctrl[0].frame_rate_den / - enc->pic.rate_ctrl[0].frame_rate_num); - enc->enc_pic.rc.peak_bits_picture_fraction = - (((enc->pic.rate_ctrl[0].peak_bitrate * - (uint64_t)enc->pic.rate_ctrl[0].frame_rate_den) % - enc->pic.rate_ctrl[0].frame_rate_num) << 32) / - enc->pic.rate_ctrl[0].frame_rate_num; -} - -static void get_motion_estimation_param(struct rvce_encoder *enc, - struct pipe_h264_enc_picture_desc *pic) -{ - enc->enc_pic.me.enc_ime_decimation_search = 1; - enc->enc_pic.me.motion_est_half_pixel = 1; - enc->enc_pic.me.motion_est_quarter_pixel = 1; - enc->enc_pic.me.disable_favor_pmv_point = 0; - enc->enc_pic.me.lsmvert = 2; - enc->enc_pic.me.disable_16x16_frame1 = 0; - enc->enc_pic.me.disable_satd = 0; - enc->enc_pic.me.enc_ime_skip_x = 0; - enc->enc_pic.me.enc_ime_skip_y = 0; - enc->enc_pic.me.enc_ime2_search_range_x = 4; - enc->enc_pic.me.enc_ime2_search_range_y = 4; - enc->enc_pic.me.parallel_mode_speedup_enable = 0; - enc->enc_pic.me.fme0_enc_disable_sub_mode = 0; - enc->enc_pic.me.fme1_enc_disable_sub_mode = 0; - enc->enc_pic.me.ime_sw_speedup_enable = 0; - - switch (pic->quality_modes.preset_mode) { - case 0: /* SPEED */ - enc->enc_pic.me.force_zero_point_center = 0; - enc->enc_pic.me.enc_search_range_x = 16; - enc->enc_pic.me.enc_search_range_y = 16; - enc->enc_pic.me.enc_search1_range_x = 16; - enc->enc_pic.me.enc_search1_range_y = 16; - enc->enc_pic.me.enable_amd = 0; - enc->enc_pic.me.enc_disable_sub_mode = 126; - enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0; - enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0; - break; - case 1: /* BALANCED */ - enc->enc_pic.me.force_zero_point_center = 0; - enc->enc_pic.me.enc_search_range_x = 16; - enc->enc_pic.me.enc_search_range_y = 16; - enc->enc_pic.me.enc_search1_range_x = 16; - enc->enc_pic.me.enc_search1_range_y = 16; - enc->enc_pic.me.enable_amd = 0; - enc->enc_pic.me.enc_disable_sub_mode = 120; - enc->enc_pic.me.enc_en_ime_overw_dis_subm = 1; - enc->enc_pic.me.enc_ime_overw_dis_subm_no = 1; - break; - case 2: /* QUALITY */ - default: - enc->enc_pic.me.force_zero_point_center = 1; - enc->enc_pic.me.enc_search_range_x = 36; - enc->enc_pic.me.enc_search_range_y = 36; - enc->enc_pic.me.enc_search1_range_x = 36; - enc->enc_pic.me.enc_search1_range_y = 36; - enc->enc_pic.me.enable_amd = 1; - enc->enc_pic.me.enc_disable_sub_mode = 0; - enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0; - enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0; - break; - } -} - -static void get_pic_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) -{ - uint32_t num_mbs_total, num_mbs_in_slice; - - num_mbs_total = DIV_ROUND_UP(enc->base.width, 16) * DIV_ROUND_UP(enc->base.height, 16); - - if (pic->num_slice_descriptors <= 1) { - num_mbs_in_slice = num_mbs_total; - } else { - bool use_app_config = true; - num_mbs_in_slice = pic->slices_descriptors[0].num_macroblocks; - - /* All slices must have equal size */ - for (unsigned i = 1; i < pic->num_slice_descriptors - 1; i++) { - if (num_mbs_in_slice != pic->slices_descriptors[i].num_macroblocks) - use_app_config = false; - } - /* Except last one can be smaller */ - if (pic->slices_descriptors[pic->num_slice_descriptors - 1].num_macroblocks > num_mbs_in_slice) - use_app_config = false; - - if (!use_app_config) { - assert(num_mbs_total >= pic->num_slice_descriptors); - num_mbs_in_slice = - (num_mbs_total + pic->num_slice_descriptors - 1) / pic->num_slice_descriptors; - } - } - - if (pic->seq.enc_frame_cropping_flag) { - enc->enc_pic.pc.enc_crop_left_offset = pic->seq.enc_frame_crop_left_offset; - enc->enc_pic.pc.enc_crop_right_offset = pic->seq.enc_frame_crop_right_offset; - enc->enc_pic.pc.enc_crop_top_offset = pic->seq.enc_frame_crop_top_offset; - enc->enc_pic.pc.enc_crop_bottom_offset = pic->seq.enc_frame_crop_bottom_offset; - } - enc->enc_pic.pc.enc_num_mbs_per_slice = num_mbs_in_slice; - enc->enc_pic.pc.enc_number_of_reference_frames = 1; - enc->enc_pic.pc.enc_max_num_ref_frames = pic->seq.max_num_ref_frames; - enc->enc_pic.pc.enc_num_default_active_ref_l0 = pic->pic_ctrl.num_ref_idx_l0_default_active_minus1 + 1; - enc->enc_pic.pc.enc_num_default_active_ref_l1 = pic->pic_ctrl.num_ref_idx_l1_default_active_minus1 + 1; - enc->enc_pic.pc.enc_slice_mode = 1; - enc->enc_pic.pc.enc_use_constrained_intra_pred = pic->pic_ctrl.constrained_intra_pred_flag; - enc->enc_pic.pc.enc_cabac_enable = pic->pic_ctrl.enc_cabac_enable; - enc->enc_pic.pc.enc_cabac_idc = pic->pic_ctrl.enc_cabac_init_idc; - enc->enc_pic.pc.enc_constraint_set_flags = pic->seq.enc_constraint_set_flags << 2; - enc->enc_pic.pc.enc_loop_filter_disable = !!pic->dbk.disable_deblocking_filter_idc; - enc->enc_pic.pc.enc_lf_beta_offset = pic->dbk.beta_offset_div2; - enc->enc_pic.pc.enc_lf_alpha_c0_offset = pic->dbk.alpha_c0_offset_div2; - enc->enc_pic.pc.enc_pic_order_cnt_type = pic->seq.pic_order_cnt_type; - enc->enc_pic.pc.log2_max_pic_order_cnt_lsb_minus4 = pic->seq.log2_max_pic_order_cnt_lsb_minus4; -} - -static void get_task_info_param(struct rvce_encoder *enc) -{ - enc->enc_pic.ti.offset_of_next_task_info = 0xffffffff; -} - -static void get_feedback_buffer_param(struct rvce_encoder *enc, struct pipe_enc_feedback_metadata* metadata) -{ - enc->enc_pic.fb.feedback_ring_size = 0x00000001; -} - -static void get_config_ext_param(struct rvce_encoder *enc) -{ - enc->enc_pic.ce.enc_enable_perf_logging = 0x00000003; -} - -static void get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) -{ - int i; - - get_rate_control_param(enc, pic); - get_motion_estimation_param(enc, pic); - get_pic_control_param(enc, pic); - get_task_info_param(enc); - get_feedback_buffer_param(enc, NULL); - get_config_ext_param(enc); - - enc->enc_pic.picture_type = pic->picture_type; - enc->enc_pic.frame_num = pic->frame_num; - enc->enc_pic.frame_num_cnt = pic->frame_num_cnt - 1; - enc->enc_pic.p_remain = pic->p_remain; - enc->enc_pic.i_remain = pic->i_remain; - enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; - enc->enc_pic.not_referenced = pic->not_referenced; - enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = enc->fw_version >= 52 ? 0x01000201 : 0; - enc->enc_pic.is_idr = (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR); - enc->enc_pic.eo.enc_idr_pic_id = pic->idr_pic_id; - enc->enc_pic.ec.enc_vbaq_mode = - pic->rate_ctrl[0].rate_ctrl_method != PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE && - pic->quality_modes.vbaq_mode; - if (pic->intra_refresh.mode != PIPE_VIDEO_ENC_INTRA_REFRESH_NONE) { - enc->enc_pic.eo.enable_intra_refresh = 1; - enc->enc_pic.pc.enc_force_intra_refresh = INTRAREFRESH_METHOD_BAR_BASED; - enc->enc_pic.pc.enc_intra_refresh_num_mbs_per_slot = pic->intra_refresh.region_size; - } else { - enc->enc_pic.eo.enable_intra_refresh = 0; - } - - enc->enc_pic.eo.num_ref_idx_active_override_flag = pic->slice.num_ref_idx_active_override_flag; - enc->enc_pic.eo.num_ref_idx_l0_active_minus1 = pic->slice.num_ref_idx_l0_active_minus1; - enc->enc_pic.eo.num_ref_idx_l1_active_minus1 = pic->slice.num_ref_idx_l1_active_minus1; - - i = 0; - if (pic->slice.ref_pic_list_modification_flag_l0) { - for (; i < MIN2(4, pic->slice.num_ref_list0_mod_operations); i++) { - struct pipe_h264_ref_list_mod_entry *entry = &pic->slice.ref_list0_mod_operations[i]; - switch (entry->modification_of_pic_nums_idc) { - case 0: - enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_SHORT_TERM_SUBTRACT; - enc->enc_pic.eo.enc_ref_list_modification_num[i] = entry->abs_diff_pic_num_minus1; - break; - case 2: - enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_LONG_TERM; - enc->enc_pic.eo.enc_ref_list_modification_num[i] = entry->long_term_pic_num; - break; - case 5: - enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_VIEW_ADD; - enc->enc_pic.eo.enc_ref_list_modification_num[i] = entry->abs_diff_pic_num_minus1; - break; - default: - case 3: - enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_END; - break; - } - } - } - if (i < 4) - enc->enc_pic.eo.enc_ref_list_modification_op[i] = REF_LIST_MODIFICATION_OP_END; - - i = 0; - if (pic->pic_ctrl.nal_unit_type == PIPE_H264_NAL_IDR_SLICE) { - enc->enc_pic.eo.enc_decoded_picture_marking_op[i++] = pic->slice.long_term_reference_flag ? 6 : 0; - } else if (pic->slice.adaptive_ref_pic_marking_mode_flag) { - for (; i < MIN2(4, pic->slice.num_ref_pic_marking_operations); i++) { - struct pipe_h264_ref_pic_marking_entry *entry = &pic->slice.ref_pic_marking_operations[i]; - enc->enc_pic.eo.enc_decoded_picture_marking_op[i] = entry->memory_management_control_operation; - switch (entry->memory_management_control_operation) { - case 1: - enc->enc_pic.eo.enc_decoded_picture_marking_num[i] = entry->difference_of_pic_nums_minus1; - break; - case 2: - enc->enc_pic.eo.enc_decoded_picture_marking_num[i] = entry->long_term_pic_num; - break; - case 3: - enc->enc_pic.eo.enc_decoded_picture_marking_num[i] = entry->difference_of_pic_nums_minus1; - enc->enc_pic.eo.enc_decoded_picture_marking_idx[i] = entry->long_term_frame_idx; - break; - case 4: - enc->enc_pic.eo.enc_decoded_picture_marking_idx[i] = entry->max_long_term_frame_idx_plus1; - break; - case 6: - enc->enc_pic.eo.enc_decoded_picture_marking_idx[i] = entry->long_term_frame_idx; - break; - default: - break; - } - } - } - if (i < 4) - enc->enc_pic.eo.enc_decoded_picture_marking_op[i] = 0; - - enc->enc_pic.eo.cur_dpb_idx = pic->dpb_curr_pic; - - enc->enc_pic.eo.l0_dpb_idx = pic->ref_list0[0]; - - enc->enc_pic.eo.l1_dpb_idx = PIPE_H2645_LIST_REF_INVALID_ENTRY; - enc->enc_pic.eo.l1_luma_offset = 0xffffffff; - enc->enc_pic.eo.l1_chroma_offset = 0xffffffff; -} - -static void create(struct rvce_encoder *enc) -{ - struct si_screen *sscreen = (struct si_screen *)enc->screen; - enc->task_info(enc, 0x00000000, 0); - - RVCE_BEGIN(0x01000001); // create cmd - RVCE_CS(enc->enc_pic.ec.enc_use_circular_buffer); - RVCE_CS(enc->pic.seq.profile_idc); // encProfile - RVCE_CS(enc->pic.seq.level_idc); // encLevel - RVCE_CS(enc->enc_pic.ec.enc_pic_struct_restriction); - RVCE_CS(align(enc->base.width, 16)); // encImageWidth - RVCE_CS(align(enc->base.height, 16)); // encImageHeight - - if (sscreen->info.gfx_level < GFX9) { - RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encRefPicLumaPitch - RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encRefPicChromaPitch - RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16) / 8); // encRefYHeightInQw - } else { - RVCE_CS(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe); // encRefPicLumaPitch - RVCE_CS(enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe); // encRefPicChromaPitch - RVCE_CS(align(enc->luma->u.gfx9.surf_height, 16) / 8); // encRefYHeightInQw - } - - RVCE_CS(enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants); - - if (enc->fw_version >= 52) { - RVCE_CS(enc->enc_pic.ec.enc_pre_encode_context_buffer_offset); - RVCE_CS(enc->enc_pic.ec.enc_pre_encode_input_luma_buffer_offset); - RVCE_CS(enc->enc_pic.ec.enc_pre_encode_input_chroma_buffer_offset); - RVCE_CS(enc->enc_pic.ec.enc_pre_encode_mode_chromaflag_vbaqmode_scenechangesensitivity); - } - RVCE_END(); -} - -static void encode(struct rvce_encoder *enc) -{ - struct si_screen *sscreen = (struct si_screen *)enc->screen; - signed luma_offset, chroma_offset; - int i; - - enc->task_info(enc, 0x00000003, 0); - - RVCE_BEGIN(0x05000001); // context buffer - RVCE_READWRITE(enc->dpb.res->buf, enc->dpb.res->domains, 0); // encodeContextAddressHi/Lo - RVCE_END(); - - RVCE_BEGIN(0x05000004); // video bitstream buffer - RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, enc->bs_offset); // videoBitstreamRingAddressHi/Lo - RVCE_CS(enc->bs_size); // videoBitstreamRingSize - RVCE_END(); - - if (enc->dual_pipe) { - unsigned aux_offset = 0; - RVCE_BEGIN(0x05000002); // auxiliary buffer - for (i = 0; i < 8; ++i) { - RVCE_CS(aux_offset); - aux_offset += RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE; - } - for (i = 0; i < 8; ++i) - RVCE_CS(RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE); - RVCE_END(); - } - - RVCE_BEGIN(0x03000001); // encode - RVCE_CS(enc->enc_pic.eo.insert_headers); - RVCE_CS(enc->enc_pic.eo.picture_structure); - RVCE_CS(enc->bs_size - enc->bs_offset); // allowedMaxBitstreamSize - RVCE_CS(enc->enc_pic.eo.force_refresh_map); - RVCE_CS(enc->enc_pic.eo.insert_aud); - RVCE_CS(enc->enc_pic.eo.end_of_sequence); - RVCE_CS(enc->enc_pic.eo.end_of_stream); - - if (sscreen->info.gfx_level < GFX9) { - RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, - (uint64_t)enc->luma->u.legacy.level[0].offset_256B * 256); // inputPictureLumaAddressHi/Lo - RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, - (uint64_t)enc->chroma->u.legacy.level[0].offset_256B * 256); // inputPictureChromaAddressHi/Lo - RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch - RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch - RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch - } else { - RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, - enc->luma->u.gfx9.surf_offset); // inputPictureLumaAddressHi/Lo - RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM, - enc->chroma->u.gfx9.surf_offset); // inputPictureChromaAddressHi/Lo - RVCE_CS(align(enc->luma->u.gfx9.surf_height, 16)); // encInputFrameYPitch - RVCE_CS(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe); // encInputPicLumaPitch - RVCE_CS(enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe); // encInputPicChromaPitch - enc->enc_pic.eo.enc_input_pic_swizzle_mode = enc->luma->u.gfx9.swizzle_mode; - } - - enc->enc_pic.eo.enc_disable_two_pipe_mode = enc->fw_version >= 50 ? !enc->dual_pipe : 0; - RVCE_CS(enc->enc_pic.eo.enc_input_pic_addr_array_disable2pipe_disablemboffload); - RVCE_CS(enc->enc_pic.eo.enc_input_pic_tile_config); - RVCE_CS(enc->enc_pic.picture_type); // encPicType - RVCE_CS(enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR); // encIdrFlag - RVCE_CS(enc->enc_pic.eo.enc_idr_pic_id); - RVCE_CS(enc->enc_pic.eo.enc_mgs_key_pic); - RVCE_CS(!enc->enc_pic.not_referenced); - RVCE_CS(enc->enc_pic.eo.enc_temporal_layer_index); - RVCE_CS(enc->enc_pic.eo.num_ref_idx_active_override_flag); - RVCE_CS(enc->enc_pic.eo.num_ref_idx_l0_active_minus1); - RVCE_CS(enc->enc_pic.eo.num_ref_idx_l1_active_minus1); - - for (i = 0; i < 4; ++i) { - RVCE_CS(enc->enc_pic.eo.enc_ref_list_modification_op[i]); - RVCE_CS(enc->enc_pic.eo.enc_ref_list_modification_num[i]); - } - - for (i = 0; i < 4; ++i) { - RVCE_CS(enc->enc_pic.eo.enc_decoded_picture_marking_op[i]); - RVCE_CS(enc->enc_pic.eo.enc_decoded_picture_marking_num[i]); - RVCE_CS(enc->enc_pic.eo.enc_decoded_picture_marking_idx[i]); - } - - for (i = 0; i < 4; ++i) { - RVCE_CS(enc->enc_pic.eo.enc_decoded_ref_base_picture_marking_op[i]); - RVCE_CS(enc->enc_pic.eo.enc_decoded_ref_base_picture_marking_num[i]); - } - - // encReferencePictureL0[0] - if (enc->enc_pic.eo.l0_dpb_idx != PIPE_H2645_LIST_REF_INVALID_ENTRY) { - si_vce_frame_offset(enc, enc->enc_pic.eo.l0_dpb_idx, &luma_offset, &chroma_offset); - enc->enc_pic.eo.l0_luma_offset = luma_offset; - enc->enc_pic.eo.l0_chroma_offset = chroma_offset; - } else { - enc->enc_pic.eo.l0_luma_offset = 0xffffffff; - enc->enc_pic.eo.l0_chroma_offset = 0xffffffff; - } - RVCE_CS(0x00000000); // pictureStructure - RVCE_CS(enc->enc_pic.eo.l0_enc_pic_type); - RVCE_CS(enc->enc_pic.eo.l0_frame_number); - RVCE_CS(enc->enc_pic.eo.l0_picture_order_count); - RVCE_CS(enc->enc_pic.eo.l0_luma_offset); - RVCE_CS(enc->enc_pic.eo.l0_chroma_offset); - - // encReferencePictureL0[1] - enc->enc_pic.eo.l0_picture_structure = 0x00000000; - enc->enc_pic.eo.l0_enc_pic_type = 0x00000000; - enc->enc_pic.eo.l0_frame_number = 0x00000000; - enc->enc_pic.eo.l0_picture_order_count = 0x00000000; - enc->enc_pic.eo.l0_luma_offset = 0xffffffff; - enc->enc_pic.eo.l0_chroma_offset = 0xffffffff; - RVCE_CS(enc->enc_pic.eo.l0_picture_structure); - RVCE_CS(enc->enc_pic.eo.l0_enc_pic_type); - RVCE_CS(enc->enc_pic.eo.l0_frame_number); - RVCE_CS(enc->enc_pic.eo.l0_picture_order_count); - RVCE_CS(enc->enc_pic.eo.l0_luma_offset); - RVCE_CS(enc->enc_pic.eo.l0_chroma_offset); - - // encReferencePictureL1[0] - RVCE_CS(0x00000000); // pictureStructure - RVCE_CS(enc->enc_pic.eo.l1_enc_pic_type); - RVCE_CS(enc->enc_pic.eo.l1_frame_number); - RVCE_CS(enc->enc_pic.eo.l1_picture_order_count); - RVCE_CS(enc->enc_pic.eo.l1_luma_offset); - RVCE_CS(enc->enc_pic.eo.l1_chroma_offset); - - si_vce_frame_offset(enc, enc->enc_pic.eo.cur_dpb_idx, &luma_offset, &chroma_offset); - RVCE_CS(luma_offset); - RVCE_CS(chroma_offset); - RVCE_CS(enc->enc_pic.eo.enc_coloc_buffer_offset); - RVCE_CS(enc->enc_pic.eo.enc_reconstructed_ref_base_picture_luma_offset); - RVCE_CS(enc->enc_pic.eo.enc_reconstructed_ref_base_picture_chroma_offset); - RVCE_CS(enc->enc_pic.eo.enc_reference_ref_base_picture_luma_offset); - RVCE_CS(enc->enc_pic.eo.enc_reference_ref_base_picture_chroma_offset); - RVCE_CS(enc->enc_pic.frame_num_cnt); - RVCE_CS(enc->enc_pic.frame_num); - RVCE_CS(enc->enc_pic.pic_order_cnt); - RVCE_CS(enc->enc_pic.i_remain); - RVCE_CS(enc->enc_pic.p_remain); - RVCE_CS(enc->enc_pic.eo.num_b_pic_remain_in_rcgop); - RVCE_CS(enc->enc_pic.eo.num_ir_pic_remain_in_rcgop); - RVCE_CS(enc->enc_pic.eo.enable_intra_refresh); - - if (enc->fw_version >= 52) { - RVCE_CS(enc->enc_pic.eo.aq_variance_en); - RVCE_CS(enc->enc_pic.eo.aq_block_size); - RVCE_CS(enc->enc_pic.eo.aq_mb_variance_sel); - RVCE_CS(enc->enc_pic.eo.aq_frame_variance_sel); - RVCE_CS(enc->enc_pic.eo.aq_param_a); - RVCE_CS(enc->enc_pic.eo.aq_param_b); - RVCE_CS(enc->enc_pic.eo.aq_param_c); - RVCE_CS(enc->enc_pic.eo.aq_param_d); - RVCE_CS(enc->enc_pic.eo.aq_param_e); - RVCE_CS(enc->enc_pic.eo.context_in_sfb); - } - RVCE_END(); -} - -static void rate_control(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x04000005); // rate control - RVCE_CS(enc->enc_pic.rc.rc_method); - RVCE_CS(enc->enc_pic.rc.target_bitrate); - RVCE_CS(enc->enc_pic.rc.peak_bitrate); - RVCE_CS(enc->enc_pic.rc.frame_rate_num); - RVCE_CS(enc->enc_pic.rc.gop_size); - RVCE_CS(enc->enc_pic.rc.quant_i_frames); - RVCE_CS(enc->enc_pic.rc.quant_p_frames); - RVCE_CS(enc->enc_pic.rc.quant_b_frames); - RVCE_CS(enc->enc_pic.rc.vbv_buffer_size); - RVCE_CS(enc->enc_pic.rc.frame_rate_den); - RVCE_CS(enc->enc_pic.rc.vbv_buf_lv); - RVCE_CS(enc->enc_pic.rc.max_au_size); - RVCE_CS(enc->enc_pic.rc.qp_initial_mode); - RVCE_CS(enc->enc_pic.rc.target_bits_picture); - RVCE_CS(enc->enc_pic.rc.peak_bits_picture_integer); - RVCE_CS(enc->enc_pic.rc.peak_bits_picture_fraction); - RVCE_CS(enc->enc_pic.rc.min_qp); - RVCE_CS(enc->enc_pic.rc.max_qp); - RVCE_CS(enc->enc_pic.rc.skip_frame_enable); - RVCE_CS(enc->enc_pic.rc.fill_data_enable); - RVCE_CS(enc->enc_pic.rc.enforce_hrd); - RVCE_CS(enc->enc_pic.rc.b_pics_delta_qp); - RVCE_CS(enc->enc_pic.rc.ref_b_pics_delta_qp); - RVCE_CS(enc->enc_pic.rc.rc_reinit_disable); - if (enc->fw_version >= 50) { - RVCE_CS(enc->enc_pic.rc.enc_lcvbr_init_qp_flag); - RVCE_CS(enc->enc_pic.rc.lcvbrsatd_based_nonlinear_bit_budget_flag); - } - RVCE_END(); -} - -static void config(struct rvce_encoder *enc) -{ - enc->task_info(enc, 0x00000002, 0xffffffff); - enc->rate_control(enc); - enc->config_extension(enc); - enc->motion_estimation(enc); - enc->rdo(enc); - enc->pic_control(enc); -} - -static void config_extension(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x04000001); // config extension - RVCE_CS(enc->enc_pic.ce.enc_enable_perf_logging); - RVCE_END(); -} - -static void feedback(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x05000005); // feedback buffer - RVCE_WRITE(enc->fb->res->buf, enc->fb->res->domains, 0x0); // feedbackRingAddressHi/Lo - RVCE_CS(enc->enc_pic.fb.feedback_ring_size); - RVCE_END(); -} - -static void destroy(struct rvce_encoder *enc) -{ - enc->task_info(enc, 0x00000001, 0); - - feedback(enc); - - RVCE_BEGIN(0x02000001); // destroy - RVCE_END(); -} - -static void motion_estimation(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x04000007); // motion estimation - RVCE_CS(enc->enc_pic.me.enc_ime_decimation_search); - RVCE_CS(enc->enc_pic.me.motion_est_half_pixel); - RVCE_CS(enc->enc_pic.me.motion_est_quarter_pixel); - RVCE_CS(enc->enc_pic.me.disable_favor_pmv_point); - RVCE_CS(enc->enc_pic.me.force_zero_point_center); - RVCE_CS(enc->enc_pic.me.lsmvert); - RVCE_CS(enc->enc_pic.me.enc_search_range_x); - RVCE_CS(enc->enc_pic.me.enc_search_range_y); - RVCE_CS(enc->enc_pic.me.enc_search1_range_x); - RVCE_CS(enc->enc_pic.me.enc_search1_range_y); - RVCE_CS(enc->enc_pic.me.disable_16x16_frame1); - RVCE_CS(enc->enc_pic.me.disable_satd); - RVCE_CS(enc->enc_pic.me.enable_amd); - RVCE_CS(enc->enc_pic.me.enc_disable_sub_mode); - RVCE_CS(enc->enc_pic.me.enc_ime_skip_x); - RVCE_CS(enc->enc_pic.me.enc_ime_skip_y); - RVCE_CS(enc->enc_pic.me.enc_en_ime_overw_dis_subm); - RVCE_CS(enc->enc_pic.me.enc_ime_overw_dis_subm_no); - RVCE_CS(enc->enc_pic.me.enc_ime2_search_range_x); - RVCE_CS(enc->enc_pic.me.enc_ime2_search_range_y); - RVCE_CS(enc->enc_pic.me.parallel_mode_speedup_enable); - RVCE_CS(enc->enc_pic.me.fme0_enc_disable_sub_mode); - RVCE_CS(enc->enc_pic.me.fme1_enc_disable_sub_mode); - RVCE_CS(enc->enc_pic.me.ime_sw_speedup_enable); - RVCE_END(); -} - -static void pic_control(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x04000002); // pic control - RVCE_CS(enc->enc_pic.pc.enc_use_constrained_intra_pred); - RVCE_CS(enc->enc_pic.pc.enc_cabac_enable); - RVCE_CS(enc->enc_pic.pc.enc_cabac_idc); - RVCE_CS(enc->enc_pic.pc.enc_loop_filter_disable); - RVCE_CS(enc->enc_pic.pc.enc_lf_beta_offset); - RVCE_CS(enc->enc_pic.pc.enc_lf_alpha_c0_offset); - RVCE_CS(enc->enc_pic.pc.enc_crop_left_offset); - RVCE_CS(enc->enc_pic.pc.enc_crop_right_offset); - RVCE_CS(enc->enc_pic.pc.enc_crop_top_offset); - RVCE_CS(enc->enc_pic.pc.enc_crop_bottom_offset); - RVCE_CS(enc->enc_pic.pc.enc_num_mbs_per_slice); - RVCE_CS(enc->enc_pic.pc.enc_intra_refresh_num_mbs_per_slot); - RVCE_CS(enc->enc_pic.pc.enc_force_intra_refresh); - RVCE_CS(enc->enc_pic.pc.enc_force_imb_period); - RVCE_CS(enc->enc_pic.pc.enc_pic_order_cnt_type); - RVCE_CS(enc->enc_pic.pc.log2_max_pic_order_cnt_lsb_minus4); - RVCE_CS(enc->enc_pic.pc.enc_sps_id); - RVCE_CS(enc->enc_pic.pc.enc_pps_id); - RVCE_CS(enc->enc_pic.pc.enc_constraint_set_flags); - RVCE_CS(enc->enc_pic.pc.enc_b_pic_pattern); - RVCE_CS(enc->enc_pic.pc.weight_pred_mode_b_picture); - RVCE_CS(enc->enc_pic.pc.enc_number_of_reference_frames); - RVCE_CS(enc->enc_pic.pc.enc_max_num_ref_frames); - RVCE_CS(enc->enc_pic.pc.enc_num_default_active_ref_l0); - RVCE_CS(enc->enc_pic.pc.enc_num_default_active_ref_l1); - RVCE_CS(enc->enc_pic.pc.enc_slice_mode); - RVCE_CS(enc->enc_pic.pc.enc_max_slice_size); - RVCE_END(); -} - -static void rdo(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x04000008); // rdo - RVCE_CS(enc->enc_pic.rdo.enc_disable_tbe_pred_i_frame); - RVCE_CS(enc->enc_pic.rdo.enc_disable_tbe_pred_p_frame); - RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_y); - RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_uv); - RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_y); - RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_uv); - RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_y_1); - RVCE_CS(enc->enc_pic.rdo.use_fme_interpol_uv_1); - RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_y_1); - RVCE_CS(enc->enc_pic.rdo.use_fme_intrapol_uv_1); - RVCE_CS(enc->enc_pic.rdo.enc_16x16_cost_adj); - RVCE_CS(enc->enc_pic.rdo.enc_skip_cost_adj); - RVCE_CS(enc->enc_pic.rdo.enc_force_16x16_skip); - RVCE_CS(enc->enc_pic.rdo.enc_disable_threshold_calc_a); - RVCE_CS(enc->enc_pic.rdo.enc_luma_coeff_cost); - RVCE_CS(enc->enc_pic.rdo.enc_luma_mb_coeff_cost); - RVCE_CS(enc->enc_pic.rdo.enc_chroma_coeff_cost); - RVCE_END(); -} - -static void session(struct rvce_encoder *enc) -{ - RVCE_BEGIN(0x00000001); // session cmd - RVCE_CS(enc->stream_handle); - RVCE_END(); -} - -static void task_info(struct rvce_encoder *enc, uint32_t op, uint32_t fb_idx) -{ - RVCE_BEGIN(0x00000002); // task info - enc->enc_pic.ti.task_operation = op; - enc->enc_pic.ti.reference_picture_dependency = 0; - enc->enc_pic.ti.feedback_index = fb_idx; - enc->enc_pic.ti.video_bitstream_ring_index = 0; - RVCE_CS(enc->enc_pic.ti.offset_of_next_task_info); - RVCE_CS(enc->enc_pic.ti.task_operation); - RVCE_CS(enc->enc_pic.ti.reference_picture_dependency); - RVCE_CS(enc->enc_pic.ti.collocate_flag_dependency); - RVCE_CS(enc->enc_pic.ti.feedback_index); - RVCE_CS(enc->enc_pic.ti.video_bitstream_ring_index); - RVCE_END(); -} - -unsigned int si_vce_write_sps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out) -{ - struct pipe_h264_enc_seq_param *sps = &enc->pic.seq; - struct radeon_bitstream bs; - - radeon_bs_reset(&bs, out, NULL); - radeon_bs_set_emulation_prevention(&bs, false); - radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); - radeon_bs_code_fixed_bits(&bs, nal_byte, 8); - radeon_bs_set_emulation_prevention(&bs, true); - radeon_bs_code_fixed_bits(&bs, sps->profile_idc, 8); - radeon_bs_code_fixed_bits(&bs, sps->enc_constraint_set_flags, 6); - radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* reserved_zero_2bits */ - radeon_bs_code_fixed_bits(&bs, sps->level_idc, 8); - radeon_bs_code_ue(&bs, 0x0); /* seq_parameter_set_id */ - - if (sps->profile_idc == 100 || sps->profile_idc == 110 || - sps->profile_idc == 122 || sps->profile_idc == 244 || - sps->profile_idc == 44 || sps->profile_idc == 83 || - sps->profile_idc == 86 || sps->profile_idc == 118 || - sps->profile_idc == 128 || sps->profile_idc == 138) { - radeon_bs_code_ue(&bs, 0x1); /* chroma_format_idc */ - radeon_bs_code_ue(&bs, 0x0); /* bit_depth_luma_minus8 */ - radeon_bs_code_ue(&bs, 0x0); /* bit_depth_chroma_minus8 */ - radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* qpprime_y_zero_transform_bypass_flag + seq_scaling_matrix_present_flag */ - } - - radeon_bs_code_ue(&bs, 3); /* log2_max_frame_num_minus4 */ - radeon_bs_code_ue(&bs, sps->pic_order_cnt_type); - - if (sps->pic_order_cnt_type == 0) - radeon_bs_code_ue(&bs, sps->log2_max_pic_order_cnt_lsb_minus4); - - radeon_bs_code_ue(&bs, sps->max_num_ref_frames); - radeon_bs_code_fixed_bits(&bs, sps->gaps_in_frame_num_value_allowed_flag, 1); - radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.width, 16) - 1); - radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.height, 16) - 1); - radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* frame_mbs_only_flag */ - radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* direct_8x8_inference_flag */ - - radeon_bs_code_fixed_bits(&bs, sps->enc_frame_cropping_flag, 1); - if (sps->enc_frame_cropping_flag) { - radeon_bs_code_ue(&bs, sps->enc_frame_crop_left_offset); - radeon_bs_code_ue(&bs, sps->enc_frame_crop_right_offset); - radeon_bs_code_ue(&bs, sps->enc_frame_crop_top_offset); - radeon_bs_code_ue(&bs, sps->enc_frame_crop_bottom_offset); - } - - radeon_bs_code_fixed_bits(&bs, sps->vui_parameters_present_flag, 1); - if (sps->vui_parameters_present_flag) { - radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.aspect_ratio_info_present_flag), 1); - if (sps->vui_flags.aspect_ratio_info_present_flag) { - radeon_bs_code_fixed_bits(&bs, (sps->aspect_ratio_idc), 8); - if (sps->aspect_ratio_idc == PIPE_H2645_EXTENDED_SAR) { - radeon_bs_code_fixed_bits(&bs, (sps->sar_width), 16); - radeon_bs_code_fixed_bits(&bs, (sps->sar_height), 16); - } - } - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.overscan_info_present_flag, 1); - if (sps->vui_flags.overscan_info_present_flag) - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.overscan_appropriate_flag, 1); - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.video_signal_type_present_flag, 1); - if (sps->vui_flags.video_signal_type_present_flag) { - radeon_bs_code_fixed_bits(&bs, sps->video_format, 3); - radeon_bs_code_fixed_bits(&bs, sps->video_full_range_flag, 1); - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.colour_description_present_flag, 1); - if (sps->vui_flags.colour_description_present_flag) { - radeon_bs_code_fixed_bits(&bs, sps->colour_primaries, 8); - radeon_bs_code_fixed_bits(&bs, sps->transfer_characteristics, 8); - radeon_bs_code_fixed_bits(&bs, sps->matrix_coefficients, 8); - } - } - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.chroma_loc_info_present_flag, 1); - if (sps->vui_flags.chroma_loc_info_present_flag) { - radeon_bs_code_ue(&bs, sps->chroma_sample_loc_type_top_field); - radeon_bs_code_ue(&bs, sps->chroma_sample_loc_type_bottom_field); - } - radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.timing_info_present_flag), 1); - if (sps->vui_flags.timing_info_present_flag) { - radeon_bs_code_fixed_bits(&bs, (sps->num_units_in_tick), 32); - radeon_bs_code_fixed_bits(&bs, (sps->time_scale), 32); - radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.fixed_frame_rate_flag), 1); - } - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.nal_hrd_parameters_present_flag, 1); - if (sps->vui_flags.nal_hrd_parameters_present_flag) - radeon_bs_h264_hrd_parameters(&bs, &sps->nal_hrd_parameters); - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.vcl_hrd_parameters_present_flag, 1); - if (sps->vui_flags.vcl_hrd_parameters_present_flag) - radeon_bs_h264_hrd_parameters(&bs, &sps->vcl_hrd_parameters); - if (sps->vui_flags.nal_hrd_parameters_present_flag || sps->vui_flags.vcl_hrd_parameters_present_flag) - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.low_delay_hrd_flag, 1); - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.pic_struct_present_flag, 1); - radeon_bs_code_fixed_bits(&bs, sps->vui_flags.bitstream_restriction_flag, 1); - if (sps->vui_flags.bitstream_restriction_flag) { - radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* motion_vectors_over_pic_boundaries_flag */ - radeon_bs_code_ue(&bs, 0x2); /* max_bytes_per_pic_denom */ - radeon_bs_code_ue(&bs, 0x1); /* max_bits_per_mb_denom */ - radeon_bs_code_ue(&bs, 0x10); /* log2_max_mv_length_horizontal */ - radeon_bs_code_ue(&bs, 0x10); /* log2_max_mv_length_vertical */ - radeon_bs_code_ue(&bs, sps->max_num_reorder_frames); - radeon_bs_code_ue(&bs, sps->max_dec_frame_buffering); - } - } - - radeon_bs_code_fixed_bits(&bs, 0x1, 1); - radeon_bs_byte_align(&bs); - - return bs.bits_output / 8; -} - -unsigned int si_vce_write_pps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out) -{ - struct radeon_bitstream bs; - - radeon_bs_reset(&bs, out, NULL); - radeon_bs_set_emulation_prevention(&bs, false); - radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); - radeon_bs_code_fixed_bits(&bs, nal_byte, 8); - radeon_bs_set_emulation_prevention(&bs, true); - radeon_bs_code_ue(&bs, 0x0); /* pic_parameter_set_id */ - radeon_bs_code_ue(&bs, 0x0); /* seq_parameter_set_id */ - radeon_bs_code_fixed_bits(&bs, enc->enc_pic.pc.enc_cabac_enable, 1); - radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* bottom_field_pic_order_in_frame_present_flag */ - radeon_bs_code_ue(&bs, 0x0); /* num_slice_groups_minus_1 */ - radeon_bs_code_ue(&bs, enc->enc_pic.pc.enc_num_default_active_ref_l0 - 1); - radeon_bs_code_ue(&bs, enc->enc_pic.pc.enc_num_default_active_ref_l1 - 1); - radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* weighted_pred_flag */ - radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* weighted_bipred_idc */ - radeon_bs_code_se(&bs, 0x0); /* pic_init_qp_minus26 */ - radeon_bs_code_se(&bs, 0x0); /* pic_init_qs_minus26 */ - radeon_bs_code_se(&bs, 0x0); /* chroma_qp_index_offset */ - bool deblocking_filter_present_flag = - enc->enc_pic.pc.enc_loop_filter_disable || - enc->enc_pic.pc.enc_lf_beta_offset || - enc->enc_pic.pc.enc_lf_alpha_c0_offset; - radeon_bs_code_fixed_bits(&bs, deblocking_filter_present_flag, 1); - radeon_bs_code_fixed_bits(&bs, enc->enc_pic.pc.enc_use_constrained_intra_pred, 1); - radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* redundant_pic_cnt_present_flag */ - - radeon_bs_code_fixed_bits(&bs, 0x1, 1); - radeon_bs_byte_align(&bs); - - return bs.bits_output / 8; -} - -void si_vce_52_init(struct rvce_encoder *enc) -{ - enc->session = session; - enc->task_info = task_info; - enc->create = create; - enc->feedback = feedback; - enc->rate_control = rate_control; - enc->config_extension = config_extension; - enc->pic_control = pic_control; - enc->motion_estimation = motion_estimation; - enc->rdo = rdo; - enc->config = config; - enc->encode = encode; - enc->destroy = destroy; - enc->si_get_pic_param = get_param; -}