diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c | 18 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c | 21 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c | 13 | ||||
-rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c | 12 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_vbo.c | 4 |
7 files changed, 38 insertions, 34 deletions
diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c index fd6d05b7fa..d684ab4d7c 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c @@ -205,6 +205,9 @@ nouveau_bo_del(struct nouveau_bo **userbo) if (--bo->refcount) return; + if (bo->fence) + nouveau_fence_wait(&bo->fence); + nouveau_bo_realloc_gpu(bo, 0, 0); if (bo->sysmem && !bo->user) free(bo->sysmem); @@ -235,13 +238,15 @@ nouveau_bo_unmap(struct nouveau_bo *userbo) static int nouveau_bo_upload(struct nouveau_bo_priv *bo) { + if (bo->fence) + nouveau_fence_wait(&bo->fence); memcpy(bo->map, bo->sysmem, bo->drm.size); return 0; } int nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, - uint32_t flags) + struct nouveau_fence *fence, uint32_t flags) { struct nouveau_bo_priv *nvbo = nouveau_bo(bo); @@ -249,14 +254,23 @@ nouveau_bo_validate(struct nouveau_channel *chan, struct nouveau_bo *bo, nouveau_bo_realloc_gpu(nvbo, flags, nvbo->base.size); nouveau_bo_upload(nvbo); } else - if (nvbo->user || nvbo->base.map) + if (nvbo->user) { + nouveau_bo_upload(nvbo); + } else + if (nvbo->base.map) { nouveau_bo_upload(nvbo); + nvbo->sync_hack = 1; + } if (!nvbo->user && !nvbo->base.map) { free(nvbo->sysmem); nvbo->sysmem = NULL; } + if (nvbo->fence) + nouveau_fence_del(&nvbo->fence); + nouveau_fence_ref(fence, &nvbo->fence); + nvbo->base.offset = nvbo->drm.offset; if (nvbo->drm.flags & NOUVEAU_MEM_AGP) nvbo->base.flags = NOUVEAU_BO_GART; diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c index 6e32d739ab..d7bddbcfe2 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c @@ -155,7 +155,6 @@ nouveau_dma_kickoff(struct nouveau_channel *userchan) if ((chan->pushbuf[i] & 0xf0000000) == 0x20000000) { int n = (((chan->pushbuf[i] & 0x0fffffff) - chan->dma.base) / 4); - do { NOUVEAU_MSG("\t0x%08x 0x%08x\n", (n<<2)+chan->dma.base, diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h b/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h index 8af0b9d5cd..f176767f13 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h @@ -243,6 +243,7 @@ struct nouveau_bo_priv { int user; int refcount; + int sync_hack; }; #define nouveau_bo(n) ((struct nouveau_bo_priv *)(n)) @@ -277,7 +278,7 @@ nouveau_bo_unmap(struct nouveau_bo *); extern int nouveau_bo_validate(struct nouveau_channel *, struct nouveau_bo *, - uint32_t flags); + struct nouveau_fence *fence, uint32_t flags); extern int nouveau_resource_init(struct nouveau_resource **heap, int size); diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c index 4a964cb82b..6cb06f8c37 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c @@ -55,6 +55,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) struct nouveau_channel_priv *nvchan = nouveau_channel(chan); struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(nvchan->pb_tail); struct nouveau_pushbuf_bo *pbbo; + struct nouveau_fence *fence = NULL; + int sync_hack = 0; int ret; if (!nvpb) @@ -63,7 +65,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) if (nvpb->base.remaining == nvpb->res->size / 4) return 0; - ret = nouveau_fence_new(chan, &nvpb->fence); + ret = nouveau_fence_new(chan, &fence); if (ret) return ret; @@ -72,9 +74,12 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) struct nouveau_pushbuf_reloc *r; struct nouveau_bo *bo = &ptr_to_bo(pbbo->handle)->base; - ret = nouveau_bo_validate(chan, bo, pbbo->flags); + ret = nouveau_bo_validate(chan, bo, fence, pbbo->flags); assert (ret == 0); + sync_hack |= nouveau_bo(bo)->sync_hack; + nouveau_bo(bo)->sync_hack = 0; + while ((r = ptr_to_pbrel(pbbo->relocs))) { uint32_t push; @@ -108,6 +113,9 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) if (nvchan->dma.free < 1) WAIT_RING_CH(chan, 1); nvchan->dma.free -= 1; +#ifdef NOUVEAU_DMA_DEBUG + nvchan->dma.push_free = 1; +#endif OUT_RING_CH(chan, 0x20000000 | (nvpb->res->start + 4096)); /* Add JMP back to master pushbuf from indirect pushbuf */ @@ -115,6 +123,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan) 0x20000000 | ((nvchan->dma.cur << 2) + nvchan->dma.base); /* Fence */ + nvpb->fence = fence; nouveau_fence_emit(nvpb->fence); /* Kickoff */ @@ -173,12 +182,18 @@ out_realloc: nvpb->base.cur = &nvchan->pushbuf[(nvpb->res->start + 4096)/4]; if (nvchan->pb_tail) { - nouveau_pushbuf(nvchan->pb_tail)->next = & nvpb->base; + nouveau_pushbuf(nvchan->pb_tail)->next = &nvpb->base; } else { nvchan->pb_head = &nvpb->base; } nvchan->pb_tail = &nvpb->base; + if (sync_hack) { + struct nouveau_fence *f = NULL; + nouveau_fence_ref(nvpb->fence, &f); + nouveau_fence_wait(&f); + } + return 0; } diff --git a/src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c b/src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c index 893f292e23..67e2514026 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c @@ -116,13 +116,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, static void nv04_surface_copy_done(struct nouveau_context *nv) { - nouveau_notifier_reset(nv->sync_notifier, 0); - BEGIN_RING(NvGdiRect, 0x104, 1); - OUT_RING (0); - BEGIN_RING(NvGdiRect, 0x100, 1); - OUT_RING (0); FIRE_RING(); - nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); } static int @@ -160,14 +154,7 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING ((dx << 16) | dy); OUT_RING (( w << 16) | h); - nouveau_notifier_reset(nv->sync_notifier, 0); - BEGIN_RING(NvGdiRect, 0x104, 1); - OUT_RING (0); - BEGIN_RING(NvGdiRect, 0x100, 1); - OUT_RING (0); FIRE_RING(); - nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); - return 0; } diff --git a/src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c b/src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c index 2525476a79..2a95b1fcd3 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c @@ -82,13 +82,7 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy, static void nv50_surface_copy_done(struct nouveau_context *nv) { - nouveau_notifier_reset(nv->sync_notifier, 0); - BEGIN_RING(Nv2D, 0x104, 1); - OUT_RING (0); - BEGIN_RING(Nv2D, 0x100, 1); - OUT_RING (0); FIRE_RING(); - nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); } static int @@ -134,13 +128,7 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst, OUT_RING (dx + w); OUT_RING (dy + h); - nouveau_notifier_reset(nv->sync_notifier, 0); - BEGIN_RING(Nv2D, 0x104, 1); - OUT_RING (0); - BEGIN_RING(Nv2D, 0x100, 1); - OUT_RING (0); FIRE_RING(); - nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000); return 0; } diff --git a/src/mesa/pipe/nv40/nv40_vbo.c b/src/mesa/pipe/nv40/nv40_vbo.c index 5e919c5ca9..8491f2a3ec 100644 --- a/src/mesa/pipe/nv40/nv40_vbo.c +++ b/src/mesa/pipe/nv40/nv40_vbo.c @@ -41,7 +41,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (0); - pipe->flush(pipe, PIPE_FLUSH_WAIT); + pipe->flush(pipe, 0); return TRUE; } @@ -153,7 +153,7 @@ nv40_draw_elements(struct pipe_context *pipe, OUT_RING (0); pipe->winsys->buffer_unmap(pipe->winsys, ib); - pipe->flush(pipe, PIPE_FLUSH_WAIT); + pipe->flush(pipe, 0); return TRUE; } |