[Mesa-dev] [PATCH 1/5] mesa: align atomic buffer handling code with ubo/ssbo

Iago Toral itoral at igalia.com
Fri Sep 15 09:06:19 UTC 2017


Thanks for cleaning this up, I left some minor comments in this patch
but otherwise patches 1-4 are:

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>

Regarding patch 5, I have not worked on the state tracker before, but
the change seems straight forward enough that I think you can also add
my Rb (it is the same thing it does for ubos and ssbos).

Iago

On Fri, 2017-09-15 at 13:57 +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
> 
> this adds automatic size support to the atomic buffer code,
> but also realigns the code to act like the ubo/ssbo code.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/mesa/main/bufferobj.c | 132 ++++++++++++++++++++++++++++++----
> ------------
>  src/mesa/main/mtypes.h    |   1 +
>  2 files changed, 88 insertions(+), 45 deletions(-)
> 
> diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
> index 2da2128..93b66dc 100644
> --- a/src/mesa/main/bufferobj.c
> +++ b/src/mesa/main/bufferobj.c
> @@ -1268,18 +1268,19 @@ set_atomic_buffer_binding(struct gl_context
> *ctx,
>                            struct gl_atomic_buffer_binding *binding,
>                            struct gl_buffer_object *bufObj,
>                            GLintptr offset,
> -                          GLsizeiptr size)
> +                          GLsizeiptr size,
> +                          bool autoSize)
>  {
>     _mesa_reference_buffer_object(ctx, &binding->BufferObject,
> bufObj);
>  
> -   if (bufObj == ctx->Shared->NullBufferObj) {
> -      binding->Offset = 0;
> -      binding->Size = 0;
> -   } else {
> -      binding->Offset = offset;
> -      binding->Size = size;
> -      bufObj->UsageHistory |= USAGE_ATOMIC_COUNTER_BUFFER;
> -   }
> +   binding->Offset = offset;
> +   binding->Size = size;
> +   binding->AutomaticSize = autoSize;
> +   /* If this is a real buffer object, mark it has having been used
> +    * at some point as an atomic counter buffer.
> +    */
> +   if (size >= 0)
> +     bufObj->UsageHistory |= USAGE_ATOMIC_COUNTER_BUFFER;
>  }
>  
>  /**
> @@ -1399,6 +1400,33 @@ bind_shader_storage_buffer(struct gl_context
> *ctx,
>  }
>  
>  /**
> + * Binds a buffer object to an atomic buffer binding point.
> + *
> + * Unlike set_atomic_binding(), this function also flushes vertices
> + * and updates NewDriverState.  It also checks if the binding
> + * has actually changed before updating it.
> + */
> +static void
> +bind_atomic_buffer(struct gl_context *ctx, unsigned index,
> +                   struct gl_buffer_object *bufObj, GLintptr offset,
> +                   GLsizeiptr size, GLboolean autoSize)
> +{
> +   struct gl_atomic_buffer_binding *binding =
> +      &ctx->AtomicBufferBindings[index];
> +   if (binding->BufferObject == bufObj &&
> +       binding->Offset == offset &&
> +       binding->Size == size &&
> +       binding->AutomaticSize == autoSize) {
> +      return;
> +   }
> +
> +   FLUSH_VERTICES(ctx, 0);
> +   ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
> +
> +   set_atomic_buffer_binding(ctx, binding, bufObj, offset, size,
> autoSize);
> +}
> +
> +/**
>   * Bind a buffer object to a uniform block binding point.
>   * As above, but offset = 0.
>   */
> @@ -1442,25 +1470,26 @@ bind_buffer_base_shader_storage_buffer(struct
> gl_context *ctx,
>        bind_shader_storage_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
>  }
>  
> +/**
> + * Bind a buffer object to a shader storage block binding point.
> + * As above, but offset = 0.
> + */
>  static void
> -bind_atomic_buffer(struct gl_context *ctx, unsigned index,
> -                   struct gl_buffer_object *bufObj, GLintptr offset,
> -                   GLsizeiptr size)
> +bind_buffer_base_atomic_buffer(struct gl_context *ctx,
> +                               GLuint index,
> +                               struct gl_buffer_object *bufObj)
>  {
> -   _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
> -
> -   struct gl_atomic_buffer_binding *binding =
> -      &ctx->AtomicBufferBindings[index];
> -   if (binding->BufferObject == bufObj &&
> -       binding->Offset == offset &&
> -       binding->Size == size) {
> +   if (index >= ctx->Const.MaxAtomicBufferBindings) {
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> "glBindBufferBase(index=%d)", index);
>        return;
>     }
>  
> -   FLUSH_VERTICES(ctx, 0);
> -   ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
> +   _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
>  
> -   set_atomic_buffer_binding(ctx, binding, bufObj, offset, size);
> +   if (bufObj == ctx->Shared->NullBufferObj)
> +      bind_atomic_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
> +   else
> +      bind_atomic_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
>  }
>  
>  /**
> @@ -1562,8 +1591,8 @@ delete_buffers(struct gl_context *ctx, GLsizei
> n, const GLuint *ids)
>           /* unbind Atomci Buffer binding points */
>           for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) {
>              if (ctx->AtomicBufferBindings[j].BufferObject == bufObj)
> {
> -               _mesa_BindBufferBase( GL_ATOMIC_COUNTER_BUFFER, j, 0
> );
> -               bind_atomic_buffer(ctx, j, ctx->Shared-
> >NullBufferObj, 0, 0);
> +               bind_buffer_base_atomic_buffer(ctx, j,
> +                                              ctx->Shared-
> >NullBufferObj);
>              }
>           }
>  
> @@ -3564,32 +3593,46 @@
> bind_buffer_range_shader_storage_buffer_err(struct gl_context *ctx,
>     bind_buffer_range_shader_storage_buffer(ctx, index, bufObj,
> offset, size);
>  }
>  
> +static void
> +bind_buffer_range_atomic_buffer(struct gl_context *ctx, GLuint
> index,
> +                                 struct gl_buffer_object *bufObj,
> +                                 GLintptr offset, GLsizeiptr size)
> +{
> +   if (bufObj == ctx->Shared->NullBufferObj) {
> +      offset = -1;
> +      size = -1;
> +   }
> +
> +   _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
> +   bind_atomic_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
> +}
> +
>  /**
> - * Binds a buffer object to an atomic buffer binding point.
> - *
> - * Unlike set_atomic_buffer_binding(), this function also validates
> the
> - * index and offset, flushes vertices, and updates NewDriverState.
> - * It also checks if the binding has actually changing before
> - * updating it.
> + * Bind a region of a buffer object to an atomic storage block
> binding point.
> + * \param index  the shader storage buffer binding point index
> + * \param bufObj  the buffer object
> + * \param offset  offset to the start of buffer object region
> + * \param size  size of the buffer object region
>   */
>  static void
> -bind_atomic_buffer_err(struct gl_context *ctx, unsigned index,
> -                       struct gl_buffer_object *bufObj, GLintptr
> offset,
> -                       GLsizeiptr size, const char *name)
> +bind_buffer_range_atomic_buffer_err(struct gl_context *ctx,
> +                                    GLuint index,
> +                                    struct gl_buffer_object *bufObj,
> +                                    GLintptr offset, GLsizeiptr
> size)
>  {
>     if (index >= ctx->Const.MaxAtomicBufferBindings) {
> -      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d)", name,
> index);
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> "glBindBufferRange(index=%d)", index);
>        return;
>     }
>  
>     if (offset & (ATOMIC_COUNTER_SIZE - 1)) {
> -      _mesa_error(ctx, GL_INVALID_VALUE,
> -                  "%s(offset misaligned %d/%d)", name, (int) offset,
> -                  ATOMIC_COUNTER_SIZE);
> +     _mesa_error(ctx, GL_INVALID_VALUE,
> +                 "glBindBufferRange(offset misaligned %d/%d)", (int)
> offset,
> +                 ATOMIC_COUNTER_SIZE);
>        return;
>     }
>  
> -   bind_atomic_buffer(ctx, index, bufObj, offset, size);
> +   bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset,
> size);
>  }
>  
>  static inline bool
> @@ -4150,7 +4193,7 @@ unbind_atomic_buffers(struct gl_context *ctx,
> GLuint first, GLsizei count)
>  
>     for (int i = 0; i < count; i++)
>        set_atomic_buffer_binding(ctx, &ctx-
> >AtomicBufferBindings[first + i],
> -                                bufObj, -1, -1);
> +                                bufObj, -1, -1, GL_TRUE);
>  }
>  
>  static void
> @@ -4252,7 +4295,7 @@ bind_atomic_buffers(struct gl_context *ctx,
>           bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i,
> caller);
>  
>        if (bufObj)
> -         set_atomic_buffer_binding(ctx, binding, bufObj, offset,
> size);
> +         set_atomic_buffer_binding(ctx, binding, bufObj, offset,
> size, !range);
>     }
>  
>     _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
> @@ -4300,7 +4343,7 @@ bind_buffer_range(GLenum target, GLuint index,
> GLuint buffer, GLintptr offset,
>                                                   size);
>           return;
>        case GL_ATOMIC_COUNTER_BUFFER:
> -         bind_atomic_buffer(ctx, index, bufObj, offset, size);
> +         bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset,
> size);
>           return;
>        default:
>           unreachable("invalid BindBufferRange target with
> KHR_no_error");
> @@ -4334,8 +4377,8 @@ bind_buffer_range(GLenum target, GLuint index,
> GLuint buffer, GLintptr offset,
>                                                       offset, size);
>           return;
>        case GL_ATOMIC_COUNTER_BUFFER:
> -         bind_atomic_buffer_err(ctx, index, bufObj, offset, size,
> -                                "glBindBufferRange");
> +         bind_buffer_range_atomic_buffer_err(ctx, index, bufObj,
> +                                             offset, size);
>           return;
>        default:
>           _mesa_error(ctx, GL_INVALID_ENUM,
> "glBindBufferRange(target)");
> @@ -4423,8 +4466,7 @@ _mesa_BindBufferBase(GLenum target, GLuint
> index, GLuint buffer)
>        bind_buffer_base_shader_storage_buffer(ctx, index, bufObj);
>        return;
>     case GL_ATOMIC_COUNTER_BUFFER:
> -      bind_atomic_buffer_err(ctx, index, bufObj, 0, 0,
> -                             "glBindBufferBase");
> +      bind_buffer_base_atomic_buffer(ctx, index, bufObj);
>        return;
>     default:
>        _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index db9ea76..9c2c7d4 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -4635,6 +4635,7 @@ struct gl_atomic_buffer_binding
>     struct gl_buffer_object *BufferObject;
>     GLintptr Offset;
>     GLsizeiptr Size;
> +   GLboolean AutomaticSize;
>  };
>  
>  /**


More information about the mesa-dev mailing list