nouveau: turn pushbuf macros into inline functions
authorBen Skeggs <skeggsb@gmail.com>
Sun, 2 Mar 2008 03:09:57 +0000 (14:09 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Sun, 2 Mar 2008 03:09:57 +0000 (14:09 +1100)
src/gallium/winsys/dri/nouveau/nouveau_context.c
src/gallium/winsys/dri/nouveau/nouveau_context.h
src/gallium/winsys/dri/nouveau/nouveau_local.h
src/gallium/winsys/dri/nouveau/nouveau_swapbuffers.c
src/gallium/winsys/dri/nouveau/nouveau_winsys.c
src/gallium/winsys/dri/nouveau/nv04_surface.c
src/gallium/winsys/dri/nouveau/nv50_surface.c

index 01fada5b89b282851e79c247d90343171e479a58..7915afae226025b735d940c1e91c1077c6f0daca 100644 (file)
@@ -21,6 +21,75 @@ static const struct dri_debug_control debug_control[] = {
 int __nouveau_debug = 0;
 #endif
 
+static void
+nouveau_channel_context_destroy(struct nouveau_channel_context *nvc)
+{
+       nouveau_grobj_free(&nvc->NvNull);
+       nouveau_grobj_free(&nvc->NvCtxSurf2D);
+       nouveau_grobj_free(&nvc->NvImageBlit);
+       nouveau_grobj_free(&nvc->NvGdiRect);
+       nouveau_grobj_free(&nvc->NvM2MF);
+       nouveau_grobj_free(&nvc->Nv2D);
+
+       nouveau_notifier_free(&nvc->sync_notifier);
+
+       nouveau_channel_free(&nvc->channel);
+
+       FREE(nvc);
+}
+
+static struct nouveau_channel_context *
+nouveau_channel_context_create(struct nouveau_device *nvdev, unsigned chipset)
+{
+       struct nouveau_channel_context *nvc;
+       int ret;
+
+       nvc = CALLOC_STRUCT(nouveau_channel_context);
+       if (!nvc)
+               return NULL;
+       nvc->chipset = chipset;
+
+       if ((ret = nouveau_channel_alloc(nvdev, 0x8003d001, 0x8003d002,
+                                        &nvc->channel))) {
+               NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
+               nouveau_channel_context_destroy(nvc);
+               return NULL;
+       }
+
+       if ((ret = nouveau_grobj_alloc(nvc->channel, 0x00000000, 0x30,
+                                      &nvc->NvNull))) {
+               NOUVEAU_ERR("Error creating NULL object: %d\n", ret);
+               nouveau_channel_context_destroy(nvc);
+               return NULL;
+       }
+       nvc->next_handle = 0x80000000;
+
+       if ((ret = nouveau_notifier_alloc(nvc->channel, nvc->next_handle++, 1,
+                                         &nvc->sync_notifier))) {
+               NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret);
+               nouveau_channel_context_destroy(nvc);
+               return NULL;
+       }
+
+       switch (chipset) {
+       case 0x50:
+       case 0x80:
+               ret = nouveau_surface_channel_create_nv50(nvc);
+               break;
+       default:
+               ret = nouveau_surface_channel_create_nv04(nvc);
+               break;
+       }
+
+       if (ret) {
+               NOUVEAU_ERR("Error initialising surface objects: %d\n", ret);
+               nouveau_channel_context_destroy(nvc);
+               return NULL;
+       }
+
+       return nvc;
+}
+
 GLboolean
 nouveau_context_create(const __GLcontextModes *glVis,
                       __DRIcontextPrivate *driContextPriv,
@@ -45,13 +114,6 @@ nouveau_context_create(const __GLcontextModes *glVis,
                return GL_FALSE;
        }
 
-       if ((ret = nouveau_channel_alloc(nv_screen->device,
-                                        0x8003d001, 0x8003d002,
-                                        &nv->channel))) {
-               NOUVEAU_ERR("Error creating GPU channel: %d\n", ret);
-               return GL_FALSE;
-       }
-
        driContextPriv->driverPrivate = (void *)nv;
        nv->nv_screen  = nv_screen;
        nv->dri_screen = driScrnPriv;
@@ -101,16 +163,9 @@ nouveau_context_create(const __GLcontextModes *glVis,
                nv->frontbuffer = fb_surf;
        }
 
-       if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30,
-                                      &nv->NvNull))) {
-               NOUVEAU_ERR("Error creating NULL object: %d\n", ret);
-               return GL_FALSE;
-       }
-       nv->next_handle = 0x80000000;
-
-       if ((ret = nouveau_notifier_alloc(nv->channel, nv->next_handle++, 1,
-                                         &nv->sync_notifier))) {
-               NOUVEAU_ERR("Error creating channel sync notifier: %d\n", ret);
+       nv->nvc = nouveau_channel_context_create(&nvdev->base, nv->chipset);
+       if (!nv->nvc) {
+               NOUVEAU_ERR("Failed initialising GPU channel context\n");
                return GL_FALSE;
        }
 
@@ -152,9 +207,7 @@ nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
        st_flush(nv->st, PIPE_FLUSH_WAIT);
        st_destroy_context(nv->st);
 
-       nouveau_grobj_free(&nv->NvCtxSurf2D);
-       nouveau_grobj_free(&nv->NvImageBlit);
-       nouveau_channel_free(&nv->channel);
+       nouveau_channel_context_destroy(nv->nvc);
 
        free(nv);
 }
index 5805f969ba831b1c9df65d3789c7d0687600ea2a..736c8d8bef39631d66b845c1fa4af9273ae495e1 100644 (file)
@@ -13,6 +13,25 @@ struct nouveau_framebuffer {
        struct st_framebuffer *stfb;
 };
 
+struct nouveau_channel_context {
+       unsigned chipset;
+
+       struct nouveau_channel  *channel;
+
+       struct nouveau_notifier *sync_notifier;
+
+       struct nouveau_grobj    *NvNull;
+       struct nouveau_grobj    *NvCtxSurf2D;
+       struct nouveau_grobj    *NvImageBlit;
+       struct nouveau_grobj    *NvGdiRect;
+       struct nouveau_grobj    *NvM2MF;
+       struct nouveau_grobj    *Nv2D;
+
+       uint32_t                 next_handle;
+       uint32_t                 next_subchannel;
+       uint32_t                 next_sequence;
+};
+
 struct nouveau_context {
        struct st_context *st;
 
@@ -31,17 +50,7 @@ struct nouveau_context {
        struct pipe_surface *frontbuffer;
 
        /* Hardware context */
-       struct nouveau_channel  *channel;
-       struct nouveau_notifier *sync_notifier;
-       struct nouveau_grobj    *NvNull;
-       struct nouveau_grobj    *NvCtxSurf2D;
-       struct nouveau_grobj    *NvImageBlit;
-       struct nouveau_grobj    *NvGdiRect;
-       struct nouveau_grobj    *NvM2MF;
-       struct nouveau_grobj    *Nv2D;
-       uint32_t                 next_handle;
-       uint32_t                 next_subchannel;
-       uint32_t                 next_sequence;
+       struct nouveau_channel_context *nvc;
 
        /* pipe_surface accel */
        struct pipe_surface *surf_src, *surf_dst;
@@ -80,6 +89,10 @@ extern int __nouveau_debug;
 extern void LOCK_HARDWARE(struct nouveau_context *);
 extern void UNLOCK_HARDWARE(struct nouveau_context *);
 
+extern int
+nouveau_surface_channel_create_nv04(struct nouveau_channel_context *);
+extern int
+nouveau_surface_channel_create_nv50(struct nouveau_channel_context *);
 extern int nouveau_surface_init_nv04(struct nouveau_context *);
 extern int nouveau_surface_init_nv50(struct nouveau_context *);
 
index 59febca2929af70208311ae69b5f2f719a5e6d93..f7d91fc74876e3c28ca76e8b440592ce599fb6f3 100644 (file)
@@ -1,8 +1,11 @@
 #ifndef __NOUVEAU_LOCAL_H__
 #define __NOUVEAU_LOCAL_H__
 
+#include "pipe/p_compiler.h"
 #include <stdio.h>
 
+struct pipe_buffer;
+
 /* Debug output */
 #define NOUVEAU_MSG(fmt, args...) do {                                         \
        fprintf(stdout, "nouveau: "fmt, ##args);                               \
 #define NOUVEAU_DMA_TIMEOUT 2000
 
 /* Push buffer access macros */
-#define OUT_RING(data) do {                                                    \
-       (*nv->channel->pushbuf->cur++) = (data);                               \
-} while(0)
-
-#define OUT_RINGp(src,size) do {                                               \
-       memcpy(nv->channel->pushbuf->cur, (src), (size)<<2);                   \
-       nv->channel->pushbuf->cur += (size);                                   \
-} while(0)
-
-#define OUT_RINGf(data) do {                                                   \
-       union { float v; uint32_t u; } c;                                      \
-       c.v = (data);                                                          \
-       OUT_RING(c.u);                                                         \
-} while(0)
-
-#define FIRE_RING() do {                                                       \
-       nouveau_pushbuf_flush(nv->channel, 0);                                 \
-} while(0)
-
-#define BEGIN_RING_GR(obj,mthd,size) do {                                      \
-       if (nv->channel->pushbuf->remaining < ((size) + 1))                    \
-               nouveau_pushbuf_flush(nv->channel, ((size) + 1));              \
-       OUT_RING(((obj)->subc << 13) | ((size) << 18) | (mthd));               \
-       nv->channel->pushbuf->remaining -= ((size) + 1);                       \
-} while(0)
-
-#define BEGIN_RING(obj,mthd,size) do {                                         \
-       BEGIN_RING_GR(nv->obj, (mthd), (size));                                \
-} 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(buf,data,flags,vor,tor) do {                                 \
-       nouveau_pipe_emit_reloc(nv->channel, nv->channel->pushbuf->cur++,      \
-                                  buf, (data), (flags), (vor), (tor));        \
-} while(0)
+static INLINE void
+OUT_RING(struct nouveau_channel *chan, unsigned data)
+{
+       *(chan->pushbuf->cur++) = (data);
+}
+
+static INLINE void
+OUT_RINGp(struct nouveau_channel *chan, uint32_t *data, unsigned size)
+{
+       memcpy(chan->pushbuf->cur, data, size * 4);
+       chan->pushbuf->cur += size;
+}
+
+static INLINE void
+OUT_RINGf(struct nouveau_channel *chan, float f)
+{
+       union { uint32_t i; float f; } c;
+       c.f = f;
+       OUT_RING(chan, c.i);
+}
+
+static INLINE void
+BEGIN_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr,
+          unsigned mthd, unsigned size)
+{
+       if (chan->pushbuf->remaining < (size + 1))
+               nouveau_pushbuf_flush(chan, (size + 1));
+       OUT_RING(chan, (gr->subc << 13) | (size << 18) | mthd);
+       chan->pushbuf->remaining -= (size + 1);
+}
+
+static INLINE void
+FIRE_RING(struct nouveau_channel *chan)
+{
+       nouveau_pushbuf_flush(chan, 0);
+}
+
+static INLINE void
+BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned subc)
+{
+       gr->subc = subc;
+       BEGIN_RING(chan, gr, 0x0000, 1);
+       OUT_RING  (chan, gr->handle);
+}
+
+static INLINE void
+OUT_RELOC(struct nouveau_channel *chan, struct pipe_buffer *buf,
+         unsigned data, unsigned flags, unsigned vor, unsigned tor)
+{
+       nouveau_pipe_emit_reloc(chan, chan->pushbuf->cur++, buf,
+                               data, flags, vor, tor);
+}
 
 /* Raw data + flags depending on FB/TT buffer */
-#define OUT_RELOCd(bo,data,flags,vor,tor) do {                                 \
-       OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor));        \
-} while(0)
+static INLINE void
+OUT_RELOCd(struct nouveau_channel *chan, struct pipe_buffer *buf,
+          unsigned data, unsigned flags, unsigned vor, unsigned tor)
+{
+       OUT_RELOC(chan, buf, data, flags | NOUVEAU_BO_OR, vor, tor);
+}
 
 /* FB/TT object handle */
-#define OUT_RELOCo(bo,flags) do {                                              \
-       OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR,                            \
-                 nv->channel->vram->handle, nv->channel->gart->handle);       \
-} while(0)
+static INLINE void
+OUT_RELOCo(struct nouveau_channel *chan, struct pipe_buffer *buf,
+          unsigned flags)
+{
+       OUT_RELOC(chan, buf, 0, flags | NOUVEAU_BO_OR,
+                 chan->vram->handle, chan->gart->handle);
+}
 
 /* Low 32-bits of offset */
-#define OUT_RELOCl(bo,delta,flags) do {                                        \
-       OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0);              \
-} while(0)
+static INLINE void
+OUT_RELOCl(struct nouveau_channel *chan, struct pipe_buffer *buf,
+          unsigned delta, unsigned flags)
+{
+       OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_LOW, 0, 0);
+}
 
 /* High 32-bits of offset */
-#define OUT_RELOCh(bo,delta,flags) do {                                        \
-       OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0);             \
-} while(0)
+static INLINE void
+OUT_RELOCh(struct nouveau_channel *chan, struct pipe_buffer *buf,
+          unsigned delta, unsigned flags)
+{
+       OUT_RELOC(chan, buf, delta, flags | NOUVEAU_BO_HIGH, 0, 0);
+}
 
 #endif
index 91bf243f424bcd12041999875b09f905d0a02f82..70e0104e83b930d0afcc13205803c8da44dd3a85 100644 (file)
@@ -42,7 +42,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
                nv->surface_copy(nv, dx, dy, sx, sy, w, h);
        }
 
-       FIRE_RING();
+       FIRE_RING(nv->nvc->channel);
        UNLOCK_HARDWARE(nv);
 
        if (nv->last_stamp != dPriv->lastStamp) {
index 529f57718124bec5ddaee9faf12ab1812c89256c..50d7549b1b751d964e3d261a1e9b6e856f721292 100644 (file)
@@ -11,7 +11,7 @@ nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count,
 {
        struct nouveau_context *nv = nvws->nv;
 
-       return nouveau_notifier_alloc(nv->channel, nv->next_handle++,
+       return nouveau_notifier_alloc(nv->nvc->channel, nv->nvc->next_handle++,
                                      count, notify);
 }
 
@@ -20,17 +20,16 @@ nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
                         struct nouveau_grobj **grobj)
 {
        struct nouveau_context *nv = nvws->nv;
+       struct nouveau_channel *chan = nv->nvc->channel;
        int ret;
 
-       ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++,
+       ret = nouveau_grobj_alloc(chan, nv->nvc->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);
+       assert(nv->nvc->next_subchannel < 7);
+       BIND_RING(chan, *grobj, nv->nvc->next_subchannel++);
        return 0;
 }
 
@@ -103,7 +102,7 @@ nouveau_pipe_create(struct nouveau_context *nv)
        }
 
        nvws->nv                = nv;
-       nvws->channel           = nv->channel;
+       nvws->channel           = nv->nvc->channel;
 
        nvws->res_init          = nouveau_resource_init;
        nvws->res_alloc         = nouveau_resource_alloc;
index fe1ea4ed70f20296764560fe6d8f4a8c6db432ba..cdcd71eaad6fa950fec4d3f104c8005846c4ff98 100644 (file)
@@ -30,6 +30,7 @@ static void
 nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy,
                       unsigned sx, unsigned sy, unsigned w, unsigned h)
 {
+       struct nouveau_channel *chan = nv->nvc->channel;
        struct pipe_surface *dst = nv->surf_dst;
        struct pipe_surface *src = nv->surf_src;
        unsigned dst_offset, src_offset;
@@ -40,17 +41,18 @@ nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy,
        while (h) {
                int count = (h > 2047) ? 2047 : h;
 
-               BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
-               OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM |
+               BEGIN_RING(chan, nv->nvc->NvM2MF,
+                          NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+               OUT_RELOCl(chan, src->buffer, src_offset, NOUVEAU_BO_VRAM |
                           NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-               OUT_RELOCl(dst->buffer, dst_offset, NOUVEAU_BO_VRAM |
+               OUT_RELOCl(chan, dst->buffer, dst_offset, NOUVEAU_BO_VRAM |
                           NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-               OUT_RING  (src->pitch * src->cpp);
-               OUT_RING  (dst->pitch * dst->cpp);
-               OUT_RING  (w * src->cpp);
-               OUT_RING  (count);
-               OUT_RING  (0x0101);
-               OUT_RING  (0);
+               OUT_RING  (chan, src->pitch * src->cpp);
+               OUT_RING  (chan, dst->pitch * dst->cpp);
+               OUT_RING  (chan, w * src->cpp);
+               OUT_RING  (chan, count);
+               OUT_RING  (chan, 0x0101);
+               OUT_RING  (chan, 0);
 
                h -= count;
                src_offset += src->pitch * src->cpp * count;
@@ -62,16 +64,19 @@ static void
 nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy,
                       unsigned sx, unsigned sy, unsigned w, unsigned h)
 {
-       BEGIN_RING(NvImageBlit, 0x0300, 3);
-       OUT_RING  ((sy << 16) | sx);
-       OUT_RING  ((dy << 16) | dx);
-       OUT_RING  (( h << 16) |  w);
+       struct nouveau_channel *chan = nv->nvc->channel;
+
+       BEGIN_RING(chan, nv->nvc->NvImageBlit, 0x0300, 3);
+       OUT_RING  (chan, (sy << 16) | sx);
+       OUT_RING  (chan, (dy << 16) | dx);
+       OUT_RING  (chan, ( h << 16) |  w);
 }
 
 static int
 nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
                       struct pipe_surface *src)
 {
+       struct nouveau_channel *chan = nv->nvc->channel;
        int format;
 
        if (src->cpp != dst->cpp)
@@ -81,12 +86,12 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
         * to NV_MEMORY_TO_MEMORY_FORMAT in this case.
         */
        if ((src->offset & 63) || (dst->offset & 63)) {
-               BEGIN_RING(NvM2MF,
+               BEGIN_RING(nv->nvc->channel, nv->nvc->NvM2MF,
                           NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
-               OUT_RELOCo(src->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM |
-                          NOUVEAU_BO_RD);
-               OUT_RELOCo(dst->buffer, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM |
-                          NOUVEAU_BO_WR);
+               OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_GART |
+                          NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+               OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_GART |
+                          NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
                nv->surface_copy = nv04_surface_copy_m2mf;
                nv->surf_dst = dst;
@@ -101,15 +106,20 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
        }
        nv->surface_copy = nv04_surface_copy_blit;
 
-       BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
-       OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-
-       BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
-       OUT_RING  (format);
-       OUT_RING  (((dst->pitch * dst->cpp) << 16) | (src->pitch * src->cpp));
-       OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       BEGIN_RING(chan, nv->nvc->NvCtxSurf2D,
+                  NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
+       OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+       BEGIN_RING(chan, nv->nvc->NvCtxSurf2D,
+                  NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
+       OUT_RING  (chan, format);
+       OUT_RING  (chan, ((dst->pitch * dst->cpp) << 16) | 
+                         (src->pitch * src->cpp));
+       OUT_RELOCl(chan, src->buffer, src->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       OUT_RELOCl(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
        return 0;
 }
@@ -117,7 +127,7 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
 static void
 nv04_surface_copy_done(struct nouveau_context *nv)
 {
-       FIRE_RING();
+       FIRE_RING(nv->nvc->channel);
 }
 
 static int
@@ -125,6 +135,9 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
                  unsigned dx, unsigned dy, unsigned w, unsigned h,
                  unsigned value)
 {
+       struct nouveau_channel *chan = nv->nvc->channel;
+       struct nouveau_grobj *surf2d = nv->nvc->NvCtxSurf2D;
+       struct nouveau_grobj *rect = nv->nvc->NvGdiRect;
        int cs2d_format, gdirect_format;
 
        if ((cs2d_format = nv04_surface_format(dst->cpp)) < 0) {
@@ -137,86 +150,99 @@ nv04_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
                return 1;
        }
 
-       BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
-       OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       BEGIN_RING(NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
-       OUT_RING  (cs2d_format);
-       OUT_RING  (((dst->pitch * dst->cpp) << 16) | (dst->pitch * dst->cpp));
-       OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-
-       BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
-       OUT_RING  (gdirect_format);
-       BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
-       OUT_RING  (value);
-       BEGIN_RING(NvGdiRect,
+       BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
+       OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
+       OUT_RING  (chan, cs2d_format);
+       OUT_RING  (chan, ((dst->pitch * dst->cpp) << 16) |
+                         (dst->pitch * dst->cpp));
+       OUT_RELOCl(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+       BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
+       OUT_RING  (chan, gdirect_format);
+       BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
+       OUT_RING  (chan, value);
+       BEGIN_RING(chan, rect,
                   NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
-       OUT_RING  ((dx << 16) | dy);
-       OUT_RING  (( w << 16) |  h);
+       OUT_RING  (chan, (dx << 16) | dy);
+       OUT_RING  (chan, ( w << 16) |  h);
 
-       FIRE_RING();
+       FIRE_RING(chan);
        return 0;
 }
 
 int
-nouveau_surface_init_nv04(struct nouveau_context *nv)
+nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc)
 {
+       struct nouveau_channel *chan = nvc->channel;
        unsigned class;
        int ret;
 
-       if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, 0x39,
-                                      &nv->NvM2MF))) {
+       if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, 0x39,
+                                      &nvc->NvM2MF))) {
                NOUVEAU_ERR("Error creating m2mf object: %d\n", ret);
                return 1;
        }
-       BIND_RING (NvM2MF, nv->next_subchannel++);
-       BEGIN_RING(NvM2MF, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
-       OUT_RING  (nv->sync_notifier->handle);
-
-       class = nv->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D :
-                                    NV10_CONTEXT_SURFACES_2D;
-       if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class,
-                                      &nv->NvCtxSurf2D))) {
+       BIND_RING (chan, nvc->NvM2MF, nvc->next_subchannel++);
+       BEGIN_RING(chan, nvc->NvM2MF,
+                  NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
+       OUT_RING  (chan, nvc->sync_notifier->handle);
+
+       class = nvc->chipset < 0x10 ? NV04_CONTEXT_SURFACES_2D :
+                                     NV10_CONTEXT_SURFACES_2D;
+       if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class,
+                                      &nvc->NvCtxSurf2D))) {
                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);
-
-       class = nv->chipset < 0x10 ? NV04_IMAGE_BLIT :
-                                    NV12_IMAGE_BLIT;
-       if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class,
-                                      &nv->NvImageBlit))) {
+       BIND_RING (chan, nvc->NvCtxSurf2D, nvc->next_subchannel++);
+       BEGIN_RING(chan, nvc->NvCtxSurf2D,
+                  NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
+       OUT_RING  (chan, nvc->channel->vram->handle);
+       OUT_RING  (chan, nvc->channel->vram->handle);
+
+       class = nvc->chipset < 0x10 ? NV04_IMAGE_BLIT :
+                                     NV12_IMAGE_BLIT;
+       if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class,
+                                      &nvc->NvImageBlit))) {
                NOUVEAU_ERR("Error creating blit object: %d\n", ret);
                return 1;
        }
-       BIND_RING (NvImageBlit, nv->next_subchannel++);
-       BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1);
-       OUT_RING  (nv->sync_notifier->handle);
-       BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1);
-       OUT_RING  (nv->NvCtxSurf2D->handle);
-       BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1);
-       OUT_RING  (NV04_IMAGE_BLIT_OPERATION_SRCCOPY);
+       BIND_RING (chan, nvc->NvImageBlit, nvc->next_subchannel++);
+       BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1);
+       OUT_RING  (chan, nvc->sync_notifier->handle);
+       BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1);
+       OUT_RING  (chan, nvc->NvCtxSurf2D->handle);
+       BEGIN_RING(chan, nvc->NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1);
+       OUT_RING  (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY);
 
        class = NV04_GDI_RECTANGLE_TEXT;
-       if ((ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, class,
-                                      &nv->NvGdiRect))) {
+       if ((ret = nouveau_grobj_alloc(chan, nvc->next_handle++, class,
+                                      &nvc->NvGdiRect))) {
                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);
-       OUT_RING  (nv->NvCtxSurf2D->handle);
-       BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
-       OUT_RING  (NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY);
-       BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
-       OUT_RING  (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
+       BIND_RING (chan, nvc->NvGdiRect, nvc->next_subchannel++);
+       BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
+       OUT_RING  (chan, nvc->sync_notifier->handle);
+       BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
+       OUT_RING  (chan, nvc->NvCtxSurf2D->handle);
+       BEGIN_RING(chan, nvc->NvGdiRect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
+       OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY);
+       BEGIN_RING(chan, nvc->NvGdiRect,
+                  NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
+       OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
 
+       return 0;
+}
+
+int
+nouveau_surface_init_nv04(struct nouveau_context *nv)
+{
        nv->surface_copy_prep = nv04_surface_copy_prep;
        nv->surface_copy = nv04_surface_copy_blit;
        nv->surface_copy_done = nv04_surface_copy_done;
index 15a100286131154d9f32310d3ec24394e592d498..5d74fb8d2bc4c30f20bd128c3f310d42bac47597 100644 (file)
@@ -19,6 +19,8 @@ static int
 nv50_surface_copy_prep(struct nouveau_context *nv,
                       struct pipe_surface *dst, struct pipe_surface *src)
 {
+       struct nouveau_channel *chan = nv->nvc->channel;
+       struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
        int surf_format;
 
        assert(src->cpp == dst->cpp);
@@ -26,34 +28,38 @@ nv50_surface_copy_prep(struct nouveau_context *nv,
        surf_format = nv50_format(dst->cpp);
        assert(surf_format >= 0);
 
-       BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);
-       OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-
-       BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2);
-       OUT_RING  (surf_format);
-       OUT_RING  (1);
-       BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5);
-       OUT_RING  (dst->pitch * dst->cpp);
-       OUT_RING  (dst->pitch);
-       OUT_RING  (dst->height);
-       OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4);
-       OUT_RING  (0);
-       OUT_RING  (0);
-       OUT_RING  (dst->pitch);
-       OUT_RING  (dst->height);
-
-       BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2);
-       OUT_RING  (surf_format);
-       OUT_RING  (1);
-       BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5);
-       OUT_RING  (src->pitch * src->cpp);
-       OUT_RING  (src->pitch);
-       OUT_RING  (src->height);
-       OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2);
+       OUT_RELOCo(chan, src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+       BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
+       OUT_RING  (chan, surf_format);
+       OUT_RING  (chan, 1);
+       BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5);
+       OUT_RING  (chan, dst->pitch * dst->cpp);
+       OUT_RING  (chan, dst->pitch);
+       OUT_RING  (chan, dst->height);
+       OUT_RELOCh(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, dst->pitch);
+       OUT_RING  (chan, dst->height);
+
+       BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2);
+       OUT_RING  (chan, surf_format);
+       OUT_RING  (chan, 1);
+       BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5);
+       OUT_RING  (chan, src->pitch * src->cpp);
+       OUT_RING  (chan, src->pitch);
+       OUT_RING  (chan, src->height);
+       OUT_RELOCh(chan, src->buffer, src->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       OUT_RELOCl(chan, src->buffer, src->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
 
        return 0;
 }
@@ -62,27 +68,30 @@ static void
 nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
                  unsigned sx, unsigned sy, unsigned w, unsigned h)
 {
-       BEGIN_RING(Nv2D, 0x0110, 1);
-       OUT_RING  (0);
-       BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12);
-       OUT_RING  (dx);
-       OUT_RING  (dy);
-       OUT_RING  (w);
-       OUT_RING  (h);
-       OUT_RING  (0);
-       OUT_RING  (1);
-       OUT_RING  (0);
-       OUT_RING  (1);
-       OUT_RING  (0);
-       OUT_RING  (sx);
-       OUT_RING  (0);
-       OUT_RING  (sy);
+       struct nouveau_channel *chan = nv->nvc->channel;
+       struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
+
+       BEGIN_RING(chan, eng2d, 0x0110, 1);
+       OUT_RING  (chan, 0);
+       BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+       OUT_RING  (chan, dx);
+       OUT_RING  (chan, dy);
+       OUT_RING  (chan, w);
+       OUT_RING  (chan, h);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, 1);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, 1);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, sx);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, sy);
 }
 
 static void
 nv50_surface_copy_done(struct nouveau_context *nv)
 {
-       FIRE_RING();
+       FIRE_RING(nv->nvc->channel);
 }
 
 static int
@@ -90,6 +99,8 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
                  unsigned dx, unsigned dy, unsigned w, unsigned h,
                  unsigned value)
 {
+       struct nouveau_channel *chan = nv->nvc->channel;
+       struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
        int surf_format, rect_format;
 
        surf_format = nv50_format(dst->cpp);
@@ -100,57 +111,65 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
        if (rect_format < 0)
                return 1;
 
-       BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1);
-       OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2);
-       OUT_RING  (surf_format);
-       OUT_RING  (1);
-       BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5);
-       OUT_RING  (dst->pitch * dst->cpp);
-       OUT_RING  (dst->pitch);
-       OUT_RING  (dst->height);
-       OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4);
-       OUT_RING  (0);
-       OUT_RING  (0);
-       OUT_RING  (dst->pitch);
-       OUT_RING  (dst->height);
-
-       BEGIN_RING(Nv2D, 0x0580, 3);
-       OUT_RING  (4);
-       OUT_RING  (rect_format);
-       OUT_RING  (value);
-
-       BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4);
-       OUT_RING  (dx);
-       OUT_RING  (dy);
-       OUT_RING  (dx + w);
-       OUT_RING  (dy + h);
-
-       FIRE_RING();
+       BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1);
+       OUT_RELOCo(chan, dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
+       OUT_RING  (chan, surf_format);
+       OUT_RING  (chan, 1);
+       BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5);
+       OUT_RING  (chan, dst->pitch * dst->cpp);
+       OUT_RING  (chan, dst->pitch);
+       OUT_RING  (chan, dst->height);
+       OUT_RELOCh(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(chan, dst->buffer, dst->offset,
+                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, dst->pitch);
+       OUT_RING  (chan, dst->height);
+
+       BEGIN_RING(chan, eng2d, 0x0580, 3);
+       OUT_RING  (chan, 4);
+       OUT_RING  (chan, rect_format);
+       OUT_RING  (chan, value);
+
+       BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4);
+       OUT_RING  (chan, dx);
+       OUT_RING  (chan, dy);
+       OUT_RING  (chan, dx + w);
+       OUT_RING  (chan, dy + h);
+
+       FIRE_RING(chan);
 
        return 0;
 }
 
 int
-nouveau_surface_init_nv50(struct nouveau_context *nv)
+nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc)
 {
        int ret;
 
-       ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D,
-                                 &nv->Nv2D);
+       ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D,
+                                 &nvc->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);
-       OUT_RING  (nv->channel->vram->handle);
-       OUT_RING  (nv->channel->vram->handle);
-       BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1);
-       OUT_RING  (NV50_2D_OPERATION_SRCCOPY);
+       BIND_RING (nvc->channel, nvc->Nv2D, 0);
+       BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1);
+       OUT_RING  (nvc->channel, nvc->sync_notifier->handle);
+       BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);
+       OUT_RING  (nvc->channel, nvc->channel->vram->handle);
+       OUT_RING  (nvc->channel, nvc->channel->vram->handle);
+       BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1);
+       OUT_RING  (nvc->channel, NV50_2D_OPERATION_SRCCOPY);
+
+       return 0;
+}
 
+int
+nouveau_surface_init_nv50(struct nouveau_context *nv)
+{
        nv->surface_copy_prep = nv50_surface_copy_prep;
        nv->surface_copy = nv50_surface_copy;
        nv->surface_copy_done = nv50_surface_copy_done;