[Mesa-dev] [PATCH 1/5] mesa: align atomic buffer handling code with ubo/ssbo
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Sep 15 08:00:32 UTC 2017
On 09/15/2017 05:57 AM, 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);
offset/size have to be -1 if it's the null buffer object.
With that fixed, patch is:
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> }
>
> _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