diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c index 437fe4d6e23..36c160aa474 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c @@ -259,55 +259,82 @@ static void radeon_enc_cs_flush(void *ctx, unsigned flags, struct pipe_fence_han // just ignored } -static unsigned get_cpb_num(struct radeon_encoder *enc) +/* configure reconstructed picture offset */ +static void radeon_enc_rec_offset(rvcn_enc_reconstructed_picture_t *recon, + uint32_t *offset, + uint32_t luma_size, + uint32_t chroma_size) { - unsigned w = align(enc->base.width, 16) / 16; - unsigned h = align(enc->base.height, 16) / 16; - unsigned dpb; + if (offset) { + recon->luma_offset = *offset; + *offset += luma_size; + recon->chroma_offset = *offset; + *offset += chroma_size; + } else { + recon->luma_offset = 0; + recon->chroma_offset = 0; + } +} - switch (enc->base.level) { - case 10: - dpb = 396; - break; - case 11: - dpb = 900; - break; - case 12: - case 13: - case 20: - dpb = 2376; - break; - case 21: - dpb = 4752; - break; - case 22: - case 30: - dpb = 8100; - break; - case 31: - dpb = 18000; - break; - case 32: - dpb = 20480; - break; - case 40: - case 41: - dpb = 32768; - break; - case 42: - dpb = 34816; - break; - case 50: - dpb = 110400; - break; - default: - case 51: - case 52: - dpb = 184320; - break; +static int setup_dpb(struct radeon_encoder *enc) +{ + uint32_t rec_alignment = (u_reduce_video_profile(enc->base.profile) + == PIPE_VIDEO_FORMAT_MPEG4_AVC) ? 16 : 64; + uint32_t aligned_width = align(enc->base.width, rec_alignment); + uint32_t aligned_height = align(enc->base.height, rec_alignment); + uint32_t aligned_chroma_height = align(aligned_height / 2, rec_alignment); + uint32_t pitch = align(aligned_width, enc->alignment); + uint32_t num_reconstructed_pictures = enc->base.max_references + 1; + uint32_t luma_size, chroma_size, offset; + struct radeon_enc_pic *enc_pic = &enc->enc_pic; + int i; + + luma_size = align(pitch * aligned_height, enc->alignment); + chroma_size = align(pitch * aligned_chroma_height, enc->alignment); + if (enc_pic->bit_depth_luma_minus8 || enc_pic->bit_depth_chroma_minus8) { + luma_size *= 2; + chroma_size *= 2; } - return MIN2(dpb / (w * h), 16); + assert(num_reconstructed_pictures <= RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES); + + enc_pic->ctx_buf.rec_luma_pitch = pitch; + enc_pic->ctx_buf.rec_chroma_pitch = pitch; + enc_pic->ctx_buf.pre_encode_picture_luma_pitch = pitch; + enc_pic->ctx_buf.pre_encode_picture_chroma_pitch = pitch; + + offset = 0; + for (i = 0; i < num_reconstructed_pictures; i++) { + radeon_enc_rec_offset(&enc_pic->ctx_buf.reconstructed_pictures[i], + &offset, luma_size, chroma_size); + + if (enc_pic->quality_modes.pre_encode_mode) + radeon_enc_rec_offset(&enc_pic->ctx_buf.pre_encode_reconstructed_pictures[i], + &offset, luma_size, chroma_size); + } + + for (; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + radeon_enc_rec_offset(&enc_pic->ctx_buf.reconstructed_pictures[i], + NULL, 0, 0); + if (enc_pic->quality_modes.pre_encode_mode) + radeon_enc_rec_offset(&enc_pic->ctx_buf.pre_encode_reconstructed_pictures[i], + NULL, 0, 0); + } + + if (enc_pic->quality_modes.pre_encode_mode) { + enc_pic->ctx_buf.pre_encode_input_picture.rgb.red_offset = offset; + offset += luma_size; + enc_pic->ctx_buf.pre_encode_input_picture.rgb.green_offset = offset; + offset += luma_size; + enc_pic->ctx_buf.pre_encode_input_picture.rgb.blue_offset = offset; + offset += luma_size; + } + + enc_pic->ctx_buf.num_reconstructed_pictures = num_reconstructed_pictures; + enc_pic->ctx_buf.colloc_buffer_offset = 0; + enc->dpb_size = offset; + + return offset; } static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, @@ -330,6 +357,15 @@ static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, } radeon_vcn_enc_get_param(enc, picture); + if (!enc->dpb) { + enc->dpb = CALLOC_STRUCT(rvid_buffer); + setup_dpb(enc); + if (!enc->dpb || + !si_vid_create_buffer(enc->screen, enc->dpb, enc->dpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't create DPB buffer.\n"); + goto error; + } + } enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma); enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma); @@ -351,6 +387,11 @@ static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, enc->begin(enc); flush(enc); } + + return; + +error: + RADEON_ENC_DESTROY_VIDEO_BUFFER(enc->dpb); } static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, @@ -390,15 +431,11 @@ static void radeon_enc_destroy(struct pipe_video_codec *encoder) enc->fb = &fb; enc->destroy(enc); flush(enc); - if (enc->si) { - si_vid_destroy_buffer(enc->si); - FREE(enc->si); - enc->si = NULL; - } + RADEON_ENC_DESTROY_VIDEO_BUFFER(enc->si); si_vid_destroy_buffer(&fb); } - si_vid_destroy_buffer(&enc->cpb); + RADEON_ENC_DESTROY_VIDEO_BUFFER(enc->dpb); enc->ws->cs_destroy(&enc->cs); FREE(enc); } @@ -423,47 +460,6 @@ static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, void *feed FREE(fb); } -static int setup_dpb(struct radeon_encoder *enc, enum pipe_format buffer_format, - enum amd_gfx_level gfx_level) -{ - uint32_t aligned_width = align(enc->base.width, 16); - uint32_t aligned_height = align(enc->base.height, 16); - uint32_t rec_luma_pitch = align(aligned_width, enc->alignment); - - int luma_size = rec_luma_pitch * align(aligned_height, enc->alignment); - if (buffer_format == PIPE_FORMAT_P010) - luma_size *= 2; - int chroma_size = align(luma_size / 2, enc->alignment); - int offset = 0; - - uint32_t num_reconstructed_pictures = enc->base.max_references + 1; - assert(num_reconstructed_pictures <= RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES); - - int i; - for (i = 0; i < num_reconstructed_pictures; i++) { - if (gfx_level >= GFX11) { - enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].luma_offset = offset; - offset += luma_size; - enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].chroma_offset = offset; - offset += chroma_size; - } else { - enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset = offset; - offset += luma_size; - enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset = offset; - offset += chroma_size; - } - } - for (; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { - enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset = 0; - enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset = 0; - } - - enc->enc_pic.ctx_buf.num_reconstructed_pictures = num_reconstructed_pictures; - enc->dpb_size = offset; - - return offset; -} - struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, const struct pipe_video_codec *templ, struct radeon_winsys *ws, @@ -472,9 +468,6 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, struct si_screen *sscreen = (struct si_screen *)context->screen; struct si_context *sctx = (struct si_context *)context; struct radeon_encoder *enc; - struct pipe_video_buffer *tmp_buf, templat = {}; - struct radeon_surf *tmp_surf; - unsigned cpb_size; enc = CALLOC_STRUCT(radeon_encoder); @@ -500,42 +493,6 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, goto error; } - templat.buffer_format = PIPE_FORMAT_NV12; - if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) - templat.buffer_format = PIPE_FORMAT_P010; - templat.width = enc->base.width; - templat.height = enc->base.height; - templat.interlaced = false; - - if (!(tmp_buf = context->create_video_buffer(context, &templat))) { - RVID_ERR("Can't create video buffer.\n"); - goto error; - } - - enc->cpb_num = get_cpb_num(enc); - - if (!enc->cpb_num) - goto error; - - get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf); - - cpb_size = (sscreen->info.gfx_level < GFX9) - ? align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) * - align(tmp_surf->u.legacy.level[0].nblk_y, 32) - : align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) * - align(tmp_surf->u.gfx9.surf_height, 32); - - cpb_size = cpb_size * 3 / 2; - cpb_size = cpb_size * enc->cpb_num; - tmp_buf->destroy(tmp_buf); - - cpb_size += setup_dpb(enc, templat.buffer_format, sscreen->info.gfx_level); - - if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) { - RVID_ERR("Can't create CPB buffer.\n"); - goto error; - } - if (sscreen->info.gfx_level >= GFX11) radeon_enc_4_0_init(enc); else if (sscreen->info.family >= CHIP_NAVI21) @@ -549,9 +506,6 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, error: enc->ws->cs_destroy(&enc->cs); - - si_vid_destroy_buffer(&enc->cpb); - FREE(enc); return NULL; } diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h index eefcb1a3678..f17e6d030af 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h @@ -151,6 +151,15 @@ enc->total_task_size += *begin; \ } +#define RADEON_ENC_DESTROY_VIDEO_BUFFER(buf) \ + do { \ + if (buf) { \ + si_vid_destroy_buffer(buf); \ + FREE(buf); \ + (buf) = NULL; \ + } \ + } while(0) + typedef struct rvcn_enc_session_info_s { uint32_t interface_version; uint32_t sw_context_address_hi; @@ -336,11 +345,6 @@ typedef struct rvcn_enc_intra_refresh_s { typedef struct rvcn_enc_reconstructed_picture_s { uint32_t luma_offset; uint32_t chroma_offset; -} rvcn_enc_reconstructed_picture_t; - -typedef struct rvcn_enc_reconstructed_picture_v4_0_s { - uint32_t luma_offset; - uint32_t chroma_offset; union { struct { @@ -348,7 +352,7 @@ typedef struct rvcn_enc_reconstructed_picture_v4_0_s { uint32_t unused_offset2; } unused; }; -} rvcn_enc_reconstructed_picture_v4_0_t; +} rvcn_enc_reconstructed_picture_t; typedef struct rvcn_enc_picture_info_s { @@ -378,12 +382,11 @@ typedef struct rvcn_enc_encode_context_buffer_s { uint32_t rec_chroma_pitch; uint32_t num_reconstructed_pictures; rvcn_enc_reconstructed_picture_t reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES]; - rvcn_enc_reconstructed_picture_v4_0_t reconstructed_pictures_v4_0[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES]; uint32_t pre_encode_picture_luma_pitch; uint32_t pre_encode_picture_chroma_pitch; rvcn_enc_reconstructed_picture_t - pre_encode_reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES]; - rvcn_enc_reconstructed_picture_t pre_encode_input_picture; + pre_encode_reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES]; + rvcn_enc_pre_encode_input_picture_t pre_encode_input_picture; uint32_t two_pass_search_center_map_offset; uint32_t colloc_buffer_offset; } rvcn_enc_encode_context_buffer_t; @@ -574,11 +577,9 @@ struct radeon_encoder { struct pb_buffer *bs_handle; unsigned bs_size; - unsigned cpb_num; - struct rvid_buffer *si; struct rvid_buffer *fb; - struct rvid_buffer cpb; + struct rvid_buffer *dpb; struct radeon_enc_pic enc_pic; rvcn_enc_cmd_t cmd; @@ -596,7 +597,7 @@ struct radeon_encoder { bool emulation_prevention; bool need_feedback; unsigned dpb_size; - rvcn_enc_picture_info_t dpb[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES]; + rvcn_enc_picture_info_t dpb_info[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES]; }; void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf, diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c index b570a6ae08b..b48695cbc30 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c @@ -102,9 +102,9 @@ static void radeon_enc_session_init(struct radeon_encoder *enc) enc->enc_pic.session_init.aligned_picture_width - enc->base.width; enc->enc_pic.session_init.padding_height = enc->enc_pic.session_init.aligned_picture_height - enc->base.height; - enc->enc_pic.session_init.pre_encode_mode = RENCODE_PREENCODE_MODE_NONE; - enc->enc_pic.session_init.pre_encode_chroma_enabled = false; enc->enc_pic.session_init.display_remote = 0; + enc->enc_pic.session_init.pre_encode_mode = enc->enc_pic.quality_modes.pre_encode_mode; + enc->enc_pic.session_init.pre_encode_chroma_enabled = !!(enc->enc_pic.quality_modes.pre_encode_mode); RADEON_ENC_BEGIN(enc->cmd.session_init); RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); @@ -1036,27 +1036,8 @@ static void radeon_enc_ctx(struct radeon_encoder *enc) enc->enc_pic.ctx_buf.swizzle_mode = 0; enc->enc_pic.ctx_buf.two_pass_search_center_map_offset = 0; - uint32_t aligned_width = enc->enc_pic.session_init.aligned_picture_width; - uint32_t aligned_height = enc->enc_pic.session_init.aligned_picture_height; - - enc->enc_pic.ctx_buf.rec_luma_pitch = align(aligned_width, enc->alignment); - enc->enc_pic.ctx_buf.rec_chroma_pitch = align(aligned_width, enc->alignment); - - int luma_size = enc->enc_pic.ctx_buf.rec_luma_pitch * align(aligned_height, enc->alignment); - if (enc->enc_pic.bit_depth_luma_minus8 == 2) - luma_size *= 2; - int chroma_size = align(luma_size / 2, enc->alignment); - int offset = 0; - - for (int i = 0; i < enc->enc_pic.ctx_buf.num_reconstructed_pictures; i++) { - offset += luma_size; - offset += chroma_size; - } - - assert(offset == enc->dpb_size); - RADEON_ENC_BEGIN(enc->cmd.ctx); - RADEON_ENC_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0); + RADEON_ENC_READWRITE(enc->dpb->res->buf, enc->dpb->res->domains, 0); RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode); RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch); RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch); @@ -1067,14 +1048,16 @@ static void radeon_enc_ctx(struct radeon_encoder *enc) RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset); } - // 2: 1 pre encode pitch * 2 (luma + chroma) - // 68: 34 pre encode reconstructed pics * 2 (luma + chroma offsets) - // 2: 1 pre encode input pic * 2 (luma + chroma) - //---- - // 72 + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_luma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_chroma_pitch); - for (int i = 0; i < 72; i++) - RADEON_ENC_CS(0x00000000); + for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].chroma_offset); + } + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.yuv.luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.yuv.chroma_offset); RADEON_ENC_CS(enc->enc_pic.ctx_buf.two_pass_search_center_map_offset); RADEON_ENC_END(); @@ -1317,7 +1300,7 @@ static void destroy(struct radeon_encoder *enc) static int find_short_ref_idx(struct radeon_encoder *enc, int frame_num) { for (int i = 0; i < enc->base.max_references + 1; i++) - if (enc->dpb[i].frame_num == frame_num && enc->dpb[i].in_use) + if (enc->dpb_info[i].frame_num == frame_num && enc->dpb_info[i].in_use) return i; return -1; @@ -1326,8 +1309,8 @@ static int find_short_ref_idx(struct radeon_encoder *enc, int frame_num) static int get_picture_storage(struct radeon_encoder *enc) { for (int i = 0; i < enc->base.max_references + 1; i++) { - if (!enc->dpb[i].in_use) { - memset(&(enc->dpb[i]), 0, sizeof(rvcn_enc_picture_info_t)); + if (!enc->dpb_info[i].in_use) { + memset(&(enc->dpb_info[i]), 0, sizeof(rvcn_enc_picture_info_t)); return i; } } @@ -1336,13 +1319,13 @@ static int get_picture_storage(struct radeon_encoder *enc) unsigned int oldest_frame_num = 0xFFFFFFFF; int oldest_idx = -1; for (int i = 0; i < enc->base.max_references + 1; i++) - if (enc->dpb[i].frame_num < oldest_frame_num) { - oldest_frame_num = enc->dpb[i].frame_num; + if (enc->dpb_info[i].frame_num < oldest_frame_num) { + oldest_frame_num = enc->dpb_info[i].frame_num; oldest_idx = i; } if (oldest_idx >= 0) - enc->dpb[oldest_idx].in_use = FALSE; + enc->dpb_info[oldest_idx].in_use = FALSE; return oldest_idx; } @@ -1354,7 +1337,7 @@ static void manage_dpb_before_encode(struct radeon_encoder *enc) if (enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) { /* clear reference frames */ for (int i = 0; i < enc->base.max_references + 1; i++) - memset(&(enc->dpb[i]), 0, sizeof(rvcn_enc_picture_info_t)); + memset(&(enc->dpb_info[i]), 0, sizeof(rvcn_enc_picture_info_t)); } current_pic_idx = get_picture_storage(enc); @@ -1363,9 +1346,9 @@ static void manage_dpb_before_encode(struct radeon_encoder *enc) int ref0_idx = find_short_ref_idx(enc, enc->enc_pic.ref_idx_l0); if (!enc->enc_pic.not_referenced) - enc->dpb[current_pic_idx].in_use = TRUE; + enc->dpb_info[current_pic_idx].in_use = TRUE; - enc->dpb[current_pic_idx].frame_num = enc->enc_pic.frame_num; + enc->dpb_info[current_pic_idx].frame_num = enc->enc_pic.frame_num; if (enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) enc->enc_pic.enc_params.reference_picture_index = 0xFFFFFFFF; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c index 9c711c331e9..cfa38cd26a1 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c @@ -428,6 +428,40 @@ static void radeon_enc_output_format(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_ctx(struct radeon_encoder *enc) +{ + enc->enc_pic.ctx_buf.swizzle_mode = 0; + enc->enc_pic.ctx_buf.two_pass_search_center_map_offset = 0; + + RADEON_ENC_BEGIN(enc->cmd.ctx); + RADEON_ENC_READWRITE(enc->dpb->res->buf, enc->dpb->res->domains, 0); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures); + + for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset); + } + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_luma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_chroma_pitch); + + for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].chroma_offset); + } + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.yuv.luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.yuv.chroma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.two_pass_search_center_map_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.red_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.green_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.blue_offset); + + RADEON_ENC_END(); +} static void encode(struct radeon_encoder *enc) { enc->before_encode(enc); @@ -454,13 +488,14 @@ void radeon_enc_2_0_init(struct radeon_encoder *enc) enc->encode = encode; enc->input_format = radeon_enc_input_format; enc->output_format = radeon_enc_output_format; + enc->ctx = radeon_enc_ctx; + enc->op_preset = radeon_enc_op_balance; 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; enc->slice_header = radeon_enc_slice_header_hevc; - enc->op_preset = radeon_enc_op_balance; } enc->cmd.session_info = RENCODE_IB_PARAM_SESSION_INFO; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c index 9e28b62c081..5454c82319d 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_3_0.c @@ -167,14 +167,85 @@ static void radeon_enc_nalu_pps_hevc(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_ctx(struct radeon_encoder *enc) +{ + enc->enc_pic.ctx_buf.swizzle_mode = 0; + enc->enc_pic.ctx_buf.two_pass_search_center_map_offset = 0; + + RADEON_ENC_BEGIN(enc->cmd.ctx); + RADEON_ENC_READWRITE(enc->dpb->res->buf, enc->dpb->res->domains, 0); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures); + + for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset); + } + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.colloc_buffer_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_luma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_chroma_pitch); + + for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].chroma_offset); + } + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.red_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.green_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.blue_offset); + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.two_pass_search_center_map_offset); + RADEON_ENC_CS(0x00000000); + RADEON_ENC_CS(0x00000000); + RADEON_ENC_END(); +} + +static void radeon_enc_session_init(struct radeon_encoder *enc) +{ + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_H264; + enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 16); + } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { + enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_HEVC; + enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 64); + } + enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16); + enc->enc_pic.session_init.padding_width = + enc->enc_pic.session_init.aligned_picture_width - enc->base.width; + enc->enc_pic.session_init.padding_height = + enc->enc_pic.session_init.aligned_picture_height - enc->base.height; + enc->enc_pic.session_init.slice_output_enabled = 0; + enc->enc_pic.session_init.display_remote = 0; + enc->enc_pic.session_init.pre_encode_mode = enc->enc_pic.quality_modes.pre_encode_mode; + enc->enc_pic.session_init.pre_encode_chroma_enabled = !!(enc->enc_pic.quality_modes.pre_encode_mode); + + RADEON_ENC_BEGIN(enc->cmd.session_init); + RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); + RADEON_ENC_CS(enc->enc_pic.session_init.slice_output_enabled); + RADEON_ENC_CS(enc->enc_pic.session_init.display_remote); + RADEON_ENC_END(); +} + void radeon_enc_3_0_init(struct radeon_encoder *enc) { radeon_enc_2_0_init(enc); + enc->session_init = radeon_enc_session_init; + enc->quality_params = radeon_enc_quality_params; + enc->ctx = radeon_enc_ctx; + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { enc->spec_misc = radeon_enc_spec_misc; enc->encode_params_codec_spec = radeon_enc_encode_params_h264; - enc->quality_params = radeon_enc_quality_params; } if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c index a8e1abc43d1..0ec5869f22a 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_4_0.c @@ -58,85 +58,39 @@ static void radeon_enc_sq_destroy(struct radeon_encoder *enc) rvcn_sq_tail(&enc->cs, &enc->sq); } -static void radeon_enc_session_init(struct radeon_encoder *enc) -{ - if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { - enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_H264; - enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 16); - } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { - enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_HEVC; - enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 64); - } - enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16); - enc->enc_pic.session_init.padding_width = - enc->enc_pic.session_init.aligned_picture_width - enc->base.width; - enc->enc_pic.session_init.padding_height = - enc->enc_pic.session_init.aligned_picture_height - enc->base.height; - enc->enc_pic.session_init.pre_encode_mode = RENCODE_PREENCODE_MODE_NONE; - enc->enc_pic.session_init.pre_encode_chroma_enabled = false; - enc->enc_pic.session_init.slice_output_enabled = false; - enc->enc_pic.session_init.display_remote = 0; - - RADEON_ENC_BEGIN(enc->cmd.session_init); - RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); - RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); - RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); - RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); - RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); - RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); - RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); - RADEON_ENC_CS(enc->enc_pic.session_init.slice_output_enabled); - RADEON_ENC_CS(enc->enc_pic.session_init.display_remote); - RADEON_ENC_END(); -} - static void radeon_enc_ctx(struct radeon_encoder *enc) { enc->enc_pic.ctx_buf.swizzle_mode = 0; enc->enc_pic.ctx_buf.two_pass_search_center_map_offset = 0; enc->enc_pic.ctx_buf.colloc_buffer_offset = enc->dpb_size; - uint32_t aligned_width = enc->enc_pic.session_init.aligned_picture_width; - uint32_t aligned_height = enc->enc_pic.session_init.aligned_picture_height; - - enc->enc_pic.ctx_buf.rec_luma_pitch = align(aligned_width, enc->alignment); - enc->enc_pic.ctx_buf.rec_chroma_pitch = align(aligned_width, enc->alignment); - - int luma_size = enc->enc_pic.ctx_buf.rec_luma_pitch * align(aligned_height, enc->alignment); - if (enc->enc_pic.bit_depth_luma_minus8 == 2) - luma_size *= 2; - int chroma_size = align(luma_size / 2, enc->alignment); - int offset = 0; - - for (int i = 0; i < enc->enc_pic.ctx_buf.num_reconstructed_pictures; i++) { - offset += luma_size; - offset += chroma_size; - } - - assert(offset == enc->dpb_size); - RADEON_ENC_BEGIN(enc->cmd.ctx); - RADEON_ENC_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0); + RADEON_ENC_READWRITE(enc->dpb->res->buf, enc->dpb->res->domains, 0); RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode); RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch); RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch); RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures); for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { - RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].luma_offset); - RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].chroma_offset); - RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].unused.unused_offset1); - RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].unused.unused_offset2); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset); + RADEON_ENC_CS(0x00000000); /* unused offset 1 */ + RADEON_ENC_CS(0x00000000); /* unused offset 2 */ } - // 2: 1 pre encode pitch * 2 (luma + chroma) - // 136: 34 pre encode reconstructed pics * 4 (luma + chroma offsets + unused union) - // 3: 1 pre encode input pic * 3 (r,g,b offset union) - //---- - // 141 + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_luma_pitch); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_chroma_pitch); - for (int i = 0; i < 141; i++) - RADEON_ENC_CS(0x00000000); + for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].chroma_offset); + RADEON_ENC_CS(0x00000000); /* unused offset 1 */ + RADEON_ENC_CS(0x00000000); /* unused offset 2 */ + } + + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.red_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.green_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.blue_offset); RADEON_ENC_CS(enc->enc_pic.ctx_buf.two_pass_search_center_map_offset); RADEON_ENC_CS(enc->enc_pic.ctx_buf.colloc_buffer_offset); @@ -147,7 +101,6 @@ void radeon_enc_4_0_init(struct radeon_encoder *enc) { radeon_enc_3_0_init(enc); - enc->session_init = radeon_enc_session_init; enc->ctx = radeon_enc_ctx; enc->mq_begin = enc->begin; enc->mq_encode = enc->encode;