mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 11:00:11 +01:00
radeonsi/vcn: dpb change for supporting pre-encoding
- dpb buffer created while receive the first begin_frame moved out from encoder creation. - dpb buffer name changed from cpb. - dpb buffer allocation to support pre-encoding - different vcn version IB package adjustment - merge reconstructed_picture_v4_0_t to reconstructed_picture_t Signed-off-by: Ruijing Dong <ruijing.dong@amd.com> Reviewed-by: Boyuan Zhang <boyuan.zhang@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17994>
This commit is contained in:
parent
60f0a182e1
commit
20ca84646b
6 changed files with 248 additions and 251 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue