summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/bufferobj.c
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2013-10-07 18:53:40 -0700
committerFrancisco Jerez <[email protected]>2013-10-29 12:40:55 -0700
commit1c7dcfed7ceb9e47943d6adaacc1ca483c97fcf6 (patch)
tree2452628247d8021725a47e408c1300d4f0d63363 /src/mesa/main/bufferobj.c
parente3fd31dc411c023495970ac51ce28b4d0deb80e6 (diff)
mesa: Add support for ARB_shader_atomic_counters.
This patch implements the common support code required for the ARB_shader_atomic_counters extension. It defines the necessary data structures for tracking atomic counter buffer objects (from now on "ABOs") associated with some specific context or shader program, it implements support for binding buffers to an ABO binding point and querying the existing atomic counters and buffers declared by GLSL shaders. v2: Fix extension checks. Drop unused MAX_ATOMIC_BUFFERS constant. Acked-by: Paul Berry <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/mesa/main/bufferobj.c')
-rw-r--r--src/mesa/main/bufferobj.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 312ffb78888..1f5506157ca 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -102,6 +102,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
return &ctx->UniformBuffer;
}
break;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ if (ctx->Extensions.ARB_shader_atomic_counters) {
+ return &ctx->AtomicBuffer;
+ }
+ break;
default:
return NULL;
}
@@ -2119,6 +2124,51 @@ bind_buffer_base_uniform_buffer(struct gl_context *ctx,
set_ubo_binding(ctx, index, bufObj, 0, 0, GL_TRUE);
}
+static void
+set_atomic_buffer_binding(struct gl_context *ctx,
+ unsigned index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size,
+ const char *name)
+{
+ struct gl_atomic_buffer_binding *binding;
+
+ if (index >= ctx->Const.MaxAtomicBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d)", name, index);
+ return;
+ }
+
+ if (offset & (ATOMIC_COUNTER_SIZE - 1)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(offset misalgned %d/%d)", name, (int) offset,
+ ATOMIC_COUNTER_SIZE);
+ return;
+ }
+
+ _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
+
+ binding = &ctx->AtomicBufferBindings[index];
+ if (binding->BufferObject == bufObj &&
+ binding->Offset == offset &&
+ binding->Size == size) {
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
+
+ _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
+
+ if (bufObj == ctx->Shared->NullBufferObj) {
+ binding->Offset = -1;
+ binding->Size = -1;
+ } else {
+ binding->Offset = offset;
+ binding->Size = size;
+ }
+}
+
void GLAPIENTRY
_mesa_BindBufferRange(GLenum target, GLuint index,
GLuint buffer, GLintptr offset, GLsizeiptr size)
@@ -2156,6 +2206,10 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
case GL_UNIFORM_BUFFER:
bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
return;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ set_atomic_buffer_binding(ctx, index, bufObj, offset, size,
+ "glBindBufferRange");
+ return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
return;
@@ -2215,6 +2269,10 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
case GL_UNIFORM_BUFFER:
bind_buffer_base_uniform_buffer(ctx, index, bufObj);
return;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ set_atomic_buffer_binding(ctx, index, bufObj, 0, 0,
+ "glBindBufferBase");
+ return;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
return;