[Mesa-dev] [PATCH] radeon/uvd: fix feedback buffer handling

Alex Deucher alexdeucher at gmail.com
Mon Feb 3 20:31:40 CET 2014


On Mon, Feb 3, 2014 at 5:33 AM, Christian König <deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> Without the correct feedback buffer size UVD runs
> into an error on each frame, reducing the maximum FPS.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

Should probably also CC 10.1, 10.0, and 9.2?

> ---
>  src/gallium/drivers/radeon/radeon_uvd.c | 38 +++++++++++++++++++++++----------
>  1 file changed, 27 insertions(+), 11 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
> index 95757e3..6ac2199 100644
> --- a/src/gallium/drivers/radeon/radeon_uvd.c
> +++ b/src/gallium/drivers/radeon/radeon_uvd.c
> @@ -58,6 +58,9 @@
>  #define NUM_H264_REFS 17
>  #define NUM_VC1_REFS 5
>
> +#define FB_BUFFER_OFFSET 0x1000
> +#define FB_BUFFER_SIZE 2048
> +
>  /* UVD buffer representation */
>  struct ruvd_buffer
>  {
> @@ -81,6 +84,7 @@ struct ruvd_decoder {
>
>         struct ruvd_buffer              msg_fb_buffers[NUM_BUFFERS];
>         struct ruvd_msg                 *msg;
> +       uint32_t                        *fb;
>
>         struct ruvd_buffer              bs_buffers[NUM_BUFFERS];
>         void*                           bs_ptr;
> @@ -132,15 +136,20 @@ static void send_cmd(struct ruvd_decoder *dec, unsigned cmd,
>  }
>
>  /* map the next available message buffer */
> -static void map_msg_buf(struct ruvd_decoder *dec)
> +static void map_msg_fb_buf(struct ruvd_decoder *dec)
>  {
>         struct ruvd_buffer* buf;
> +       void *ptr;
>
> -       /* grap the current message buffer */
> +       /* grap the current message/feedback buffer */
>         buf = &dec->msg_fb_buffers[dec->cur_buffer];
>
> -       /* copy the message into it */
> -       dec->msg = dec->ws->buffer_map(buf->cs_handle, dec->cs, PIPE_TRANSFER_WRITE);
> +       /* and map it for CPU access */
> +       ptr = dec->ws->buffer_map(buf->cs_handle, dec->cs, PIPE_TRANSFER_WRITE);
> +
> +       /* calc buffer offsets */
> +       dec->msg = ptr;
> +       dec->fb = ptr + FB_BUFFER_OFFSET;
>  }
>
>  /* unmap and send a message command to the VCPU */
> @@ -148,8 +157,8 @@ static void send_msg_buf(struct ruvd_decoder *dec)
>  {
>         struct ruvd_buffer* buf;
>
> -       /* ignore the request if message buffer isn't mapped */
> -       if (!dec->msg)
> +       /* ignore the request if message/feedback buffer isn't mapped */
> +       if (!dec->msg || !dec->fb)
>                 return;
>
>         /* grap the current message buffer */
> @@ -157,6 +166,8 @@ static void send_msg_buf(struct ruvd_decoder *dec)
>
>         /* unmap the buffer */
>         dec->ws->buffer_unmap(buf->cs_handle);
> +       dec->msg = NULL;
> +       dec->fb = NULL;
>
>         /* and send it to the hardware */
>         send_cmd(dec, RUVD_CMD_MSG_BUFFER, buf->cs_handle, 0,
> @@ -644,7 +655,7 @@ static void ruvd_destroy(struct pipe_video_codec *decoder)
>
>         assert(decoder);
>
> -       map_msg_buf(dec);
> +       map_msg_fb_buf(dec);
>         memset(dec->msg, 0, sizeof(*dec->msg));
>         dec->msg->size = sizeof(*dec->msg);
>         dec->msg->msg_type = RUVD_MSG_DESTROY;
> @@ -773,7 +784,7 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
>         memset(dec->bs_ptr, 0, bs_size - dec->bs_size);
>         dec->ws->buffer_unmap(bs_buf->cs_handle);
>
> -       map_msg_buf(dec);
> +       map_msg_fb_buf(dec);
>         dec->msg->size = sizeof(*dec->msg);
>         dec->msg->msg_type = RUVD_MSG_DECODE;
>         dec->msg->stream_handle = dec->stream_handle;
> @@ -813,6 +824,10 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
>
>         dec->msg->body.decode.db_surf_tile_config = dec->msg->body.decode.dt_surf_tile_config;
>         dec->msg->body.decode.extension_support = 0x1;
> +
> +       /* set at least the feedback buffer size */
> +       dec->fb[0] = FB_BUFFER_SIZE;
> +
>         send_msg_buf(dec);
>
>         send_cmd(dec, RUVD_CMD_DPB_BUFFER, dec->dpb.cs_handle, 0,
> @@ -822,7 +837,7 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
>         send_cmd(dec, RUVD_CMD_DECODING_TARGET_BUFFER, dt, 0,
>                  RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
>         send_cmd(dec, RUVD_CMD_FEEDBACK_BUFFER, msg_fb_buf->cs_handle,
> -                0x1000, RADEON_USAGE_WRITE, RADEON_DOMAIN_GTT);
> +                FB_BUFFER_OFFSET, RADEON_USAGE_WRITE, RADEON_DOMAIN_GTT);
>         set_reg(dec, RUVD_ENGINE_CNTL, 1);
>
>         flush(dec);
> @@ -898,7 +913,8 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context,
>
>         bs_buf_size = width * height * 512 / (16 * 16);
>         for (i = 0; i < NUM_BUFFERS; ++i) {
> -               unsigned msg_fb_size = align(sizeof(struct ruvd_msg), 0x1000) + 0x1000;
> +               unsigned msg_fb_size = FB_BUFFER_OFFSET + FB_BUFFER_SIZE;
> +               assert(sizeof(struct ruvd_msg) <= FB_BUFFER_OFFSET);
>                 if (!create_buffer(dec, &dec->msg_fb_buffers[i], msg_fb_size)) {
>                         RUVD_ERR("Can't allocated message buffers.\n");
>                         goto error;
> @@ -920,7 +936,7 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context,
>
>         clear_buffer(dec, &dec->dpb);
>
> -       map_msg_buf(dec);
> +       map_msg_fb_buf(dec);
>         dec->msg->size = sizeof(*dec->msg);
>         dec->msg->msg_type = RUVD_MSG_CREATE;
>         dec->msg->stream_handle = dec->stream_handle;
> --
> 1.8.1.2
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list