mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-12 11:10:34 +01:00
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 <maarten.lankhorst@canonical.com> Cc: "10.2 10.3" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
parent
1187dbdd10
commit
f6afed7076
4 changed files with 87 additions and 11 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue