summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c18
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c1
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h3
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c21
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c13
-rw-r--r--src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c12
-rw-r--r--src/mesa/pipe/nv40/nv40_vbo.c4
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;
}