From c3c24c3accd1401cbe96098e44850bb1130d80b9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Mon, 3 Feb 2014 02:28:58 -0700 Subject: [PATCH] radeon/uvd: fix feedback buffer handling v2 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Without the correct feedback buffer size UVD runs into an error on each frame, reducing the maximum FPS. v2: fixing Michels comments Signed-off-by: Christian König Reviewed-by: Michel Dänzer Cc: "10.1" "10.0" "9.2" --- src/gallium/drivers/radeon/radeon_uvd.c | 40 +++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 95757e30395..e88c45c5e5d 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; @@ -131,16 +135,21 @@ static void send_cmd(struct ruvd_decoder *dec, unsigned cmd, set_reg(dec, RUVD_GPCOM_VCPU_CMD, cmd << 1); } -/* map the next available message buffer */ -static void map_msg_buf(struct ruvd_decoder *dec) +/* map the next available message/feedback buffer */ +static void map_msg_fb_buf(struct ruvd_decoder *dec) { struct ruvd_buffer* buf; + uint8_t *ptr; - /* grap the current message buffer */ + /* grab 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 = (struct ruvd_msg *)ptr; + dec->fb = (uint32_t *)(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; + STATIC_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; -- 2.30.2