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

Dave Airlie airlied at gmail.com
Fri Sep 15 03:57:10 UTC 2017


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;
 };
 
 /**
-- 
2.9.5



More information about the mesa-dev mailing list