radeon/uvd: add and manage render picture list
authorBoyuan Zhang <boyuan.zhang@amd.com>
Fri, 15 Dec 2017 16:23:25 +0000 (11:23 -0500)
committerLeo Liu <leo.liu@amd.com>
Fri, 15 Dec 2017 21:04:31 +0000 (16:04 -0500)
Create a list in decoder to store all render picture buffer pointers that
currently being used in reference picture lists.

During get message buffer call, check each pointer in render_pic_list[]
within given pic->ref[] list, remove pointer that no longer being used by
pic->ref[]. Then add current render surface pointer to the render_pic_list[]
and assign the associated index to result.curr_idx.

As a result, result.curr_idx will have the correct index to represent the
current render picture, instead of the previous increamenting values.

Signed-off-by: Boyuan Zhang <boyuan.zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
src/gallium/drivers/radeon/radeon_uvd.c

index ee76e748b087401ac3bc70e2686fde90407c30fe..b46ee6e3c4045772508f532e4b2f16eabace011c 100644 (file)
@@ -91,6 +91,8 @@ struct ruvd_decoder {
                unsigned                cmd;
                unsigned                cntl;
        } reg;
+
+       void                            *render_pic_list[16];
 };
 
 /* flush IB to the hardware */
@@ -590,7 +592,7 @@ static struct ruvd_h265 get_h265_msg(struct ruvd_decoder *dec, struct pipe_video
                                     struct pipe_h265_picture_desc *pic)
 {
        struct ruvd_h265 result;
-       unsigned i;
+       unsigned i, j;
 
        memset(&result, 0, sizeof(result));
 
@@ -670,11 +672,28 @@ static struct ruvd_h265 get_h265_msg(struct ruvd_decoder *dec, struct pipe_video
                result.row_height_minus1[i] = pic->pps->row_height_minus1[i];
 
        result.num_delta_pocs_ref_rps_idx = pic->NumDeltaPocsOfRefRpsIdx;
-       result.curr_idx = pic->CurrPicOrderCntVal;
        result.curr_poc = pic->CurrPicOrderCntVal;
 
+       for (i = 0 ; i < 16 ; i++) {
+               for (j = 0; (pic->ref[j] != NULL) && (j < 16) ; j++) {
+                       if (dec->render_pic_list[i] == pic->ref[j])
+                               break;
+                       if (j == 15)
+                               dec->render_pic_list[i] = NULL;
+                       else if (pic->ref[j+1] == NULL)
+                               dec->render_pic_list[i] = NULL;
+               }
+       }
+       for (i = 0 ; i < 16 ; i++) {
+               if (dec->render_pic_list[i] == NULL) {
+                       dec->render_pic_list[i] = target;
+                       result.curr_idx = i;
+                       break;
+               }
+       }
+
        vl_video_buffer_set_associated_data(target, &dec->base,
-                                           (void *)(uintptr_t)pic->CurrPicOrderCntVal,
+                                           (void *)(uintptr_t)result.curr_idx,
                                            &ruvd_destroy_associated_data);
 
        for (i = 0; i < 16; ++i) {
@@ -717,7 +736,7 @@ static struct ruvd_h265 get_h265_msg(struct ruvd_decoder *dec, struct pipe_video
        memcpy(dec->it + 864, pic->pps->sps->ScalingList32x32, 2 * 64);
 
        for (i = 0 ; i < 2 ; i++) {
-               for (int j = 0 ; j < 15 ; j++)
+               for (j = 0 ; j < 15 ; j++)
                        result.direct_reflist[i][j] = pic->RefPicList[i][j];
        }
 
@@ -1398,6 +1417,8 @@ struct pipe_video_codec *si_common_uvd_create_decoder(struct pipe_context *conte
                goto error;
        }
 
+       for (i = 0; i < 16; i++)
+                dec->render_pic_list[i] = NULL;
        dec->fb_size = (rctx->family == CHIP_TONGA) ? FB_BUFFER_SIZE_TONGA :
                        FB_BUFFER_SIZE;
        bs_buf_size = width * height * (512 / (16 * 16));