summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0/nvc0_transfer.c
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-04-03 00:18:55 +0200
committerChristoph Bumiller <[email protected]>2013-04-03 12:54:44 +0200
commit8e1dd58a7e76834c1fb6d117b6ea5755e05cfb77 (patch)
tree5332b79c7af6d65cedc8139fd7f55414db35a9ab /src/gallium/drivers/nvc0/nvc0_transfer.c
parentba9b0b682f51222752ac56e7a0615f9bbb686089 (diff)
nvc0: place staging textures in GART and map them directly
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_transfer.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_transfer.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c
index bdba83d90fb..3f876622353 100644
--- a/src/gallium/drivers/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nvc0/nvc0_transfer.c
@@ -328,6 +328,30 @@ nve4_m2mf_copy_linear(struct nouveau_context *nv,
nouveau_bufctx_reset(bctx, 0);
}
+
+static INLINE boolean
+nvc0_mt_transfer_can_map_directly(struct nv50_miptree *mt)
+{
+ if (mt->base.domain == NOUVEAU_BO_VRAM)
+ return FALSE;
+ if (mt->base.base.usage != PIPE_USAGE_STAGING)
+ return FALSE;
+ return !nouveau_bo_memtype(mt->base.bo);
+}
+
+static INLINE boolean
+nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage)
+{
+ if (!mt->base.mm) {
+ uint32_t access = (usage & PIPE_TRANSFER_WRITE) ?
+ NOUVEAU_BO_WR : NOUVEAU_BO_RD;
+ return !nouveau_bo_wait(mt->base.bo, access, nvc0->base.client);
+ }
+ if (usage & PIPE_TRANSFER_WRITE)
+ return !mt->base.fence || nouveau_fence_wait(mt->base.fence);
+ return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr);
+}
+
void *
nvc0_miptree_transfer_map(struct pipe_context *pctx,
struct pipe_resource *res,
@@ -344,6 +368,16 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
int ret;
unsigned flags = 0;
+ if (nvc0_mt_transfer_can_map_directly(mt)) {
+ ret = !nvc0_mt_sync(nvc0, mt, usage);
+ if (!ret)
+ ret = nouveau_bo_map(mt->base.bo, 0, NULL);
+ if (ret &&
+ (usage & PIPE_TRANSFER_MAP_DIRECTLY))
+ return NULL;
+ if (!ret)
+ usage |= PIPE_TRANSFER_MAP_DIRECTLY;
+ } else
if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
return NULL;
@@ -369,6 +403,12 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format);
tx->base.layer_stride = tx->nblocksy * tx->base.stride;
+ if (usage & PIPE_TRANSFER_MAP_DIRECTLY) {
+ tx->base.stride = align(tx->base.stride, 128);
+ *ptransfer = &tx->base;
+ return mt->base.bo->map + mt->base.offset;
+ }
+
nv50_m2mf_rect_setup(&tx->rect[0], res, level, box->x, box->y, box->z);
size = tx->base.layer_stride;
@@ -437,6 +477,13 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
unsigned i;
+ if (tx->base.usage & PIPE_TRANSFER_MAP_DIRECTLY) {
+ pipe_resource_reference(&transfer->resource, NULL);
+
+ FREE(tx);
+ return;
+ }
+
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
for (i = 0; i < tx->nlayers; ++i) {
nvc0->m2mf_copy_rect(nvc0, &tx->rect[0], &tx->rect[1],