Module: Mesa Branch: refs/tags/staging-dw Commit: 2627865eb2b717427eb3035bcacaa934611dda8d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2627865eb2b717427eb3035bcacaa934611dda8d
Author: Emil Velikov <[email protected]> Date: Thu Jun 13 17:16:50 2013 +0100 nouveau: start ripping out common stuff *transfer_staging() *buffer_cache() Signed-off-by: Emil Velikov <[email protected]> --- 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..9c7ce2f 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(NOUVEAU_BO_RD, nv->client, tx, FALSE)) + if (!nouveau_transfer_staging(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; _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
