nouveau: g8x winsys support, yay softpipe!
authorBen Skeggs <skeggsb@gmail.com>
Wed, 5 Dec 2007 00:57:50 +0000 (11:57 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Wed, 5 Dec 2007 00:57:50 +0000 (11:57 +1100)
16 files changed:
src/mesa/drivers/dri/nouveau_winsys/nouveau_bo.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_context.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_context.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_drmif.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_screen.h
src/mesa/drivers/dri/nouveau_winsys/nouveau_swapbuffers.c
src/mesa/drivers/dri/nouveau_winsys/nouveau_winsys.c
src/mesa/drivers/dri/nouveau_winsys/nv04_region.c
src/mesa/drivers/dri/nouveau_winsys/nv50_region.c
src/mesa/pipe/nouveau/nouveau_winsys.h
src/mesa/pipe/nv40/nv40_fragprog.c
src/mesa/pipe/nv40/nv40_miptree.c
src/mesa/pipe/nv40/nv40_region.c
src/mesa/pipe/nv40/nv40_state_tex.c
src/mesa/pipe/nv40/nv40_vbo.c

index 3b508cf92b3d3c65fa3f1fecdd70bfa078eb3656..f1981b977706460dad59c98e564c144fa40725c5 100644 (file)
 int
 nouveau_bo_init(struct nouveau_device *userdev)
 {
-       struct nouveau_device_priv *nv = nouveau_device(userdev);
-       struct nouveau_channel *chan;
-       int ret;
-
-       if ((ret = nouveau_channel_alloc(userdev, 0x80000001, 0x80000002,
-                                        &nv->bufmgr.channel)))
-               return ret;
-       chan = nv->bufmgr.channel;
-
-       if ((ret = nouveau_notifier_alloc(nv->bufmgr.channel, 0x80000003, 1,
-                                         &nv->bufmgr.notify)))
-               return ret;
-
-       if ((ret = nouveau_grobj_alloc(nv->bufmgr.channel, 0x80000004, 0x39,
-                                      &nv->bufmgr.m2mf)))
-               return ret;
-
-       nouveau_notifier_reset(nv->bufmgr.notify, 0);
-       BEGIN_RING_CH(chan, nv->bufmgr.m2mf, 0x180, 1);
-       OUT_RING_CH  (chan, nv->bufmgr.notify->handle);
-       BEGIN_RING_CH(chan, nv->bufmgr.m2mf, 0x104, 1);
-       OUT_RING_CH  (chan, 0);
-       BEGIN_RING_CH(chan, nv->bufmgr.m2mf, 0x100, 1);
-       OUT_RING_CH  (chan, 0);
-       FIRE_RING_CH (chan);
-       if ((ret = nouveau_notifier_wait_status(nv->bufmgr.notify, 0, 0, 2000)))
-               return ret;
-
        return 0;
 }
 
 void
 nouveau_bo_takedown(struct nouveau_device *userdev)
 {
-       struct nouveau_device_priv *nv = nouveau_device(userdev);
-
-       nouveau_notifier_free(&nv->bufmgr.notify);
-       nouveau_grobj_free(&nv->bufmgr.m2mf);
-       nouveau_channel_free(&nv->bufmgr.channel);
 }
 
 static int
index 67df43647aad798b6730413f786a4d67cf209bcc..70655a1a7d94e7b69e9b25e131c6201d149ae80b 100644 (file)
@@ -125,6 +125,36 @@ nouveau_context_create(const __GLcontextModes *glVis,
                                              debug_control);
 #endif
 
+       /*XXX: Hack up a fake region and buffer object for front buffer.
+        *     This will go away with TTM, replaced with a simple reference
+        *     of the front buffer handle passed to us by the DDX.
+        */
+       {
+               struct pipe_region *fb_region;
+               struct nouveau_bo_priv *fb_bo;
+
+               fb_bo = calloc(1, sizeof(struct nouveau_bo_priv));
+               fb_bo->drm.offset = nv_screen->front_offset;
+               fb_bo->drm.flags = NOUVEAU_MEM_FB;
+               fb_bo->drm.size = nv_screen->front_pitch * 
+                                 nv_screen->front_height;
+               fb_bo->refcount = 1;
+               fb_bo->base.flags = NOUVEAU_BO_PIN | NOUVEAU_BO_VRAM;
+               fb_bo->base.offset = fb_bo->drm.offset;
+               fb_bo->base.handle = (unsigned long)fb_bo;
+               fb_bo->base.size = fb_bo->drm.size;
+               fb_bo->base.device = nv_screen->device;
+
+               fb_region = calloc(1, sizeof(struct pipe_region));
+               fb_region->cpp = nv_screen->front_cpp;
+               fb_region->pitch = nv_screen->front_pitch / fb_region->cpp;
+               fb_region->height = nv_screen->front_height;
+               fb_region->refcount = 1;
+               fb_region->buffer = (void *)fb_bo;
+
+               nv->frontbuffer = fb_region;
+       }
+
        if ((ret = nouveau_grobj_alloc(nv->channel, 0x00000000, 0x30,
                                       &nv->NvNull))) {
                NOUVEAU_ERR("Error creating NULL object: %d\n", ret);
index f2557af935dd08d1cb92cad5e1d5b9605898d169..70110f976832d1dddd6be25645db1e479f026380 100644 (file)
@@ -31,6 +31,7 @@ struct nouveau_context {
        drmLock                drm_lock;
        GLboolean              locked;
        struct nouveau_screen *nv_screen;
+       struct pipe_region *frontbuffer;
 
        /* Bufmgr */
        struct {
@@ -53,14 +54,19 @@ struct nouveau_context {
        struct nouveau_grobj    *NvImageBlit;
        struct nouveau_grobj    *NvGdiRect;
        struct nouveau_grobj    *NvM2MF;
+       struct nouveau_grobj    *Nv2D;
        uint32_t                 next_handle;
        uint32_t                 next_sequence;
 
        /* pipe_region accel */
-       int (*region_display)(void);
-       int (*region_copy)(struct nouveau_context *, struct pipe_region *,
-                          unsigned, unsigned, unsigned, struct pipe_region *,
-                          unsigned, unsigned, unsigned, unsigned, unsigned);
+       struct pipe_region *region_src, *region_dst;
+       unsigned region_src_offset, region_dst_offset;
+       int  (*region_copy_prep)(struct nouveau_context *,
+                                struct pipe_region *dst, uint32_t dst_offset,
+                                struct pipe_region *src, uint32_t src_offset);
+       void (*region_copy)(struct nouveau_context *, unsigned dx, unsigned dy,
+                           unsigned sx, unsigned sy, unsigned w, unsigned h);
+       void (*region_copy_done)(struct nouveau_context *);
        int (*region_fill)(struct nouveau_context *, struct pipe_region *,
                           unsigned, unsigned, unsigned, unsigned, unsigned,
                           unsigned);
index 1a21da698570a0a8c5076232e94cf90e723ad51b..df98890f8e21537988cd2159d8234151b166bc05 100644 (file)
@@ -40,12 +40,6 @@ struct nouveau_device_priv {
        drm_context_t ctx;
        drmLock *lock;
        int needs_close;
-
-       struct {
-               struct nouveau_channel *channel;
-               struct nouveau_notifier *notify;
-               struct nouveau_grobj *m2mf;
-       } bufmgr;
 };
 #define nouveau_device(n) ((struct nouveau_device_priv *)(n))
 
index 16c4324164b2dd7babcb778503ce2f400e5d670d..6554082e62203c68aa106c399544a90f5ca315fb 100644 (file)
@@ -61,6 +61,8 @@ nouveau_screen_create(__DRIscreenPrivate *driScrnPriv)
 
        nv_screen->front_offset = nv_dri->front_offset;
        nv_screen->front_pitch  = nv_dri->front_pitch * (nv_dri->bpp / 8);
+       nv_screen->front_cpp = nv_dri->bpp / 8;
+       nv_screen->front_height = nv_dri->height;
 
        return GL_TRUE;
 }
index e53cd873a7e5e1dd3c454be7a4ac40131d0bd15d..019823bd44d9be39806956963918fae1dceafe00 100644 (file)
@@ -12,6 +12,8 @@ struct nouveau_screen {
 
        uint32_t front_offset;
        uint32_t front_pitch;
+       uint32_t front_cpp;
+       uint32_t front_height;
 };
 
 #endif
index 57598f9cab9564c2b6521a1aa005266ac57b9c5e..5b2e76b942f617c3df0f7989994554e19e11e8dc 100644 (file)
@@ -14,7 +14,6 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
                    const drm_clip_rect_t *rect)
 {
        struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
-       struct nouveau_screen *nv_screen = nv->nv_screen;
        struct pipe_region *p_region = surf->region;
        drm_clip_rect_t *pbox;
        int nbox, i;
@@ -27,17 +26,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
        pbox = dPriv->pClipRects;
        nbox = dPriv->numClipRects;
 
-       BEGIN_RING(NvCtxSurf2D, 0x184, 2);
-       OUT_RELOCo(p_region->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RING  (nv->channel->vram->handle);
-
-       BEGIN_RING(NvCtxSurf2D, 0x300, 4);
-       OUT_RING  ((p_region->cpp == 4) ? 6 : 4);
-       OUT_RING  ((nv_screen->front_pitch << 16) |
-                  (p_region->pitch * p_region->cpp));
-       OUT_RELOCl(p_region->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RING  (nv_screen->front_offset);
-
+       nv->region_copy_prep(nv, nv->frontbuffer, 0, p_region, 0);
        for (i = 0; i < nbox; i++, pbox++) {
                int sx, sy, dx, dy, w, h;
 
@@ -48,10 +37,7 @@ nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
                w  = pbox->x2 - pbox->x1;
                h  = pbox->y2 - pbox->y1;
 
-               BEGIN_RING(NvImageBlit, 0x300, 3);
-               OUT_RING  ((sy << 16) | sx);
-               OUT_RING  ((dy << 16) | dx);
-               OUT_RING  (( h << 16) |  w);
+               nv->region_copy(nv, dx, dy, sx, sy, w, h);
        }
 
        FIRE_RING();
index bdc89b953184f9424d72a7e98c2c53ce497f4d10..6840ec5f7549324e9191a62e22a3fa2adc2b6d96 100644 (file)
@@ -127,6 +127,45 @@ nouveau_pipe_dma_kickoff(struct nouveau_channel *userchan)
        FIRE_RING_CH(userchan);
 }
 
+static int
+nouveau_pipe_region_copy(struct nouveau_winsys *nvws, struct pipe_region *dst,
+                        unsigned dst_offset, unsigned dx, unsigned dy,
+                        struct pipe_region *src, unsigned src_offset,
+                        unsigned sx, unsigned sy, unsigned w, unsigned h)
+{
+       struct nouveau_context *nv = nvws->nv;
+
+       if (nv->region_copy_prep(nv, dst, dst_offset, src, src_offset))
+               return 1;
+       nv->region_copy(nv, dx, dy, sx, sy, w, h);
+       nv->region_copy_done(nv);
+
+       return 0;
+}
+
+static int
+nouveau_pipe_region_fill(struct nouveau_winsys *nvws, struct pipe_region *dst,
+                        unsigned dst_offset, unsigned dx, unsigned dy,
+                        unsigned w, unsigned h, unsigned value)
+{
+       if (nvws->nv->region_fill(nvws->nv, dst, dst_offset, dx, dy,
+                                 w, h, value))
+               return 1;
+       return 0;
+}
+
+static int
+nouveau_pipe_region_data(struct nouveau_winsys *nvws, struct pipe_region *dst,
+                        unsigned dst_offset, unsigned dx, unsigned dy,
+                        const void *src, unsigned src_pitch,
+                        unsigned sx, unsigned sy, unsigned w, unsigned h)
+{
+       if (nvws->nv->region_data(nvws->nv, dst, dst_offset, dx, dy, src,
+                                 src_pitch, sx, sy, w, h))
+               return 1;
+       return 0;
+}
+
 struct pipe_context *
 nouveau_pipe_create(struct nouveau_context *nv)
 {
@@ -168,9 +207,9 @@ nouveau_pipe_create(struct nouveau_context *nv)
        nvws->notifier_retval   = nouveau_notifier_return_val;
        nvws->notifier_wait     = nouveau_notifier_wait_status;
 
-       nvws->region_copy       = nv->region_copy;
-       nvws->region_fill       = nv->region_fill;
-       nvws->region_data       = nv->region_data;
+       nvws->region_copy       = nouveau_pipe_region_copy;
+       nvws->region_fill       = nouveau_pipe_region_fill;
+       nvws->region_data       = nouveau_pipe_region_data;
 
        return hw_create(nouveau_create_pipe_winsys(nv), nvws, nv->chipset);
 }
index 0fdb38e105c694650c5f3cc46bfb4fec5babf7ea..d41588d89077a0ba5a73fbb9c3c3755be52c3b5a 100644 (file)
@@ -26,26 +26,19 @@ nv04_rect_format(int cpp)
        }
 }
 
-static int
-nv04_region_display(void)
-{
-       NOUVEAU_ERR("unimplemented\n");
-       return 0;
-}
-
-static int
-nv04_region_copy_m2mf(struct nouveau_context *nv, struct pipe_region *dst,
-                     unsigned dst_offset, struct pipe_region *src,
-                     unsigned src_offset, unsigned line_len, unsigned height)
+static void
+nv04_region_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy,
+                     unsigned sx, unsigned sy, unsigned w, unsigned h)
 {
-       BEGIN_RING(NvM2MF, NV_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);
+       struct pipe_region *dst = nv->region_dst;
+       struct pipe_region *src = nv->region_dst;
+       unsigned dst_offset, src_offset;
+       
+       dst_offset = nv->region_dst_offset + (dy * dst->pitch + dx) * dst->cpp;
+       src_offset = nv->region_src_offset + (sy * src->pitch + sx) * src->cpp;
 
-       while (height) {
-               int count = (height > 2047) ? 2047 : height;
+       while (h) {
+               int count = (h > 2047) ? 2047 : h;
 
                BEGIN_RING(NvM2MF, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
                OUT_RELOCl(src->buffer, src_offset, NOUVEAU_BO_VRAM |
@@ -54,32 +47,31 @@ nv04_region_copy_m2mf(struct nouveau_context *nv, struct pipe_region *dst,
                           NOUVEAU_BO_GART | NOUVEAU_BO_WR);
                OUT_RING  (src->pitch * src->cpp);
                OUT_RING  (dst->pitch * dst->cpp);
-               OUT_RING  (line_len);
+               OUT_RING  (w * src->cpp);
                OUT_RING  (count);
                OUT_RING  (0x0101);
                OUT_RING  (0);
 
-               height -= count;
+               h -= count;
                src_offset += src->pitch * count;
                dst_offset += dst->pitch * count;
        }
+}
 
-       nouveau_notifier_reset(nv->sync_notifier, 0);
-       BEGIN_RING(NvM2MF, 0x104, 1);
-       OUT_RING  (0);
-       BEGIN_RING(NvM2MF, 0x100, 1);
-       OUT_RING  (0);
-       FIRE_RING();
-       nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000);
-
-       return 0;
+static void
+nv04_region_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);
 }
 
 static int
-nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst,
-                unsigned dst_offset, unsigned dx, unsigned dy,
-                struct pipe_region *src, unsigned src_offset,
-                unsigned sx, unsigned sy, unsigned w, unsigned h)
+nv04_region_copy_prep(struct nouveau_context *nv,
+                     struct pipe_region *dst, unsigned dst_offset,
+                     struct pipe_region *src, unsigned src_offset)
 {
        int format;
 
@@ -90,10 +82,18 @@ nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst,
         * to NV_MEMORY_TO_MEMORY_FORMAT in this case.
         */
        if ((src_offset & 63) || (dst_offset & 63)) {
-               dst_offset += (dy * dst->pitch + dx) * dst->cpp;
-               src_offset += (sy * src->pitch + sx) * src->cpp;
-               return nv04_region_copy_m2mf(nv, dst, dst_offset, src,
-                                            src_offset, w * src->cpp, h);
+               BEGIN_RING(NvM2MF, NV_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);
+
+               nv->region_copy = nv04_region_copy_m2mf;
+               nv->region_dst = dst;
+               nv->region_dst_offset = dst_offset;
+               nv->region_src = src;
+               nv->region_src_offset = src_offset;
+               return 0;
 
        }
 
@@ -101,21 +101,24 @@ nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst,
                NOUVEAU_ERR("Bad cpp = %d\n", dst->cpp);
                return 1;
        }
+       nv->region_copy = nv04_region_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(NvImageBlit, 0x0300, 3);
-       OUT_RING  ((sy << 16) | sx);
-       OUT_RING  ((dy << 16) | dx);
-       OUT_RING  (( h << 16) |  w);
+       return 0;
+}
 
+static void
+nv04_region_copy_done(struct nouveau_context *nv)
+{
        nouveau_notifier_reset(nv->sync_notifier, 0);
        BEGIN_RING(NvGdiRect, 0x104, 1);
        OUT_RING  (0);
@@ -123,8 +126,6 @@ nv04_region_copy(struct nouveau_context *nv, struct pipe_region *dst,
        OUT_RING  (0);
        FIRE_RING();
        nouveau_notifier_wait_status(nv->sync_notifier, 0, 0, 2000);
-
-       return 0;
 }
 
 static int
@@ -238,8 +239,9 @@ nouveau_region_init_nv04(struct nouveau_context *nv)
        BEGIN_RING(NvGdiRect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
        OUT_RING  (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
 
-       nv->region_display = nv04_region_display;
-       nv->region_copy = nv04_region_copy;
+       nv->region_copy_prep = nv04_region_copy_prep;
+       nv->region_copy = nv04_region_copy_blit;
+       nv->region_copy_done = nv04_region_copy_done;
        nv->region_fill = nv04_region_fill;
        nv->region_data = nv04_region_data;
        return 0;
index c7450c5c8d0741a6ac29a1759947ee6c95592a23..75bfcaf6c8ae3ed07b5798884dc53fc92399842d 100644 (file)
@@ -2,21 +2,94 @@
 
 #include "nouveau_context.h"
 
+static INLINE int
+nv50_format(int cpp)
+{
+       switch (cpp) {
+       case 4: return NV50_2D_DST_FORMAT_32BPP;
+       case 3: return NV50_2D_DST_FORMAT_24BPP;
+       case 2: return NV50_2D_DST_FORMAT_16BPP;
+       case 1: return NV50_2D_DST_FORMAT_8BPP;
+       default:
+               return -1;
+       }
+}
+
 static int
-nv50_region_display(void)
+nv50_region_copy_prep(struct nouveau_context *nv,
+                     struct pipe_region *dst, unsigned dst_offset,
+                     struct pipe_region *src, unsigned src_offset)
 {
-       NOUVEAU_ERR("unimplemented\n");
+       int surf_format;
+
+       assert(src->cpp == dst->cpp);
+
+       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);
+
        return 0;
 }
 
-static int
-nv50_region_copy(struct nouveau_context *nv, struct pipe_region *dst,
-                unsigned dst_offset, unsigned dx, unsigned dy,
-                struct pipe_region *src, unsigned src_offset,
+static void
+nv50_region_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
                 unsigned sx, unsigned sy, unsigned w, unsigned h)
 {
-       NOUVEAU_ERR("unimplemented!!\n");
-       return 0;
+       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);
+}
+
+static void
+nv50_region_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
@@ -25,7 +98,52 @@ nv50_region_fill(struct nouveau_context *nv,
                 unsigned dx, unsigned dy, unsigned w, unsigned h,
                 unsigned value)
 {
-       NOUVEAU_ERR("unimplemented!!\n");
+       int surf_format, rect_format;
+
+       surf_format = nv50_format(dst->cpp);
+       if (surf_format < 0)
+               return 1;
+
+       rect_format = nv50_format(dst->cpp);
+       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, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RELOCl(dst->buffer, 0, 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, 4);
+       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);
+
+       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;
 }
 
@@ -42,8 +160,24 @@ nv50_region_data(struct nouveau_context *nv, struct pipe_region *dst,
 int
 nouveau_region_init_nv50(struct nouveau_context *nv)
 {
-       nv->region_display = nv50_region_display;
+       int ret;
+
+       ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D,
+                                 &nv->Nv2D);
+       if (ret)
+               return ret;
+
+       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);
+
+       nv->region_copy_prep = nv50_region_copy_prep;
        nv->region_copy = nv50_region_copy;
+       nv->region_copy_done = nv50_region_copy_done;
        nv->region_fill = nv50_region_fill;
        nv->region_data = nv50_region_data;
        return 0;
index 28f17cdc8fa7a94f6c5298215e585531a8df1b88..1dc15f93ecdd0d96c03aa93fbccaa335475cafea 100644 (file)
@@ -53,13 +53,13 @@ struct nouveau_winsys {
        int       (*notifier_wait)(struct nouveau_notifier *, int id,
                                   int status, int timeout);
 
-       int (*region_copy)(struct nouveau_context *, struct pipe_region *,
+       int (*region_copy)(struct nouveau_winsys *, struct pipe_region *,
                           unsigned, unsigned, unsigned, struct pipe_region *,
                           unsigned, unsigned, unsigned, unsigned, unsigned);
-       int (*region_fill)(struct nouveau_context *, struct pipe_region *,
+       int (*region_fill)(struct nouveau_winsys *, struct pipe_region *,
                           unsigned, unsigned, unsigned, unsigned, unsigned,
                           unsigned);
-       int (*region_data)(struct nouveau_context *, struct pipe_region *,
+       int (*region_data)(struct nouveau_winsys *, struct pipe_region *,
                           unsigned, unsigned, unsigned, const void *,
                           unsigned, unsigned, unsigned, unsigned, unsigned);
 };
index ec8cac676e98d19e5cb07c164c143dc98191ca8c..8f3eeb1f4811ffae39d186985a3379bd31e666f6 100644 (file)
@@ -620,7 +620,6 @@ nv40_fragprog_translate(struct nv40_context *nv40,
 {
        struct tgsi_parse_context parse;
        struct nv40_fpc *fpc = NULL;
-       int i;
 
        fpc = calloc(1, sizeof(struct nv40_fpc));
        if (!fpc)
index 15639f01e90dec02251f58200fa55a814f97489c..f5c4206f4021567a811e9abc0f7f5393b68a582e 100644 (file)
@@ -7,7 +7,6 @@
 boolean
 nv40_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *mt)
 {
-       struct nv40_context *nv40 = (struct nv40_context *)pipe;
        boolean swizzled = FALSE;
        uint width = mt->width0, height = mt->height0, depth = mt->depth0;
        uint offset;
index f62bf89d183110c352a586e9c019fd32b0e8019a..572b82bca3af87551677321a43b0b4b95fd7ae48 100644 (file)
@@ -42,7 +42,7 @@ nv40_region_data(struct pipe_context *pipe,
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
        struct nouveau_winsys *nvws = nv40->nvws;
 
-       nvws->region_data(nvws->nv, dst, dst_offset, dstx, dsty,
+       nvws->region_data(nvws, dst, dst_offset, dstx, dsty,
                          src, src_pitch, srcx, srcy, width, height);
 }
 
@@ -56,7 +56,7 @@ nv40_region_copy(struct pipe_context *pipe, struct pipe_region *dst,
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
        struct nouveau_winsys *nvws = nv40->nvws;
 
-       nvws->region_copy(nvws->nv, dst, dst_offset, dstx, dsty,
+       nvws->region_copy(nvws, dst, dst_offset, dstx, dsty,
                          src, src_offset, srcx, srcy, width, height);
 }
 
@@ -69,7 +69,7 @@ nv40_region_fill(struct pipe_context *pipe,
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
        struct nouveau_winsys *nvws = nv40->nvws;
 
-       nvws->region_fill(nvws->nv, dst, dst_offset, dstx, dsty,
+       nvws->region_fill(nvws, dst, dst_offset, dstx, dsty,
                          width, height, value);
 }
 
index bd779df9b36555fe57b0385864f170843974b612..6902b41ba7165771209a015094e7951b19df09a7 100644 (file)
@@ -53,7 +53,6 @@ nv40_tex_format(uint pipe_format)
 static void
 nv40_tex_unit_enable(struct nv40_context *nv40, int unit)
 {
-       struct nouveau_winsys *nvws = nv40->nvws;
        struct nv40_sampler_state *ps = nv40->tex_sampler[unit];
        struct pipe_mipmap_tree *mt = nv40->tex_miptree[unit];
        struct nv40_texture_format *tf;
index 2da0001b2886d2b87fb6fe5361223a538a656e9c..cc71fb99de20ccf4d387a4a28f8317599aa48a94 100644 (file)
@@ -175,7 +175,6 @@ nv40_vbo_format_to_ncomp(uint format)
 void
 nv40_vbo_arrays_update(struct nv40_context *nv40)
 {
-       struct nouveau_winsys *nvws = nv40->nvws;
        struct nv40_vertex_program *vp = nv40->vertprog.active;
        uint32_t inputs, vtxfmt[16];
        int hw, num_hw;