On 09/15/2017 05:57 AM, Dave Airlie wrote:
From: Dave Airlie <[email protected]>

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 <[email protected]>
---
  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 <[email protected]>

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

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to