From 98f711859dfe360a46a2ea1cd5e28e1311319719 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Mon, 30 Dec 2024 10:16:14 +0100 Subject: [PATCH] radeonsi/uvd_enc: Rework DPB allocation Reviewed-by: Ruijing Dong Acked-by: Leo Liu Part-of: --- src/gallium/drivers/radeonsi/radeon_uvd_enc.c | 107 ++++++------------ src/gallium/drivers/radeonsi/radeon_uvd_enc.h | 4 +- .../drivers/radeonsi/radeon_uvd_enc_1_1.c | 26 ++--- 3 files changed, 48 insertions(+), 89 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc.c b/src/gallium/drivers/radeonsi/radeon_uvd_enc.c index e04f852ae28..26c0a0a18d6 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc.c @@ -17,20 +17,6 @@ #include -#define UVD_HEVC_LEVEL_1 30 -#define UVD_HEVC_LEVEL_2 60 -#define UVD_HEVC_LEVEL_2_1 63 -#define UVD_HEVC_LEVEL_3 90 -#define UVD_HEVC_LEVEL_3_1 93 -#define UVD_HEVC_LEVEL_4 120 -#define UVD_HEVC_LEVEL_4_1 123 -#define UVD_HEVC_LEVEL_5 150 -#define UVD_HEVC_LEVEL_5_1 153 -#define UVD_HEVC_LEVEL_5_2 156 -#define UVD_HEVC_LEVEL_6 180 -#define UVD_HEVC_LEVEL_6_1 183 -#define UVD_HEVC_LEVEL_6_2 186 - static void radeon_uvd_enc_get_vui_param(struct radeon_uvd_encoder *enc, struct pipe_h265_enc_picture_desc *pic) { @@ -130,53 +116,33 @@ static void radeon_uvd_enc_cs_flush(void *ctx, unsigned flags, struct pipe_fence // just ignored } -static unsigned get_cpb_num(struct radeon_uvd_encoder *enc, unsigned level_idc) +static uint32_t setup_dpb(struct radeon_uvd_encoder *enc, uint32_t num_reconstructed_pictures) { - unsigned w = align(enc->base.width, 16) / 16; - unsigned h = align(enc->base.height, 16) / 16; - unsigned dpb; + uint32_t i; + uint32_t alignment = 256; + uint32_t aligned_width = align(enc->base.width, 64); + uint32_t aligned_height = align(enc->base.height, 16); + uint32_t pitch = align(aligned_width, alignment); + uint32_t luma_size = align(pitch * MAX2(256, aligned_height), alignment); + uint32_t chroma_size = align(luma_size / 2, alignment); + uint32_t offset = 0; - switch (level_idc) { - case UVD_HEVC_LEVEL_1: - dpb = 36864; - break; + assert(num_reconstructed_pictures <= RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES); - case UVD_HEVC_LEVEL_2: - dpb = 122880; - break; + enc->enc_pic.ctx_buf.rec_luma_pitch = pitch; + enc->enc_pic.ctx_buf.rec_chroma_pitch = pitch; + enc->enc_pic.ctx_buf.num_reconstructed_pictures = num_reconstructed_pictures; - case UVD_HEVC_LEVEL_2_1: - dpb = 245760; - break; - - case UVD_HEVC_LEVEL_3: - dpb = 552960; - break; - - case UVD_HEVC_LEVEL_3_1: - dpb = 983040; - break; - - case UVD_HEVC_LEVEL_4: - case UVD_HEVC_LEVEL_4_1: - dpb = 2228224; - break; - - case UVD_HEVC_LEVEL_5: - case UVD_HEVC_LEVEL_5_1: - case UVD_HEVC_LEVEL_5_2: - dpb = 8912896; - break; - - case UVD_HEVC_LEVEL_6: - case UVD_HEVC_LEVEL_6_1: - case UVD_HEVC_LEVEL_6_2: - default: - dpb = 35651584; - break; + for (i = 0; i < num_reconstructed_pictures; i++) { + 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; } - return MIN2(dpb / (w * h), 16); + enc->dpb_slots = num_reconstructed_pictures; + + return offset; } static void radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder, @@ -194,25 +160,17 @@ static void radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder, enc->need_feedback = false; - if (!enc->cpb_num) { - struct si_screen *sscreen = (struct si_screen *)encoder->context->screen; - unsigned cpb_size; + unsigned dpb_slots = MAX2(pic->seq.sps_max_dec_pic_buffering_minus1[0] + 1, pic->dpb_size); - enc->cpb_num = get_cpb_num(enc, pic->seq.general_level_idc); - if (!enc->cpb_num) - return; - - cpb_size = (sscreen->info.gfx_level < GFX9) - ? align(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe, 128) * - align(enc->luma->u.legacy.level[0].nblk_y, 32) - : align(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe, 256) * - align(enc->luma->u.gfx9.surf_height, 32); - - cpb_size = cpb_size * 3 / 2; - cpb_size = cpb_size * enc->cpb_num; - - if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) { - RVID_ERR("Can't create CPB buffer.\n"); + if (enc->dpb_slots < dpb_slots) { + uint32_t dpb_size = setup_dpb(enc, dpb_slots); + if (!enc->dpb.res) { + if (!si_vid_create_buffer(enc->screen, &enc->dpb, dpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't create DPB buffer.\n"); + return; + } + } else if (!si_vid_resize_buffer(enc->base.context, &enc->cs, &enc->dpb, dpb_size, NULL)) { + RVID_ERR("Can't resize DPB buffer.\n"); return; } } @@ -275,7 +233,8 @@ static void radeon_uvd_enc_destroy(struct pipe_video_codec *encoder) si_vid_destroy_buffer(&fb); } - si_vid_destroy_buffer(&enc->cpb); + if (enc->dpb.res) + si_vid_destroy_buffer(&enc->dpb); enc->ws->cs_destroy(&enc->cs); FREE(enc); } diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc.h b/src/gallium/drivers/radeonsi/radeon_uvd_enc.h index 43e902913c1..759a3ec6e9a 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc.h +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc.h @@ -413,11 +413,11 @@ struct radeon_uvd_encoder { struct pb_buffer_lean *bs_handle; unsigned bs_size; - unsigned cpb_num; + unsigned dpb_slots; struct rvid_buffer *si; struct rvid_buffer *fb; - struct rvid_buffer cpb; + struct rvid_buffer dpb; struct radeon_uvd_enc_pic enc_pic; unsigned shifter; diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c b/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c index 26c849747a6..b73f49aa74c 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c @@ -795,24 +795,24 @@ static void radeon_uvd_enc_ctx(struct radeon_uvd_encoder *enc) enc->enc_pic.ctx_buf.num_reconstructed_pictures = 2; RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_ENCODE_CONTEXT_BUFFER); - 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(0x00000000); // reserved 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); - /* reconstructed_picture_1_luma_offset */ - RADEON_ENC_CS(0x00000000); - /* reconstructed_picture_1_chroma_offset */ - RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch * align(enc->base.height, 16)); - /* reconstructed_picture_2_luma_offset */ - RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch * align(enc->base.height, 16) * 3 / 2); - /* reconstructed_picture_2_chroma_offset */ - RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch * align(enc->base.height, 16) * 5 / 2); - - for (int i = 0; i < 136; i++) - RADEON_ENC_CS(0x00000000); - + for (uint32_t i = 0; i < RENC_UVD_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 (uint32_t i = 0; i < RENC_UVD_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.luma_offset); + RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.chroma_offset); RADEON_ENC_END(); }