nouveau: some cleanups
authorBen Skeggs <skeggsb@gmail.com>
Sun, 23 Dec 2007 05:06:24 +0000 (16:06 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Sun, 23 Dec 2007 05:17:22 +0000 (16:17 +1100)
src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_dma.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_pushbuf.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c
src/mesa/pipe/nouveau/nouveau_channel.h
src/mesa/pipe/nouveau/nouveau_pushbuf.h [new file with mode: 0644]

index 294b66e..f201001 100644 (file)
@@ -30,19 +30,6 @@ struct nouveau_context {
        struct nouveau_screen *nv_screen;
        struct pipe_surface *frontbuffer;
 
-       /* Bufmgr */
-       struct {
-               struct nouveau_channel *channel;
-               struct nouveau_notifier *notify;
-               struct nouveau_grobj *m2mf;
-               uint32_t m2mf_src_ctxdma;
-               uint32_t m2mf_dst_ctxdma;
-               uint32_t next_sequence;
-       } bo;
-
-       /* Relocations */
-       struct nouveau_bo *reloc_head;
-
        /* Hardware context */
        uint32_t                *pushbuf;
        struct nouveau_channel  *channel;
index d00fddb..3bb7c49 100644 (file)
@@ -59,12 +59,13 @@ nouveau_dma_channel_init(struct nouveau_channel *chan)
        int i;
 
        nvchan->dma.base = nvchan->drm.put_base;
-       nvchan->dma.cur  = nvchan->dma.put = RING_SKIPS;
+       nvchan->dma.cur  = nvchan->dma.put = 0;
        nvchan->dma.max  = (nvchan->drm.cmdbuf_size >> 2) - 2;
        nvchan->dma.free = nvchan->dma.max - nvchan->dma.cur;
 
+       RING_SPACE_CH(chan, RING_SKIPS);
        for (i = 0; i < RING_SKIPS; i++)
-               nvchan->pushbuf[i] = 0x00000000;
+               OUT_RING_CH(chan, 0);
 }
 
 #define CHECK_TIMEOUT() do {                                                   \
index c4667cc..940a196 100644 (file)
@@ -88,11 +88,26 @@ nouveau_dma_outp(struct nouveau_channel *chan, uint32_t *ptr, int size)
 }
 
 static inline void
+nouveau_dma_space(struct nouveau_channel *chan, int size)
+{
+       struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
+
+       if (nvchan->dma.free < size) {
+               if (nouveau_dma_wait(chan, size) && chan->hang_notify)
+                       chan->hang_notify(chan);
+       }
+       nvchan->dma.free -= size;
+#ifdef NOUVEAU_DMA_DEBUG
+       nvchan->dma.push_free = size;
+#endif
+}
+
+static inline void
 nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
                  int method, int size, const char* file, int line)
 {
        struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
-       int push_size = size + 1;
+       (void)nvchan;
 
 #ifdef NOUVEAU_DMA_TRACE
        NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel,
@@ -108,20 +123,11 @@ nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
        sprintf(faulty,"%s:%d",file,line);
 #endif
 
-       if (nvchan->dma.free < push_size) {
-               if (nouveau_dma_wait(chan, push_size) &&
-                   chan->hang_notify) {
-                       chan->hang_notify(chan);
-               }
-       }
-       nvchan->dma.free -= push_size;
-#ifdef NOUVEAU_DMA_DEBUG
-       nvchan->dma.push_free = push_size;
-#endif
-
+       nouveau_dma_space(chan, (size + 1));
        nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method);
 }
 
+#define RING_SPACE_CH(ch,sz)         nouveau_dma_space((ch), (sz))
 #define BEGIN_RING_CH(ch,gr,m,sz)    nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ )
 #define OUT_RING_CH(ch, data)        nouveau_dma_out((ch), (data))
 #define OUT_RINGp_CH(ch,ptr,dwords)  nouveau_dma_outp((ch), (void*)(ptr),      \
index 7e52de4..4dc40b7 100644 (file)
@@ -33,6 +33,7 @@
 #include "pipe/nouveau/nouveau_notifier.h"
 #include "pipe/nouveau/nouveau_bo.h"
 #include "pipe/nouveau/nouveau_resource.h"
+#include "pipe/nouveau/nouveau_pushbuf.h"
 
 struct nouveau_device_priv {
        struct nouveau_device base;
@@ -121,12 +122,6 @@ struct nouveau_pushbuf_bo {
        int nr_relocs;
 };
 
-struct nouveau_pushbuf {
-       struct nouveau_channel *channel;
-       unsigned remaining;
-       uint32_t *cur;
-};
-
 struct nouveau_pushbuf_priv {
        struct nouveau_pushbuf base;
        struct nouveau_pushbuf *next;
@@ -138,6 +133,7 @@ struct nouveau_pushbuf_priv {
        int nr_buffers;
 };
 #define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n))
+
 #define pbbo_to_ptr(o) ((uint64_t)(unsigned long)(o))
 #define ptr_to_pbbo(h) ((struct nouveau_pushbuf_bo *)(unsigned long)(h))
 #define pbrel_to_ptr(o) ((uint64_t)(unsigned long)(o))
index c9f0903..3b35a11 100644 (file)
@@ -109,14 +109,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
                NOUVEAU_ERR("AII wrap unhandled\n");
 
        /*XXX: assumes subc 0 is populated */
-       if (nvchan->dma.free < 2)
-               WAIT_RING_CH(&nvchan->base, 2);
-       nvchan->dma.free -= 2;
-#ifdef NOUVEAU_DMA_DEBUG
-       nvchan->dma.push_free += 2;
-#endif
-       OUT_RING_CH(&nvchan->base, 0x00040050);
-       OUT_RING_CH(&nvchan->base, nvfence->sequence);
+       RING_SPACE_CH(fence->channel, 2);
+       OUT_RING_CH  (fence->channel, 0x00040050);
+       OUT_RING_CH  (fence->channel, nvfence->sequence);
 
        if (nvchan->fence_tail) {
                nouveau_fence(nvchan->fence_tail)->next = fence;
index 981c4dd..2179664 100644 (file)
 
 #define PB_RSVD_DWORDS 2
 
+static int
+nouveau_pushbuf_space(struct nouveau_channel *chan)
+{
+       struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
+       struct nouveau_pushbuf_priv *nvpb;
+
+       nvpb = calloc(1, sizeof(struct nouveau_pushbuf_priv));
+       if (!nvpb)
+               return -ENOMEM;
+
+       while (nouveau_resource_alloc(nvchan->pb_heap, 0x2100, NULL,
+                                     &nvpb->res)) {
+               nouveau_fence_flush(chan);
+       }
+
+       nvpb->base.channel = chan;
+       nvpb->base.remaining = (nvpb->res->size / 4) - PB_RSVD_DWORDS;
+       nvpb->base.cur = &nvchan->pushbuf[nvpb->res->start/4];
+       nvchan->pb_tail = &nvpb->base;
+       nvchan->base.pushbuf = nvchan->pb_tail;
+
+       return 0;
+}
+
 int
 nouveau_pushbuf_init(struct nouveau_channel *chan)
 {
@@ -47,6 +71,8 @@ nouveau_pushbuf_init(struct nouveau_channel *chan)
        nvchan->dma.max = (4096 / 4) - 2;
        nvchan->dma.free = nvchan->dma.max - nvchan->dma.cur;
 
+       assert(!nouveau_pushbuf_space(chan));
+
        return 0;
 }
 
@@ -65,14 +91,11 @@ int
 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_priv *nvpb = nouveau_pushbuf(chan->pushbuf);
        struct nouveau_pushbuf_bo *pbbo;
        struct nouveau_fence *fence = NULL;
        int ret;
 
-       if (!nvpb)
-               goto out_realloc;
-
        if (nvpb->base.remaining == (nvpb->res->size / 4) - PB_RSVD_DWORDS)
                return 0;
        nvchan->pb_tail = NULL;
@@ -119,12 +142,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
        nvpb->nr_buffers = 0;
 
        /* Emit JMP to indirect pushbuf */
-       if (nvchan->dma.free < 1)
-               WAIT_RING_CH(chan, 1);
-       nvchan->dma.free -= 1;
-#ifdef NOUVEAU_DMA_DEBUG
-       nvchan->dma.push_free = 1;
-#endif
+       RING_SPACE_CH(chan, 1);
        OUT_RING_CH(chan, 0x20000000 | nvpb->res->start);
 
        /* Add JMP back to master pushbuf from indirect pushbuf */
@@ -141,20 +159,7 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan)
        FIRE_RING_CH(chan);
 
        /* Allocate space for next push buffer */
-out_realloc:
-       nvpb = calloc(1, sizeof(struct nouveau_pushbuf_priv));
-       if (!nvpb)
-               return -ENOMEM;
-
-       while (nouveau_resource_alloc(nvchan->pb_heap, 0x2100, NULL,
-                                     &nvpb->res)) {
-               nouveau_fence_flush(chan);
-       }
-
-       nvpb->base.channel = chan;
-       nvpb->base.remaining = (nvpb->res->size / 4) - PB_RSVD_DWORDS;
-       nvpb->base.cur = &nvchan->pushbuf[nvpb->res->start/4];
-       nvchan->pb_tail = &nvpb->base;
+       assert(!nouveau_pushbuf_space(chan));
 
        return 0;
 }
index f588c95..b31e0dc 100644 (file)
@@ -37,15 +37,15 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
 uint32_t *
 nouveau_pipe_dma_beginp(struct nouveau_grobj *grobj, int mthd, int size)
 {
-       struct nouveau_channel_priv *nvchan = nouveau_channel(grobj->channel);
+       struct nouveau_channel *chan = grobj->channel;
        uint32_t *pushbuf;
 
-       if (!nvchan->pb_tail || nvchan->pb_tail->remaining < (size + 1))
-               nouveau_pushbuf_flush(grobj->channel);
+       if (chan->pushbuf->remaining < (size + 1))
+               nouveau_pushbuf_flush(chan);
 
-       pushbuf = nvchan->pb_tail->cur;
-       nvchan->pb_tail->cur += (size + 1);
-       nvchan->pb_tail->remaining -= (size + 1);
+       pushbuf = chan->pushbuf->cur;
+       chan->pushbuf->cur += (size + 1);
+       chan->pushbuf->remaining -= (size + 1);
 
        (*pushbuf++) = ((grobj->subc << 13) | (size << 18) | mthd);
        return pushbuf;
index eccc7b3..b99de9a 100644 (file)
@@ -27,6 +27,8 @@ struct nouveau_channel {
        struct nouveau_device *device;
        int id;
 
+       struct nouveau_pushbuf *pushbuf;
+
        struct nouveau_grobj *vram;
        struct nouveau_grobj *gart;
 
diff --git a/src/mesa/pipe/nouveau/nouveau_pushbuf.h b/src/mesa/pipe/nouveau/nouveau_pushbuf.h
new file mode 100644 (file)
index 0000000..1909765
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2007 Nouveau Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_PUSHBUF_H__
+#define __NOUVEAU_PUSHBUF_H__
+
+struct nouveau_pushbuf {
+       struct nouveau_channel *channel;
+       unsigned remaining;
+       uint32_t *cur;
+};
+
+#endif