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