nouveau: switch to libdrm_nouveau-2.0
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 6 Apr 2012 13:41:55 +0000 (15:41 +0200)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 13 Apr 2012 16:56:33 +0000 (02:56 +1000)
58 files changed:
configure.ac
src/gallium/drivers/nouveau/Makefile.sources
src/gallium/drivers/nouveau/nouveau_buffer.c
src/gallium/drivers/nouveau/nouveau_buffer.h
src/gallium/drivers/nouveau/nouveau_context.h
src/gallium/drivers/nouveau/nouveau_fence.c
src/gallium/drivers/nouveau/nouveau_heap.c [new file with mode: 0644]
src/gallium/drivers/nouveau/nouveau_heap.h [new file with mode: 0644]
src/gallium/drivers/nouveau/nouveau_mm.c
src/gallium/drivers/nouveau/nouveau_mm.h
src/gallium/drivers/nouveau/nouveau_screen.c
src/gallium/drivers/nouveau/nouveau_screen.h
src/gallium/drivers/nouveau/nouveau_statebuf.h
src/gallium/drivers/nouveau/nouveau_video.c
src/gallium/drivers/nouveau/nouveau_video.h
src/gallium/drivers/nouveau/nouveau_winsys.h
src/gallium/drivers/nouveau/nv_m2mf.xml.h
src/gallium/drivers/nouveau/nv_object.xml.h
src/gallium/drivers/nv50/nv50_3d.xml.h
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_miptree.c
src/gallium/drivers/nv50/nv50_program.c
src/gallium/drivers/nv50/nv50_program.h
src/gallium/drivers/nv50/nv50_push.c
src/gallium/drivers/nv50/nv50_query.c
src/gallium/drivers/nv50/nv50_resource.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_shader_state.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_stateobj.h
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_transfer.c
src/gallium/drivers/nv50/nv50_vbo.c
src/gallium/drivers/nv50/nv50_winsys.h
src/gallium/drivers/nvc0/nvc0_3d.xml.h
src/gallium/drivers/nvc0/nvc0_context.c
src/gallium/drivers/nvc0/nvc0_context.h
src/gallium/drivers/nvc0/nvc0_miptree.c
src/gallium/drivers/nvc0/nvc0_program.c
src/gallium/drivers/nvc0/nvc0_program.h
src/gallium/drivers/nvc0/nvc0_push.c
src/gallium/drivers/nvc0/nvc0_query.c
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/nvc0/nvc0_screen.h
src/gallium/drivers/nvc0/nvc0_shader_state.c
src/gallium/drivers/nvc0/nvc0_state.c
src/gallium/drivers/nvc0/nvc0_state_validate.c
src/gallium/drivers/nvc0/nvc0_stateobj.h
src/gallium/drivers/nvc0/nvc0_surface.c
src/gallium/drivers/nvc0/nvc0_tex.c
src/gallium/drivers/nvc0/nvc0_transfer.c
src/gallium/drivers/nvc0/nvc0_vbo.c
src/gallium/drivers/nvc0/nvc0_winsys.h
src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c

index 1e4d9ae5587f8ff4dcbe3714062de3b4698d38e3..c9be8c76fbdd8a76f6ea2d76ae90e7a0ae97f070 100644 (file)
@@ -39,7 +39,7 @@ LIBDRM_REQUIRED=2.4.24
 LIBDRM_RADEON_REQUIRED=2.4.31
 LIBDRM_INTEL_REQUIRED=2.4.32
 LIBDRM_NVVIEUX_REQUIRED=2.4.33
-LIBDRM_NOUVEAU_REQUIRED=0.6
+LIBDRM_NOUVEAU_REQUIRED=2.4.33
 DRI2PROTO_REQUIRED=2.6
 GLPROTO_REQUIRED=1.4.14
 LIBDRM_XORG_REQUIRED=2.4.24
index 5a5998bca0a0fa62cb9d3cefc9a0e93ad51b4098..cc9e68f44a82f7c1b85b5e964825a2886d0ec076 100644 (file)
@@ -3,4 +3,5 @@ C_SOURCES := \
        nouveau_fence.c \
        nouveau_mm.c \
        nouveau_buffer.c \
+       nouveau_heap.c \
        nouveau_video.c
index f3cef8c288f3fc9fa540c164e48f7f408046148d..653acaa18fe8d030dd0297b4678f18b97210f728 100644 (file)
@@ -49,6 +49,9 @@ nouveau_buffer_allocate(struct nouveau_screen *screen,
       }
    }
    buf->domain = domain;
+   if (buf->bo)
+      buf->address = buf->bo->offset + buf->offset;
+
    return TRUE;
 }
 
@@ -112,10 +115,9 @@ nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf,
    nv->copy_data(nv, bounce, offset, NOUVEAU_BO_GART,
                  buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size);
 
-   if (nouveau_bo_map_range(bounce, offset, size, NOUVEAU_BO_RD))
+   if (nouveau_bo_map(bounce, NOUVEAU_BO_RD, nv->screen->client))
       return FALSE;
-   memcpy(buf->data + start, bounce->map, size);
-   nouveau_bo_unmap(bounce);
+   memcpy(buf->data + start, (uint8_t *)bounce->map + offset, size);
 
    buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
 
@@ -147,10 +149,8 @@ nouveau_buffer_upload(struct nouveau_context *nv, struct nv04_resource *buf,
    if (!bounce)
       return FALSE;
 
-   nouveau_bo_map_range(bounce, offset, size,
-                        NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC);
-   memcpy(bounce->map, buf->data + start, size);
-   nouveau_bo_unmap(bounce);
+   nouveau_bo_map(bounce, 0, nv->screen->client);
+   memcpy((uint8_t *)bounce->map + offset, buf->data + start, size);
 
    nv->copy_data(nv, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM,
                  bounce, offset, NOUVEAU_BO_GART, size);
@@ -246,34 +246,27 @@ static void *
 nouveau_buffer_transfer_map(struct pipe_context *pipe,
                             struct pipe_transfer *transfer)
 {
+   struct nouveau_context *nv = nouveau_context(pipe);
    struct nouveau_transfer *xfr = nouveau_transfer(transfer);
    struct nv04_resource *buf = nv04_resource(transfer->resource);
    struct nouveau_bo *bo = buf->bo;
    uint8_t *map;
    int ret;
    uint32_t offset = xfr->base.box.x;
-   uint32_t flags;
+   uint32_t flags = 0;
 
    if (buf->domain != NOUVEAU_BO_GART)
       return buf->data + offset;
 
-   if (buf->mm)
-      flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR;
-   else
+   if (!buf->mm)
       flags = nouveau_screen_transfer_flags(xfr->base.usage);
 
    offset += buf->offset;
 
-   ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags);
+   ret = nouveau_bo_map(buf->bo, flags, nv->screen->client);
    if (ret)
       return NULL;
-   map = bo->map;
-
-   /* Unmap right now. Since multiple buffers can share a single nouveau_bo,
-    * not doing so might make future maps fail or trigger "reloc while mapped"
-    * errors. For now, mappings to userspace are guaranteed to be persistent.
-    */
-   nouveau_bo_unmap(bo);
+   map = (uint8_t *)bo->map + offset;
 
    if (buf->mm) {
       if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) {
@@ -294,6 +287,7 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe,
                                      struct pipe_transfer *transfer,
                                      const struct pipe_box *box)
 {
+#if 0
    struct nv04_resource *res = nv04_resource(transfer->resource);
    struct nouveau_bo *bo = res->bo;
    unsigned offset = res->offset + transfer->box.x + box->x;
@@ -303,17 +297,43 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe,
       return;
 
    /* XXX: maybe need to upload for VRAM buffers here */
-
-   nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width);
+#endif
 }
 
 static void
 nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
                               struct pipe_transfer *transfer)
 {
-   /* we've called nouveau_bo_unmap right after map */
 }
 
+
+void *
+nouveau_resource_map_offset(struct nouveau_context *nv,
+                            struct nv04_resource *res, uint32_t offset,
+                            uint32_t flags)
+{
+   if ((res->domain == NOUVEAU_BO_VRAM) &&
+       (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING))
+      nouveau_buffer_download(nv, res, 0, res->base.width0);
+
+   if ((res->domain != NOUVEAU_BO_GART) ||
+       (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY))
+      return res->data + offset;
+
+   if (res->mm) {
+      unsigned rw;
+      rw = (flags & NOUVEAU_BO_WR) ? PIPE_TRANSFER_WRITE : PIPE_TRANSFER_READ;
+      nouveau_buffer_sync(res, rw);
+      if (nouveau_bo_map(res->bo, 0, NULL))
+         return NULL;
+   } else {
+      if (nouveau_bo_map(res->bo, flags, nv->screen->client))
+         return NULL;
+   }
+   return (uint8_t *)res->bo->map + res->offset + offset;
+}
+
+
 const struct u_resource_vtbl nouveau_buffer_vtbl =
 {
    u_default_resource_get_handle,     /* get_handle */
@@ -387,18 +407,17 @@ nouveau_user_buffer_create(struct pipe_screen *pscreen, void *ptr,
 
 /* Like download, but for GART buffers. Merge ? */
 static INLINE boolean
-nouveau_buffer_data_fetch(struct nv04_resource *buf, struct nouveau_bo *bo,
-                          unsigned offset, unsigned size)
+nouveau_buffer_data_fetch(struct nouveau_context *nv, struct nv04_resource *buf,
+                          struct nouveau_bo *bo, unsigned offset, unsigned size)
 {
    if (!buf->data) {
       buf->data = MALLOC(size);
       if (!buf->data)
          return FALSE;
    }
-   if (nouveau_bo_map_range(bo, offset, size, NOUVEAU_BO_RD))
+   if (nouveau_bo_map(bo, NOUVEAU_BO_RD, nv->screen->client))
       return FALSE;
-   memcpy(buf->data, bo->map, size);
-   nouveau_bo_unmap(bo);
+   memcpy(buf->data, (uint8_t *)bo->map + offset, size);
 
    return TRUE;
 }
@@ -420,12 +439,10 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
    if (new_domain == NOUVEAU_BO_GART && old_domain == 0) {
       if (!nouveau_buffer_allocate(screen, buf, new_domain))
          return FALSE;
-      ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR |
-                                 NOUVEAU_BO_NOSYNC);
+      ret = nouveau_bo_map(buf->bo, 0, nv->screen->client);
       if (ret)
          return ret;
-      memcpy(buf->bo->map, buf->data, size);
-      nouveau_bo_unmap(buf->bo);
+      memcpy((uint8_t *)buf->bo->map + buf->offset, buf->data, size);
       FREE(buf->data);
    } else
    if (old_domain != 0 && new_domain != 0) {
@@ -433,7 +450,7 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
 
       if (new_domain == NOUVEAU_BO_VRAM) {
          /* keep a system memory copy of our data in case we hit a fallback */
-         if (!nouveau_buffer_data_fetch(buf, buf->bo, buf->offset, size))
+         if (!nouveau_buffer_data_fetch(nv, buf, buf->bo, buf->offset, size))
             return FALSE;
          if (nouveau_mesa_debug)
             debug_printf("migrating %u KiB to VRAM\n", size / 1024);
@@ -469,7 +486,8 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
  * the vertex indices ...
  */
 boolean
-nouveau_user_buffer_upload(struct nv04_resource *buf,
+nouveau_user_buffer_upload(struct nouveau_context *nv,
+                           struct nv04_resource *buf,
                            unsigned base, unsigned size)
 {
    struct nouveau_screen *screen = nouveau_screen(buf->base.screen);
@@ -481,12 +499,10 @@ nouveau_user_buffer_upload(struct nv04_resource *buf,
    if (!nouveau_buffer_reallocate(screen, buf, NOUVEAU_BO_GART))
       return FALSE;
 
-   ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size,
-                              NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC);
+   ret = nouveau_bo_map(buf->bo, 0, nv->screen->client);
    if (ret)
       return FALSE;
-   memcpy(buf->bo->map, buf->data + base, size);
-   nouveau_bo_unmap(buf->bo);
+   memcpy((uint8_t *)buf->bo->map + buf->offset + base, buf->data + base, size);
 
    return TRUE;
 }
index c0a781c6fd37504dbdcc617ceb97692ea67dad75..3d97ac33b7d133ff55e303799f284de7030ccebe 100644 (file)
@@ -28,6 +28,8 @@ struct nv04_resource {
    struct pipe_resource base;
    const struct u_resource_vtbl *vtbl;
 
+   uint64_t address; /* virtual address (nv50+) */
+
    uint8_t *data;
    struct nouveau_bo *bo;
    uint32_t offset;
@@ -52,33 +54,9 @@ boolean
 nouveau_buffer_migrate(struct nouveau_context *,
                        struct nv04_resource *, unsigned domain);
 
-/* XXX: wait for fence (atm only using this for vertex push) */
-static INLINE void *
-nouveau_resource_map_offset(struct nouveau_context *pipe,
-                            struct nv04_resource *res, uint32_t offset,
-                            uint32_t flags)
-{
-   void *map;
-
-   if ((res->domain == NOUVEAU_BO_VRAM) &&
-       (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING))
-      nouveau_buffer_download(pipe, res, 0, res->base.width0);
-
-   if ((res->domain != NOUVEAU_BO_GART) ||
-       (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY))
-      return res->data + offset;
-
-   if (res->mm)
-      flags |= NOUVEAU_BO_NOSYNC;
-
-   if (nouveau_bo_map_range(res->bo, res->offset + offset,
-                            res->base.width0, flags))
-      return NULL;
-
-   map = res->bo->map;
-   nouveau_bo_unmap(res->bo);
-   return map;
-}
+void *
+nouveau_resource_map_offset(struct nouveau_context *, struct nv04_resource *,
+                            uint32_t offset, uint32_t flags);
 
 static INLINE void
 nouveau_resource_unmap(struct nv04_resource *res)
@@ -108,7 +86,7 @@ nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr,
                            unsigned bytes, unsigned usage);
 
 boolean
-nouveau_user_buffer_upload(struct nv04_resource *, unsigned base,
-                           unsigned size);
+nouveau_user_buffer_upload(struct nouveau_context *, struct nv04_resource *,
+                           unsigned base, unsigned size);
 
 #endif
index 92aea76b4242678511ff76f40ee26a200f71feb6..4e6085f6935e746d6610d5d92f4fd303b7132161 100644 (file)
@@ -3,10 +3,14 @@
 
 #include "pipe/p_context.h"
 
+struct nouveau_pushbuf;
+
 struct nouveau_context {
    struct pipe_context pipe;
    struct nouveau_screen *screen;
 
+   struct nouveau_pushbuf *pushbuf;
+
    boolean vbo_dirty;
    boolean cb_dirty;
 
index a2fcafef4a7bea8fc2eeeb97cb01f85c3a8164c2..d2f98654f319137b80749144a92125fb538f6e50 100644 (file)
 #include "util/u_double_list.h"
 
 #include "nouveau_screen.h"
+#include "nouveau_winsys.h"
 #include "nouveau_fence.h"
 
-#include "nouveau/nouveau_pushbuf.h"
-
 #ifdef PIPE_OS_UNIX
 #include <sched.h>
 #endif
@@ -197,7 +196,7 @@ nouveau_fence_wait(struct nouveau_fence *fence)
          nouveau_fence_new(screen, &screen->fence.current, FALSE);
    }
    if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
-      FIRE_RING(screen->channel);
+      nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel);
 
    do {
       nouveau_fence_update(screen, FALSE);
diff --git a/src/gallium/drivers/nouveau/nouveau_heap.c b/src/gallium/drivers/nouveau/nouveau_heap.c
new file mode 100644 (file)
index 0000000..769211b
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2007 Nouveau Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "nouveau_heap.h"
+
+int
+nouveau_heap_init(struct nouveau_heap **heap,
+                  unsigned start, unsigned size)
+{
+       struct nouveau_heap *r;
+
+       r = calloc(1, sizeof(struct nouveau_heap));
+       if (!r)
+               return 1;
+
+       r->start = start;
+       r->size  = size;
+       *heap = r;
+       return 0;
+}
+
+void
+nouveau_heap_destroy(struct nouveau_heap **heap)
+{
+       if (!*heap)
+               return;
+       free(*heap);
+       *heap = NULL;
+}
+
+int
+nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv,
+                   struct nouveau_heap **res)
+{
+       struct nouveau_heap *r;
+
+       if (!heap || !size || !res || *res)
+               return 1;
+
+       while (heap) {
+               if (!heap->in_use && heap->size >= size) {
+                       r = calloc(1, sizeof(struct nouveau_heap));
+                       if (!r)
+                               return 1;
+
+                       r->start  = (heap->start + heap->size) - size;
+                       r->size   = size;
+                       r->in_use = 1;
+                       r->priv   = priv;
+
+                       heap->size -= size;
+
+                       r->next = heap->next;
+                       if (heap->next)
+                               heap->next->prev = r;
+                       r->prev = heap;
+                       heap->next = r;
+
+                       *res = r;
+                       return 0;
+               }
+
+               heap = heap->next;
+       }
+
+       return 1;
+}
+
+void
+nouveau_heap_free(struct nouveau_heap **res)
+{
+       struct nouveau_heap *r;
+
+       if (!res || !*res)
+               return;
+       r = *res;
+       *res = NULL;
+
+       r->in_use = 0;
+
+       if (r->next && !r->next->in_use) {
+               struct nouveau_heap *new = r->next;
+
+               new->prev = r->prev;
+               if (r->prev)
+                       r->prev->next = new;
+               new->size += r->size;
+               new->start = r->start;
+
+               free(r);
+               r = new;
+       }
+
+       if (r->prev && !r->prev->in_use) {
+               r->prev->next = r->next;
+               if (r->next)
+                       r->next->prev = r->prev;
+               r->prev->size += r->size;
+               free(r);
+       }
+}
diff --git a/src/gallium/drivers/nouveau/nouveau_heap.h b/src/gallium/drivers/nouveau/nouveau_heap.h
new file mode 100644 (file)
index 0000000..34d9a82
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 Nouveau Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __NOUVEAU_HEAP_H__
+#define __NOUVEAU_HEAP_H__
+
+struct nouveau_heap {
+       struct nouveau_heap *prev;
+       struct nouveau_heap *next;
+
+       void *priv;
+
+       unsigned start;
+       unsigned size;
+
+       int in_use;
+};
+
+int
+nouveau_heap_init(struct nouveau_heap **heap, unsigned start,
+                  unsigned size);
+
+void
+nouveau_heap_destroy(struct nouveau_heap **heap);
+
+int
+nouveau_heap_alloc(struct nouveau_heap *heap, unsigned size, void *priv,
+                   struct nouveau_heap **);
+
+void
+nouveau_heap_free(struct nouveau_heap **);
+
+#endif
index 8d0b7bfe99a86433040f496789648465113776ac..4207084aecf5a6739c5b4defd8f0579459b1eed8 100644 (file)
@@ -5,11 +5,10 @@
 #include "util/u_memory.h"
 #include "util/u_double_list.h"
 
+#include "nouveau_winsys.h"
 #include "nouveau_screen.h"
 #include "nouveau_mm.h"
 
-#include "nouveau/nouveau_bo.h"
-
 #define MM_MIN_ORDER 7
 #define MM_MAX_ORDER 20
 
@@ -28,8 +27,8 @@ struct mm_bucket {
 struct nouveau_mman {
    struct nouveau_device *dev;
    struct mm_bucket bucket[MM_NUM_BUCKETS];
-   uint32_t storage_type;
    uint32_t domain;
+   union nouveau_bo_config config;
    uint64_t allocated;
 };
 
@@ -128,8 +127,9 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order)
    memset(&slab->bits[0], ~0, words * 4);
 
    slab->bo = NULL;
-   ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size,
-                             0, cache->storage_type, &slab->bo);
+
+   ret = nouveau_bo_new(cache->dev, cache->domain, 0, size, &cache->config,
+                        &slab->bo);
    if (ret) {
       FREE(slab);
       return PIPE_ERROR_OUT_OF_MEMORY;
@@ -155,7 +155,7 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order)
 /* @return token to identify slab or NULL if we just allocated a new bo */
 struct nouveau_mm_allocation *
 nouveau_mm_allocate(struct nouveau_mman *cache,
-                 uint32_t size, struct nouveau_bo **bo, uint32_t *offset)
+                    uint32_t size, struct nouveau_bo **bo, uint32_t *offset)
 {
    struct mm_bucket *bucket;
    struct mm_slab *slab;
@@ -164,10 +164,11 @@ nouveau_mm_allocate(struct nouveau_mman *cache,
 
    bucket = mm_bucket_by_size(cache, size);
    if (!bucket) {
-      ret = nouveau_bo_new_tile(cache->dev, cache->domain, 0, size,
-                                0, cache->storage_type, bo);
+      ret = nouveau_bo_new(cache->dev, cache->domain, 0, size, &cache->config,
+                           bo);
       if (ret)
-         debug_printf("bo_new(%x, %x): %i\n", size, cache->storage_type, ret);
+         debug_printf("bo_new(%x, %x): %i\n",
+                      size, cache->config.nv50.memtype, ret);
 
       *offset = 0;
       return NULL;
@@ -233,7 +234,7 @@ nouveau_mm_free_work(void *data)
 
 struct nouveau_mman *
 nouveau_mm_create(struct nouveau_device *dev, uint32_t domain,
-               uint32_t storage_type)
+                  union nouveau_bo_config *config)
 {
    struct nouveau_mman *cache = MALLOC_STRUCT(nouveau_mman);
    int i;
@@ -243,7 +244,7 @@ nouveau_mm_create(struct nouveau_device *dev, uint32_t domain,
 
    cache->dev = dev;
    cache->domain = domain;
-   cache->storage_type = storage_type;
+   cache->config = *config;
    cache->allocated = 0;
 
    for (i = 0; i < MM_NUM_BUCKETS; ++i) {
index 5b57c8ba4f21ef31d78df5f8950c99df8bef26f0..8e4f1e5713f20b4871a5d47fb342bd1d29f53450 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __NOUVEAU_MM_H__
 #define __NOUVEAU_MM_H__
 
+union nouveau_bo_config;
 struct nouveau_mman;
 
 /* Since a resource can be migrated, we need to decouple allocations from
@@ -14,7 +15,7 @@ struct nouveau_mm_allocation {
 
 extern struct nouveau_mman *
 nouveau_mm_create(struct nouveau_device *, uint32_t domain,
-                  uint32_t storage_type);
+                  union nouveau_bo_config *);
 
 extern void
 nouveau_mm_destroy(struct nouveau_mman *);
index 8ebae8e27dc15d91e8ee64464cb6994798935927..7437779997754590230b5739c8898f0c47270f78 100644 (file)
 #include <errno.h>
 #include <stdlib.h>
 
-#include "nouveau/nouveau_bo.h"
-#include "nouveau/nouveau_mm.h"
 #include "nouveau_winsys.h"
 #include "nouveau_screen.h"
 #include "nouveau_fence.h"
+#include "nouveau_mm.h"
+#include "nouveau_buffer.h"
 
 /* XXX this should go away */
 #include "state_tracker/drm_driver.h"
 
-#include "nouveau_drmif.h"
-
 int nouveau_mesa_debug = 0;
 
 static const char *
@@ -41,102 +39,6 @@ nouveau_screen_get_vendor(struct pipe_screen *pscreen)
        return "nouveau";
 }
 
-
-
-struct nouveau_bo *
-nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
-                     unsigned usage, unsigned bind, unsigned size)
-{
-       struct nouveau_device *dev = nouveau_screen(pscreen)->device;
-       struct nouveau_bo *bo = NULL;
-       uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
-       int ret;
-
-       if (bind & PIPE_BIND_VERTEX_BUFFER)
-               flags |= nouveau_screen(pscreen)->vertex_buffer_flags;
-       else if (bind & PIPE_BIND_INDEX_BUFFER)
-               flags |= nouveau_screen(pscreen)->index_buffer_flags;
-
-       if (bind & (PIPE_BIND_RENDER_TARGET |
-                       PIPE_BIND_DEPTH_STENCIL |
-                       PIPE_BIND_SCANOUT |
-                       PIPE_BIND_DISPLAY_TARGET |
-                       PIPE_BIND_SAMPLER_VIEW))
-       {
-               /* TODO: this may be incorrect or suboptimal */
-               if (!(bind & PIPE_BIND_SCANOUT))
-                       flags |= NOUVEAU_BO_GART;
-               if (usage != PIPE_USAGE_DYNAMIC)
-                       flags |= NOUVEAU_BO_VRAM;
-
-               if (dev->chipset == 0x50 || dev->chipset >= 0x80) {
-                       if (bind & PIPE_BIND_DEPTH_STENCIL)
-                               tile_flags = 0x2800;
-                       else
-                               tile_flags = 0x7000;
-               }
-       }
-
-       ret = nouveau_bo_new_tile(dev, flags, alignment, size,
-                                 tile_mode, tile_flags, &bo);
-       if (ret)
-               return NULL;
-
-       return bo;
-}
-
-void *
-nouveau_screen_bo_map(struct pipe_screen *pscreen,
-                     struct nouveau_bo *bo,
-                     unsigned map_flags)
-{
-       int ret;
-
-       ret = nouveau_bo_map(bo, map_flags);
-       if (ret) {
-               debug_printf("map failed: %d\n", ret);
-               return NULL;
-       }
-
-       return bo->map;
-}
-
-void *
-nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
-                           unsigned offset, unsigned length, unsigned flags)
-{
-       int ret;
-
-       ret = nouveau_bo_map_range(bo, offset, length, flags);
-       if (ret) {
-               nouveau_bo_unmap(bo);
-               if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
-                       debug_printf("map_range failed: %d\n", ret);
-               return NULL;
-       }
-
-       return (char *)bo->map - offset; /* why gallium? why? */
-}
-
-void
-nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
-                                 unsigned offset, unsigned length)
-{
-       nouveau_bo_map_flush(bo, offset, length);
-}
-
-void
-nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo)
-{
-       nouveau_bo_unmap(bo);
-}
-
-void
-nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo)
-{
-       nouveau_bo_ref(NULL, &bo);
-}
-
 static void
 nouveau_screen_fence_ref(struct pipe_screen *pscreen,
                         struct pipe_fence_handle **ptr,
@@ -157,7 +59,7 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
                            struct pipe_fence_handle *pfence,
                             uint64_t timeout)
 {
-        return nouveau_fence_wait(nouveau_fence(pfence));
+       return nouveau_fence_wait(nouveau_fence(pfence));
 }
 
 
@@ -170,7 +72,7 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
        struct nouveau_bo *bo = 0;
        int ret;
  
-       ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo);
+       ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
        if (ret) {
                debug_printf("%s: ref name 0x%08x failed with %d\n",
                             __FUNCTION__, whandle->handle, ret);
@@ -191,7 +93,7 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
        whandle->stride = stride;
 
        if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { 
-               return nouveau_bo_handle_get(bo, &whandle->handle) == 0;
+               return nouveau_bo_name_get(bo, &whandle->handle) == 0;
        } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
                whandle->handle = bo->handle;
                return TRUE;
@@ -204,18 +106,39 @@ int
 nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
 {
        struct pipe_screen *pscreen = &screen->base;
-       int ret;
+       struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
+       struct nvc0_fifo nvc0_data = { };
+       int size, ret;
+       void *data;
+       union nouveau_bo_config mm_config;
 
        char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
        if (nv_dbg)
           nouveau_mesa_debug = atoi(nv_dbg);
 
-       ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
-                                   512*1024, &screen->channel);
+       if (dev->chipset < 0xc0) {
+               data = &nv04_data;
+               size = sizeof(nv04_data);
+       } else {
+               data = &nvc0_data;
+               size = sizeof(nvc0_data);
+       }
+
+       ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
+                                data, size, &screen->channel);
        if (ret)
                return ret;
        screen->device = dev;
 
+       ret = nouveau_client_new(screen->device, &screen->client);
+       if (ret)
+               return ret;
+       ret = nouveau_pushbuf_new(screen->client, screen->channel,
+                                 4, 512 * 1024, 1,
+                                 &screen->pushbuf);
+       if (ret)
+               return ret;
+
        pscreen->get_name = nouveau_screen_get_name;
        pscreen->get_vendor = nouveau_screen_get_vendor;
 
@@ -225,10 +148,12 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
 
        util_format_s3tc_init();
 
+       memset(&mm_config, 0, sizeof(mm_config));
+
        screen->mm_GART = nouveau_mm_create(dev,
                                            NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
-                                           0x000);
-       screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
+                                           &mm_config);
+       screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
        return 0;
 }
 
@@ -238,8 +163,10 @@ nouveau_screen_fini(struct nouveau_screen *screen)
        nouveau_mm_destroy(screen->mm_GART);
        nouveau_mm_destroy(screen->mm_VRAM);
 
-       nouveau_channel_free(&screen->channel);
+       nouveau_pushbuf_del(&screen->pushbuf);
 
-       nouveau_device_close(&screen->device);
-}
+       nouveau_client_del(&screen->client);
+       nouveau_object_del(&screen->channel);
 
+       nouveau_device_del(&screen->device);
+}
index d2003e62f511e465b652a3439d1514ac47858238..a2784773143b402b1e47faedb67ed12d01f819f4 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
+
 typedef uint32_t u32;
 
 extern int nouveau_mesa_debug;
@@ -12,12 +13,10 @@ struct nouveau_bo;
 struct nouveau_screen {
        struct pipe_screen base;
        struct nouveau_device *device;
-       struct nouveau_channel *channel;
+       struct nouveau_object *channel;
+       struct nouveau_client *client;
+       struct nouveau_pushbuf *pushbuf;
 
-       /* note that OpenGL doesn't distinguish between these, so
-        * these almost always should be set to the same value */
-       unsigned vertex_buffer_flags;
-       unsigned index_buffer_flags;
        unsigned sysmem_bindings;
 
        struct {
@@ -40,30 +39,6 @@ nouveau_screen(struct pipe_screen *pscreen)
        return (struct nouveau_screen *)pscreen;
 }
 
-
-
-/* Not really sure if this is needed, or whether the individual
- * drivers are happy to talk to the bo functions themselves.  In a way
- * this is what we'd expect from a regular winsys interface.
- */
-struct nouveau_bo *
-nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
-                     unsigned usage, unsigned bind, unsigned size);
-void *
-nouveau_screen_bo_map(struct pipe_screen *pscreen,
-                     struct nouveau_bo *pb,
-                     unsigned usage);
-void *
-nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
-                           unsigned offset, unsigned length, unsigned usage);
-void
-nouveau_screen_bo_map_flush_range(struct pipe_screen *pscreen, struct nouveau_bo *bo,
-                                 unsigned offset, unsigned length);
-void
-nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct nouveau_bo *bo);
-void
-nouveau_screen_bo_release(struct pipe_screen *pscreen, struct nouveau_bo *bo);
-
 boolean
 nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
                             struct nouveau_bo *bo,
@@ -80,19 +55,4 @@ void nouveau_screen_fini(struct nouveau_screen *);
 
 void nouveau_screen_init_vdec(struct nouveau_screen *);
 
-
-#ifndef NOUVEAU_NVC0
-static INLINE unsigned
-RING_3D(unsigned mthd, unsigned size)
-{
-       return (7 << 13) | (size << 18) | mthd;
-}
-
-static INLINE unsigned
-RING_3D_NI(unsigned mthd, unsigned size)
-{
-       return 0x40000000 | (7 << 13) | (size << 18) | mthd;
-}
-#endif
-
 #endif
index dcffdd911548e3a656a9cd5b4270aba3c4dec2b2..4f8bd7bdf1621ed0d76e9843fe54000743cf36c3 100644 (file)
@@ -20,8 +20,13 @@ struct nouveau_statebuf_builder
 #define sb_data(sb, v) *(sb).p++ = (v)
 #endif
 
-#define sb_method(sb, v, n)  sb_data(sb, RING_3D(v, n));
+static INLINE uint32_t sb_header(unsigned subc, unsigned mthd, unsigned size)
+{
+       return (size << 18) | (subc << 13) | mthd;
+}
+
+#define sb_method(sb, v, n)  sb_data(sb, sb_header(SUBC_3D(v), n));
 
 #define sb_len(sb, var) ((sb).p - (var))
-#define sb_emit(chan, sb_buf, sb_len) do {WAIT_RING((chan), (sb_len)); OUT_RINGp((chan), (sb_buf), (sb_len)); } while(0)
+#define sb_emit(push, sb_buf, sb_len) do {PUSH_SPACE((push), (sb_len)); PUSH_DATAp((push), (sb_buf), (sb_len)); } while(0)
 #endif
index 42bc102b1cf5d0f4a74570ef53310c197264907f..bd8f0961bc4f39bc2065af3a65c64866f7f3a0e2 100644 (file)
 #include "nouveau_context.h"
 #include "nouveau_video.h"
 
-#include "nouveau/nouveau_bo.h"
 #include "nouveau/nouveau_buffer.h"
 #include "util/u_video.h"
 #include "util/u_format.h"
 #include "util/u_sampler.h"
-#include "nouveau/nouveau_device.h"
-#include "nouveau_winsys.h"
 
 static int
 nouveau_vpe_init(struct nouveau_decoder *dec) {
    int ret;
    if (dec->cmds)
       return 0;
-   ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR);
+   ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR, dec->client);
    if (ret) {
       debug_printf("Mapping cmd bo: %s\n", strerror(-ret));
       return ret;
    }
-   ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR);
+   ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR, dec->client);
    if (ret) {
-      nouveau_bo_unmap(dec->cmd_bo);
       debug_printf("Mapping data bo: %s\n", strerror(-ret));
       return ret;
    }
@@ -58,39 +54,45 @@ nouveau_vpe_init(struct nouveau_decoder *dec) {
 
 static void
 nouveau_vpe_synch(struct nouveau_decoder *dec) {
-   struct nouveau_channel *chan = dec->screen->channel;
+   struct nouveau_pushbuf *push = dec->push;
 #if 0
    if (dec->fence_map) {
-      BEGIN_RING(chan, dec->mpeg, NV84_MPEG_QUERY_COUNTER, 1);
-      OUT_RING(chan, ++dec->fence_seq);
-      FIRE_RING(chan);
+      BEGIN_NV04(push, NV84_MPEG(QUERY_COUNTER), 1);
+      PUSH_DATA (push, ++dec->fence_seq);
+      PUSH_KICK (push);
       while (dec->fence_map[0] != dec->fence_seq)
          usleep(1000);
    } else
 #endif
-      FIRE_RING(chan);
+      PUSH_KICK(push);
 }
 
 static void
 nouveau_vpe_fini(struct nouveau_decoder *dec) {
-   struct nouveau_channel *chan = dec->screen->channel;
+   struct nouveau_pushbuf *push = dec->push;
    if (!dec->cmds)
       return;
 
-   nouveau_bo_unmap(dec->data_bo);
-   nouveau_bo_unmap(dec->cmd_bo);
+   nouveau_pushbuf_space(push, 8, 2, 0);
+   nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_CMD);
 
-   MARK_RING(chan, 8, 2);
-   BEGIN_RING(chan, dec->mpeg, NV31_MPEG_CMD_OFFSET, 2);
-   OUT_RELOCl(chan, dec->cmd_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART);
-   OUT_RING(chan, dec->ofs * 4);
+#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_CMD, NOUVEAU_BO_RD
 
-   BEGIN_RING(chan, dec->mpeg, NV31_MPEG_DATA_OFFSET, 2);
-   OUT_RELOCl(chan, dec->data_bo, 0, NOUVEAU_BO_RD|NOUVEAU_BO_GART);
-   OUT_RING(chan, dec->data_pos * 4);
+   BEGIN_NV04(push, NV31_MPEG(CMD_OFFSET), 2);
+   PUSH_MTHDl(push, NV31_MPEG(CMD_OFFSET), dec->cmd_bo, 0, BCTX_ARGS);
+   PUSH_DATA (push, dec->ofs * 4);
 
-   BEGIN_RING(chan, dec->mpeg, NV31_MPEG_EXEC, 1);
-   OUT_RING(chan, 1);
+   BEGIN_NV04(push, NV31_MPEG(DATA_OFFSET), 2);
+   PUSH_MTHDl(push, NV31_MPEG(DATA_OFFSET), dec->data_bo, 0, BCTX_ARGS);
+   PUSH_DATA (push, dec->data_pos * 4);
+
+#undef BCTX_ARGS
+
+   if (unlikely(nouveau_pushbuf_validate(dec->push)))
+      return;
+
+   BEGIN_NV04(push, NV31_MPEG(EXEC), 1);
+   PUSH_DATA (push, 1);
 
    nouveau_vpe_synch(dec);
    dec->ofs = dec->data_pos = dec->num_surfaces = 0;
@@ -384,9 +386,10 @@ nouveau_decoder_surface_index(struct nouveau_decoder *dec,
                               struct pipe_video_buffer *buffer)
 {
    struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer;
-   struct nouveau_channel *chan = dec->screen->channel;
-   struct nouveau_bo *bo_y = ((struct nv04_resource *)buf->resources[0])->bo;
-   struct nouveau_bo *bo_c = ((struct nv04_resource *)buf->resources[1])->bo;
+   struct nouveau_pushbuf *push = dec->push;
+   struct nouveau_bo *bo_y = nv04_resource(buf->resources[0])->bo;
+   struct nouveau_bo *bo_c = nv04_resource(buf->resources[1])->bo;
+
    unsigned i;
 
    if (!buf)
@@ -399,10 +402,14 @@ nouveau_decoder_surface_index(struct nouveau_decoder *dec,
    dec->surfaces[i] = buf;
    dec->num_surfaces++;
 
-   MARK_RING(chan, 3, 2);
-   BEGIN_RING(chan, dec->mpeg, NV31_MPEG_IMAGE_Y_OFFSET(i), 2);
-   OUT_RELOCl(chan, bo_y, 0, NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, bo_c, 0, NOUVEAU_BO_RDWR);
+   nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_IMG(i));
+
+#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_IMG(i), NOUVEAU_BO_RDWR
+   BEGIN_NV04(push, NV31_MPEG(IMAGE_Y_OFFSET(i)), 2);
+   PUSH_MTHDl(push, NV31_MPEG(IMAGE_Y_OFFSET(i)), bo_y, 0, BCTX_ARGS);
+   PUSH_MTHDl(push, NV31_MPEG(IMAGE_C_OFFSET(i)), bo_c, 0, BCTX_ARGS);
+#undef BCTX_ARGS
+
    return i;
 }
 
@@ -475,18 +482,24 @@ nouveau_decoder_destroy(struct pipe_video_decoder *decoder)
 {
    struct nouveau_decoder *dec = (struct nouveau_decoder*)decoder;
 
-   if (dec->cmds) {
-      nouveau_bo_unmap(dec->data_bo);
-      nouveau_bo_unmap(dec->cmd_bo);
-   }
-
    if (dec->data_bo)
       nouveau_bo_ref(NULL, &dec->data_bo);
    if (dec->cmd_bo)
       nouveau_bo_ref(NULL, &dec->cmd_bo);
    if (dec->fence_bo)
       nouveau_bo_ref(NULL, &dec->fence_bo);
-   nouveau_grobj_free(&dec->mpeg);
+
+   nouveau_object_del(&dec->mpeg);
+
+   if (dec->bufctx)
+      nouveau_bufctx_del(&dec->bufctx);
+   if (dec->push)
+      nouveau_pushbuf_del(&dec->push);
+   if (dec->client)
+      nouveau_client_del(&dec->client);
+   if (dec->chan)
+      nouveau_object_del(&dec->chan);
+
    FREE(dec);
 }
 
@@ -499,9 +512,10 @@ nouveau_create_decoder(struct pipe_context *context,
                        unsigned width, unsigned height,
                        unsigned max_references, bool expect_chunked_decode)
 {
-   struct nouveau_channel *chan = screen->channel;
-   struct nouveau_grobj *mpeg = NULL;
+   struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
+   struct nouveau_object *mpeg = NULL;
    struct nouveau_decoder *dec;
+   struct nouveau_pushbuf *push;
    int ret;
    bool is8274 = screen->device->chipset > 0x80;
 
@@ -515,23 +529,40 @@ nouveau_create_decoder(struct pipe_context *context,
    if (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0)
       goto vl;
 
+   dec = CALLOC_STRUCT(nouveau_decoder);
+   if (!dec)
+      return NULL;
+
+   ret = nouveau_object_new(&screen->device->object, 0,
+                            NOUVEAU_FIFO_CHANNEL_CLASS,
+                            &nv04_data, sizeof(nv04_data), &dec->chan);
+   if (ret)
+      goto fail;
+   ret = nouveau_client_new(screen->device, &dec->client);
+   if (ret)
+      goto fail;
+   ret = nouveau_pushbuf_new(dec->client, dec->chan, 2, 4096, 1, &dec->push);
+   if (ret)
+      goto fail;
+   ret = nouveau_bufctx_new(dec->client, NV31_VIDEO_BIND_COUNT, &dec->bufctx);
+   if (ret)
+      goto fail;
+   push = dec->push;
+
    width = align(width, 64);
    height = align(height, 64);
 
    if (is8274)
-       ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x8274, &mpeg);
+      ret = nouveau_object_new(dec->chan, 0xbeef8274, NV84_MPEG_CLASS, NULL, 0,
+                               &mpeg);
    else
-       ret = nouveau_grobj_alloc(chan, 0xbeef8274, 0x3174, &mpeg);
+      ret = nouveau_object_new(dec->chan, 0xbeef3174, NV31_MPEG_CLASS, NULL, 0,
+                               &mpeg);
    if (ret < 0) {
       debug_printf("Creation failed: %s (%i)\n", strerror(-ret), ret);
       return NULL;
    }
 
-   dec = CALLOC_STRUCT(nouveau_decoder);
-   if (!dec) {
-      nouveau_grobj_free(&mpeg);
-      goto fail;
-   }
    dec->mpeg = mpeg;
    dec->base.context = context;
    dec->base.profile = profile;
@@ -543,61 +574,67 @@ nouveau_create_decoder(struct pipe_context *context,
    dec->base.destroy = nouveau_decoder_destroy;
    dec->base.begin_frame = nouveau_decoder_begin_frame;
    dec->base.decode_macroblock = nouveau_decoder_decode_macroblock;
-   dec->base.begin_frame = nouveau_decoder_end_frame;
+   dec->base.end_frame = nouveau_decoder_end_frame;
    dec->base.flush = nouveau_decoder_flush;
    dec->screen = screen;
 
-   ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, 1024 * 1024, &dec->cmd_bo);
+   ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
+                        0, 1024 * 1024, NULL, &dec->cmd_bo);
    if (ret)
       goto fail;
 
-   ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART, 0, width * height * 6, &dec->data_bo);
+   ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
+                        0, width * height * 6, NULL, &dec->data_bo);
    if (ret)
       goto fail;
 
-   ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART|NOUVEAU_BO_MAP, 0, 4096,
-                        &dec->fence_bo);
+   /* we don't need the fence, the kernel sync's for us */
+#if 0
+   ret = nouveau_bo_new(dec->screen->device, NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
+                        0, 4096, NULL, &dec->fence_bo);
    if (ret)
       goto fail;
-   nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR);
+   nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, NULL);
    dec->fence_map = dec->fence_bo->map;
-   nouveau_bo_unmap(dec->fence_bo);
    dec->fence_map[0] = 0;
+#endif
 
-   if (is8274)
-      MARK_RING(chan, 25, 3);
-   else
-      MARK_RING(chan, 20, 2);
+   nouveau_pushbuf_bufctx(dec->push, dec->bufctx);
+   nouveau_pushbuf_space(push, 32, 4, 0);
 
-   BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_CMD, 1);
-   OUT_RING(chan, chan->vram->handle);
+   BEGIN_NV04(push, SUBC_MPEG(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, dec->mpeg->handle);
 
-   BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_DATA, 1);
-   OUT_RING(chan, chan->vram->handle);
+   BEGIN_NV04(push, NV31_MPEG(DMA_CMD), 1);
+   PUSH_DATA (push, nv04_data.gart);
 
-   BEGIN_RING(chan, mpeg, NV31_MPEG_DMA_IMAGE, 1);
-   OUT_RING(chan, chan->vram->handle);
+   BEGIN_NV04(push, NV31_MPEG(DMA_DATA), 1);
+   PUSH_DATA (push, nv04_data.gart);
 
-   BEGIN_RING(chan, mpeg, NV31_MPEG_PITCH, 2);
-   OUT_RING(chan, width | NV31_MPEG_PITCH_UNK);
-   OUT_RING(chan, (height << NV31_MPEG_SIZE_H__SHIFT) | width);
+   BEGIN_NV04(push, NV31_MPEG(DMA_IMAGE), 1);
+   PUSH_DATA (push, nv04_data.vram);
 
-   BEGIN_RING(chan, mpeg, NV31_MPEG_FORMAT, 2);
-   OUT_RING(chan, 0);
+   BEGIN_NV04(push, NV31_MPEG(PITCH), 2);
+   PUSH_DATA (push, width | NV31_MPEG_PITCH_UNK);
+   PUSH_DATA (push, (height << NV31_MPEG_SIZE_H__SHIFT) | width);
+
+   BEGIN_NV04(push, NV31_MPEG(FORMAT), 2);
+   PUSH_DATA (push, 0);
    switch (entrypoint) {
-      case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: OUT_RING(chan, 0x100); break;
-      case PIPE_VIDEO_ENTRYPOINT_IDCT: OUT_RING(chan, 1); break;
-      case PIPE_VIDEO_ENTRYPOINT_MC: OUT_RING(chan, 0); break;
+      case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: PUSH_DATA (push, 0x100); break;
+      case PIPE_VIDEO_ENTRYPOINT_IDCT: PUSH_DATA (push, 1); break;
+      case PIPE_VIDEO_ENTRYPOINT_MC: PUSH_DATA (push, 0); break;
       default: assert(0);
    }
 
    if (is8274) {
-      BEGIN_RING(chan, mpeg, NV84_MPEG_DMA_QUERY, 1);
-      OUT_RING(chan, chan->vram->handle);
-
-      BEGIN_RING(chan, mpeg, NV84_MPEG_QUERY_OFFSET, 2);
-      OUT_RELOCl(chan, dec->fence_bo, 0, NOUVEAU_BO_WR|NOUVEAU_BO_GART);
-      OUT_RING(chan, dec->fence_seq);
+      BEGIN_NV04(push, NV84_MPEG(DMA_QUERY), 1);
+      PUSH_DATA (push, nv04_data.vram);
+#if 0
+      BEGIN_NV04(push, NV84_MPEG(QUERY_OFFSET), 2);
+      PUSH_DATA (push, dec->fence_bo->offset);
+      PUSH_DATA (push, dec->fence_seq);
+#endif
    }
 
    ret = nouveau_vpe_init(dec);
index 22593ff9bbc9210ec8f407d9e27634ac8b83a7a8..1d6ced035fb8f562410b6930be24dad96f3aa60d 100644 (file)
@@ -1,8 +1,11 @@
 #ifndef __NOUVEAU_VIDEO_H__
-#define __NOUVEAU_SCREEN_H__
+#define __NOUVEAU_VIDEO_H__
 
 #include "nv17_mpeg.xml.h"
 #include "nv31_mpeg.xml.h"
+#include "nv_object.xml.h"
+
+#include "nouveau_winsys.h"
 
 struct nouveau_video_buffer {
    struct pipe_video_buffer base;
@@ -16,7 +19,11 @@ struct nouveau_video_buffer {
 struct nouveau_decoder {
    struct pipe_video_decoder base;
    struct nouveau_screen *screen;
-   struct nouveau_grobj *mpeg;
+   struct nouveau_pushbuf *push;
+   struct nouveau_object *chan;
+   struct nouveau_client *client;
+   struct nouveau_bufctx *bufctx;
+   struct nouveau_object *mpeg;
    struct nouveau_bo *cmd_bo, *data_bo, *fence_bo;
 
    unsigned *fence_map;
@@ -34,9 +41,56 @@ struct nouveau_decoder {
    struct nouveau_video_buffer *surfaces[8];
 };
 
+#define NV31_VIDEO_BIND_IMG(i)  i
+#define NV31_VIDEO_BIND_CMD     NV31_MPEG_IMAGE_Y_OFFSET__LEN
+#define NV31_VIDEO_BIND_COUNT  (NV31_MPEG_IMAGE_Y_OFFSET__LEN + 1)
+
 static INLINE void
 nouveau_vpe_write(struct nouveau_decoder *dec, unsigned data) {
    dec->cmds[dec->ofs++] = data;
 }
 
+#define SUBC_MPEG(mthd) 1, mthd
+#define NV31_MPEG(mthd) SUBC_MPEG(NV31_MPEG_##mthd)
+#define NV84_MPEG(mthd) SUBC_MPEG(NV84_MPEG_##mthd)
+
+static INLINE uint32_t
+NV04_FIFO_PKHDR(int subc, int mthd, unsigned size)
+{
+   return 0x00000000 | (size << 18) | (subc << 13) | mthd;
+}
+
+static INLINE uint32_t
+NV04_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
+{
+   return 0x40000000 | (size << 18) | (subc << 13) | mthd;
+}
+
+static INLINE void
+BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
+{
+   PUSH_SPACE(push, size + 1);
+   PUSH_DATA (push, NV04_FIFO_PKHDR(subc, mthd, size));
+}
+
+static INLINE void
+BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
+{
+   PUSH_SPACE(push, size + 1);
+   PUSH_DATA (push, NV04_FIFO_PKHDR_NI(subc, mthd, size));
+}
+
+static INLINE void
+PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd,
+           struct nouveau_bo *bo, uint32_t offset,
+          struct nouveau_bufctx *ctx, int bin, uint32_t rw)
+{
+   nouveau_bufctx_mthd(ctx, bin, NV04_FIFO_PKHDR(subc, mthd, 1),
+                       bo, offset,
+                       NOUVEAU_BO_LOW | (bo->flags & NOUVEAU_BO_APER) | rw,
+                       0, 0);
+
+   PUSH_DATA(push, bo->offset + offset);
+}
+
 #endif
index 5c634771aff46a4bce6bc9236a4edea9f2c443c7..9fb865e170d3e827d59bd2c514d2586c165e2847 100644 (file)
@@ -6,19 +6,54 @@
 
 #include "pipe/p_defines.h"
 
-#include "nouveau/nouveau_bo.h"
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_device.h"
-#include "nouveau/nouveau_grobj.h"
-#include "nouveau/nouveau_notifier.h"
-#ifndef NOUVEAU_NVC0
-#include "nouveau/nv04_pushbuf.h"
-#endif
+#include <libdrm/nouveau.h>
 
 #ifndef NV04_PFIFO_MAX_PACKET_LEN
 #define NV04_PFIFO_MAX_PACKET_LEN 2047
 #endif
 
+static INLINE uint32_t
+PUSH_AVAIL(struct nouveau_pushbuf *push)
+{
+   return push->end - push->cur;
+}
+
+static INLINE boolean
+PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
+{
+   if (PUSH_AVAIL(push) < size)
+      return nouveau_pushbuf_space(push, size, 0, 0) == 0;
+   return TRUE;
+}
+
+static INLINE void
+PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
+{
+   *push->cur++ = data;
+}
+
+static INLINE void
+PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size)
+{
+   memcpy(push->cur, data, size * 4);
+   push->cur += size;
+}
+
+static INLINE void
+PUSH_DATAf(struct nouveau_pushbuf *push, float f)
+{
+   union { float f; uint32_t i; } u;
+   u.f = f;
+   PUSH_DATA(push, u.i);
+}
+
+static INLINE void
+PUSH_KICK(struct nouveau_pushbuf *push)
+{
+   nouveau_pushbuf_kick(push, push->channel);
+}
+
+
 #define NOUVEAU_RESOURCE_FLAG_LINEAR   (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
 #define NOUVEAU_RESOURCE_FLAG_DRV_PRIV (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
 
@@ -27,16 +62,14 @@ nouveau_screen_transfer_flags(unsigned pipe)
 {
        uint32_t flags = 0;
 
-       if (pipe & PIPE_TRANSFER_READ)
-               flags |= NOUVEAU_BO_RD;
-       if (pipe & PIPE_TRANSFER_WRITE)
-               flags |= NOUVEAU_BO_WR;
-       if (pipe & PIPE_TRANSFER_DISCARD_RANGE)
-               flags |= NOUVEAU_BO_INVAL;
-       if (pipe & PIPE_TRANSFER_UNSYNCHRONIZED)
-               flags |= NOUVEAU_BO_NOSYNC;
-       else if (pipe & PIPE_TRANSFER_DONTBLOCK)
-               flags |= NOUVEAU_BO_NOWAIT;
+       if (!(pipe & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+               if (pipe & PIPE_TRANSFER_READ)
+                       flags |= NOUVEAU_BO_RD;
+               if (pipe & PIPE_TRANSFER_WRITE)
+                       flags |= NOUVEAU_BO_WR;
+               if (pipe & PIPE_TRANSFER_DONTBLOCK)
+                       flags |= NOUVEAU_BO_NOBLOCK;
+       }
 
        return flags;
 }
index ffdaf95de62cd173050557d8da36350fbf6c0dc0..dbc96a945ef75f21360067b6bc28aab28fd16b86 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef NV_M2MF_XML
-#define NV_M2MF_XML
+#ifndef RNNDB_NV_M2MF_XML
+#define RNNDB_NV_M2MF_XML
 
 /* Autogenerated file, DO NOT EDIT manually!
 
@@ -8,13 +8,14 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
 git clone git://0x04.net/rules-ng-ng
 
 The rules-ng-ng source files this header was generated from are:
-- nv_m2mf.xml    (   2710 bytes, from 2010-08-05 19:38:53)
-- copyright.xml  (   6503 bytes, from 2010-04-10 23:15:50)
-- nv_object.xml  (  10424 bytes, from 2010-08-05 19:38:53)
-- nvchipsets.xml (   2824 bytes, from 2010-08-05 19:38:53)
-- nv_defs.xml    (   4437 bytes, from 2010-08-05 19:38:53)
-
-Copyright (C) 2006-2010 by the following authors:
+- rnndb/nv_m2mf.xml      (   2696 bytes, from 2011-07-09 13:43:58)
+- ./rnndb/copyright.xml  (   6452 bytes, from 2011-07-09 13:43:58)
+- ./rnndb/nv_object.xml  (  12672 bytes, from 2011-07-17 12:14:32)
+- ./rnndb/nvchipsets.xml (   3701 bytes, from 2012-04-06 13:21:15)
+- ./rnndb/nv_defs.xml    (   4437 bytes, from 2011-07-09 13:43:58)
+- ./rnndb/nv50_defs.xml  (   5468 bytes, from 2011-07-09 13:43:58)
+
+Copyright (C) 2006-2011 by the following authors:
 - Artur Huillet <arthur.huillet@free.fr> (ahuillet)
 - Ben Skeggs (darktama, darktama_)
 - B. R. <koala_br@users.sourceforge.net> (koala_br)
@@ -25,7 +26,7 @@ Copyright (C) 2006-2010 by the following authors:
 - Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
 - EdB <edb_@users.sf.net> (edb_)
 - Erik Waling <erikwailing@users.sf.net> (erikwaling)
-- Francisco Jerez <currojerez@riseup.net> (curro, curro_, currojerez)
+- Francisco Jerez <currojerez@riseup.net> (curro)
 - imirkin <imirkin@users.sf.net> (imirkin)
 - jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
 - Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
@@ -36,7 +37,7 @@ Copyright (C) 2006-2010 by the following authors:
 - Mark Carey <mark.carey@gmail.com> (careym)
 - Matthieu Castet <matthieu.castet@parrot.com> (mat-c)
 - nvidiaman <nvidiaman@users.sf.net> (nvidiaman)
-- Patrice Mandin <mandin.patrice@orange.fr> (pmandin, pmdata)
+- Patrice Mandin <patmandin@gmail.com> (pmandin, pmdata)
 - Pekka Paalanen <pq@iki.fi> (pq, ppaalanen)
 - Peter Popov <ironpeter@users.sf.net> (ironpeter)
 - Richard Hughes <hughsient@users.sf.net> (hughsient)
@@ -74,11 +75,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
-#define NV04_M2MF_DMA_NOTIFY                                   0x00000180
+#define NV03_M2MF_DMA_NOTIFY                                   0x00000180
 
-#define NV04_M2MF_DMA_BUFFER_IN                                        0x00000184
+#define NV03_M2MF_DMA_BUFFER_IN                                        0x00000184
 
-#define NV04_M2MF_DMA_BUFFER_OUT                               0x00000188
+#define NV03_M2MF_DMA_BUFFER_OUT                               0x00000188
 
 
 #define NV50_M2MF_LINEAR_IN                                    0x00000200
@@ -121,35 +122,35 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NV50_M2MF_OFFSET_OUT_HIGH                              0x0000023c
 
-#define NV04_M2MF_OFFSET_IN                                    0x0000030c
+#define NV03_M2MF_OFFSET_IN                                    0x0000030c
 
-#define NV04_M2MF_OFFSET_OUT                                   0x00000310
+#define NV03_M2MF_OFFSET_OUT                                   0x00000310
 
-#define NV04_M2MF_PITCH_IN                                     0x00000314
+#define NV03_M2MF_PITCH_IN                                     0x00000314
 
-#define NV04_M2MF_PITCH_OUT                                    0x00000318
+#define NV03_M2MF_PITCH_OUT                                    0x00000318
 
-#define NV04_M2MF_LINE_LENGTH_IN                               0x0000031c
+#define NV03_M2MF_LINE_LENGTH_IN                               0x0000031c
 
-#define NV04_M2MF_LINE_COUNT                                   0x00000320
+#define NV03_M2MF_LINE_COUNT                                   0x00000320
 
-#define NV04_M2MF_FORMAT                                       0x00000324
-#define NV04_M2MF_FORMAT_INPUT_INC__MASK                       0x000000ff
-#define NV04_M2MF_FORMAT_INPUT_INC__SHIFT                      0
-#define NV04_M2MF_FORMAT_INPUT_INC_1                           0x00000001
-#define NV04_M2MF_FORMAT_INPUT_INC_2                           0x00000002
-#define NV04_M2MF_FORMAT_INPUT_INC_4                           0x00000004
+#define NV03_M2MF_FORMAT                                       0x00000324
+#define NV03_M2MF_FORMAT_INPUT_INC__MASK                       0x000000ff
+#define NV03_M2MF_FORMAT_INPUT_INC__SHIFT                      0
+#define NV03_M2MF_FORMAT_INPUT_INC_1                           0x00000001
+#define NV03_M2MF_FORMAT_INPUT_INC_2                           0x00000002
+#define NV03_M2MF_FORMAT_INPUT_INC_4                           0x00000004
 #define NV50_M2MF_FORMAT_INPUT_INC_8                           0x00000008
 #define NV50_M2MF_FORMAT_INPUT_INC_16                          0x00000010
-#define NV04_M2MF_FORMAT_OUTPUT_INC__MASK                      0x0000ff00
-#define NV04_M2MF_FORMAT_OUTPUT_INC__SHIFT                     8
-#define NV04_M2MF_FORMAT_OUTPUT_INC_1                          0x00000100
-#define NV04_M2MF_FORMAT_OUTPUT_INC_2                          0x00000200
-#define NV04_M2MF_FORMAT_OUTPUT_INC_4                          0x00000400
+#define NV03_M2MF_FORMAT_OUTPUT_INC__MASK                      0x0000ff00
+#define NV03_M2MF_FORMAT_OUTPUT_INC__SHIFT                     8
+#define NV03_M2MF_FORMAT_OUTPUT_INC_1                          0x00000100
+#define NV03_M2MF_FORMAT_OUTPUT_INC_2                          0x00000200
+#define NV03_M2MF_FORMAT_OUTPUT_INC_4                          0x00000400
 #define NV50_M2MF_FORMAT_OUTPUT_INC_8                          0x00000800
 #define NV50_M2MF_FORMAT_OUTPUT_INC_16                         0x00001000
 
-#define NV04_M2MF_BUF_NOTIFY                                   0x00000328
+#define NV03_M2MF_BUF_NOTIFY                                   0x00000328
 
 
-#endif /* NV_M2MF_XML */
+#endif /* RNNDB_NV_M2MF_XML */
index 47dc67510410e992c70c29dbf285ac95b82c5cd0..d87d7139bf3073cc2c3c3d8de7e700fe57d043df 100644 (file)
@@ -1,5 +1,10 @@
-#ifndef NV_OBJECT_XML
-#define NV_OBJECT_XML
+#ifndef RNNDB_NV_OBJECT_XML
+#define RNNDB_NV_OBJECT_XML
+
+/* WARNING ABOUT NOT EDITING AUTOGENERATED FILE IGNORED, _CLASS SUFFIX HAS
+ * BEEN ADDED TO ALL THE OBJECT CLASS DEFINITIONS TO AVOID CONFLICTS WITH
+ * THE RING MACROS WE WANT TO USE
+ */
 
 /* Autogenerated file, DO NOT EDIT manually!
 
@@ -8,12 +13,13 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
 git clone git://0x04.net/rules-ng-ng
 
 The rules-ng-ng source files this header was generated from are:
-- nv_object.xml  (  11547 bytes, from 2010-10-24 15:29:34)
-- copyright.xml  (   6498 bytes, from 2010-10-03 13:18:37)
-- nvchipsets.xml (   2907 bytes, from 2010-10-15 16:28:21)
-- nv_defs.xml    (   4437 bytes, from 2010-07-06 07:43:58)
+- rnndb/nv_object.xml    (  12672 bytes, from 2011-07-17 12:14:32)
+- ./rnndb/copyright.xml  (   6452 bytes, from 2011-07-09 13:43:58)
+- ./rnndb/nvchipsets.xml (   3701 bytes, from 2012-04-06 13:21:15)
+- ./rnndb/nv_defs.xml    (   4437 bytes, from 2011-07-09 13:43:58)
+- ./rnndb/nv50_defs.xml  (   5468 bytes, from 2011-07-09 13:43:58)
 
-Copyright (C) 2006-2010 by the following authors:
+Copyright (C) 2006-2011 by the following authors:
 - Artur Huillet <arthur.huillet@free.fr> (ahuillet)
 - Ben Skeggs (darktama, darktama_)
 - B. R. <koala_br@users.sourceforge.net> (koala_br)
@@ -24,7 +30,7 @@ Copyright (C) 2006-2010 by the following authors:
 - Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
 - EdB <edb_@users.sf.net> (edb_)
 - Erik Waling <erikwailing@users.sf.net> (erikwaling)
-- Francisco Jerez <currojerez@riseup.net> (curro, curro_, currojerez)
+- Francisco Jerez <currojerez@riseup.net> (curro)
 - imirkin <imirkin@users.sf.net> (imirkin)
 - jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
 - Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
@@ -72,114 +78,129 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 
-#define NV01_ROOT                                              0x00000001
-#define NV01_CONTEXT_DMA                                       0x00000002
-#define NV01_DEVICE                                            0x00000003
-#define NV01_TIMER                                             0x00000004
-#define NV01_NULL                                              0x00000030
-#define NV01_MEMORY_LOCAL_BANKED                               0x0000003d
-#define NV01_MAPPING_SYSTEM                                    0x0000003e
-#define NV03_MEMORY_LOCAL_CURSOR                               0x0000003f
-#define NV01_MEMORY_LOCAL_LINEAR                               0x00000040
-#define NV01_MAPPING_LOCAL                                     0x00000041
-#define NV03_VIDEO_LUT_CURSOR_DAC                              0x00000046
-#define NV03_CHANNEL_PIO                                       0x0000006a
-#define NV03_CHANNEL_DMA                                       0x0000006b
-#define NV10_VIDEO_DISPLAY                                     0x0000007c
-#define NV01_CONTEXT_BETA1                                     0x00000012
-#define NV04_BETA_SOLID                                                0x00000072
-#define NV01_CONTEXT_COLOR_KEY                                 0x00000017
-#define NV04_CONTEXT_COLOR_KEY                                 0x00000057
-#define NV01_CONTEXT_PATTERN                                   0x00000018
-#define NV01_CONTEXT_CLIP_RECTANGLE                            0x00000019
-#define NV03_CONTEXT_ROP                                       0x00000043
-#define NV04_IMAGE_PATTERN                                     0x00000044
-#define NV01_RENDER_SOLID_LINE                                 0x0000001c
-#define NV04_RENDER_SOLID_LINE                                 0x0000005c
-#define NV30_RENDER_SOLID_LINE                                 0x0000035c
-#define NV40_RENDER_SOLID_LINE                                 0x0000305c
-#define NV01_RENDER_SOLID_TRIANGLE                             0x0000001d
-#define NV04_RENDER_SOLID_TRIANGLE                             0x0000005d
-#define NV01_RENDER_SOLID_RECTANGLE                            0x0000001e
-#define NV04_RENDER_SOLID_RECTANGLE                            0x0000005e
-#define NV01_IMAGE_BLIT                                                0x0000001f
-#define NV04_IMAGE_BLIT                                                0x0000005f
-#define NV11_IMAGE_BLIT                                                0x0000009f
-#define NV01_IMAGE_FROM_CPU                                    0x00000021
-#define NV04_IMAGE_FROM_CPU                                    0x00000061
-#define NV05_IMAGE_FROM_CPU                                    0x00000065
-#define NV10_IMAGE_FROM_CPU                                    0x0000008a
-#define NV30_IMAGE_FROM_CPU                                    0x0000038a
-#define NV40_IMAGE_FROM_CPU                                    0x0000308a
-#define NV03_STRETCHED_IMAGE_FROM_CPU                          0x00000036
-#define NV04_STRETCHED_IMAGE_FROM_CPU                          0x00000076
-#define NV05_STRETCHED_IMAGE_FROM_CPU                          0x00000066
-#define NV30_STRETCHED_IMAGE_FROM_CPU                          0x00000366
-#define NV40_STRETCHED_IMAGE_FROM_CPU                          0x00003066
-#define NV03_SCALED_IMAGE_FROM_MEMORY                          0x00000037
-#define NV04_SCALED_IMAGE_FROM_MEMORY                          0x00000077
-#define NV05_SCALED_IMAGE_FROM_MEMORY                          0x00000063
-#define NV10_SCALED_IMAGE_FROM_MEMORY                          0x00000089
-#define NV30_SCALED_IMAGE_FROM_MEMORY                          0x00000389
-#define NV40_SCALED_IMAGE_FROM_MEMORY                          0x00003089
-#define NV50_SCALED_IMAGE_FROM_MEMORY                          0x00005089
-#define NV04_DVD_SUBPICTURE                                    0x00000038
-#define NV10_DVD_SUBPICTURE                                    0x00000088
-#define NV03_GDI_RECTANGLE_TEXT                                        0x0000004b
-#define NV04_GDI_RECTANGLE_TEXT                                        0x0000004a
-#define NV04_SWIZZLED_SURFACE                                  0x00000052
-#define NV11_SWIZZLED_SURFACE                                  0x0000009e
-#define NV30_SWIZZLED_SURFACE                                  0x0000039e
-#define NV40_SWIZZLED_SURFACE                                  0x0000309e
-#define NV03_CONTEXT_SURFACE_DST                               0x00000058
-#define NV03_CONTEXT_SURFACE_SRC                               0x00000059
-#define NV04_CONTEXT_SURFACES_2D                               0x00000042
-#define NV10_CONTEXT_SURFACES_2D                               0x00000062
-#define NV30_CONTEXT_SURFACES_2D                               0x00000362
-#define NV40_CONTEXT_SURFACES_2D                               0x00003062
-#define NV50_CONTEXT_SURFACES_2D                               0x00005062
-#define NV04_INDEXED_IMAGE_FROM_CPU                            0x00000060
-#define NV05_INDEXED_IMAGE_FROM_CPU                            0x00000064
-#define NV30_INDEXED_IMAGE_FROM_CPU                            0x00000364
-#define NV40_INDEXED_IMAGE_FROM_CPU                            0x00003064
-#define NV10_TEXTURE_FROM_CPU                                  0x0000007b
-#define NV30_TEXTURE_FROM_CPU                                  0x0000037b
-#define NV40_TEXTURE_FROM_CPU                                  0x0000307b
-#define NV04_M2MF                                              0x00000039
-#define NV50_M2MF                                              0x00005039
-#define NVC0_M2MF                                              0x00009039
-#define NV03_TEXTURED_TRIANGLE                                 0x00000048
-#define NV04_TEXTURED_TRIANGLE                                 0x00000054
-#define NV10_TEXTURED_TRIANGLE                                 0x00000094
-#define NV04_MULTITEX_TRIANGLE                                 0x00000055
-#define NV10_MULTITEX_TRIANGLE                                 0x00000095
-#define NV03_CONTEXT_SURFACE_COLOR                             0x0000005a
-#define NV03_CONTEXT_SURFACE_ZETA                              0x0000005b
-#define NV04_CONTEXT_SURFACES_3D                               0x00000053
-#define NV10_CONTEXT_SURFACES_3D                               0x00000093
-#define NV10_3D                                                        0x00000056
-#define NV11_3D                                                        0x00000096
-#define NV17_3D                                                        0x00000099
-#define NV20_3D                                                        0x00000097
-#define NV25_3D                                                        0x00000597
-#define NV30_3D                                                        0x00000397
-#define NV35_3D                                                        0x00000497
-#define NV34_3D                                                        0x00000697
-#define NV40_3D                                                        0x00004097
-#define NV44_3D                                                        0x00004497
-#define NV50_3D                                                        0x00005097
-#define NV84_3D                                                        0x00008297
-#define NVA0_3D                                                        0x00008397
-#define NVA3_3D                                                        0x00008597
-#define NVAF_3D                                                        0x00008697
-#define NVC0_3D                                                        0x00009097
-#define NV50_2D                                                        0x0000502d
-#define NVC0_2D                                                        0x0000902d
-#define NV50_COMPUTE                                           0x000050c0
-#define NVA3_COMPUTE                                           0x000085c0
-#define NVC0_COMPUTE                                           0x000090c0
-#define NV84_CRYPT                                             0x000074c1
-#define NV01_SUBCHAN__SIZE                                     0x00002000
+#define NV01_DMA_FROM_MEMORY_CLASS                             0x00000002
+#define NV01_DMA_TO_MEMORY_CLASS                               0x00000003
+#define NV01_NULL_CLASS                                                0x00000030
+#define NV03_DMA_IN_MEMORY_CLASS                               0x0000003d
+#define NV01_OP_CLIP_CLASS                                     0x00000010
+#define NV01_OP_BLEND_AND_CLASS                                        0x00000011
+#define NV01_BETA_CLASS                                                0x00000012
+#define NV04_BETA4_CLASS                                       0x00000072
+#define NV01_OP_ROP_AND_CLASS                                  0x00000013
+#define NV01_ROP_CLASS                                         0x00000014
+#define NV03_ROP_CLASS                                         0x00000043
+#define NV01_OP_CHROMA_CLASS                                   0x00000015
+#define NV01_OP_PLANE_SWITCH_CLASS                             0x00000016
+#define NV01_CHROMA_CLASS                                      0x00000017
+#define NV04_CHROMA_CLASS                                      0x00000057
+#define NV01_PATTERN_CLASS                                     0x00000018
+#define NV04_PATTERN_CLASS                                     0x00000044
+#define NV01_CLIP_CLASS                                                0x00000019
+#define NV01_OP_SRCCOPY_AND_CLASS                              0x00000064
+#define NV03_OP_SRCCOPY_CLASS                                  0x00000065
+#define NV04_OP_SRCCOPY_PREMULT_CLASS                          0x00000066
+#define NV04_OP_BLEND_PREMULT_CLASS                            0x00000067
+#define NV01_POINT_CLASS                                       0x0000001a
+#define NV01_LINE_CLASS                                                0x0000001b
+#define NV01_LIN_CLASS                                         0x0000001c
+#define NV04_LIN_CLASS                                         0x0000005c
+#define NV30_LIN_CLASS                                         0x0000035c
+#define NV40_LIN_CLASS                                         0x0000305c
+#define NV01_TRI_CLASS                                         0x0000001d
+#define NV04_TRI_CLASS                                         0x0000005d
+#define NV01_RECT_CLASS                                                0x0000001e
+#define NV04_RECT_CLASS                                                0x0000005e
+#define NV01_BLIT_CLASS                                                0x0000001f
+#define NV04_BLIT_CLASS                                                0x0000005f
+#define NV15_BLIT_CLASS                                                0x0000009f
+#define NV01_IFROMMEM_CLASS                                    0x00000020
+#define NV01_IFC_CLASS                                         0x00000021
+#define NV04_IFC_CLASS                                         0x00000061
+#define NV05_IFC_CLASS                                         0x00000065
+#define NV10_IFC_CLASS                                         0x0000008a
+#define NV30_IFC_CLASS                                         0x0000038a
+#define NV40_IFC_CLASS                                         0x0000308a
+#define NV01_BITMAP_CLASS                                      0x00000022
+#define NV01_ITOMEM_CLASS                                      0x00000025
+#define NV03_SIFC_CLASS                                                0x00000036
+#define NV04_SIFC_CLASS                                                0x00000076
+#define NV05_SIFC_CLASS                                                0x00000066
+#define NV30_SIFC_CLASS                                                0x00000366
+#define NV40_SIFC_CLASS                                                0x00003066
+#define NV03_SIFM_CLASS                                                0x00000037
+#define NV04_SIFM_CLASS                                                0x00000077
+#define NV05_SIFM_CLASS                                                0x00000063
+#define NV10_SIFM_CLASS                                                0x00000089
+#define NV30_SIFM_CLASS                                                0x00000389
+#define NV40_SIFM_CLASS                                                0x00003089
+#define NV50_SIFM_CLASS                                                0x00005089
+#define NV03_SYFM_CLASS                                                0x00000038
+#define NV03_GDI_CLASS                                         0x0000004b
+#define NV04_GDI_CLASS                                         0x0000004a
+#define NV04_SURFACE_SWZ_CLASS                                 0x00000052
+#define NV20_SURFACE_SWZ_CLASS                                 0x0000009e
+#define NV30_SURFACE_SWZ_CLASS                                 0x0000039e
+#define NV40_SURFACE_SWZ_CLASS                                 0x0000309e
+#define NV03_SURFACE_DST_CLASS                                 0x00000058
+#define NV03_SURFACE_SRC_CLASS                                 0x00000059
+#define NV04_SURFACE_2D_CLASS                                  0x00000042
+#define NV10_SURFACE_2D_CLASS                                  0x00000062
+#define NV30_SURFACE_2D_CLASS                                  0x00000362
+#define NV40_SURFACE_2D_CLASS                                  0x00003062
+#define NV50_SURFACE_2D_CLASS                                  0x00005062
+#define NV04_INDEX_CLASS                                       0x00000060
+#define NV05_INDEX_CLASS                                       0x00000064
+#define NV30_INDEX_CLASS                                       0x00000364
+#define NV40_INDEX_CLASS                                       0x00003064
+#define NV10_TEXUPLOAD_CLASS                                   0x0000007b
+#define NV30_TEXUPLOAD_CLASS                                   0x0000037b
+#define NV40_TEXUPLOAD_CLASS                                   0x0000307b
+#define NV04_DVD_SUBPICTURE_CLASS                              0x00000038
+#define NV10_DVD_SUBPICTURE_CLASS                              0x00000088
+#define NV03_M2MF_CLASS                                                0x00000039
+#define NV50_M2MF_CLASS                                                0x00005039
+#define NVC0_M2MF_CLASS                                                0x00009039
+#define NV03_SURFACE_COLOR_CLASS                               0x0000005a
+#define NV03_SURFACE_ZETA_CLASS                                        0x0000005b
+#define NV03_TEXTURED_TRIANGLE_CLASS                           0x00000048
+#define NV04_TEXTURED_TRIANGLE_CLASS                           0x00000054
+#define NV10_TEXTURED_TRIANGLE_CLASS                           0x00000094
+#define NV04_SURFACE_3D_CLASS                                  0x00000053
+#define NV10_SURFACE_3D_CLASS                                  0x00000093
+#define NV04_MULTITEX_TRIANGLE_CLASS                           0x00000055
+#define NV10_MULTITEX_TRIANGLE_CLASS                           0x00000095
+#define NV10_3D_CLASS                                          0x00000056
+#define NV15_3D_CLASS                                          0x00000096
+#define NV11_3D_CLASS                                          0x00000098
+#define NV17_3D_CLASS                                          0x00000099
+#define NV20_3D_CLASS                                          0x00000097
+#define NV25_3D_CLASS                                          0x00000597
+#define NV30_3D_CLASS                                          0x00000397
+#define NV35_3D_CLASS                                          0x00000497
+#define NV34_3D_CLASS                                          0x00000697
+#define NV40_3D_CLASS                                          0x00004097
+#define NV44_3D_CLASS                                          0x00004497
+#define NV50_3D_CLASS                                          0x00005097
+#define NV84_3D_CLASS                                          0x00008297
+#define NVA0_3D_CLASS                                          0x00008397
+#define NVA3_3D_CLASS                                          0x00008597
+#define NVAF_3D_CLASS                                          0x00008697
+#define NVC0_3D_CLASS                                          0x00009097
+#define NVC1_3D_CLASS                                          0x00009197
+#define NVC8_3D_CLASS                                          0x00009297
+#define NV50_2D_CLASS                                          0x0000502d
+#define NVC0_2D_CLASS                                          0x0000902d
+#define NV50_COMPUTE_CLASS                                     0x000050c0
+#define NVA3_COMPUTE_CLASS                                     0x000085c0
+#define NVC0_COMPUTE_CLASS                                     0x000090c0
+#define NVC8_COMPUTE_CLASS                                     0x000092c0
+#define NV84_CRYPT_CLASS                                       0x000074c1
+#define BLOB_NVC0_PCOPY1_CLASS                                 0x000090b8
+#define BLOB_NVC0_PCOPY0_CLASS                                 0x000090b5
+#define NV31_MPEG_CLASS                                                0x00003174
+#define NV84_MPEG_CLASS                                                0x00008274
+
+#define NV01_SUBCHAN__SIZE                                     0x00008000
 #define NV01_SUBCHAN                                           0x00000000
 
 #define NV01_SUBCHAN_OBJECT                                    0x00000000
@@ -217,55 +238,64 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NV04_GRAPH_NOP                                         0x00000100
 
-#define NV01_GRAPH_NOTIFY                                      0x00000104
-#define NV01_GRAPH_NOTIFY_WRITE                                        0x00000000
-#define NV01_GRAPH_NOTIFY_WRITE_AND_AWAKEN                     0x00000001
-
-#define NV50_GRAPH_WAIT_FOR_IDLE                               0x00000110
+#define NV04_GRAPH_NOTIFY                                      0x00000104
+#define NV04_GRAPH_NOTIFY_WRITE                                        0x00000000
+#define NV04_GRAPH_NOTIFY_WRITE_AND_AWAKEN                     0x00000001
 
-#define NVA3_GRAPH_UNK0120                                     0x00000120
+#define NVC0_GRAPH_NOTIFY_ADDRESS_HIGH                         0x00000104
 
-#define NVA3_GRAPH_UNK0124                                     0x00000124
+#define NVC0_GRAPH_NOTIFY_ADDRESS_LOW                          0x00000108
 
-#define NV40_GRAPH_PM_TRIGGER                                  0x00000140
+#define NVC0_GRAPH_NOTIFY                                      0x0000010c
+#define NVC0_GRAPH_NOTIFY_WRITE                                        0x00000000
+#define NVC0_GRAPH_NOTIFY_WRITE_AND_AWAKEN                     0x00000001
 
-#define NVC0_SUBCHAN__SIZE                                     0x00008000
-#define NVC0_SUBCHAN                                           0x00000000
+#define NV50_GRAPH_SERIALIZE                                   0x00000110
 
-#define NVC0_SUBCHAN_OBJECT                                    0x00000000
+#define NVC0_GRAPH_MACRO_UPLOAD_POS                            0x00000114
 
+#define NVC0_GRAPH_MACRO_UPLOAD_DATA                           0x00000118
 
-#define NVC0_SUBCHAN_QUERY_ADDRESS_HIGH                                0x00000010
+#define NVC0_GRAPH_MACRO_ID                                    0x0000011c
 
-#define NVC0_SUBCHAN_QUERY_ADDRESS_LOW                         0x00000014
+#define NVC0_GRAPH_MACRO_POS                                   0x00000120
 
-#define NVC0_SUBCHAN_QUERY_SEQUENCE                            0x00000018
+#define NVA3_GRAPH_UNK0120                                     0x00000120
 
-#define NVC0_SUBCHAN_QUERY_GET                                 0x0000001c
+#define NVA3_GRAPH_UNK0124                                     0x00000124
 
-#define NVC0_SUBCHAN_REF_CNT                                   0x00000050
+#define NVC0_GRAPH_UNK0124                                     0x00000124
 
-#define NVC0_GRAPH                                             0x00000000
+#define NVC0_GRAPH_COND_ADDRESS_HIGH                           0x00000130
 
-#define NVC0_GRAPH_NOP                                         0x00000100
+#define NVC0_GRAPH_COND_ADDRESS_LOW                            0x00000134
 
-#define NVC0_GRAPH_NOTIFY_ADDRESS_HIGH                         0x00000104
+#define NVC0_GRAPH_COND_MODE                                   0x00000138
+#define NVC0_GRAPH_COND_MODE_NEVER                             0x00000000
+#define NVC0_GRAPH_COND_MODE_ALWAYS                            0x00000001
+#define NVC0_GRAPH_COND_MODE_RES_NON_ZERO                      0x00000002
+#define NVC0_GRAPH_COND_MODE_EQUAL                             0x00000003
+#define NVC0_GRAPH_COND_MODE_NOT_EQUAL                         0x00000004
 
-#define NVC0_GRAPH_NOTIFY_ADDRESS_LOW                          0x00000108
+#define NVC0_GRAPH_UNK013C                                     0x0000013c
 
-#define NVC0_GRAPH_NOTIFY                                      0x0000010c
-#define NVC0_GRAPH_NOTIFY_WRITE                                        0x00000000
-#define NVC0_GRAPH_NOTIFY_WRITE_AND_AWAKEN                     0x00000001
+#define NV40_GRAPH_PM_TRIGGER                                  0x00000140
 
-#define NVC0_GRAPH_SERIALIZE                                   0x00000110
+#define NVC0_GRAPH_UNK0150                                     0x00000150
 
-#define NVC0_GRAPH_MACRO_UPLOAD_POS                            0x00000114
+#define NVC0_GRAPH_UNK0154                                     0x00000154
 
-#define NVC0_GRAPH_MACRO_UPLOAD_DATA                           0x00000118
+#define NVC0_GRAPH_SCRATCH(i0)                                (0x00003400 + 0x4*(i0))
+#define NVC0_GRAPH_SCRATCH__ESIZE                              0x00000004
+#define NVC0_GRAPH_SCRATCH__LEN                                        0x00000080
 
-#define NVC0_GRAPH_MACRO_ID                                    0x0000011c
+#define NVC0_GRAPH_MACRO(i0)                                  (0x00003800 + 0x8*(i0))
+#define NVC0_GRAPH_MACRO__ESIZE                                        0x00000008
+#define NVC0_GRAPH_MACRO__LEN                                  0x00000080
 
-#define NVC0_GRAPH_MACRO_POS                                   0x00000120
+#define NVC0_GRAPH_MACRO_PARAM(i0)                            (0x00003804 + 0x8*(i0))
+#define NVC0_GRAPH_MACRO_PARAM__ESIZE                          0x00000008
+#define NVC0_GRAPH_MACRO_PARAM__LEN                            0x00000080
 
 
-#endif /* NV_OBJECT_XML */
+#endif /* RNNDB_NV_OBJECT_XML */
index 0f5a77de9a18d3071bbb753e9527a4cfddfd9580..9dff8b2dd13b422dac93c8429e1ce7cac48350dc 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef NV50_3D_XML
-#define NV50_3D_XML
+#ifndef RNNDB_NV50_3D_XML
+#define RNNDB_NV50_3D_XML
 
 /* Autogenerated file, DO NOT EDIT manually!
 
@@ -8,15 +8,15 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
 git clone git://0x04.net/rules-ng-ng
 
 The rules-ng-ng source files this header was generated from are:
-- nv50_3d.xml    (  64479 bytes, from 2011-02-27 17:58:08)
-- copyright.xml  (   6452 bytes, from 2010-12-15 23:45:18)
-- nv_defs.xml    (   4437 bytes, from 2010-12-15 23:45:18)
-- nv50_defs.xml  (   4487 bytes, from 2010-12-15 23:45:18)
-- nv_3ddefs.xml  (  16394 bytes, from 2010-12-15 23:45:18)
-- nv_object.xml  (  12191 bytes, from 2011-02-27 17:58:08)
-- nvchipsets.xml (   3074 bytes, from 2011-02-27 17:58:08)
-
-Copyright (C) 2006-2011 by the following authors:
+- rnndb/nv50_3d.xml      (  65226 bytes, from 2012-01-28 13:46:30)
+- ./rnndb/copyright.xml  (   6452 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv_defs.xml    (   4437 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv50_defs.xml  (   5468 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nvchipsets.xml (   3617 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv_3ddefs.xml  (  16394 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv_object.xml  (  12672 bytes, from 2011-08-11 18:25:12)
+
+Copyright (C) 2006-2012 by the following authors:
 - Artur Huillet <arthur.huillet@free.fr> (ahuillet)
 - Ben Skeggs (darktama, darktama_)
 - B. R. <koala_br@users.sourceforge.net> (koala_br)
@@ -74,7 +74,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#define NV50_3D_SERIALIZE              0x00000110
+
 
 #define NV50_3D_DMA_NOTIFY                                     0x00000180
 
@@ -592,9 +592,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NV50_3D_CLIPID_ADDRESS_LOW                             0x00000fd0
 
-#define NV50_3D_MAP_SEMANTIC_5                                 0x00000fd4
-#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__MASK               0x000000ff
-#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__SHIFT              0
+#define NV50_3D_SEMANTIC_VIEWPORT                              0x00000fd4
+#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__MASK            0x000000ff
+#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__SHIFT           0
 
 #define NV50_3D_UNK0FD8                                                0x00000fd8
 #define NV50_3D_UNK0FD8_UNK0                                   0x00000001
@@ -1184,7 +1184,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_3D_BIND_TSC2__ESIZE                               0x00000008
 #define NV50_3D_BIND_TSC2__LEN                                 0x00000003
 #define NV50_3D_BIND_TSC2_VALID                                        0x00000001
-#define NV50_3D_BIND_TSC2_SAMPLER__MASK                                0x000000f0
+#define NV50_3D_BIND_TSC2_SAMPLER__MASK                                0x00000010
 #define NV50_3D_BIND_TSC2_SAMPLER__SHIFT                       4
 #define NV50_3D_BIND_TSC2_TSC__MASK                            0x001ff000
 #define NV50_3D_BIND_TSC2_TSC__SHIFT                           12
@@ -1193,7 +1193,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_3D_BIND_TIC2__ESIZE                               0x00000008
 #define NV50_3D_BIND_TIC2__LEN                                 0x00000003
 #define NV50_3D_BIND_TIC2_VALID                                        0x00000001
-#define NV50_3D_BIND_TIC2_TEXTURE__MASK                                0x000001fe
+#define NV50_3D_BIND_TIC2_TEXTURE__MASK                                0x00000002
 #define NV50_3D_BIND_TIC2_TEXTURE__SHIFT                       1
 #define NV50_3D_BIND_TIC2_TIC__MASK                            0x7ffffe00
 #define NV50_3D_BIND_TIC2_TIC__SHIFT                           9
@@ -1217,15 +1217,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK               0xffff0000
 #define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT              16
 
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE                                0x00001510
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_0                      0x00000001
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_1                      0x00000002
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_2                      0x00000004
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_3                      0x00000008
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_4                      0x00000010
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_5                      0x00000020
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_6                      0x00000040
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_7                      0x00000080
+#define NV50_3D_CLIP_DISTANCE_ENABLE                           0x00001510
+#define NV50_3D_CLIP_DISTANCE_ENABLE_0                         0x00000001
+#define NV50_3D_CLIP_DISTANCE_ENABLE_1                         0x00000002
+#define NV50_3D_CLIP_DISTANCE_ENABLE_2                         0x00000004
+#define NV50_3D_CLIP_DISTANCE_ENABLE_3                         0x00000008
+#define NV50_3D_CLIP_DISTANCE_ENABLE_4                         0x00000010
+#define NV50_3D_CLIP_DISTANCE_ENABLE_5                         0x00000020
+#define NV50_3D_CLIP_DISTANCE_ENABLE_6                         0x00000040
+#define NV50_3D_CLIP_DISTANCE_ENABLE_7                         0x00000080
 
 #define NV50_3D_SAMPLECNT_ENABLE                               0x00001514
 
@@ -1391,9 +1391,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_3D_MULTISAMPLE_MODE_MS8                           0x00000003
 #define NV50_3D_MULTISAMPLE_MODE_MS8_ALT                       0x00000004
 #define NV50_3D_MULTISAMPLE_MODE_MS2_ALT                       0x00000005
+#define NV50_3D_MULTISAMPLE_MODE_UNK6                          0x00000006
 #define NV50_3D_MULTISAMPLE_MODE_MS4_CS4                       0x00000008
 #define NV50_3D_MULTISAMPLE_MODE_MS4_CS12                      0x00000009
 #define NV50_3D_MULTISAMPLE_MODE_MS8_CS8                       0x0000000a
+#define NV50_3D_MULTISAMPLE_MODE_MS8_CS24                      0x0000000b
 
 #define NV50_3D_VERTEX_BEGIN_D3D                               0x000015d4
 #define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK               0x0fffffff
@@ -1440,7 +1442,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_3D_VERTEX_END_GL_UNK0                             0x00000001
 #define NVA0_3D_VERTEX_END_GL_UNK1                             0x00000002
 
-#define NV50_3D_EDGEFLAG_ENABLE                                        0x000015e4
+#define NV50_3D_EDGEFLAG                                       0x000015e4
 
 #define NV50_3D_VB_ELEMENT_U32                                 0x000015e8
 
@@ -1666,34 +1668,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NV50_3D_GP_VIEWPORT_ID_ENABLE                          0x00001900
 
-#define NV50_3D_MAP_SEMANTIC_0                                 0x00001904
-#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__MASK                   0x000000ff
-#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT                  0
-#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__MASK                   0x0000ff00
-#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__SHIFT                  8
-#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__MASK                   0x00ff0000
-#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__SHIFT                  16
-#define NV50_3D_MAP_SEMANTIC_0_CLMP_EN                         0x01000000
-
-#define NV50_3D_MAP_SEMANTIC_1                                 0x00001908
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__MASK                        0x000000ff
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__SHIFT               0
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__MASK                  0x00000f00
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__SHIFT                 8
-
-#define NV50_3D_MAP_SEMANTIC_2                                 0x0000190c
-#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__MASK                  0x000000ff
-#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__SHIFT                 0
-
-#define NV50_3D_MAP_SEMANTIC_3                                 0x00001910
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK                   0x00000001
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__SHIFT                  0
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__MASK                   0x00000ff0
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__SHIFT                  4
-
-#define NV50_3D_MAP_SEMANTIC_4                                 0x00001914
-#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__MASK                   0x000000ff
-#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__SHIFT                  0
+#define NV50_3D_SEMANTIC_COLOR                                 0x00001904
+#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__MASK                   0x000000ff
+#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT                  0
+#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__MASK                   0x0000ff00
+#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__SHIFT                  8
+#define NV50_3D_SEMANTIC_COLOR_COLR_NR__MASK                   0x00ff0000
+#define NV50_3D_SEMANTIC_COLOR_COLR_NR__SHIFT                  16
+#define NV50_3D_SEMANTIC_COLOR_CLMP_EN                         0x01000000
+
+#define NV50_3D_SEMANTIC_CLIP                                  0x00001908
+#define NV50_3D_SEMANTIC_CLIP_CLIP_START__MASK                 0x000000ff
+#define NV50_3D_SEMANTIC_CLIP_CLIP_START__SHIFT                        0
+#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__MASK                   0x00000f00
+#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__SHIFT                  8
+
+#define NV50_3D_SEMANTIC_LAYER                                 0x0000190c
+#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__MASK                  0x000000ff
+#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__SHIFT                 0
+
+#define NV50_3D_SEMANTIC_PTSZ                                  0x00001910
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK                    0x00000001
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__SHIFT                   0
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__MASK                    0x00000ff0
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__SHIFT                   4
+
+#define NV50_3D_SEMANTIC_PRIM_ID                               0x00001914
+#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__MASK                 0x000000ff
+#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__SHIFT                        0
 
 #define NV50_3D_CULL_FACE_ENABLE                               0x00001918
 
@@ -1729,15 +1731,39 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1               0x00001000
 #define NV84_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2               0x00002000
 
-#define NV50_3D_UNK1940                                                0x00001940
-#define NV50_3D_UNK1940_0                                      0x00000001
-#define NV50_3D_UNK1940_1                                      0x00000010
-#define NV50_3D_UNK1940_2                                      0x00000100
-#define NV50_3D_UNK1940_3                                      0x00001000
-#define NV50_3D_UNK1940_4                                      0x00010000
-#define NV50_3D_UNK1940_5                                      0x00100000
-#define NV50_3D_UNK1940_6                                      0x01000000
-#define NV50_3D_UNK1940_7                                      0x10000000
+#define NV50_3D_CLIP_DISTANCE_MODE                             0x00001940
+#define NV50_3D_CLIP_DISTANCE_MODE_0__MASK                     0x00000001
+#define NV50_3D_CLIP_DISTANCE_MODE_0__SHIFT                    0
+#define NV50_3D_CLIP_DISTANCE_MODE_0_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_0_CULL                      0x00000001
+#define NV50_3D_CLIP_DISTANCE_MODE_1__MASK                     0x00000010
+#define NV50_3D_CLIP_DISTANCE_MODE_1__SHIFT                    4
+#define NV50_3D_CLIP_DISTANCE_MODE_1_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_1_CULL                      0x00000010
+#define NV50_3D_CLIP_DISTANCE_MODE_2__MASK                     0x00000100
+#define NV50_3D_CLIP_DISTANCE_MODE_2__SHIFT                    8
+#define NV50_3D_CLIP_DISTANCE_MODE_2_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_2_CULL                      0x00000100
+#define NV50_3D_CLIP_DISTANCE_MODE_3__MASK                     0x00001000
+#define NV50_3D_CLIP_DISTANCE_MODE_3__SHIFT                    12
+#define NV50_3D_CLIP_DISTANCE_MODE_3_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_3_CULL                      0x00001000
+#define NV50_3D_CLIP_DISTANCE_MODE_4__MASK                     0x00010000
+#define NV50_3D_CLIP_DISTANCE_MODE_4__SHIFT                    16
+#define NV50_3D_CLIP_DISTANCE_MODE_4_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_4_CULL                      0x00010000
+#define NV50_3D_CLIP_DISTANCE_MODE_5__MASK                     0x00100000
+#define NV50_3D_CLIP_DISTANCE_MODE_5__SHIFT                    20
+#define NV50_3D_CLIP_DISTANCE_MODE_5_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_5_CULL                      0x00100000
+#define NV50_3D_CLIP_DISTANCE_MODE_6__MASK                     0x01000000
+#define NV50_3D_CLIP_DISTANCE_MODE_6__SHIFT                    24
+#define NV50_3D_CLIP_DISTANCE_MODE_6_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_6_CULL                      0x01000000
+#define NV50_3D_CLIP_DISTANCE_MODE_7__MASK                     0x10000000
+#define NV50_3D_CLIP_DISTANCE_MODE_7__SHIFT                    28
+#define NV50_3D_CLIP_DISTANCE_MODE_7_CLIP                      0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_7_CULL                      0x10000000
 
 #define NVA3_3D_UNK1944                                                0x00001944
 
@@ -2048,7 +2074,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVA3_3D_IBLEND__ESIZE                                  0x00000020
 #define NVA3_3D_IBLEND__LEN                                    0x00000008
 
-#define NVA3_3D_IBLEND_UNK00(i0)                              (0x00001e00 + 0x20*(i0))
+#define NVA3_3D_IBLEND_SEPARATE_ALPHA(i0)                     (0x00001e00 + 0x20*(i0))
 
 #define NVA3_3D_IBLEND_EQUATION_RGB(i0)                               (0x00001e04 + 0x20*(i0))
 #define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_ADD                   0x00008006
@@ -2081,4 +2107,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__LEN                        0x00000020
 
 
-#endif /* NV50_3D_XML */
+#endif /* RNNDB_NV50_3D_XML */
index 3b0f8f07d1c123bc980d2f2207eda8e52a28ee87..88eb4bb246caa6432fd9632edab47d93c446eb8b 100644 (file)
@@ -33,40 +33,36 @@ static void
 nv50_flush(struct pipe_context *pipe,
            struct pipe_fence_handle **fence)
 {
-   struct nouveau_screen *screen = &nv50_context(pipe)->screen->base;
+   struct nouveau_screen *screen = nouveau_screen(pipe->screen);
 
    if (fence)
       nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
 
-   /* Try to emit before firing to avoid having to flush again right after
-    * in case we have to wait on this fence.
-    */
-   nouveau_fence_emit(screen->fence.current);
-
-   FIRE_RING(screen->channel);
+   PUSH_KICK(screen->pushbuf);
 }
 
 static void
 nv50_texture_barrier(struct pipe_context *pipe)
 {
-   struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;
 
-   BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
-   OUT_RING  (chan, 0x20);
+   BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
+   PUSH_DATA (push, 0x20);
 }
 
 void
-nv50_default_flush_notify(struct nouveau_channel *chan)
+nv50_default_kick_notify(struct nouveau_pushbuf *push)
 {
-   struct nv50_screen *screen = chan->user_private;
-
-   if (!screen)
-      return;
+   struct nv50_screen *screen = push->user_priv;
 
-   nouveau_fence_update(&screen->base, TRUE);
-   nouveau_fence_next(&screen->base);
+   if (screen) {
+      nouveau_fence_next(&screen->base);
+      nouveau_fence_update(&screen->base, TRUE);
+      if (screen->cur_ctx)
+         screen->cur_ctx->state.flushed = TRUE;
+   }
 }
 
 static void
@@ -74,8 +70,8 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
 {
    unsigned s, i;
 
-   for (i = 0; i < NV50_BUFCTX_COUNT; ++i)
-      nv50_bufctx_reset(nv50, i);
+   nouveau_bufctx_del(&nv50->bufctx_3d);
+   nouveau_bufctx_del(&nv50->bufctx);
 
    for (i = 0; i < nv50->num_vtxbufs; ++i)
       pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
@@ -96,13 +92,18 @@ nv50_destroy(struct pipe_context *pipe)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
+   if (nv50_context_screen(nv50)->cur_ctx == nv50) {
+      nv50->base.pushbuf->kick_notify = NULL;
+      nv50_context_screen(nv50)->cur_ctx = NULL;
+      nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
+   }
+   /* need to flush before destroying the bufctx */
+   nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);
+
    nv50_context_unreference_resources(nv50);
 
    draw_destroy(nv50->draw);
 
-   if (nv50->screen->cur_ctx == nv50)
-      nv50->screen->cur_ctx = NULL;
-
    FREE(nv50);
 }
 
@@ -112,17 +113,28 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
    struct nv50_screen *screen = nv50_screen(pscreen);
    struct nv50_context *nv50;
    struct pipe_context *pipe;
+   int ret;
+   uint32_t flags;
 
    nv50 = CALLOC_STRUCT(nv50_context);
    if (!nv50)
       return NULL;
    pipe = &nv50->base.pipe;
 
-   nv50->screen = screen;
+   nv50->base.pushbuf = screen->base.pushbuf;
+
+   ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT,
+                            &nv50->bufctx_3d);
+   if (!ret)
+      ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
+   if (ret)
+      goto out_err;
+
    nv50->base.screen    = &screen->base;
    nv50->base.copy_data = nv50_m2mf_copy_linear;
    nv50->base.push_data = nv50_sifc_linear_u8;
 
+   nv50->screen = screen;
    pipe->screen = pscreen;
    pipe->priv = priv;
 
@@ -134,9 +146,10 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
    pipe->flush = nv50_flush;
    pipe->texture_barrier = nv50_texture_barrier;
 
-   if (!screen->cur_ctx)
+   if (!screen->cur_ctx) {
       screen->cur_ctx = nv50;
-   screen->base.channel->flush_notify = nv50_default_flush_notify;
+      nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
+   }
 
    nv50_init_query_functions(nv50);
    nv50_init_surface_functions(nv50);
@@ -149,72 +162,41 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
 
    nouveau_context_init_vdec(&nv50->base);
 
-   return pipe;
-}
+   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
 
-struct resident {
-   struct nv04_resource *res;
-   uint32_t flags;
-};
+   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->code);
+   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms);
+   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc);
+   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo);
 
-void
-nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
-                         struct nv04_resource *resource, uint32_t flags)
-{
-   struct resident rsd = { resource, flags };
+   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
 
-   if (!resource->bo)
-      return;
-   nv50->residents_size += sizeof(struct resident);
+   BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo);
+   BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);
 
-   /* We don't need to reference the resource here, it will be referenced
-    * in the context/state, and bufctx will be reset when state changes.
-    */
-   util_dynarray_append(&nv50->residents[ctx], struct resident, rsd);
-}
+   return pipe;
 
-void
-nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
-                         struct nv04_resource *resource)
-{
-   struct resident *rsd, *top;
-   unsigned i;
-
-   for (i = 0; i < nv50->residents[ctx].size / sizeof(struct resident); ++i) {
-      rsd = util_dynarray_element(&nv50->residents[ctx], struct resident, i);
-
-      if (rsd->res == resource) {
-         top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident);
-         if (rsd != top)
-            *rsd = *top;
-         nv50->residents_size -= sizeof(struct resident);
-         break;
-      }
+out_err:
+   if (nv50) {
+      if (nv50->bufctx_3d)
+         nouveau_bufctx_del(&nv50->bufctx_3d);
+      if (nv50->bufctx)
+         nouveau_bufctx_del(&nv50->bufctx);
+      FREE(nv50);
    }
+   return NULL;
 }
 
 void
-nv50_bufctx_emit_relocs(struct nv50_context *nv50)
+nv50_bufctx_fence(struct nouveau_bufctx *bufctx, boolean on_flush)
 {
-   struct resident *rsd;
-   struct util_dynarray *array;
-   unsigned ctx, i, n;
-
-   n  = nv50->residents_size / sizeof(struct resident);
-   n += NV50_SCREEN_RESIDENT_BO_COUNT;
-
-   MARK_RING(nv50->screen->base.channel, 0, n);
-
-   for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) {
-      array = &nv50->residents[ctx];
-
-      n = array->size / sizeof(struct resident);
-      for (i = 0; i < n; ++i) {
-         rsd = util_dynarray_element(array, struct resident, i);
-
-         nv50_resource_validate(rsd->res, rsd->flags);
-      }
+   struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
+   struct nouveau_list *it;
+
+   for (it = list->next; it != list; it = it->next) {
+      struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
+      struct nv04_resource *res = ref->priv;
+      if (res)
+         nv50_resource_validate(res, (unsigned)ref->priv_data);
    }
-
-   nv50_screen_make_buffers_resident(nv50->screen);
 }
index 2bf634a82376e34ef4ed3078632d83a4244723dd..0dd6c16bb48ef9edd16f8b50abe8d0df84bb69d5 100644 (file)
 #define NV50_NEW_CONSTBUF     (1 << 18)
 #define NV50_NEW_TEXTURES     (1 << 19)
 #define NV50_NEW_SAMPLERS     (1 << 20)
-
-#define NV50_BUFCTX_CONSTANT 0
-#define NV50_BUFCTX_FRAME    1
-#define NV50_BUFCTX_VERTEX   2
-#define NV50_BUFCTX_TEXTURES 3
-#define NV50_BUFCTX_COUNT    4
+#define NV50_NEW_CONTEXT      (1 << 31)
+
+#define NV50_BIND_FB          0
+#define NV50_BIND_VERTEX      1
+#define NV50_BIND_VERTEX_TMP  2
+#define NV50_BIND_INDEX       3
+#define NV50_BIND_TEXTURES    4
+#define NV50_BIND_CB(s, i)   (5 + 16 * (s) + (i))
+#define NV50_BIND_SCREEN     53
+#define NV50_BIND_TLS        54
+#define NV50_BIND_COUNT      55
+#define NV50_BIND_2D          0
+#define NV50_BIND_M2MF        0
+#define NV50_BIND_FENCE       1
 
 #define NV50_CB_TMP 123
 /* fixed constant buffer binding points - low indices for user's constbufs */
 #define NV50_CB_PFP 125
 #define NV50_CB_AUX 127
 
+
 struct nv50_context {
    struct nouveau_context base;
 
    struct nv50_screen *screen;
 
-   struct util_dynarray residents[NV50_BUFCTX_COUNT];
-   unsigned residents_size;
+   struct nouveau_bufctx *bufctx_3d;
+   struct nouveau_bufctx *bufctx;
 
    uint32_t dirty;
 
@@ -79,6 +88,9 @@ struct nv50_context {
       int32_t index_bias;
       boolean prim_restart;
       boolean point_sprite;
+      boolean rt_serialize;
+      boolean flushed;
+      uint8_t tls_required;
       uint8_t num_vtxbufs;
       uint8_t num_vtxelts;
       uint8_t num_textures[3];
@@ -97,6 +109,7 @@ struct nv50_context {
 
    struct pipe_resource *constbuf[3][16];
    uint16_t constbuf_dirty[3];
+   uint16_t constbuf_valid[3];
 
    struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
    unsigned num_vtxbufs;
@@ -132,22 +145,19 @@ nv50_context(struct pipe_context *pipe)
    return (struct nv50_context *)pipe;
 }
 
+static INLINE struct nv50_screen *
+nv50_context_screen(struct nv50_context *nv50)
+{
+   return nv50_screen(&nv50->base.screen->base);
+}
+
+
 /* nv50_context.c */
 struct pipe_context *nv50_create(struct pipe_screen *, void *);
 
-void nv50_default_flush_notify(struct nouveau_channel *);
+void nv50_bufctx_fence(struct nouveau_bufctx *, boolean on_flush);
 
-void nv50_bufctx_emit_relocs(struct nv50_context *);
-void nv50_bufctx_add_resident(struct nv50_context *, int ctx,
-                              struct nv04_resource *, uint32_t flags);
-void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
-                              struct nv04_resource *);
-static INLINE void
-nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
-{
-   nv50->residents_size -= nv50->residents[ctx].size;
-   util_dynarray_resize(&nv50->residents[ctx], 0);
-}
+void nv50_default_kick_notify(struct nouveau_pushbuf *);
 
 /* nv50_draw.c */
 extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
@@ -194,7 +204,7 @@ nv50_create_sampler_view(struct pipe_context *,
 
 /* nv50_transfer.c */
 void
-nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nv50_m2mf_transfer_rect(struct nv50_context *,
                         const struct nv50_m2mf_rect *dst,
                         const struct nv50_m2mf_rect *src,
                         uint32_t nblocksx, uint32_t nblocksy);
index 76b60592bfb9218df0d7197bd0abd8e3cea4131b..bfadbc5ab2879545e48bfa8ffaef0c815f1a80d4 100644 (file)
@@ -31,7 +31,7 @@
 static INLINE uint32_t
 nv50_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz)
 {
-   return nvc0_tex_choose_tile_dims(nx, ny * 2, nz) >> 4;
+   return nvc0_tex_choose_tile_dims(nx, ny * 2, nz);
 }
 
 static uint32_t
@@ -41,58 +41,60 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
 
    uint32_t tile_flags;
 
-   if (mt->base.base.bind & PIPE_BIND_CURSOR)
-      return NOUVEAU_BO_TILE_SCANOUT;
+   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
+      return 0;
+   if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
+      return 0;
 
    switch (mt->base.base.format) {
    case PIPE_FORMAT_Z16_UNORM:
-      tile_flags = 0x6c00 + (ms << 8);
+      tile_flags = 0x6c + (ms << 8);
       break;
    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
-      tile_flags = 0x1800 + (ms << 8);
+      tile_flags = 0x18 + (ms << 8);
       break;
    case PIPE_FORMAT_Z24X8_UNORM:
    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
-      tile_flags = 0x22800 + (ms << 8);
+      tile_flags = 0x128 + (ms << 8);
       break;
    case PIPE_FORMAT_Z32_FLOAT:
-      tile_flags = 0x4000 + (ms << 8);
+      tile_flags = 0x40 + (ms << 8);
       break;
    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
-      tile_flags = 0x6000 + (ms << 8);
+      tile_flags = 0x60 + (ms << 8);
       break;
    default:
       switch (util_format_get_blocksizebits(mt->base.base.format)) {
       case 128:
          assert(ms < 3);
-         tile_flags = 0x7400;
+         tile_flags = 0x74;
          break;
       case 64:
          switch (ms) {
-         case 2: tile_flags = 0x17c00; break;
-         case 3: tile_flags = 0x17d00; break;
+         case 2: tile_flags = 0xfc; break;
+         case 3: tile_flags = 0xfd; break;
          default:
-            tile_flags = 0x7000;
+            tile_flags = 0x70;
             break;
          }
          break;
       case 32:
          if (mt->base.base.bind & PIPE_BIND_SCANOUT) {
             assert(ms == 0);
-            tile_flags = 0x7a00;
+            tile_flags = 0x7a;
          } else {
             switch (ms) {
-            case 2: tile_flags = 0x17800; break;
-            case 3: tile_flags = 0x17900; break;
+            case 2: tile_flags = 0xf8; break;
+            case 3: tile_flags = 0xf9; break;
             default:
-               tile_flags = 0x7000;
+               tile_flags = 0x70;
                break;
             }
          }
          break;
       case 16:
       case 8:
-         tile_flags = 0x7000;
+         tile_flags = 0x70;
          break;
       default:
          return 0;
@@ -101,14 +103,8 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
          tile_flags = 0;
    }
 
-   if (mt->base.base.bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR))
-      tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
-
    if (!compressed)
-      tile_flags &= ~0x30000;
-
-   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
-      tile_flags &= ~0x3ff00;
+      tile_flags &= ~0x180;
 
    return tile_flags;
 }
@@ -118,7 +114,7 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
 {
    struct nv50_miptree *mt = nv50_miptree(pt);
 
-   nouveau_screen_bo_release(pscreen, mt->base.bo);
+   nouveau_bo_ref(NULL, &mt->base.bo);
 
    FREE(mt);
 }
@@ -260,7 +256,8 @@ nv50_miptree_create(struct pipe_screen *pscreen,
    struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
    struct pipe_resource *pt = &mt->base.base;
    int ret;
-   uint32_t tile_flags;
+   union nouveau_bo_config bo_config;
+   uint32_t bo_flags;
 
    if (!mt)
       return NULL;
@@ -270,30 +267,34 @@ nv50_miptree_create(struct pipe_screen *pscreen,
    pipe_reference_init(&pt->reference, 1);
    pt->screen = pscreen;
 
-   tile_flags = nv50_mt_choose_storage_type(mt, TRUE);
+   bo_config.nv50.memtype = nv50_mt_choose_storage_type(mt, TRUE);
 
    if (!nv50_miptree_init_ms_mode(mt)) {
       FREE(mt);
       return NULL;
    }
 
-   if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+   if (bo_config.nv50.memtype != 0) {
       nv50_miptree_init_layout_tiled(mt);
    } else
    if (!nv50_miptree_init_layout_linear(mt)) {
       FREE(mt);
       return NULL;
    }
+   bo_config.nv50.tile_mode = mt->level[0].tile_mode;
+
+   bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP;
+   if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
+      bo_flags |= NOUVEAU_BO_CONTIG;
 
-   ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
-                             mt->total_size,
-                             mt->level[0].tile_mode, tile_flags,
-                             &mt->base.bo);
+   ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config,
+                        &mt->base.bo);
    if (ret) {
       FREE(mt);
       return NULL;
    }
    mt->base.domain = NOUVEAU_BO_VRAM;
+   mt->base.address = mt->base.bo->offset;
 
    return pt;
 }
@@ -323,6 +324,8 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
       FREE(mt);
       return NULL;
    }
+   mt->base.domain = NOUVEAU_BO_VRAM;
+   mt->base.address = mt->base.bo->offset;
 
    mt->base.base = *templ;
    mt->base.vtbl = &nv50_miptree_vtbl;
@@ -330,7 +333,7 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
    mt->base.base.screen = pscreen;
    mt->level[0].pitch = stride;
    mt->level[0].offset = 0;
-   mt->level[0].tile_mode = mt->base.bo->tile_mode;
+   mt->level[0].tile_mode = mt->base.bo->config.nv50.tile_mode;
 
    /* no need to adjust bo reference count */
    return &mt->base.base;
index c141a91eec23fb333e71e6506e753aaf228ad6fc..776cecaeb7e870dd817221351e89c2da689a474e 100644 (file)
@@ -489,7 +489,8 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti)
       ++nintp;
    }
 
-   p->fp.colors = 4 << NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT; /* after HPOS */
+   /* after HPOS */
+   p->fp.colors = 4 << NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT;
 
    for (i = 0; i < p->in_nr; ++i) {
       int j = p->in[i].id;
@@ -680,8 +681,8 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
    const struct pipe_shader_state pipe = p->pipe;
    const ubyte type = p->type;
 
-   if (p->res)
-      nouveau_resource_free(&p->res);
+   if (p->mem)
+      nouveau_heap_free(&p->mem);
 
    if (p->code)
       FREE(p->code);
index 993e1691ab76166a522de6f4ccf14faf933a9471..17aee97a024d820e2467b5897ee7131b33fbc020 100644 (file)
@@ -87,7 +87,7 @@ struct nv50_program {
    void *fixups;
    unsigned num_fixups;
 
-   struct nouveau_resource *res;
+   struct nouveau_heap *mem;
 };
 
 #define NV50_INTERP_LINEAR   (1 << 0)
index e8ad1ddd38a42bb9e14b99b49c6137dbdd5d0c58..04e32b7e8b9d55ad53b945ca060797ff088fddb6 100644 (file)
@@ -11,7 +11,7 @@
 #include "nv50_3d.xml.h"
 
 struct push_context {
-   struct nouveau_channel *chan;
+   struct nouveau_pushbuf *push;
 
    void *idxbuf;
 
@@ -74,20 +74,20 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
 
       size = ctx->vertex_words * nr;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
 
       ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
-                                ctx->chan->cur);
+                                ctx->push->cur);
 
-      ctx->chan->cur += size;
+      ctx->push->cur += size;
       count -= nr;
       elts += nr;
 
       if (nr != push) {
          count--;
          elts++;
-         BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
-         OUT_RING  (ctx->chan, ctx->restart_index);
+         BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
+         PUSH_DATA (ctx->push, ctx->restart_index);
       }
    }
 }
@@ -107,20 +107,20 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
 
       size = ctx->vertex_words * nr;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
 
       ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
-                                 ctx->chan->cur);
+                                 ctx->push->cur);
 
-      ctx->chan->cur += size;
+      ctx->push->cur += size;
       count -= nr;
       elts += nr;
 
       if (nr != push) {
          count--;
          elts++;
-         BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
-         OUT_RING  (ctx->chan, ctx->restart_index);
+         BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
+         PUSH_DATA (ctx->push, ctx->restart_index);
       }
    }
 }
@@ -140,20 +140,20 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
 
       size = ctx->vertex_words * nr;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
 
       ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
-                               ctx->chan->cur);
+                               ctx->push->cur);
 
-      ctx->chan->cur += size;
+      ctx->push->cur += size;
       count -= nr;
       elts += nr;
 
       if (nr != push) {
          count--;
          elts++;
-         BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
-         OUT_RING  (ctx->chan, ctx->restart_index);
+         BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
+         PUSH_DATA (ctx->push, ctx->restart_index);
       }
    }
 }
@@ -165,11 +165,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
       unsigned push = MIN2(count, ctx->packet_vertex_limit);
       unsigned size = ctx->vertex_words * push;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
 
       ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
-                          ctx->chan->cur);
-      ctx->chan->cur += size;
+                          ctx->push->cur);
+      ctx->push->cur += size;
       count -= push;
       start += push;
    }
@@ -213,7 +213,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
    unsigned inst = info->instance_count;
    boolean apply_bias = info->indexed && info->index_bias;
 
-   ctx.chan = nv50->screen->base.channel;
+   ctx.push = nv50->base.pushbuf;
    ctx.translate = nv50->vertex->translate;
    ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
    ctx.vertex_words = nv50->vertex->vertex_size;
@@ -252,19 +252,19 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
    ctx.prim = nv50_prim_gl(info->mode);
 
    if (info->primitive_restart) {
-      BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 2);
-      OUT_RING  (ctx.chan, 1);
-      OUT_RING  (ctx.chan, info->restart_index);
+      BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 2);
+      PUSH_DATA (ctx.push, 1);
+      PUSH_DATA (ctx.push, info->restart_index);
    } else
    if (nv50->state.prim_restart) {
-      BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 1);
-      OUT_RING  (ctx.chan, 0);
+      BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 1);
+      PUSH_DATA (ctx.push, 0);
    }
    nv50->state.prim_restart = info->primitive_restart;
 
    while (inst--) {
-      BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
-      OUT_RING  (ctx.chan, ctx.prim);
+      BEGIN_NV04(ctx.push, NV50_3D(VERTEX_BEGIN_GL), 1);
+      PUSH_DATA (ctx.push, ctx.prim);
       switch (index_size) {
       case 0:
          emit_vertices_seq(&ctx, info->start, info->count);
@@ -282,8 +282,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
          assert(0);
          break;
       }
-      BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1);
-      OUT_RING  (ctx.chan, 0);
+      BEGIN_NV04(ctx.push, NV50_3D(VERTEX_END_GL), 1);
+      PUSH_DATA (ctx.push, 0);
 
       ctx.instance_id++;
       ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
index 59d315aa4756137b3d86386242cee89ecd0adee3..220b166f98534def5a4da6a4bc06c33cecfdce07 100644 (file)
@@ -22,6 +22,8 @@
  * Authors: Christoph Bumiller
  */
 
+#define NV50_PUSH_EXPLICIT_SPACE_CHECKING
+
 #include "nv50_context.h"
 #include "nouveau/nv_object.xml.h"
 
@@ -64,7 +66,8 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
          if (q->ready)
             nouveau_mm_free(q->mm);
          else
-            nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm);
+            nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work,
+                               q->mm);
       }
    }
    if (size) {
@@ -73,14 +76,12 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
          return FALSE;
       q->offset = q->base;
 
-      ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD |
-                                 NOUVEAU_BO_NOSYNC);
+      ret = nouveau_bo_map(q->bo, 0, screen->base.client);
       if (ret) {
          nv50_query_allocate(nv50, q, 0);
          return FALSE;
       }
-      q->data = q->bo->map;
-      nouveau_bo_unmap(q->bo);
+      q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base);
    }
    return TRUE;
 }
@@ -121,24 +122,25 @@ nv50_query_create(struct pipe_context *pipe, unsigned type)
 }
 
 static void
-nv50_query_get(struct nouveau_channel *chan, struct nv50_query *q,
+nv50_query_get(struct nouveau_pushbuf *push, struct nv50_query *q,
                unsigned offset, uint32_t get)
 {
    offset += q->offset;
 
-   MARK_RING (chan, 5, 2);
-   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-   OUT_RING  (chan, q->sequence);
-   OUT_RING  (chan, get);
+   PUSH_SPACE(push, 5);
+   PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+   BEGIN_NV04(push, NV50_3D(QUERY_ADDRESS_HIGH), 4);
+   PUSH_DATAh(push, q->bo->offset + offset);
+   PUSH_DATA (push, q->bo->offset + offset);
+   PUSH_DATA (push, q->sequence);
+   PUSH_DATA (push, get);
 }
 
 static void
 nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_query *q = nv50_query(pq);
 
    /* For occlusion queries we have to change the storage, because a previous
@@ -161,27 +163,31 @@ nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
 
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
-      BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
-      OUT_RING  (chan, NV50_3D_COUNTER_RESET_SAMPLECNT);
-      BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
-      OUT_RING  (chan, 1);
+      PUSH_SPACE(push, 4);
+      BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
+      PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT);
+      BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
+      PUSH_DATA (push, 1);
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED: /* store before & after instead ? */
-      BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
-      OUT_RING  (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
+      PUSH_SPACE(push, 2);
+      BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
+      PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
       break;
    case PIPE_QUERY_PRIMITIVES_EMITTED:
-      BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
-      OUT_RING  (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
+      PUSH_SPACE(push, 2);
+      BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
+      PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
       break;
    case PIPE_QUERY_SO_STATISTICS:
-      BEGIN_RING_NI(chan, RING_3D(COUNTER_RESET), 2);
-      OUT_RING  (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
-      OUT_RING  (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
+      PUSH_SPACE(push, 3);
+      BEGIN_NI04(push, NV50_3D(COUNTER_RESET), 2);
+      PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
+      PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
       break;
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
    case PIPE_QUERY_TIME_ELAPSED:
-      nv50_query_get(chan, q, 0x10, 0x00005002);
+      nv50_query_get(push, q, 0x10, 0x00005002);
       break;
    default:
       break;
@@ -193,31 +199,32 @@ static void
 nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_query *q = nv50_query(pq);
 
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
-      nv50_query_get(chan, q, 0, 0x0100f002);
-      BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
-      OUT_RING  (chan, 0);
+      nv50_query_get(push, q, 0, 0x0100f002);
+      PUSH_SPACE(push, 2);
+      BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
+      PUSH_DATA (push, 0);
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
-      nv50_query_get(chan, q, 0, 0x06805002);
+      nv50_query_get(push, q, 0, 0x06805002);
       break;
    case PIPE_QUERY_PRIMITIVES_EMITTED:
-      nv50_query_get(chan, q, 0, 0x05805002);
+      nv50_query_get(push, q, 0, 0x05805002);
       break;
    case PIPE_QUERY_SO_STATISTICS:
-      nv50_query_get(chan, q, 0x00, 0x05805002);
-      nv50_query_get(chan, q, 0x10, 0x06805002);
+      nv50_query_get(push, q, 0x00, 0x05805002);
+      nv50_query_get(push, q, 0x10, 0x06805002);
       break;
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
    case PIPE_QUERY_TIME_ELAPSED:
-      nv50_query_get(chan, q, 0, 0x00005002);
+      nv50_query_get(push, q, 0, 0x00005002);
       break;
    case PIPE_QUERY_GPU_FINISHED:
-      nv50_query_get(chan, q, 0, 0x1000f010);
+      nv50_query_get(push, q, 0, 0x1000f010);
       break;
    default:
       assert(0);
@@ -231,45 +238,33 @@ nv50_query_ready(struct nv50_query *q)
    return q->ready || (!q->is64bit && (q->data[0] == q->sequence));
 }
 
-static INLINE boolean
-nv50_query_wait(struct nv50_query *q)
-{
-   int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
-   if (ret)
-      return FALSE;
-   nouveau_bo_unmap(q->bo);
-   return TRUE;
-}
-
 static boolean
 nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
                   boolean wait, union pipe_query_result *result)
 {
+   struct nv50_context *nv50 = nv50_context(pipe);
    struct nv50_query *q = nv50_query(pq);
-   uint64_t *res64 = (uint64_t*)result;
-   boolean *res8 = (boolean*)result;
+   uint64_t *res64 = (uint64_t *)result;
+   boolean *res8 = (boolean *)result;
    uint64_t *data64 = (uint64_t *)q->data;
 
-   if (q->type == PIPE_QUERY_GPU_FINISHED) {
-      res8[0] = nv50_query_ready(q);
-      return TRUE;
-   }
-
    if (!q->ready) /* update ? */
       q->ready = nv50_query_ready(q);
    if (!q->ready) {
-      struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
       if (!wait) {
-         if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
-            FIRE_RING(chan);
+         /* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
+         PUSH_KICK(nv50->base.pushbuf);
          return FALSE;
       }
-      if (!nv50_query_wait(q))
+      if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
          return FALSE;
    }
    q->ready = TRUE;
 
    switch (q->type) {
+   case PIPE_QUERY_GPU_FINISHED:
+      res8[0] = TRUE;
+      break;
    case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */
       res64[0] = q->data[1];
       break;
@@ -300,27 +295,28 @@ nv50_render_condition(struct pipe_context *pipe,
                       struct pipe_query *pq, uint mode)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_query *q;
 
+   PUSH_SPACE(push, 6);
+
    if (!pq) {
-      BEGIN_RING(chan, RING_3D(COND_MODE), 1);
-      OUT_RING  (chan, NV50_3D_COND_MODE_ALWAYS);
+      BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
+      PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
       return;
    }
    q = nv50_query(pq);
 
    if (mode == PIPE_RENDER_COND_WAIT ||
        mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
-      BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+      PUSH_DATA (push, 0);
    }
 
-   MARK_RING (chan, 4, 2);
-   BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-   OUT_RING  (chan, NV50_3D_COND_MODE_RES_NON_ZERO);
+   BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, q->bo->offset + q->offset);
+   PUSH_DATA (push, q->bo->offset + q->offset);
+   PUSH_DATA (push, NV50_3D_COND_MODE_RES_NON_ZERO);
 }
 
 void
index 50cc2afdbe138dbae14e32fab28b928ceb07e85f..5d5596ea6e3a8b2a269ca92fe1fff31ce398cc76 100644 (file)
@@ -4,10 +4,9 @@
 
 #include "util/u_transfer.h"
 #include "util/u_double_list.h"
-#define NOUVEAU_NVC0
+
 #include "nouveau/nouveau_winsys.h"
 #include "nouveau/nouveau_buffer.h"
-#undef NOUVEAU_NVC0
 
 #ifndef __NVC0_RESOURCE_H__ /* make sure we don't use these in nvc0: */
 
@@ -19,12 +18,12 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
 
 
 #define NV50_TILE_SHIFT_X(m) 6
-#define NV50_TILE_SHIFT_Y(m) ((((m) >> 0) & 0xf) + 2)
-#define NV50_TILE_SHIFT_Z(m) ((((m) >> 4) & 0xf) + 0)
+#define NV50_TILE_SHIFT_Y(m) ((((m) >> 4) & 0xf) + 2)
+#define NV50_TILE_SHIFT_Z(m) ((((m) >> 8) & 0xf) + 0)
 
 #define NV50_TILE_SIZE_X(m) 64
-#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 0) & 0xf))
-#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 4) & 0xf))
+#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 4) & 0xf))
+#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 8) & 0xf))
 
 #define NV50_TILE_SIZE_2D(m) (NV50_TILE_SIZE_X(m) << NV50_TILE_SHIFT_Y(m))
 
index 27566e241083df5d55390f45b69ce19a42608127..8a3c552784f82469d7766a079bd8f2b3d321fea8 100644 (file)
@@ -33,9 +33,6 @@
 # define NOUVEAU_GETPARAM_GRAPH_UNITS 13
 #endif
 
-extern int nouveau_device_get_param(struct nouveau_device *dev,
-                                    uint64_t param, uint64_t *value);
-
 static boolean
 nv50_screen_is_format_supported(struct pipe_screen *pscreen,
                                 enum pipe_format format,
@@ -53,7 +50,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
 
    switch (format) {
    case PIPE_FORMAT_Z16_UNORM:
-      if (nv50_screen(pscreen)->tesla->grclass < NVA0_3D)
+      if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS)
          return FALSE;
       break;
    case PIPE_FORMAT_R8G8B8A8_UNORM:
@@ -100,7 +97,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
    case PIPE_CAP_SEAMLESS_CUBE_MAP:
-      return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D;
+      return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
       return 0;
    case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -131,7 +128,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_INDEP_BLEND_ENABLE:
       return 1;
    case PIPE_CAP_INDEP_BLEND_FUNC:
-      return nv50_screen(pscreen)->tesla->grclass >= NVA3_3D;
+      return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS;
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
       return 1;
@@ -241,8 +238,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
       nouveau_fence_wait(screen->base.fence.current);
       nouveau_fence_ref (NULL, &screen->base.fence.current);
    }
-   if (screen->base.channel)
-      screen->base.channel->user_private = NULL;
+   if (screen->base.pushbuf)
+      screen->base.pushbuf->user_priv = NULL;
+
    if (screen->blitctx)
       FREE(screen->blitctx);
 
@@ -253,20 +251,17 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
    nouveau_bo_ref(NULL, &screen->uniforms);
    nouveau_bo_ref(NULL, &screen->fence.bo);
 
-   nouveau_resource_destroy(&screen->vp_code_heap);
-   nouveau_resource_destroy(&screen->gp_code_heap);
-   nouveau_resource_destroy(&screen->fp_code_heap);
+   nouveau_heap_destroy(&screen->vp_code_heap);
+   nouveau_heap_destroy(&screen->gp_code_heap);
+   nouveau_heap_destroy(&screen->fp_code_heap);
 
    if (screen->tic.entries)
       FREE(screen->tic.entries);
 
-   nouveau_mm_destroy(screen->mm_VRAM_fe0);
-
-   nouveau_grobj_free(&screen->tesla);
-   nouveau_grobj_free(&screen->eng2d);
-   nouveau_grobj_free(&screen->m2mf);
-
-   nouveau_notifier_free(&screen->sync);
+   nouveau_object_del(&screen->tesla);
+   nouveau_object_del(&screen->eng2d);
+   nouveau_object_del(&screen->m2mf);
+   nouveau_object_del(&screen->sync);
 
    nouveau_screen_fini(&screen->base);
 
@@ -277,18 +272,16 @@ static void
 nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
 {
    struct nv50_screen *screen = nv50_screen(pscreen);
-   struct nouveau_channel *chan = screen->base.channel;
-
-   MARK_RING (chan, 5, 2);
+   struct nouveau_pushbuf *push = screen->base.pushbuf;
 
    /* we need to do it after possible flush in MARK_RING */
    *sequence = ++screen->base.fence.sequence;
 
-   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RING  (chan, *sequence);
-   OUT_RING  (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
+   PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4));
+   PUSH_DATAh(push, screen->fence.bo->offset);
+   PUSH_DATA (push, screen->fence.bo->offset);
+   PUSH_DATA (push, *sequence);
+   PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
                     NV50_3D_QUERY_GET_UNK4 |
                     NV50_3D_QUERY_GET_UNIT_CROP |
                     NV50_3D_QUERY_GET_TYPE_QUERY |
@@ -299,8 +292,205 @@ nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
 static u32
 nv50_screen_fence_update(struct pipe_screen *pscreen)
 {
-   struct nv50_screen *screen = nv50_screen(pscreen);
-   return screen->fence.map[0];
+   return nv50_screen(pscreen)->fence.map[0];
+}
+
+static int
+nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space)
+{
+   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nv04_fifo *fifo;
+   unsigned i;
+
+   fifo = (struct nv04_fifo *)screen->base.channel->data;
+
+   BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, screen->m2mf->handle);
+   BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
+   PUSH_DATA (push, screen->sync->handle);
+   PUSH_DATA (push, fifo->vram);
+   PUSH_DATA (push, fifo->vram);
+
+   BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, screen->eng2d->handle);
+   BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
+   PUSH_DATA (push, screen->sync->handle);
+   PUSH_DATA (push, fifo->vram);
+   PUSH_DATA (push, fifo->vram);
+   PUSH_DATA (push, fifo->vram);
+   BEGIN_NV04(push, NV50_2D(OPERATION), 1);
+   PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
+   BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, SUBC_2D(0x0888), 1);
+   PUSH_DATA (push, 1);
+
+   BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, screen->tesla->handle);
+
+   BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
+   PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
+
+   BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
+   PUSH_DATA (push, screen->sync->handle);
+   BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
+   for (i = 0; i < 11; ++i)
+      PUSH_DATA(push, fifo->vram);
+   BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
+   for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
+      PUSH_DATA(push, fifo->vram);
+
+   BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
+   PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
+   BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
+   PUSH_DATA (push, 0xf);
+
+   BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+   PUSH_DATA (push, 1);
+
+   BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+   PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
+   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
+   PUSH_DATA (push, 1);
+
+   if (screen->tesla->oclass >= NVA0_3D_CLASS) {
+      BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
+      PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
+   }
+
+   BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
+   PUSH_DATA (push, 0x3f);
+
+   BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
+   PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
+   PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
+
+   BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
+   PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
+   PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
+
+   BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
+   PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
+   PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
+
+   BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->tls_bo->offset);
+   PUSH_DATA (push, screen->tls_bo->offset);
+   PUSH_DATA (push, util_logbase2(tls_space / 8));
+
+   BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->stack_bo->offset);
+   PUSH_DATA (push, screen->stack_bo->offset);
+   PUSH_DATA (push, 4);
+
+   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
+   PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
+   PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);
+
+   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
+   PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
+   PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);
+
+   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
+   PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
+   PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);
+
+   BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
+   PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
+   PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
+
+   BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6);
+   PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001);
+   PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021);
+   PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031);
+   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
+   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
+   PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
+
+   /* max TIC (bits 4:8) & TSC bindings, per program type */
+   for (i = 0; i < 3; ++i) {
+      BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
+      PUSH_DATA (push, 0x54);
+   }
+
+   BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->txc->offset);
+   PUSH_DATA (push, screen->txc->offset);
+   PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
+
+   BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->txc->offset + 65536);
+   PUSH_DATA (push, screen->txc->offset + 65536);
+   PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
+
+   BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
+   PUSH_DATA (push, 0);
+
+   BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
+   PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
+   BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
+   for (i = 0; i < 8 * 2; ++i)
+      PUSH_DATA(push, 0);
+   BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
+   PUSH_DATA (push, 0);
+
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
+   PUSH_DATAf(push, 0.0f);
+   PUSH_DATAf(push, 1.0f);
+
+   BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+#ifdef NV50_SCISSORS_CLIPPING
+   PUSH_DATA (push, 0x0000);
+#else
+   PUSH_DATA (push, 0x1080);
+#endif
+
+   BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
+   PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
+
+   /* We use scissors instead of exact view volume clipping,
+    * so they're always enabled.
+    */
+   BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3);
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 8192 << 16);
+   PUSH_DATA (push, 8192 << 16);
+
+   BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
+   PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
+   BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
+   PUSH_DATA (push, 0x11111111);
+   BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
+   PUSH_DATA (push, 1);
+
+   PUSH_KICK (push);
+
+   return 0;
 }
 
 #define FAIL_SCREEN_INIT(str, err)                    \
@@ -314,13 +504,12 @@ struct pipe_screen *
 nv50_screen_create(struct nouveau_device *dev)
 {
    struct nv50_screen *screen;
-   struct nouveau_channel *chan;
    struct pipe_screen *pscreen;
+   struct nouveau_object *chan;
    uint64_t value;
    uint32_t tesla_class;
    unsigned stack_size, max_warps, tls_space;
    int ret;
-   unsigned i, base;
 
    screen = CALLOC_STRUCT(nv50_screen);
    if (!screen)
@@ -333,8 +522,10 @@ nv50_screen_create(struct nouveau_device *dev)
    if (ret)
       FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret);
 
+   screen->base.pushbuf->user_priv = screen;
+   screen->base.pushbuf->rsvd_kick = 5;
+
    chan = screen->base.channel;
-   chan->user_private = screen;
 
    pscreen->destroy = nv50_screen_destroy;
    pscreen->context_create = nv50_create;
@@ -348,68 +539,52 @@ nv50_screen_create(struct nouveau_device *dev)
    nouveau_screen_init_vdec(&screen->base);
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
-                        &screen->fence.bo);
+                        NULL, &screen->fence.bo);
    if (ret)
       goto fail;
-   nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
+   nouveau_bo_map(screen->fence.bo, 0, NULL);
    screen->fence.map = screen->fence.bo->map;
-   nouveau_bo_unmap(screen->fence.bo);
    screen->base.fence.emit = nv50_screen_fence_emit;
    screen->base.fence.update = nv50_screen_fence_update;
 
-   ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
+   ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS,
+                            &(struct nv04_notify){ .length = 32 },
+                            sizeof(struct nv04_notify), &screen->sync);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret);
 
-   ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf);
+
+   ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS,
+                            NULL, 0, &screen->m2mf);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
 
-   BIND_RING (chan, screen->m2mf, NV50_SUBCH_MF);
-   BEGIN_RING(chan, RING_MF_(NV04_M2MF_DMA_NOTIFY), 3);
-   OUT_RING  (chan, screen->sync->handle);
-   OUT_RING  (chan, chan->vram->handle);
-   OUT_RING  (chan, chan->vram->handle);
 
-   ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
+   ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS,
+                            NULL, 0, &screen->eng2d);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
 
-   BIND_RING (chan, screen->eng2d, NV50_SUBCH_2D);
-   BEGIN_RING(chan, RING_2D(DMA_NOTIFY), 4);
-   OUT_RING  (chan, screen->sync->handle);
-   OUT_RING  (chan, chan->vram->handle);
-   OUT_RING  (chan, chan->vram->handle);
-   OUT_RING  (chan, chan->vram->handle);
-   BEGIN_RING(chan, RING_2D(OPERATION), 1);
-   OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
-   BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_2D_(0x0888), 1);
-   OUT_RING  (chan, 1);
-
    switch (dev->chipset & 0xf0) {
    case 0x50:
-      tesla_class = NV50_3D;
+      tesla_class = NV50_3D_CLASS;
       break;
    case 0x80:
    case 0x90:
-      tesla_class = NV84_3D;
+      tesla_class = NV84_3D_CLASS;
       break;
    case 0xa0:
       switch (dev->chipset) {
       case 0xa0:
       case 0xaa:
       case 0xac:
-         tesla_class = NVA0_3D;
+         tesla_class = NVA0_3D_CLASS;
          break;
       case 0xaf:
-         tesla_class = NVAF_3D;
+         tesla_class = NVAF_3D_CLASS;
          break;
       default:
-         tesla_class = NVA3_3D;
+         tesla_class = NVA3_3D_CLASS;
          break;
       }
       break;
@@ -418,98 +593,33 @@ nv50_screen_create(struct nouveau_device *dev)
       break;
    }
 
-   ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
+   ret = nouveau_object_new(chan, 0xbeef5097, tesla_class,
+                            NULL, 0, &screen->tesla);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
 
-   BIND_RING (chan, screen->tesla, NV50_SUBCH_3D);
-
-   BEGIN_RING(chan, RING_3D(COND_MODE), 1);
-   OUT_RING  (chan, NV50_3D_COND_MODE_ALWAYS);
-
-   BEGIN_RING(chan, RING_3D(DMA_NOTIFY), 1);
-   OUT_RING  (chan, screen->sync->handle);
-   BEGIN_RING(chan, RING_3D(DMA_ZETA), 11);
-   for (i = 0; i < 11; ++i)
-      OUT_RING(chan, chan->vram->handle);
-   BEGIN_RING(chan, RING_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
-   for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
-      OUT_RING(chan, chan->vram->handle);
-
-   BEGIN_RING(chan, RING_3D(REG_MODE), 1);
-   OUT_RING  (chan, NV50_3D_REG_MODE_STRIPED);
-   BEGIN_RING(chan, RING_3D(UNK1400_LANES), 1);
-   OUT_RING  (chan, 0xf);
-
-   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
-   OUT_RING  (chan, 1);
-
-   BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
-   OUT_RING  (chan, NV50_3D_MULTISAMPLE_MODE_MS1);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1);
-   OUT_RING  (chan, 1);
-
-   if (tesla_class >= NVA0_3D) {
-      BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1);
-      OUT_RING  (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
-   }
-
-   BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
-   OUT_RING  (chan, 0x3f);
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
-                        3 << NV50_CODE_BO_SIZE_LOG2, &screen->code);
+                        3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code);
    if (ret)
       goto fail;
 
-   nouveau_resource_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
-   nouveau_resource_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
-   nouveau_resource_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
-
-   base = 1 << NV50_CODE_BO_SIZE_LOG2;
-
-   BEGIN_RING(chan, RING_3D(VP_ADDRESS_HIGH), 2);
-   OUT_RELOCh(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-
-   BEGIN_RING(chan, RING_3D(FP_ADDRESS_HIGH), 2);
-   OUT_RELOCh(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-
-   BEGIN_RING(chan, RING_3D(GP_ADDRESS_HIGH), 2);
-   OUT_RELOCh(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
+   nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
+   nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
 
-   nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
+   nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
 
    max_warps  = util_bitcount(value & 0xffff);
    max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
 
    stack_size = max_warps * 64 * 8;
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL,
                         &screen->stack_bo);
    if (ret)
       FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
 
-   BEGIN_RING(chan, RING_3D(STACK_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RING  (chan, 4);
-
    tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
 
    screen->tls_size = tls_space * max_warps * 32;
@@ -518,126 +628,32 @@ nv50_screen_create(struct nouveau_device *dev)
       debug_printf("max_warps = %i, tls_size = %"PRIu64" KiB\n",
                      max_warps, screen->tls_size >> 10);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, NULL,
                         &screen->tls_bo);
    if (ret)
       FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
 
-   BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RING  (chan, util_logbase2(tls_space / 8));
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL,
                         &screen->uniforms);
    if (ret)
       goto fail;
 
-   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, (NV50_CB_PVP << 16) | 0x0000);
-
-   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, (NV50_CB_PGP << 16) | 0x0000);
-
-   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, (NV50_CB_PFP << 16) | 0x0000);
-
-   BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, (NV50_CB_AUX << 16) | 0x0200);
-
-   BEGIN_RING_NI(chan, RING_3D(SET_PROGRAM_CB), 6);
-   OUT_RING  (chan, (NV50_CB_PVP << 12) | 0x001);
-   OUT_RING  (chan, (NV50_CB_PGP << 12) | 0x021);
-   OUT_RING  (chan, (NV50_CB_PFP << 12) | 0x031);
-   OUT_RING  (chan, (NV50_CB_AUX << 12) | 0xf01);
-   OUT_RING  (chan, (NV50_CB_AUX << 12) | 0xf21);
-   OUT_RING  (chan, (NV50_CB_AUX << 12) | 0xf31);
-
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL,
                         &screen->txc);
    if (ret)
       FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret);
 
-   /* max TIC (bits 4:8) & TSC bindings, per program type */
-   for (i = 0; i < 3; ++i) {
-      BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
-      OUT_RING  (chan, 0x54);
-   }
-
-   BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, NV50_TIC_MAX_ENTRIES - 1);
-
-   BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, NV50_TSC_MAX_ENTRIES - 1);
-
-   BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
-   OUT_RING  (chan, 0);
-
-   BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
-   OUT_RING  (chan, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
-   BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
-   for (i = 0; i < 8 * 2; ++i)
-      OUT_RING(chan, 0);
-   BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
-   OUT_RING  (chan, 0);
-
-   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
-   OUT_RINGf (chan, 0.0f);
-   OUT_RINGf (chan, 1.0f);
-
-   BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
-#ifdef NV50_SCISSORS_CLIPPING
-   OUT_RING  (chan, 0x0000);
-#else
-   OUT_RING  (chan, 0x1080);
-#endif
-
-   BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
-   OUT_RING  (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
-
-   /* We use scissors instead of exact view volume clipping,
-    * so they're always enabled.
-    */
-   BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3);
-   OUT_RING  (chan, 1);
-   OUT_RING  (chan, 8192 << 16);
-   OUT_RING  (chan, 8192 << 16);
-
-   BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
-   OUT_RING  (chan, NV50_3D_POINT_RASTER_RULES_OGL);
-   BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
-   OUT_RING  (chan, 0x11111111);
-   BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
-   OUT_RING  (chan, 1);
-
-   FIRE_RING (chan);
-
    screen->tic.entries = CALLOC(4096, sizeof(void *));
    screen->tsc.entries = screen->tic.entries + 2048;
 
-   screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
 
    if (!nv50_blitctx_create(screen))
       goto fail;
 
+   if (nv50_screen_init_hwctx(screen, tls_space))
+      goto fail;
+
    nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
 
    return pscreen;
@@ -647,21 +663,6 @@ fail:
    return NULL;
 }
 
-void
-nv50_screen_make_buffers_resident(struct nv50_screen *screen)
-{
-   struct nouveau_channel *chan = screen->base.channel;
-
-   const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-
-   MARK_RING(chan, 0, 5);
-   nouveau_bo_validate(chan, screen->code, flags);
-   nouveau_bo_validate(chan, screen->uniforms, flags);
-   nouveau_bo_validate(chan, screen->txc, flags);
-   nouveau_bo_validate(chan, screen->tls_bo, flags);
-   nouveau_bo_validate(chan, screen->stack_bo, flags);
-}
-
 int
 nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry)
 {
index cb7e956cd84b1ec7b86f410c5d031b840c533b7d..b7803cfed80e46ea269663666319f804a199cba5 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef __NV50_SCREEN_H__
 #define __NV50_SCREEN_H__
 
-#define NOUVEAU_NVC0
 #include "nouveau/nouveau_screen.h"
 #include "nouveau/nouveau_fence.h"
 #include "nouveau/nouveau_mm.h"
-#undef NOUVEAU_NVC0
+#include "nouveau/nouveau_heap.h"
+
 #include "nv50_winsys.h"
 #include "nv50_stateobj.h"
 
@@ -36,9 +36,9 @@ struct nv50_screen {
 
    uint64_t tls_size;
 
-   struct nouveau_resource *vp_code_heap;
-   struct nouveau_resource *gp_code_heap;
-   struct nouveau_resource *fp_code_heap;
+   struct nouveau_heap *vp_code_heap;
+   struct nouveau_heap *gp_code_heap;
+   struct nouveau_heap *fp_code_heap;
 
    struct nv50_blitctx *blitctx;
 
@@ -59,13 +59,11 @@ struct nv50_screen {
       struct nouveau_bo *bo;
    } fence;
 
-   struct nouveau_notifier *sync;
-
-   struct nouveau_mman *mm_VRAM_fe0;
+   struct nouveau_object *sync;
 
-   struct nouveau_grobj *tesla;
-   struct nouveau_grobj *eng2d;
-   struct nouveau_grobj *m2mf;
+   struct nouveau_object *tesla;
+   struct nouveau_object *eng2d;
+   struct nouveau_object *m2mf;
 };
 
 static INLINE struct nv50_screen *
@@ -76,8 +74,6 @@ nv50_screen(struct pipe_screen *screen)
 
 boolean nv50_blitctx_create(struct nv50_screen *);
 
-void nv50_screen_make_buffers_resident(struct nv50_screen *);
-
 int nv50_screen_tic_alloc(struct nv50_screen *, void *);
 int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
 
@@ -88,7 +84,6 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
 
    if (res->mm) {
       nouveau_fence_ref(screen->base.fence.current, &res->fence);
-
       if (flags & NOUVEAU_BO_WR)
          nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
    }
@@ -97,11 +92,7 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
 static INLINE void
 nv50_resource_validate(struct nv04_resource *res, uint32_t flags)
 {
-   struct nv50_screen *screen = nv50_screen(res->base.screen);
-
    if (likely(res->bo)) {
-      nouveau_bo_validate(screen->base.channel, res->bo, flags);
-
       if (flags & NOUVEAU_BO_WR)
          res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       if (flags & NOUVEAU_BO_RD)
index d3cdb69796091ca58dfd4d4a4dca78e3bba786d0..07d4e6bb0c5d9a7cd114354b11d087bbc804579c 100644 (file)
@@ -31,7 +31,7 @@
 void
 nv50_constbufs_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    unsigned s;
 
    for (s = 0; s < 3; ++s) {
@@ -58,8 +58,8 @@ nv50_constbufs_validate(struct nv50_context *nv50)
          res = nv04_resource(nv50->constbuf[s][i]);
          if (!res) {
             if (i != 0) {
-               BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
-               OUT_RING  (chan, (i << 8) | p | 0);
+               BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+               PUSH_DATA (push, (i << 8) | p | 0);
             }
             continue;
          }
@@ -78,43 +78,35 @@ nv50_constbufs_validate(struct nv50_context *nv50)
             if (!nouveau_resource_mapped_by_gpu(&res->base)) {
                nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM);
 
-               BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1);
-               OUT_RING  (chan, 0);
+               BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1);
+               PUSH_DATA (push, 0);
             }
-            MARK_RING (chan, 6, 2);
-            BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
-            OUT_RESRCh(chan, res, 0, NOUVEAU_BO_RD);
-            OUT_RESRCl(chan, res, 0, NOUVEAU_BO_RD);
-            OUT_RING  (chan, (b << 16) | (res->base.width0 & 0xffff));
-            BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
-            OUT_RING  (chan, (b << 12) | (i << 8) | p | 1);
+            BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+            PUSH_DATAh(push, res->address);
+            PUSH_DATA (push, res->address);
+            PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff));
+            BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+            PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
 
             bo = res->bo;
-
-            nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res,
-                                     res->domain | NOUVEAU_BO_RD);
          }
 
-         if (words) {
-            MARK_RING(chan, 8, 1);
-
-            nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
-         }
+         if (bo != nv50->screen->uniforms)
+            BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
 
          while (words) {
-            unsigned nr = AVAIL_RING(chan);
+            unsigned nr;
 
-            if (nr < 16) {
-               FIRE_RING(chan);
-               nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
-               continue;
-            }
+            if (!PUSH_SPACE(push, 16))
+               break;
+            nr = PUSH_AVAIL(push);
+            assert(nr >= 16);
             nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
 
-            BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
-            OUT_RING  (chan, (start << 8) | b);
-            BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
-            OUT_RINGp (chan, &res->data[start * 4], nr);
+            BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+            PUSH_DATA (push, (start << 8) | b);
+            BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
+            PUSH_DATAp(push, &res->data[start * 4], nr);
 
             start += nr;
             words -= nr;
@@ -126,7 +118,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
 static boolean
 nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
 {
-   struct nouveau_resource *heap;
+   struct nouveau_heap *heap;
    int ret;
    unsigned size;
 
@@ -135,7 +127,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
       if (!prog->translated)
          return FALSE;
    } else
-   if (prog->res)
+   if (prog->mem)
       return TRUE;
 
    if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap;
@@ -146,12 +138,12 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
 
    size = align(prog->code_size, 0x100);
 
-   ret = nouveau_resource_alloc(heap, size, prog, &prog->res);
+   ret = nouveau_heap_alloc(heap, size, prog, &prog->mem);
    if (ret) {
       NOUVEAU_ERR("out of code space for shader type %i\n", prog->type);
       return FALSE;
    }
-   prog->code_base = prog->res->start;
+   prog->code_base = prog->mem->start;
 
    nv50_relocate_program(prog, prog->code_base, 0);
 
@@ -159,80 +151,99 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
                        (prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
                        NOUVEAU_BO_VRAM, prog->code_size, prog->code);
 
-   BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1);
-   OUT_RING  (nv50->screen->base.channel, 0);
+   BEGIN_NV04(nv50->base.pushbuf, NV50_3D(CODE_CB_FLUSH), 1);
+   PUSH_DATA (nv50->base.pushbuf, 0);
 
    return TRUE;
 }
 
+static INLINE void
+nv50_program_update_context_state(struct nv50_context *nv50,
+                                  struct nv50_program *prog, int stage)
+{
+   const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
+
+   if (prog && prog->uses_lmem) {
+      if (!nv50->state.tls_required)
+         BCTX_REFN_bo(nv50->bufctx_3d, TLS, flags, nv50->screen->tls_bo);
+      nv50->state.tls_required |= 1 << stage;
+   } else {
+      if (nv50->state.tls_required == (1 << stage))
+         nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TLS);
+      nv50->state.tls_required &= ~(1 << stage);
+   }
+}
+
 void
 nv50_vertprog_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *vp = nv50->vertprog;
 
    if (!nv50_program_validate(nv50, vp))
          return;
-
-   BEGIN_RING(chan, RING_3D(VP_ATTR_EN(0)), 2);
-   OUT_RING  (chan, vp->vp.attrs[0]);
-   OUT_RING  (chan, vp->vp.attrs[1]);
-   BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_RESULT), 1);
-   OUT_RING  (chan, vp->max_out);
-   BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_TEMP), 1);
-   OUT_RING  (chan, vp->max_gpr);
-   BEGIN_RING(chan, RING_3D(VP_START_ID), 1);
-   OUT_RING  (chan, vp->code_base);
+   nv50_program_update_context_state(nv50, vp, 0);
+
+   BEGIN_NV04(push, NV50_3D(VP_ATTR_EN(0)), 2);
+   PUSH_DATA (push, vp->vp.attrs[0]);
+   PUSH_DATA (push, vp->vp.attrs[1]);
+   BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_RESULT), 1);
+   PUSH_DATA (push, vp->max_out);
+   BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_TEMP), 1);
+   PUSH_DATA (push, vp->max_gpr);
+   BEGIN_NV04(push, NV50_3D(VP_START_ID), 1);
+   PUSH_DATA (push, vp->code_base);
 }
 
 void
 nv50_fragprog_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *fp = nv50->fragprog;
 
    if (!nv50_program_validate(nv50, fp))
          return;
-
-   BEGIN_RING(chan, RING_3D(FP_REG_ALLOC_TEMP), 1);
-   OUT_RING  (chan, fp->max_gpr);
-   BEGIN_RING(chan, RING_3D(FP_RESULT_COUNT), 1);
-   OUT_RING  (chan, fp->max_out);
-   BEGIN_RING(chan, RING_3D(FP_CONTROL), 1);
-   OUT_RING  (chan, fp->fp.flags[0]);
-   BEGIN_RING(chan, RING_3D(FP_CTRL_UNK196C), 1);
-   OUT_RING  (chan, fp->fp.flags[1]);
-   BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
-   OUT_RING  (chan, fp->code_base);
+   nv50_program_update_context_state(nv50, fp, 1);
+
+   BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1);
+   PUSH_DATA (push, fp->max_gpr);
+   BEGIN_NV04(push, NV50_3D(FP_RESULT_COUNT), 1);
+   PUSH_DATA (push, fp->max_out);
+   BEGIN_NV04(push, NV50_3D(FP_CONTROL), 1);
+   PUSH_DATA (push, fp->fp.flags[0]);
+   BEGIN_NV04(push, NV50_3D(FP_CTRL_UNK196C), 1);
+   PUSH_DATA (push, fp->fp.flags[1]);
+   BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
+   PUSH_DATA (push, fp->code_base);
 }
 
 void
 nv50_gmtyprog_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *gp = nv50->gmtyprog;
 
-   if (!gp) /* GP_ENABLE is updated in linkage validation */
-      return;
-   if (!nv50_program_validate(nv50, gp))
-      return;
+   if (gp) {
+      BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_TEMP), 1);
+      PUSH_DATA (push, gp->max_gpr);
+      BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_RESULT), 1);
+      PUSH_DATA (push, gp->max_out);
+      BEGIN_NV04(push, NV50_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
+      PUSH_DATA (push, gp->gp.prim_type);
+      BEGIN_NV04(push, NV50_3D(GP_VERTEX_OUTPUT_COUNT), 1);
+      PUSH_DATA (push, gp->gp.vert_count);
+      BEGIN_NV04(push, NV50_3D(GP_START_ID), 1);
+      PUSH_DATA (push, gp->code_base);
+   }
+   nv50_program_update_context_state(nv50, gp, 2);
 
-   BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1);
-   OUT_RING  (chan, gp->max_gpr);
-   BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_RESULT), 1);
-   OUT_RING  (chan, gp->max_out);
-   BEGIN_RING(chan, RING_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
-   OUT_RING  (chan, gp->gp.prim_type);
-   BEGIN_RING(chan, RING_3D(GP_VERTEX_OUTPUT_COUNT), 1);
-   OUT_RING  (chan, gp->gp.vert_count);
-   BEGIN_RING(chan, RING_3D(GP_START_ID), 1);
-   OUT_RING  (chan, gp->code_base);
+   /* GP_ENABLE is updated in linkage validation */
 }
 
 static void
 nv50_sprite_coords_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    uint32_t pntc[8], mode;
    struct nv50_program *fp = nv50->fragprog;
    unsigned i, c;
@@ -240,9 +251,9 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
 
    if (!nv50->rast->pipe.point_quad_rasterization) {
       if (nv50->state.point_sprite) {
-         BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+         BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8);
          for (i = 0; i < 8; ++i)
-            OUT_RING(chan, 0);
+            PUSH_DATA(push, 0);
 
          nv50->state.point_sprite = FALSE;
       }
@@ -278,43 +289,43 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
    else
       mode = 0x10;
 
-   BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1);
-   OUT_RING  (chan, mode);
+   BEGIN_NV04(push, NV50_3D(POINT_SPRITE_CTRL), 1);
+   PUSH_DATA (push, mode);
 
-   BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
-   OUT_RINGp (chan, pntc, 8);
+   BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+   PUSH_DATAp(push, pntc, 8);
 }
 
 /* Validate state derived from shaders and the rasterizer cso. */
 void
 nv50_validate_derived_rs(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    uint32_t color, psize;
 
    nv50_sprite_coords_validate(nv50);
 
    if (nv50->dirty & NV50_NEW_FRAGPROG)
       return;
-   psize = nv50->state.semantic_psize & ~NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
-   color = nv50->state.semantic_color & ~NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+   psize = nv50->state.semantic_psize & ~NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK;
+   color = nv50->state.semantic_color & ~NV50_3D_SEMANTIC_COLOR_CLMP_EN;
 
    if (nv50->rast->pipe.clamp_vertex_color)
-      color |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+      color |= NV50_3D_SEMANTIC_COLOR_CLMP_EN;
 
    if (color != nv50->state.semantic_color) {
       nv50->state.semantic_color = color;
-      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 1);
-      OUT_RING  (chan, color);
+      BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 1);
+      PUSH_DATA (push, color);
    }
 
    if (nv50->rast->pipe.point_size_per_vertex)
-      psize |= NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
+      psize |= NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK;
 
    if (psize != nv50->state.semantic_psize) {
       nv50->state.semantic_psize = psize;
-      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_3), 1);
-      OUT_RING  (chan, psize);
+      BEGIN_NV04(push, NV50_3D(SEMANTIC_PTSZ), 1);
+      PUSH_DATA (push, psize);
    }
 }
 
@@ -348,7 +359,7 @@ nv50_vec4_map(uint8_t *map, int mid, uint32_t lin[4],
 void
 nv50_fp_linkage_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog;
    struct nv50_program *fp = nv50->fragprog;
    struct nv50_varying dummy;
@@ -409,48 +420,48 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    }
 
    if (nv50->rast->pipe.clamp_vertex_color)
-      colors |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+      colors |= NV50_3D_SEMANTIC_COLOR_CLMP_EN;
 
    n = (m + 3) / 4;
    assert(m <= 64);
 
    if (unlikely(nv50->gmtyprog)) {
-      BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1);
-      OUT_RING  (chan, m);
-      BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n);
-      OUT_RINGp (chan, map, n);
+      BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP_SIZE), 1);
+      PUSH_DATA (push, m);
+      BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP(0)), n);
+      PUSH_DATAp(push, map, n);
    } else {
-      BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
-      OUT_RING  (chan, vp->vp.attrs[2]);
+      BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
+      PUSH_DATA (push, vp->vp.attrs[2]);
 
-      BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1);
-      OUT_RING  (chan, primid);
+      BEGIN_NV04(push, NV50_3D(SEMANTIC_PRIM_ID), 1);
+      PUSH_DATA (push, primid);
 
-      BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
-      OUT_RING  (chan, m);
-      BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
-      OUT_RINGp (chan, map, n);
+      BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
+      PUSH_DATA (push, m);
+      BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
+      PUSH_DATAp(push, map, n);
    }
 
-   BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4);
-   OUT_RING  (chan, colors);
-   OUT_RING  (chan, (vp->vp.clpd_nr << 8) | 4);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, psiz);
+   BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4);
+   PUSH_DATA (push, colors);
+   PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, psiz);
 
-   BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1);
-   OUT_RING  (chan, interp);
+   BEGIN_NV04(push, NV50_3D(FP_INTERPOLANT_CTRL), 1);
+   PUSH_DATA (push, interp);
 
    nv50->state.interpolant_ctrl = interp;
 
    nv50->state.semantic_color = colors;
    nv50->state.semantic_psize = psiz;
 
-   BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
-   OUT_RINGp (chan, lin, 4);
+   BEGIN_NV04(push, NV50_3D(NOPERSPECTIVE_BITMAP(0)), 4);
+   PUSH_DATAp(push, lin, 4);
 
-   BEGIN_RING(chan, RING_3D(GP_ENABLE), 1);
-   OUT_RING  (chan, nv50->gmtyprog ? 1 : 0);
+   BEGIN_NV04(push, NV50_3D(GP_ENABLE), 1);
+   PUSH_DATA (push, nv50->gmtyprog ? 1 : 0);
 }
 
 static int
@@ -486,7 +497,7 @@ nv50_vp_gp_mapping(uint8_t *map, int m,
 void
 nv50_gp_linkage_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *vp = nv50->vertprog;
    struct nv50_program *gp = nv50->gmtyprog;
    int m = 0;
@@ -501,11 +512,11 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
 
    n = (m + 3) / 4;
 
-   BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
-   OUT_RING  (chan, vp->vp.attrs[2] | gp->vp.attrs[2]);
+   BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
+   PUSH_DATA (push, vp->vp.attrs[2] | gp->vp.attrs[2]);
 
-   BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
-   OUT_RING  (chan, m);
-   BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
-   OUT_RINGp (chan, map, n);
+   BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
+   PUSH_DATA (push, m);
+   BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
+   PUSH_DATAp(push, map, n);
 }
index 0f46afb882b5f1f76a336426336390a76ffb7e2f..e1e1af039bb1ae9ef15f605503b734ac71381d43 100644 (file)
@@ -121,7 +121,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
    boolean emit_common_func = cso->rt[0].blend_enable;
    uint32_t ms;
 
-   if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
+   if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
       SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
       SB_DATA    (so, cso->independent_blend_enable);
    }
@@ -142,7 +142,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
             emit_common_func = TRUE;
       }
 
-      if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
+      if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
          emit_common_func = FALSE;
 
          for (i = 0; i < 8; ++i) {
@@ -628,7 +628,7 @@ nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
 
    nv50->num_textures[s] = nr;
 
-   nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
 
    nv50->dirty |= NV50_NEW_TEXTURES;
 }
@@ -741,13 +741,15 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
-   if (nv50->constbuf[shader][index])
-      nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
-                              nv04_resource(nv50->constbuf[shader][index]));
-
    pipe_resource_reference(&nv50->constbuf[shader][index], res);
 
    nv50->constbuf_dirty[shader] |= 1 << index;
+   if (res)
+      nv50->constbuf_valid[shader] |= 1 << index;
+   else
+      nv50->constbuf_valid[shader] &= ~(1 << index);
+
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
 
    nv50->dirty |= NV50_NEW_CONSTBUF;
 }
@@ -802,6 +804,8 @@ nv50_set_framebuffer_state(struct pipe_context *pipe,
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
+
    nv50->framebuffer = *fb;
    nv50->dirty |= NV50_NEW_FRAMEBUFFER;
 }
@@ -852,7 +856,7 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
    memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
    nv50->num_vtxbufs = count;
 
-   nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
 
    nv50->dirty |= NV50_NEW_ARRAYS;
 }
@@ -863,10 +867,15 @@ nv50_set_index_buffer(struct pipe_context *pipe,
 {
    struct nv50_context *nv50 = nv50_context(pipe);
 
-   if (ib) {
-      pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+   if (nv50->idxbuf.buffer)
+      nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
 
-      memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+   if (ib && ib->buffer) {
+      pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+      nv50->idxbuf.offset = ib->offset;
+      nv50->idxbuf.index_size = ib->index_size;
+      if (nouveau_resource_mapped_by_gpu(ib->buffer))
+         BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD);
    } else {
       pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
    }
index c8a1c4ecb37381e2268c79e2f270496963ad8249..7af992076c7185bb9051f11e6f68278efe814f43 100644 (file)
@@ -5,48 +5,44 @@
 static void
 nv50_validate_fb(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
    unsigned i;
    unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
-   boolean serialize = FALSE;
 
-   nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
 
-   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
-   OUT_RING  (chan, (076543210 << 4) | fb->nr_cbufs);
-   BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
-   OUT_RING  (chan, fb->width << 16);
-   OUT_RING  (chan, fb->height << 16);
-
-   MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
+   BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+   PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
+   BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
+   PUSH_DATA (push, fb->width << 16);
+   PUSH_DATA (push, fb->height << 16);
 
    for (i = 0; i < fb->nr_cbufs; ++i) {
       struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
       struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
       struct nouveau_bo *bo = mt->base.bo;
-      uint32_t offset = sf->offset;
-
-      BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5);
-      OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-      OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-      OUT_RING  (chan, nv50_format_table[sf->base.format].rt);
-      if (likely(nouveau_bo_tile_layout(bo))) {
-         OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
-         OUT_RING  (chan, mt->layer_stride >> 2);
-         BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
-         OUT_RING  (chan, sf->width);
-         OUT_RING  (chan, sf->height);
-         BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
-         OUT_RING  (chan, sf->depth);
+
+      BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
+      PUSH_DATAh(push, bo->offset + sf->offset);
+      PUSH_DATA (push, bo->offset + sf->offset);
+      PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
+      if (likely(nouveau_bo_memtype(bo))) {
+         PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+         PUSH_DATA (push, mt->layer_stride >> 2);
+         BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
+         PUSH_DATA (push, sf->width);
+         PUSH_DATA (push, sf->height);
+         BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+         PUSH_DATA (push, sf->depth);
       } else {
-         OUT_RING  (chan, 0);
-         OUT_RING  (chan, 0);
-         BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
-         OUT_RING  (chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
-         OUT_RING  (chan, sf->height);
-         BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
-         OUT_RING  (chan, 0);
+         PUSH_DATA (push, 0);
+         PUSH_DATA (push, 0);
+         BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
+         PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
+         PUSH_DATA (push, sf->height);
+         BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+         PUSH_DATA (push, 0);
 
          assert(!fb->zsbuf);
          assert(!mt->ms_mode);
@@ -55,13 +51,12 @@ nv50_validate_fb(struct nv50_context *nv50)
       ms_mode = mt->ms_mode;
 
       if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
-         serialize = TRUE;
+         nv50->state.rt_serialize = TRUE;
       mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
 
       /* only register for writing, otherwise we'd always serialize here */
-      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
-                               NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+      BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
    }
 
    if (fb->zsbuf) {
@@ -69,87 +64,79 @@ nv50_validate_fb(struct nv50_context *nv50)
       struct nv50_surface *sf = nv50_surface(fb->zsbuf);
       struct nouveau_bo *bo = mt->base.bo;
       int unk = mt->base.base.target == PIPE_TEXTURE_2D;
-      uint32_t offset = sf->offset;
-
-      MARK_RING (chan, 12, 2);
-      BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
-      OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-      OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-      OUT_RING  (chan, nv50_format_table[fb->zsbuf->format].rt);
-      OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
-      OUT_RING  (chan, mt->layer_stride >> 2);
-      BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
-      OUT_RING  (chan, sf->width);
-      OUT_RING  (chan, sf->height);
-      OUT_RING  (chan, (unk << 16) | sf->depth);
+
+      BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
+      PUSH_DATAh(push, bo->offset + sf->offset);
+      PUSH_DATA (push, bo->offset + sf->offset);
+      PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt);
+      PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+      PUSH_DATA (push, mt->layer_stride >> 2);
+      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+      PUSH_DATA (push, 1);
+      BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
+      PUSH_DATA (push, sf->width);
+      PUSH_DATA (push, sf->height);
+      PUSH_DATA (push, (unk << 16) | sf->depth);
 
       ms_mode = mt->ms_mode;
 
       if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
-         serialize = TRUE;
+         nv50->state.rt_serialize = TRUE;
       mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
 
-      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
-                               NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+      BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
    } else {
-      BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+      PUSH_DATA (push, 0);
    }
 
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
-   OUT_RING  (chan, ms_mode);
+   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+   PUSH_DATA (push, ms_mode);
 
-   BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
-   OUT_RING  (chan, fb->width << 16);
-   OUT_RING  (chan, fb->height << 16);
-
-   if (serialize) {
-      BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
-      OUT_RING  (chan, 0);
-   }
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
+   PUSH_DATA (push, fb->width << 16);
+   PUSH_DATA (push, fb->height << 16);
 }
 
 static void
 nv50_validate_blend_colour(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
-   BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
-   OUT_RINGf (chan, nv50->blend_colour.color[0]);
-   OUT_RINGf (chan, nv50->blend_colour.color[1]);
-   OUT_RINGf (chan, nv50->blend_colour.color[2]);
-   OUT_RINGf (chan, nv50->blend_colour.color[3]);    
+   BEGIN_NV04(push, NV50_3D(BLEND_COLOR(0)), 4);
+   PUSH_DATAf(push, nv50->blend_colour.color[0]);
+   PUSH_DATAf(push, nv50->blend_colour.color[1]);
+   PUSH_DATAf(push, nv50->blend_colour.color[2]);
+   PUSH_DATAf(push, nv50->blend_colour.color[3]);
 }
 
 static void
 nv50_validate_stencil_ref(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
-   BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1);
-   OUT_RING  (chan, nv50->stencil_ref.ref_value[0]);
-   BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1);
-   OUT_RING  (chan, nv50->stencil_ref.ref_value[1]);
+   BEGIN_NV04(push, NV50_3D(STENCIL_FRONT_FUNC_REF), 1);
+   PUSH_DATA (push, nv50->stencil_ref.ref_value[0]);
+   BEGIN_NV04(push, NV50_3D(STENCIL_BACK_FUNC_REF), 1);
+   PUSH_DATA (push, nv50->stencil_ref.ref_value[1]);
 }
 
 static void
 nv50_validate_stipple(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    unsigned i;
 
-   BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
+   BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
    for (i = 0; i < 32; ++i)
-      OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i]));
+      PUSH_DATA(push, util_bswap32(nv50->stipple.stipple[i]));
 }
 
 static void
 nv50_validate_scissor(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct pipe_scissor_state *s = &nv50->scissor;
 #ifdef NV50_SCISSORS_CLIPPING
    struct pipe_viewport_state *vp = &nv50->viewport;
@@ -178,38 +165,38 @@ nv50_validate_scissor(struct nv50_context *nv50)
    miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
    maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
 
-   BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
-   OUT_RING  (chan, (maxx << 16) | minx);
-   OUT_RING  (chan, (maxy << 16) | miny);
+   BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
+   PUSH_DATA (push, (maxx << 16) | minx);
+   PUSH_DATA (push, (maxy << 16) | miny);
 #else
-   BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
-   OUT_RING  (chan, (s->maxx << 16) | s->minx);
-   OUT_RING  (chan, (s->maxy << 16) | s->miny);
+   BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
+   PUSH_DATA (push, (s->maxx << 16) | s->minx);
+   PUSH_DATA (push, (s->maxy << 16) | s->miny);
 #endif
 }
 
 static void
 nv50_validate_viewport(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    float zmin, zmax;
 
-   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
-   OUT_RINGf (chan, nv50->viewport.translate[0]);
-   OUT_RINGf (chan, nv50->viewport.translate[1]);
-   OUT_RINGf (chan, nv50->viewport.translate[2]);
-   BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
-   OUT_RINGf (chan, nv50->viewport.scale[0]);
-   OUT_RINGf (chan, nv50->viewport.scale[1]);
-   OUT_RINGf (chan, nv50->viewport.scale[2]);
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(0)), 3);
+   PUSH_DATAf(push, nv50->viewport.translate[0]);
+   PUSH_DATAf(push, nv50->viewport.translate[1]);
+   PUSH_DATAf(push, nv50->viewport.translate[2]);
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3);
+   PUSH_DATAf(push, nv50->viewport.scale[0]);
+   PUSH_DATAf(push, nv50->viewport.scale[1]);
+   PUSH_DATAf(push, nv50->viewport.scale[2]);
 
    zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
    zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
 
 #ifdef NV50_SCISSORS_CLIPPING
-   BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
-   OUT_RINGf (chan, zmin);
-   OUT_RINGf (chan, zmax);
+   BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
+   PUSH_DATAf(push, zmin);
+   PUSH_DATAf(push, zmax);
 #endif
 }
 
@@ -234,15 +221,15 @@ nv50_check_program_ucps(struct nv50_context *nv50,
 static void
 nv50_validate_clip(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_program *vp;
    uint8_t clip_enable;
 
    if (nv50->dirty & NV50_NEW_CLIP) {
-      BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
-      OUT_RING  (chan, (0 << 8) | NV50_CB_AUX);
-      BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
-      OUT_RINGp (chan, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
+      BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+      PUSH_DATA (push, (0 << 8) | NV50_CB_AUX);
+      BEGIN_NI04(push, NV50_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
+      PUSH_DATAp(push, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
    }
 
    vp = nv50->gmtyprog;
@@ -251,8 +238,8 @@ nv50_validate_clip(struct nv50_context *nv50)
 
    clip_enable = nv50->rast->pipe.clip_plane_enable;
 
-   BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
-   OUT_RING  (chan, clip_enable);
+   BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_ENABLE), 1);
+   PUSH_DATA (push, clip_enable);
 
    if (clip_enable)
       nv50_check_program_ucps(nv50, vp, clip_enable);
@@ -261,34 +248,34 @@ nv50_validate_clip(struct nv50_context *nv50)
 static void
 nv50_validate_blend(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
-   WAIT_RING(chan, nv50->blend->size);
-   OUT_RINGp(chan, nv50->blend->state, nv50->blend->size);
+   PUSH_SPACE(push, nv50->blend->size);
+   PUSH_DATAp(push, nv50->blend->state, nv50->blend->size);
 }
 
 static void
 nv50_validate_zsa(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
-   WAIT_RING(chan, nv50->zsa->size);
-   OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size);
+   PUSH_SPACE(push, nv50->zsa->size);
+   PUSH_DATAp(push, nv50->zsa->state, nv50->zsa->size);
 }
 
 static void
 nv50_validate_rasterizer(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
-   WAIT_RING(chan, nv50->rast->size);
-   OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
+   PUSH_SPACE(push, nv50->rast->size);
+   PUSH_DATAp(push, nv50->rast->state, nv50->rast->size);
 }
 
 static void
 nv50_validate_sample_mask(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
    unsigned mask[4] =
    {
@@ -298,11 +285,11 @@ nv50_validate_sample_mask(struct nv50_context *nv50)
       nv50->sample_mask & 0xffff
    };
 
-   BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
-   OUT_RING  (chan, mask[0]);
-   OUT_RING  (chan, mask[1]);
-   OUT_RING  (chan, mask[2]);
-   OUT_RING  (chan, mask[3]);
+   BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
+   PUSH_DATA (push, mask[0]);
+   PUSH_DATA (push, mask[1]);
+   PUSH_DATA (push, mask[2]);
+   PUSH_DATA (push, mask[3]);
 }
 
 static void
@@ -378,6 +365,7 @@ boolean
 nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
 {
    uint32_t state_mask;
+   int ret;
    unsigned i;
 
    if (nv50->screen->cur_ctx != nv50)
@@ -393,11 +381,21 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
             validate->func(nv50);
       }
       nv50->dirty &= ~state_mask;
-   }
 
-   MARK_RING(nv50->screen->base.channel, words, 0);
+      if (nv50->state.rt_serialize) {
+         nv50->state.rt_serialize = FALSE;
+         BEGIN_NV04(nv50->base.pushbuf, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+         PUSH_DATA (nv50->base.pushbuf, 0);
+      }
 
-   nv50_bufctx_emit_relocs(nv50);
+      nv50_bufctx_fence(nv50->bufctx_3d, FALSE);
+   }
+   nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d);
+   ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
 
-   return TRUE;
+   if (unlikely(nv50->state.flushed)) {
+      nv50->state.flushed = FALSE;
+      nv50_bufctx_fence(nv50->bufctx_3d, TRUE);
+   }
+   return !ret;
 }
index c443dfbfec643fd8954553e6229505a5768284bd..b056e19ea503df51770184cc4c9a598c92e33622 100644 (file)
@@ -6,13 +6,11 @@
 
 #define NV50_SCISSORS_CLIPPING
 
-#define SB_BEGIN_3D(so, m, s)                                                  \
-   (so)->state[(so)->size++] =                                                 \
-      ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m
+#define SB_BEGIN_3D(so, m, s) \
+   (so)->state[(so)->size++] = NV50_FIFO_PKHDR(NV50_3D(m), s)
 
-#define SB_BEGIN_3D_(so, m, s)                                                 \
-   (so)->state[(so)->size++] =                                                 \
-      ((s) << 18) | (NV50_SUBCH_3D << 13) | m
+#define SB_BEGIN_3D_(so, m, s) \
+   (so)->state[(so)->size++] = NV50_FIFO_PKHDR(SUBC_3D(m), s)
 
 #define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
 
index 28e34bd9ef6ab02e93a6ec1ca972e4cdca90f3d8..0d29dcc8a2a40a92e39b4d5638767eff2822299a 100644 (file)
@@ -70,14 +70,13 @@ nv50_2d_format(enum pipe_format format)
 }
 
 static int
-nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
+nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
                     struct nv50_miptree *mt, unsigned level, unsigned layer)
 {
    struct nouveau_bo *bo = mt->base.bo;
    uint32_t width, height, depth;
    uint32_t format;
    uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
-   uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
    uint32_t offset = mt->level[level].offset;
 
    format = nv50_2d_format(mt->base.base.format);
@@ -99,44 +98,44 @@ nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
       depth = u_minify(mt->base.base.depth0, level);
    }
 
-   if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
-      BEGIN_RING(chan, RING_2D_(mthd), 2);
-      OUT_RING  (chan, format);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
-      OUT_RING  (chan, mt->level[level].pitch);
-      OUT_RING  (chan, width);
-      OUT_RING  (chan, height);
-      OUT_RELOCh(chan, bo, offset, flags);
-      OUT_RELOCl(chan, bo, offset, flags);
+   if (!nouveau_bo_memtype(bo)) {
+      BEGIN_NV04(push, SUBC_2D(mthd), 2);
+      PUSH_DATA (push, format);
+      PUSH_DATA (push, 1);
+      BEGIN_NV04(push, SUBC_2D(mthd + 0x14), 5);
+      PUSH_DATA (push, mt->level[level].pitch);
+      PUSH_DATA (push, width);
+      PUSH_DATA (push, height);
+      PUSH_DATAh(push, bo->offset + offset);
+      PUSH_DATA (push, bo->offset + offset);
    } else {
-      BEGIN_RING(chan, RING_2D_(mthd), 5);
-      OUT_RING  (chan, format);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, mt->level[level].tile_mode << 4);
-      OUT_RING  (chan, depth);
-      OUT_RING  (chan, layer);
-      BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
-      OUT_RING  (chan, width);
-      OUT_RING  (chan, height);
-      OUT_RELOCh(chan, bo, offset, flags);
-      OUT_RELOCl(chan, bo, offset, flags);
+      BEGIN_NV04(push, SUBC_2D(mthd), 5);
+      PUSH_DATA (push, format);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, mt->level[level].tile_mode);
+      PUSH_DATA (push, depth);
+      PUSH_DATA (push, layer);
+      BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4);
+      PUSH_DATA (push, width);
+      PUSH_DATA (push, height);
+      PUSH_DATAh(push, bo->offset + offset);
+      PUSH_DATA (push, bo->offset + offset);
    }
 
 #if 0
    if (dst) {
-      BEGIN_RING(chan, RING_2D_(NV50_2D_CLIP_X), 4);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, width);
-      OUT_RING  (chan, height);
+      BEGIN_NV04(push, SUBC_2D(NV50_2D_CLIP_X), 4);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, width);
+      PUSH_DATA (push, height);
    }
 #endif
    return 0;
 }
 
 static int
-nv50_2d_texture_do_copy(struct nouveau_channel *chan,
+nv50_2d_texture_do_copy(struct nouveau_pushbuf *push,
                         struct nv50_miptree *dst, unsigned dst_level,
                         unsigned dx, unsigned dy, unsigned dz,
                         struct nv50_miptree *src, unsigned src_level,
@@ -150,16 +149,16 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan,
 
    int ret;
    uint32_t ctrl;
-
+#if 0
    ret = MARK_RING(chan, 2 * 16 + 32, 4);
    if (ret)
       return ret;
-
-   ret = nv50_2d_texture_set(chan, 1, dst, dst_level, dz);
+#endif
+   ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz);
    if (ret)
       return ret;
 
-   ret = nv50_2d_texture_set(chan, 0, src, src_level, sz);
+   ret = nv50_2d_texture_set(push, 0, src, src_level, sz);
    if (ret)
       return ret;
 
@@ -168,23 +167,23 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan,
       ctrl = 0x11;
 
    /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */
-   BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
-   OUT_RING  (chan, ctrl);
-   BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
-   OUT_RING  (chan, dx << dst->ms_x);
-   OUT_RING  (chan, dy << dst->ms_y);
-   OUT_RING  (chan, w << dst->ms_x);
-   OUT_RING  (chan, h << dst->ms_y);
-   BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
-   BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, sx << src->ms_x);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, sy << src->ms_y);
+   BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
+   PUSH_DATA (push, ctrl);
+   BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
+   PUSH_DATA (push, dx << dst->ms_x);
+   PUSH_DATA (push, dy << dst->ms_y);
+   PUSH_DATA (push, w << dst->ms_x);
+   PUSH_DATA (push, h << dst->ms_y);
+   BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
+   BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, sx << src->ms_x);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, sy << src->ms_y);
 
    return 0;
 }
@@ -196,7 +195,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
                           struct pipe_resource *src, unsigned src_level,
                           const struct pipe_box *src_box)
 {
-   struct nv50_screen *screen = nv50_context(pipe)->screen;
+   struct nv50_context *nv50 = nv50_context(pipe);
    int ret;
    boolean m2mf;
    unsigned dst_layer = dstz, src_layer = src_box->z;
@@ -227,7 +226,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
                            src_box->x, src_box->y, src_box->z);
 
       for (i = 0; i < src_box->depth; ++i) {
-         nv50_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
+         nv50_m2mf_transfer_rect(nv50, &drect, &srect, nx, ny);
 
          if (nv50_miptree(dst)->layout_3d)
             drect.z++;
@@ -246,16 +245,22 @@ nv50_resource_copy_region(struct pipe_context *pipe,
           (nv50_2d_format_faithful(src->format) &&
            nv50_2d_format_faithful(dst->format)));
 
+   BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
+   BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
+   nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
+   nouveau_pushbuf_validate(nv50->base.pushbuf);
+
    for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
-      ret = nv50_2d_texture_do_copy(screen->base.channel,
+      ret = nv50_2d_texture_do_copy(nv50->base.pushbuf,
                                     nv50_miptree(dst), dst_level,
                                     dstx, dsty, dst_layer,
                                     nv50_miptree(src), src_level,
                                     src_box->x, src_box->y, src_layer,
                                     src_box->width, src_box->height);
       if (ret)
-         return;
+         break;
    }
+   nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
 }
 
 static void
@@ -266,51 +271,50 @@ nv50_clear_render_target(struct pipe_context *pipe,
                          unsigned width, unsigned height)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nv50_screen *screen = nv50->screen;
-   struct nouveau_channel *chan = screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_miptree *mt = nv50_miptree(dst->texture);
    struct nv50_surface *sf = nv50_surface(dst);
    struct nouveau_bo *bo = mt->base.bo;
 
-   BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
-   OUT_RINGf (chan, color->f[0]);
-   OUT_RINGf (chan, color->f[1]);
-   OUT_RINGf (chan, color->f[2]);
-   OUT_RINGf (chan, color->f[3]);
-
+   BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
+   PUSH_DATAf(push, color->f[0]);
+   PUSH_DATAf(push, color->f[1]);
+   PUSH_DATAf(push, color->f[2]);
+   PUSH_DATAf(push, color->f[3]);
+#if 0
    if (MARK_RING(chan, 18, 2))
       return;
-
-   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 5);
-   OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-   OUT_RING  (chan, nv50_format_table[dst->format].rt);
-   OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2);
-   if (nouveau_bo_tile_layout(bo))
-      OUT_RING(chan, sf->width);
+#endif
+   BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
+   PUSH_DATAh(push, bo->offset + sf->offset);
+   PUSH_DATA (push, bo->offset + sf->offset);
+   PUSH_DATA (push, nv50_format_table[dst->format].rt);
+   PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
+   if (nouveau_bo_memtype(bo))
+      PUSH_DATA(push, sf->width);
    else
-      OUT_RING(chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
-   OUT_RING  (chan, sf->height);
-   BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
-   OUT_RING  (chan, 1);
-
-   if (!nouveau_bo_tile_layout(bo)) {
-      BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-      OUT_RING  (chan, 0);
+      PUSH_DATA(push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
+   PUSH_DATA (push, sf->height);
+   BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+   PUSH_DATA (push, 1);
+
+   if (!nouveau_bo_memtype(bo)) {
+      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+      PUSH_DATA (push, 0);
    }
 
    /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
 
-   BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
-   OUT_RING  (chan, (width << 16) | dstx);
-   OUT_RING  (chan, (height << 16) | dsty);
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
+   PUSH_DATA (push, (width << 16) | dstx);
+   PUSH_DATA (push, (height << 16) | dsty);
 
-   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-   OUT_RING  (chan, 0x3c);
+   BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+   PUSH_DATA (push, 0x3c);
 
    nv50->dirty |= NV50_NEW_FRAMEBUFFER;
 }
@@ -325,49 +329,48 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
                          unsigned width, unsigned height)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nv50_screen *screen = nv50->screen;
-   struct nouveau_channel *chan = screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_miptree *mt = nv50_miptree(dst->texture);
    struct nv50_surface *sf = nv50_surface(dst);
    struct nouveau_bo *bo = mt->base.bo;
    uint32_t mode = 0;
 
-   assert(nouveau_bo_tile_layout(bo)); /* ZETA cannot be linear */
+   assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
 
    if (clear_flags & PIPE_CLEAR_DEPTH) {
-      BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
-      OUT_RINGf (chan, depth);
+      BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
+      PUSH_DATAf(push, depth);
       mode |= NV50_3D_CLEAR_BUFFERS_Z;
    }
 
    if (clear_flags & PIPE_CLEAR_STENCIL) {
-      BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
-      OUT_RING  (chan, stencil & 0xff);
+      BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
+      PUSH_DATA (push, stencil & 0xff);
       mode |= NV50_3D_CLEAR_BUFFERS_S;
    }
-
+#if 0
    if (MARK_RING(chan, 17, 2))
       return;
-
-   BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
-   OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-   OUT_RING  (chan, nv50_format_table[dst->format].rt);
-   OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
-   OUT_RING  (chan, sf->width);
-   OUT_RING  (chan, sf->height);
-   OUT_RING  (chan, (1 << 16) | 1);
-
-   BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
-   OUT_RING  (chan, (width << 16) | dstx);
-   OUT_RING  (chan, (height << 16) | dsty);
-
-   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-   OUT_RING  (chan, mode);
+#endif
+   BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
+   PUSH_DATAh(push, bo->offset + sf->offset);
+   PUSH_DATA (push, bo->offset + sf->offset);
+   PUSH_DATA (push, nv50_format_table[dst->format].rt);
+   PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
+   PUSH_DATA (push, sf->width);
+   PUSH_DATA (push, sf->height);
+   PUSH_DATA (push, (1 << 16) | 1);
+
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
+   PUSH_DATA (push, (width << 16) | dstx);
+   PUSH_DATA (push, (height << 16) | dsty);
+
+   BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+   PUSH_DATA (push, mode);
 
    nv50->dirty |= NV50_NEW_FRAMEBUFFER;
 }
@@ -378,7 +381,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
            double depth, unsigned stencil)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
    unsigned i;
    uint32_t mode = 0;
@@ -388,34 +391,34 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
       return;
 
    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
-      BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
-      OUT_RINGf (chan, color->f[0]);
-      OUT_RINGf (chan, color->f[1]);
-      OUT_RINGf (chan, color->f[2]);
-      OUT_RINGf (chan, color->f[3]);
+      BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
+      PUSH_DATAf(push, color->f[0]);
+      PUSH_DATAf(push, color->f[1]);
+      PUSH_DATAf(push, color->f[2]);
+      PUSH_DATAf(push, color->f[3]);
       mode =
          NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G |
          NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A;
    }
 
    if (buffers & PIPE_CLEAR_DEPTH) {
-      BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
-      OUT_RING  (chan, fui(depth));
+      BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
+      PUSH_DATA (push, fui(depth));
       mode |= NV50_3D_CLEAR_BUFFERS_Z;
    }
 
    if (buffers & PIPE_CLEAR_STENCIL) {
-      BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
-      OUT_RING  (chan, stencil & 0xff);
+      BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
+      PUSH_DATA (push, stencil & 0xff);
       mode |= NV50_3D_CLEAR_BUFFERS_S;
    }
 
-   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-   OUT_RING  (chan, mode);
+   BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+   PUSH_DATA (push, mode);
 
    for (i = 1; i < fb->nr_cbufs; i++) {
-      BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-      OUT_RING  (chan, (i << 6) | 0x3c);
+      BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+      PUSH_DATA (push, (i << 6) | 0x3c);
    }
 }
 
@@ -709,50 +712,50 @@ nv50_blit_set_src(struct nv50_context *nv50,
 static void
 nv50_blitctx_prepare_state(struct nv50_blitctx *blit)
 {
-   struct nouveau_channel *chan = blit->screen->base.channel;
+   struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
 
    /* blend state */
-   BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1);
-   OUT_RING  (chan, blit->color_mask);
-   BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(LOGIC_OP_ENABLE), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NV04(push, NV50_3D(COLOR_MASK(0)), 1);
+   PUSH_DATA (push, blit->color_mask);
+   BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(LOGIC_OP_ENABLE), 1);
+   PUSH_DATA (push, 0);
 
    /* rasterizer state */
 #ifndef NV50_SCISSORS_CLIPPING
-   BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 1);
-   OUT_RING  (chan, 1);
+   BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1);
+   PUSH_DATA (push, 1);
 #endif
-   BEGIN_RING(chan, RING_3D(VERTEX_TWO_SIDE_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
-   OUT_RING  (chan, 0xffff);
-   OUT_RING  (chan, 0xffff);
-   OUT_RING  (chan, 0xffff);
-   OUT_RING  (chan, 0xffff);
-   BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 3);
-   OUT_RING  (chan, NV50_3D_POLYGON_MODE_FRONT_FILL);
-   OUT_RING  (chan, NV50_3D_POLYGON_MODE_BACK_FILL);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(CULL_FACE_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NV04(push, NV50_3D(VERTEX_TWO_SIDE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
+   PUSH_DATA (push, 0xffff);
+   PUSH_DATA (push, 0xffff);
+   PUSH_DATA (push, 0xffff);
+   PUSH_DATA (push, 0xffff);
+   BEGIN_NV04(push, NV50_3D(POLYGON_MODE_FRONT), 3);
+   PUSH_DATA (push, NV50_3D_POLYGON_MODE_FRONT_FILL);
+   PUSH_DATA (push, NV50_3D_POLYGON_MODE_BACK_FILL);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(CULL_FACE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
+   PUSH_DATA (push, 0);
 
    /* zsa state */
-   BEGIN_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(STENCIL_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NV04(push, NV50_3D(DEPTH_TEST_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(STENCIL_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NV04(push, NV50_3D(ALPHA_TEST_ENABLE), 1);
+   PUSH_DATA (push, 0);
 }
 
 static void
@@ -834,7 +837,7 @@ nv50_resource_resolve(struct pipe_context *pipe,
    struct nv50_context *nv50 = nv50_context(pipe);
    struct nv50_screen *screen = nv50->screen;
    struct nv50_blitctx *blit = screen->blitctx;
-   struct nouveau_channel *chan = screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct pipe_resource *src = info->src.res;
    struct pipe_resource *dst = info->dst.res;
    float x0, x1, y0, y1, z;
@@ -873,12 +876,12 @@ nv50_resource_resolve(struct pipe_context *pipe,
 
    z = (float)info->src.layer;
 
-   BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
-   OUT_RING  (chan,
+   BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
+   PUSH_DATA (push,
               blit->fp.code_base + blit->fp_offset);
 
-   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+   PUSH_DATA (push, 0);
 
    /* Draw a large triangle in screen coordinates covering the whole
     * render target, with scissors defining the destination region.
@@ -886,40 +889,40 @@ nv50_resource_resolve(struct pipe_context *pipe,
     * arranged in a way to yield the desired offset and scale.
     */
 
-   BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
-   OUT_RING  (chan, (info->dst.x1 << 16) | info->dst.x0);
-   OUT_RING  (chan, (info->dst.y1 << 16) | info->dst.y0);
-
-   BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-   OUT_RING  (chan, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
-   OUT_RINGf (chan, x0);
-   OUT_RINGf (chan, y0);
-   OUT_RINGf (chan, z);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
-   OUT_RINGf (chan, 0.0f);
-   OUT_RINGf (chan, 0.0f);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
-   OUT_RINGf (chan, x1);
-   OUT_RINGf (chan, y0);
-   OUT_RINGf (chan, z);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
-   OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x);
-   OUT_RINGf (chan, 0.0f);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
-   OUT_RINGf (chan, x0);
-   OUT_RINGf (chan, y1);
-   OUT_RINGf (chan, z);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
-   OUT_RINGf (chan, 0.0f);
-   OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y);
-   BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
+   PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0);
+   PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0);
+
+   BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+   PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
+   BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
+   PUSH_DATAf(push, x0);
+   PUSH_DATAf(push, y0);
+   PUSH_DATAf(push, z);
+   BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
+   PUSH_DATAf(push, 0.0f);
+   PUSH_DATAf(push, 0.0f);
+   BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
+   PUSH_DATAf(push, x1);
+   PUSH_DATAf(push, y0);
+   PUSH_DATAf(push, z);
+   BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
+   PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
+   PUSH_DATAf(push, 0.0f);
+   BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
+   PUSH_DATAf(push, x0);
+   PUSH_DATAf(push, y1);
+   PUSH_DATAf(push, z);
+   BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
+   PUSH_DATAf(push, 0.0f);
+   PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
+   BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+   PUSH_DATA (push, 0);
 
    /* re-enable normally constant state */
 
-   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
-   OUT_RING  (chan, 1);
+   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+   PUSH_DATA (push, 1);
 
    nv50_blitctx_post_blit(nv50, blit);
 }
index 1be4e9aff19949d3cf83c7a67c2300e4acd35f11..4a769d5b810a7de2b4d57c1f3620fbdbeb8caca5 100644 (file)
@@ -75,6 +75,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
                          const struct pipe_sampler_view *templ)
 {
    const struct util_format_description *desc;
+   uint64_t addr;
    uint32_t *tic;
    uint32_t swz[4];
    uint32_t depth;
@@ -115,15 +116,25 @@ nv50_create_sampler_view(struct pipe_context *pipe,
       (swz[2] << NV50_TIC_0_MAPB__SHIFT) |
       (swz[3] << NV50_TIC_0_MAPA__SHIFT);
 
-   tic[1] = /* mt->base.bo->offset; */ 0;
-   tic[2] = /* mt->base.bo->offset >> 32 */ 0;
+   addr = mt->base.address;
+
+   if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY ||
+       mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) {
+      addr += view->pipe.u.tex.first_layer * mt->layer_stride;
+      depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
+   } else {
+      depth = mt->base.base.depth0;
+   }
+
+   tic[1] = addr;
+   tic[2] = (addr >> 32) & 0xff;
 
    tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
 
    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
       tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
 
-   if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
+   if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
       nv50_init_tic_entry_linear(tic, texture);
       return &view->pipe;
    }
@@ -132,16 +143,8 @@ nv50_create_sampler_view(struct pipe_context *pipe,
       tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
 
    tic[2] |=
-      ((mt->base.bo->tile_mode & 0x0f) << (22 - 0)) |
-      ((mt->base.bo->tile_mode & 0xf0) << (25 - 4));
-
-   depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
-
-   if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY ||
-       mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) {
-      tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride;
-      depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
-   }
+      ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
+      ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
 
    switch (mt->base.base.target) {
    case PIPE_TEXTURE_1D:
@@ -196,7 +199,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
 static boolean
 nv50_validate_tic(struct nv50_context *nv50, int s)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nouveau_bo *txc = nv50->screen->txc;
    unsigned i;
    boolean need_flush = FALSE;
@@ -206,53 +209,46 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
       struct nv04_resource *res;
 
       if (!tic) {
-         BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
-         OUT_RING  (chan, (i << 1) | 0);
+         BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
+         PUSH_DATA (push, (i << 1) | 0);
          continue;
       }
       res = &nv50_miptree(tic->pipe.texture)->base;
 
       if (tic->id < 0) {
-         uint32_t offset = tic->tic[1];
-
          tic->id = nv50_screen_tic_alloc(nv50->screen, tic);
 
-         MARK_RING (chan, 24 + 8, 4);
-         BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
-         OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
-         OUT_RING  (chan, 1);
-         BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
-         OUT_RING  (chan, 262144);
-         OUT_RING  (chan, 65536);
-         OUT_RING  (chan, 1);
-         OUT_RELOCh(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-         OUT_RELOCl(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-         BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
-         OUT_RING  (chan, 0);
-         OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
-         BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
-         OUT_RING  (chan, 32);
-         OUT_RING  (chan, 1);
-         OUT_RING  (chan, 0);
-         OUT_RING  (chan, 1);
-         OUT_RING  (chan, 0);
-         OUT_RING  (chan, 1);
-         OUT_RING  (chan, 0);
-         OUT_RING  (chan, tic->id * 32);
-         OUT_RING  (chan, 0);
-         OUT_RING  (chan, 0);
-         BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), 8);
-         OUT_RING  (chan, tic->tic[0]);
-         OUT_RELOCl(chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-         OUT_RELOC (chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
-                    NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
-         OUT_RINGp (chan, &tic->tic[3], 5);
+         BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
+         PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+         PUSH_DATA (push, 1);
+         BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
+         PUSH_DATA (push, 262144);
+         PUSH_DATA (push, 65536);
+         PUSH_DATA (push, 1);
+         PUSH_DATAh(push, txc->offset);
+         PUSH_DATA (push, txc->offset);
+         BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
+         PUSH_DATA (push, 0);
+         PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+         BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
+         PUSH_DATA (push, 32);
+         PUSH_DATA (push, 1);
+         PUSH_DATA (push, 0);
+         PUSH_DATA (push, 1);
+         PUSH_DATA (push, 0);
+         PUSH_DATA (push, 1);
+         PUSH_DATA (push, 0);
+         PUSH_DATA (push, tic->id * 32);
+         PUSH_DATA (push, 0);
+         PUSH_DATA (push, 0);
+         BEGIN_NI04(push, NV50_2D(SIFC_DATA), 8);
+         PUSH_DATAp(push, &tic->tic[0], 8);
 
          need_flush = TRUE;
       } else
       if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
-         BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
-         OUT_RING  (chan, 0x20); //(tic->id << 4) | 1);
+         BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
+         PUSH_DATA (push, 0x20);
       }
 
       nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
@@ -260,15 +256,14 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
       res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
 
-      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res,
-                               NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+      BCTX_REFN(nv50->bufctx_3d, TEXTURES, res, RD);
 
-      BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
-      OUT_RING  (chan, (tic->id << 9) | (i << 1) | 1);
+      BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
+      PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
    }
    for (; i < nv50->state.num_textures[s]; ++i) {
-      BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
-      OUT_RING  (chan, (i << 1) | 0);
+      BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
+      PUSH_DATA (push, (i << 1) | 0);
    }
    nv50->state.num_textures[s] = nv50->num_textures[s];
 
@@ -283,15 +278,15 @@ void nv50_validate_textures(struct nv50_context *nv50)
    need_flush |= nv50_validate_tic(nv50, 2);
 
    if (need_flush) {
-      BEGIN_RING(nv50->screen->base.channel, RING_3D(TIC_FLUSH), 1);
-      OUT_RING  (nv50->screen->base.channel, 0);
+      BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TIC_FLUSH), 1);
+      PUSH_DATA (nv50->base.pushbuf, 0);
    }
 }
 
 static boolean
 nv50_validate_tsc(struct nv50_context *nv50, int s)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    unsigned i;
    boolean need_flush = FALSE;
 
@@ -299,8 +294,8 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
       struct nv50_tsc_entry *tsc = nv50_tsc_entry(nv50->samplers[s][i]);
 
       if (!tsc) {
-         BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
-         OUT_RING  (chan, (i << 4) | 0);
+         BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+         PUSH_DATA (push, (i << 4) | 0);
          continue;
       }
       if (tsc->id < 0) {
@@ -313,12 +308,12 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
       }
       nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
 
-      BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
-      OUT_RING  (chan, (tsc->id << 12) | (i << 4) | 1);
+      BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+      PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
    }
    for (; i < nv50->state.num_samplers[s]; ++i) {
-      BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
-      OUT_RING  (chan, (i << 4) | 0);
+      BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+      PUSH_DATA (push, (i << 4) | 0);
    }
    nv50->state.num_samplers[s] = nv50->num_samplers[s];
 
@@ -333,7 +328,7 @@ void nv50_validate_samplers(struct nv50_context *nv50)
    need_flush |= nv50_validate_tsc(nv50, 2);
 
    if (need_flush) {
-      BEGIN_RING(nv50->screen->base.channel, RING_3D(TSC_FLUSH), 1);
-      OUT_RING  (nv50->screen->base.channel, 0);
+      BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TSC_FLUSH), 1);
+      PUSH_DATA (nv50->base.pushbuf, 0);
    }
 }
index 6f860e7334863639c92e96cfc766ba07c9404658..b960dc0d191fc72fa9065b8cff7ccc9feaa05977 100644 (file)
@@ -50,12 +50,13 @@ nv50_m2mf_rect_setup(struct nv50_m2mf_rect *rect,
 }
 
 void
-nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nv50_m2mf_transfer_rect(struct nv50_context *nv50,
                         const struct nv50_m2mf_rect *dst,
                         const struct nv50_m2mf_rect *src,
                         uint32_t nblocksx, uint32_t nblocksy)
 {
-   struct nouveau_channel *chan = nouveau_screen(pscreen)->channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
+   struct nouveau_bufctx *bctx = nv50->bufctx;
    const int cpp = dst->cpp;
    uint32_t src_ofst = src->base;
    uint32_t dst_ofst = dst->base;
@@ -65,76 +66,81 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
 
    assert(dst->cpp == src->cpp);
 
-   if (nouveau_bo_tile_layout(src->bo)) {
-      BEGIN_RING(chan, RING_MF(LINEAR_IN), 6);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, src->tile_mode << 4);
-      OUT_RING  (chan, src->width * cpp);
-      OUT_RING  (chan, src->height);
-      OUT_RING  (chan, src->depth);
-      OUT_RING  (chan, src->z);
+   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
+   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
+   nouveau_pushbuf_bufctx(push, bctx);
+   nouveau_pushbuf_validate(push);
+
+   if (nouveau_bo_memtype(src->bo)) {
+      BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 6);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, src->tile_mode);
+      PUSH_DATA (push, src->width * cpp);
+      PUSH_DATA (push, src->height);
+      PUSH_DATA (push, src->depth);
+      PUSH_DATA (push, src->z);
    } else {
       src_ofst += src->y * src->pitch + src->x * cpp;
 
-      BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_IN), 1);
-      OUT_RING  (chan, src->pitch);
+      BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
+      PUSH_DATA (push, 1);
+      BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_IN), 1);
+      PUSH_DATA (push, src->pitch);
    }
 
-   if (nouveau_bo_tile_layout(dst->bo)) {
-      BEGIN_RING(chan, RING_MF(LINEAR_OUT), 6);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, dst->tile_mode << 4);
-      OUT_RING  (chan, dst->width * cpp);
-      OUT_RING  (chan, dst->height);
-      OUT_RING  (chan, dst->depth);
-      OUT_RING  (chan, dst->z);
+   if (nouveau_bo_memtype(dst->bo)) {
+      BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 6);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, dst->tile_mode);
+      PUSH_DATA (push, dst->width * cpp);
+      PUSH_DATA (push, dst->height);
+      PUSH_DATA (push, dst->depth);
+      PUSH_DATA (push, dst->z);
    } else {
       dst_ofst += dst->y * dst->pitch + dst->x * cpp;
 
-      BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_OUT), 1);
-      OUT_RING  (chan, dst->pitch);
+      BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1);
+      PUSH_DATA (push, 1);
+      BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_OUT), 1);
+      PUSH_DATA (push, dst->pitch);
    }
 
    while (height) {
       int line_count = height > 2047 ? 2047 : height;
 
-      MARK_RING (chan, 17, 4);
+      BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2);
+      PUSH_DATAh(push, src->bo->offset + src_ofst);
+      PUSH_DATAh(push, dst->bo->offset + dst_ofst);
 
-      BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
-      OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
-      OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
+      BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2);
+      PUSH_DATA (push, src->bo->offset + src_ofst);
+      PUSH_DATA (push, dst->bo->offset + dst_ofst);
 
-      BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
-      OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
-      OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
-
-      if (nouveau_bo_tile_layout(src->bo)) {
-         BEGIN_RING(chan, RING_MF(TILING_POSITION_IN), 1);
-         OUT_RING  (chan, (sy << 16) | (src->x * cpp));
+      if (nouveau_bo_memtype(src->bo)) {
+         BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_IN), 1);
+         PUSH_DATA (push, (sy << 16) | (src->x * cpp));
       } else {
          src_ofst += line_count * src->pitch;
       }
-      if (nouveau_bo_tile_layout(dst->bo)) {
-         BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT), 1);
-         OUT_RING  (chan, (dy << 16) | (dst->x * cpp));
+      if (nouveau_bo_memtype(dst->bo)) {
+         BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_OUT), 1);
+         PUSH_DATA (push, (dy << 16) | (dst->x * cpp));
       } else {
          dst_ofst += line_count * dst->pitch;
       }
 
-      BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
-      OUT_RING  (chan, nblocksx * cpp);
-      OUT_RING  (chan, line_count);
-      OUT_RING  (chan, (1 << 8) | (1 << 0));
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4);
+      PUSH_DATA (push, nblocksx * cpp);
+      PUSH_DATA (push, line_count);
+      PUSH_DATA (push, (1 << 8) | (1 << 0));
+      PUSH_DATA (push, 0);
 
       height -= line_count;
       sy += line_count;
       dy += line_count;
    }
+
+   nouveau_bufctx_reset(bctx, 0);
 }
 
 void
@@ -142,55 +148,60 @@ nv50_sifc_linear_u8(struct nouveau_context *nv,
                     struct nouveau_bo *dst, unsigned offset, unsigned domain,
                     unsigned size, const void *data)
 {
-   struct nouveau_channel *chan = nv->screen->channel;
+   struct nv50_context *nv50 = nv50_context(&nv->pipe);
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    uint32_t *src = (uint32_t *)data;
    unsigned count = (size + 3) / 4;
    unsigned xcoord = offset & 0xff;
 
+   nouveau_bufctx_refn(nv50->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
+   nouveau_pushbuf_bufctx(push, nv50->bufctx);
+   nouveau_pushbuf_validate(push);
+
    offset &= ~0xff;
 
-   MARK_RING (chan, 23, 4);
-   BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
-   OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
-   OUT_RING  (chan, 262144);
-   OUT_RING  (chan, 65536);
-   OUT_RING  (chan, 1);
-   OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
-   BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, NV50_SURFACE_FORMAT_R8_UNORM);
-   BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
-   OUT_RING  (chan, size);
-   OUT_RING  (chan, 1);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, 1);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, 1);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, xcoord);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, 0);
+   BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
+   PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+   PUSH_DATA (push, 1);
+   BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
+   PUSH_DATA (push, 262144);
+   PUSH_DATA (push, 65536);
+   PUSH_DATA (push, 1);
+   PUSH_DATAh(push, dst->offset + offset);
+   PUSH_DATA (push, dst->offset + offset);
+   BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+   BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
+   PUSH_DATA (push, size);
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, xcoord);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0);
 
    while (count) {
-      unsigned nr = AVAIL_RING(chan);
+      unsigned nr;
 
-      if (nr < 9) {
-         FIRE_RING(chan);
-         nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR);
-         continue;
-      }
+      if (!PUSH_SPACE(push, 16))
+         break;
+      nr = PUSH_AVAIL(push);
+      assert(nr >= 16);
       nr = MIN2(count, nr - 1);
       nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
 
-      BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), nr);
-      OUT_RINGp (chan, src, nr);
+      BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr);
+      PUSH_DATAp(push, src, nr);
 
       src += nr;
       count -= nr;
    }
+
+   nouveau_bufctx_reset(nv50->bufctx, 0);
 }
 
 void
@@ -199,33 +210,40 @@ nv50_m2mf_copy_linear(struct nouveau_context *nv,
                       struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
                       unsigned size)
 {
-   struct nouveau_channel *chan = nv->screen->channel;
+   struct nouveau_pushbuf *push = nv->pushbuf;
+   struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
+
+   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
+   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
+   nouveau_pushbuf_bufctx(push, bctx);
+   nouveau_pushbuf_validate(push);
 
-   BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
-   OUT_RING  (chan, 1);
+   BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1);
+   PUSH_DATA (push, 1);
 
    while (size) {
       unsigned bytes = MIN2(size, 1 << 17);
 
-      MARK_RING (chan, 11, 4);
-      BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
-      OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
-      OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
-      BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
-      OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
-      OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
-      BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
-      OUT_RING  (chan, bytes);
-      OUT_RING  (chan, 1);
-      OUT_RING  (chan, (1 << 8) | (1 << 0));
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2);
+      PUSH_DATAh(push, src->offset + srcoff);
+      PUSH_DATAh(push, dst->offset + dstoff);
+      BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2);
+      PUSH_DATA (push, src->offset + srcoff);
+      PUSH_DATA (push, dst->offset + dstoff);
+      BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4);
+      PUSH_DATA (push, bytes);
+      PUSH_DATA (push, 1);
+      PUSH_DATA (push, (1 << 8) | (1 << 0));
+      PUSH_DATA (push, 0);
 
       srcoff += bytes;
       dstoff += bytes;
       size -= bytes;
    }
+
+   nouveau_bufctx_reset(bctx, 0);
 }
 
 struct pipe_transfer *
@@ -236,7 +254,6 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
                           const struct pipe_box *box)
 {
    struct nv50_context *nv50 = nv50_context(pctx);
-   struct pipe_screen *pscreen = pctx->screen;
    struct nouveau_device *dev = nv50->screen->base.device;
    const struct nv50_miptree *mt = nv50_miptree(res);
    struct nv50_transfer *tx;
@@ -272,7 +289,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
    size = tx->base.layer_stride;
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
-                        size * tx->base.box.depth, &tx->rect[1].bo);
+                        size * tx->base.box.depth, NULL, &tx->rect[1].bo);
    if (ret) {
       FREE(tx);
       return NULL;
@@ -290,7 +307,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
       unsigned z = tx->rect[0].z;
       unsigned i;
       for (i = 0; i < box->depth; ++i) {
-         nv50_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
+         nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0],
                                  tx->nblocksx, tx->nblocksy);
          if (mt->layout_3d)
             tx->rect[0].z++;
@@ -310,14 +327,14 @@ void
 nv50_miptree_transfer_del(struct pipe_context *pctx,
                           struct pipe_transfer *transfer)
 {
-   struct pipe_screen *pscreen = pctx->screen;
+   struct nv50_context *nv50 = nv50_context(pctx);
    struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
    struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
    unsigned i;
 
    if (tx->base.usage & PIPE_TRANSFER_WRITE) {
       for (i = 0; i < tx->base.box.depth; ++i) {
-         nv50_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
+         nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1],
                                  tx->nblocksx, tx->nblocksy);
          if (mt->layout_3d)
             tx->rect[0].z++;
@@ -337,6 +354,7 @@ void *
 nv50_miptree_transfer_map(struct pipe_context *pctx,
                           struct pipe_transfer *transfer)
 {
+   struct nv50_screen *screen = nv50_screen(pctx->screen);
    struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
    int ret;
    unsigned flags = 0;
@@ -349,7 +367,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
    if (transfer->usage & PIPE_TRANSFER_WRITE)
       flags |= NOUVEAU_BO_WR;
 
-   ret = nouveau_bo_map(tx->rect[1].bo, flags);
+   ret = nouveau_bo_map(tx->rect[1].bo, flags, screen->base.client);
    if (ret)
       return NULL;
    return tx->rect[1].bo->map;
@@ -359,9 +377,7 @@ void
 nv50_miptree_transfer_unmap(struct pipe_context *pctx,
                             struct pipe_transfer *transfer)
 {
-   struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
-
-   nouveau_bo_unmap(tx->rect[1].bo);
+   /* nothing to do */
 }
 
 void
@@ -370,30 +386,36 @@ nv50_cb_push(struct nouveau_context *nv,
              unsigned base, unsigned size,
              unsigned offset, unsigned words, const uint32_t *data)
 {
-   struct nouveau_channel *chan = nv->screen->channel;
+   struct nouveau_pushbuf *push = nv->pushbuf;
+   struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
 
    assert(!(offset & 3));
    size = align(size, 0x100);
 
+   nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
+   nouveau_pushbuf_bufctx(push, bctx);
+   nouveau_pushbuf_validate(push);
+
    while (words) {
       unsigned nr;
 
-      MARK_RING(chan, 24, 2);
-      nr = AVAIL_RING(chan);
+      nr = PUSH_AVAIL(push);
       nr = MIN2(nr - 7, words);
       nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
 
-      BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
-      OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR);
-      OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR);
-      OUT_RING  (chan, (NV50_CB_TMP << 16) | (size & 0xffff));
-      BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
-      OUT_RING  (chan, (offset << 6) | NV50_CB_TMP);
-      BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
-      OUT_RINGp (chan, data, nr);
+      BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+      PUSH_DATAh(push, bo->offset + base);
+      PUSH_DATA (push, bo->offset + base);
+      PUSH_DATA (push, (NV50_CB_TMP << 16) | (size & 0xffff));
+      BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+      PUSH_DATA (push, (offset << 6) | NV50_CB_TMP);
+      BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
+      PUSH_DATAp(push, data, nr);
 
       words -= nr;
       data += nr;
       offset += nr * 4;
    }
+
+   nouveau_bufctx_reset(bctx, 0);
 }
index cb3ea382f3d8bd0fdedd93bf586fbe00bf3cb081..9be43ef15d4a798f840d9f3ba292d37c4a488deb 100644 (file)
@@ -124,7 +124,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
                   struct pipe_vertex_element *ve, unsigned attr)
 {
    const void *data;
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv04_resource *res = nv04_resource(vb->buffer);
    float v[4];
    const unsigned nc = util_format_get_nr_components(ve->src_format);
@@ -136,30 +136,30 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
 
    switch (nc) {
    case 4:
-      BEGIN_RING(chan, RING_3D(VTX_ATTR_4F_X(attr)), 4);
-      OUT_RINGf (chan, v[0]);
-      OUT_RINGf (chan, v[1]);
-      OUT_RINGf (chan, v[2]);
-      OUT_RINGf (chan, v[3]);
+      BEGIN_NV04(push, NV50_3D(VTX_ATTR_4F_X(attr)), 4);
+      PUSH_DATAf(push, v[0]);
+      PUSH_DATAf(push, v[1]);
+      PUSH_DATAf(push, v[2]);
+      PUSH_DATAf(push, v[3]);
       break;
    case 3:
-      BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(attr)), 3);
-      OUT_RINGf (chan, v[0]);
-      OUT_RINGf (chan, v[1]);
-      OUT_RINGf (chan, v[2]);
+      BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(attr)), 3);
+      PUSH_DATAf(push, v[0]);
+      PUSH_DATAf(push, v[1]);
+      PUSH_DATAf(push, v[2]);
       break;
    case 2:
-      BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(attr)), 2);
-      OUT_RINGf (chan, v[0]);
-      OUT_RINGf (chan, v[1]);
+      BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(attr)), 2);
+      PUSH_DATAf(push, v[0]);
+      PUSH_DATAf(push, v[1]);
       break;
    case 1:
       if (attr == nv50->vertprog->vp.edgeflag) {
-         BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
-         OUT_RING  (chan, v[0] ? 1 : 0);
+         BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
+         PUSH_DATA (push, v[0] ? 1 : 0);
       }
-      BEGIN_RING(chan, RING_3D(VTX_ATTR_1F(attr)), 1);
-      OUT_RINGf (chan, v[0]);
+      BEGIN_NV04(push, NV50_3D(VTX_ATTR_1F(attr)), 1);
+      PUSH_DATAf(push, v[0]);
       break;
    default:
       assert(0);
@@ -193,7 +193,7 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
 
    nv50->vbo_fifo = nv50->vbo_user = 0;
 
-   nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
 
    for (i = 0; i < nv50->num_vtxbufs; ++i) {
       vb = &nv50->vtxbuf[i];
@@ -211,33 +211,37 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
                nv50->vbo_user |= 1 << i;
                assert(vb->stride > vb->buffer_offset);
                nv50_vbuf_range(nv50, i, &base, &size);
-               nouveau_user_buffer_upload(buf, base, size);
+               nouveau_user_buffer_upload(&nv50->base, buf, base, size);
             } else {
                nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART);
             }
             nv50->base.vbo_dirty = TRUE;
          }
       }
-      nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
+      BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
    }
 }
 
 static void
 nv50_update_user_vbufs(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    uint32_t base, offset, size;
    int i;
    uint32_t written = 0;
 
+   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
+
    for (i = 0; i < nv50->vertex->num_elements; ++i) {
       struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe;
       const int b = ve->vertex_buffer_index;
       struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b];
       struct nv04_resource *buf = nv04_resource(vb->buffer);
 
-      if (!(nv50->vbo_user & (1 << b)))
+      if (!(nv50->vbo_user & (1 << b))) {
+         BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
          continue;
+      }
 
       if (!vb->stride) {
          nv50_emit_vtxattr(nv50, vb, ve, i);
@@ -247,17 +251,18 @@ nv50_update_user_vbufs(struct nv50_context *nv50)
 
       if (!(written & (1 << b))) {
          written |= 1 << b;
-         nouveau_user_buffer_upload(buf, base, size);
+         nouveau_user_buffer_upload(&nv50->base, buf, base, size);
       }
       offset = vb->buffer_offset + ve->src_offset;
 
-      MARK_RING (chan, 6, 4);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
-      OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
-      OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
+      PUSH_DATAh(push, buf->address + base + size - 1);
+      PUSH_DATA (push, buf->address + base + size - 1);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
+      PUSH_DATAh(push, buf->address + offset);
+      PUSH_DATA (push, buf->address + offset);
+
+      BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
    }
    nv50->base.vbo_dirty = TRUE;
 }
@@ -278,7 +283,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50)
 void
 nv50_vertex_arrays_validate(struct nv50_context *nv50)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_vertex_stateobj *vertex = nv50->vertex;
    struct pipe_vertex_buffer *vb;
    struct nv50_vertex_element *ve;
@@ -291,15 +296,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
       nv50_prevalidate_vbufs(nv50);
    }
 
-   BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
+   BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
    for (i = 0; i < vertex->num_elements; ++i) {
       ve = &vertex->element[i];
       vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index];
 
       if (likely(vb->stride) || nv50->vbo_fifo) {
-         OUT_RING(chan, ve->state);
+         PUSH_DATA(push, ve->state);
       } else {
-         OUT_RING(chan, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
+         PUSH_DATA(push, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
          nv50->vbo_fifo &= ~(1 << i);
       }
    }
@@ -313,15 +318,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
 
       if (unlikely(ve->pipe.instance_divisor)) {
          if (!(nv50->state.instance_elts & (1 << i))) {
-            BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
-            OUT_RING  (chan, 1);
+            BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+            PUSH_DATA (push, 1);
          }
-         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
-         OUT_RING  (chan, ve->pipe.instance_divisor);
+         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
+         PUSH_DATA (push, ve->pipe.instance_divisor);
       } else
       if (unlikely(nv50->state.instance_elts & (1 << i))) {
-         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
-         OUT_RING  (chan, 0);
+         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+         PUSH_DATA (push, 0);
       }
 
       res = nv04_resource(vb->buffer);
@@ -329,33 +334,32 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
       if (nv50->vbo_fifo || unlikely(vb->stride == 0)) {
          if (!nv50->vbo_fifo)
             nv50_emit_vtxattr(nv50, vb, &ve->pipe, i);
-         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
-         OUT_RING  (chan, 0);
+         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
+         PUSH_DATA (push, 0);
          continue;
       }
 
       size = vb->buffer->width0;
       offset = ve->pipe.src_offset + vb->buffer_offset;
 
-      MARK_RING (chan, 8, 4);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
-      OUT_RING  (chan, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
-      OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
-      OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
+      PUSH_DATA (push, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
+      PUSH_DATAh(push, res->address + size - 1);
+      PUSH_DATA (push, res->address + size - 1);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
+      PUSH_DATAh(push, res->address + offset);
+      PUSH_DATA (push, res->address + offset);
    }
    for (; i < nv50->state.num_vtxelts; ++i) {
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
-      OUT_RING  (chan, NV50_3D_VERTEX_ATTRIB_INACTIVE);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
+      PUSH_DATA (push, NV50_3D_VERTEX_ATTRIB_INACTIVE);
       if (unlikely(nv50->state.instance_elts & (1 << i))) {
-         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
-         OUT_RING  (chan, 0);
+         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+         PUSH_DATA (push, 0);
       }
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
+      PUSH_DATA (push, 0);
    }
 
    nv50->state.num_vtxelts = vertex->num_elements;
@@ -389,65 +393,55 @@ nv50_prim_gl(unsigned prim)
    }
 }
 
-static void
-nv50_draw_vbo_flush_notify(struct nouveau_channel *chan)
-{
-   struct nv50_screen *screen = chan->user_private;
-
-   nouveau_fence_update(&screen->base, TRUE);
-
-   nv50_bufctx_emit_relocs(screen->cur_ctx);
-}
-
 static void
 nv50_draw_arrays(struct nv50_context *nv50,
                  unsigned mode, unsigned start, unsigned count,
                  unsigned instance_count)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    unsigned prim;
 
    if (nv50->state.index_bias) {
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
+      PUSH_DATA (push, 0);
       nv50->state.index_bias = 0;
    }
 
    prim = nv50_prim_gl(mode);
 
    while (instance_count--) {
-      BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-      OUT_RING  (chan, prim);
-      BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2);
-      OUT_RING  (chan, start);
-      OUT_RING  (chan, count);
-      BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+      PUSH_DATA (push, prim);
+      BEGIN_NV04(push, NV50_3D(VERTEX_BUFFER_FIRST), 2);
+      PUSH_DATA (push, start);
+      PUSH_DATA (push, count);
+      BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+      PUSH_DATA (push, 0);
 
       prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
 }
 
 static void
-nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
+nv50_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
 
    if (count & 3) {
       unsigned i;
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3);
+      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), count & 3);
       for (i = 0; i < (count & 3); ++i)
-         OUT_RING(chan, *map++);
+         PUSH_DATA(push, *map++);
       count &= ~3;
    }
    while (count) {
       unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr);
+      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U8), nr);
       for (i = 0; i < nr; ++i) {
-         OUT_RING(chan,
-                  (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
+         PUSH_DATA(push,
+                   (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
          map += 4;
       }
       count -= nr * 4;
@@ -455,22 +449,22 @@ nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
 }
 
 static void
-nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
+nv50_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
 
    if (count & 1) {
       count &= ~1;
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
-      OUT_RING  (chan, *map++);
+      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
    }
    while (count) {
       unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
       for (i = 0; i < nr; ++i) {
-         OUT_RING(chan, (map[1] << 16) | map[0]);
+         PUSH_DATA(push, (map[1] << 16) | map[0]);
          map += 2;
       }
       count -= nr * 2;
@@ -478,7 +472,7 @@ nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
 }
 
 static void
-nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
+nv50_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
@@ -486,8 +480,8 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
    while (count) {
       const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr);
-      OUT_RINGp    (chan, map, nr);
+      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), nr);
+      PUSH_DATAp(push, map, nr);
 
       map += nr;
       count -= nr;
@@ -495,22 +489,22 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
 }
 
 static void
-nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
+nv50_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
                                     unsigned start, unsigned count)
 {
    map += start;
 
    if (count & 1) {
       count--;
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
-      OUT_RING  (chan, *map++);
+      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
    }
    while (count) {
       unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
       for (i = 0; i < nr; ++i) {
-         OUT_RING(chan, (map[1] << 16) | map[0]);
+         PUSH_DATA(push, (map[1] << 16) | map[0]);
          map += 2;
       }
       count -= nr * 2;
@@ -522,121 +516,116 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
                    unsigned mode, unsigned start, unsigned count,
                    unsigned instance_count, int32_t index_bias)
 {
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
    void *data;
+   struct nv04_resource *buf = nv04_resource(nv50->idxbuf.buffer);
    unsigned prim;
    const unsigned index_size = nv50->idxbuf.index_size;
 
    prim = nv50_prim_gl(mode);
 
    if (index_bias != nv50->state.index_bias) {
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
-      OUT_RING  (chan, index_bias);
+      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
+      PUSH_DATA (push, index_bias);
       nv50->state.index_bias = index_bias;
    }
 
    if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) {
-      struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer);
+      unsigned pb_start;
+      unsigned pb_bytes;
+      const unsigned base = buf->offset;
 
       start += nv50->idxbuf.offset >> (index_size >> 1);
 
       while (instance_count--) {
-         BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-         OUT_RING  (chan, mode);
+         BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+         PUSH_DATA (push, prim);
+
+         nouveau_pushbuf_space(push, 8, 0, 1);
 
          switch (index_size) {
          case 4:
-         {
-            WAIT_RING (chan, 2);
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32) | 0x30000, 0);
-            OUT_RING  (chan, count);
-            nouveau_pushbuf_submit(chan, res->bo, res->offset + start * 4,
-                                   count * 4);
-         }
+            BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U32), count);
+            nouveau_pushbuf_data(push, buf->bo, base + start * 4, count * 4);
             break;
          case 2:
-         {
-            unsigned pb_start = (start & ~1);
-            unsigned pb_words = (((start + count + 1) & ~1) - pb_start) >> 1;
-
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
-            OUT_RING  (chan, (start << 31) | count);
-            WAIT_RING (chan, 2);
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16) | 0x30000, 0);
-            OUT_RING  (chan, pb_words);
-            nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start * 2,
-                                   pb_words * 4);
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
-            OUT_RING  (chan, 0);
-            break;
-         }
-         case 1:
-         {
-            unsigned pb_start = (start & ~3);
-            unsigned pb_words = (((start + count + 3) & ~3) - pb_start) >> 1;
-
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
-            OUT_RING  (chan, (start << 30) | count);
-            WAIT_RING (chan, 2);
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8) | 0x30000, 0);
-            OUT_RING  (chan, pb_words);
-            nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start,
-                                   pb_words * 4);
-            BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
-            OUT_RING  (chan, 0);
+            pb_start = (start & ~1) * 2;
+            pb_bytes = ((start + count + 1) & ~1) * 2 - pb_start;
+
+            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
+            PUSH_DATA (push, (start << 31) | count);
+            BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U16), pb_bytes / 4);
+            nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
+            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
+            PUSH_DATA (push, 0);
             break;
-         }
          default:
-            assert(0);
-            return;
+            assert(index_size == 1);
+            pb_start = start & ~3;
+            pb_bytes = ((start + count + 3) & ~3) - pb_start;
+
+            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
+            PUSH_DATA (push, (start << 30) | count);
+            BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U8), pb_bytes / 4);
+            nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
+            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
+            PUSH_DATA (push, 0);
+            break;
          }
-         BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
-         OUT_RING  (chan, 0);
+         BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+         PUSH_DATA (push, 0);
 
-         nv50_resource_fence(res, NOUVEAU_BO_RD);
-
-         mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
+         prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
    } else {
-      data = nouveau_resource_map_offset(&nv50->base,
-                                         nv04_resource(nv50->idxbuf.buffer),
+      data = nouveau_resource_map_offset(&nv50->base, buf,
                                          nv50->idxbuf.offset, NOUVEAU_BO_RD);
       if (!data)
          return;
 
       while (instance_count--) {
-         BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-         OUT_RING  (chan, prim);
+         BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+         PUSH_DATA (push, prim);
          switch (index_size) {
          case 1:
-            nv50_draw_elements_inline_u08(chan, data, start, count);
+            nv50_draw_elements_inline_u08(push, data, start, count);
             break;
          case 2:
-            nv50_draw_elements_inline_u16(chan, data, start, count);
+            nv50_draw_elements_inline_u16(push, data, start, count);
             break;
          case 4:
             if (shorten)
-               nv50_draw_elements_inline_u32_short(chan, data, start, count);
+               nv50_draw_elements_inline_u32_short(push, data, start, count);
             else
-               nv50_draw_elements_inline_u32(chan, data, start, count);
+               nv50_draw_elements_inline_u32(push, data, start, count);
             break;
          default:
             assert(0);
             return;
          }
-         BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
-         OUT_RING  (chan, 0);
+         BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+         PUSH_DATA (push, 0);
 
          prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
    }
 }
 
+static void
+nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
+{
+   struct nv50_screen *screen = chan->user_priv;
+
+   nouveau_fence_update(&screen->base, TRUE);
+
+   nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, TRUE);
+}
+
 void
 nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   struct nouveau_channel *chan = nv50->screen->base.channel;
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
 
    /* For picking only a few vertices from a large user buffer, push is better,
     * if index count is larger and we expect repeated vertices, suggest upload.
@@ -656,24 +645,25 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    nv50_state_validate(nv50, ~0, 8); /* 8 as minimum, we use flush_notify */
 
-   chan->flush_notify = nv50_draw_vbo_flush_notify;
+   push->kick_notify = nv50_draw_vbo_kick_notify;
 
    if (nv50->vbo_fifo) {
       nv50_push_vbo(nv50, info);
-      chan->flush_notify = nv50_default_flush_notify;
+      push->kick_notify = nv50_default_kick_notify;
+      nouveau_pushbuf_bufctx(push, NULL);
       return;
    }
 
    if (nv50->state.instance_base != info->start_instance) {
       nv50->state.instance_base = info->start_instance;
       /* NOTE: this does not affect the shader input, should it ? */
-      BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1);
-      OUT_RING  (chan, info->start_instance);
+      BEGIN_NV04(push, NV50_3D(VB_INSTANCE_BASE), 1);
+      PUSH_DATA (push, info->start_instance);
    }
 
    if (nv50->base.vbo_dirty) {
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1);
+      PUSH_DATA (push, 0);
       nv50->base.vbo_dirty = FALSE;
    }
 
@@ -688,21 +678,21 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
       if (info->primitive_restart != nv50->state.prim_restart) {
          if (info->primitive_restart) {
-            BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2);
-            OUT_RING  (chan, 1);
-            OUT_RING  (chan, info->restart_index);
+            BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 2);
+            PUSH_DATA (push, 1);
+            PUSH_DATA (push, info->restart_index);
 
             if (info->restart_index > 65535)
                shorten = FALSE;
          } else {
-            BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 1);
-            OUT_RING  (chan, 0);
+            BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 1);
+            PUSH_DATA (push, 0);
          }
          nv50->state.prim_restart = info->primitive_restart;
       } else
       if (info->primitive_restart) {
-         BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1);
-         OUT_RING  (chan, info->restart_index);
+         BEGIN_NV04(push, NV50_3D(PRIM_RESTART_INDEX), 1);
+         PUSH_DATA (push, info->restart_index);
 
          if (info->restart_index > 65535)
             shorten = FALSE;
@@ -712,7 +702,9 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                          info->mode, info->start, info->count,
                          info->instance_count, info->index_bias);
    }
-   chan->flush_notify = nv50_default_flush_notify;
+   push->kick_notify = nv50_default_kick_notify;
 
    nv50_release_user_vbufs(nv50);
+
+   nouveau_pushbuf_bufctx(push, NULL);
 }
index 694c78a2fbda3e0f8da773857ba7ed38beecf52a..b36898dabe64dcecd2a005f51411e5f95b8dedd3 100644 (file)
 
 #include "pipe/p_defines.h"
 
-#include "nouveau/nouveau_bo.h"
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_grobj.h"
-#include "nouveau/nouveau_device.h"
-#include "nouveau/nouveau_resource.h"
-#include "nouveau/nouveau_pushbuf.h"
-#include "nouveau/nouveau_reloc.h"
-#include "nouveau/nouveau_notifier.h"
-
+#include "nouveau/nouveau_winsys.h"
 #include "nouveau/nouveau_buffer.h"
 
+
 #ifndef NV04_PFIFO_MAX_PACKET_LEN
 #define NV04_PFIFO_MAX_PACKET_LEN 2047
 #endif
 
-#define NV50_SUBCH_3D 5
-#define NV50_SUBCH_2D 6
-#define NV50_SUBCH_MF 7
 
-#define NV50_MF_(n) NV50_M2MF_##n
+static INLINE void
+nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin,
+                            unsigned flags, struct nouveau_bo *bo)
+{
+   nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL;
+}
+
+static INLINE void
+nv50_add_bufctx_resident(struct nouveau_bufctx *bufctx, int bin,
+                         struct nv04_resource *res, unsigned flags)
+{
+   struct nouveau_bufref *ref =
+      nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain);
+   ref->priv = res;
+   ref->priv_data = flags;
+}
+
+#define BCTX_REFN_bo(ctx, bin, fl, bo) \
+   nv50_add_bufctx_resident_bo(ctx, NV50_BIND_##bin, fl, bo);
+
+#define BCTX_REFN(bctx, bin, res, acc) \
+   nv50_add_bufctx_resident(bctx, NV50_BIND_##bin, res, NOUVEAU_BO_##acc)
+
+static INLINE void
+PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
+{
+   struct nouveau_pushbuf_refn ref = { bo, flags };
+   nouveau_pushbuf_refn(push, &ref, 1);
+}
+
+
+#define SUBC_3D(m) 3, (m)
+#define NV50_3D(n) SUBC_3D(NV50_3D_##n)
 
-#define RING_3D(n) ((NV50_SUBCH_3D << 13) | NV50_3D_##n)
-#define RING_2D(n) ((NV50_SUBCH_2D << 13) | NV50_2D_##n)
-#define RING_MF(n) ((NV50_SUBCH_MF << 13) | NV50_MF_(n))
+#define SUBC_2D(m) 4, (m)
+#define NV50_2D(n) SUBC_2D(NV50_2D_##n)
 
-#define RING_3D_(m) ((NV50_SUBCH_3D << 13) | (m))
-#define RING_2D_(m) ((NV50_SUBCH_2D << 13) | (m))
-#define RING_MF_(m) ((NV50_SUBCH_MF << 13) | (m))
+#define SUBC_M2MF(m) 5, (m)
+#define NV50_M2MF(n) SUBC_M2MF(NV50_M2MF_##n)
 
-#define RING_GR(gr, m) (((gr)->subc << 13) | (m))
+#define SUBC_COMPUTE(m) 6, (m)
+#define NV50_COMPUTE(n) SUBC_COMPUTE(NV50_COMPUTE_##n)
 
-int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
 
-static inline uint32_t
-nouveau_bo_tile_layout(const struct nouveau_bo *bo)
+static INLINE uint32_t
+NV50_FIFO_PKHDR(int subc, int mthd, unsigned size)
 {
-   return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
+   return 0x00000000 | (size << 18) | (subc << 13) | mthd;
 }
 
-static INLINE void
-nouveau_bo_validate(struct nouveau_channel *chan,
-                    struct nouveau_bo *bo, unsigned flags)
+static INLINE uint32_t
+NV50_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
 {
-   nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
+   return 0x40000000 | (size << 18) | (subc << 13) | mthd;
 }
 
-/* incremental methods */
-static INLINE void
-BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+static INLINE uint32_t
+NV50_FIFO_PKHDR_L(int subc, int mthd)
 {
-   WAIT_RING(chan, size + 1);
-   OUT_RING (chan, (size << 18) | mthd);
+   return 0x00030000 | (subc << 13) | mthd;
 }
 
-/* non-incremental */
-static INLINE void
-BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+
+static INLINE uint32_t
+nouveau_bo_memtype(const struct nouveau_bo *bo)
 {
-   WAIT_RING(chan, size + 1);
-   OUT_RING (chan, (0x2 << 29) | (size << 18) | mthd);
+   return bo->config.nv50.memtype;
 }
 
-static INLINE int
-OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
-           unsigned delta, unsigned flags)
+
+static INLINE void
+PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data)
 {
-   return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
+   *push->cur++ = (uint32_t)(data >> 32);
 }
 
-static INLINE int
-OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
-           unsigned delta, unsigned flags)
+static INLINE void
+BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
 {
-   if (flags & NOUVEAU_BO_WR)
-      res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
-   return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
+#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, size + 1);
+#endif
+   PUSH_DATA (push, NV50_FIFO_PKHDR(subc, mthd, size));
 }
 
 static INLINE void
-BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
+BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
 {
-   struct nouveau_subchannel *subc = &gr->channel->subc[s];
-
-   assert(s < 8);
-   if (subc->gr) {
-      assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT);
-      subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
-   }
-   subc->gr = gr;
-   subc->gr->subc = s;
-   subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
-
-   BEGIN_RING(chan, RING_GR(gr, 0x0000), 1);
-   OUT_RING  (chan, gr->handle);
+#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, size + 1);
+#endif
+   PUSH_DATA (push, NV50_FIFO_PKHDR_NI(subc, mthd, size));
 }
 
+/* long, non-incremental, nv50-only */
+static INLINE void
+BEGIN_NL50(struct nouveau_pushbuf *push, int subc, int mthd, uint32_t size)
+{
+#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, 2);
 #endif
+   PUSH_DATA (push, NV50_FIFO_PKHDR_L(subc, mthd));
+   PUSH_DATA (push, size);
+}
+
+#endif /* __NV50_WINSYS_H__ */
index 6a1dff70f760c9bd2373f913101a7cb476f4260c..18d27865d716a08e6d37ad8ad087a0d97b207b53 100644 (file)
@@ -153,13 +153,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NVC0_3D_LOCAL_BASE                                     0x0000077c
 
-#define NVC0_3D_LOCAL_ADDRESS_HIGH                             0x00000790
+#define NVC0_3D_TEMP_ADDRESS_HIGH                              0x00000790
 
-#define NVC0_3D_LOCAL_ADDRESS_LOW                              0x00000794
+#define NVC0_3D_TEMP_ADDRESS_LOW                               0x00000794
 
-#define NVC0_3D_LOCAL_SIZE_HIGH                                        0x00000798
+#define NVC0_3D_TEMP_SIZE_HIGH                                 0x00000798
 
-#define NVC0_3D_LOCAL_SIZE_LOW                                 0x0000079c
+#define NVC0_3D_TEMP_SIZE_LOW                                  0x0000079c
+
+#define NVC0_3D_WARP_TEMP_ALLOC                                        0x000007a0
+
+#define NVC0_3D_ZCULL_WIDTH                                    0x000007c0
+
+#define NVC0_3D_ZCULL_HEIGHT                                   0x000007c4
+
+#define NVC0_3D_ZCULL_ADDRESS_HIGH                             0x000007e8
+
+#define NVC0_3D_ZCULL_ADDRESS_LOW                              0x000007ec
+
+#define NVC0_3D_ZCULL_LIMIT_HIGH                               0x000007f0
+
+#define NVC0_3D_ZCULL_LIMIT_LOW                                        0x000007f4
 
 #define NVC0_3D_RT(i0)                                        (0x00000800 + 0x40*(i0))
 #define NVC0_3D_RT__ESIZE                                      0x00000040
@@ -772,6 +786,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NVC0_3D_TIC_LIMIT                                      0x0000157c
 
+#define NVC0_3D_ZCULL_REGION                                   0x00001590
+
 #define NVC0_3D_STENCIL_TWO_SIDE_ENABLE                                0x00001594
 
 #define NVC0_3D_STENCIL_BACK_OP_FAIL                           0x00001598
@@ -856,7 +872,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVC0_3D_VERTEX_END_D3D_UNK0                            0x00000001
 #define NVC0_3D_VERTEX_END_D3D_UNK1                            0x00000002
 
-#define NVC0_3D_EDGEFLAG_ENABLE                                        0x000015e4
+#define NVC0_3D_EDGEFLAG                                       0x000015e4
 
 #define NVC0_3D_VB_ELEMENT_U32                                 0x000015e8
 
@@ -876,6 +892,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NVC0_3D_VERTEX_BASE_LOW                                        0x000015f8
 
+#define NVC0_3D_ZCULL_WINDOW_OFFSET_X                          0x000015fc
+
+#define NVC0_3D_ZCULL_WINDOW_OFFSET_Y                          0x00001600
+
 #define NVC0_3D_POINT_COORD_REPLACE                            0x00001604
 #define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__MASK         0x00000004
 #define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__SHIFT                2
@@ -1070,6 +1090,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVC0_3D_CLIP_RECTS_MODE_OUTSIDE_ALL                    0x00000001
 #define NVC0_3D_CLIP_RECTS_MODE_NEVER                          0x00000002
 
+#define NVC0_3D_ZCULL_INVALIDATE                               0x00001958
+
+#define NVC0_3D_ZCULL_TEST_MASK                                        0x0000196c
+#define NVC0_3D_ZCULL_TEST_MASK_FAIL_GT_PASS_LT                        0x00000001
+#define NVC0_3D_ZCULL_TEST_MASK_PASS_GT_FAIL_LT                        0x00000010
+
 #define NVC0_3D_FP_ZORDER_CTRL                                 0x0000196c
 #define NVC0_3D_FP_ZORDER_CTRL_0                               0x00000001
 #define NVC0_3D_FP_ZORDER_CTRL_1                               0x00000010
@@ -1082,11 +1108,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define NVC0_3D_CLIPID_ID                                      0x00001984
 
-#define NVC0_3D_FP_CONTROL                                     0x000019a8
-#define NVC0_3D_FP_CONTROL_MULTIPLE_RESULTS                    0x00000001
-#define NVC0_3D_FP_CONTROL_EXPORTS_Z                           0x00000100
-#define NVC0_3D_FP_CONTROL_USES_KIL                            0x00100000
-
 #define NVC0_3D_DEPTH_BOUNDS_EN                                        0x000019bc
 
 #define NVC0_3D_LOGIC_OP_ENABLE                                        0x000019c4
index 1b3a06dfa333ab3b508ea505a51e066f3269e33b..c15d0256c60ba2e7bdbd986c2ddaa3d9f7fe4258 100644 (file)
@@ -33,26 +33,22 @@ static void
 nvc0_flush(struct pipe_context *pipe,
            struct pipe_fence_handle **fence)
 {
-   struct nouveau_screen *screen = &nvc0_context(pipe)->screen->base;
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
+   struct nouveau_screen *screen = &nvc0->screen->base;
 
    if (fence)
       nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
 
-   /* Try to emit before firing to avoid having to flush again right after
-    * in case we have to wait on this fence.
-    */
-   nouveau_fence_emit(screen->fence.current);
-
-   FIRE_RING(screen->channel);
+   PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
 }
 
 static void
 nvc0_texture_barrier(struct pipe_context *pipe)
 {
-   struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf;
 
-   IMMED_RING(chan, RING_3D(SERIALIZE), 0);
-   IMMED_RING(chan, RING_3D(TEX_CACHE_CTL), 0);
+   IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+   IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0);
 }
 
 static void
@@ -60,8 +56,8 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0)
 {
    unsigned s, i;
 
-   for (i = 0; i < NVC0_BUFCTX_COUNT; ++i)
-      nvc0_bufctx_reset(nvc0, i);
+   nouveau_bufctx_del(&nvc0->bufctx_3d);
+   nouveau_bufctx_del(&nvc0->bufctx);
 
    for (i = 0; i < nvc0->num_vtxbufs; ++i)
       pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
@@ -85,26 +81,31 @@ nvc0_destroy(struct pipe_context *pipe)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
 
+   if (nvc0->screen->cur_ctx == nvc0) {
+      nvc0->base.pushbuf->kick_notify = NULL;
+      nvc0->screen->cur_ctx = NULL;
+      nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
+   }
+   nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);
+
    nvc0_context_unreference_resources(nvc0);
 
    draw_destroy(nvc0->draw);
 
-   if (nvc0->screen->cur_ctx == nvc0)
-      nvc0->screen->cur_ctx = NULL;
-
    FREE(nvc0);
 }
 
 void
-nvc0_default_flush_notify(struct nouveau_channel *chan)
+nvc0_default_kick_notify(struct nouveau_pushbuf *push)
 {
-   struct nvc0_screen *screen = chan->user_private;
-
-   if (!screen)
-      return;
+   struct nvc0_screen *screen = push->user_priv;
 
-   nouveau_fence_update(&screen->base, TRUE);
-   nouveau_fence_next(&screen->base);
+   if (screen) {
+      nouveau_fence_next(&screen->base);
+      nouveau_fence_update(&screen->base, TRUE);
+      if (screen->cur_ctx)
+         screen->cur_ctx->state.flushed = TRUE;
+   }
 }
 
 struct pipe_context *
@@ -113,12 +114,23 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
    struct nvc0_screen *screen = nvc0_screen(pscreen);
    struct nvc0_context *nvc0;
    struct pipe_context *pipe;
+   int ret;
+   uint32_t flags;
 
    nvc0 = CALLOC_STRUCT(nvc0_context);
    if (!nvc0)
       return NULL;
    pipe = &nvc0->base.pipe;
 
+   nvc0->base.pushbuf = screen->base.pushbuf;
+
+   ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT,
+                            &nvc0->bufctx_3d);
+   if (!ret)
+      nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
+   if (ret)
+      goto out_err;
+
    nvc0->screen = screen;
    nvc0->base.screen    = &screen->base;
    nvc0->base.copy_data = nvc0_m2mf_copy_linear;
@@ -136,9 +148,11 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
    pipe->flush = nvc0_flush;
    pipe->texture_barrier = nvc0_texture_barrier;
 
-   if (!screen->cur_ctx)
+   if (!screen->cur_ctx) {
       screen->cur_ctx = nvc0;
-   screen->base.channel->flush_notify = nvc0_default_flush_notify;
+      nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
+   }
+   screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;
 
    nvc0_init_query_functions(nvc0);
    nvc0_init_surface_functions(nvc0);
@@ -154,72 +168,43 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
    /* shader builtin library is per-screen, but we need a context for m2mf */
    nvc0_program_library_upload(nvc0);
 
-   return pipe;
-}
+   /* add permanently resident buffers to bufctxts */
 
-struct resident {
-   struct nv04_resource *res;
-   uint32_t flags;
-};
+   flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
 
-void
-nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx,
-                         struct nv04_resource *resource, uint32_t flags)
-{
-   struct resident rsd = { resource, flags };
+   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
+   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniforms);
+   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);
 
-   if (!resource->bo)
-      return;
-   nvc0->residents_size += sizeof(struct resident);
+   flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
 
-   /* We don't need to reference the resource here, it will be referenced
-    * in the context/state, and bufctx will be reset when state changes.
-    */
-   util_dynarray_append(&nvc0->residents[ctx], struct resident, rsd);
-}
+   BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
+   BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);
 
-void
-nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx,
-                         struct nv04_resource *resource)
-{
-   struct resident *rsd, *top;
-   unsigned i;
-
-   for (i = 0; i < nvc0->residents[ctx].size / sizeof(struct resident); ++i) {
-      rsd = util_dynarray_element(&nvc0->residents[ctx], struct resident, i);
-
-      if (rsd->res == resource) {
-         top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident);
-         if (rsd != top)
-            *rsd = *top;
-         nvc0->residents_size -= sizeof(struct resident);
-         break;
-      }
+   return pipe;
+
+out_err:
+   if (nvc0) {
+      if (nvc0->bufctx_3d)
+         nouveau_bufctx_del(&nvc0->bufctx_3d);
+      if (nvc0->bufctx)
+         nouveau_bufctx_del(&nvc0->bufctx);
+      FREE(nvc0);
    }
+   return NULL;
 }
 
 void
-nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0)
+nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
+                  boolean on_flush)
 {
-   struct resident *rsd;
-   struct util_dynarray *array;
-   unsigned ctx, i, n;
-
-   n  = nvc0->residents_size / sizeof(struct resident);
-   n += NVC0_SCREEN_RESIDENT_BO_COUNT;
-
-   MARK_RING(nvc0->screen->base.channel, 0, n);
-
-   for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) {
-      array = &nvc0->residents[ctx];
-
-      n = array->size / sizeof(struct resident);
-      for (i = 0; i < n; ++i) {
-         rsd = util_dynarray_element(array, struct resident, i);
-
-         nvc0_resource_validate(rsd->res, rsd->flags);
-      }
+   struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
+   struct nouveau_list *it;
+
+   for (it = list->next; it != list; it = it->next) {
+      struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
+      struct nv04_resource *res = ref->priv;
+      if (res)
+         nvc0_resource_validate(res, (unsigned)ref->priv_data);
    }
-
-   nvc0_screen_make_buffers_resident(nvc0->screen);
 }
index b8f0d92b6b4244da51bc6c01025a02ceaeb6eaf7..4b35330ef8adaf069a9afc82547d046c52a560d0 100644 (file)
 #define NVC0_NEW_TEXTURES     (1 << 19)
 #define NVC0_NEW_SAMPLERS     (1 << 20)
 #define NVC0_NEW_TFB_TARGETS  (1 << 21)
-
-#define NVC0_BUFCTX_CONSTANT 0
-#define NVC0_BUFCTX_FRAME    1
-#define NVC0_BUFCTX_VERTEX   2
-#define NVC0_BUFCTX_TEXTURES 3
-#define NVC0_BUFCTX_TFB      4
-#define NVC0_BUFCTX_COUNT    5
+#define NVC0_NEW_IDXBUF       (1 << 22)
+
+#define NVC0_BIND_FB          0
+#define NVC0_BIND_VTX         1
+#define NVC0_BIND_IDX         2
+#define NVC0_BIND_TEX         3
+#define NVC0_BIND_CB(s, i)   (4 + 16 * (s) + (i))
+#define NVC0_BIND_TFB         84
+#define NVC0_BIND_SCREEN      85
+#define NVC0_BIND_TLS         86
+#define NVC0_BIND_COUNT       87
+#define NVC0_BIND_2D          0
+#define NVC0_BIND_M2MF        0
+#define NVC0_BIND_FENCE       1
 
 struct nvc0_context {
    struct nouveau_context base;
 
-   struct nvc0_screen *screen;
+   struct nouveau_bufctx *bufctx_3d;
+   struct nouveau_bufctx *bufctx;
 
-   struct util_dynarray residents[NVC0_BUFCTX_COUNT];
-   unsigned residents_size;
+   struct nvc0_screen *screen;
 
    uint32_t dirty;
 
    struct {
+      boolean flushed;
+      boolean rasterizer_discard;
+      boolean early_z;
+      boolean prim_restart;
       uint32_t instance_elts; /* bitmask of per-instance elements */
       uint32_t instance_base;
       int32_t index_bias;
-      boolean prim_restart;
-      boolean early_z;
       uint16_t scissor;
-      boolean rasterizer_discard;
       uint8_t num_vtxbufs;
       uint8_t num_vtxelts;
       uint8_t num_textures[5];
@@ -142,20 +150,9 @@ nvc0_context(struct pipe_context *pipe)
 
 /* nvc0_context.c */
 struct pipe_context *nvc0_create(struct pipe_screen *, void *);
-
-void nvc0_default_flush_notify(struct nouveau_channel *);
-
-void nvc0_bufctx_emit_relocs(struct nvc0_context *);
-void nvc0_bufctx_add_resident(struct nvc0_context *, int ctx,
-                              struct nv04_resource *, uint32_t flags);
-void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx,
-                              struct nv04_resource *);
-static INLINE void
-nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx)
-{
-   nvc0->residents_size -= nvc0->residents[ctx].size;
-   util_dynarray_resize(&nvc0->residents[ctx], 0);
-}
+void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
+                       boolean on_flush);
+void nvc0_default_kick_notify(struct nouveau_pushbuf *);
 
 /* nvc0_draw.c */
 extern struct draw_stage *nvc0_draw_render_stage(struct nvc0_context *);
@@ -168,9 +165,9 @@ void nvc0_program_library_upload(struct nvc0_context *);
 
 /* nvc0_query.c */
 void nvc0_init_query_functions(struct nvc0_context *);
-void nvc0_query_pushbuf_submit(struct nouveau_channel *,
+void nvc0_query_pushbuf_submit(struct nouveau_pushbuf *,
                                struct pipe_query *, unsigned result_offset);
-void nvc0_query_fifo_wait(struct nouveau_channel *, struct pipe_query *);
+void nvc0_query_fifo_wait(struct nouveau_pushbuf *, struct pipe_query *);
 void nvc0_so_target_save_offset(struct pipe_context *,
                                 struct pipe_stream_output_target *, unsigned i,
                                 boolean *serialize);
@@ -210,7 +207,7 @@ nvc0_create_sampler_view(struct pipe_context *,
 
 /* nvc0_transfer.c */
 void
-nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nvc0_m2mf_transfer_rect(struct nvc0_context *,
                         const struct nv50_m2mf_rect *dst,
                         const struct nv50_m2mf_rect *src,
                         uint32_t nblocksx, uint32_t nblocksy);
@@ -241,8 +238,9 @@ nvc0_vertex_state_delete(struct pipe_context *pipe, void *hwcso);
 
 void nvc0_vertex_arrays_validate(struct nvc0_context *nvc0);
 
+void nvc0_idxbuf_validate(struct nvc0_context *);
+
 /* nvc0_push.c */
 void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *);
-void nvc0_push_vbo2(struct nvc0_context *, const struct pipe_draw_info *);
 
 #endif
index b180fc8db37351a0660c6fce96963f044036e0bb..591ac4402db92f0c9de4922afc52bf95ee70fa5b 100644 (file)
@@ -65,80 +65,82 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
 
    compressed = FALSE; /* not yet supported */
 
-   if (mt->base.base.bind & PIPE_BIND_CURSOR)
-      return NOUVEAU_BO_TILE_SCANOUT;
+   if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
+      return 0;
+   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
+      return 0;
 
    switch (mt->base.base.format) {
    case PIPE_FORMAT_Z16_UNORM:
       if (compressed)
-         tile_flags = 0x0200 + (ms << 8);
+         tile_flags = 0x02 + ms;
       else
-         tile_flags = 0x0100;
+         tile_flags = 0x01;
       break;
    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
       if (compressed)
-         tile_flags = 0x5100 + (ms << 8);
+         tile_flags = 0x51 + ms;
       else
-         tile_flags = 0x4600;
+         tile_flags = 0x46;
       break;
    case PIPE_FORMAT_Z24X8_UNORM:
    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
       if (compressed)
-         tile_flags = 0x1700 + (ms << 8);
+         tile_flags = 0x17 + ms;
       else
-         tile_flags = 0x1100;
+         tile_flags = 0x11;
       break;
    case PIPE_FORMAT_Z32_FLOAT:
       if (compressed)
-         tile_flags = 0x8600 + (ms << 8);
+         tile_flags = 0x86 + ms;
       else
-         tile_flags = 0x7b00;
+         tile_flags = 0x7b;
       break;
    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
       if (compressed)
-         tile_flags = 0xce00 + (ms << 8);
+         tile_flags = 0xce + ms;
       else
-         tile_flags = 0xc300;
+         tile_flags = 0xc3;
       break;
    default:
       switch (util_format_get_blocksizebits(mt->base.base.format)) {
       case 128:
          if (compressed)
-            tile_flags = 0xf400 + (ms << 9);
+            tile_flags = 0xf4 + ms;
          else
-            tile_flags = 0xfe00;
+            tile_flags = 0xfe;
          break;
       case 64:
          if (compressed) {
             switch (ms) {
-            case 0: tile_flags = 0xe600; break;
-            case 1: tile_flags = 0xeb00; break;
-            case 2: tile_flags = 0xed00; break;
-            case 3: tile_flags = 0xf200; break;
+            case 0: tile_flags = 0xe6; break;
+            case 1: tile_flags = 0xeb; break;
+            case 2: tile_flags = 0xed; break;
+            case 3: tile_flags = 0xf2; break;
             default:
                return 0;
             }
          } else {
-            tile_flags = 0xfe00;
+            tile_flags = 0xfe;
          }
          break;
       case 32:
          if (compressed) {
             switch (ms) {
-            case 0: tile_flags = 0xdb00; break;
-            case 1: tile_flags = 0xdd00; break;
-            case 2: tile_flags = 0xdf00; break;
-            case 3: tile_flags = 0xe400; break;
+            case 0: tile_flags = 0xdb; break;
+            case 1: tile_flags = 0xdd; break;
+            case 2: tile_flags = 0xdf; break;
+            case 3: tile_flags = 0xe4; break;
             default:
                return 0;
             }
          } else {
-            tile_flags = 0xfe00;
+            tile_flags = 0xfe;
          }
          break;
       case 16:
       case 8:
-         tile_flags = 0xfe00;
+         tile_flags = 0xfe;
          break;
       default:
          return 0;
@@ -146,12 +148,6 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
       break;
    }
 
-   if (mt->base.base.bind & PIPE_BIND_SCANOUT)
-      tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
-
-   if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
-      tile_flags &= ~0xff00;
-
    return tile_flags;
 }
 
@@ -279,7 +275,8 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
    struct pipe_resource *pt = &mt->base.base;
    int ret;
-   uint32_t tile_flags;
+   union nouveau_bo_config bo_config;
+   uint32_t bo_flags;
 
    if (!mt)
       return NULL;
@@ -289,7 +286,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    pipe_reference_init(&pt->reference, 1);
    pt->screen = pscreen;
 
-   tile_flags = nvc0_mt_choose_storage_type(mt, TRUE);
+   bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(mt, TRUE);
 
    if (!nvc0_miptree_init_ms_mode(mt)) {
       FREE(mt);
@@ -299,23 +296,29 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    if (unlikely(pt->flags & NVC0_RESOURCE_FLAG_VIDEO)) {
       nvc0_miptree_init_layout_video(mt);
    } else
-   if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+   if (likely(bo_config.nvc0.memtype)) {
       nvc0_miptree_init_layout_tiled(mt);
    } else
    if (!nv50_miptree_init_layout_linear(mt)) {
       FREE(mt);
       return NULL;
    }
+   bo_config.nvc0.tile_mode = mt->level[0].tile_mode;
 
-   ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
-                             mt->total_size,
-                             mt->level[0].tile_mode, tile_flags,
-                             &mt->base.bo);
+   mt->base.domain = NOUVEAU_BO_VRAM;
+
+   bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP;
+
+   if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
+      bo_flags |= NOUVEAU_BO_CONTIG;
+
+   ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config,
+                        &mt->base.bo);
    if (ret) {
       FREE(mt);
       return NULL;
    }
-   mt->base.domain = NOUVEAU_BO_VRAM;
+   mt->base.address = mt->base.bo->offset;
 
    return pt;
 }
index 44c7a65e3c99e6d201b7199ecec6a0ba46b58de8..b403e2ee9f24801f2a34989e02f878938eec492d 100644 (file)
@@ -618,7 +618,17 @@ nvc0_program_translate(struct nvc0_program *prog)
       assert(info->bin.tlsSpace < (1 << 24));
       prog->hdr[0] |= 1 << 26;
       prog->hdr[1] |= info->bin.tlsSpace; /* l[] size */
+      prog->need_tls = TRUE;
    }
+   /* TODO: factor 2 only needed where joinat/precont is used,
+    *       and we only have to count non-uniform branches
+    */
+   /*
+   if ((info->maxCFDepth * 2) > 16) {
+      prog->hdr[2] |= (((info->maxCFDepth * 2) + 47) / 48) * 0x200;
+      prog->need_tls = TRUE;
+   }
+   */
    if (info->io.globalAccess)
       prog->hdr[0] |= 1 << 16;
 
@@ -649,15 +659,15 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
    }
    size = align(size, 0x40); /* required by SP_START_ID */
 
-   ret = nouveau_resource_alloc(screen->text_heap, size, prog, &prog->res);
+   ret = nouveau_heap_alloc(screen->text_heap, size, prog, &prog->mem);
    if (ret) {
       NOUVEAU_ERR("out of code space\n");
       return FALSE;
    }
-   prog->code_base = prog->res->start;
-   prog->immd_base = align(prog->res->start + prog->immd_base, 0x100);
+   prog->code_base = prog->mem->start;
+   prog->immd_base = align(prog->mem->start + prog->immd_base, 0x100);
    assert((prog->immd_size == 0) || (prog->immd_base + prog->immd_size <=
-                                     prog->res->start + prog->res->size));
+                                     prog->mem->start + prog->mem->size));
 
    code_pos = prog->code_base + NVC0_SHADER_HEADER_SIZE;
 
@@ -679,8 +689,8 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
                             screen->text, prog->immd_base, NOUVEAU_BO_VRAM,
                             prog->immd_size, prog->immd_data);
 
-   BEGIN_RING(screen->base.channel, RING_3D(MEM_BARRIER), 1);
-   OUT_RING  (screen->base.channel, 0x1111);
+   BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(MEM_BARRIER), 1);
+   PUSH_DATA (nvc0->base.pushbuf, 0x1111);
 
    return TRUE;
 }
@@ -701,8 +711,8 @@ nvc0_program_library_upload(struct nvc0_context *nvc0)
    if (!size)
       return;
 
-   ret = nouveau_resource_alloc(screen->text_heap, align(size, 0x100), NULL,
-                                &screen->lib_code);
+   ret = nouveau_heap_alloc(screen->text_heap, align(size, 0x100), NULL,
+                            &screen->lib_code);
    if (ret)
       return;
 
@@ -718,8 +728,8 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog)
    const struct pipe_shader_state pipe = prog->pipe;
    const ubyte type = prog->type;
 
-   if (prog->res)
-      nouveau_resource_free(&prog->res);
+   if (prog->mem)
+      nouveau_heap_free(&prog->mem);
 
    if (prog->code)
       FREE(prog->code);
index c90f364ab9f4ff266711545bfccf8c076d148de1..f6d1121c6dd2d9cad99297b9fc74ba5d0a0a4fc5 100644 (file)
@@ -21,6 +21,7 @@ struct nvc0_program {
 
    ubyte type;
    boolean translated;
+   boolean need_tls;
    uint8_t max_gpr;
 
    uint32_t *code;
@@ -54,7 +55,7 @@ struct nvc0_program {
 
    struct nvc0_transform_feedback_state *tfb;
 
-   struct nouveau_resource *res;
+   struct nouveau_heap *mem;
 };
 
 #endif
index cea58b447a28996880b45305eb884c535c4347be..78cc5c206416ff4530e6807746441f47749d0f51 100644 (file)
@@ -11,7 +11,7 @@
 #include "nvc0_3d.xml.h"
 
 struct push_context {
-   struct nouveau_channel *chan;
+   struct nouveau_pushbuf *push;
 
    void *idxbuf;
 
@@ -40,7 +40,7 @@ init_push_context(struct nvc0_context *nvc0, struct push_context *ctx)
 {
    struct pipe_vertex_element *ve;
 
-   ctx->chan = nvc0->screen->base.channel;
+   ctx->push = nvc0->base.pushbuf;
    ctx->translate = nvc0->vertex->translate;
 
    if (likely(nvc0->vertex->num_elements < 32))
@@ -72,7 +72,7 @@ set_edgeflag(struct push_context *ctx, unsigned vtx_id)
 
    if (ctx->edgeflag.value != f) {
       ctx->edgeflag.value = f;
-      IMMED_RING(ctx->chan, RING_3D(EDGEFLAG_ENABLE), f ? 1 : 0);
+      IMMED_NVC0(ctx->push, NVC0_3D(EDGEFLAG), f ? 1 : 0);
    }
 }
 
@@ -80,11 +80,11 @@ static INLINE void
 set_vertexid(struct push_context *ctx, uint32_t vtx_id)
 {
 #if 0
-   BEGIN_RING(ctx->chan, RING_3D(VERTEX_ID), 1); /* broken on nvc0 */
+   BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_ID), 1); /* broken on nvc0 */
 #else
-   BEGIN_RING(ctx->chan, RING_3D(VERTEX_DATA), 1); /* as last attribute */
+   BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_DATA), 1); /* as last attribute */
 #endif
-   OUT_RING  (ctx->chan, vtx_id);
+   PUSH_DATA (ctx->push, vtx_id);
 }
 
 static INLINE unsigned
@@ -135,11 +135,11 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
 
       size = ctx->vertex_words * nr;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
 
       ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
-                                ctx->chan->cur);
-      ctx->chan->cur += size;
+                                ctx->push->cur);
+      ctx->push->cur += size;
 
       if (unlikely(ctx->need_vertex_id) && likely(size))
          set_vertexid(ctx, elts[0]);
@@ -150,9 +150,9 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
       if (nr != push) {
          count--;
          elts++;
-         BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
-         OUT_RING  (ctx->chan, 0);
-         OUT_RING  (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+         BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
+         PUSH_DATA (ctx->push, 0);
+         PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
                     (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
       }
    }
@@ -176,11 +176,11 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
 
       size = ctx->vertex_words * nr;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
 
       ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
-                                 ctx->chan->cur);
-      ctx->chan->cur += size;
+                                 ctx->push->cur);
+      ctx->push->cur += size;
 
       if (unlikely(ctx->need_vertex_id))
          set_vertexid(ctx, elts[0]);
@@ -191,9 +191,9 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
       if (nr != push) {
          count--;
          elts++;
-         BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
-         OUT_RING  (ctx->chan, 0);
-         OUT_RING  (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+         BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
+         PUSH_DATA (ctx->push, 0);
+         PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
                     (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
       }
    }
@@ -217,11 +217,11 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
 
       size = ctx->vertex_words * nr;
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
 
       ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
-                               ctx->chan->cur);
-      ctx->chan->cur += size;
+                               ctx->push->cur);
+      ctx->push->cur += size;
 
       if (unlikely(ctx->need_vertex_id))
          set_vertexid(ctx, elts[0]);
@@ -232,9 +232,9 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
       if (nr != push) {
          count--;
          elts++;
-         BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
-         OUT_RING  (ctx->chan, 0);
-         OUT_RING  (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+         BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
+         PUSH_DATA (ctx->push, 0);
+         PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
                     (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
       }
    }
@@ -250,11 +250,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
       if (unlikely(ctx->edgeflag.buffer >= 0))
          set_edgeflag(ctx, start);
 
-      BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+      BEGIN_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
 
       ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
-                          ctx->chan->cur);
-      ctx->chan->cur += size;
+                          ctx->push->cur);
+      ctx->push->cur += size;
 
       if (unlikely(ctx->need_vertex_id))
          set_vertexid(ctx, start);
@@ -354,17 +354,17 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
 
    if (unlikely(ctx.need_vertex_id)) {
       const unsigned a = nvc0->vertex->num_elements;
-      BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
-      OUT_RING  (ctx.chan, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
+      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
+      PUSH_DATA (ctx.push, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
                  NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
                  NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
-      BEGIN_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 1);
-      OUT_RING  (ctx.chan, (((0x80 + a * 0x10) / 4) << 4) | 1);
+      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 1);
+      PUSH_DATA (ctx.push, (((0x80 + a * 0x10) / 4) << 4) | 1);
    }
 
    while (inst_count--) {
-      BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
-      OUT_RING  (ctx.chan, ctx.prim);
+      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+      PUSH_DATA (ctx.push, ctx.prim);
       switch (index_size) {
       case 0:
          emit_vertices_seq(&ctx, info->start, vert_count);
@@ -382,20 +382,20 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
          assert(0);
          break;
       }
-      IMMED_RING(ctx.chan, RING_3D(VERTEX_END_GL), 0);
+      IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_END_GL), 0);
 
       ctx.instance_id++;
       ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
 
    if (unlikely(ctx.edgeflag.value == 0.0f))
-      IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1);
+      IMMED_NVC0(ctx.push, NVC0_3D(EDGEFLAG), 1);
 
    if (unlikely(ctx.need_vertex_id)) {
       const unsigned a = nvc0->vertex->num_elements;
-      IMMED_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 0);
-      BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
-      OUT_RING  (ctx.chan,
+      IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 0);
+      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
+      PUSH_DATA (ctx.push,
                  NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST |
                  NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
                  NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
index 699d582fe3d1ec5486cf7b9d9c1a88344d6a5032..b0ef83a1df20734ebca7c3d9671b49ca841e09db 100644 (file)
@@ -22,6 +22,8 @@
  * Authors: Christoph Bumiller
  */
 
+#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+
 #include "nvc0_context.h"
 #include "nouveau/nv_object.xml.h"
 
@@ -71,14 +73,12 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size)
          return FALSE;
       q->offset = q->base;
 
-      ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD |
-                                 NOUVEAU_BO_NOSYNC);
+      ret = nouveau_bo_map(q->bo, 0, screen->base.client);
       if (ret) {
          nvc0_query_allocate(nvc0, q, 0);
          return FALSE;
       }
-      q->data = q->bo->map;
-      nouveau_bo_unmap(q->bo);
+      q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base);
    }
    return TRUE;
 }
@@ -150,17 +150,18 @@ nvc0_query_create(struct pipe_context *pipe, unsigned type)
 }
 
 static void
-nvc0_query_get(struct nouveau_channel *chan, struct nvc0_query *q,
+nvc0_query_get(struct nouveau_pushbuf *push, struct nvc0_query *q,
                unsigned offset, uint32_t get)
 {
    offset += q->offset;
 
-   MARK_RING (chan, 5, 2);
-   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
-   OUT_RING  (chan, q->sequence);
-   OUT_RING  (chan, get);
+   PUSH_SPACE(push, 5);
+   PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+   BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4);
+   PUSH_DATAh(push, q->bo->offset + offset);
+   PUSH_DATA (push, q->bo->offset + offset);
+   PUSH_DATA (push, q->sequence);
+   PUSH_DATA (push, get);
 }
 
 static void
@@ -176,7 +177,7 @@ static void
 nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_query *q = nvc0_query(pq);
 
    /* For occlusion queries we have to change the storage, because a previous
@@ -201,41 +202,42 @@ nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
    case PIPE_QUERY_OCCLUSION_PREDICATE:
       q->nesting = nvc0->screen->num_occlusion_queries_active++;
       if (q->nesting) {
-         nvc0_query_get(chan, q, 0x10, 0x0100f002);
+         nvc0_query_get(push, q, 0x10, 0x0100f002);
       } else {
-         BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
-         OUT_RING  (chan, NVC0_3D_COUNTER_RESET_SAMPLECNT);
-         IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
+         PUSH_SPACE(push, 3);
+         BEGIN_NVC0(push, NVC0_3D(COUNTER_RESET), 1);
+         PUSH_DATA (push, NVC0_3D_COUNTER_RESET_SAMPLECNT);
+         IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1);
       }
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
-      nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5));
       break;
    case PIPE_QUERY_PRIMITIVES_EMITTED:
-      nvc0_query_get(chan, q, 0x10, 0x05805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x10, 0x05805002 | (q->index << 5));
       break;
    case PIPE_QUERY_SO_STATISTICS:
-      nvc0_query_get(chan, q, 0x20, 0x05805002 | (q->index << 5));
-      nvc0_query_get(chan, q, 0x30, 0x06805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x20, 0x05805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x30, 0x06805002 | (q->index << 5));
       break;
    case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
-      nvc0_query_get(chan, q, 0x10, 0x03005002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x10, 0x03005002 | (q->index << 5));
       break;
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
    case PIPE_QUERY_TIME_ELAPSED:
-      nvc0_query_get(chan, q, 0x10, 0x00005002);
+      nvc0_query_get(push, q, 0x10, 0x00005002);
       break;
    case PIPE_QUERY_PIPELINE_STATISTICS:
-      nvc0_query_get(chan, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */
-      nvc0_query_get(chan, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */
-      nvc0_query_get(chan, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */
-      nvc0_query_get(chan, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */
-      nvc0_query_get(chan, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */
-      nvc0_query_get(chan, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */
-      nvc0_query_get(chan, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */
-      nvc0_query_get(chan, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */
-      nvc0_query_get(chan, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */
-      nvc0_query_get(chan, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
+      nvc0_query_get(push, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */
+      nvc0_query_get(push, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */
+      nvc0_query_get(push, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */
+      nvc0_query_get(push, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */
+      nvc0_query_get(push, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */
+      nvc0_query_get(push, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */
+      nvc0_query_get(push, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */
+      nvc0_query_get(push, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */
+      nvc0_query_get(push, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */
+      nvc0_query_get(push, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
       break;
    default:
       break;
@@ -248,7 +250,7 @@ static void
 nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_query *q = nvc0_query(pq);
 
    if (!q->active) {
@@ -263,49 +265,51 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
    switch (q->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
    case PIPE_QUERY_OCCLUSION_PREDICATE:
-      nvc0_query_get(chan, q, 0, 0x0100f002);
-      if (--nvc0->screen->num_occlusion_queries_active == 0)
-         IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 0);
+      nvc0_query_get(push, q, 0, 0x0100f002);
+      if (--nvc0->screen->num_occlusion_queries_active == 0) {
+         PUSH_SPACE(push, 1);
+         IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0);
+      }
       break;
    case PIPE_QUERY_PRIMITIVES_GENERATED:
-      nvc0_query_get(chan, q, 0, 0x06805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0, 0x06805002 | (q->index << 5));
       break;
    case PIPE_QUERY_PRIMITIVES_EMITTED:
-      nvc0_query_get(chan, q, 0, 0x05805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0, 0x05805002 | (q->index << 5));
       break;
    case PIPE_QUERY_SO_STATISTICS:
-      nvc0_query_get(chan, q, 0x00, 0x05805002 | (q->index << 5));
-      nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x00, 0x05805002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5));
       break;
    case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
       /* TODO: How do we sum over all streams for render condition ? */
       /* PRIMS_DROPPED doesn't write sequence, use a ZERO query to sync on */
-      nvc0_query_get(chan, q, 0x00, 0x03005002 | (q->index << 5));
-      nvc0_query_get(chan, q, 0x20, 0x00005002);
+      nvc0_query_get(push, q, 0x00, 0x03005002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x20, 0x00005002);
       break;
    case PIPE_QUERY_TIMESTAMP:
    case PIPE_QUERY_TIMESTAMP_DISJOINT:
    case PIPE_QUERY_TIME_ELAPSED:
-      nvc0_query_get(chan, q, 0, 0x00005002);
+      nvc0_query_get(push, q, 0, 0x00005002);
       break;
    case PIPE_QUERY_GPU_FINISHED:
-      nvc0_query_get(chan, q, 0, 0x1000f010);
+      nvc0_query_get(push, q, 0, 0x1000f010);
       break;
    case PIPE_QUERY_PIPELINE_STATISTICS:
-      nvc0_query_get(chan, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
-      nvc0_query_get(chan, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
-      nvc0_query_get(chan, q, 0x20, 0x02802002); /* VP, LAUNCHES */
-      nvc0_query_get(chan, q, 0x30, 0x03806002); /* GP, LAUNCHES */
-      nvc0_query_get(chan, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
-      nvc0_query_get(chan, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
-      nvc0_query_get(chan, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
-      nvc0_query_get(chan, q, 0x70, 0x0980a002); /* ROP, PIXELS */
-      nvc0_query_get(chan, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */
-      nvc0_query_get(chan, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */
+      nvc0_query_get(push, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
+      nvc0_query_get(push, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
+      nvc0_query_get(push, q, 0x20, 0x02802002); /* VP, LAUNCHES */
+      nvc0_query_get(push, q, 0x30, 0x03806002); /* GP, LAUNCHES */
+      nvc0_query_get(push, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
+      nvc0_query_get(push, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
+      nvc0_query_get(push, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
+      nvc0_query_get(push, q, 0x70, 0x0980a002); /* ROP, PIXELS */
+      nvc0_query_get(push, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */
+      nvc0_query_get(push, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */
       break;
    case NVC0_QUERY_TFB_BUFFER_OFFSET:
       /* indexed by TFB buffer instead of by vertex stream */
-      nvc0_query_get(chan, q, 0x00, 0x0d005002 | (q->index << 5));
+      nvc0_query_get(push, q, 0x00, 0x0d005002 | (q->index << 5));
       break;
    default:
       assert(0);
@@ -314,32 +318,20 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 }
 
 static INLINE boolean
-nvc0_query_ready(struct nvc0_query *q)
+nvc0_query_ready(struct nouveau_client *cli, struct nvc0_query *q)
 {
    if (q->is64bit) {
-      if (nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOWAIT))
-         return FALSE;
-      nouveau_bo_unmap(q->bo);
-      return TRUE;
+      return !nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOBLOCK, cli);
    } else {
       return q->data[0] == q->sequence;
    }
 }
 
-static INLINE boolean
-nvc0_query_wait(struct nvc0_query *q)
-{
-   int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
-   if (ret)
-      return FALSE;
-   nouveau_bo_unmap(q->bo);
-   return TRUE;
-}
-
 static boolean
 nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
                   boolean wait, union pipe_query_result *result)
 {
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
    struct nvc0_query *q = nvc0_query(pq);
    uint64_t *res64 = (uint64_t*)result;
    uint32_t *res32 = (uint32_t*)result;
@@ -348,15 +340,15 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
    unsigned i;
 
    if (!q->ready) /* update ? */
-      q->ready = nvc0_query_ready(q);
+      q->ready = nvc0_query_ready(nvc0->screen->base.client, q);
    if (!q->ready) {
-      struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
       if (!wait) {
-         if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
-            FIRE_RING(chan);
+         /* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
+         if (nouveau_pushbuf_refd(nvc0->base.pushbuf, q->bo) & NOUVEAU_BO_WR)
+            PUSH_KICK(nvc0->base.pushbuf);
          return FALSE;
       }
-      if (!nvc0_query_wait(q))
+      if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
          return FALSE;
    }
    q->ready = TRUE;
@@ -407,19 +399,20 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
 }
 
 void
-nvc0_query_fifo_wait(struct nouveau_channel *chan, struct pipe_query *pq)
+nvc0_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq)
 {
    struct nvc0_query *q = nvc0_query(pq);
    unsigned offset = q->offset;
 
    if (q->type == PIPE_QUERY_SO_OVERFLOW_PREDICATE) offset += 0x20;
 
-   MARK_RING (chan, 5, 2);
-   BEGIN_RING(chan, RING_3D_(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-   OUT_RING  (chan, q->sequence);
-   OUT_RING  (chan, (1 << 12) |
+   PUSH_SPACE(push, 5);
+   PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+   BEGIN_NVC0(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
+   PUSH_DATAh(push, q->bo->offset + offset);
+   PUSH_DATA (push, q->bo->offset + offset);
+   PUSH_DATA (push, q->sequence);
+   PUSH_DATA (push, (1 << 12) |
               NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
 }
 
@@ -428,7 +421,7 @@ nvc0_render_condition(struct pipe_context *pipe,
                       struct pipe_query *pq, uint mode)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_query *q;
    uint32_t cond;
    boolean negated = FALSE;
@@ -437,7 +430,8 @@ nvc0_render_condition(struct pipe_context *pipe,
       mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
 
    if (!pq) {
-      IMMED_RING(chan, RING_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
+      PUSH_SPACE(push, 1);
+      IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
       return;
    }
    q = nvc0_query(pq);
@@ -468,25 +462,27 @@ nvc0_render_condition(struct pipe_context *pipe,
    }
 
    if (wait)
-      nvc0_query_fifo_wait(chan, pq);
-
-   MARK_RING (chan, 4, 2);
-   BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-   OUT_RING  (chan, cond);
+      nvc0_query_fifo_wait(push, pq);
+
+   PUSH_SPACE(push, 4);
+   PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+   BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, q->bo->offset + q->offset);
+   PUSH_DATA (push, q->bo->offset + q->offset);
+   PUSH_DATA (push, cond);
 }
 
 void
-nvc0_query_pushbuf_submit(struct nouveau_channel *chan,
+nvc0_query_pushbuf_submit(struct nouveau_pushbuf *push,
                           struct pipe_query *pq, unsigned result_offset)
 {
    struct nvc0_query *q = nvc0_query(pq);
 
 #define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8))
 
-   nouveau_pushbuf_submit(chan, q->bo, q->offset + result_offset, 4 |
-                          NVC0_IB_ENTRY_1_NO_PREFETCH);
+   nouveau_pushbuf_space(push, 0, 0, 1);
+   nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 |
+                        NVC0_IB_ENTRY_1_NO_PREFETCH);
 }
 
 void
@@ -497,9 +493,9 @@ nvc0_so_target_save_offset(struct pipe_context *pipe,
    struct nvc0_so_target *targ = nvc0_so_target(ptarg);
 
    if (*serialize) {
-      struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
       *serialize = FALSE;
-      IMMED_RING(chan, RING_3D(SERIALIZE), 0);
+      PUSH_SPACE(nvc0_context(pipe)->base.pushbuf, 1);
+      IMMED_NVC0(nvc0_context(pipe)->base.pushbuf, NVC0_3D(SERIALIZE), 0);
    }
 
    nvc0_query(targ->pq)->index = index;
index f7637eedc43dbab7bea78d152d61573229e8191d..f314cb631f2e71473cdca0380ad79a42994e9fdc 100644 (file)
@@ -238,8 +238,8 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
       nouveau_fence_wait(screen->base.fence.current);
       nouveau_fence_ref(NULL, &screen->base.fence.current);
    }
-   if (screen->base.channel)
-      screen->base.channel->user_private = NULL;
+   if (screen->base.pushbuf)
+      screen->base.pushbuf->user_priv = NULL;
 
    if (screen->blitctx)
       FREE(screen->blitctx);
@@ -250,17 +250,17 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
    nouveau_bo_ref(NULL, &screen->fence.bo);
    nouveau_bo_ref(NULL, &screen->vfetch_cache);
 
-   nouveau_resource_destroy(&screen->lib_code);
-   nouveau_resource_destroy(&screen->text_heap);
+   nouveau_heap_destroy(&screen->lib_code);
+   nouveau_heap_destroy(&screen->text_heap);
 
    if (screen->tic.entries)
       FREE(screen->tic.entries);
 
    nouveau_mm_destroy(screen->mm_VRAM_fe0);
 
-   nouveau_grobj_free(&screen->fermi);
-   nouveau_grobj_free(&screen->eng2d);
-   nouveau_grobj_free(&screen->m2mf);
+   nouveau_object_del(&screen->fermi);
+   nouveau_object_del(&screen->eng2d);
+   nouveau_object_del(&screen->m2mf);
 
    nouveau_screen_fini(&screen->base);
 
@@ -271,102 +271,100 @@ static int
 nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos,
                      unsigned size, const uint32_t *data)
 {
-   struct nouveau_channel *chan = screen->base.channel;
+   struct nouveau_pushbuf *push = screen->base.pushbuf;
 
    size /= 4;
 
-   BEGIN_RING(chan, RING_3D_(NVC0_GRAPH_MACRO_ID), 2);
-   OUT_RING  (chan, (m - 0x3800) / 8);
-   OUT_RING  (chan, pos);
-   BEGIN_RING_1I(chan, RING_3D_(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
-   OUT_RING  (chan, pos);
-   OUT_RINGp (chan, data, size);
+   BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2);
+   PUSH_DATA (push, (m - 0x3800) / 8);
+   PUSH_DATA (push, pos);
+   BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
+   PUSH_DATA (push, pos);
+   PUSH_DATAp(push, data, size);
 
    return pos + size;
 }
 
 static void
-nvc0_magic_3d_init(struct nouveau_channel *chan)
+nvc0_magic_3d_init(struct nouveau_pushbuf *push)
 {
-   BEGIN_RING(chan, RING_3D_(0x10cc), 1);
-   OUT_RING  (chan, 0xff);
-   BEGIN_RING(chan, RING_3D_(0x10e0), 2);
-   OUT_RING(chan, 0xff);
-   OUT_RING(chan, 0xff);
-   BEGIN_RING(chan, RING_3D_(0x10ec), 2);
-   OUT_RING(chan, 0xff);
-   OUT_RING(chan, 0xff);
-   BEGIN_RING(chan, RING_3D_(0x074c), 1);
-   OUT_RING  (chan, 0x3f);
-
-   BEGIN_RING(chan, RING_3D_(0x16a8), 1);
-   OUT_RING  (chan, (3 << 16) | 3);
-   BEGIN_RING(chan, RING_3D_(0x1794), 1);
-   OUT_RING  (chan, (2 << 16) | 2);
-   BEGIN_RING(chan, RING_3D_(0x0de8), 1);
-   OUT_RING  (chan, 1);
+   BEGIN_NVC0(push, SUBC_3D(0x10cc), 1);
+   PUSH_DATA (push, 0xff);
+   BEGIN_NVC0(push, SUBC_3D(0x10e0), 2);
+   PUSH_DATA(push, 0xff);
+   PUSH_DATA(push, 0xff);
+   BEGIN_NVC0(push, SUBC_3D(0x10ec), 2);
+   PUSH_DATA(push, 0xff);
+   PUSH_DATA(push, 0xff);
+   BEGIN_NVC0(push, SUBC_3D(0x074c), 1);
+   PUSH_DATA (push, 0x3f);
+
+   BEGIN_NVC0(push, SUBC_3D(0x16a8), 1);
+   PUSH_DATA (push, (3 << 16) | 3);
+   BEGIN_NVC0(push, SUBC_3D(0x1794), 1);
+   PUSH_DATA (push, (2 << 16) | 2);
+   BEGIN_NVC0(push, SUBC_3D(0x0de8), 1);
+   PUSH_DATA (push, 1);
 
 #if 0 /* software method */
-   BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, SUBC_3D(0x1528), 1); /* MP poke */
+   PUSH_DATA (push, 0);
 #endif
 
-   BEGIN_RING(chan, RING_3D_(0x12ac), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D_(0x0218), 1);
-   OUT_RING  (chan, 0x10);
-   BEGIN_RING(chan, RING_3D_(0x10fc), 1);
-   OUT_RING  (chan, 0x10);
-   BEGIN_RING(chan, RING_3D_(0x1290), 1);
-   OUT_RING  (chan, 0x10);
-   BEGIN_RING(chan, RING_3D_(0x12d8), 2);
-   OUT_RING  (chan, 0x10);
-   OUT_RING  (chan, 0x10);
-   BEGIN_RING(chan, RING_3D_(0x06d4), 1);
-   OUT_RING  (chan, 8);
-   BEGIN_RING(chan, RING_3D_(0x1140), 1);
-   OUT_RING  (chan, 0x10);
-   BEGIN_RING(chan, RING_3D_(0x1610), 1);
-   OUT_RING  (chan, 0xe);
-
-   BEGIN_RING(chan, RING_3D_(0x164c), 1);
-   OUT_RING  (chan, 1 << 12);
-   BEGIN_RING(chan, RING_3D_(0x151c), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D_(0x030c), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D_(0x0300), 1);
-   OUT_RING  (chan, 3);
+   BEGIN_NVC0(push, SUBC_3D(0x12ac), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, SUBC_3D(0x0218), 1);
+   PUSH_DATA (push, 0x10);
+   BEGIN_NVC0(push, SUBC_3D(0x10fc), 1);
+   PUSH_DATA (push, 0x10);
+   BEGIN_NVC0(push, SUBC_3D(0x1290), 1);
+   PUSH_DATA (push, 0x10);
+   BEGIN_NVC0(push, SUBC_3D(0x12d8), 2);
+   PUSH_DATA (push, 0x10);
+   PUSH_DATA (push, 0x10);
+   BEGIN_NVC0(push, SUBC_3D(0x06d4), 1);
+   PUSH_DATA (push, 8);
+   BEGIN_NVC0(push, SUBC_3D(0x1140), 1);
+   PUSH_DATA (push, 0x10);
+   BEGIN_NVC0(push, SUBC_3D(0x1610), 1);
+   PUSH_DATA (push, 0xe);
+
+   BEGIN_NVC0(push, SUBC_3D(0x164c), 1);
+   PUSH_DATA (push, 1 << 12);
+   BEGIN_NVC0(push, SUBC_3D(0x151c), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, SUBC_3D(0x030c), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, SUBC_3D(0x0300), 1);
+   PUSH_DATA (push, 3);
 #if 0 /* software method */
-   BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, SUBC_3D(0x1280), 1); /* PGRAPH poke */
+   PUSH_DATA (push, 0);
 #endif
-   BEGIN_RING(chan, RING_3D_(0x02d0), 1);
-   OUT_RING  (chan, 0x1f40);
-   BEGIN_RING(chan, RING_3D_(0x00fdc), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D_(0x19c0), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D_(0x075c), 1);
-   OUT_RING  (chan, 3);
+   BEGIN_NVC0(push, SUBC_3D(0x02d0), 1);
+   PUSH_DATA (push, 0x1f40);
+   BEGIN_NVC0(push, SUBC_3D(0x0fdc), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, SUBC_3D(0x19c0), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, SUBC_3D(0x075c), 1);
+   PUSH_DATA (push, 3);
 }
 
 static void
 nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
 {
    struct nvc0_screen *screen = nvc0_screen(pscreen);
-   struct nouveau_channel *chan = screen->base.channel;
-
-   MARK_RING (chan, 5, 2);
+   struct nouveau_pushbuf *push = screen->base.pushbuf;
 
    /* we need to do it after possible flush in MARK_RING */
    *sequence = ++screen->base.fence.sequence;
 
-   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RING  (chan, *sequence);
-   OUT_RING  (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
+   BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4);
+   PUSH_DATAh(push, screen->fence.bo->offset);
+   PUSH_DATA (push, screen->fence.bo->offset);
+   PUSH_DATA (push, *sequence);
+   PUSH_DATA (push, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
               (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
 }
 
@@ -388,10 +386,12 @@ struct pipe_screen *
 nvc0_screen_create(struct nouveau_device *dev)
 {
    struct nvc0_screen *screen;
-   struct nouveau_channel *chan;
    struct pipe_screen *pscreen;
+   struct nouveau_object *chan;
+   struct nouveau_pushbuf *push;
    int ret;
    unsigned i;
+   union nouveau_bo_config mm_config;
 
    screen = CALLOC_STRUCT(nvc0_screen);
    if (!screen)
@@ -406,7 +406,8 @@ nvc0_screen_create(struct nouveau_device *dev)
       return NULL;
    }
    chan = screen->base.channel;
-   chan->user_private = screen;
+   push = screen->base.pushbuf;
+   push->user_priv = screen;
 
    pscreen->destroy = nvc0_screen_destroy;
    pscreen->context_create = nvc0_create;
@@ -419,203 +420,210 @@ nvc0_screen_create(struct nouveau_device *dev)
 
    nouveau_screen_init_vdec(&screen->base);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, NULL,
                         &screen->fence.bo);
    if (ret)
       goto fail;
-   nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
+   nouveau_bo_map(screen->fence.bo, 0, NULL);
    screen->fence.map = screen->fence.bo->map;
-   nouveau_bo_unmap(screen->fence.bo);
    screen->base.fence.emit = nvc0_screen_fence_emit;
    screen->base.fence.update = nvc0_screen_fence_update;
 
    for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) {
-      ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE,
+      ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, NULL,
                            &screen->scratch.bo[i]);
       if (ret)
          goto fail;
    }
 
-   ret = nouveau_grobj_alloc(chan, 0xbeef9039, NVC0_M2MF, &screen->m2mf);
+   ret = nouveau_object_new(chan, 0xbeef9039, NVC0_M2MF_CLASS, NULL, 0,
+                            &screen->m2mf);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
 
-   BIND_RING (chan, screen->m2mf, NVC0_SUBCH_MF);
-   BEGIN_RING(chan, RING_MF(NOTIFY_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, screen->m2mf->oclass);
+   BEGIN_NVC0(push, NVC0_M2MF(NOTIFY_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->fence.bo->offset + 16);
+   PUSH_DATA (push, screen->fence.bo->offset + 16);
+   PUSH_DATA (push, 0);
 
-   ret = nouveau_grobj_alloc(chan, 0xbeef902d, NVC0_2D, &screen->eng2d);
+   ret = nouveau_object_new(chan, 0xbeef902d, NVC0_2D_CLASS, NULL, 0,
+                            &screen->eng2d);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
 
-   BIND_RING (chan, screen->eng2d, NVC0_SUBCH_2D);
-   BEGIN_RING(chan, RING_2D(OPERATION), 1);
-   OUT_RING  (chan, NVC0_2D_OPERATION_SRCCOPY);
-   BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_2D_(0x0884), 1);
-   OUT_RING  (chan, 0x3f);
-   BEGIN_RING(chan, RING_2D_(0x0888), 1);
-   OUT_RING  (chan, 1);
-
-   ret = nouveau_grobj_alloc(chan, 0xbeef9097, NVC0_3D, &screen->fermi);
+   BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, screen->eng2d->oclass);
+   BEGIN_NVC0(push, NVC0_2D(OPERATION), 1);
+   PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY);
+   BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_2D(COLOR_KEY_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, SUBC_2D(0x0884), 1);
+   PUSH_DATA (push, 0x3f);
+   BEGIN_NVC0(push, SUBC_2D(0x0888), 1);
+   PUSH_DATA (push, 1);
+
+   ret = nouveau_object_new(chan, 0xbeef9097, NVC0_3D_CLASS, NULL, 0,
+                            &screen->fermi);
    if (ret)
       FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
 
-   BIND_RING (chan, screen->fermi, NVC0_SUBCH_3D);
-   BEGIN_RING(chan, RING_3D(NOTIFY_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
+   PUSH_DATA (push, screen->fermi->oclass);
+   BEGIN_NVC0(push, NVC0_3D(NOTIFY_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->fence.bo->offset + 32);
+   PUSH_DATA (push, screen->fence.bo->offset + 32);
+   PUSH_DATA (push, 0);
 
-   BEGIN_RING(chan, RING_3D(COND_MODE), 1);
-   OUT_RING  (chan, NVC0_3D_COND_MODE_ALWAYS);
+   BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1);
+   PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS);
 
    if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
       /* kill shaders after about 1 second (at 100 MHz) */
-      BEGIN_RING(chan, RING_3D(WATCHDOG_TIMER), 1);
-      OUT_RING  (chan, 0x17);
+      BEGIN_NVC0(push, NVC0_3D(WATCHDOG_TIMER), 1);
+      PUSH_DATA (push, 0x17);
    }
 
-   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
-   OUT_RING  (chan, 1);
-
-   BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
-   OUT_RING  (chan, NVC0_3D_MULTISAMPLE_MODE_MS1);
-   BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(LINE_WIDTH_SEPARATE), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(TEX_MISC), 1);
-   OUT_RING  (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
-
-   nvc0_magic_3d_init(chan);
-
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, &screen->text);
+   BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+   PUSH_DATA (push, 1);
+
+   BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1);
+   PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1);
+   BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(LINE_WIDTH_SEPARATE), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(LINE_LAST_PIXEL), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(TEX_MISC), 1);
+   PUSH_DATA (push, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
+
+   nvc0_magic_3d_init(push);
+
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
+                        &screen->text);
    if (ret)
       goto fail;
 
    /* XXX: getting a page fault at the end of the code buffer every few
     *  launches, don't use the last 256 bytes to work around them - prefetch ?
     */
-   nouveau_resource_init(&screen->text_heap, 0, (1 << 20) - 0x100);
+   nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL,
                         &screen->uniforms);
    if (ret)
       goto fail;
 
    /* auxiliary constants (6 user clip planes, base instance id) */
-   BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
-   OUT_RING  (chan, 256);
-   OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+   BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+   PUSH_DATA (push, 256);
+   PUSH_DATAh(push, screen->uniforms->offset + (5 << 16));
+   PUSH_DATA (push, screen->uniforms->offset + (5 << 16));
    for (i = 0; i < 5; ++i) {
-      BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1);
-      OUT_RING  (chan, (15 << 4) | 1);
+      BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1);
+      PUSH_DATA (push, (15 << 4) | 1);
    }
 
    screen->tls_size = (16 * 32) * (NVC0_CAP_MAX_PROGRAM_TEMPS * 16);
    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17,
-                        screen->tls_size, &screen->tls);
+                        screen->tls_size, NULL, &screen->tls);
    if (ret)
       goto fail;
 
-   BEGIN_RING(chan, RING_3D(CODE_ADDRESS_HIGH), 2);
-   OUT_RELOCh(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RING  (chan, screen->tls_size >> 32);
-   OUT_RING  (chan, screen->tls_size);
-   BEGIN_RING(chan, RING_3D_(0x07a0), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2);
+   PUSH_DATAh(push, screen->text->offset);
+   PUSH_DATA (push, screen->text->offset);
+   BEGIN_NVC0(push, NVC0_3D(TEMP_ADDRESS_HIGH), 4);
+   PUSH_DATAh(push, screen->tls->offset);
+   PUSH_DATA (push, screen->tls->offset);
+   PUSH_DATA (push, screen->tls_size >> 32);
+   PUSH_DATA (push, screen->tls_size);
+   BEGIN_NVC0(push, NVC0_3D(WARP_TEMP_ALLOC), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(LOCAL_BASE), 1);
+   PUSH_DATA (push, 0);
 
    for (i = 0; i < 5; ++i) {
-      BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
-      OUT_RING  (chan, 0x54);
+      BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1);
+      PUSH_DATA (push, 0x54);
    }
-   BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
+   PUSH_DATA (push, 0);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20,
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
                         &screen->vfetch_cache);
    if (ret)
       goto fail;
 
-   BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-   OUT_RING  (chan, 3);
+   BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->vfetch_cache->offset);
+   PUSH_DATA (push, screen->vfetch_cache->offset);
+   PUSH_DATA (push, 3);
 
-   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc);
+   ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL,
+                        &screen->txc);
    if (ret)
       goto fail;
 
-   BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, NVC0_TIC_MAX_ENTRIES - 1);
-
-   BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3);
-   OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RING  (chan, NVC0_TSC_MAX_ENTRIES - 1);
-
-   BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D_(0x1590), 1); /* deactivate ZCULL */
-   OUT_RING  (chan, 0x3f);
-
-   BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
-   OUT_RING  (chan, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
-   BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
+   BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->txc->offset);
+   PUSH_DATA (push, screen->txc->offset);
+   PUSH_DATA (push, NVC0_TIC_MAX_ENTRIES - 1);
+
+   BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3);
+   PUSH_DATAh(push, screen->txc->offset + 65536);
+   PUSH_DATA (push, screen->txc->offset + 65536);
+   PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1);
+
+   BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
+   PUSH_DATA (push, 0x3f);
+
+   BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_MODE), 1);
+   PUSH_DATA (push, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
+   BEGIN_NVC0(push, NVC0_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
    for (i = 0; i < 8 * 2; ++i)
-      OUT_RING(chan, 0);
-   BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
-   OUT_RING  (chan, 0);
+      PUSH_DATA(push, 0);
+   BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1);
+   PUSH_DATA (push, 0);
 
    /* neither scissors, viewport nor stencil mask should affect clears */
-   BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
-   OUT_RING  (chan, 0);
+   BEGIN_NVC0(push, NVC0_3D(CLEAR_FLAGS), 1);
+   PUSH_DATA (push, 0);
 
-   BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
-   OUT_RINGf (chan, 0.0f);
-   OUT_RINGf (chan, 1.0f);
-   BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
-   OUT_RING  (chan, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
+   BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
+   PUSH_DATAf(push, 0.0f);
+   PUSH_DATAf(push, 1.0f);
+   BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+   PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
 
    /* We use scissors instead of exact view volume clipping,
     * so they're always enabled.
     */
-   BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3);
-   OUT_RING  (chan, 1);
-   OUT_RING  (chan, 8192 << 16);
-   OUT_RING  (chan, 8192 << 16);
+   BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 3);
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 8192 << 16);
+   PUSH_DATA (push, 8192 << 16);
 
 #define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n);
 
@@ -627,41 +635,42 @@ nvc0_screen_create(struct nouveau_device *dev)
    MK_MACRO(NVC0_3D_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front);
    MK_MACRO(NVC0_3D_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back);
 
-   BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(RT_SEPARATE_FRAG_DATA), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
-   OUT_RING  (chan, 0x40);
-   BEGIN_RING(chan, RING_3D(LAYER), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
-   OUT_RING  (chan, 0x30);
-   BEGIN_RING(chan, RING_3D(PATCH_VERTICES), 1);
-   OUT_RING  (chan, 3);
-   BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1);
-   OUT_RING  (chan, 0x20);
-   BEGIN_RING(chan, RING_3D(SP_SELECT(0)), 1);
-   OUT_RING  (chan, 0x00);
-
-   BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1);
-   OUT_RING  (chan, 0);
-   BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
-   OUT_RING  (chan, NVC0_3D_POINT_RASTER_RULES_OGL);
-
-   BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
-   OUT_RING  (chan, 1);
-
-   BEGIN_RING(chan, RING_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
-   OUT_RING  (chan, 0xab);
-   OUT_RING  (chan, 0x00000000);
-
-   FIRE_RING (chan);
+   BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
+   PUSH_DATA (push, 0x40);
+   BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
+   PUSH_DATA (push, 0x30);
+   BEGIN_NVC0(push, NVC0_3D(PATCH_VERTICES), 1);
+   PUSH_DATA (push, 3);
+   BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
+   PUSH_DATA (push, 0x20);
+   BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1);
+   PUSH_DATA (push, 0x00);
+
+   BEGIN_NVC0(push, NVC0_3D(POINT_COORD_REPLACE), 1);
+   PUSH_DATA (push, 0);
+   BEGIN_NVC0(push, NVC0_3D(POINT_RASTER_RULES), 1);
+   PUSH_DATA (push, NVC0_3D_POINT_RASTER_RULES_OGL);
+
+   IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1);
+
+   BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
+   PUSH_DATA (push, 0xab);
+   PUSH_DATA (push, 0x00000000);
+
+   PUSH_KICK (push);
 
    screen->tic.entries = CALLOC(4096, sizeof(void *));
    screen->tsc.entries = screen->tic.entries + 2048;
 
-   screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
+   mm_config.nvc0.tile_mode = 0;
+   mm_config.nvc0.memtype = 0xfe0;
+   screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
 
    if (!nvc0_blitctx_create(screen))
       goto fail;
@@ -675,23 +684,6 @@ fail:
    return NULL;
 }
 
-void
-nvc0_screen_make_buffers_resident(struct nvc0_screen *screen)
-{
-   struct nouveau_channel *chan = screen->base.channel;
-
-   const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-
-   MARK_RING(chan, 0, 5);
-   nouveau_bo_validate(chan, screen->text, flags);
-   nouveau_bo_validate(chan, screen->uniforms, flags);
-   nouveau_bo_validate(chan, screen->txc, flags);
-   nouveau_bo_validate(chan, screen->vfetch_cache, flags);
-
-   if (screen->cur_ctx && screen->cur_ctx->state.tls_required)
-      nouveau_bo_validate(chan, screen->tls, flags);
-}
-
 int
 nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry)
 {
index be42970ca396aea2e9c4b49a9577da404e57c05a..9abf4b1fd3dcd6e85a5887ff71b05cebb64ec178 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef __NVC0_SCREEN_H__
 #define __NVC0_SCREEN_H__
 
-#define NOUVEAU_NVC0
 #include "nouveau/nouveau_screen.h"
 #include "nouveau/nouveau_mm.h"
 #include "nouveau/nouveau_fence.h"
-#undef NOUVEAU_NVC0
+#include "nouveau/nouveau_heap.h"
+
 #include "nvc0_winsys.h"
 #include "nvc0_stateobj.h"
 
@@ -36,8 +36,8 @@ struct nvc0_screen {
 
    uint64_t tls_size;
 
-   struct nouveau_resource *text_heap;
-   struct nouveau_resource *lib_code; /* allocated from text_heap */
+   struct nouveau_heap *text_heap;
+   struct nouveau_heap *lib_code; /* allocated from text_heap */
 
    struct nvc0_blitctx *blitctx;
 
@@ -67,9 +67,10 @@ struct nvc0_screen {
 
    struct nouveau_mman *mm_VRAM_fe0;
 
-   struct nouveau_grobj *fermi;
-   struct nouveau_grobj *eng2d;
-   struct nouveau_grobj *m2mf;
+   struct nouveau_object *fermi;
+   struct nouveau_object *eng2d;
+   struct nouveau_object *m2mf;
+   struct nouveau_object *dijkstra;
 };
 
 static INLINE struct nvc0_screen *
@@ -92,7 +93,6 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
 
    if (res->mm) {
       nouveau_fence_ref(screen->base.fence.current, &res->fence);
-
       if (flags & NOUVEAU_BO_WR)
          nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
    }
@@ -101,11 +101,7 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
 static INLINE void
 nvc0_resource_validate(struct nv04_resource *res, uint32_t flags)
 {
-   struct nvc0_screen *screen = nvc0_screen(res->base.screen);
-
    if (likely(res->bo)) {
-      nouveau_bo_validate(screen->base.channel, res->bo, flags);
-
       if (flags & NOUVEAU_BO_WR)
          res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       if (flags & NOUVEAU_BO_RD)
index 9945b8e7b1f78cd1966a23d98ec2439d13068956..9d6888434735abdab5a4e8a37706f07da52f15dd 100644 (file)
@@ -31,29 +31,33 @@ static INLINE void
 nvc0_program_update_context_state(struct nvc0_context *nvc0,
                                   struct nvc0_program *prog, int stage)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
-   if (prog->hdr[1])
+   if (prog && prog->need_tls) {
+      const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
+      if (!nvc0->state.tls_required)
+         BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls);
       nvc0->state.tls_required |= 1 << stage;
-   else
+   } else {
+      if (nvc0->state.tls_required == (1 << stage))
+         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TLS);
       nvc0->state.tls_required &= ~(1 << stage);
+   }
 
-   if (prog->immd_size) {
-      const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-
-      BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
+   if (prog && prog->immd_size) {
+      BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
       /* NOTE: may overlap code of a different shader */
-      OUT_RING  (chan, align(prog->immd_size, 0x100));
-      OUT_RELOCh(chan, nvc0->screen->text, prog->immd_base, rl);
-      OUT_RELOCl(chan, nvc0->screen->text, prog->immd_base, rl);
-      BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
-      OUT_RING  (chan, (14 << 4) | 1);
+      PUSH_DATA (push, align(prog->immd_size, 0x100));
+      PUSH_DATAh(push, nvc0->screen->text->offset + prog->immd_base);
+      PUSH_DATA (push, nvc0->screen->text->offset + prog->immd_base);
+      BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
+      PUSH_DATA (push, (14 << 4) | 1);
 
       nvc0->state.c14_bound |= 1 << stage;
    } else
    if (nvc0->state.c14_bound & (1 << stage)) {
-      BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
-      OUT_RING  (chan, (14 << 4) | 0);
+      BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
+      PUSH_DATA (push, (14 << 4) | 0);
 
       nvc0->state.c14_bound &= ~(1 << stage);
    }
@@ -62,7 +66,7 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0,
 static INLINE boolean
 nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
 {
-   if (prog->res)
+   if (prog->mem)
       return TRUE;
 
    if (!prog->translated) {
@@ -79,133 +83,129 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
 void
 nvc0_vertprog_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_program *vp = nvc0->vertprog;
 
    if (!nvc0_program_validate(nvc0, vp))
          return;
    nvc0_program_update_context_state(nvc0, vp, 0);
 
-   BEGIN_RING(chan, RING_3D(SP_SELECT(1)), 2);
-   OUT_RING  (chan, 0x11);
-   OUT_RING  (chan, vp->code_base);
-   BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(1)), 1);
-   OUT_RING  (chan, vp->max_gpr);
+   BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2);
+   PUSH_DATA (push, 0x11);
+   PUSH_DATA (push, vp->code_base);
+   BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1);
+   PUSH_DATA (push, vp->max_gpr);
 
-   // BEGIN_RING(chan, RING_3D_(0x163c), 1);
-   // OUT_RING  (chan, 0);
+   // BEGIN_NVC0(push, NVC0_3D_(0x163c), 1);
+   // PUSH_DATA (push, 0);
 }
 
 void
 nvc0_fragprog_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_program *fp = nvc0->fragprog;
 
    if (!nvc0_program_validate(nvc0, fp))
          return;
    nvc0_program_update_context_state(nvc0, fp, 4);
 
-   BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2);
-   OUT_RING  (chan, 0x51);
-   OUT_RING  (chan, fp->code_base);
-   BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(5)), 1);
-   OUT_RING  (chan, fp->max_gpr);
-
-   BEGIN_RING(chan, RING_3D_(0x0360), 2);
-   OUT_RING  (chan, 0x20164010);
-   OUT_RING  (chan, 0x20);
-   BEGIN_RING(chan, RING_3D_(0x196c), 1);
-   OUT_RING  (chan, fp->flags[0]);
+   BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2);
+   PUSH_DATA (push, 0x51);
+   PUSH_DATA (push, fp->code_base);
+   BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1);
+   PUSH_DATA (push, fp->max_gpr);
+
+   BEGIN_NVC0(push, SUBC_3D(0x0360), 2);
+   PUSH_DATA (push, 0x20164010);
+   PUSH_DATA (push, 0x20);
+   BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1);
+   PUSH_DATA (push, fp->flags[0]);
 }
 
 void
 nvc0_tctlprog_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_program *tp = nvc0->tctlprog;
 
-   if (!tp) {
-      BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1);
-      OUT_RING  (chan, 0x20);
-      return;
+   if (tp && nvc0_program_validate(nvc0, tp)) {
+      if (tp->tp.tess_mode != ~0) {
+         BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
+         PUSH_DATA (push, tp->tp.tess_mode);
+      }
+      BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
+      PUSH_DATA (push, 0x21);
+      PUSH_DATA (push, tp->code_base);
+      BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1);
+      PUSH_DATA (push, tp->max_gpr);
+
+      if (tp->tp.input_patch_size <= 32)
+         IMMED_NVC0(push, NVC0_3D(PATCH_VERTICES), tp->tp.input_patch_size);
+   } else {
+      BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
+      PUSH_DATA (push, 0x20);
    }
-   if (!nvc0_program_validate(nvc0, tp))
-         return;
    nvc0_program_update_context_state(nvc0, tp, 1);
-
-   if (tp->tp.tess_mode != ~0) {
-      BEGIN_RING(chan, RING_3D(TESS_MODE), 1);
-      OUT_RING  (chan, tp->tp.tess_mode);
-   }
-   BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 2);
-   OUT_RING  (chan, 0x21);
-   OUT_RING  (chan, tp->code_base);
-   BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(2)), 1);
-   OUT_RING  (chan, tp->max_gpr);
-
-   if (tp->tp.input_patch_size <= 32)
-      IMMED_RING(chan, RING_3D(PATCH_VERTICES), tp->tp.input_patch_size);
 }
 
 void
 nvc0_tevlprog_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_program *tp = nvc0->tevlprog;
 
-   if (!tp) {
-      BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
-      OUT_RING  (chan, 0x30);
-      return;
+   if (tp && nvc0_program_validate(nvc0, tp)) {
+      if (tp->tp.tess_mode != ~0) {
+         BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
+         PUSH_DATA (push, tp->tp.tess_mode);
+      }
+      BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
+      PUSH_DATA (push, 0x31);
+      BEGIN_NVC0(push, NVC0_3D(SP_START_ID(3)), 1);
+      PUSH_DATA (push, tp->code_base);
+      BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(3)), 1);
+      PUSH_DATA (push, tp->max_gpr);
+   } else {
+      BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
+      PUSH_DATA (push, 0x30);
    }
-   if (!nvc0_program_validate(nvc0, tp))
-         return;
    nvc0_program_update_context_state(nvc0, tp, 2);
-
-   if (tp->tp.tess_mode != ~0) {
-      BEGIN_RING(chan, RING_3D(TESS_MODE), 1);
-      OUT_RING  (chan, tp->tp.tess_mode);
-   }
-   BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
-   OUT_RING  (chan, 0x31);
-   BEGIN_RING(chan, RING_3D(SP_START_ID(3)), 1);
-   OUT_RING  (chan, tp->code_base);
-   BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(3)), 1);
-   OUT_RING  (chan, tp->max_gpr);
 }
 
 void
 nvc0_gmtyprog_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_program *gp = nvc0->gmtyprog;
 
    if (gp)
       nvc0_program_validate(nvc0, gp);
+
    /* we allow GPs with no code for specifying stream output state only */
-   if (!gp || !gp->code_size) {
-      BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
-      OUT_RING  (chan, 0x40);
-      IMMED_RING(chan, RING_3D(LAYER), 0);
-      return;
+   if (gp && gp->code_size) {
+      const boolean gp_selects_layer = gp->hdr[13] & (1 << 9);
+
+      BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
+      PUSH_DATA (push, 0x41);
+      BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1);
+      PUSH_DATA (push, gp->code_base);
+      BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1);
+      PUSH_DATA (push, gp->max_gpr);
+      BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
+      PUSH_DATA (push, gp_selects_layer ? NVC0_3D_LAYER_USE_GP : 0);
+   } else {
+      IMMED_NVC0(push, NVC0_3D(LAYER), 0);
+      BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
+      PUSH_DATA (push, 0x40);
    }
    nvc0_program_update_context_state(nvc0, gp, 3);
-
-   BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
-   OUT_RING  (chan, 0x41);
-   BEGIN_RING(chan, RING_3D(SP_START_ID(4)), 1);
-   OUT_RING  (chan, gp->code_base);
-   BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(4)), 1);
-   OUT_RING  (chan, gp->max_gpr);
-   BEGIN_RING(chan, RING_3D(LAYER), 1);
-   OUT_RING  (chan, (gp->hdr[13] & (1 << 9)) ? NVC0_3D_LAYER_USE_GP : 0);
 }
 
 void
 nvc0_tfb_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_transform_feedback_state *tfb;
    unsigned b;
 
@@ -215,24 +215,24 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
    else
       tfb = nvc0->vertprog->tfb;
 
-   IMMED_RING(chan, RING_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
+   IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
 
    if (tfb && tfb != nvc0->state.tfb) {
       for (b = 0; b < 4; ++b) {
          if (tfb->varying_count[b]) {
             unsigned n = (tfb->varying_count[b] + 3) / 4;
 
-            BEGIN_RING(chan, RING_3D(TFB_STREAM(b)), 3);
-            OUT_RING  (chan, 0);
-            OUT_RING  (chan, tfb->varying_count[b]);
-            OUT_RING  (chan, tfb->stride[b]);
-            BEGIN_RING(chan, RING_3D(TFB_VARYING_LOCS(b, 0)), n);
-            OUT_RINGp (chan, tfb->varying_index[b], n);
+            BEGIN_NVC0(push, NVC0_3D(TFB_STREAM(b)), 3);
+            PUSH_DATA (push, 0);
+            PUSH_DATA (push, tfb->varying_count[b]);
+            PUSH_DATA (push, tfb->stride[b]);
+            BEGIN_NVC0(push, NVC0_3D(TFB_VARYING_LOCS(b, 0)), n);
+            PUSH_DATAp(push, tfb->varying_index[b], n);
 
             if (nvc0->tfbbuf[b])
                nvc0_so_target(nvc0->tfbbuf[b])->stride = tfb->stride[b];
          } else {
-            IMMED_RING(chan, RING_3D(TFB_VARYING_COUNT(b)), 0);
+            IMMED_NVC0(push, NVC0_3D(TFB_VARYING_COUNT(b)), 0);
          }
       }
    }
@@ -240,7 +240,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
 
    if (!(nvc0->dirty & NVC0_NEW_TFB_TARGETS))
       return;
-   nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TFB);
+   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TFB);
 
    for (b = 0; b < nvc0->num_tfbbufs; ++b) {
       struct nvc0_so_target *targ = nvc0_so_target(nvc0->tfbbuf[b]);
@@ -253,20 +253,20 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
          continue;
 
       if (!targ->clean)
-         nvc0_query_fifo_wait(chan, targ->pq);
-      BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 5);
-      OUT_RING  (chan, 1);
-      OUT_RESRCh(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR);
-      OUT_RESRCl(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR);
-      OUT_RING  (chan, targ->pipe.buffer_size);
+         nvc0_query_fifo_wait(push, targ->pq);
+      BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
+      PUSH_DATA (push, 1);
+      PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset);
+      PUSH_DATA (push, buf->address + targ->pipe.buffer_offset);
+      PUSH_DATA (push, targ->pipe.buffer_size);
       if (!targ->clean) {
-         nvc0_query_pushbuf_submit(chan, targ->pq, 0x4);
+         nvc0_query_pushbuf_submit(push, targ->pq, 0x4);
       } else {
-         OUT_RING(chan, 0); /* TFB_BUFFER_OFFSET */
+         PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */
          targ->clean = FALSE;
       }
-      nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TFB, buf, NOUVEAU_BO_WR);
+      BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR);
    }
    for (; b < 4; ++b)
-      IMMED_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 0);
+      IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
 }
index 32b7a8a8ecfcf3fead62e23b6bb12b9e2aa9e8d3..e349491b66e1bf348253d2287a3d710a47ccbbba 100644 (file)
@@ -489,7 +489,7 @@ nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
 
    nvc0->num_textures[s] = nr;
 
-   nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES);
+   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX);
 
    nvc0->dirty |= NVC0_NEW_TEXTURES;
 }
@@ -621,8 +621,7 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    }
 
    if (nvc0->constbuf[shader][index])
-      nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT,
-                              nv04_resource(nvc0->constbuf[shader][index]));
+      nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index));
 
    pipe_resource_reference(&nvc0->constbuf[shader][index], res);
 
@@ -681,6 +680,8 @@ nvc0_set_framebuffer_state(struct pipe_context *pipe,
 {
     struct nvc0_context *nvc0 = nvc0_context(pipe);
 
+    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
+
     nvc0->framebuffer = *fb;
     nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
 }
@@ -731,7 +732,7 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
     memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count);
     nvc0->num_vtxbufs = count;
 
-    nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
+    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
 
     nvc0->dirty |= NVC0_NEW_ARRAYS;
 }
@@ -742,11 +743,16 @@ nvc0_set_index_buffer(struct pipe_context *pipe,
 {
     struct nvc0_context *nvc0 = nvc0_context(pipe);
 
-    if (ib) {
-       pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
+    if (nvc0->idxbuf.buffer)
+       nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX);
 
-       memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
+    if (ib && ib->buffer) {
+       nvc0->dirty |= NVC0_NEW_IDXBUF;
+       pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
+       nvc0->idxbuf.offset = ib->offset;
+       nvc0->idxbuf.index_size = ib->index_size;
     } else {
+       nvc0->dirty &= ~NVC0_NEW_IDXBUF;
        pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
     }
 }
index 6307b3a3de68de9bfe6a21a2f4f39e9d1915db9c..f235ba57e3650dd2379682bec6243339268efa21 100644 (file)
@@ -6,7 +6,7 @@
 static void
 nvc0_validate_zcull(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
     struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
     struct nv50_surface *sf = nv50_surface(fb->zsbuf);
     struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
@@ -26,89 +26,85 @@ nvc0_validate_zcull(struct nvc0_context *nvc0)
     else
        width = fb->width;
 
-    MARK_RING (chan, 23, 4);
-    BEGIN_RING(chan, RING_3D_(0x1590), 1); /* ZCULL_REGION_INDEX (bits 0x3f) */
-    OUT_RING  (chan, 0);
-    BEGIN_RING(chan, RING_3D_(0x07e8), 2); /* ZCULL_ADDRESS_A_HIGH */
-    OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-    OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+    BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1);
+    PUSH_DATA (push, 0);
+    BEGIN_NVC0(push, NVC0_3D(ZCULL_ADDRESS_HIGH), 2);
+    PUSH_DATAh(push, bo->offset + offset);
+    PUSH_DATA (push, bo->offset + offset);
     offset += 1 << 17;
-    BEGIN_RING(chan, RING_3D_(0x07f0), 2); /* ZCULL_ADDRESS_B_HIGH */
-    OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-    OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-    BEGIN_RING(chan, RING_3D_(0x07e0), 2);
-    OUT_RING  (chan, size);
-    OUT_RING  (chan, size >> 16);
-    BEGIN_RING(chan, RING_3D_(0x15c8), 1); /* bits 0x3 */
-    OUT_RING  (chan, 2);
-    BEGIN_RING(chan, RING_3D_(0x07c0), 4); /* ZCULL dimensions */
-    OUT_RING  (chan, width);
-    OUT_RING  (chan, height);
-    OUT_RING  (chan, 1);
-    OUT_RING  (chan, 0);
-    BEGIN_RING(chan, RING_3D_(0x15fc), 2);
-    OUT_RING  (chan, 0); /* bits 0xffff */
-    OUT_RING  (chan, 0); /* bits 0xffff */
-    BEGIN_RING(chan, RING_3D_(0x1958), 1);
-    OUT_RING  (chan, 0); /* bits ~0 */
+    BEGIN_NVC0(push, NVC0_3D(ZCULL_LIMIT_HIGH), 2);
+    PUSH_DATAh(push, bo->offset + offset);
+    PUSH_DATA (push, bo->offset + offset);
+    BEGIN_NVC0(push, SUBC_3D(0x07e0), 2);
+    PUSH_DATA (push, size);
+    PUSH_DATA (push, size >> 16);
+    BEGIN_NVC0(push, SUBC_3D(0x15c8), 1); /* bits 0x3 */
+    PUSH_DATA (push, 2);
+    BEGIN_NVC0(push, NVC0_3D(ZCULL_WIDTH), 4);
+    PUSH_DATA (push, width);
+    PUSH_DATA (push, height);
+    PUSH_DATA (push, 1);
+    PUSH_DATA (push, 0);
+    BEGIN_NVC0(push, NVC0_3D(ZCULL_WINDOW_OFFSET_X), 2);
+    PUSH_DATA (push, 0);
+    PUSH_DATA (push, 0);
+    BEGIN_NVC0(push, NVC0_3D(ZCULL_INVALIDATE), 1);
+    PUSH_DATA (push, 0);
 }
 
 static void
 nvc0_validate_fb(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
     struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
     unsigned i;
     unsigned ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1;
     boolean serialize = FALSE;
 
-    nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_FRAME);
+    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
 
-    BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
-    OUT_RING  (chan, (076543210 << 4) | fb->nr_cbufs);
-    BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
-    OUT_RING  (chan, fb->width << 16);
-    OUT_RING  (chan, fb->height << 16);
-
-    MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
+    BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+    PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
+    BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
+    PUSH_DATA (push, fb->width << 16);
+    PUSH_DATA (push, fb->height << 16);
 
     for (i = 0; i < fb->nr_cbufs; ++i) {
         struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
         struct nv04_resource *res = nv04_resource(sf->base.texture);
         struct nouveau_bo *bo = res->bo;
-        uint32_t offset = sf->offset + res->offset;
 
-        BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 9);
-        OUT_RELOCh(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR);
-        OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR);
-        if (likely(nouveau_bo_tile_layout(bo))) {
+        BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 9);
+        PUSH_DATAh(push, res->address + sf->offset);
+        PUSH_DATA (push, res->address + sf->offset);
+        if (likely(nouveau_bo_memtype(bo))) {
            struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
 
            assert(sf->base.texture->target != PIPE_BUFFER);
 
-           OUT_RING(chan, sf->width);
-           OUT_RING(chan, sf->height);
-           OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
-           OUT_RING(chan, (mt->layout_3d << 16) |
+           PUSH_DATA(push, sf->width);
+           PUSH_DATA(push, sf->height);
+           PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
+           PUSH_DATA(push, (mt->layout_3d << 16) |
                     mt->level[sf->base.u.tex.level].tile_mode);
-           OUT_RING(chan, sf->base.u.tex.first_layer + sf->depth);
-           OUT_RING(chan, mt->layer_stride >> 2);
-           OUT_RING(chan, sf->base.u.tex.first_layer);
+           PUSH_DATA(push, sf->base.u.tex.first_layer + sf->depth);
+           PUSH_DATA(push, mt->layer_stride >> 2);
+           PUSH_DATA(push, sf->base.u.tex.first_layer);
 
            ms_mode = mt->ms_mode;
         } else {
            if (res->base.target == PIPE_BUFFER) {
-              OUT_RING(chan, 262144);
-              OUT_RING(chan, 1);
+              PUSH_DATA(push, 262144);
+              PUSH_DATA(push, 1);
            } else {
-              OUT_RING(chan, nv50_miptree(sf->base.texture)->level[0].pitch);
-              OUT_RING(chan, sf->height);
+              PUSH_DATA(push, nv50_miptree(sf->base.texture)->level[0].pitch);
+              PUSH_DATA(push, sf->height);
            }
-           OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
-           OUT_RING(chan, 1 << 12);
-           OUT_RING(chan, 1);
-           OUT_RING(chan, 0);
-           OUT_RING(chan, 0);
+           PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
+           PUSH_DATA(push, 1 << 12);
+           PUSH_DATA(push, 1);
+           PUSH_DATA(push, 0);
+           PUSH_DATA(push, 0);
 
            nvc0_resource_fence(res, NOUVEAU_BO_WR);
 
@@ -121,33 +117,29 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
         res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
 
         /* only register for writing, otherwise we'd always serialize here */
-        nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, res,
-                                 res->domain | NOUVEAU_BO_WR);
+        BCTX_REFN(nvc0->bufctx_3d, FB, res, WR);
     }
 
     if (fb->zsbuf) {
         struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
         struct nv50_surface *sf = nv50_surface(fb->zsbuf);
-        struct nouveau_bo *bo = mt->base.bo;
         int unk = mt->base.base.target == PIPE_TEXTURE_2D;
-        uint32_t offset = sf->offset;
-
-        MARK_RING (chan, 12, 2);
-        BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
-        OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-        OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
-        OUT_RING  (chan, nvc0_format_table[fb->zsbuf->format].rt);
-        OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode);
-        OUT_RING  (chan, mt->layer_stride >> 2);
-        BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-        OUT_RING  (chan, 1);
-        BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
-        OUT_RING  (chan, sf->width);
-        OUT_RING  (chan, sf->height);
-        OUT_RING  (chan, (unk << 16) |
+
+        BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
+        PUSH_DATAh(push, mt->base.address + sf->offset);
+        PUSH_DATA (push, mt->base.address + sf->offset);
+        PUSH_DATA (push, nvc0_format_table[fb->zsbuf->format].rt);
+        PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+        PUSH_DATA (push, mt->layer_stride >> 2);
+        BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+        PUSH_DATA (push, 1);
+        BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
+        PUSH_DATA (push, sf->width);
+        PUSH_DATA (push, sf->height);
+        PUSH_DATA (push, (unk << 16) |
                    (sf->base.u.tex.first_layer + sf->depth));
-        BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1);
-        OUT_RING  (chan, sf->base.u.tex.first_layer);
+        BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
+        PUSH_DATA (push, sf->base.u.tex.first_layer);
 
         ms_mode = mt->ms_mode;
 
@@ -156,58 +148,55 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
         mt->base.status |=  NOUVEAU_BUFFER_STATUS_GPU_WRITING;
         mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
 
-        nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
-                                 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+        BCTX_REFN(nvc0->bufctx_3d, FB, &mt->base, WR);
     } else {
-        BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-        OUT_RING  (chan, 0);
+        BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+        PUSH_DATA (push, 0);
     }
 
-    IMMED_RING(chan, RING_3D(MULTISAMPLE_MODE), ms_mode);
+    IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), ms_mode);
 
-    if (serialize) {
-       BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
-       OUT_RING  (chan, 0);
-    }
+    if (serialize)
+       IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
 }
 
 static void
 nvc0_validate_blend_colour(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
-    BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
-    OUT_RINGf (chan, nvc0->blend_colour.color[0]);
-    OUT_RINGf (chan, nvc0->blend_colour.color[1]);
-    OUT_RINGf (chan, nvc0->blend_colour.color[2]);
-    OUT_RINGf (chan, nvc0->blend_colour.color[3]);    
+   BEGIN_NVC0(push, NVC0_3D(BLEND_COLOR(0)), 4);
+   PUSH_DATAf(push, nvc0->blend_colour.color[0]);
+   PUSH_DATAf(push, nvc0->blend_colour.color[1]);
+   PUSH_DATAf(push, nvc0->blend_colour.color[2]);
+   PUSH_DATAf(push, nvc0->blend_colour.color[3]);
 }
 
 static void
 nvc0_validate_stencil_ref(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
     const ubyte *ref = &nvc0->stencil_ref.ref_value[0];
 
-    IMMED_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), ref[0]);
-    IMMED_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), ref[1]);
+    IMMED_NVC0(push, NVC0_3D(STENCIL_FRONT_FUNC_REF), ref[0]);
+    IMMED_NVC0(push, NVC0_3D(STENCIL_BACK_FUNC_REF), ref[1]);
 }
 
 static void
 nvc0_validate_stipple(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
     unsigned i;
 
-    BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
+    BEGIN_NVC0(push, NVC0_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
     for (i = 0; i < 32; ++i)
-        OUT_RING(chan, util_bswap32(nvc0->stipple.stipple[i]));
+        PUSH_DATA(push, util_bswap32(nvc0->stipple.stipple[i]));
 }
 
 static void
 nvc0_validate_scissor(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
     struct pipe_scissor_state *s = &nvc0->scissor;
 
     if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
@@ -215,32 +204,32 @@ nvc0_validate_scissor(struct nvc0_context *nvc0)
        return;
     nvc0->state.scissor = nvc0->rast->pipe.scissor;
 
-    BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
+    BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
     if (nvc0->rast->pipe.scissor) {
-       OUT_RING(chan, (s->maxx << 16) | s->minx);
-       OUT_RING(chan, (s->maxy << 16) | s->miny);
+       PUSH_DATA(push, (s->maxx << 16) | s->minx);
+       PUSH_DATA(push, (s->maxy << 16) | s->miny);
     } else {
-       OUT_RING(chan, (0xffff << 16) | 0);
-       OUT_RING(chan, (0xffff << 16) | 0);
+       PUSH_DATA(push, (0xffff << 16) | 0);
+       PUSH_DATA(push, (0xffff << 16) | 0);
     }
 }
 
 static void
 nvc0_validate_viewport(struct nvc0_context *nvc0)
 {
-    struct nouveau_channel *chan = nvc0->screen->base.channel;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
     struct pipe_viewport_state *vp = &nvc0->viewport;
     int x, y, w, h;
     float zmin, zmax;
 
-    BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
-    OUT_RINGf (chan, vp->translate[0]);
-    OUT_RINGf (chan, vp->translate[1]);
-    OUT_RINGf (chan, vp->translate[2]);
-    BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
-    OUT_RINGf (chan, vp->scale[0]);
-    OUT_RINGf (chan, vp->scale[1]);
-    OUT_RINGf (chan, vp->scale[2]);
+    BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSLATE_X(0)), 3);
+    PUSH_DATAf(push, vp->translate[0]);
+    PUSH_DATAf(push, vp->translate[1]);
+    PUSH_DATAf(push, vp->translate[2]);
+    BEGIN_NVC0(push, NVC0_3D(VIEWPORT_SCALE_X(0)), 3);
+    PUSH_DATAf(push, vp->scale[0]);
+    PUSH_DATAf(push, vp->scale[1]);
+    PUSH_DATAf(push, vp->scale[2]);
 
     /* now set the viewport rectangle to viewport dimensions for clipping */
 
@@ -252,28 +241,27 @@ nvc0_validate_viewport(struct nvc0_context *nvc0)
     zmin = vp->translate[2] - fabsf(vp->scale[2]);
     zmax = vp->translate[2] + fabsf(vp->scale[2]);
 
-    BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
-    OUT_RING  (chan, (w << 16) | x);
-    OUT_RING  (chan, (h << 16) | y);
-    BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
-    OUT_RINGf (chan, zmin);
-    OUT_RINGf (chan, zmax);
+    BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
+    PUSH_DATA (push, (w << 16) | x);
+    PUSH_DATA (push, (h << 16) | y);
+    BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
+    PUSH_DATAf(push, zmin);
+    PUSH_DATAf(push, zmax);
 }
 
 static INLINE void
 nvc0_upload_uclip_planes(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nouveau_bo *bo = nvc0->screen->uniforms;
 
-   MARK_RING (chan, 6 + PIPE_MAX_CLIP_PLANES * 4, 2);
-   BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
-   OUT_RING  (chan, 256);
-   OUT_RELOCh(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   OUT_RELOCl(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-   BEGIN_RING_1I(chan, RING_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1);
-   OUT_RING  (chan, 0);
-   OUT_RINGp (chan, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
+   BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+   PUSH_DATA (push, 256);
+   PUSH_DATAh(push, bo->offset + (5 << 16));
+   PUSH_DATA (push, bo->offset + (5 << 16));
+   BEGIN_1IC0(push, NVC0_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1);
+   PUSH_DATA (push, 0);
+   PUSH_DATAp(push, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
 }
 
 static INLINE void
@@ -299,7 +287,7 @@ nvc0_check_program_ucps(struct nvc0_context *nvc0,
 static void
 nvc0_validate_clip(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_program *vp;
    uint8_t clip_enable = nvc0->rast->pipe.clip_plane_enable;
 
@@ -320,46 +308,46 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
 
    if (nvc0->state.clip_enable != clip_enable) {
       nvc0->state.clip_enable = clip_enable;
-      IMMED_RING(chan, RING_3D(CLIP_DISTANCE_ENABLE), clip_enable);
+      IMMED_NVC0(push, NVC0_3D(CLIP_DISTANCE_ENABLE), clip_enable);
    }
    if (nvc0->state.clip_mode != vp->vp.clip_mode) {
       nvc0->state.clip_mode = vp->vp.clip_mode;
-      BEGIN_RING(chan, RING_3D(CLIP_DISTANCE_MODE), 1);
-      OUT_RING  (chan, vp->vp.clip_mode);
+      BEGIN_NVC0(push, NVC0_3D(CLIP_DISTANCE_MODE), 1);
+      PUSH_DATA (push, vp->vp.clip_mode);
    }
 }
 
 static void
 nvc0_validate_blend(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
-   WAIT_RING(chan, nvc0->blend->size);
-   OUT_RINGp(chan, nvc0->blend->state, nvc0->blend->size);
+   PUSH_SPACE(push, nvc0->blend->size);
+   PUSH_DATAp(push, nvc0->blend->state, nvc0->blend->size);
 }
 
 static void
 nvc0_validate_zsa(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
-   WAIT_RING(chan, nvc0->zsa->size);
-   OUT_RINGp(chan, nvc0->zsa->state, nvc0->zsa->size);
+   PUSH_SPACE(push, nvc0->zsa->size);
+   PUSH_DATAp(push, nvc0->zsa->state, nvc0->zsa->size);
 }
 
 static void
 nvc0_validate_rasterizer(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
-   WAIT_RING(chan, nvc0->rast->size);
-   OUT_RINGp(chan, nvc0->rast->state, nvc0->rast->size);
+   PUSH_SPACE(push, nvc0->rast->size);
+   PUSH_DATAp(push, nvc0->rast->state, nvc0->rast->size);
 }
 
 static void
 nvc0_constbufs_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nouveau_bo *bo;
    unsigned s;
 
@@ -377,8 +365,8 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
 
          res = nv04_resource(nvc0->constbuf[s][i]);
          if (!res) {
-            BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
-            OUT_RING  (chan, (i << 4) | 0);
+            BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+            PUSH_DATA (push, (i << 4) | 0);
             if (i == 0)
                nvc0->state.uniform_buffer_bound[s] = 0;
             continue;
@@ -409,17 +397,15 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
          }
 
          if (bo != nvc0->screen->uniforms)
-            nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_CONSTANT, res,
-                                     NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+            BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
 
          if (rebind) {
-            MARK_RING (chan, 4, 2);
-            BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
-            OUT_RING  (chan, align(res->base.width0, 0x100));
-            OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-            OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-            BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
-            OUT_RING  (chan, (i << 4) | 1);
+            BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+            PUSH_DATA (push, align(res->base.width0, 0x100));
+            PUSH_DATAh(push, bo->offset + base);
+            PUSH_DATA (push, bo->offset + base);
+            BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+            PUSH_DATA (push, (i << 4) | 1);
          }
 
          if (words)
@@ -433,7 +419,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
 static void
 nvc0_validate_sample_mask(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
    unsigned mask[4] =
    {
@@ -443,19 +429,19 @@ nvc0_validate_sample_mask(struct nvc0_context *nvc0)
       nvc0->sample_mask & 0xffff
    };
 
-   BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
-   OUT_RING  (chan, mask[0]);
-   OUT_RING  (chan, mask[1]);
-   OUT_RING  (chan, mask[2]);
-   OUT_RING  (chan, mask[3]);
-   BEGIN_RING(chan, RING_3D(SAMPLE_SHADING), 1);
-   OUT_RING  (chan, 0x01);
+   BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4);
+   PUSH_DATA (push, mask[0]);
+   PUSH_DATA (push, mask[1]);
+   PUSH_DATA (push, mask[2]);
+   PUSH_DATA (push, mask[3]);
+   BEGIN_NVC0(push, NVC0_3D(SAMPLE_SHADING), 1);
+   PUSH_DATA (push, 0x01);
 }
 
 static void
 nvc0_validate_derived_1(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    boolean early_z;
    boolean rasterizer_discard;
 
@@ -463,7 +449,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0)
 
    if (early_z != nvc0->state.early_z) {
       nvc0->state.early_z = early_z;
-      IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z);
+      IMMED_NVC0(push, NVC0_3D(EARLY_FRAGMENT_TESTS), early_z);
    }
 
    rasterizer_discard = (!nvc0->fragprog || !nvc0->fragprog->hdr[18]) &&
@@ -473,7 +459,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0)
 
    if (rasterizer_discard != nvc0->state.rasterizer_discard) {
       nvc0->state.rasterizer_discard = rasterizer_discard;
-      IMMED_RING(chan, RING_3D(RASTERIZE_ENABLE), !rasterizer_discard);
+      IMMED_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), !rasterizer_discard);
    }
 }
 
@@ -534,6 +520,7 @@ static struct state_validate {
     { nvc0_validate_textures,      NVC0_NEW_TEXTURES },
     { nvc0_validate_samplers,      NVC0_NEW_SAMPLERS },
     { nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS },
+    { nvc0_idxbuf_validate,        NVC0_NEW_IDXBUF },
     { nvc0_tfb_validate,           NVC0_NEW_TFB_TARGETS | NVC0_NEW_GMTYPROG }
 };
 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
@@ -542,6 +529,7 @@ boolean
 nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
 {
    uint32_t state_mask;
+   int ret;
    unsigned i;
 
    if (nvc0->screen->cur_ctx != nvc0)
@@ -557,11 +545,17 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
             validate->func(nvc0);
       }
       nvc0->dirty &= ~state_mask;
+
+      nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, FALSE);
    }
 
-   MARK_RING(nvc0->screen->base.channel, words, 0);
+   nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx_3d);
+   ret = nouveau_pushbuf_validate(nvc0->base.pushbuf);
+   if (unlikely(ret))
+      return FALSE;
 
-   nvc0_bufctx_emit_relocs(nvc0);
+   if (unlikely(nvc0->state.flushed))
+      nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, TRUE);
 
    return TRUE;
 }
index dc5771a03aa5adf07fa599d5b1d32559a73619c9..bd54302970551c2ada5af0ed4f92a47ff4ff9f9b 100644 (file)
@@ -5,12 +5,10 @@
 #include "pipe/p_state.h"
 
 #define SB_BEGIN_3D(so, m, s)                                                  \
-   (so)->state[(so)->size++] =                                                 \
-      (0x2 << 28) | ((s) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
+   (so)->state[(so)->size++] = NVC0_FIFO_PKHDR_SQ(NVC0_3D(m), s)
 
 #define SB_IMMED_3D(so, m, d)                                                  \
-   (so)->state[(so)->size++] =                                                 \
-      (0x8 << 28) | ((d) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
+   (so)->state[(so)->size++] = NVC0_FIFO_PKHDR_IL(NVC0_3D(m), d)
 
 #define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
 
index 46b5da551db35711ad529639cf0ddf4f7abaaba0..cb5091ae3761f88874848ad719ebba632a8588e8 100644 (file)
@@ -73,14 +73,13 @@ nvc0_2d_format(enum pipe_format format)
 }
 
 static int
-nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
+nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
                     struct nv50_miptree *mt, unsigned level, unsigned layer)
 {
    struct nouveau_bo *bo = mt->base.bo;
    uint32_t width, height, depth;
    uint32_t format;
    uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
-   uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
    uint32_t offset = mt->level[level].offset;
 
    format = nvc0_2d_format(mt->base.base.format);
@@ -106,44 +105,44 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
       layer = 0;
    }
 
-   if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
-      BEGIN_RING(chan, RING_2D_(mthd), 2);
-      OUT_RING  (chan, format);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
-      OUT_RING  (chan, mt->level[level].pitch);
-      OUT_RING  (chan, width);
-      OUT_RING  (chan, height);
-      OUT_RELOCh(chan, bo, offset, flags);
-      OUT_RELOCl(chan, bo, offset, flags);
+   if (nouveau_bo_memtype(bo)) {
+      BEGIN_NVC0(push, SUBC_2D(mthd), 2);
+      PUSH_DATA (push, format);
+      PUSH_DATA (push, 1);
+      BEGIN_NVC0(push, SUBC_2D(mthd + 0x14), 5);
+      PUSH_DATA (push, mt->level[level].pitch);
+      PUSH_DATA (push, width);
+      PUSH_DATA (push, height);
+      PUSH_DATAh(push, bo->offset + offset);
+      PUSH_DATA (push, bo->offset + offset);
    } else {
-      BEGIN_RING(chan, RING_2D_(mthd), 5);
-      OUT_RING  (chan, format);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, mt->level[level].tile_mode);
-      OUT_RING  (chan, depth);
-      OUT_RING  (chan, layer);
-      BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
-      OUT_RING  (chan, width);
-      OUT_RING  (chan, height);
-      OUT_RELOCh(chan, bo, offset, flags);
-      OUT_RELOCl(chan, bo, offset, flags);
+      BEGIN_NVC0(push, SUBC_2D(mthd), 5);
+      PUSH_DATA (push, format);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, mt->level[level].tile_mode);
+      PUSH_DATA (push, depth);
+      PUSH_DATA (push, layer);
+      BEGIN_NVC0(push, SUBC_2D(mthd + 0x18), 4);
+      PUSH_DATA (push, width);
+      PUSH_DATA (push, height);
+      PUSH_DATAh(push, bo->offset + offset);
+      PUSH_DATA (push, bo->offset + offset);
    }
 
 #if 0
    if (dst) {
-      BEGIN_RING(chan, RING_2D_(NVC0_2D_CLIP_X), 4);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, 0);
-      OUT_RING  (chan, width);
-      OUT_RING  (chan, height);
+      BEGIN_NVC0(push, SUBC_2D(NVC0_2D_CLIP_X), 4);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, width);
+      PUSH_DATA (push, height);
    }
 #endif
    return 0;
 }
 
 static int
-nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
+nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push,
                         struct nv50_miptree *dst, unsigned dst_level,
                         unsigned dx, unsigned dy, unsigned dz,
                         struct nv50_miptree *src, unsigned src_level,
@@ -158,15 +157,15 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
    int ret;
    uint32_t ctrl = 0x00;
 
-   ret = MARK_RING(chan, 2 * 16 + 32, 4);
+   ret = PUSH_SPACE(push, 2 * 16 + 32);
    if (ret)
       return ret;
 
-   ret = nvc0_2d_texture_set(chan, 1, dst, dst_level, dz);
+   ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz);
    if (ret)
       return ret;
 
-   ret = nvc0_2d_texture_set(chan, 0, src, src_level, sz);
+   ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz);
    if (ret)
       return ret;
 
@@ -175,23 +174,23 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
       ctrl = 0x11;
 
    /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */
-   BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
-   OUT_RING  (chan, ctrl);
-   BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
-   OUT_RING  (chan, dx << dst->ms_x);
-   OUT_RING  (chan, dy << dst->ms_y);
-   OUT_RING  (chan, w << dst->ms_x);
-   OUT_RING  (chan, h << dst->ms_y);
-   BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
-   OUT_RING  (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
-   BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, sx << src->ms_x);
-   OUT_RING  (chan, 0);
-   OUT_RING  (chan, sy << src->ms_x);
+   BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1);
+   PUSH_DATA (push, ctrl);
+   BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4);
+   PUSH_DATA (push, dx << dst->ms_x);
+   PUSH_DATA (push, dy << dst->ms_y);
+   PUSH_DATA (push, w << dst->ms_x);
+   PUSH_DATA (push, h << dst->ms_y);
+   BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
+   PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
+   BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, sx << src->ms_x);
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, sy << src->ms_x);
 
    return 0;
 }
@@ -203,7 +202,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
                           struct pipe_resource *src, unsigned src_level,
                           const struct pipe_box *src_box)
 {
-   struct nvc0_screen *screen = nvc0_context(pipe)->screen;
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
    int ret;
    boolean m2mf;
    unsigned dst_layer = dstz, src_layer = src_box->z;
@@ -234,7 +233,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
                            src_box->x, src_box->y, src_box->z);
 
       for (i = 0; i < src_box->depth; ++i) {
-         nvc0_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
+         nvc0_m2mf_transfer_rect(nvc0, &drect, &srect, nx, ny);
 
          if (nv50_miptree(dst)->layout_3d)
             drect.z++;
@@ -252,16 +251,22 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
    assert(nvc0_2d_format_faithful(src->format));
    assert(nvc0_2d_format_faithful(dst->format));
 
+   BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
+   BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
+   nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
+   nouveau_pushbuf_validate(nvc0->base.pushbuf);
+
    for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
-      ret = nvc0_2d_texture_do_copy(screen->base.channel,
+      ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf,
                                     nv50_miptree(dst), dst_level,
                                     dstx, dsty, dst_layer,
                                     nv50_miptree(src), src_level,
                                     src_box->x, src_box->y, src_layer,
                                     src_box->width, src_box->height);
       if (ret)
-         return;
+         break;
    }
+   nouveau_bufctx_reset(nvc0->bufctx, 0);
 }
 
 static void
@@ -271,69 +276,65 @@ nvc0_clear_render_target(struct pipe_context *pipe,
                          unsigned dstx, unsigned dsty,
                          unsigned width, unsigned height)
 {
-   struct nvc0_context *nv50 = nvc0_context(pipe);
-   struct nvc0_screen *screen = nv50->screen;
-   struct nouveau_channel *chan = screen->base.channel;
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nv50_surface *sf = nv50_surface(dst);
    struct nv04_resource *res = nv04_resource(sf->base.texture);
    unsigned z;
 
-   BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
-   OUT_RINGf (chan, color->f[0]);
-   OUT_RINGf (chan, color->f[1]);
-   OUT_RINGf (chan, color->f[2]);
-   OUT_RINGf (chan, color->f[3]);
-
-   if (MARK_RING(chan, 18, 2))
-      return;
-
-   BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
-   OUT_RING  (chan, ( width << 16) | dstx);
-   OUT_RING  (chan, (height << 16) | dsty);
-
-   BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
-   OUT_RING  (chan, 1);
-   BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 9);
-   OUT_RESRCh(chan, res, sf->offset, NOUVEAU_BO_WR);
-   OUT_RESRCl(chan, res, sf->offset, NOUVEAU_BO_WR);
-   if (likely(nouveau_bo_tile_layout(res->bo))) {
+   BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
+   PUSH_DATAf(push, color->f[0]);
+   PUSH_DATAf(push, color->f[1]);
+   PUSH_DATAf(push, color->f[2]);
+   PUSH_DATAf(push, color->f[3]);
+
+   BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
+   PUSH_DATA (push, ( width << 16) | dstx);
+   PUSH_DATA (push, (height << 16) | dsty);
+
+   BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+   PUSH_DATA (push, 1);
+   BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9);
+   PUSH_DATAh(push, res->address + sf->offset);
+   PUSH_DATA (push, res->address + sf->offset);
+   if (likely(nouveau_bo_memtype(res->bo))) {
       struct nv50_miptree *mt = nv50_miptree(dst->texture);
 
-      OUT_RING(chan, sf->width);
-      OUT_RING(chan, sf->height);
-      OUT_RING(chan, nvc0_format_table[dst->format].rt);
-      OUT_RING(chan, (mt->layout_3d << 16) |
+      PUSH_DATA(push, sf->width);
+      PUSH_DATA(push, sf->height);
+      PUSH_DATA(push, nvc0_format_table[dst->format].rt);
+      PUSH_DATA(push, (mt->layout_3d << 16) |
                mt->level[sf->base.u.tex.level].tile_mode);
-      OUT_RING(chan, dst->u.tex.first_layer + sf->depth);
-      OUT_RING(chan, mt->layer_stride >> 2);
-      OUT_RING(chan, dst->u.tex.first_layer);
+      PUSH_DATA(push, dst->u.tex.first_layer + sf->depth);
+      PUSH_DATA(push, mt->layer_stride >> 2);
+      PUSH_DATA(push, dst->u.tex.first_layer);
    } else {
       if (res->base.target == PIPE_BUFFER) {
-         OUT_RING(chan, 262144);
-         OUT_RING(chan, 1);
+         PUSH_DATA(push, 262144);
+         PUSH_DATA(push, 1);
       } else {
-         OUT_RING(chan, nv50_miptree(&res->base)->level[0].pitch);
-         OUT_RING(chan, sf->height);
+         PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch);
+         PUSH_DATA(push, sf->height);
       }
-      OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
-      OUT_RING(chan, 1 << 12);
-      OUT_RING(chan, 1);
-      OUT_RING(chan, 0);
-      OUT_RING(chan, 0);
+      PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
+      PUSH_DATA(push, 1 << 12);
+      PUSH_DATA(push, 1);
+      PUSH_DATA(push, 0);
+      PUSH_DATA(push, 0);
 
-      IMMED_RING(chan, RING_3D(ZETA_ENABLE), 0);
+      IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);
 
       /* tiled textures don't have to be fenced, they're not mapped directly */
       nvc0_resource_fence(res, NOUVEAU_BO_WR);
    }
 
    for (z = 0; z < sf->depth; ++z) {
-      BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-      OUT_RING  (chan, 0x3c |
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+      PUSH_DATA (push, 0x3c |
                  (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
    }
 
-   nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
+   nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
 }
 
 static void
@@ -345,57 +346,52 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
                          unsigned dstx, unsigned dsty,
                          unsigned width, unsigned height)
 {
-       struct nvc0_context *nv50 = nvc0_context(pipe);
-       struct nvc0_screen *screen = nv50->screen;
-       struct nouveau_channel *chan = screen->base.channel;
+       struct nvc0_context *nvc0 = nvc0_context(pipe);
+       struct nouveau_pushbuf *push = nvc0->base.pushbuf;
        struct nv50_miptree *mt = nv50_miptree(dst->texture);
        struct nv50_surface *sf = nv50_surface(dst);
-       struct nouveau_bo *bo = mt->base.bo;
        uint32_t mode = 0;
        int unk = mt->base.base.target == PIPE_TEXTURE_2D;
        unsigned z;
 
        if (clear_flags & PIPE_CLEAR_DEPTH) {
-               BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
-               OUT_RINGf (chan, depth);
+               BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
+               PUSH_DATAf(push, depth);
                mode |= NVC0_3D_CLEAR_BUFFERS_Z;
        }
 
        if (clear_flags & PIPE_CLEAR_STENCIL) {
-               BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
-               OUT_RING  (chan, stencil & 0xff);
+               BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
+               PUSH_DATA (push, stencil & 0xff);
                mode |= NVC0_3D_CLEAR_BUFFERS_S;
        }
 
-       if (MARK_RING(chan, 20, 2))
-               return;
-
-       BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
-       OUT_RING  (chan, ( width << 16) | dstx);
-       OUT_RING  (chan, (height << 16) | dsty);
-
-       BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
-       OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       OUT_RING  (chan, nvc0_format_table[dst->format].rt);
-       OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode);
-       OUT_RING  (chan, mt->layer_stride >> 2);
-       BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
-       OUT_RING  (chan, 1);
-       BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
-       OUT_RING  (chan, sf->width);
-       OUT_RING  (chan, sf->height);
-       OUT_RING  (chan, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
-       BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1);
-       OUT_RING  (chan, dst->u.tex.first_layer);
+       BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
+       PUSH_DATA (push, ( width << 16) | dstx);
+       PUSH_DATA (push, (height << 16) | dsty);
+
+       BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
+       PUSH_DATAh(push, mt->base.address + sf->offset);
+       PUSH_DATA (push, mt->base.address + sf->offset);
+       PUSH_DATA (push, nvc0_format_table[dst->format].rt);
+       PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+       PUSH_DATA (push, mt->layer_stride >> 2);
+       BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+       PUSH_DATA (push, 1);
+       BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
+       PUSH_DATA (push, sf->width);
+       PUSH_DATA (push, sf->height);
+       PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
+       BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
+       PUSH_DATA (push, dst->u.tex.first_layer);
 
        for (z = 0; z < sf->depth; ++z) {
-               BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-               OUT_RING  (chan, mode |
+               BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+               PUSH_DATA (push, mode |
                           (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
        }
 
-       nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
+       nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
 }
 
 void
@@ -404,7 +400,7 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
            double depth, unsigned stencil)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
    unsigned i;
    uint32_t mode = 0;
@@ -414,34 +410,34 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
       return;
 
    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
-      BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
-      OUT_RINGf (chan, color->f[0]);
-      OUT_RINGf (chan, color->f[1]);
-      OUT_RINGf (chan, color->f[2]);
-      OUT_RINGf (chan, color->f[3]);
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
+      PUSH_DATAf(push, color->f[0]);
+      PUSH_DATAf(push, color->f[1]);
+      PUSH_DATAf(push, color->f[2]);
+      PUSH_DATAf(push, color->f[3]);
       mode =
          NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G |
          NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A;
    }
 
    if (buffers & PIPE_CLEAR_DEPTH) {
-      BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
-      OUT_RING  (chan, fui(depth));
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
+      PUSH_DATA (push, fui(depth));
       mode |= NVC0_3D_CLEAR_BUFFERS_Z;
    }
 
    if (buffers & PIPE_CLEAR_STENCIL) {
-      BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
-      OUT_RING  (chan, stencil & 0xff);
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
+      PUSH_DATA (push, stencil & 0xff);
       mode |= NVC0_3D_CLEAR_BUFFERS_S;
    }
 
-   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-   OUT_RING  (chan, mode);
+   BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+   PUSH_DATA (push, mode);
 
    for (i = 1; i < fb->nr_cbufs; i++) {
-      BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
-      OUT_RING  (chan, (i << 6) | 0x3c);
+      BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+      PUSH_DATA (push, (i << 6) | 0x3c);
    }
 }
 
@@ -709,42 +705,42 @@ nvc0_blit_set_src(struct nvc0_context *nvc0,
 static void
 nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit)
 {
-   struct nouveau_channel *chan = blit->screen->base.channel;
+   struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
 
    /* TODO: maybe make this a MACRO (if we need more logic) ? */
 
    /* blend state */
-   BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1);
-   OUT_RING  (chan, blit->color_mask);
-   BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1);
-   OUT_RING  (chan, 0);
-   IMMED_RING(chan, RING_3D(LOGIC_OP_ENABLE), 0);
+   BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1);
+   PUSH_DATA (push, blit->color_mask);
+   BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1);
+   PUSH_DATA (push, 0);
+   IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0);
 
    /* rasterizer state */
-   BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
-   OUT_RING  (chan, 0);
-   IMMED_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 0);
-   BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
-   OUT_RING  (chan, 0xffff);
-   OUT_RING  (chan, 0xffff);
-   OUT_RING  (chan, 0xffff);
-   OUT_RING  (chan, 0xffff);
-   BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 1);
-   OUT_RING  (chan, NVC0_3D_POLYGON_MODE_FRONT_FILL);
-   BEGIN_RING(chan, RING_3D(POLYGON_MODE_BACK), 1);
-   OUT_RING  (chan, NVC0_3D_POLYGON_MODE_BACK_FILL);
-   IMMED_RING(chan, RING_3D(POLYGON_SMOOTH_ENABLE), 0);
-   IMMED_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
-   IMMED_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 0);
-   IMMED_RING(chan, RING_3D(CULL_FACE_ENABLE), 0);
+   BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1);
+   PUSH_DATA (push, 0);
+   IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0);
+   BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4);
+   PUSH_DATA (push, 0xffff);
+   PUSH_DATA (push, 0xffff);
+   PUSH_DATA (push, 0xffff);
+   PUSH_DATA (push, 0xffff);
+   BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_FRONT), 1);
+   PUSH_DATA (push, NVC0_3D_POLYGON_MODE_FRONT_FILL);
+   BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_BACK), 1);
+   PUSH_DATA (push, NVC0_3D_POLYGON_MODE_BACK_FILL);
+   IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0);
 
    /* zsa state */
-   IMMED_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 0);
-   IMMED_RING(chan, RING_3D(STENCIL_ENABLE), 0);
-   IMMED_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0);
 
    /* disable transform feedback */
-   IMMED_RING(chan, RING_3D(TFB_ENABLE), 0);
+   IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0);
 }
 
 static void
@@ -835,7 +831,7 @@ nvc0_resource_resolve(struct pipe_context *pipe,
    struct nvc0_context *nvc0 = nvc0_context(pipe);
    struct nvc0_screen *screen = nvc0->screen;
    struct nvc0_blitctx *blit = screen->blitctx;
-   struct nouveau_channel *chan = screen->base.channel;
+   struct nouveau_pushbuf *push = screen->base.pushbuf;
    struct pipe_resource *src = info->src.res;
    struct pipe_resource *dst = info->dst.res;
    float x0, x1, y0, y1;
@@ -878,11 +874,11 @@ nvc0_resource_resolve(struct pipe_context *pipe,
    y0 *= (float)(1 << nv50_miptree(src)->ms_y);
    y1 *= (float)(1 << nv50_miptree(src)->ms_y);
 
-   BEGIN_RING(chan, RING_3D(SP_START_ID(5)), 1);
-   OUT_RING  (chan,
+   BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1);
+   PUSH_DATA (push,
               blit->fp.code_base + blit->fp_offset);
 
-   IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 0);
+   IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
 
    /* Draw a large triangle in screen coordinates covering the whole
     * render target, with scissors defining the destination region.
@@ -890,43 +886,43 @@ nvc0_resource_resolve(struct pipe_context *pipe,
     * arranged in a way to yield the desired offset and scale.
     */
 
-   BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
-   OUT_RING  (chan, (info->dst.x1 << 16) | info->dst.x0);
-   OUT_RING  (chan, (info->dst.y1 << 16) | info->dst.y0);
+   BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
+   PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0);
+   PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0);
 
-   IMMED_RING(chan, RING_3D(VERTEX_BEGIN_GL),
+   IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL),
               NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
 
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
-   OUT_RING  (chan, 0x74201);
-   OUT_RINGf (chan, x0);
-   OUT_RINGf (chan, y0);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
-   OUT_RING  (chan, 0x74200);
-   OUT_RINGf (chan, 0.0f);
-   OUT_RINGf (chan, 0.0f);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
-   OUT_RING  (chan, 0x74201);
-   OUT_RINGf (chan, x1);
-   OUT_RINGf (chan, y0);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
-   OUT_RING  (chan, 0x74200);
-   OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x);
-   OUT_RINGf (chan, 0.0f);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
-   OUT_RING  (chan, 0x74201);
-   OUT_RINGf (chan, x0);
-   OUT_RINGf (chan, y1);
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
-   OUT_RING  (chan, 0x74200);
-   OUT_RINGf (chan, 0.0f);
-   OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y);
-
-   IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+   PUSH_DATA (push, 0x74201);
+   PUSH_DATAf(push, x0);
+   PUSH_DATAf(push, y0);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+   PUSH_DATA (push, 0x74200);
+   PUSH_DATAf(push, 0.0f);
+   PUSH_DATAf(push, 0.0f);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+   PUSH_DATA (push, 0x74201);
+   PUSH_DATAf(push, x1);
+   PUSH_DATAf(push, y0);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+   PUSH_DATA (push, 0x74200);
+   PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
+   PUSH_DATAf(push, 0.0f);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+   PUSH_DATA (push, 0x74201);
+   PUSH_DATAf(push, x0);
+   PUSH_DATAf(push, y1);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+   PUSH_DATA (push, 0x74200);
+   PUSH_DATAf(push, 0.0f);
+   PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
+
+   IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
 
    /* re-enable normally constant state */
 
-   IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
+   IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
 
    nvc0_blitctx_post_blit(nvc0, blit);
 }
index 0a1bc379868bdec22de55b5f784416b354d7fc30..fd58f80ab970c8879c8245a980fb95b9284c7d97 100644 (file)
@@ -56,6 +56,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
                          const struct pipe_sampler_view *templ)
 {
    const struct util_format_description *desc;
+   uint64_t address;
    uint32_t *tic;
    uint32_t swz[4];
    uint32_t depth;
@@ -66,6 +67,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
    view = MALLOC_STRUCT(nv50_tic_entry);
    if (!view)
       return NULL;
+   mt = nv50_miptree(texture);
 
    view->pipe = *templ;
    view->pipe.reference.count = 1;
@@ -80,8 +82,6 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
 
    desc = util_format_description(view->pipe.format);
 
-   /* TIC[0] */
-
    tic[0] = nvc0_format_table[view->pipe.format].tic;
 
    tex_int = util_format_is_pure_integer(view->pipe.format);
@@ -96,26 +96,24 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
       (swz[2] << NV50_TIC_0_MAPB__SHIFT) |
       (swz[3] << NV50_TIC_0_MAPA__SHIFT);
 
-   tic[1] = /* mt->base.bo->offset; */ 0;
-   tic[2] = /* mt->base.bo->offset >> 32 */ 0;
+   address = mt->base.address;
 
-   tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
+   tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER;
 
    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
       tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
 
    /* check for linear storage type */
-   if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
+   if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
       if (texture->target == PIPE_BUFFER) {
-         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
-         tic[1] = /* address offset */
+         address +=
             view->pipe.u.buf.first_element * desc->block.bits / 8;
+         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
          tic[3] = 0;
          tic[4] = /* width */
             view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
-        tic[5] = 0;
+         tic[5] = 0;
       } else {
-         mt = nv50_miptree(texture);
          /* must be 2D texture without mip maps */
          tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
          if (texture->target != PIPE_TEXTURE_RECT)
@@ -126,24 +124,27 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
       }
       tic[6] =
       tic[7] = 0;
+      tic[1] = address;
+      tic[2] |= address >> 32;
       return &view->pipe;
    }
-   mt = nv50_miptree(texture);
 
    if (mt->base.base.target != PIPE_TEXTURE_RECT)
       tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
 
    tic[2] |=
-      ((mt->base.bo->tile_mode & 0x0f0) << (22 - 4)) |
-      ((mt->base.bo->tile_mode & 0xf00) << (25 - 8));
+      ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
+      ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
 
    depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
 
    if (mt->base.base.array_size > 1) {
       /* there doesn't seem to be a base layer field in TIC */
-      tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride;
+      address += view->pipe.u.tex.first_layer * mt->layer_stride;
       depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
    }
+   tic[1] = address;
+   tic[2] |= address >> 32;
 
    switch (mt->base.base.target) {
    case PIPE_TEXTURE_1D:
@@ -205,7 +206,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
 static boolean
 nvc0_validate_tic(struct nvc0_context *nvc0, int s)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nouveau_bo *txc = nvc0->screen->txc;
    unsigned i;
    boolean need_flush = FALSE;
@@ -215,53 +216,46 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
       struct nv04_resource *res;
 
       if (!tic) {
-         BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
-         OUT_RING  (chan, (i << 1) | 0);
+         BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
+         PUSH_DATA (push, (i << 1) | 0);
          continue;
       }
       res = nv04_resource(tic->pipe.texture);
 
       if (tic->id < 0) {
-         uint32_t offset = res->offset + tic->tic[1];
-
          tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
 
-         MARK_RING (chan, 9 + 8, 4);
-         BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
-         OUT_RELOCh(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-         OUT_RELOCl(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-         BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
-         OUT_RING  (chan, 32);
-         OUT_RING  (chan, 1);
-         BEGIN_RING(chan, RING_MF(EXEC), 1);
-         OUT_RING  (chan, 0x100111);
-         BEGIN_RING_NI(chan, RING_MF(DATA), 8);
-         OUT_RING  (chan, tic->tic[0]);
-         OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RD);
-         OUT_RELOC (chan, res->bo, offset, res->domain | NOUVEAU_BO_RD |
-                    NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
-         OUT_RINGp (chan, &tic->tic[3], 5);
+         PUSH_SPACE(push, 17);
+         BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+         PUSH_DATAh(push, txc->offset + (tic->id * 32));
+         PUSH_DATA (push, txc->offset + (tic->id * 32));
+         BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+         PUSH_DATA (push, 32);
+         PUSH_DATA (push, 1);
+         BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+         PUSH_DATA (push, 0x100111);
+         BEGIN_NIC0(push, NVC0_M2MF(DATA), 8);
+         PUSH_DATAp(push, &tic->tic[0], 8);
 
          need_flush = TRUE;
       } else
       if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
-         BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
-         OUT_RING  (chan, (tic->id << 4) | 1);
+         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
+         PUSH_DATA (push, (tic->id << 4) | 1);
       }
       nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
 
       res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
 
-      nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res,
-                               res->domain | NOUVEAU_BO_RD);
+      BCTX_REFN(nvc0->bufctx_3d, TEX, res, RD);
 
-      BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
-      OUT_RING  (chan, (tic->id << 9) | (i << 1) | 1);
+      BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
+      PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
    }
    for (; i < nvc0->state.num_textures[s]; ++i) {
-      BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
-      OUT_RING  (chan, (i << 1) | 0);
+      BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
+      PUSH_DATA (push, (i << 1) | 0);
    }
    nvc0->state.num_textures[s] = nvc0->num_textures[s];
 
@@ -277,15 +271,15 @@ void nvc0_validate_textures(struct nvc0_context *nvc0)
    need_flush |= nvc0_validate_tic(nvc0, 4);
 
    if (need_flush) {
-      BEGIN_RING(nvc0->screen->base.channel, RING_3D(TIC_FLUSH), 1);
-      OUT_RING  (nvc0->screen->base.channel, 0);
+      BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
+      PUSH_DATA (nvc0->base.pushbuf, 0);
    }
 }
 
 static boolean
 nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    unsigned i;
    boolean need_flush = FALSE;
 
@@ -293,8 +287,8 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
       struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
 
       if (!tsc) {
-         BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
-         OUT_RING  (chan, (i << 4) | 0);
+         BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
+         PUSH_DATA (push, (i << 4) | 0);
          continue;
       }
       if (tsc->id < 0) {
@@ -307,12 +301,12 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
       }
       nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
 
-      BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
-      OUT_RING  (chan, (tsc->id << 12) | (i << 4) | 1);
+      BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
+      PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
    }
    for (; i < nvc0->state.num_samplers[s]; ++i) {
-      BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
-      OUT_RING  (chan, (i << 4) | 0);
+      BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
+      PUSH_DATA (push, (i << 4) | 0);
    }
    nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
 
@@ -328,7 +322,7 @@ void nvc0_validate_samplers(struct nvc0_context *nvc0)
    need_flush |= nvc0_validate_tsc(nvc0, 4);
 
    if (need_flush) {
-      BEGIN_RING(nvc0->screen->base.channel, RING_3D(TSC_FLUSH), 1);
-      OUT_RING  (nvc0->screen->base.channel, 0);
+      BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
+      PUSH_DATA (nvc0->base.pushbuf, 0);
    }
 }
index f16863733b7c907dffc59e060ca4b76fbd9c698f..774793d8d022b14fa99373c0d6aa400babdd80dc 100644 (file)
@@ -14,12 +14,13 @@ struct nvc0_transfer {
 };
 
 void
-nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
                         const struct nv50_m2mf_rect *dst,
                         const struct nv50_m2mf_rect *src,
                         uint32_t nblocksx, uint32_t nblocksy)
 {
-   struct nouveau_channel *chan = nouveau_screen(pscreen)->channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+   struct nouveau_bufctx *bctx = nvc0->bufctx;
    const int cpp = dst->cpp;
    uint32_t src_ofst = src->base;
    uint32_t dst_ofst = dst->base;
@@ -30,34 +31,39 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
 
    assert(dst->cpp == src->cpp);
 
-   if (nouveau_bo_tile_layout(src->bo)) {
-      BEGIN_RING(chan, RING_MF(TILING_MODE_IN), 5);
-      OUT_RING  (chan, src->tile_mode);
-      OUT_RING  (chan, src->width * cpp);
-      OUT_RING  (chan, src->height);
-      OUT_RING  (chan, src->depth);
-      OUT_RING  (chan, src->z);
+   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
+   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
+   nouveau_pushbuf_bufctx(push, bctx);
+   nouveau_pushbuf_validate(push);
+
+   if (nouveau_bo_memtype(src->bo)) {
+      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
+      PUSH_DATA (push, src->tile_mode);
+      PUSH_DATA (push, src->width * cpp);
+      PUSH_DATA (push, src->height);
+      PUSH_DATA (push, src->depth);
+      PUSH_DATA (push, src->z);
    } else {
       src_ofst += src->y * src->pitch + src->x * cpp;
 
-      BEGIN_RING(chan, RING_MF(PITCH_IN), 1);
-      OUT_RING  (chan, src->width * cpp);
+      BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1);
+      PUSH_DATA (push, src->width * cpp);
 
       exec |= NVC0_M2MF_EXEC_LINEAR_IN;
    }
 
-   if (nouveau_bo_tile_layout(dst->bo)) {
-      BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5);
-      OUT_RING  (chan, dst->tile_mode);
-      OUT_RING  (chan, dst->width * cpp);
-      OUT_RING  (chan, dst->height);
-      OUT_RING  (chan, dst->depth);
-      OUT_RING  (chan, dst->z);
+   if (nouveau_bo_memtype(dst->bo)) {
+      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5);
+      PUSH_DATA (push, dst->tile_mode);
+      PUSH_DATA (push, dst->width * cpp);
+      PUSH_DATA (push, dst->height);
+      PUSH_DATA (push, dst->depth);
+      PUSH_DATA (push, dst->z);
    } else {
       dst_ofst += dst->y * dst->pitch + dst->x * cpp;
 
-      BEGIN_RING(chan, RING_MF(PITCH_OUT), 1);
-      OUT_RING  (chan, dst->width * cpp);
+      BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1);
+      PUSH_DATA (push, dst->width * cpp);
 
       exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
    }
@@ -65,41 +71,41 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
    while (height) {
       int line_count = height > 2047 ? 2047 : height;
 
-      MARK_RING (chan, 17, 4);
+      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
+      PUSH_DATAh(push, src->bo->offset + src_ofst);
+      PUSH_DATA (push, src->bo->offset + src_ofst);
 
-      BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
-      OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
-      OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
-
-      BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
-      OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
-      OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
+      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+      PUSH_DATAh(push, dst->bo->offset + dst_ofst);
+      PUSH_DATA (push, dst->bo->offset + dst_ofst);
 
       if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) {
-         BEGIN_RING(chan, RING_MF(TILING_POSITION_IN_X), 2);
-         OUT_RING  (chan, src->x * cpp);
-         OUT_RING  (chan, sy);
+         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2);
+         PUSH_DATA (push, src->x * cpp);
+         PUSH_DATA (push, sy);
       } else {
          src_ofst += line_count * src->pitch;
       }
       if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) {
-         BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2);
-         OUT_RING  (chan, dst->x * cpp);
-         OUT_RING  (chan, dy);
+         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2);
+         PUSH_DATA (push, dst->x * cpp);
+         PUSH_DATA (push, dy);
       } else {
          dst_ofst += line_count * dst->pitch;
       }
 
-      BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
-      OUT_RING  (chan, nblocksx * cpp);
-      OUT_RING  (chan, line_count);
-      BEGIN_RING(chan, RING_MF(EXEC), 1);
-      OUT_RING  (chan, exec);
+      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+      PUSH_DATA (push, nblocksx * cpp);
+      PUSH_DATA (push, line_count);
+      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+      PUSH_DATA (push, exec);
 
       height -= line_count;
       sy += line_count;
       dy += line_count;
    }
+
+   nouveau_bufctx_reset(bctx, 0);
 }
 
 void
@@ -107,36 +113,44 @@ nvc0_m2mf_push_linear(struct nouveau_context *nv,
                       struct nouveau_bo *dst, unsigned offset, unsigned domain,
                       unsigned size, const void *data)
 {
-   struct nouveau_channel *chan = nv->screen->channel;
+   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
+   struct nouveau_pushbuf *push = nv->pushbuf;
    uint32_t *src = (uint32_t *)data;
    unsigned count = (size + 3) / 4;
 
+   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
+   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
+   nouveau_pushbuf_validate(push);
+
    while (count) {
       unsigned nr;
 
-      MARK_RING (chan, 16, 2);
-
-      nr = AVAIL_RING(chan) - 9;
-      nr = MIN2(count, nr);
+      if (!PUSH_SPACE(push, 16))
+         break;
+      nr = PUSH_AVAIL(push);
+      assert(nr >= 16);
+      nr = MIN2(count, nr - 9);
       nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
 
-      BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
-      OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
-      OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
-      BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
-      OUT_RING  (chan, nr * 4);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_MF(EXEC), 1);
-      OUT_RING  (chan, 0x100111);
+      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+      PUSH_DATAh(push, dst->offset + offset);
+      PUSH_DATA (push, dst->offset + offset);
+      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+      PUSH_DATA (push, nr * 4);
+      PUSH_DATA (push, 1);
+      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+      PUSH_DATA (push, 0x100111);
 
       /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
-      BEGIN_RING_NI(chan, RING_MF(DATA), nr);
-      OUT_RINGp (chan, src, nr);
+      BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);
+      PUSH_DATAp(push, src, nr);
 
       count -= nr;
       src += nr;
       offset += nr * 4;
    }
+
+   nouveau_bufctx_reset(nvc0->bufctx, 0);
 }
 
 void
@@ -145,88 +159,37 @@ nvc0_m2mf_copy_linear(struct nouveau_context *nv,
                       struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
                       unsigned size)
 {
-   struct nouveau_channel *chan = nv->screen->channel;
+   struct nouveau_pushbuf *push = nv->pushbuf;
+   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
+
+   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
+   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
+   nouveau_pushbuf_bufctx(push, bctx);
+   nouveau_pushbuf_validate(push);
 
    while (size) {
       unsigned bytes = MIN2(size, 1 << 17);
 
-      MARK_RING (chan, 11, 4);
-
-      BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
-      OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
-      OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
-      BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
-      OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
-      OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
-      BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
-      OUT_RING  (chan, bytes);
-      OUT_RING  (chan, 1);
-      BEGIN_RING(chan, RING_MF(EXEC), 1);
-      OUT_RING  (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
+      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+      PUSH_DATAh(push, dst->offset + dstoff);
+      PUSH_DATA (push, dst->offset + dstoff);
+      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
+      PUSH_DATAh(push, src->offset + srcoff);
+      PUSH_DATA (push, src->offset + srcoff);
+      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+      PUSH_DATA (push, bytes);
+      PUSH_DATA (push, 1);
+      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+      PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
                  NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT);
 
       srcoff += bytes;
       dstoff += bytes;
       size -= bytes;
    }
-}
-
-#if 0
-static void
-nvc0_m2mf_push_rect(struct pipe_screen *pscreen,
-                    const struct nv50_m2mf_rect *dst,
-                    const void *data,
-                    unsigned nblocksx, unsigned nblocksy)
-{
-   struct nouveau_channel *chan;
-   const uint8_t *src = (const uint8_t *)data;
-   const int cpp = dst->cpp;
-   const int line_len = nblocksx * cpp;
-   int dy = dst->y;
-
-   assert(nouveau_bo_tile_layout(dst->bo));
-
-   BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5);
-   OUT_RING  (chan, dst->tile_mode);
-   OUT_RING  (chan, dst->width * cpp);
-   OUT_RING  (chan, dst->height);
-   OUT_RING  (chan, dst->depth);
-   OUT_RING  (chan, dst->z);
-
-   while (nblocksy) {
-      int line_count, words;
-      int size = MIN2(AVAIL_RING(chan), NV04_PFIFO_MAX_PACKET_LEN);
 
-      if (size < (12 + words)) {
-         FIRE_RING(chan);
-         continue;
-      }
-      line_count = (size * 4) / line_len;
-      words = (line_count * line_len + 3) / 4;
-
-      BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
-      OUT_RELOCh(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR);
-      OUT_RELOCl(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR);
-
-      BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2);
-      OUT_RING  (chan, dst->x * cpp);
-      OUT_RING  (chan, dy);
-      BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
-      OUT_RING  (chan, line_len);
-      OUT_RING  (chan, line_count);
-      BEGIN_RING(chan, RING_MF(EXEC), 1);
-      OUT_RING  (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
-                 NVC0_M2MF_EXEC_PUSH | NVC0_M2MF_EXEC_LINEAR_IN);
-
-      BEGIN_RING_NI(chan, RING_MF(DATA), words);
-      OUT_RINGp (chan, src, words);
-
-      dy += line_count;
-      src += line_len * line_count;
-      nblocksy -= line_count;
-   }
+   nouveau_bufctx_reset(bctx, 0);
 }
-#endif
 
 struct pipe_transfer *
 nvc0_miptree_transfer_new(struct pipe_context *pctx,
@@ -236,7 +199,6 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
                           const struct pipe_box *box)
 {
    struct nvc0_context *nvc0 = nvc0_context(pctx);
-   struct pipe_screen *pscreen = pctx->screen;
    struct nouveau_device *dev = nvc0->screen->base.device;
    struct nv50_miptree *mt = nv50_miptree(res);
    struct nvc0_transfer *tx;
@@ -273,7 +235,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
    size = tx->base.layer_stride;
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
-                        size * tx->nlayers, &tx->rect[1].bo);
+                        size * tx->nlayers, NULL, &tx->rect[1].bo);
    if (ret) {
       FREE(tx);
       return NULL;
@@ -291,7 +253,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
       unsigned z = tx->rect[0].z;
       unsigned i;
       for (i = 0; i < tx->nlayers; ++i) {
-         nvc0_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
+         nvc0_m2mf_transfer_rect(nvc0, &tx->rect[1], &tx->rect[0],
                                  tx->nblocksx, tx->nblocksy);
          if (mt->layout_3d)
             tx->rect[0].z++;
@@ -311,14 +273,14 @@ void
 nvc0_miptree_transfer_del(struct pipe_context *pctx,
                           struct pipe_transfer *transfer)
 {
-   struct pipe_screen *pscreen = pctx->screen;
+   struct nvc0_context *nvc0 = nvc0_context(pctx);
    struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
    struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
    unsigned i;
 
    if (tx->base.usage & PIPE_TRANSFER_WRITE) {
       for (i = 0; i < tx->nlayers; ++i) {
-         nvc0_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
+         nvc0_m2mf_transfer_rect(nvc0, &tx->rect[0], &tx->rect[1],
                                  tx->nblocksx, tx->nblocksy);
          if (mt->layout_3d)
             tx->rect[0].z++;
@@ -338,6 +300,7 @@ void *
 nvc0_miptree_transfer_map(struct pipe_context *pctx,
                           struct pipe_transfer *transfer)
 {
+   struct nvc0_context *nvc0 = nvc0_context(pctx);
    struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
    int ret;
    unsigned flags = 0;
@@ -350,7 +313,7 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
    if (transfer->usage & PIPE_TRANSFER_WRITE)
       flags |= NOUVEAU_BO_WR;
 
-   ret = nouveau_bo_map(tx->rect[1].bo, flags);
+   ret = nouveau_bo_map(tx->rect[1].bo, flags, nvc0->screen->base.client);
    if (ret)
       return NULL;
    return tx->rect[1].bo->map;
@@ -360,9 +323,6 @@ void
 nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
                             struct pipe_transfer *transfer)
 {
-   struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
-
-   nouveau_bo_unmap(tx->rect[1].bo);
 }
 
 void
@@ -371,33 +331,34 @@ nvc0_cb_push(struct nouveau_context *nv,
              unsigned base, unsigned size,
              unsigned offset, unsigned words, const uint32_t *data)
 {
-   struct nouveau_channel *chan = nv->screen->channel;
+   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
+   struct nouveau_pushbuf *push = nv->pushbuf;
 
    assert(!(offset & 3));
    size = align(size, 0x100);
 
-   MARK_RING (chan, 16, 2);
-   BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
-   OUT_RING  (chan, size);
-   OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR);
+   nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
+   nouveau_pushbuf_bufctx(push, bctx);
+   nouveau_pushbuf_validate(push);
+
+   BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+   PUSH_DATA (push, size);
+   PUSH_DATAh(push, bo->offset + base);
+   PUSH_DATA (push, bo->offset + base);
 
    while (words) {
-      unsigned nr = AVAIL_RING(chan);
+      unsigned nr = PUSH_AVAIL(push);
       nr = MIN2(nr, words);
       nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
 
-      BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1);
-      OUT_RING  (chan, offset);
-      OUT_RINGp (chan, data, nr);
+      BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
+      PUSH_DATA (push, offset);
+      PUSH_DATAp(push, data, nr);
 
       words -= nr;
       data += nr;
       offset += nr * 4;
-
-      if (words) {
-         MARK_RING(chan, 6, 1);
-         nouveau_bo_validate(chan, bo, domain | NOUVEAU_BO_WR);
-      }
    }
+
+   nouveau_bufctx_reset(bctx, 0);
 }
index de456b91945273e6fce7c813aeadfbd5e0c76193..fbdc5d25d58488ebf39e83cf3c340ccff169684b 100644 (file)
@@ -20,6 +20,8 @@
  * SOFTWARE.
  */
 
+#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
@@ -128,7 +130,7 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb,
                   struct pipe_vertex_element *ve, unsigned attr)
 {
    const void *data;
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nv04_resource *res = nv04_resource(vb->buffer);
    float v[4];
    int i;
@@ -139,10 +141,11 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb,
 
    util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1);
 
-   BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), nc + 1);
-   OUT_RING  (chan, VTX_ATTR(attr, nc, FLOAT, 32));
+   PUSH_SPACE(push, 6);
+   BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), nc + 1);
+   PUSH_DATA (push, VTX_ATTR(attr, nc, FLOAT, 32));
    for (i = 0; i < nc; ++i)
-      OUT_RINGf(chan, v[i]);
+      PUSH_DATAf(push, v[i]);
 }
 
 static INLINE void
@@ -171,7 +174,7 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
 
    nvc0->vbo_fifo = nvc0->vbo_user = 0;
 
-   nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
+   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
 
    for (i = 0; i < nvc0->num_vtxbufs; ++i) {
       vb = &nvc0->vtxbuf[i];
@@ -189,33 +192,41 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
                nvc0->vbo_user |= 1 << i;
                assert(vb->stride > vb->buffer_offset);
                nvc0_vbuf_range(nvc0, i, &base, &size);
-               nouveau_user_buffer_upload(buf, base, size);
+               nouveau_user_buffer_upload(&nvc0->base, buf, base, size);
             } else {
                nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART);
             }
             nvc0->base.vbo_dirty = TRUE;
          }
       }
-      nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
+      BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
    }
 }
 
 static void
 nvc0_update_user_vbufs(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    uint32_t base, offset, size;
    int i;
    uint32_t written = 0;
 
+   /* TODO: use separate bufctx bin for user buffers
+    */
+   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
+
+   PUSH_SPACE(push, nvc0->vertex->num_elements * 8);
+
    for (i = 0; i < nvc0->vertex->num_elements; ++i) {
       struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe;
       const int b = ve->vertex_buffer_index;
       struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b];
       struct nv04_resource *buf = nv04_resource(vb->buffer);
 
-      if (!(nvc0->vbo_user & (1 << b)))
+      if (!(nvc0->vbo_user & (1 << b))) {
+         BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
          continue;
+      }
 
       if (!vb->stride) {
          nvc0_emit_vtxattr(nvc0, vb, ve, i);
@@ -225,17 +236,18 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0)
 
       if (!(written & (1 << b))) {
          written |= 1 << b;
-         nouveau_user_buffer_upload(buf, base, size);
+         nouveau_user_buffer_upload(&nvc0->base, buf, base, size);
       }
       offset = vb->buffer_offset + ve->src_offset;
 
-      MARK_RING (chan, 6, 4);
-      BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
-      OUT_RING  (chan, i);
-      OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
+      BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5);
+      PUSH_DATA (push, i);
+      PUSH_DATAh(push, buf->address + base + size - 1);
+      PUSH_DATA (push, buf->address + base + size - 1);
+      PUSH_DATAh(push, buf->address + offset);
+      PUSH_DATA (push, buf->address + offset);
+
+      BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
    }
    nvc0->base.vbo_dirty = TRUE;
 }
@@ -256,7 +268,7 @@ nvc0_release_user_vbufs(struct nvc0_context *nvc0)
 void
 nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_vertex_stateobj *vertex = nvc0->vertex;
    struct pipe_vertex_buffer *vb;
    struct nvc0_vertex_element *ve;
@@ -270,19 +282,21 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
       nvc0_prevalidate_vbufs(nvc0);
    }
 
-   BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
+   PUSH_SPACE(push, vertex->num_elements + 1);
+   BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
    for (i = 0; i < vertex->num_elements; ++i) {
       ve = &vertex->element[i];
       vb = &nvc0->vtxbuf[ve->pipe.vertex_buffer_index];
 
       if (likely(vb->stride) || nvc0->vbo_fifo) {
-         OUT_RING(chan, ve->state);
+         PUSH_DATA(push, ve->state);
       } else {
-         OUT_RING(chan, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
+         PUSH_DATA(push, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
          nvc0->vbo_fifo &= ~(1 << i);
       }
    }
 
+   PUSH_SPACE(push, vertex->num_elements * 16);
    for (i = 0; i < vertex->num_elements; ++i) {
       struct nv04_resource *res;
       unsigned size, offset;
@@ -292,13 +306,13 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
 
       if (unlikely(ve->pipe.instance_divisor)) {
          if (!(nvc0->state.instance_elts & (1 << i))) {
-            IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+            IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
          }
-         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
-         OUT_RING  (chan, ve->pipe.instance_divisor);
+         BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
+         PUSH_DATA (push, ve->pipe.instance_divisor);
       } else
       if (unlikely(nvc0->state.instance_elts & (1 << i))) {
-         IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
+         IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
       }
 
       res = nv04_resource(vb->buffer);
@@ -306,37 +320,58 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
       if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) {
          if (!nvc0->vbo_fifo)
             nvc0_emit_vtxattr(nvc0, vb, &ve->pipe, i);
-         BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
-         OUT_RING  (chan, 0);
+         BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
+         PUSH_DATA (push, 0);
          continue;
       }
 
       size = vb->buffer->width0;
       offset = ve->pipe.src_offset + vb->buffer_offset;
 
-      MARK_RING (chan, 8, 4);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
-      OUT_RING  (chan, (1 << 12) | vb->stride);
-      BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
-      OUT_RING  (chan, i);
-      OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
+      PUSH_DATA (push, (1 << 12) | vb->stride);
+      BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5);
+      PUSH_DATA (push, i);
+      PUSH_DATAh(push, res->address + size - 1);
+      PUSH_DATA (push, res->address + size - 1);
+      PUSH_DATAh(push, res->address + offset);
+      PUSH_DATA (push, res->address + offset);
    }
    for (; i < nvc0->state.num_vtxelts; ++i) {
-      BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(i)), 1);
-      OUT_RING  (chan, NVC0_3D_VERTEX_ATTRIB_INACTIVE);
+      PUSH_SPACE(push, 5);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(i)), 1);
+      PUSH_DATA (push, NVC0_3D_VERTEX_ATTRIB_INACTIVE);
       if (unlikely(nvc0->state.instance_elts & (1 << i)))
-         IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
-      OUT_RING  (chan, 0);
+         IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
+      PUSH_DATA (push, 0);
    }
 
    nvc0->state.num_vtxelts = vertex->num_elements;
    nvc0->state.instance_elts = vertex->instance_elts;
 }
 
+void
+nvc0_idxbuf_validate(struct nvc0_context *nvc0)
+{
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+   struct nv04_resource *buf = nv04_resource(nvc0->idxbuf.buffer);
+
+   assert(buf);
+   if (!nouveau_resource_mapped_by_gpu(&buf->base))
+      return;
+
+   PUSH_SPACE(push, 6);
+   BEGIN_NVC0(push, NVC0_3D(INDEX_ARRAY_START_HIGH), 5);
+   PUSH_DATAh(push, buf->address + nvc0->idxbuf.offset);
+   PUSH_DATA (push, buf->address + nvc0->idxbuf.offset);
+   PUSH_DATAh(push, buf->address + buf->base.width0 - 1);
+   PUSH_DATA (push, buf->address + buf->base.width0 - 1);
+   PUSH_DATA (push, nvc0->idxbuf.index_size >> 1);
+
+   BCTX_REFN(nvc0->bufctx_3d, IDX, buf, RD);
+}
+
 #define NVC0_PRIM_GL_CASE(n) \
    case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
 
@@ -367,13 +402,11 @@ nvc0_prim_gl(unsigned prim)
 }
 
 static void
-nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan)
+nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
 {
-   struct nvc0_screen *screen = chan->user_private;
+   struct nvc0_screen *screen = push->user_priv;
 
    nouveau_fence_update(&screen->base, TRUE);
-
-   nvc0_bufctx_emit_relocs(screen->cur_ctx);
 }
 
 static void
@@ -381,47 +414,51 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
                  unsigned mode, unsigned start, unsigned count,
                  unsigned instance_count)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    unsigned prim;
 
    if (nvc0->state.index_bias) {
-      IMMED_RING(chan, RING_3D(VB_ELEMENT_BASE), 0);
+      PUSH_SPACE(push, 1);
+      IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0);
       nvc0->state.index_bias = 0;
    }
 
    prim = nvc0_prim_gl(mode);
 
    while (instance_count--) {
-      BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-      OUT_RING  (chan, prim);
-      BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2);
-      OUT_RING  (chan, start);
-      OUT_RING  (chan, count);
-      IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+      PUSH_SPACE(push, 6);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+      PUSH_DATA (push, prim);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2);
+      PUSH_DATA (push, start);
+      PUSH_DATA (push, count);
+      IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
 
       prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
 }
 
 static void
-nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
+nvc0_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
 
    if (count & 3) {
       unsigned i;
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3);
+      PUSH_SPACE(push, 4);
+      BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), count & 3);
       for (i = 0; i < (count & 3); ++i)
-         OUT_RING(chan, *map++);
+         PUSH_DATA(push, *map++);
       count &= ~3;
    }
    while (count) {
       unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr);
+      PUSH_SPACE(push, nr + 1);
+      BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U8), nr);
       for (i = 0; i < nr; ++i) {
-         OUT_RING(chan,
+         PUSH_DATA(push,
                   (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
          map += 4;
       }
@@ -430,22 +467,24 @@ nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
 }
 
 static void
-nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
+nvc0_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
 
    if (count & 1) {
       count &= ~1;
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
-      OUT_RING  (chan, *map++);
+      PUSH_SPACE(push, 2);
+      BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
    }
    while (count) {
       unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+      PUSH_SPACE(push, nr + 1);
+      BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U16), nr);
       for (i = 0; i < nr; ++i) {
-         OUT_RING(chan, (map[1] << 16) | map[0]);
+         PUSH_DATA(push, (map[1] << 16) | map[0]);
          map += 2;
       }
       count -= nr * 2;
@@ -453,7 +492,7 @@ nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
 }
 
 static void
-nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
+nvc0_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
@@ -461,8 +500,9 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
    while (count) {
       const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr);
-      OUT_RINGp    (chan, map, nr);
+      PUSH_SPACE(push, nr + 1);
+      BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), nr);
+      PUSH_DATAp(push, map, nr);
 
       map += nr;
       count -= nr;
@@ -470,22 +510,24 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
 }
 
 static void
-nvc0_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
+nvc0_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
                                     unsigned start, unsigned count)
 {
    map += start;
 
    if (count & 1) {
       count--;
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
-      OUT_RING  (chan, *map++);
+      PUSH_SPACE(push, 1);
+      BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_U32), 1);
+      PUSH_DATA (push, *map++);
    }
    while (count) {
       unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
 
-      BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+      PUSH_SPACE(push, nr + 1);
+      BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U16), nr);
       for (i = 0; i < nr; ++i) {
-         OUT_RING(chan, (map[1] << 16) | map[0]);
+         PUSH_DATA(push, (map[1] << 16) | map[0]);
          map += 2;
       }
       count -= nr * 2;
@@ -497,7 +539,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
                    unsigned mode, unsigned start, unsigned count,
                    unsigned instance_count, int32_t index_bias)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    void *data;
    unsigned prim;
    const unsigned index_size = nvc0->idxbuf.index_size;
@@ -505,34 +547,27 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
    prim = nvc0_prim_gl(mode);
 
    if (index_bias != nvc0->state.index_bias) {
-      BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
-      OUT_RING  (chan, index_bias);
+      PUSH_SPACE(push, 2);
+      BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 1);
+      PUSH_DATA (push, index_bias);
       nvc0->state.index_bias = index_bias;
    }
 
    if (nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) {
-      struct nv04_resource *res = nv04_resource(nvc0->idxbuf.buffer);
-      unsigned offset = nvc0->idxbuf.offset;
-      unsigned limit = nvc0->idxbuf.buffer->width0 - 1;
-
-      while (instance_count--) {
-         MARK_RING (chan, 11, 4);
-         BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-         OUT_RING  (chan, mode);
-         BEGIN_RING(chan, RING_3D(INDEX_ARRAY_START_HIGH), 7);
-         OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
-         OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
-         OUT_RESRCh(chan, res, limit, NOUVEAU_BO_RD);
-         OUT_RESRCl(chan, res, limit, NOUVEAU_BO_RD);
-         OUT_RING  (chan, index_size >> 1);
-         OUT_RING  (chan, start);
-         OUT_RING  (chan, count);
-         IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
-
-         nvc0_resource_fence(res, NOUVEAU_BO_RD);
-
-         mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
-      }
+      PUSH_SPACE(push, 1);
+      IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), prim);
+      do {
+         PUSH_SPACE(push, 7);
+         BEGIN_NVC0(push, NVC0_3D(INDEX_BATCH_FIRST), 2);
+         PUSH_DATA (push, start);
+         PUSH_DATA (push, count);
+         if (--instance_count) {
+            BEGIN_NVC0(push, NVC0_3D(VERTEX_END_GL), 2);
+            PUSH_DATA (push, 0);
+            PUSH_DATA (push, prim | NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT);
+         }
+      } while (instance_count);
+      IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
    } else {
       data = nouveau_resource_map_offset(&nvc0->base,
                                          nv04_resource(nvc0->idxbuf.buffer),
@@ -541,26 +576,28 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
          return;
 
       while (instance_count--) {
-         BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-         OUT_RING  (chan, prim);
+         PUSH_SPACE(push, 2);
+         BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+         PUSH_DATA (push, prim);
          switch (index_size) {
          case 1:
-            nvc0_draw_elements_inline_u08(chan, data, start, count);
+            nvc0_draw_elements_inline_u08(push, data, start, count);
             break;
          case 2:
-            nvc0_draw_elements_inline_u16(chan, data, start, count);
+            nvc0_draw_elements_inline_u16(push, data, start, count);
             break;
          case 4:
             if (shorten)
-               nvc0_draw_elements_inline_u32_short(chan, data, start, count);
+               nvc0_draw_elements_inline_u32_short(push, data, start, count);
             else
-               nvc0_draw_elements_inline_u32(chan, data, start, count);
+               nvc0_draw_elements_inline_u32(push, data, start, count);
             break;
          default:
             assert(0);
             return;
          }
-         IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+         PUSH_SPACE(push, 1);
+         IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
 
          prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
@@ -571,7 +608,7 @@ static void
 nvc0_draw_stream_output(struct nvc0_context *nvc0,
                         const struct pipe_draw_info *info)
 {
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nvc0_so_target *so = nvc0_so_target(info->count_from_stream_output);
    struct nv04_resource *res = nv04_resource(so->pipe.buffer);
    unsigned mode = nvc0_prim_gl(info->mode);
@@ -579,21 +616,23 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0,
 
    if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
       res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
-      IMMED_RING(chan, RING_3D(SERIALIZE), 0);
-      nvc0_query_fifo_wait(chan, so->pq);
-      IMMED_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 0);
+      PUSH_SPACE(push, 2);
+      IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+      nvc0_query_fifo_wait(push, so->pq);
+      IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
    }
 
    while (num_instances--) {
-      BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
-      OUT_RING  (chan, mode);
-      BEGIN_RING(chan, RING_3D(DRAW_TFB_BASE), 1);
-      OUT_RING  (chan, 0);
-      BEGIN_RING(chan, RING_3D(DRAW_TFB_STRIDE), 1);
-      OUT_RING  (chan, so->stride);
-      BEGIN_RING(chan, RING_3D(DRAW_TFB_BYTES), 1);
-      nvc0_query_pushbuf_submit(chan, so->pq, 0x4);
-      IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+      PUSH_SPACE(push, 8);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+      PUSH_DATA (push, mode);
+      BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BASE), 1);
+      PUSH_DATA (push, 0);
+      BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_STRIDE), 1);
+      PUSH_DATA (push, so->stride);
+      BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BYTES), 1);
+      nvc0_query_pushbuf_submit(push, so->pq, 0x4);
+      IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
 
       mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
@@ -603,7 +642,7 @@ void
 nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
-   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
 
    /* For picking only a few vertices from a large user buffer, push is better,
     * if index count is larger and we expect repeated vertices, suggest upload.
@@ -624,24 +663,27 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    /* 8 as minimum to avoid immediate double validation of new buffers */
    nvc0_state_validate(nvc0, ~0, 8);
 
-   chan->flush_notify = nvc0_draw_vbo_flush_notify;
+   push->kick_notify = nvc0_draw_vbo_kick_notify;
 
    if (nvc0->vbo_fifo) {
       nvc0_push_vbo(nvc0, info);
-      chan->flush_notify = nvc0_default_flush_notify;
+      push->kick_notify = nvc0_default_kick_notify;
       return;
    }
 
+   /* space for base instance, flush, and prim restart */
+   PUSH_SPACE(push, 8);
+
    if (nvc0->state.instance_base != info->start_instance) {
       nvc0->state.instance_base = info->start_instance;
       /* NOTE: this does not affect the shader input, should it ? */
-      BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1);
-      OUT_RING  (chan, info->start_instance);
+      BEGIN_NVC0(push, NVC0_3D(VB_INSTANCE_BASE), 1);
+      PUSH_DATA (push, info->start_instance);
    }
 
    if (nvc0->base.vbo_dirty) {
-      BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
-      OUT_RING  (chan, 0);
+      BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 1);
+      PUSH_DATA (push, 0);
       nvc0->base.vbo_dirty = FALSE;
    }
 
@@ -659,20 +701,20 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
       if (info->primitive_restart != nvc0->state.prim_restart) {
          if (info->primitive_restart) {
-            BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2);
-            OUT_RING  (chan, 1);
-            OUT_RING  (chan, info->restart_index);
+            BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 2);
+            PUSH_DATA (push, 1);
+            PUSH_DATA (push, info->restart_index);
 
             if (info->restart_index > 65535)
                shorten = FALSE;
          } else {
-            IMMED_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 0);
+            IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0);
          }
          nvc0->state.prim_restart = info->primitive_restart;
       } else
       if (info->primitive_restart) {
-         BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1);
-         OUT_RING  (chan, info->restart_index);
+         BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_INDEX), 1);
+         PUSH_DATA (push, info->restart_index);
 
          if (info->restart_index > 65535)
             shorten = FALSE;
@@ -682,7 +724,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                          info->mode, info->start, info->count,
                          info->instance_count, info->index_bias);
    }
-   chan->flush_notify = nvc0_default_flush_notify;
+   push->kick_notify = nvc0_default_kick_notify;
 
    nvc0_release_user_vbufs(nvc0);
 }
index 0fcf9944c1415eca81588d8541083f1bf4b473f2..c3ab1c93644110ac64a9cf52931fd25b7bcc9866 100644 (file)
 
 #include <stdint.h>
 #include <unistd.h>
-#include "pipe/p_defines.h"
 
-#include "nouveau/nouveau_bo.h"
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_grobj.h"
-#include "nouveau/nouveau_device.h"
-#include "nouveau/nouveau_resource.h"
-#include "nouveau/nouveau_pushbuf.h"
-#include "nouveau/nouveau_reloc.h"
+#include "pipe/p_defines.h"
 
-#include "nvc0_resource.h" /* OUT_RESRC */
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_buffer.h"
 
 #ifndef NV04_PFIFO_MAX_PACKET_LEN
 #define NV04_PFIFO_MAX_PACKET_LEN 2047
 #endif
 
-#define NVC0_SUBCH_3D 1
-#define NVC0_SUBCH_2D 2
-#define NVC0_SUBCH_MF 3
 
-#define NVC0_MF_(n) NVC0_M2MF_##n
+static INLINE void
+nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin,
+                            unsigned flags, struct nouveau_bo *bo)
+{
+   nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL;
+}
+
+static INLINE void
+nvc0_add_resident(struct nouveau_bufctx *bufctx, int bin,
+                  struct nv04_resource *res, unsigned flags)
+{
+   struct nouveau_bufref *ref =
+      nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain);
+   ref->priv = res;
+   ref->priv_data = flags;
+}
+
+#define BCTX_REFN_bo(ctx, bin, fl, bo) \
+   nv50_add_bufctx_resident_bo(ctx, NVC0_BIND_##bin, fl, bo);
+
+#define BCTX_REFN(bctx, bin, res, acc) \
+   nvc0_add_resident(bctx, NVC0_BIND_##bin, res, NOUVEAU_BO_##acc)
+
+static INLINE void
+PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
+{
+   struct nouveau_pushbuf_refn ref = { bo, flags };
+   nouveau_pushbuf_refn(push, &ref, 1);
+}
+
 
-#define RING_3D(n) ((NVC0_SUBCH_3D << 13) | (NVC0_3D_##n >> 2))
-#define RING_2D(n) ((NVC0_SUBCH_2D << 13) | (NVC0_2D_##n >> 2))
-#define RING_MF(n) ((NVC0_SUBCH_MF << 13) | (NVC0_MF_(n) >> 2))
+#define SUBC_3D(m) 1, (m)
+#define NVC0_3D(n) SUBC_3D(NVC0_3D_##n)
 
-#define RING_3D_(m) ((NVC0_SUBCH_3D << 13) | ((m) >> 2))
-#define RING_2D_(m) ((NVC0_SUBCH_2D << 13) | ((m) >> 2))
-#define RING_MF_(m) ((NVC0_SUBCH_MF << 13) | ((m) >> 2))
+#define SUBC_2D(m) 2, (m)
+#define NVC0_2D(n) SUBC_2D(NVC0_2D_##n)
 
-#define RING_GR(gr, m) (((gr)->subc << 13) | ((m) >> 2))
+#define SUBC_M2MF(m) 3, (m)
+#define NVC0_M2MF(n) SUBC_M2MF(NVC0_M2MF_##n)
 
-int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
+#define SUBC_COMPUTE(m) 4, (m)
+#define NVC0_COMPUTE(n) SUBC_COMPUTE(NVC0_COMPUTE_##n)
 
-static inline uint32_t
-nouveau_bo_tile_layout(const struct nouveau_bo *bo)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_SQ(int subc, int mthd, unsigned size)
 {
-   return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
+   return 0x20000000 | (size << 16) | (subc << 13) | (mthd >> 2);
 }
 
-static INLINE void
-nouveau_bo_validate(struct nouveau_channel *chan,
-                    struct nouveau_bo *bo, unsigned flags)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
 {
-   nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
+   return 0x60000000 | (size << 16) | (subc << 13) | (mthd >> 2);
 }
 
-/* incremental methods */
-static INLINE void
-BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint8_t data)
 {
-   WAIT_RING(chan, size + 1);
-   OUT_RING (chan, (0x2 << 28) | (size << 16) | mthd);
+   return 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2);
 }
 
-/* non-incremental */
-static INLINE void
-BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_1I(int subc, int mthd, unsigned size)
 {
-   WAIT_RING(chan, size + 1);
-   OUT_RING (chan, (0x6 << 28) | (size << 16) | mthd);
+   return 0xa0000000 | (size << 16) | (subc << 13) | (mthd >> 2);
 }
 
-/* increment-once */
-static INLINE void
-BEGIN_RING_1I(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+
+static INLINE uint8_t
+nouveau_bo_memtype(const struct nouveau_bo *bo)
 {
-   WAIT_RING(chan, size + 1);
-   OUT_RING (chan, (0xa << 28) | (size << 16) | mthd);
+   return bo->config.nvc0.memtype;
 }
 
-/* inline-data */
+
 static INLINE void
-IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data)
+PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data)
 {
-   WAIT_RING(chan, 1);
-   OUT_RING (chan, (0x8 << 28) | (data << 16) | mthd);
+   *push->cur++ = (uint32_t)(data >> 32);
 }
 
-static INLINE int
-OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
-           unsigned delta, unsigned flags)
+static INLINE void
+BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
 {
-   return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, size + 1);
+#endif
+   PUSH_DATA (push, NVC0_FIFO_PKHDR_SQ(subc, mthd, size));
 }
 
-static INLINE int
-OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
-           unsigned delta, unsigned flags)
+static INLINE void
+BEGIN_NIC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
 {
-   if (flags & NOUVEAU_BO_WR)
-      res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
-   return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, size + 1);
+#endif
+   PUSH_DATA (push, NVC0_FIFO_PKHDR_NI(subc, mthd, size));
 }
 
 static INLINE void
-BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
+BEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
 {
-   struct nouveau_subchannel *subc = &gr->channel->subc[s];
-
-   assert(s < 8);
-   if (subc->gr) {
-      assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT);
-      subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
-   }
-   subc->gr = gr;
-   subc->gr->subc = s;
-   subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
-
-   BEGIN_RING(chan, RING_GR(gr, 0x0000), 1);
-   OUT_RING  (chan, gr->grclass);
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, size + 1);
+#endif
+   PUSH_DATA (push, NVC0_FIFO_PKHDR_1I(subc, mthd, size));
 }
 
+static INLINE void
+IMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, uint8_t data)
+{
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+   PUSH_SPACE(push, 1);
 #endif
+   PUSH_DATA (push, NVC0_FIFO_PKHDR_IL(subc, mthd, data));
+}
+
+#endif /* __NVC0_WINSYS_H__ */
index 0cbcc4b2a93943c3db6906daca51dc4bd13f197e..017e92ece9cc2528b07c144ac91c4c4fd9c73aae 100644 (file)
@@ -6,10 +6,6 @@
 
 #include "nouveau_drm_public.h"
 
-#include "nouveau_drmif.h"
-#include "nouveau_channel.h"
-#include "nouveau_bo.h"
-
 #include "nouveau/nouveau_winsys.h"
 #include "nouveau/nouveau_screen.h"
 
@@ -20,7 +16,7 @@ nouveau_drm_screen_create(int fd)
        struct pipe_screen *(*init)(struct nouveau_device *);
        int ret;
 
-       ret = nouveau_device_open_existing(&dev, 0, fd, 0);
+       ret = nouveau_device_wrap(fd, 0, &dev);
        if (ret)
                return NULL;