nouveau: downgrade hacked syncs to hacked flushes
authorBen Skeggs <skeggsb@gmail.com>
Sun, 9 Dec 2007 11:25:35 +0000 (22:25 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Sun, 9 Dec 2007 11:25:35 +0000 (22:25 +1100)
Unfortunately we still need to keep the forced flushes as mesa's vbo path
is still insane.  But, at least this is a little less brutal.  The bo code will
detect when it needs to do a sync.

src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c
src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c
src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c
src/mesa/pipe/nv40/nv40_vbo.c

index fd6d05b7fab1b66f1fe659fd33e0b991a77e6083..d684ab4d7c402ffb4a413fa1e226a3a94f284b04 100644 (file)
@@ -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;
index 6e32d739abc0ae640652423949d5be618b3f44c3..d7bddbcfe20dfc648a80e61a65d954d53ad5245f 100644 (file)
@@ -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,
index 8af0b9d5cd3c1b1a4e1c36a7e84371998b167ad0..f176767f13651f0d9139d853fadfa9c3b695c5b3 100644 (file)
@@ -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);
index 4a964cb82b581f7384d1826f689d0a8127aa35b8..6cb06f8c37bc9d46d66308e89bd5cfda0ac6f31d 100644 (file)
@@ -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;
 }
 
index 893f292e23249a73dfd6af976f7b819155c90ac1..67e2514026b42395a72e07b9b8d2a5bf2b066995 100644 (file)
@@ -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;
 }
 
index 2525476a792fb3e6466c4b200e25754a7f1f9594..2a95b1fcd36cfa10e3014bfba1b5651205393b80 100644 (file)
@@ -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;
 }
index 5e919c5ca97f7d8ee39a40df54496aa17ce651e6..8491f2a3ec82c93f051cbf79e2328c2cee1bbab8 100644 (file)
@@ -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;
 }