nouveau: re-allocate bo's on overflow
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>
Wed, 10 Sep 2014 11:17:13 +0000 (13:17 +0200)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 12 Sep 2014 03:17:52 +0000 (23:17 -0400)
The BSP bo might be too small to contain all of the bsp data,
bump its size on overflow. Also bump inter_bo when this happens,
it might be too small otherwise.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Cc: "10.2 10.3" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/nouveau/nouveau_vp3_video.h
src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
src/gallium/drivers/nouveau/nvc0/nvc0_video.c
src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c

index 5c1af7104fc19b61d4195a6de3559dcc5a3a216b..279a1ce18efa0d200211b62bc2b8cd9e719aa596 100644 (file)
@@ -39,6 +39,8 @@ struct nouveau_vp3_video_buffer {
 #define VP_OFFSET 0x200
 #define COMM_OFFSET 0x500
 
+#define NOUVEAU_VP3_BSP_RESERVED_SIZE 0x700
+
 #define NOUVEAU_VP3_DEBUG_FENCE 0
 
 #if NOUVEAU_VP3_DEBUG_FENCE
index 97d4119b6d177a4bf19fed84cd0374e84c28d84a..6058c22138bb304145dc896d73f5034455c82b85 100644 (file)
@@ -42,8 +42,8 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
    struct nouveau_pushbuf *push = dec->pushbuf[0];
    enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
    uint32_t bsp_addr, comm_addr, inter_addr;
-   uint32_t slice_size, bucket_size, ring_size;
-   uint32_t caps;
+   uint32_t slice_size, bucket_size, ring_size, bsp_size;
+   uint32_t caps, i;
    int ret;
    struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
    struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
@@ -65,6 +65,41 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
    fence_extra = 4;
 #endif
 
+   bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;
+   for (i = 0; i < num_buffers; i++)
+      bsp_size += num_bytes[i];
+   bsp_size += 256; /* the 4 end markers */
+
+   if (!bsp_bo || bsp_size > bsp_bo->size) {
+      struct nouveau_bo *tmp_bo = NULL;
+
+      /* round up to the nearest mb */
+      bsp_size += (1 << 20) - 1;
+      bsp_size &= ~((1 << 20) - 1);
+
+      ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_size, NULL, &tmp_bo);
+      if (ret) {
+         debug_printf("reallocating bsp %u -> %u failed with %i\n",
+                      bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_size, ret);
+         return -1;
+      }
+      nouveau_bo_ref(NULL, &bsp_bo);
+      bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;
+   }
+
+   if (!inter_bo || bsp_bo->size * 4 > inter_bo->size) {
+      struct nouveau_bo *tmp_bo = NULL;
+
+      ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_bo->size * 4, NULL, &tmp_bo);
+      if (ret) {
+         debug_printf("reallocating inter %u -> %u failed with %i\n",
+                      inter_bo ? (unsigned)inter_bo->size : 0, (unsigned)bsp_bo->size * 4, ret);
+         return -1;
+      }
+      nouveau_bo_ref(NULL, &inter_bo);
+      bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;
+   }
+
    ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
    if (ret) {
       debug_printf("map failed: %i %s\n", ret, strerror(-ret));
index 5871f590e0e7d25f13b33391fa24cc98c15c6c6d..48ffac1b715cc0c96e97cc3d68542f51e042a0c1 100644 (file)
@@ -173,16 +173,12 @@ nvc0_create_decoder(struct pipe_context *context,
       ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
                            0x100, 4 << 20, &cfg, &dec->inter_bo[0]);
    if (!ret) {
-      if (!kepler)
-         nouveau_bo_ref(dec->inter_bo[0], &dec->inter_bo[1]);
-      else
-         ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
-                              0x100, dec->inter_bo[0]->size, &cfg,
-                              &dec->inter_bo[1]);
+      ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
+                           0x100, dec->inter_bo[0]->size, &cfg,
+                           &dec->inter_bo[1]);
    }
    if (ret)
       goto fail;
-
    switch (u_reduce_video_profile(templ->profile)) {
    case PIPE_VIDEO_FORMAT_MPEG12: {
       codec = 1;
index 40696fa779f77869c4dc34a230f735413fd48fbb..9139bc1c9119e5f80bf676dcab677d3e89cfd068 100644 (file)
@@ -42,8 +42,8 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
    struct nouveau_pushbuf *push = dec->pushbuf[0];
    enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
    uint32_t bsp_addr, comm_addr, inter_addr;
-   uint32_t slice_size, bucket_size, ring_size;
-   uint32_t caps;
+   uint32_t slice_size, bucket_size, ring_size, bsp_size;
+   uint32_t caps, i;
    int ret;
    struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
    struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
@@ -65,6 +65,49 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
    fence_extra = 4;
 #endif
 
+   bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;
+   for (i = 0; i < num_buffers; i++)
+      bsp_size += num_bytes[i];
+   bsp_size += 256; /* the 4 end markers */
+
+   if (!bsp_bo || bsp_size > bsp_bo->size) {
+      union nouveau_bo_config cfg;
+      struct nouveau_bo *tmp_bo = NULL;
+
+      cfg.nvc0.tile_mode = 0x10;
+      cfg.nvc0.memtype = 0xfe;
+
+      /* round up to the nearest mb */
+      bsp_size += (1 << 20) - 1;
+      bsp_size &= ~((1 << 20) - 1);
+
+      ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_size, &cfg, &tmp_bo);
+      if (ret) {
+         debug_printf("reallocating bsp %u -> %u failed with %i\n",
+                      bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_size, ret);
+         return -1;
+      }
+      nouveau_bo_ref(NULL, &bsp_bo);
+      bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;
+   }
+
+   if (!inter_bo || bsp_bo->size * 4 > inter_bo->size) {
+      union nouveau_bo_config cfg;
+      struct nouveau_bo *tmp_bo = NULL;
+
+      cfg.nvc0.tile_mode = 0x10;
+      cfg.nvc0.memtype = 0xfe;
+
+      ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_bo->size * 4, &cfg, &tmp_bo);
+      if (ret) {
+         debug_printf("reallocating inter %u -> %u failed with %i\n",
+                      inter_bo ? (unsigned)inter_bo->size : 0, (unsigned)bsp_bo->size * 4, ret);
+         return -1;
+      }
+      nouveau_bo_ref(NULL, &inter_bo);
+      bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;
+   }
+
    ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
    if (ret) {
       debug_printf("map failed: %i %s\n", ret, strerror(-ret));