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:
Ruijing Dong 2022-08-08 18:13:36 -04:00 committed by Marge Bot
parent 60f0a182e1
commit 20ca84646b
6 changed files with 248 additions and 251 deletions

View file

@ -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;
}

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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;