From 0950086376b1c8b7fb89eda81ed7f2f06dee58bc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 2 Jan 2012 01:13:15 +0100 Subject: [PATCH] gallium: add flag PIPE_TRANSFER_MAP_PERMANENTLY MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Please see the diff for further info. This paves the way for moving user buffer uploads out of drivers and should allow to clean up the mess in u_upload_mgr in the meantime. For now only allowed for buffers on r300 and r600. Acked-by: Christian König --- src/gallium/drivers/i915/i915_resource_buffer.c | 7 ++++++- src/gallium/drivers/i915/i915_resource_texture.c | 7 ++++++- src/gallium/drivers/llvmpipe/lp_texture.c | 4 ++++ src/gallium/drivers/nouveau/nouveau_buffer.c | 8 +++++++- src/gallium/drivers/nv50/nv50_transfer.c | 2 +- src/gallium/drivers/nvc0/nvc0_transfer.c | 2 +- src/gallium/drivers/nvfx/nvfx_transfer.c | 3 +++ src/gallium/drivers/r300/r300_transfer.c | 4 ++++ src/gallium/drivers/r600/r600_texture.c | 4 ++++ src/gallium/drivers/svga/svga_resource_buffer.c | 4 ++++ src/gallium/drivers/svga/svga_resource_texture.c | 2 +- src/gallium/include/pipe/p_defines.h | 16 ++++++++++++++++ 12 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c index 77c03450b3a..c54e481698e 100644 --- a/src/gallium/drivers/i915/i915_resource_buffer.c +++ b/src/gallium/drivers/i915/i915_resource_buffer.c @@ -68,8 +68,13 @@ i915_get_transfer(struct pipe_context *pipe, const struct pipe_box *box) { struct i915_context *i915 = i915_context(pipe); - struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); + struct pipe_transfer *transfer; + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } + + transfer = util_slab_alloc(&i915->transfer_pool); if (transfer == NULL) return NULL; diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 8ff733a7be5..64d071c9d53 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -720,9 +720,14 @@ i915_texture_get_transfer(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); struct i915_texture *tex = i915_texture(resource); - struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool); + struct i915_transfer *transfer; boolean use_staging_texture = FALSE; + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } + + transfer = util_slab_alloc(&i915->texture_transfer_pool); if (transfer == NULL) return NULL; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index ca38571b2bc..d86d493a0a2 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -587,6 +587,10 @@ llvmpipe_get_transfer(struct pipe_context *pipe, assert(resource); assert(level <= resource->last_level); + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } + /* * Transfers, like other pipe operations, must happen in order, so flush the * context if necessary. diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index f822625af90..02186ba3739 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -172,7 +172,13 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe, { struct nv04_resource *buf = nv04_resource(resource); struct nouveau_context *nv = nouveau_context(pipe); - struct nouveau_transfer *xfr = CALLOC_STRUCT(nouveau_transfer); + struct nouveau_transfer *xfr; + + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } + + xfr = CALLOC_STRUCT(nouveau_transfer); if (!xfr) return NULL; diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index 6f860e73348..8ddebeb7451 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -243,7 +243,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx, uint32_t size; int ret; - if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY)) return NULL; tx = CALLOC_STRUCT(nv50_transfer); diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index f16863733b7..c04f41f6ea3 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -243,7 +243,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx, uint32_t size; int ret; - if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY)) return NULL; tx = CALLOC_STRUCT(nvc0_transfer); diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c index 7a218b18c64..605af8efa8e 100644 --- a/src/gallium/drivers/nvfx/nvfx_transfer.c +++ b/src/gallium/drivers/nvfx/nvfx_transfer.c @@ -26,6 +26,9 @@ nvfx_transfer_new(struct pipe_context *pipe, unsigned usage, const struct pipe_box *box) { + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } if((usage & (PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_DONTBLOCK)) == PIPE_TRANSFER_DONTBLOCK) { struct nouveau_bo* bo = ((struct nvfx_resource*)pt)->bo; diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index afdd530d15d..91e861a4a73 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -89,6 +89,10 @@ r300_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource base; boolean referenced_cs, referenced_hw; + if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY)) { + return NULL; + } + referenced_cs = r300->rws->cs_is_buffer_referenced(r300->cs, tex->cs_buf); if (referenced_cs) { diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 8fe54c8a539..decd9415225 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -630,6 +630,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, int r; boolean use_staging_texture = FALSE; + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } + /* We cannot map a tiled texture directly because the data is * in a different order, therefore we do detiling using a blit. * diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index fa713ee88ad..57ec752bf9b 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -74,6 +74,10 @@ svga_buffer_get_transfer(struct pipe_context *pipe, struct svga_buffer *sbuf = svga_buffer(resource); struct pipe_transfer *transfer; + if (usage & PIPE_TRANSFER_MAP_PERMANENTLY) { + return NULL; + } + transfer = CALLOC_STRUCT(pipe_transfer); if (transfer == NULL) { return NULL; diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 697c1d3c5e3..4eb1068e226 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -259,7 +259,7 @@ svga_texture_get_transfer(struct pipe_context *pipe, unsigned nblocksy = util_format_get_nblocksy(texture->format, box->height); /* We can't map texture storage directly */ - if (usage & PIPE_TRANSFER_MAP_DIRECTLY) + if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY)) return NULL; assert(box->depth == 1); diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 3b3940db893..91d8b1e4525 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -225,6 +225,22 @@ enum pipe_transfer_usage { */ PIPE_TRANSFER_MAP_DIRECTLY = (1 << 2), + /** + * The transfer should map the resource storage directly and the GPU should + * be able to see what the CPU has written. Such a storage may stay mapped + * while issuing draw commands which use it. The only allowed usage is + * non-overlapping writes which are suballocated out of a big buffer. + * The minimum allowed alignment of suballocations is 256 bytes (this is + * a subject to change). + * The flag is intended to be used to avoid mapping and unmapping + * resources repeatedly when doing uploads and draws intermixed. + * + * The driver may return NULL if that isn't possible, and the state + * tracker needs to cope with that and use an alternative path + * without this flag. + */ + PIPE_TRANSFER_MAP_PERMANENTLY = (1 << 3), + /** * Discards the memory within the mapped region. * -- 2.30.2