mesa: align atomic buffer handling code with ubo/ssbo (v1.1)

this adds automatic size support to the atomic buffer code,
but also realigns the code to act like the ubo/ssbo code.

v1.1:
add missing blank lines.
reindent one block properly.
check for NullBufferObj.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2017-09-15 12:38:18 +10:00
parent 03087686ff
commit 65d3ef7cd4
2 changed files with 92 additions and 44 deletions

View File

@ -1268,18 +1268,20 @@ set_atomic_buffer_binding(struct gl_context *ctx,
struct gl_atomic_buffer_binding *binding, struct gl_atomic_buffer_binding *binding,
struct gl_buffer_object *bufObj, struct gl_buffer_object *bufObj,
GLintptr offset, GLintptr offset,
GLsizeiptr size) GLsizeiptr size,
bool autoSize)
{ {
_mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj); _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
if (bufObj == ctx->Shared->NullBufferObj) { binding->Offset = offset;
binding->Offset = 0; binding->Size = size;
binding->Size = 0; binding->AutomaticSize = autoSize;
} else {
binding->Offset = offset; /* If this is a real buffer object, mark it has having been used
binding->Size = size; * at some point as an atomic counter buffer.
bufObj->UsageHistory |= USAGE_ATOMIC_COUNTER_BUFFER; */
} if (size >= 0)
bufObj->UsageHistory |= USAGE_ATOMIC_COUNTER_BUFFER;
} }
/** /**
@ -1398,6 +1400,34 @@ bind_shader_storage_buffer(struct gl_context *ctx,
set_ssbo_binding(ctx, binding, bufObj, offset, size, autoSize); set_ssbo_binding(ctx, binding, bufObj, offset, size, autoSize);
} }
/**
* 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. * Bind a buffer object to a uniform block binding point.
* As above, but offset = 0. * As above, but offset = 0.
@ -1442,25 +1472,26 @@ bind_buffer_base_shader_storage_buffer(struct gl_context *ctx,
bind_shader_storage_buffer(ctx, index, bufObj, 0, 0, GL_TRUE); 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 static void
bind_atomic_buffer(struct gl_context *ctx, unsigned index, bind_buffer_base_atomic_buffer(struct gl_context *ctx,
struct gl_buffer_object *bufObj, GLintptr offset, GLuint index,
GLsizeiptr size) struct gl_buffer_object *bufObj)
{ {
_mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj); if (index >= ctx->Const.MaxAtomicBufferBindings) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
struct gl_atomic_buffer_binding *binding =
&ctx->AtomicBufferBindings[index];
if (binding->BufferObject == bufObj &&
binding->Offset == offset &&
binding->Size == size) {
return; return;
} }
FLUSH_VERTICES(ctx, 0); _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
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 +1593,8 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids)
/* unbind Atomci Buffer binding points */ /* unbind Atomci Buffer binding points */
for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) { for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) {
if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) { if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) {
_mesa_BindBufferBase( GL_ATOMIC_COUNTER_BUFFER, j, 0 ); bind_buffer_base_atomic_buffer(ctx, j,
bind_atomic_buffer(ctx, j, ctx->Shared->NullBufferObj, 0, 0); ctx->Shared->NullBufferObj);
} }
} }
@ -3565,32 +3596,46 @@ bind_buffer_range_shader_storage_buffer_err(struct gl_context *ctx,
bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset, size); 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. * Bind a region of a buffer object to an atomic storage block binding point.
* * \param index the shader storage buffer binding point index
* Unlike set_atomic_buffer_binding(), this function also validates the * \param bufObj the buffer object
* index and offset, flushes vertices, and updates NewDriverState. * \param offset offset to the start of buffer object region
* It also checks if the binding has actually changing before * \param size size of the buffer object region
* updating it.
*/ */
static void static void
bind_atomic_buffer_err(struct gl_context *ctx, unsigned index, bind_buffer_range_atomic_buffer_err(struct gl_context *ctx,
struct gl_buffer_object *bufObj, GLintptr offset, GLuint index,
GLsizeiptr size, const char *name) struct gl_buffer_object *bufObj,
GLintptr offset, GLsizeiptr size)
{ {
if (index >= ctx->Const.MaxAtomicBufferBindings) { 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; return;
} }
if (offset & (ATOMIC_COUNTER_SIZE - 1)) { if (offset & (ATOMIC_COUNTER_SIZE - 1)) {
_mesa_error(ctx, GL_INVALID_VALUE, _mesa_error(ctx, GL_INVALID_VALUE,
"%s(offset misaligned %d/%d)", name, (int) offset, "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
ATOMIC_COUNTER_SIZE); ATOMIC_COUNTER_SIZE);
return; return;
} }
bind_atomic_buffer(ctx, index, bufObj, offset, size); bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size);
} }
static inline bool static inline bool
@ -4151,7 +4196,7 @@ unbind_atomic_buffers(struct gl_context *ctx, GLuint first, GLsizei count)
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
set_atomic_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i], set_atomic_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i],
bufObj, -1, -1); bufObj, -1, -1, GL_TRUE);
} }
static void static void
@ -4253,7 +4298,10 @@ bind_atomic_buffers(struct gl_context *ctx,
bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller); bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller);
if (bufObj) if (bufObj)
set_atomic_buffer_binding(ctx, binding, bufObj, offset, size); if (bufObj == ctx->Shared->NullBufferObj)
set_atomic_buffer_binding(ctx, binding, bufObj, -1, -1, !range);
else
set_atomic_buffer_binding(ctx, binding, bufObj, offset, size, !range);
} }
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects); _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
@ -4301,7 +4349,7 @@ bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset,
size); size);
return; return;
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffer(ctx, index, bufObj, offset, size); bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size);
return; return;
default: default:
unreachable("invalid BindBufferRange target with KHR_no_error"); unreachable("invalid BindBufferRange target with KHR_no_error");
@ -4335,8 +4383,8 @@ bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset,
offset, size); offset, size);
return; return;
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffer_err(ctx, index, bufObj, offset, size, bind_buffer_range_atomic_buffer_err(ctx, index, bufObj,
"glBindBufferRange"); offset, size);
return; return;
default: default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)"); _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
@ -4424,8 +4472,7 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
bind_buffer_base_shader_storage_buffer(ctx, index, bufObj); bind_buffer_base_shader_storage_buffer(ctx, index, bufObj);
return; return;
case GL_ATOMIC_COUNTER_BUFFER: case GL_ATOMIC_COUNTER_BUFFER:
bind_atomic_buffer_err(ctx, index, bufObj, 0, 0, bind_buffer_base_atomic_buffer(ctx, index, bufObj);
"glBindBufferBase");
return; return;
default: default:
_mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)"); _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");

View File

@ -4640,6 +4640,7 @@ struct gl_atomic_buffer_binding
struct gl_buffer_object *BufferObject; struct gl_buffer_object *BufferObject;
GLintptr Offset; GLintptr Offset;
GLsizeiptr Size; GLsizeiptr Size;
GLboolean AutomaticSize;
}; };
/** /**