radeonsi: Add support for DPB resize
This patch will add support for dpb resize when low to high resolution change/ svc use-cases. With DPB tier1 type,vp9 svc decoder use cases are failed. This Change will fix this[VCN1/VCN2]. Signed-off-by: SureshGuttula <suresh.guttula@amd.com> Reviewed-by: Leo Liu <leo.liu@amd.com> Reviewed-by: Boyuan Zhang <boyuan.zhang@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21548>
This commit is contained in:
@@ -160,6 +160,11 @@
|
||||
|
||||
#define RDECODE_VP9_PROBS_DATA_SIZE 2304
|
||||
|
||||
/* *** decode flags *** */
|
||||
#define RDECODE_FLAGS_USE_DYNAMIC_DPB_MASK 0x00000001
|
||||
#define RDECODE_FLAGS_USE_PAL_MASK 0x00000008
|
||||
#define RDECODE_FLAGS_DPB_RESIZE_MASK 0x00000100
|
||||
|
||||
#define mmUVD_JPEG_CNTL 0x0200
|
||||
#define mmUVD_JPEG_CNTL_BASE_IDX 1
|
||||
#define mmUVD_JPEG_RB_BASE 0x0201
|
||||
|
||||
@@ -1059,7 +1059,7 @@ static void ruvd_decode_bitstream(struct pipe_video_codec *decoder,
|
||||
|
||||
if (new_size > buf->res->buf->size) {
|
||||
dec->ws->buffer_unmap(dec->ws, buf->res->buf);
|
||||
if (!si_vid_resize_buffer(dec->screen, &dec->cs, buf, new_size)) {
|
||||
if (!si_vid_resize_buffer(dec->screen, &dec->cs, buf, new_size, NULL)) {
|
||||
RVID_ERR("Can't resize bitstream buffer!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1958,7 +1958,7 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
|
||||
rvcn_dec_message_drm_t *drm = NULL;
|
||||
rvcn_dec_message_dynamic_dpb_t *dynamic_dpb = NULL;
|
||||
rvcn_dec_message_dynamic_dpb_t2_t *dynamic_dpb_t2 = NULL;
|
||||
|
||||
bool dpb_resize = false;
|
||||
header = dec->msg;
|
||||
sizes += sizeof(rvcn_dec_message_header_t);
|
||||
|
||||
@@ -2044,9 +2044,9 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
|
||||
|
||||
decode->bsd_size = align(dec->bs_size, 128);
|
||||
|
||||
if (!dec->dpb.res && dec->dpb_type != DPB_DYNAMIC_TIER_2) {
|
||||
if (dec->dpb_type != DPB_DYNAMIC_TIER_2) {
|
||||
bool r;
|
||||
if (dec->dpb_size) {
|
||||
if (!dec->dpb.res && dec->dpb_size) {
|
||||
if (encrypted) {
|
||||
r = si_vid_create_tmz_buffer(dec->screen, &dec->dpb, dec->dpb_size, PIPE_USAGE_DEFAULT);
|
||||
} else {
|
||||
@@ -2058,6 +2058,25 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
|
||||
return NULL;
|
||||
}
|
||||
si_vid_clear_buffer(dec->base.context, &dec->dpb);
|
||||
} else if (dec->dpb_type == DPB_DYNAMIC_TIER_1 && dec->dpb.res &&
|
||||
(dec->max_width < dec->base.width || dec->max_height < dec->base.height)) {
|
||||
struct rvid_buf_offset_info buf_offset_info;
|
||||
|
||||
buf_offset_info.num_units = (NUM_VP9_REFS + 1);
|
||||
buf_offset_info.old_offset = (align(dec->max_width, dec->db_alignment) *
|
||||
align(dec->max_height, dec->db_alignment) * 3 / 2);
|
||||
buf_offset_info.new_offset = (align(dec->base.width, dec->db_alignment) *
|
||||
align(dec->base.height, dec->db_alignment) * 3 / 2);
|
||||
|
||||
dec->dpb_size = calc_dpb_size(dec);
|
||||
r = si_vid_resize_buffer(dec->screen, &dec->cs, &dec->dpb, dec->dpb_size, &buf_offset_info);
|
||||
if (!r) {
|
||||
RVID_ERR("Can't resize dpb.\n");
|
||||
return NULL;
|
||||
}
|
||||
dec->max_width = dec->base.width;
|
||||
dec->max_height = dec->base.height;
|
||||
dpb_resize = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2202,10 +2221,14 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
|
||||
}
|
||||
|
||||
if (dec->dpb_type == DPB_DYNAMIC_TIER_1) {
|
||||
decode->decode_flags = 1;
|
||||
decode->decode_flags |= (RDECODE_FLAGS_USE_DYNAMIC_DPB_MASK | RDECODE_FLAGS_USE_PAL_MASK);
|
||||
// Add decode flag for RESIZE_DPB ,when we do resize
|
||||
if (dpb_resize == true)
|
||||
decode->decode_flags |= RDECODE_FLAGS_DPB_RESIZE_MASK;
|
||||
|
||||
dynamic_dpb->dpbArraySize = NUM_VP9_REFS + 1;
|
||||
dynamic_dpb->dpbLumaPitch = align(decode->width_in_samples, dec->db_alignment);
|
||||
dynamic_dpb->dpbLumaAlignedHeight = align(decode->height_in_samples, dec->db_alignment);
|
||||
dynamic_dpb->dpbLumaPitch = align(dec->max_width, dec->db_alignment);
|
||||
dynamic_dpb->dpbLumaAlignedHeight = align(dec->max_height, dec->db_alignment);
|
||||
dynamic_dpb->dpbLumaAlignedSize =
|
||||
dynamic_dpb->dpbLumaPitch * dynamic_dpb->dpbLumaAlignedHeight;
|
||||
dynamic_dpb->dpbChromaPitch = dynamic_dpb->dpbLumaPitch >> 1;
|
||||
@@ -2846,7 +2869,7 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder,
|
||||
if (new_size > buf->res->buf->size) {
|
||||
dec->ws->buffer_unmap(dec->ws, buf->res->buf);
|
||||
dec->bs_ptr = NULL;
|
||||
if (!si_vid_resize_buffer(dec->screen, &dec->cs, buf, new_size)) {
|
||||
if (!si_vid_resize_buffer(dec->screen, &dec->cs, buf, new_size, NULL)) {
|
||||
RVID_ERR("Can't resize bitstream buffer!");
|
||||
return;
|
||||
}
|
||||
@@ -3021,7 +3044,8 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context,
|
||||
dec->base.context = context;
|
||||
dec->base.width = width;
|
||||
dec->base.height = height;
|
||||
|
||||
dec->max_width = width;
|
||||
dec->max_height = height;
|
||||
dec->base.destroy = radeon_dec_destroy;
|
||||
dec->base.begin_frame = radeon_dec_begin_frame;
|
||||
dec->base.decode_macroblock = radeon_dec_decode_macroblock;
|
||||
|
||||
@@ -51,6 +51,8 @@ struct radeon_decoder {
|
||||
unsigned dpb_size;
|
||||
unsigned last_width;
|
||||
unsigned last_height;
|
||||
unsigned max_width;
|
||||
unsigned max_height;
|
||||
unsigned addr_gfx_mode;
|
||||
|
||||
struct pipe_screen *screen;
|
||||
|
||||
@@ -87,7 +87,8 @@ void si_vid_destroy_buffer(struct rvid_buffer *buffer)
|
||||
|
||||
/* reallocate a buffer, preserving its content */
|
||||
bool si_vid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs,
|
||||
struct rvid_buffer *new_buf, unsigned new_size)
|
||||
struct rvid_buffer *new_buf, unsigned new_size,
|
||||
struct rvid_buf_offset_info *buf_ofst_info)
|
||||
{
|
||||
struct si_screen *sscreen = (struct si_screen *)screen;
|
||||
struct radeon_winsys *ws = sscreen->ws;
|
||||
@@ -106,11 +107,20 @@ bool si_vid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs,
|
||||
if (!dst)
|
||||
goto error;
|
||||
|
||||
memcpy(dst, src, bytes);
|
||||
if (new_size > bytes) {
|
||||
new_size -= bytes;
|
||||
dst += bytes;
|
||||
if (buf_ofst_info) {
|
||||
memset(dst, 0, new_size);
|
||||
for(int i =0; i < buf_ofst_info->num_units; i++) {
|
||||
memcpy(dst, src, buf_ofst_info->old_offset);
|
||||
dst += buf_ofst_info->new_offset;
|
||||
src += buf_ofst_info->old_offset;
|
||||
}
|
||||
} else {
|
||||
memcpy(dst, src, bytes);
|
||||
if (new_size > bytes) {
|
||||
new_size -= bytes;
|
||||
dst += bytes;
|
||||
memset(dst, 0, new_size);
|
||||
}
|
||||
}
|
||||
ws->buffer_unmap(ws, new_buf->res->buf);
|
||||
ws->buffer_unmap(ws, old_buf.res->buf);
|
||||
|
||||
@@ -42,6 +42,13 @@ struct rvid_buffer {
|
||||
struct si_resource *res;
|
||||
};
|
||||
|
||||
/* video buffer offset info representation */
|
||||
struct rvid_buf_offset_info {
|
||||
unsigned num_units;
|
||||
unsigned old_offset;
|
||||
unsigned new_offset;
|
||||
};
|
||||
|
||||
/* generate an stream handle */
|
||||
unsigned si_vid_alloc_stream_handle(void);
|
||||
|
||||
@@ -58,7 +65,8 @@ void si_vid_destroy_buffer(struct rvid_buffer *buffer);
|
||||
|
||||
/* reallocate a buffer, preserving its content */
|
||||
bool si_vid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs,
|
||||
struct rvid_buffer *new_buf, unsigned new_size);
|
||||
struct rvid_buffer *new_buf, unsigned new_size,
|
||||
struct rvid_buf_offset_info *buf_ofst_info);
|
||||
|
||||
/* clear the buffer with zeros */
|
||||
void si_vid_clear_buffer(struct pipe_context *context, struct rvid_buffer *buffer);
|
||||
|
||||
Reference in New Issue
Block a user