nouveau: nuke subchan auto-assign.
authorBen Skeggs <skeggsb@gmail.com>
Wed, 19 Dec 2007 08:40:38 +0000 (19:40 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Wed, 19 Dec 2007 08:40:38 +0000 (19:40 +1100)
It's annoying for several reasons, especially in its current form.  May
possibly be reincarnated later (DDX depends on it these days), but in
not quite the same way.

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_local.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c
src/mesa/drivers/dri/nouveau_winsys/nv04_surface.c
src/mesa/drivers/dri/nouveau_winsys/nv50_surface.c
src/mesa/pipe/nouveau/nouveau_grobj.h

index cd59b7cc43631b86c1ff1a5cc1cd2835c5d0f099..294b66e5188016cff0c8fe1efa14bf2fb25d488e 100644 (file)
@@ -54,6 +54,7 @@ struct nouveau_context {
        struct nouveau_grobj    *NvM2MF;
        struct nouveau_grobj    *Nv2D;
        uint32_t                 next_handle;
+       uint32_t                 next_subchannel;
        uint32_t                 next_sequence;
 
        /* pipe_surface accel */
index b89f1b5cf5f48d1861b67367bb549dbc95bbce4f..d00fddbff2f7769379a29b06092dc5d3e97b63af 100644 (file)
@@ -126,34 +126,6 @@ nouveau_dma_wait(struct nouveau_channel *chan, int size)
        return 0;
 }
 
-#ifdef NOUVEAU_DMA_SUBCHAN_LRU
-void
-nouveau_dma_subc_bind(struct nouveau_grobj *grobj)
-{
-       struct nouveau_channel_priv *nvchan = nouveau_channel(grobj->channel);
-       int subc = -1, i;
-       
-       for (i = 0; i < 8; i++) {
-               if (nvchan->subchannel[i].grobj &&
-                   nvchan->subchannel[i].grobj->bound == 
-                   NOUVEAU_GROBJ_EXPLICIT_BIND)
-                       continue;
-               if (nvchan->subchannel[i].seq < nvchan->subchannel[subc].seq)
-                       subc = i;
-       }
-       assert(subc >= 0);
-
-       if (nvchan->subchannel[subc].grobj)
-               nvchan->subchannel[subc].grobj->bound = 0;
-       nvchan->subchannel[subc].grobj = grobj;
-       grobj->subc  = subc;
-       grobj->bound = NOUVEAU_GROBJ_BOUND;
-
-       BEGIN_RING_CH(grobj->channel, grobj, 0, 1);
-       nouveau_dma_out  (grobj->channel, grobj->handle);
-}
-#endif
-
 #ifdef NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF
 static void
 nouveau_dma_parse_pushbuf(struct nouveau_channel *chan, int get, int put)
index d4dd3054f3d86f6d0393327466ae3b3451f59588..c4667cc5c0209d323de8beaee742cf29674bc648 100644 (file)
@@ -94,12 +94,6 @@ nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
        struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
        int push_size = size + 1;
 
-#ifdef NOUVEAU_DMA_SUBCHAN_LRU
-       if (grobj->bound == NOUVEAU_GROBJ_UNBOUND)
-               nouveau_dma_subc_bind(grobj);
-       nvchan->subchannel[grobj->subc].seq = nvchan->subc_sequence++;
-#endif
-
 #ifdef NOUVEAU_DMA_TRACE
        NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", nvchan->drm.channel,
                    grobj->handle, grobj->subc, method, size);
@@ -128,26 +122,6 @@ nouveau_dma_begin(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
        nouveau_dma_out(chan, (size << 18) | (grobj->subc << 13) | method);
 }
 
-static inline void
-nouveau_dma_bind(struct nouveau_channel *chan, struct nouveau_grobj *grobj,
-                int subc)
-{
-       struct nouveau_channel_priv *nvchan = nouveau_channel(chan);
-
-       if (nvchan->subchannel[subc].grobj == grobj)
-               return;
-
-       if (nvchan->subchannel[subc].grobj)
-               nvchan->subchannel[subc].grobj->bound = NOUVEAU_GROBJ_UNBOUND;
-       nvchan->subchannel[subc].grobj = grobj;
-       grobj->subc  = subc;
-       grobj->bound = NOUVEAU_GROBJ_EXPLICIT_BIND;
-
-       nouveau_dma_begin(chan, grobj, 0x0000, 1, __FUNCTION__, __LINE__);
-       nouveau_dma_out  (chan, grobj->handle);
-}
-
-#define BIND_RING_CH(ch,gr,sc)       nouveau_dma_bind((ch), (gr), (sc))
 #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 9978652dd6ddd2d11e7fbc9a8951173b1db48843..7e52de4323581d9f14122c54c001a632a5e37a05 100644 (file)
@@ -161,12 +161,6 @@ struct nouveau_channel_priv {
 
        struct drm_nouveau_channel_alloc drm;
 
-       struct {
-               struct nouveau_grobj *grobj;
-               uint32_t seq;
-       } subchannel[8];
-       uint32_t subc_sequence;
-
        uint32_t *pushbuf;
        void     *notifier_block;
 
index 7861b6f84d386a9a0247831a51cce4c13ebafd79..c9f0903e27262ba741b1b7d0eb3e2e260519f100 100644 (file)
@@ -108,8 +108,15 @@ nouveau_fence_emit(struct nouveau_fence *fence)
        if (nvfence->sequence == 0xffffffff)
                NOUVEAU_ERR("AII wrap unhandled\n");
 
-       BEGIN_RING_CH(&nvchan->base, nvchan->subchannel[0].grobj, 0x50, 1);
-       OUT_RING_CH  (&nvchan->base, nvfence->sequence);
+       /*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);
 
        if (nvchan->fence_tail) {
                nouveau_fence(nvchan->fence_tail)->next = fence;
index 1978edea02dd7a01626a08a3ba1241810b4c5ab3..e7111de4dc137d37fe4638725d1413b39f27e85e 100644 (file)
@@ -20,7 +20,6 @@
 //#define NOUVEAU_DMA_TRACE
 //#define NOUVEAU_DMA_DEBUG
 //#define NOUVEAU_DMA_DUMP_POSTRELOC_PUSHBUF
-#define NOUVEAU_DMA_SUBCHAN_LRU
 #define NOUVEAU_DMA_BARRIER 
 #define NOUVEAU_DMA_TIMEOUT 2000
 
        nv->pushbuf = nouveau_pipe_dma_beginp(nv->obj, (mthd), (size));        \
 } while(0)
 
+#define BEGIN_RING_GR(obj,mthd,size) do {                                      \
+       nv->pushbuf = nouveau_pipe_dma_beginp(obj, (mthd), (size));            \
+} while(0)
+
 #define OUT_RING(data) do {                                                    \
        (*nv->pushbuf++) = (data);                                             \
 } while(0)
        nouveau_pipe_dma_kickoff(nv->channel);                                 \
 } while(0)
 
+#define BIND_RING(o,s) do {                                                    \
+       nv->o->subc = (s);                                                     \
+       BEGIN_RING(o, 0x0000, 1);                                              \
+       OUT_RING  (nv->o->handle);                                             \
+} while(0)
+
 #define OUT_RELOC(bo,data,flags,vor,tor) do {                                  \
        nouveau_pushbuf_emit_reloc(nv->channel, nv->pushbuf, (void*)(bo),      \
                                   (data), (flags), (vor), (tor));             \
index e6481a20f2cea8c8d73b7bf4d48e03ca7f3f3a18..f588c956ca983c843a457630f66edd3ae5b7777e 100644 (file)
@@ -20,9 +20,18 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
                         struct nouveau_grobj **grobj)
 {
        struct nouveau_context *nv = nvws->nv;
+       int ret;
 
-       return nouveau_grobj_alloc(nv->channel, nv->next_handle++,
-                                  grclass, grobj);
+       ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++,
+                                 grclass, grobj);
+       if (ret)
+               return ret;
+
+       (*grobj)->subc = nv->next_subchannel++;
+       assert((*grobj)->subc <= 7);
+       BEGIN_RING_GR(*grobj, 0x0000, 1);
+       OUT_RING     ((*grobj)->handle);
+       return 0;
 }
 
 uint32_t *
@@ -34,10 +43,6 @@ nouveau_pipe_dma_beginp(struct nouveau_grobj *grobj, int mthd, int size)
        if (!nvchan->pb_tail || nvchan->pb_tail->remaining < (size + 1))
                nouveau_pushbuf_flush(grobj->channel);
 
-       if (grobj->bound == NOUVEAU_GROBJ_UNBOUND)
-               nouveau_dma_subc_bind(grobj);
-       nvchan->subchannel[grobj->subc].seq = nvchan->subc_sequence++;
-
        pushbuf = nvchan->pb_tail->cur;
        nvchan->pb_tail->cur += (size + 1);
        nvchan->pb_tail->remaining -= (size + 1);
index 67e2514026b42395a72e07b9b8d2a5bf2b066995..b50e744d0d063e6a3f94a3ac0475125bf27c7563 100644 (file)
@@ -178,6 +178,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
                NOUVEAU_ERR("Error creating m2mf object: %d\n", ret);
                return 1;
        }
+       BIND_RING (NvM2MF, nv->next_subchannel++);
        BEGIN_RING(NvM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
        OUT_RING  (nv->sync_notifier->handle);
 
@@ -188,6 +189,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
                NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret);
                return 1;
        }
+       BIND_RING (NvCtxSurf2D, nv->next_subchannel++);
        BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
        OUT_RING  (nv->channel->vram->handle);
        OUT_RING  (nv->channel->vram->handle);
@@ -199,6 +201,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
                NOUVEAU_ERR("Error creating blit object: %d\n", ret);
                return 1;
        }
+       BIND_RING (NvImageBlit, nv->next_subchannel++);
        BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1);
        OUT_RING  (nv->sync_notifier->handle);
        BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_SURFACE, 1);
@@ -212,6 +215,7 @@ nouveau_surface_init_nv04(struct nouveau_context *nv)
                NOUVEAU_ERR("Error creating rect object: %d\n", ret);
                return 1;
        }
+       BIND_RING (NvGdiRect, nv->next_subchannel++);
        BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
        OUT_RING  (nv->sync_notifier->handle);
        BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
index 2a95b1fcd36cfa10e3014bfba1b5651205393b80..d00378d904574db3c34ba175a4fba005f5decdea 100644 (file)
@@ -151,7 +151,7 @@ nouveau_surface_init_nv50(struct nouveau_context *nv)
                                  &nv->Nv2D);
        if (ret)
                return ret;
-
+       BIND_RING (Nv2D, 0);
        BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1);
        OUT_RING  (nv->sync_notifier->handle);
        BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);
index a36db7f3bc471bb16aca392748bd1897be479469..8f5abf905146cbeef4b2b50750bd39c62e62b24f 100644 (file)
@@ -29,12 +29,6 @@ struct nouveau_grobj {
        struct nouveau_channel *channel;
        int grclass;
        uint32_t handle;
-
-       enum {
-               NOUVEAU_GROBJ_UNBOUND = 0,
-               NOUVEAU_GROBJ_BOUND = 1,
-               NOUVEAU_GROBJ_EXPLICIT_BIND = 2,
-       } bound;
        int subc;
 };