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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user