summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Justen <jordan.l.justen@intel.com>2015-01-26 10:57:15 -0800
committerJordan Justen <jordan.l.justen@intel.com>2015-06-04 14:45:12 -0700
commitd13831e8fe9a58a9faec7ac17d397a5b7c03b631 (patch)
treec01bca7311b925896beb338c5eb9020c8a812b8f
parent71e94578779e4344066d434004fd85ca493de552 (diff)
mesa/bo: Make bo locking more coarse grainedcoarse-bo-locks
SynMark's OglBatch7 calls BindBuffer a large percentage of time compared to GPU work. Therefore the locks related to changing the currently bound buffer become relatively expensive. Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
-rw-r--r--src/mesa/main/bufferobj.c130
1 files changed, 86 insertions, 44 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 66dee68025..aef547bad8 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -53,6 +53,9 @@
/*#define VBO_DEBUG*/
/*#define BOUNDS_CHECK*/
+static void
+bind_buffer_base_locked(struct gl_context *ctx,
+ GLenum target, GLuint index, GLuint buffer);
/**
* Used as a placeholder for buffer objects between glGenBuffers() and
@@ -430,17 +433,16 @@ _mesa_delete_buffer_object(struct gl_context *ctx,
* This is normally only called from the _mesa_reference_buffer_object() macro
* when there's a real pointer change.
*/
-void
-_mesa_reference_buffer_object_(struct gl_context *ctx,
- struct gl_buffer_object **ptr,
- struct gl_buffer_object *bufObj)
+static void
+reference_bufferobj_locked(struct gl_context *ctx,
+ struct gl_buffer_object **ptr,
+ struct gl_buffer_object *bufObj)
{
if (*ptr) {
/* Unreference the old buffer */
GLboolean deleteFlag = GL_FALSE;
struct gl_buffer_object *oldObj = *ptr;
- mtx_lock(&oldObj->Mutex);
assert(oldObj->RefCount > 0);
oldObj->RefCount--;
#if 0
@@ -448,7 +450,6 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
(void *) oldObj, oldObj->Name, oldObj->RefCount);
#endif
deleteFlag = (oldObj->RefCount == 0);
- mtx_unlock(&oldObj->Mutex);
if (deleteFlag) {
@@ -470,7 +471,6 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
if (bufObj) {
/* reference new buffer */
- mtx_lock(&bufObj->Mutex);
if (bufObj->RefCount == 0) {
/* this buffer's being deleted (look just above) */
/* Not sure this can every really happen. Warn if it does. */
@@ -485,11 +485,21 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
#endif
*ptr = bufObj;
}
- mtx_unlock(&bufObj->Mutex);
}
}
+void
+_mesa_reference_buffer_object_(struct gl_context *ctx,
+ struct gl_buffer_object **ptr,
+ struct gl_buffer_object *bufObj)
+{
+ mtx_lock(&ctx->Shared->Mutex);
+ reference_bufferobj_locked(ctx, ptr, bufObj);
+ mtx_unlock(&ctx->Shared->Mutex);
+}
+
+
/**
* Initialize a buffer object to default values.
*/
@@ -885,12 +895,12 @@ _mesa_free_buffer_objects( struct gl_context *ctx )
}
-bool
-_mesa_handle_bind_buffer_gen(struct gl_context *ctx,
- GLenum target,
- GLuint buffer,
- struct gl_buffer_object **buf_handle,
- const char *caller)
+static bool
+handle_bind_buffer_gen_locked(struct gl_context *ctx,
+ GLenum target,
+ GLuint buffer,
+ struct gl_buffer_object **buf_handle,
+ const char *caller)
{
struct gl_buffer_object *buf = *buf_handle;
@@ -909,13 +919,28 @@ _mesa_handle_bind_buffer_gen(struct gl_context *ctx,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
return false;
}
- _mesa_HashInsert(ctx->Shared->BufferObjects, buffer, buf);
+ _mesa_HashInsertLocked(ctx->Shared->BufferObjects, buffer, buf);
*buf_handle = buf;
}
return true;
}
+bool
+_mesa_handle_bind_buffer_gen(struct gl_context *ctx,
+ GLenum target,
+ GLuint buffer,
+ struct gl_buffer_object **buf_handle,
+ const char *caller)
+{
+ bool result;
+ mtx_lock(&ctx->Shared->Mutex);
+ result = handle_bind_buffer_gen_locked(ctx, target, buffer, buf_handle,
+ caller);
+ mtx_unlock(&ctx->Shared->Mutex);
+ return result;
+}
+
/**
* Bind the specified target to buffer for the specified context.
* Called by glBindBuffer() and other functions.
@@ -949,14 +974,14 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
}
else {
/* non-default buffer object */
- newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
- if (!_mesa_handle_bind_buffer_gen(ctx, target, buffer,
- &newBufObj, "glBindBuffer"))
+ newBufObj = _mesa_lookup_bufferobj_locked(ctx, buffer);
+ if (!handle_bind_buffer_gen_locked(ctx, target, buffer,
+ &newBufObj, "glBindBuffer"))
return;
}
/* bind new buffer */
- _mesa_reference_buffer_object(ctx, bindTarget, newBufObj);
+ reference_bufferobj_locked(ctx, bindTarget, newBufObj);
}
@@ -971,10 +996,12 @@ _mesa_update_default_objects_buffer_objects(struct gl_context *ctx)
/* Bind the NullBufferObj to remove references to those
* in the shared context hash table.
*/
+ mtx_lock(&ctx->Shared->Mutex);
bind_buffer_object( ctx, GL_ARRAY_BUFFER_ARB, 0);
bind_buffer_object( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
bind_buffer_object( ctx, GL_PIXEL_PACK_BUFFER_ARB, 0);
bind_buffer_object( ctx, GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ mtx_unlock(&ctx->Shared->Mutex);
}
@@ -1094,12 +1121,12 @@ _mesa_multi_bind_lookup_bufferobj(struct gl_context *ctx,
* unbound from all arrays in the current context.
*/
static void
-unbind(struct gl_context *ctx,
- struct gl_buffer_object **ptr,
- struct gl_buffer_object *obj)
+unbind_locked(struct gl_context *ctx,
+ struct gl_buffer_object **ptr,
+ struct gl_buffer_object *obj)
{
if (*ptr == obj) {
- _mesa_reference_buffer_object(ctx, ptr, ctx->Shared->NullBufferObj);
+ reference_bufferobj_locked(ctx, ptr, ctx->Shared->NullBufferObj);
}
}
@@ -1160,7 +1187,13 @@ _mesa_BindBuffer(GLenum target, GLuint buffer)
_mesa_debug(ctx, "glBindBuffer(%s, %u)\n",
_mesa_lookup_enum_by_nr(target), buffer);
+ mtx_lock(&ctx->Shared->Mutex);
bind_buffer_object(ctx, target, buffer);
+ mtx_unlock(&ctx->Shared->Mutex);
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glBindBuffer(%s, %u) exit\n",
+ _mesa_lookup_enum_by_nr(target), buffer);
}
@@ -1196,71 +1229,71 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
/* unbind any vertex pointers bound to this buffer */
for (j = 0; j < ARRAY_SIZE(vao->VertexBinding); j++) {
- unbind(ctx, &vao->VertexBinding[j].BufferObj, bufObj);
+ unbind_locked(ctx, &vao->VertexBinding[j].BufferObj, bufObj);
}
if (ctx->Array.ArrayBufferObj == bufObj) {
- _mesa_BindBuffer( GL_ARRAY_BUFFER_ARB, 0 );
+ bind_buffer_object(ctx, GL_ARRAY_BUFFER_ARB, 0 );
}
if (vao->IndexBufferObj == bufObj) {
- _mesa_BindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
+ bind_buffer_object(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
}
/* unbind ARB_draw_indirect binding point */
if (ctx->DrawIndirectBuffer == bufObj) {
- _mesa_BindBuffer( GL_DRAW_INDIRECT_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_DRAW_INDIRECT_BUFFER, 0 );
}
/* unbind ARB_copy_buffer binding points */
if (ctx->CopyReadBuffer == bufObj) {
- _mesa_BindBuffer( GL_COPY_READ_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_COPY_READ_BUFFER, 0 );
}
if (ctx->CopyWriteBuffer == bufObj) {
- _mesa_BindBuffer( GL_COPY_WRITE_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_COPY_WRITE_BUFFER, 0 );
}
/* unbind transform feedback binding points */
if (ctx->TransformFeedback.CurrentBuffer == bufObj) {
- _mesa_BindBuffer( GL_TRANSFORM_FEEDBACK_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_TRANSFORM_FEEDBACK_BUFFER, 0 );
}
for (j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
if (ctx->TransformFeedback.CurrentObject->Buffers[j] == bufObj) {
- _mesa_BindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, j, 0 );
+ bind_buffer_base_locked(ctx, GL_TRANSFORM_FEEDBACK_BUFFER, j, 0 );
}
}
/* unbind UBO binding points */
for (j = 0; j < ctx->Const.MaxUniformBufferBindings; j++) {
if (ctx->UniformBufferBindings[j].BufferObject == bufObj) {
- _mesa_BindBufferBase( GL_UNIFORM_BUFFER, j, 0 );
+ bind_buffer_base_locked(ctx, GL_UNIFORM_BUFFER, j, 0 );
}
}
if (ctx->UniformBuffer == bufObj) {
- _mesa_BindBuffer( GL_UNIFORM_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_UNIFORM_BUFFER, 0 );
}
/* 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_buffer_base_locked(ctx, GL_ATOMIC_COUNTER_BUFFER, j, 0 );
}
}
if (ctx->AtomicBuffer == bufObj) {
- _mesa_BindBuffer( GL_ATOMIC_COUNTER_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_ATOMIC_COUNTER_BUFFER, 0);
}
/* unbind any pixel pack/unpack pointers bound to this buffer */
if (ctx->Pack.BufferObj == bufObj) {
- _mesa_BindBuffer( GL_PIXEL_PACK_BUFFER_EXT, 0 );
+ bind_buffer_object(ctx, GL_PIXEL_PACK_BUFFER_EXT, 0 );
}
if (ctx->Unpack.BufferObj == bufObj) {
- _mesa_BindBuffer( GL_PIXEL_UNPACK_BUFFER_EXT, 0 );
+ bind_buffer_object(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 0 );
}
if (ctx->Texture.BufferObject == bufObj) {
- _mesa_BindBuffer( GL_TEXTURE_BUFFER, 0 );
+ bind_buffer_object(ctx, GL_TEXTURE_BUFFER, 0 );
}
if (ctx->ExternalVirtualMemoryBuffer == bufObj) {
@@ -1280,7 +1313,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
* which would introduce more runtime overhead than this.
*/
bufObj->DeletePending = GL_TRUE;
- _mesa_reference_buffer_object(ctx, &bufObj, NULL);
+ reference_bufferobj_locked(ctx, &bufObj, NULL);
}
}
@@ -3904,10 +3937,10 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
}
}
-void GLAPIENTRY
-_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+static void
+bind_buffer_base_locked(struct gl_context *ctx,
+ GLenum target, GLuint index, GLuint buffer)
{
- GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
if (buffer == 0) {
@@ -3915,8 +3948,8 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
} else {
bufObj = _mesa_lookup_bufferobj(ctx, buffer);
}
- if (!_mesa_handle_bind_buffer_gen(ctx, target, buffer,
- &bufObj, "glBindBufferBase"))
+ if (!handle_bind_buffer_gen_locked(ctx, target, buffer,
+ &bufObj, "glBindBufferBase"))
return;
if (!bufObj) {
@@ -3971,6 +4004,15 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
}
void GLAPIENTRY
+_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ mtx_lock(&ctx->Shared->Mutex);
+ bind_buffer_base_locked(ctx, target, index, buffer);
+ mtx_unlock(&ctx->Shared->Mutex);
+}
+
+void GLAPIENTRY
_mesa_BindBuffersRange(GLenum target, GLuint first, GLsizei count,
const GLuint *buffers,
const GLintptr *offsets, const GLsizeiptr *sizes)