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

Reply via email to