radeonsi/vce: Stop using base.level and base.max_references

Instead use the values from sequence parameters.
This needs to move the context buffer allocation to first frame
which also allows to remove the temporary surface allocation.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30992>
This commit is contained in:
David Rosca
2024-08-27 11:59:17 +02:00
committed by Marge Bot
parent 96975bc32f
commit e891717936
3 changed files with 40 additions and 53 deletions
+38 -51
View File
@@ -116,13 +116,13 @@ static void sort_cpb(struct rvce_encoder *enc)
/**
* get number of cpbs based on dpb
*/
static unsigned get_cpb_num(struct rvce_encoder *enc)
static unsigned get_cpb_num(struct rvce_encoder *enc, unsigned level_idc)
{
unsigned w = align(enc->base.width, 16) / 16;
unsigned h = align(enc->base.height, 16) / 16;
unsigned dpb;
switch (enc->base.level) {
switch (level_idc) {
case 10:
dpb = 396;
break;
@@ -251,11 +251,47 @@ 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->base.max_references = pic->seq.max_num_ref_frames;
enc->si_get_pic_param(enc, pic);
enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma);
enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma);
if (!enc->cpb_num) {
struct si_screen *sscreen = (struct si_screen *)encoder->context->screen;
unsigned cpb_size;
/* TODO enable B frame with dual instance */
if ((sscreen->info.family >= CHIP_TONGA) && (enc->base.max_references == 1) &&
(sscreen->info.vce_harvest_config == 0))
enc->dual_inst = true;
enc->cpb_num = get_cpb_num(enc, enc->pic.seq.level_idc);
if (!enc->cpb_num)
return;
enc->cpb_array = CALLOC(enc->cpb_num, sizeof(struct rvce_cpb_slot));
if (!enc->cpb_array)
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 (enc->dual_pipe)
cpb_size += RVCE_MAX_AUX_BUFFER_NUM * RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
return;
}
}
if (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR)
reset_cpb(enc);
else if (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P ||
@@ -376,9 +412,6 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context,
struct si_screen *sscreen = (struct si_screen *)context->screen;
struct si_context *sctx = (struct si_context *)context;
struct rvce_encoder *enc;
struct pipe_video_buffer *tmp_buf, templat = {};
struct radeon_surf *tmp_surf;
unsigned cpb_size;
if (!sscreen->info.vce_fw_version) {
RVID_ERR("Kernel doesn't supports VCE!\n");
@@ -402,10 +435,6 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context,
sscreen->info.family != CHIP_POLARIS11 && sscreen->info.family != CHIP_POLARIS12 &&
sscreen->info.family != CHIP_VEGAM)
enc->dual_pipe = true;
/* TODO enable B frame with dual instance */
if ((sscreen->info.family >= CHIP_TONGA) && (templ->max_references == 1) &&
(sscreen->info.vce_harvest_config == 0))
enc->dual_inst = true;
enc->base = *templ;
enc->base.context = context;
@@ -427,45 +456,6 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context,
goto error;
}
templat.buffer_format = PIPE_FORMAT_NV12;
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;
if (enc->dual_pipe)
cpb_size += RVCE_MAX_AUX_BUFFER_NUM * RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
tmp_buf->destroy(tmp_buf);
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
goto error;
}
enc->cpb_array = CALLOC(enc->cpb_num, sizeof(struct rvce_cpb_slot));
if (!enc->cpb_array)
goto error;
reset_cpb(enc);
switch (sscreen->info.vce_fw_version) {
case FW_40_2_2:
si_vce_40_2_2_init(enc);
@@ -496,9 +486,6 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context,
error:
enc->ws->cs_destroy(&enc->cs);
si_vid_destroy_buffer(&enc->cpb);
FREE(enc->cpb_array);
FREE(enc);
return NULL;
}
@@ -59,7 +59,7 @@ static void create(struct rvce_encoder *enc)
RVCE_BEGIN(0x01000001); // create cmd
RVCE_CS(0x00000000); // encUseCircularBuffer
RVCE_CS(u_get_h264_profile_idc(enc->base.profile)); // encProfile
RVCE_CS(enc->base.level); // encLevel
RVCE_CS(enc->pic.seq.level_idc); // encLevel
RVCE_CS(0x00000000); // encPicStructRestriction
RVCE_CS(enc->base.width); // encImageWidth
RVCE_CS(enc->base.height); // encImageHeight
+1 -1
View File
@@ -180,7 +180,7 @@ static void create(struct rvce_encoder *enc)
RVCE_BEGIN(0x01000001); // create cmd
RVCE_CS(enc->enc_pic.ec.enc_use_circular_buffer);
RVCE_CS(u_get_h264_profile_idc(enc->base.profile)); // encProfile
RVCE_CS(enc->base.level); // encLevel
RVCE_CS(enc->pic.seq.level_idc); // encLevel
RVCE_CS(enc->enc_pic.ec.enc_pic_struct_restriction);
RVCE_CS(enc->base.width); // encImageWidth
RVCE_CS(enc->base.height); // encImageHeight