Yes, absolutely, we should have a CAP for that. Marek
On Wed, Jul 24, 2013 at 12:20 AM, Jose Fonseca <[email protected]> wrote: > ----- Original Message ----- >> FYI, OpenGL 4.4, which was released yesterday, adds GL_MAP_PERSISTENT >> and GL_MAP_COHERENT bits as valid parameters of glMapBufferRange and >> glBufferStorage, allowing to use buffers for rendering while they are >> mapped and upload/download data to/from the buffers simultaneously. >> It's now clear that Gallium will have to support it at some point, >> it's only a matter of when. And once we have it, gallium can use it >> for faster buffer uploads. > > IIRC, this sort of mappings are tricky, but not totally impossible on Windows > WDDM. I'm OK adding this, but until we manage to get it working on Windows > this would need to be conditional though. > > Should we have a CAP, instead of having the st tracker systematically retry > with/without PERSISTENT flag? > > Jose > >> >> Marek >> >> On Mon, Jan 2, 2012 at 1:22 AM, Marek Olšák <[email protected]> wrote: >> > 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. >> > --- >> > 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 77c0345..c54e481 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 8ff733a..64d071c 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 ca38571..d86d493 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 f822625..02186ba 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 6f860e7..8ddebeb 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 f168637..c04f41f 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 7a218b1..605af8e 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 afdd530..91e861a 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 8fe54c8..decd941 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 fa713ee..57ec752 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 697c1d3..4eb1068 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 3b3940d..91d8b1e 100644 >> > --- a/src/gallium/include/pipe/p_defines.h >> > +++ b/src/gallium/include/pipe/p_defines.h >> > @@ -226,6 +226,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. >> > * >> > * It should not be used with PIPE_TRANSFER_READ. >> > -- >> > 1.7.4.1 >> > >> _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
