nv50: move 2d blit/fill code into pipe driver
authorBen Skeggs <skeggsb@gmail.com>
Thu, 5 Feb 2009 04:04:45 +0000 (14:04 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Thu, 5 Feb 2009 04:04:45 +0000 (14:04 +1000)
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/winsys/drm/nouveau/common/Makefile
src/gallium/winsys/drm/nouveau/common/nouveau_context.c
src/gallium/winsys/drm/nouveau/common/nouveau_context.h
src/gallium/winsys/drm/nouveau/common/nv50_surface.c [deleted file]
src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c

index 6cddddacd5be809408176fa7e45300d1b7a039be..58d7a621a8045cb8c5d5e25d425126466b79a9ce 100644 (file)
@@ -173,6 +173,14 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
                return NULL;
        screen->nvws = nvws;
 
+       /* 2D object */
+       ret = nvws->grobj_alloc(nvws, NV50_2D, &screen->eng2d);
+       if (ret) {
+               NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
+               nv50_screen_destroy(&screen->pipe);
+               return NULL;
+       }
+
        /* 3D object */
        if ((chipset & 0xf0) != 0x50 && (chipset & 0xf0) != 0x80) {
                NOUVEAU_ERR("Not a G8x chipset\n");
@@ -218,6 +226,22 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
                return NULL;
        }
 
+       /* Static 2D init */
+       so = so_new(64, 0);
+       so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
+       so_data  (so, screen->sync->handle);
+       so_data  (so, screen->nvws->channel->vram->handle);
+       so_data  (so, screen->nvws->channel->vram->handle);
+       so_data  (so, screen->nvws->channel->vram->handle);
+       so_method(so, screen->eng2d, NV50_2D_OPERATION, 1);
+       so_data  (so, NV50_2D_OPERATION_SRCCOPY);
+       so_method(so, screen->eng2d, 0x0290, 1);
+       so_data  (so, 0);
+       so_method(so, screen->eng2d, 0x0888, 1);
+       so_data  (so, 1);
+       so_emit(nvws, so);
+       so_ref(NULL, &so);
+
        /* Static tesla init */
        so = so_new(256, 20);
 
index 400ddcef06d86355bcd07c39e95cdccababfe59b..c888ca071c8d621fbccea8d5d7055092df35e064 100644 (file)
@@ -11,6 +11,7 @@ struct nv50_screen {
        unsigned cur_pctx;
 
        struct nouveau_grobj *tesla;
+       struct nouveau_grobj *eng2d;
        struct nouveau_notifier *sync;
 
        struct pipe_buffer *constbuf;
index 8ebbc84817e1b3ce2a88e5d85e799f758fe60e75..b3c04505cfbe0a172c9ee0b82ba7fc1dc94df2dd 100644 (file)
@@ -20,6 +20,9 @@
  * SOFTWARE.
  */
 
+#define __NOUVEAU_PUSH_H__
+#include <stdint.h>
+#include "nouveau/nouveau_pushbuf.h"
 #include "nv50_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/internal/p_winsys_screen.h"
 
 #include "util/u_tile.h"
 
+static INLINE int
+nv50_format(enum pipe_format format)
+{
+       switch (format) {
+       case PIPE_FORMAT_A8R8G8B8_UNORM:
+       case PIPE_FORMAT_Z24S8_UNORM:
+               return NV50_2D_DST_FORMAT_32BPP;
+       case PIPE_FORMAT_X8R8G8B8_UNORM:
+               return NV50_2D_DST_FORMAT_24BPP;
+       case PIPE_FORMAT_R5G6B5_UNORM:
+               return NV50_2D_DST_FORMAT_16BPP;
+       case PIPE_FORMAT_A8_UNORM:
+               return NV50_2D_DST_FORMAT_8BPP;
+       default:
+               return -1;
+       }
+}
+
+static int
+nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
+{
+       struct nouveau_channel *chan = screen->nvws->channel;
+       struct nouveau_grobj *eng2d = screen->eng2d;
+       struct nouveau_bo *bo;
+       int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
+       int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
+       bo = screen->nvws->get_bo(nv50_miptree(ps->texture)->buffer);
+       if (!bo)
+               return 1;
+
+       format = nv50_format(ps->format);
+       if (format < 0)
+               return 1;
+  
+       if (!bo->tiled) {
+               BEGIN_RING(chan, eng2d, mthd, 2);
+               OUT_RING  (chan, format);
+               OUT_RING  (chan, 1);
+               BEGIN_RING(chan, eng2d, mthd + 0x14, 5);
+               OUT_RING  (chan, ps->stride);
+               OUT_RING  (chan, ps->width);
+               OUT_RING  (chan, ps->height);
+               OUT_RELOCh(chan, bo, ps->offset, flags);
+               OUT_RELOCl(chan, bo, ps->offset, flags);
+       } else {
+               BEGIN_RING(chan, eng2d, mthd, 5);
+               OUT_RING  (chan, format);
+               OUT_RING  (chan, 0);
+               OUT_RING  (chan, 0);
+               OUT_RING  (chan, 1);
+               OUT_RING  (chan, 0);
+               BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
+               OUT_RING  (chan, ps->width);
+               OUT_RING  (chan, ps->height);
+               OUT_RELOCh(chan, bo, ps->offset, flags);
+               OUT_RELOCl(chan, bo, ps->offset, flags);
+       }
+#if 0
+       if (dst) {
+               BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+               OUT_RING  (chan, 0);
+               OUT_RING  (chan, 0);
+               OUT_RING  (chan, surf->width);
+               OUT_RING  (chan, surf->height);
+       }
+#endif
+  
+       return 0;
+}
+
+static int
+nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst,
+                    int dx, int dy, struct pipe_surface *src, int sx, int sy,
+                    int w, int h)
+{
+       struct nouveau_channel *chan = screen->nvws->channel;
+       struct nouveau_grobj *eng2d = screen->eng2d;
+       int ret;
+
+       WAIT_RING (chan, 32);
+
+       ret = nv50_surface_set(screen, dst, 1);
+       if (ret)
+               return ret;
+
+       ret = nv50_surface_set(screen, src, 0);
+       if (ret)
+               return ret;
+
+       BEGIN_RING(chan, eng2d, 0x088c, 1);
+       OUT_RING  (chan, 0);
+       BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4);
+       OUT_RING  (chan, dx);
+       OUT_RING  (chan, dy);
+       OUT_RING  (chan, w);
+       OUT_RING  (chan, h);
+       BEGIN_RING(chan, eng2d, 0x08c0, 4);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, 1);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, 1);
+       BEGIN_RING(chan, eng2d, 0x08d0, 4);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, sx);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, sy);
+
+       return 0;
+}
+
 static void
 nv50_surface_copy(struct pipe_context *pipe, boolean flip,
                  struct pipe_surface *dest, unsigned destx, unsigned desty,
@@ -34,17 +149,19 @@ nv50_surface_copy(struct pipe_context *pipe, boolean flip,
                  unsigned width, unsigned height)
 {
        struct nv50_context *nv50 = (struct nv50_context *)pipe;
-       struct nouveau_winsys *nvws = nv50->screen->nvws;
+       struct nv50_screen *screen = nv50->screen;
+
+       assert(src->format == dest->format);
 
        if (flip) {
                desty += height;
                while (height--) {
-                       nvws->surface_copy(nvws, dest, destx, desty--, src,
-                                          srcx, srcy++, width, 1);
+                       nv50_surface_do_copy(screen, dest, destx, desty--, src,
+                                            srcx, srcy++, width, 1);
                }
        } else {
-               nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy,
-                                  width, height);
+               nv50_surface_do_copy(screen, dest, destx, desty, src, srcx,
+                                    srcy, width, height);
        }
 }
 
@@ -54,9 +171,30 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
                  unsigned height, unsigned value)
 {
        struct nv50_context *nv50 = (struct nv50_context *)pipe;
-       struct nouveau_winsys *nvws = nv50->screen->nvws;
+       struct nv50_screen *screen = nv50->screen;
+       struct nouveau_channel *chan = screen->nvws->channel;
+       struct nouveau_grobj *eng2d = screen->eng2d;
+       int format, ret;
+
+       format = nv50_format(dest->format);
+       if (format < 0)
+               return;
+
+       WAIT_RING (chan, 32);
+
+       ret = nv50_surface_set(screen, dest, 1);
+       if (ret)
+               return;
 
-       nvws->surface_fill(nvws, dest, destx, desty, width, height, value);
+       BEGIN_RING(chan, eng2d, 0x0580, 3);
+       OUT_RING  (chan, 4);
+       OUT_RING  (chan, format);
+       OUT_RING  (chan, value);
+       BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4);
+       OUT_RING  (chan, destx);
+       OUT_RING  (chan, desty);
+       OUT_RING  (chan, width);
+       OUT_RING  (chan, height);
 }
 
 static void *
index 9bc5c42585925ad69ebbcdfc29a8d6f34acf003d..4cd315e28958e32ff1808579962701fb98dd7b64 100644 (file)
@@ -10,8 +10,7 @@ C_SOURCES = \
        nouveau_winsys.c \
        nouveau_winsys_pipe.c \
        nouveau_winsys_softpipe.c \
-       nv04_surface.c \
-       nv50_surface.c
+       nv04_surface.c
 
 
 include ./Makefile.template
index 70f005b8880eb157805526038e70dfe0f2e8d0d3..7be3e94d492186f4e07fac356a13b6c6154273a5 100644 (file)
@@ -56,7 +56,7 @@ nouveau_channel_context_create(struct nouveau_device *dev)
        case 0x50:
        case 0x80:
        case 0x90:
-               ret = nouveau_surface_channel_create_nv50(nvc);
+               /* pipe driver does this */
                break;
        default:
                ret = nouveau_surface_channel_create_nv04(nvc);
@@ -168,8 +168,7 @@ nouveau_context_init(struct nouveau_screen *nv_screen,
        case 0x50:
        case 0x80:
        case 0x90:
-               if (nouveau_surface_init_nv50(nv))
-                       return 1;
+               /* pipe driver does this */
                break;
        default:
                if (nouveau_surface_init_nv04(nv))
index 6f6bdafe6bbb4e3569ebf2ba313c27667361f40d..66883e85fec859a8a5b1dcfbaa5194226edad9fe 100644 (file)
@@ -78,10 +78,7 @@ 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 *);
 
 extern uint32_t *nouveau_pipe_dma_beginp(struct nouveau_grobj *, int, int);
 extern void nouveau_pipe_dma_kickoff(struct nouveau_channel *);
diff --git a/src/gallium/winsys/drm/nouveau/common/nv50_surface.c b/src/gallium/winsys/drm/nouveau/common/nv50_surface.c
deleted file mode 100644 (file)
index 540240c..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_format.h"
-
-#include "nouveau_context.h"
-
-static INLINE int
-nv50_format(enum pipe_format format)
-{
-       switch (format) {
-       case PIPE_FORMAT_A8R8G8B8_UNORM:
-       case PIPE_FORMAT_Z24S8_UNORM:
-               return NV50_2D_DST_FORMAT_32BPP;
-       case PIPE_FORMAT_X8R8G8B8_UNORM:
-               return NV50_2D_DST_FORMAT_24BPP;
-       case PIPE_FORMAT_R5G6B5_UNORM:
-               return NV50_2D_DST_FORMAT_16BPP;
-       case PIPE_FORMAT_A8_UNORM:
-               return NV50_2D_DST_FORMAT_8BPP;
-       default:
-               return -1;
-       }
-}
-
-static int
-nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst)
-{
-       struct nouveau_channel *chan = nv->nvc->channel;
-       struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
-       struct nouveau_bo *bo = nouveau_buffer(surf)->bo;
-       int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
-       int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
-  
-       surf_format = nv50_format(surf->format);
-       if (surf_format < 0)
-               return 1;
-  
-       if (!bo->tiled) {
-               BEGIN_RING(chan, eng2d, mthd, 2);
-               OUT_RING  (chan, surf_format);
-               OUT_RING  (chan, 1);
-               BEGIN_RING(chan, eng2d, mthd + 0x14, 5);
-               OUT_RING  (chan, surf->stride);
-               OUT_RING  (chan, surf->width);
-               OUT_RING  (chan, surf->height);
-               OUT_RELOCh(chan, bo, surf->offset, flags);
-               OUT_RELOCl(chan, bo, surf->offset, flags);
-       } else {
-               BEGIN_RING(chan, eng2d, mthd, 5);
-               OUT_RING  (chan, surf_format);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, 1);
-               OUT_RING  (chan, 0);
-               BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
-               OUT_RING  (chan, surf->width);
-               OUT_RING  (chan, surf->height);
-               OUT_RELOCh(chan, bo, surf->offset, flags);
-               OUT_RELOCl(chan, bo, surf->offset, flags);
-       }
-#if 0
-       if (dst) {
-               BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, 0);
-               OUT_RING  (chan, surf->width);
-               OUT_RING  (chan, surf->height);
-       }
-#endif
-  
-       return 0;
-}
-
-static int
-nv50_surface_copy_prep(struct nouveau_context *nv,
-                      struct pipe_surface *dst, struct pipe_surface *src)
-{
-       int ret;
-
-       assert(src->format == dst->format);
-
-       ret = nv50_surface_set(nv, dst, 1);
-       if (ret)
-               return ret;
-
-       ret = nv50_surface_set(nv, src, 0);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static void
-nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
-                 unsigned sx, unsigned sy, unsigned w, unsigned h)
-{
-       struct nouveau_channel *chan = nv->nvc->channel;
-       struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
-
-       BEGIN_RING(chan, eng2d, 0x088c, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4);
-       OUT_RING  (chan, dx);
-       OUT_RING  (chan, dy);
-       OUT_RING  (chan, w);
-       OUT_RING  (chan, h);
-       BEGIN_RING(chan, eng2d, 0x08c0, 4);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, 1);
-       OUT_RING  (chan, 0);
-       OUT_RING  (chan, 1);
-       BEGIN_RING(chan, eng2d, 0x08d0, 4);
-       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(nv->nvc->channel);
-}
-
-static int
-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 rect_format, ret;
-
-       rect_format = nv50_format(dst->format);
-       if (rect_format < 0)
-               return 1;
-
-       ret = nv50_surface_set(nv, dst, 1);
-       if (ret)
-               return ret;
-
-       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_channel_create_nv50(struct nouveau_channel_context *nvc)
-{
-       struct nouveau_channel *chan = nvc->channel;
-       struct nouveau_grobj *eng2d = NULL;
-       int ret;
-
-       ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d);
-       if (ret)
-               return ret;
-       nvc->Nv2D = eng2d;
-
-       BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4);
-       OUT_RING  (chan, nvc->sync_notifier->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       OUT_RING  (chan, chan->vram->handle);
-       BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1);
-       OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
-       BEGIN_RING(chan, eng2d, 0x0290, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, eng2d, 0x0888, 1);
-       OUT_RING  (chan, 1);
-
-       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;
-       nv->surface_fill = nv50_surface_fill;
-       return 0;
-}
-
index e111eec9327a23362d0396fabb9916bc25afc0ac..450c981ca44f60161ec7b67d861cdcb5c803dedd 100644 (file)
@@ -28,18 +28,36 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
        pbox = dPriv->pClipRects;
        nbox = dPriv->numClipRects;
 
-       nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf);
-       for (i = 0; i < nbox; i++, pbox++) {
-               int sx, sy, dx, dy, w, h;
-
-               sx = pbox->x1 - dPriv->x;
-               sy = pbox->y1 - dPriv->y;
-               dx = pbox->x1;
-               dy = pbox->y1;
-               w  = pbox->x2 - pbox->x1;
-               h  = pbox->y2 - pbox->y1;
-
-               nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h);
+       if (nv->base.surface_copy_prep) {
+               nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf);
+               for (i = 0; i < nbox; i++, pbox++) {
+                       int sx, sy, dx, dy, w, h;
+
+                       sx = pbox->x1 - dPriv->x;
+                       sy = pbox->y1 - dPriv->y;
+                       dx = pbox->x1;
+                       dy = pbox->y1;
+                       w  = pbox->x2 - pbox->x1;
+                       h  = pbox->y2 - pbox->y1;
+
+                       nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h);
+               }
+       } else {
+               struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id];
+
+               for (i = 0; i < nbox; i++, pbox++) {
+                       int sx, sy, dx, dy, w, h;
+
+                       sx = pbox->x1 - dPriv->x;
+                       sy = pbox->y1 - dPriv->y;
+                       dx = pbox->x1;
+                       dy = pbox->y1;
+                       w  = pbox->x2 - pbox->x1;
+                       h  = pbox->y2 - pbox->y1;
+
+                       pipe->surface_copy(pipe, FALSE, nv->base.frontbuffer,
+                                          dx, dy, surf, sx, sy, w, h);
+               }
        }
 
        FIRE_RING(nv->base.nvc->channel);