nv50: move onto common linear buffer manager
authorBen Skeggs <bskeggs@redhat.com>
Tue, 1 Mar 2011 02:26:20 +0000 (12:26 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 1 Mar 2011 04:44:43 +0000 (14:44 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
16 files changed:
src/gallium/drivers/nouveau/nouveau_buffer.h
src/gallium/drivers/nv50/Makefile
src/gallium/drivers/nv50/nv50_buffer.c [deleted file]
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_push.c
src/gallium/drivers/nv50/nv50_resource.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_tex.c
src/gallium/drivers/nv50/nv50_transfer.c
src/gallium/drivers/nv50/nv50_vbo.c
src/gallium/drivers/nv50/nv50_winsys.h

index e0d75dcc9f9a3ae3e90cf567f88e7101d1b1592b..d75bc4e0c389eb6486a0567872c692095c3b46f8 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __NOUVEAU_RESOURCE_H__
-#define __NOUVEAU_RESOURCE_H__
+#ifndef __NOUVEAU_BUFFER_H__
+#define __NOUVEAU_BUFFER_H__
 
 #include "util/u_transfer.h"
 #include "util/u_double_list.h"
index dc9ea0eeba7b0b1ad5952d801e4e5e873f0ec004..02bcc26cfb38b82cd09a7eb1ebf7f0ca98791018 100644 (file)
@@ -4,7 +4,6 @@ include $(TOP)/configs/current
 LIBNAME = nv50
 
 C_SOURCES = \
-       nv50_buffer.c \
        nv50_context.c \
        nv50_draw.c \
        nv50_formats.c \
diff --git a/src/gallium/drivers/nv50/nv50_buffer.c b/src/gallium/drivers/nv50/nv50_buffer.c
deleted file mode 100644 (file)
index ae65591..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-
-#include "util/u_inlines.h"
-#include "util/u_memory.h"
-#include "util/u_math.h"
-
-#define NOUVEAU_NVC0
-#include "nouveau/nouveau_screen.h"
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau/nouveau_mm.h"
-#undef NOUVEAU_NVC0
-
-#include "nv50_context.h"
-#include "nv50_resource.h"
-
-struct nv50_transfer {
-   struct pipe_transfer base;
-};
-
-static INLINE struct nv50_transfer *
-nv50_transfer(struct pipe_transfer *transfer)
-{
-   return (struct nv50_transfer *)transfer;
-}
-
-static INLINE boolean
-nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf,
-                     unsigned domain)
-{
-   if (domain == NOUVEAU_BO_VRAM) {
-      buf->mm = nouveau_mm_allocate(screen->base.mm_VRAM, buf->base.width0,
-                                    &buf->bo, &buf->offset);
-      if (!buf->bo)
-         return nv50_buffer_allocate(screen, buf, NOUVEAU_BO_GART);
-   } else
-   if (domain == NOUVEAU_BO_GART) {
-      buf->mm = nouveau_mm_allocate(screen->base.mm_GART, buf->base.width0,
-                                    &buf->bo, &buf->offset);
-      if (!buf->bo)
-         return FALSE;
-   }
-   if (domain != NOUVEAU_BO_GART) {
-      if (!buf->data) {
-         buf->data = MALLOC(buf->base.width0);
-         if (!buf->data)
-            return FALSE;
-      }
-   }
-   buf->domain = domain;
-   return TRUE;
-}
-
-static INLINE void
-release_allocation(struct nouveau_mm_allocation **mm, struct nouveau_fence *fence)
-{
-   nouveau_fence_work(fence, nouveau_mm_free_work, *mm);
-   (*mm) = NULL;
-}
-
-INLINE void
-nv50_buffer_release_gpu_storage(struct nv50_resource *buf)
-{
-   nouveau_bo_ref(NULL, &buf->bo);
-
-   if (buf->mm)
-      release_allocation(&buf->mm, buf->fence);
-
-   buf->domain = 0;
-}
-
-static INLINE boolean
-nv50_buffer_reallocate(struct nv50_screen *screen, struct nv50_resource *buf,
-                       unsigned domain)
-{
-   nv50_buffer_release_gpu_storage(buf);
-
-   return nv50_buffer_allocate(screen, buf, domain);
-}
-
-static void
-nv50_buffer_destroy(struct pipe_screen *pscreen,
-                    struct pipe_resource *presource)
-{
-   struct nv50_resource *res = nv50_resource(presource);
-
-   nv50_buffer_release_gpu_storage(res);
-
-   if (res->data && !(res->status & NV50_BUFFER_STATUS_USER_MEMORY))
-      FREE(res->data);
-
-   FREE(res);
-}
-
-/* Maybe just migrate to GART right away if we actually need to do this. */
-boolean
-nv50_buffer_download(struct nv50_context *nv50, struct nv50_resource *buf,
-                     unsigned start, unsigned size)
-{
-   struct nouveau_mm_allocation *mm;
-   struct nouveau_bo *bounce = NULL;
-   uint32_t offset;
-
-   assert(buf->domain == NOUVEAU_BO_VRAM);
-
-   mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset);
-   if (!bounce)
-      return FALSE;
-
-   nv50_m2mf_copy_linear(nv50, 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))
-      return FALSE;
-   memcpy(buf->data + start, bounce->map, size);
-   nouveau_bo_unmap(bounce);
-
-   buf->status &= ~NV50_BUFFER_STATUS_DIRTY;
-
-   nouveau_bo_ref(NULL, &bounce);
-   if (mm)
-      nouveau_mm_free(mm);
-   return TRUE;
-}
-
-static boolean
-nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf,
-                   unsigned start, unsigned size)
-{
-   struct nouveau_mm_allocation *mm;
-   struct nouveau_bo *bounce = NULL;
-   uint32_t offset;
-
-   if (size <= 192) {
-      nv50_sifc_linear_u8(nv50, buf->bo, buf->domain, buf->offset + start,
-                          size, buf->data + start);
-      return TRUE;
-   }
-
-   mm = nouveau_mm_allocate(nv50->screen->base.mm_GART, size, &bounce, &offset);
-   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);
-
-   nv50_m2mf_copy_linear(nv50, buf->bo, buf->offset + start, NOUVEAU_BO_VRAM,
-                         bounce, offset, NOUVEAU_BO_GART, size);
-
-   nouveau_bo_ref(NULL, &bounce);
-   if (mm)
-      release_allocation(&mm, nv50->screen->base.fence.current);
-
-   if (start == 0 && size == buf->base.width0)
-      buf->status &= ~NV50_BUFFER_STATUS_DIRTY;
-   return TRUE;
-}
-
-static struct pipe_transfer *
-nv50_buffer_transfer_get(struct pipe_context *pipe,
-                         struct pipe_resource *resource,
-                         unsigned level,
-                         unsigned usage,
-                         const struct pipe_box *box)
-{
-   struct nv50_resource *buf = nv50_resource(resource);
-   struct nv50_transfer *xfr = CALLOC_STRUCT(nv50_transfer);
-   if (!xfr)
-      return NULL;
-
-   xfr->base.resource = resource;
-   xfr->base.box.x = box->x;
-   xfr->base.box.width = box->width;
-   xfr->base.usage = usage;
-
-   if (buf->domain == NOUVEAU_BO_VRAM) {
-      if (usage & PIPE_TRANSFER_READ) {
-         if (buf->status & NV50_BUFFER_STATUS_DIRTY)
-            nv50_buffer_download(nv50_context(pipe), buf, 0, buf->base.width0);
-      }
-   }
-
-   return &xfr->base;
-}
-
-static void
-nv50_buffer_transfer_destroy(struct pipe_context *pipe,
-                             struct pipe_transfer *transfer)
-{
-   struct nv50_resource *buf = nv50_resource(transfer->resource);
-   struct nv50_transfer *xfr = nv50_transfer(transfer);
-
-   if (xfr->base.usage & PIPE_TRANSFER_WRITE) {
-      /* writing is worse */
-      nv50_buffer_adjust_score(nv50_context(pipe), buf, -5000);
-
-      if (buf->domain == NOUVEAU_BO_VRAM) {
-         nv50_buffer_upload(nv50_context(pipe), buf,
-                            transfer->box.x, transfer->box.width);
-      }
-
-      if (buf->domain != 0 && (buf->base.bind & (PIPE_BIND_VERTEX_BUFFER |
-                                                 PIPE_BIND_INDEX_BUFFER)))
-         nv50_context(pipe)->vbo_dirty = TRUE;
-   }
-
-   FREE(xfr);
-}
-
-static INLINE boolean
-nv50_buffer_sync(struct nv50_resource *buf, unsigned rw)
-{
-   if (rw == PIPE_TRANSFER_READ) {
-      if (!buf->fence_wr)
-         return TRUE;
-      if (!nouveau_fence_wait(buf->fence_wr))
-         return FALSE;
-   } else {
-      if (!buf->fence)
-         return TRUE;
-      if (!nouveau_fence_wait(buf->fence))
-         return FALSE;
-
-      nouveau_fence_ref(NULL, &buf->fence);
-   }
-   nouveau_fence_ref(NULL, &buf->fence_wr);
-
-   return TRUE;
-}
-
-static INLINE boolean
-nv50_buffer_busy(struct nv50_resource *buf, unsigned rw)
-{
-   if (rw == PIPE_TRANSFER_READ)
-      return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr));
-   else
-      return (buf->fence && !nouveau_fence_signalled(buf->fence));
-}
-
-static void *
-nv50_buffer_transfer_map(struct pipe_context *pipe,
-                         struct pipe_transfer *transfer)
-{
-   struct nv50_transfer *xfr = nv50_transfer(transfer);
-   struct nv50_resource *buf = nv50_resource(transfer->resource);
-   struct nouveau_bo *bo = buf->bo;
-   uint8_t *map;
-   int ret;
-   uint32_t offset = xfr->base.box.x;
-   uint32_t flags;
-
-   nv50_buffer_adjust_score(nv50_context(pipe), buf, -250);
-
-   if (buf->domain != NOUVEAU_BO_GART)
-      return buf->data + offset;
-
-   if (buf->mm)
-      flags = NOUVEAU_BO_NOSYNC | NOUVEAU_BO_RDWR;
-   else
-      flags = nouveau_screen_transfer_flags(xfr->base.usage);
-
-   offset += buf->offset;
-
-   ret = nouveau_bo_map_range(buf->bo, offset, xfr->base.box.width, flags);
-   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);
-
-   if (buf->mm) {
-      if (xfr->base.usage & PIPE_TRANSFER_DONTBLOCK) {
-         if (nv50_buffer_busy(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE))
-            return NULL;
-      } else
-      if (!(xfr->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
-         nv50_buffer_sync(buf, xfr->base.usage & PIPE_TRANSFER_READ_WRITE);
-      }
-   }
-   return map;
-}
-
-
-
-static void
-nv50_buffer_transfer_flush_region(struct pipe_context *pipe,
-                                  struct pipe_transfer *transfer,
-                                  const struct pipe_box *box)
-{
-   struct nv50_resource *res = nv50_resource(transfer->resource);
-   struct nouveau_bo *bo = res->bo;
-   unsigned offset = res->offset + transfer->box.x + box->x;
-
-   /* not using non-snoop system memory yet, no need for cflush */
-   if (1)
-      return;
-
-   /* XXX: maybe need to upload for VRAM buffers here */
-
-   nouveau_screen_bo_map_flush_range(pipe->screen, bo, offset, box->width);
-}
-
-static void
-nv50_buffer_transfer_unmap(struct pipe_context *pipe,
-                           struct pipe_transfer *transfer)
-{
-   /* we've called nouveau_bo_unmap right after map */
-}
-
-const struct u_resource_vtbl nv50_buffer_vtbl =
-{
-   u_default_resource_get_handle,     /* get_handle */
-   nv50_buffer_destroy,               /* resource_destroy */
-   NULL,                              /* is_resource_referenced */
-   nv50_buffer_transfer_get,          /* get_transfer */
-   nv50_buffer_transfer_destroy,      /* transfer_destroy */
-   nv50_buffer_transfer_map,          /* transfer_map */
-   nv50_buffer_transfer_flush_region, /* transfer_flush_region */
-   nv50_buffer_transfer_unmap,        /* transfer_unmap */
-   u_default_transfer_inline_write    /* transfer_inline_write */
-};
-
-struct pipe_resource *
-nv50_buffer_create(struct pipe_screen *pscreen,
-                   const struct pipe_resource *templ)
-{
-   struct nv50_screen *screen = nv50_screen(pscreen);
-   struct nv50_resource *buffer;
-   boolean ret;
-
-   buffer = CALLOC_STRUCT(nv50_resource);
-   if (!buffer)
-      return NULL;
-
-   buffer->base = *templ;
-   buffer->vtbl = &nv50_buffer_vtbl;
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->base.screen = pscreen;
-
-   if (buffer->base.bind & PIPE_BIND_CONSTANT_BUFFER)
-      ret = nv50_buffer_allocate(screen, buffer, 0);
-   else
-      ret = nv50_buffer_allocate(screen, buffer, NOUVEAU_BO_GART);
-
-   if (ret == FALSE)
-      goto fail;
-
-   return &buffer->base;
-
-fail:
-   FREE(buffer);
-   return NULL;
-}
-
-
-struct pipe_resource *
-nv50_user_buffer_create(struct pipe_screen *pscreen,
-                        void *ptr,
-                        unsigned bytes,
-                        unsigned bind)
-{
-   struct nv50_resource *buffer;
-
-   buffer = CALLOC_STRUCT(nv50_resource);
-   if (!buffer)
-      return NULL;
-
-   pipe_reference_init(&buffer->base.reference, 1);
-   buffer->vtbl = &nv50_buffer_vtbl;
-   buffer->base.screen = pscreen;
-   buffer->base.format = PIPE_FORMAT_R8_UNORM;
-   buffer->base.usage = PIPE_USAGE_IMMUTABLE;
-   buffer->base.bind = bind;
-   buffer->base.width0 = bytes;
-   buffer->base.height0 = 1;
-   buffer->base.depth0 = 1;
-
-   buffer->data = ptr;
-   buffer->status = NV50_BUFFER_STATUS_USER_MEMORY;
-
-   return &buffer->base;
-}
-
-/* Like download, but for GART buffers. Merge ? */
-static INLINE boolean
-nv50_buffer_data_fetch(struct nv50_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))
-      return FALSE;
-   memcpy(buf->data, bo->map, size);
-   nouveau_bo_unmap(bo);
-
-   return TRUE;
-}
-
-/* Migrate a linear buffer (vertex, index, constants) USER -> GART -> VRAM. */
-boolean
-nv50_buffer_migrate(struct nv50_context *nv50,
-                    struct nv50_resource *buf, const unsigned new_domain)
-{
-   struct nv50_screen *screen = nv50_screen(buf->base.screen);
-   struct nouveau_bo *bo;
-   const unsigned old_domain = buf->domain;
-   unsigned size = buf->base.width0;
-   unsigned offset;
-   int ret;
-
-   assert(new_domain != old_domain);
-
-   if (new_domain == NOUVEAU_BO_GART && old_domain == 0) {
-      if (!nv50_buffer_allocate(screen, buf, new_domain))
-         return FALSE;
-      ret = nouveau_bo_map_range(buf->bo, buf->offset, size, NOUVEAU_BO_WR |
-                                 NOUVEAU_BO_NOSYNC);
-      if (ret)
-         return ret;
-      memcpy(buf->bo->map, buf->data, size);
-      nouveau_bo_unmap(buf->bo);
-      FREE(buf->data);
-   } else
-   if (old_domain != 0 && new_domain != 0) {
-      struct nouveau_mm_allocation *mm = buf->mm;
-
-      if (new_domain == NOUVEAU_BO_VRAM) {
-         /* keep a system memory copy of our data in case we hit a fallback */
-         if (!nv50_buffer_data_fetch(buf, buf->bo, buf->offset, size))
-            return FALSE;
-         debug_printf("migrating %u KiB to VRAM\n", size / 1024);
-      }
-
-      offset = buf->offset;
-      bo = buf->bo;
-      buf->bo = NULL;
-      buf->mm = NULL;
-      nv50_buffer_allocate(screen, buf, new_domain);
-
-      nv50_m2mf_copy_linear(nv50, buf->bo, buf->offset, new_domain,
-                            bo, offset, old_domain, buf->base.width0);
-
-      nouveau_bo_ref(NULL, &bo);
-      if (mm)
-         release_allocation(&mm, screen->base.fence.current);
-   } else
-   if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
-      if (!nv50_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM))
-         return FALSE;
-      if (!nv50_buffer_upload(nv50, buf, 0, buf->base.width0))
-         return FALSE;
-   } else
-      return FALSE;
-
-   assert(buf->domain == new_domain);
-   return TRUE;
-}
-
-/* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART.
- * We'd like to only allocate @size bytes here, but then we'd have to rebase
- * the vertex indices ...
- */
-boolean
-nv50_user_buffer_upload(struct nv50_resource *buf, unsigned base, unsigned size)
-{
-   struct nv50_screen *screen = nv50_screen(buf->base.screen);
-   int ret;
-
-   assert(buf->status & NV50_BUFFER_STATUS_USER_MEMORY);
-
-   buf->base.width0 = base + size;
-   if (!nv50_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);
-   if (ret)
-      return FALSE;
-   memcpy(buf->bo->map, buf->data + base, size);
-   nouveau_bo_unmap(buf->bo);
-
-   return TRUE;
-}
index 4380945a1ee2eef5aa6759a6bc51ca243a37b5de..03a5c3d2d9110b311e2d3f2c676fc913883d0cfb 100644 (file)
@@ -119,13 +119,13 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
 }
 
 struct resident {
-   struct nv50_resource *res;
+   struct nv04_resource *res;
    uint32_t flags;
 };
 
 void
 nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
-                         struct nv50_resource *resource, uint32_t flags)
+                         struct nv04_resource *resource, uint32_t flags)
 {
    struct resident rsd = { resource, flags };
 
@@ -140,7 +140,7 @@ nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
 
 void
 nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
-                         struct nv50_resource *resource)
+                         struct nv04_resource *resource)
 {
    struct resident *rsd, *top;
    unsigned i;
index a6275d79587c7bfedcf760a96432b9616c38f887..55d996da27fc1292092c0b7c553efa2aea09160e 100644 (file)
@@ -155,9 +155,9 @@ void nv50_default_flush_notify(struct nouveau_channel *);
 
 void nv50_bufctx_emit_relocs(struct nv50_context *);
 void nv50_bufctx_add_resident(struct nv50_context *, int ctx,
-                              struct nv50_resource *, uint32_t flags);
+                              struct nv04_resource *, uint32_t flags);
 void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
-                              struct nv50_resource *);
+                              struct nv04_resource *);
 static INLINE void
 nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
 {
@@ -204,11 +204,11 @@ nv50_create_sampler_view(struct pipe_context *,
 
 /* nv50_transfer.c */
 void
-nv50_sifc_linear_u8(struct nv50_context *nv50,
-                    struct nouveau_bo *dst, unsigned domain, int offset,
+nv50_sifc_linear_u8(struct pipe_context *pipe,
+                    struct nouveau_bo *dst, unsigned offset, unsigned domain,
                     unsigned size, void *data);
 void
-nv50_m2mf_copy_linear(struct nv50_context *nv50,
+nv50_m2mf_copy_linear(struct pipe_context *pipe,
                       struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
                       struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
                       unsigned size);
index 51ada6d749909c008130f41e7ea75ba680b8d777..07034bdcf62a59420746a0825f9d0513471ecf4c 100644 (file)
@@ -227,10 +227,10 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
    for (i = 0; i < nv50->num_vtxbufs; ++i) {
       uint8_t *data;
       struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
-      struct nv50_resource *res = nv50_resource(vb->buffer);
+      struct nv04_resource *res = nv04_resource(vb->buffer);
 
-      data = nv50_resource_map_offset(nv50, res,
-                                      vb->buffer_offset, NOUVEAU_BO_RD);
+      data = nouveau_resource_map_offset(&nv50->pipe, res,
+                                         vb->buffer_offset, NOUVEAU_BO_RD);
 
       if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i))))
          data += info->index_bias * vb->stride;
@@ -239,9 +239,9 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
    }
 
    if (info->indexed) {
-      ctx.idxbuf = nv50_resource_map_offset(nv50,
-                                            nv50_resource(nv50->idxbuf.buffer),
-                                            nv50->idxbuf.offset, NOUVEAU_BO_RD);
+      ctx.idxbuf = nouveau_resource_map_offset(&nv50->pipe,
+                                               nv04_resource(nv50->idxbuf.buffer),
+                                               nv50->idxbuf.offset, NOUVEAU_BO_RD);
       if (!ctx.idxbuf)
          return;
       index_size = nv50->idxbuf.index_size;
@@ -285,8 +285,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
    }
 
    if (info->indexed)
-      nv50_resource_unmap(nv50_resource(nv50->idxbuf.buffer));
+      nouveau_resource_unmap(nv04_resource(nv50->idxbuf.buffer));
 
    for (i = 0; i < nv50->num_vtxbufs; ++i)
-      nv50_resource_unmap(nv50_resource(nv50->vtxbuf[i].buffer));
+      nouveau_resource_unmap(nv04_resource(nv50->vtxbuf[i].buffer));
 }
index ae1a2bf55da56d5ca078bd33c36f2ebfa74d9487..2a2fb0e32bc97a1bec0e36ad515b18c38a0a23ed 100644 (file)
@@ -8,7 +8,7 @@ nv50_resource_is_referenced(struct pipe_context *pipe,
                             struct pipe_resource *resource,
                             unsigned face, int layer)
 {
-   struct nv50_resource *res = nv50_resource(resource);
+   struct nv04_resource *res = nv04_resource(resource);
    unsigned flags = 0;
    unsigned bo_flags = nouveau_bo_pending(res->bo);
 
@@ -26,7 +26,7 @@ nv50_resource_create(struct pipe_screen *screen,
 {
    switch (templ->target) {
    case PIPE_BUFFER:
-      return nv50_buffer_create(screen, templ);
+      return nouveau_buffer_create(screen, templ);
    default:
       return nv50_miptree_create(screen, templ);
    }
@@ -64,5 +64,5 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen)
    pscreen->resource_from_handle = nv50_resource_from_handle;
    pscreen->resource_get_handle = u_resource_get_handle_vtbl;
    pscreen->resource_destroy = u_resource_destroy_vtbl;
-   pscreen->user_buffer_create = nv50_user_buffer_create;
+   pscreen->user_buffer_create = nouveau_user_buffer_create;
 }
index 64563421fd05916aeed3fb354ae03313aaf3d338..76229298f7caec123644385ed36b3d3d2c22788e 100644 (file)
 #include "util/u_double_list.h"
 #define NOUVEAU_NVC0
 #include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_buffer.h"
 #undef NOUVEAU_NVC0
 
-struct pipe_resource;
-struct nouveau_bo;
-struct nv50_context;
-
-#define NV50_BUFFER_SCORE_MIN -25000
-#define NV50_BUFFER_SCORE_MAX  25000
-#define NV50_BUFFER_SCORE_VRAM_THRESHOLD 20000
-
-/* DIRTY: buffer was (or will be after the next flush) written to by GPU and
- *  resource->data has not been updated to reflect modified VRAM contents
- *
- * USER_MEMORY: resource->data is a pointer to client memory and may change
- *  between GL calls
- */
-#define NV50_BUFFER_STATUS_DIRTY       (1 << 0)
-#define NV50_BUFFER_STATUS_USER_MEMORY (1 << 7)
-
-/* Resources, if mapped into the GPU's address space, are guaranteed to
- * have constant virtual addresses.
- * The address of a resource will lie within the nouveau_bo referenced,
- * and this bo should be added to the memory manager's validation list.
- */
-struct nv50_resource {
-   struct pipe_resource base;
-   const struct u_resource_vtbl *vtbl;
-
-   uint8_t *data;
-   struct nouveau_bo *bo;
-   uint32_t offset;
-
-   uint8_t status;
-   uint8_t domain;
-
-   int16_t score; /* low if mapped very often, if high can move to VRAM */
-
-   struct nouveau_fence *fence;
-   struct nouveau_fence *fence_wr;
-
-   struct nouveau_mm_allocation *mm;
-};
-
 void
-nv50_buffer_release_gpu_storage(struct nv50_resource *);
-
-boolean
-nv50_buffer_download(struct nv50_context *, struct nv50_resource *,
-                     unsigned start, unsigned size);
-
-boolean
-nv50_buffer_migrate(struct nv50_context *,
-                    struct nv50_resource *, unsigned domain);
-
-static INLINE void
-nv50_buffer_adjust_score(struct nv50_context *nv50, struct nv50_resource *res,
-                         int16_t score)
-{
-   if (score < 0) {
-      if (res->score > NV50_BUFFER_SCORE_MIN)
-         res->score += score;
-   } else
-   if (score > 0){
-      if (res->score < NV50_BUFFER_SCORE_MAX)
-         res->score += score;
-      if (res->domain == NOUVEAU_BO_GART &&
-          res->score > NV50_BUFFER_SCORE_VRAM_THRESHOLD)
-         nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM);
-   }
-}
-
-/* XXX: wait for fence (atm only using this for vertex push) */
-static INLINE void *
-nv50_resource_map_offset(struct nv50_context *nv50,
-                         struct nv50_resource *res, uint32_t offset,
-                         uint32_t flags)
-{
-   void *map;
-
-   nv50_buffer_adjust_score(nv50, res, -250);
-
-   if ((res->domain == NOUVEAU_BO_VRAM) &&
-       (res->status & NV50_BUFFER_STATUS_DIRTY))
-      nv50_buffer_download(nv50, res, 0, res->base.width0);
-
-   if ((res->domain != NOUVEAU_BO_GART) ||
-       (res->status & NV50_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;
-}
+nv50_init_resource_functions(struct pipe_context *pcontext);
 
-static INLINE void
-nv50_resource_unmap(struct nv50_resource *res)
-{
-   /* no-op */
-}
+void
+nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
 
 #define NV50_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf)
 
@@ -133,7 +35,7 @@ struct nv50_miptree_level {
 #define NV50_MAX_TEXTURE_LEVELS 16
 
 struct nv50_miptree {
-   struct nv50_resource base;
+   struct nv04_resource base;
    struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
    uint32_t total_size;
    uint32_t layer_stride;
@@ -146,25 +48,6 @@ nv50_miptree(struct pipe_resource *pt)
    return (struct nv50_miptree *)pt;
 }
 
-static INLINE struct nv50_resource *
-nv50_resource(struct pipe_resource *resource)
-{
-   return (struct nv50_resource *)resource;
-}
-
-/* is resource mapped into the GPU's address space (i.e. VRAM or GART) ? */
-static INLINE boolean
-nv50_resource_mapped_by_gpu(struct pipe_resource *resource)
-{
-   return nv50_resource(resource)->domain != 0;
-}
-
-void
-nv50_init_resource_functions(struct pipe_context *pcontext);
-
-void
-nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
-
 /* Internal functions:
  */
 struct pipe_resource *
@@ -176,17 +59,6 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
                          const struct pipe_resource *template,
                          struct winsys_handle *whandle);
 
-struct pipe_resource *
-nv50_buffer_create(struct pipe_screen *pscreen,
-                   const struct pipe_resource *templ);
-
-struct pipe_resource *
-nv50_user_buffer_create(struct pipe_screen *screen,
-                        void *ptr,
-                        unsigned bytes,
-                        unsigned usage);
-
-
 struct pipe_surface *
 nv50_miptree_surface_new(struct pipe_context *,
                          struct pipe_resource *,
@@ -195,7 +67,4 @@ nv50_miptree_surface_new(struct pipe_context *,
 void
 nv50_miptree_surface_del(struct pipe_context *, struct pipe_surface *);
 
-boolean
-nv50_user_buffer_upload(struct nv50_resource *, unsigned base, unsigned size);
-
 #endif
index f2b03e8156e2baecf66cee3c250b6e1fabddbe43..13c03b1a7e6a197f66d77a0521d0a9fe880058d3 100644 (file)
@@ -310,6 +310,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
    screen->base.vertex_buffer_flags = screen->base.index_buffer_flags =
       NOUVEAU_BO_GART;
+   screen->base.copy_data = nv50_m2mf_copy_linear;
+   screen->base.push_data = nv50_sifc_linear_u8;
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
                         &screen->fence.bo);
index 3bf67eb656b6a7d752bc4cb69c6cc533e68e2da0..eb9743a05d0aacb0d208529cb71982fcf8f86928 100644 (file)
@@ -73,7 +73,7 @@ int nv50_screen_tic_alloc(struct nv50_screen *, void *);
 int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
 
 static INLINE void
-nv50_resource_fence(struct nv50_resource *res, uint32_t flags)
+nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
 {
    struct nv50_screen *screen = nv50_screen(res->base.screen);
 
@@ -86,7 +86,7 @@ nv50_resource_fence(struct nv50_resource *res, uint32_t flags)
 }
 
 static INLINE void
-nv50_resource_validate(struct nv50_resource *res, uint32_t flags)
+nv50_resource_validate(struct nv04_resource *res, uint32_t flags)
 {
    struct nv50_screen *screen = nv50_screen(res->base.screen);
 
index e530b3390a9d8ae9ec1731c1b311bbf2ae6e2906..2d7572820f2a00545a621c92b47dcd0aa2009f46 100644 (file)
@@ -35,7 +35,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
    unsigned s;
 
    for (s = 0; s < 3; ++s) {
-      struct nv50_resource *res;
+      struct nv04_resource *res;
       int i;
       unsigned p, b;
 
@@ -55,7 +55,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
          i = ffs(nv50->constbuf_dirty[s]) - 1;
          nv50->constbuf_dirty[s] &= ~(1 << i);
 
-         res = nv50_resource(nv50->constbuf[s][i]);
+         res = nv04_resource(nv50->constbuf[s][i]);
          if (!res) {
             if (i != 0) {
                BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
@@ -75,8 +75,8 @@ nv50_constbufs_validate(struct nv50_context *nv50)
 
             assert(0);
 
-            if (!nv50_resource_mapped_by_gpu(&res->base)) {
-               nv50_buffer_migrate(nv50, res, NOUVEAU_BO_VRAM);
+            if (!nouveau_resource_mapped_by_gpu(&res->base)) {
+               nouveau_buffer_migrate(&nv50->pipe, res, NOUVEAU_BO_VRAM);
 
                BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1);
                OUT_RING  (chan, 0);
@@ -149,9 +149,9 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
       return FALSE;
    prog->code_base = prog->res->start;
 
-   nv50_sifc_linear_u8(nv50, nv50->screen->code, NOUVEAU_BO_VRAM,
-                       (prog->type << 16) + prog->code_base, prog->code_size,
-                       prog->code);
+   nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->code,
+                       (prog->type << 16) + 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);
index 5e1fff46e4178748d37a125909f3e6a5ed39460c..ed2fd3b0f88edf20f2e5e6a868028388b959b8e3 100644 (file)
@@ -651,8 +651,7 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
 
    if (nv50->constbuf[shader][index])
       nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
-                              nv50_resource(
-                                      nv50->constbuf[shader][index]));
+                              nv04_resource(nv50->constbuf[shader][index]));
 
    pipe_resource_reference(&nv50->constbuf[shader][index], res);
 
index 93e74ca0597098be79ad94ebd284c4f2941c3d93..eaee0a1107f9997fc435260efa011ccf41ef36eb 100644 (file)
@@ -168,7 +168,7 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
 
    for (i = 0; i < nv50->num_textures[s]; ++i) {
       struct nv50_tic_entry *tic = nv50_tic_entry(nv50->textures[s][i]);
-      struct nv50_resource *res;
+      struct nv04_resource *res;
 
       if (!tic) {
          BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
@@ -261,8 +261,9 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
       if (tsc->id < 0) {
          tsc->id = nv50_screen_tsc_alloc(nv50->screen, tsc);
 
-         nv50_sifc_linear_u8(nv50, nv50->screen->txc, NOUVEAU_BO_VRAM,
-                             65536 + tsc->id * 32, 32, tsc->tsc);
+         nv50_sifc_linear_u8(&nv50->pipe, nv50->screen->txc,
+                             65536 + tsc->id * 32,
+                             NOUVEAU_BO_VRAM, 32, tsc->tsc);
          need_flush = TRUE;
       }
       nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
index 696350d10c8b457a7226a8ea48be0b987978b055..d80a53549046b36d66e9a2c13f5a81ef60900d0d 100644 (file)
@@ -102,10 +102,11 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
 }
 
 void
-nv50_sifc_linear_u8(struct nv50_context *nv50,
-                    struct nouveau_bo *dst, unsigned domain, int offset,
+nv50_sifc_linear_u8(struct pipe_context *pipe,
+                    struct nouveau_bo *dst, unsigned offset, unsigned domain,
                     unsigned size, void *data)
 {
+   struct nv50_context *nv50 = nv50_context(pipe);
    struct nouveau_channel *chan = nv50->screen->base.channel;
    uint32_t *src = (uint32_t *)data;
    unsigned count = (size + 3) / 4;
@@ -158,11 +159,12 @@ nv50_sifc_linear_u8(struct nv50_context *nv50,
 }
 
 void
-nv50_m2mf_copy_linear(struct nv50_context *nv50,
+nv50_m2mf_copy_linear(struct pipe_context *pipe,
                       struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
                       struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
                       unsigned size)
 {
+   struct nv50_context *nv50 = nv50_context(pipe);
    struct nouveau_channel *chan = nv50->screen->base.channel;
 
    BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
index d18b2dffd1db8a4ec4f6909c2cd5740c22a23e95..1f0d34ed792d17e477ae68cc43da63f4c20e0280 100644 (file)
@@ -127,12 +127,12 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
 {
    const void *data;
    struct nouveau_channel *chan = nv50->screen->base.channel;
-   struct nv50_resource *res = nv50_resource(vb->buffer);
+   struct nv04_resource *res = nv04_resource(vb->buffer);
    float v[4];
    const unsigned nc = util_format_get_nr_components(ve->src_format);
 
-   data = nv50_resource_map_offset(nv50, res, vb->buffer_offset +
-                                   ve->src_offset, NOUVEAU_BO_RD);
+   data = nouveau_resource_map_offset(&nv50->pipe, res, vb->buffer_offset +
+                                      ve->src_offset, NOUVEAU_BO_RD);
 
    util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1);
 
@@ -189,7 +189,7 @@ static void
 nv50_prevalidate_vbufs(struct nv50_context *nv50)
 {
    struct pipe_vertex_buffer *vb;
-   struct nv50_resource *buf;
+   struct nv04_resource *buf;
    int i;
    uint32_t base, size;
 
@@ -201,27 +201,27 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
       vb = &nv50->vtxbuf[i];
       if (!vb->stride)
          continue;
-      buf = nv50_resource(vb->buffer);
+      buf = nv04_resource(vb->buffer);
 
       /* NOTE: user buffers with temporary storage count as mapped by GPU */
-      if (!nv50_resource_mapped_by_gpu(vb->buffer)) {
+      if (!nouveau_resource_mapped_by_gpu(vb->buffer)) {
          if (nv50->vbo_push_hint) {
             nv50->vbo_fifo = ~0;
             continue;
          } else {
-            if (buf->status & NV50_BUFFER_STATUS_USER_MEMORY) {
+            if (buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY) {
                nv50->vbo_user |= 1 << i;
                assert(vb->stride > vb->buffer_offset);
                nv50_vbuf_range(nv50, i, &base, &size);
-               nv50_user_buffer_upload(buf, base, size);
+               nouveau_user_buffer_upload(buf, base, size);
             } else {
-               nv50_buffer_migrate(nv50, buf, NOUVEAU_BO_GART);
+               nouveau_buffer_migrate(&nv50->pipe, buf, NOUVEAU_BO_GART);
             }
             nv50->vbo_dirty = TRUE;
          }
       }
       nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
-      nv50_buffer_adjust_score(nv50, buf, 1);
+      nouveau_buffer_adjust_score(&nv50->pipe, buf, 1);
    }
 }
 
@@ -237,7 +237,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50)
       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 nv50_resource *buf = nv50_resource(vb->buffer);
+      struct nv04_resource *buf = nv04_resource(vb->buffer);
 
       if (!(nv50->vbo_user & (1 << b)))
          continue;
@@ -250,7 +250,7 @@ nv50_update_user_vbufs(struct nv50_context *nv50)
 
       if (!(written & (1 << b))) {
          written |= 1 << b;
-         nv50_user_buffer_upload(buf, base, size);
+         nouveau_user_buffer_upload(buf, base, size);
       }
       offset = vb->buffer_offset + ve->src_offset;
 
@@ -274,7 +274,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50)
       int i = ffs(vbo_user) - 1;
       vbo_user &= ~(1 << i);
 
-      nv50_buffer_release_gpu_storage(nv50_resource(nv50->vtxbuf[i].buffer));
+      nouveau_buffer_release_gpu_storage(nv04_resource(nv50->vtxbuf[i].buffer));
    }
 }
 
@@ -308,7 +308,7 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
    }
 
    for (i = 0; i < vertex->num_elements; ++i) {
-      struct nv50_resource *res;
+      struct nv04_resource *res;
       unsigned size, offset;
       
       ve = &vertex->element[i];
@@ -327,7 +327,7 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
          OUT_RING  (chan, 0);
       }
 
-      res = nv50_resource(vb->buffer);
+      res = nv04_resource(vb->buffer);
 
       if (nv50->vbo_fifo || unlikely(vb->stride == 0)) {
          if (!nv50->vbo_fifo)
@@ -536,11 +536,11 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
       nv50->state.index_bias = index_bias;
    }
 
-   if (nv50_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) {
-      struct nv50_resource *res = nv50_resource(nv50->idxbuf.buffer);
+   if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer) && 0) {
+      struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer);
       unsigned offset = res->offset + nv50->idxbuf.offset;
 
-      nv50_buffer_adjust_score(nv50, res, 1);
+      nouveau_buffer_adjust_score(&nv50->pipe, res, 1);
 
       while (instance_count--) {
          BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
@@ -597,8 +597,9 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
          mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
    } else {
-      data = nv50_resource_map_offset(nv50, nv50_resource(nv50->idxbuf.buffer),
-                                      nv50->idxbuf.offset, NOUVEAU_BO_RD);
+      data = nouveau_resource_map_offset(&nv50->pipe,
+                                         nv04_resource(nv50->idxbuf.buffer),
+                                         nv50->idxbuf.offset, NOUVEAU_BO_RD);
       if (!data)
          return;
 
index 8aaf24c0093a61f7b1b8210701083779c509cfbc..35e79210a66e082a76285f582440eddad6511cdf 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <stdint.h>
 #include <unistd.h>
+
 #include "pipe/p_defines.h"
 
 #include "nouveau/nouveau_bo.h"
@@ -13,8 +14,9 @@
 #include "nouveau/nouveau_resource.h"
 #include "nouveau/nouveau_pushbuf.h"
 #include "nouveau/nouveau_reloc.h"
+#include "nouveau/nouveau_notifier.h"
 
-#include "nv50_resource.h" /* OUT_RESRC */
+#include "nouveau/nouveau_buffer.h"
 
 #ifndef NV04_PFIFO_MAX_PACKET_LEN
 #define NV04_PFIFO_MAX_PACKET_LEN 2047
@@ -68,18 +70,18 @@ BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
 }
 
 static INLINE int
-OUT_RESRCh(struct nouveau_channel *chan, struct nv50_resource *res,
+OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
            unsigned delta, unsigned flags)
 {
    return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
 }
 
 static INLINE int
-OUT_RESRCl(struct nouveau_channel *chan, struct nv50_resource *res,
+OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
            unsigned delta, unsigned flags)
 {
    if (flags & NOUVEAU_BO_WR)
-      res->status |= NV50_BUFFER_STATUS_DIRTY;
+      res->status |= NOUVEAU_BUFFER_STATUS_DIRTY;
    return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
 }