Mesa (refs/tags/staging-dw1): nouveau: start ripping out common stuff

Emil Velikov evelikov at kemper.freedesktop.org
Mon Sep 1 00:17:35 UTC 2014


Module: Mesa
Branch: refs/tags/staging-dw1
Commit: ca203f194bb976b743f920f5412a49c2bbe31635
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ca203f194bb976b743f920f5412a49c2bbe31635

Author: Emil Velikov <emil.l.velikov at gmail.com>
Date:   Thu Jun 13 17:16:50 2013 +0100

nouveau: start ripping out common stuff

*transfer_staging()
*buffer_cache()

Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>

---

 src/gallium/drivers/nouveau/nouveau_buffer.c |  123 +++++++++++++++++++++-----
 1 file changed, 100 insertions(+), 23 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 3696b82..2740a5f 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -1,4 +1,5 @@
 
+#include <stdio.h>
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
@@ -11,8 +12,15 @@
 #include "nouveau_buffer.h"
 #include "nouveau_mm.h"
 
+#define NOUVEAU_TRANSFER_PUSHBUF_THRESHOLD 192
+
 struct nouveau_transfer {
    struct pipe_transfer base;
+
+   uint8_t *map;
+   struct nouveau_bo *bo;
+   struct nouveau_mm_allocation *mm;
+   uint32_t offset;
 };
 
 static INLINE struct nouveau_transfer *
@@ -112,40 +120,75 @@ nouveau_buffer_destroy(struct pipe_screen *pscreen,
    NOUVEAU_DRV_STAT(nouveau_screen(pscreen), buf_obj_current_count, -1);
 }
 
-/* Maybe just migrate to GART right away if we actually need to do this. */
-static boolean
-nouveau_buffer_download(struct nouveau_context *nv, struct nv04_resource *buf,
-                        unsigned start, unsigned size)
+static uint8_t *
+nouveau_transfer_staging(struct nouveau_context *nv,
+/* The following params are extras */
+                         uint32_t access, struct nouveau_client *client,
+/* */
+                         struct nouveau_transfer *tx, boolean permit_pb)
 {
-   struct nouveau_mm_allocation *mm;
-   struct nouveau_bo *bounce = NULL;
-   uint32_t offset;
-
+/*
+   const unsigned adj = tx->base.box.x & NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK;
+   const unsigned size = align(tx->base.box.width, 4) + adj;
+*/
+   const unsigned adj = 0;
+   const unsigned size = tx->base.box.width;
 /*
    if (!nv->push_data)
       permit_pb = FALSE;
 */
 
-   assert(buf->domain == NOUVEAU_BO_VRAM);
+   {
+      tx->mm =
+         nouveau_mm_allocate(nv->screen->mm_GART, size, &tx->bo, &tx->offset);
+      if (tx->bo) {
+         tx->offset += adj;
+// XXX; read/download 
+//   nouveau_bo_map(bounce, NOUVEAU_BO_RD, nv->client);
+// XXX; write/upload
+//   nouveau_bo_map(bounce, 0, nv->client);
+
+// XXX: generic
+//         if (!nouveau_bo_map(tx->bo, 0, NULL))
+         if (!nouveau_bo_map(tx->bo, access, client))
+            tx->map = (uint8_t *)tx->bo->map + tx->offset;
+      }
+   }
+   return tx->map;
+}
 
-   mm = nouveau_mm_allocate(nv->screen->mm_GART, size, &bounce, &offset);
-   if (!bounce)
-      return FALSE;
+
+/* Maybe just migrate to GART right away if we actually need to do this. */
+static boolean
+nouveau_buffer_download(struct nouveau_context *nv, struct nouveau_transfer *tx)
+{
+   struct nv04_resource *buf = nv04_resource(tx->base.resource);
+   const unsigned base = tx->base.box.x;
+   const unsigned size = tx->base.box.width;
+
+   assert(buf->domain == NOUVEAU_BO_VRAM);
+   if (buf->domain != NOUVEAU_BO_VRAM) {
+      fprintf(stderr, "%s:%d domain %d\n", __func__, __LINE__, buf->domain);
+   }
 
    NOUVEAU_DRV_STAT(nv->screen, buf_read_bytes_staging_vid, size);
 
-   nv->copy_data(nv, bounce, offset, NOUVEAU_BO_GART,
-                 buf->bo, buf->offset + start, NOUVEAU_BO_VRAM, size);
+   nv->copy_data(nv, tx->bo, tx->offset, NOUVEAU_BO_GART,
+                 buf->bo, buf->offset + base, NOUVEAU_BO_VRAM, size);
 
-   if (nouveau_bo_map(bounce, NOUVEAU_BO_RD, nv->client))
+   if (nouveau_bo_wait(tx->bo, NOUVEAU_BO_RD, nv->client))
       return FALSE;
-   memcpy(buf->data + start, (uint8_t *)bounce->map + offset, size);
+   if (buf->data)
+      memcpy(buf->data + base, tx->map, size);
+   else {
+      fprintf(stderr, "%s:%d buf->data NULL\n", __func__, __LINE__);
+   }
 
    buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
 
-   nouveau_bo_ref(NULL, &bounce);
-   if (mm)
-      nouveau_mm_free(mm);
+   nouveau_bo_ref(NULL, &tx->bo);
+   if (tx->mm)
+      nouveau_mm_free(tx->mm);
    return TRUE;
 }
 
@@ -242,6 +285,33 @@ nouveau_buffer_transfer_init(struct nouveau_transfer *tx,
    tx->base.box.depth = 1;
    tx->base.stride = 0;
    tx->base.layer_stride = 0;
+
+   tx->bo = NULL;
+   tx->map = NULL;
+}
+
+
+static boolean
+nouveau_buffer_cache(struct nouveau_context *nv, struct nv04_resource *buf)
+{
+   struct nouveau_transfer tx;
+   boolean ret;
+   tx.base.resource = &buf->base;
+   tx.base.box.x = 0;
+   tx.base.box.width = buf->base.width0;
+   tx.bo = NULL;
+
+   if (!buf->data)
+         buf->data = align_malloc(buf->base.width0, 64);
+         if (!buf->data)
+            return FALSE;
+
+//   if (!nouveau_transfer_staging(nv, NOUVEAU_BO_RD, nv->client, tx, FALSE))
+   if (!nouveau_transfer_staging(nv, NOUVEAU_BO_RD, nv->client, &tx, FALSE))
+      return FALSE;
+   ret = nouveau_buffer_download(nv, &tx);
+
+   return ret;
 }
 
 static void *
@@ -271,7 +341,9 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
    if (buf->domain == NOUVEAU_BO_VRAM) {
       if (usage & PIPE_TRANSFER_READ) {
          if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)
-            nouveau_buffer_download(nv, buf, 0, buf->base.width0);
+            // XXX: No error checking
+            nouveau_transfer_staging(nv, NOUVEAU_BO_RD, nv->client, tx, TRUE);
+            nouveau_buffer_download(nv, tx);
       }
    }
 
@@ -393,9 +465,14 @@ nouveau_resource_map_offset(struct nouveau_context *nv,
    if (unlikely(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY))
       return res->data + offset;
 
-   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_VRAM) {
+      if (!res->data && (!(res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)))
+         fprintf(stderr, "%s:%d no data and NO GPU WRITING\n", __func__, __LINE__);
+
+      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)
+         nouveau_buffer_cache(nv, res);
+   }
 
    if (res->domain != NOUVEAU_BO_GART)
       return res->data + offset;




More information about the mesa-commit mailing list