diff --git a/src/gallium/drivers/radeonsi/radeon_uvd.c b/src/gallium/drivers/radeonsi/radeon_uvd.c index 8e02495612d..459de7b4bf5 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd.c @@ -1051,7 +1051,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, NULL)) { + if (!si_vid_resize_buffer(dec->base.context, &dec->cs, buf, new_size, NULL)) { RVID_ERR("Can't resize bitstream buffer!"); return; } diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c index 2fb3615517d..77105219aa7 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c @@ -1700,7 +1700,7 @@ static struct pb_buffer_lean *rvcn_dec_message_decode(struct radeon_decoder *dec 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); + r = si_vid_resize_buffer(dec->base.context, &dec->cs, &dec->dpb, dec->dpb_size, &buf_offset_info); if (!r) { RVID_ERR("Can't resize dpb.\n"); return NULL; @@ -2503,7 +2503,7 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, return; } si_vid_destroy_buffer(&old_buf); - } else if (!si_vid_resize_buffer(dec->screen, &dec->cs, buf, total_bs_size, NULL)) { + } else if (!si_vid_resize_buffer(dec->base.context, &dec->cs, buf, total_bs_size, NULL)) { RVID_ERR("Can't resize bitstream buffer!"); return; } diff --git a/src/gallium/drivers/radeonsi/radeon_video.c b/src/gallium/drivers/radeonsi/radeon_video.c index a5e2b626abc..3cb37d1eb29 100644 --- a/src/gallium/drivers/radeonsi/radeon_video.c +++ b/src/gallium/drivers/radeonsi/radeon_video.c @@ -67,44 +67,53 @@ 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, +bool si_vid_resize_buffer(struct pipe_context *context, struct radeon_cmdbuf *cs, 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 si_context *sctx = (struct si_context *)context; + struct si_screen *sscreen = (struct si_screen *)context->screen; struct radeon_winsys *ws = sscreen->ws; unsigned bytes = MIN2(new_buf->res->buf->size, new_size); struct rvid_buffer old_buf = *new_buf; void *src = NULL, *dst = NULL; - if (!si_vid_create_buffer(screen, new_buf, new_size, new_buf->usage)) + if (!si_vid_create_buffer(context->screen, new_buf, new_size, new_buf->usage)) goto error; - src = ws->buffer_map(ws, old_buf.res->buf, cs, PIPE_MAP_READ | RADEON_MAP_TEMPORARY); - if (!src) - goto error; + if (old_buf.usage == PIPE_USAGE_STAGING) { + src = ws->buffer_map(ws, old_buf.res->buf, cs, PIPE_MAP_READ | RADEON_MAP_TEMPORARY); + if (!src) + goto error; - dst = ws->buffer_map(ws, new_buf->res->buf, cs, PIPE_MAP_WRITE | RADEON_MAP_TEMPORARY); - if (!dst) - goto error; + dst = ws->buffer_map(ws, new_buf->res->buf, cs, PIPE_MAP_WRITE | RADEON_MAP_TEMPORARY); + if (!dst) + goto error; - 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; + 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); + } else { + bytes = MIN2(new_buf->res->b.b.width0, old_buf.res->b.b.width0); + si_copy_buffer(sctx, &new_buf->res->b.b, &old_buf.res->b.b, + 0, 0, bytes, SI_OP_SYNC_BEFORE); + context->flush(context, NULL, 0); } - ws->buffer_unmap(ws, new_buf->res->buf); - ws->buffer_unmap(ws, old_buf.res->buf); + si_vid_destroy_buffer(&old_buf); return true; diff --git a/src/gallium/drivers/radeonsi/radeon_video.h b/src/gallium/drivers/radeonsi/radeon_video.h index ffba87ceacf..c7134b35900 100644 --- a/src/gallium/drivers/radeonsi/radeon_video.h +++ b/src/gallium/drivers/radeonsi/radeon_video.h @@ -45,7 +45,7 @@ bool si_vid_create_tmz_buffer(struct pipe_screen *screen, struct rvid_buffer *bu 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, +bool si_vid_resize_buffer(struct pipe_context *context, struct radeon_cmdbuf *cs, struct rvid_buffer *new_buf, unsigned new_size, struct rvid_buf_offset_info *buf_ofst_info);