From f6afed7076a6ef446dbec7cb10c8f8c60efafccd Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 10 Sep 2014 13:17:13 +0200 Subject: [PATCH] nouveau: re-allocate bo's on overflow 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 Cc: "10.2 10.3" --- .../drivers/nouveau/nouveau_vp3_video.h | 2 + .../drivers/nouveau/nv50/nv98_video_bsp.c | 39 ++++++++++++++- src/gallium/drivers/nouveau/nvc0/nvc0_video.c | 10 ++-- .../drivers/nouveau/nvc0/nvc0_video_bsp.c | 47 ++++++++++++++++++- 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.h b/src/gallium/drivers/nouveau/nouveau_vp3_video.h index 5c1af7104fc..279a1ce18ef 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video.h +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.h @@ -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 diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c index 97d4119b6d1..6058c22138b 100644 --- a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c +++ b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c @@ -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)); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c index 5871f590e0e..48ffac1b715 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c @@ -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; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c index 40696fa779f..9139bc1c911 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c @@ -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)); -- 2.30.2