nv50: make use of nouveau drm 0.0.11 to get 3d going
authorBen Skeggs <skeggsb@gmail.com>
Tue, 8 Jul 2008 02:51:29 +0000 (12:51 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Tue, 8 Jul 2008 02:51:29 +0000 (12:51 +1000)
src/gallium/drivers/nouveau/nouveau_bo.h
src/gallium/drivers/nouveau/nouveau_stateobj.h
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/winsys/dri/nouveau/nouveau_bo.c
src/gallium/winsys/dri/nouveau/nouveau_drmif.h
src/gallium/winsys/dri/nouveau/nouveau_screen.c
src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c
src/gallium/winsys/dri/nouveau/nv50_surface.c

index 18020e9c65212bb591d789b4ef52b9bd7c185c5b..65b138283c48027fa208424e495670c4a9675428 100644 (file)
@@ -35,6 +35,8 @@
 #define NOUVEAU_BO_HIGH  (1 << 7)
 #define NOUVEAU_BO_OR    (1 << 8)
 #define NOUVEAU_BO_LOCAL (1 << 9)
+#define NOUVEAU_BO_TILED (1 << 10)
+#define NOUVEAU_BO_ZTILE (1 << 11)
 #define NOUVEAU_BO_DUMMY (1 << 31)
 
 struct nouveau_bo {
index 78b27380702a61e57fe13218dbd9df46c79fec21..998ec2d4ad4340db0be40ac670ecd768b6c1c66c 100644 (file)
@@ -136,6 +136,9 @@ so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
        struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
        unsigned i;
 
+       if (!so)
+               return;
+
        i = so->cur_reloc << 1;
        if (nvws->channel->pushbuf->remaining < i)
                nvws->push_flush(nvws, i, NULL);
index cf5a071a8d6144e1b29da55cf73a32f26ef3cbc3..88ef685bb1f2b0bd0f5c0ae2678631169f274ccc 100644 (file)
@@ -44,7 +44,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
                        so_data(so, 0xe6);
                        break;
                }
-               so_data(so, 0x00000040);
+               so_data(so, 0x00000000);
                so_data(so, 0x00000000);
 
                so_method(so, tesla, 0x1224, 1);
@@ -82,7 +82,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
                        so_data(so, 0x16);
                        break;
                }
-               so_data(so, 0x00000040);
+               so_data(so, 0x00000000);
                so_data(so, 0x00000000);
 
                so_method(so, tesla, 0x1538, 1);
@@ -265,7 +265,7 @@ scissor_uptodate:
                        so_data (so, 0x2a712488);
                        so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM |
                                     NOUVEAU_BO_LOW, 0, 0);
-                       so_data (so, 0xd0c05000);
+                       so_data (so, 0xd0005000);
                        so_data (so, 0x00300000);
                        so_data (so, mt->base.width[0]);
                        so_data (so, (mt->base.depth[0] << 16) |
index 57f5b7d1ae1b5cdb03cbfe94405be3357358c2ed..b5942994d94503326ae724d3956dda97b83db85a 100644 (file)
@@ -182,6 +182,13 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
        nvbo->drm.alignment = align;
        nvbo->refcount = 1;
 
+       if (flags & NOUVEAU_BO_TILED) {
+               nvbo->tiled = 1;
+               if (flags & NOUVEAU_BO_ZTILE)
+                       nvbo->tiled |= 2;
+               flags &= ~NOUVEAU_BO_TILED;
+       }
+
        ret = nouveau_bo_set_status(&nvbo->base, flags);
        if (ret) {
                free(nvbo);
@@ -332,6 +339,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags)
        else
        if (flags & NOUVEAU_BO_GART)
                new_flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI);
+       
+       if (nvbo->tiled && flags) {
+               new_flags |= NOUVEAU_MEM_TILE;
+               if (nvbo->tiled & 2)
+                       new_flags |= NOUVEAU_MEM_TILE_ZETA;
+       }
 
        if (new_flags) {
                ret = nouveau_mem_alloc(bo->device, bo->size,
@@ -347,9 +360,12 @@ nouveau_bo_set_status(struct nouveau_bo *bo, uint32_t flags)
        /* Copy old -> new */
        /*XXX: use M2MF */
        if (nvbo->sysmem || nvbo->map) {
+               struct nouveau_pushbuf_bo *pbo = nvbo->pending;
+               nvbo->pending = NULL;
                nouveau_bo_map(bo, NOUVEAU_BO_RD);
                memcpy(new_map, bo->map, bo->size);
                nouveau_bo_unmap(bo);
+               nvbo->pending = pbo;
        }
 
        /* Free old memory */
index 5829f649cd580005df1e790ac13f107d1fee644c..dcd6a5eb0a492337450eb0ce2034d98075146c3d 100644 (file)
@@ -259,6 +259,7 @@ struct nouveau_bo_priv {
 
        uint64_t offset;
        uint64_t flags;
+       int tiled;
 };
 #define nouveau_bo(n) ((struct nouveau_bo_priv *)(n))
 
index b15ee7509cc6f8640c0d65563b9f3463a472654f..df1fe7e69b4f16bd676823a63695d5560bfd7122 100644 (file)
@@ -13,7 +13,7 @@
 #include "nouveau_screen.h"
 #include "nouveau_swapbuffers.h"
 
-#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
+#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11
 #error nouveau_drm.h version does not match expected version
 #endif
 
index ba5dd2eea4bfd5d8e4391f3920c9c2c184122f89..765ea36f881d05f654204d3d27fd5b585cb0eea4 100644 (file)
@@ -76,6 +76,18 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
                if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
                        flags |= NOUVEAU_BO_GART;
                flags |= NOUVEAU_BO_VRAM;
+
+               switch (dev->chipset & 0xf0) {
+               case 0x50:
+               case 0x80:
+               case 0x90:
+                       flags |= NOUVEAU_BO_TILED;
+                       if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
+                               flags |= NOUVEAU_BO_ZTILE;
+                       break;
+               default:
+                       break;
+               }
        }
 
        if (usage & PIPE_BUFFER_USAGE_VERTEX) {
index cf76d76cf528a701433468542fa73cb3597069e6..c8ab7f690f30ddd9538798ce27735de57794c16f 100644 (file)
@@ -22,52 +22,70 @@ nv50_format(enum pipe_format format)
 }
 
 static int
-nv50_surface_copy_prep(struct nouveau_context *nv,
-                      struct pipe_surface *dst, struct pipe_surface *src)
+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;
-       int surf_format;
-
-       assert(src->format == dst->format);
+       struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->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 (!nouveau_bo(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;
+}
 
-       surf_format = nv50_format(dst->format);
-       assert(surf_format >= 0);
+static int
+nv50_surface_copy_prep(struct nouveau_context *nv,
+                      struct pipe_surface *dst, struct pipe_surface *src)
+{
+       int ret;
 
-       BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2);
-       OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo,
-                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
-                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       assert(src->format == dst->format);
 
-       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->stride);
-       OUT_RING  (chan, dst->width);
-       OUT_RING  (chan, dst->height);
-       OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
-                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, 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->width);
-       OUT_RING  (chan, dst->height);
+       ret = nv50_surface_set(nv, dst, 1);
+       if (ret)
+               return ret;
 
-       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->stride);
-       OUT_RING  (chan, src->width);
-       OUT_RING  (chan, src->height);
-       OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset,
-                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-       OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset,
-                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       ret = nv50_surface_set(nv, src, 0);
+       if (ret)
+               return ret;
 
        return 0;
 }
@@ -79,17 +97,19 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
        struct nouveau_channel *chan = nv->nvc->channel;
        struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
 
-       BEGIN_RING(chan, eng2d, 0x0110, 1);
+       BEGIN_RING(chan, eng2d, 0x088c, 1);
        OUT_RING  (chan, 0);
-       BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+       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);
@@ -109,35 +129,15 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
 {
        struct nouveau_channel *chan = nv->nvc->channel;
        struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
-       int surf_format, rect_format;
-
-       surf_format = nv50_format(dst->format);
-       if (surf_format < 0)
-               return 1;
+       int rect_format, ret;
 
        rect_format = nv50_format(dst->format);
        if (rect_format < 0)
                return 1;
 
-       BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1);
-       OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
-                  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->stride);
-       OUT_RING  (chan, dst->width);
-       OUT_RING  (chan, dst->height);
-       OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
-                  NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, 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->width);
-       OUT_RING  (chan, dst->height);
+       ret = nv50_surface_set(nv, dst, 1);
+       if (ret)
+               return ret;
 
        BEGIN_RING(chan, eng2d, 0x0580, 3);
        OUT_RING  (chan, 4);
@@ -151,27 +151,33 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
        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(nvc->channel, nvc->next_handle++, NV50_2D,
-                                 &nvc->Nv2D);
+       ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d);
        if (ret)
                return ret;
-       BIND_RING (nvc->channel, nvc->Nv2D, nvc->next_subchannel++);
-       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);
+       nvc->Nv2D = eng2d;
+
+       BIND_RING (chan, eng2d, nvc->next_subchannel++);
+       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;
 }