mesa: lock Shared->BufferObjects only once for a glthread batch

This removes a lot of locking from the driver thread.

If multiple contexts sharing buffers submit GL calls from multiple threads,
they will be serialized by this mutex. I can add a driconf option to turn
off this optimization if needed, but I currently don't anticipate to see
GL apps that use multiple shared contexts in different threads
simultaneously.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7053>
This commit is contained in:
Marek Olšák
2020-10-03 16:52:25 -04:00
committed by Marge Bot
parent b8684672ff
commit 8e7270de55
5 changed files with 92 additions and 18 deletions
+33 -16
View File
@@ -590,7 +590,8 @@ _mesa_total_buffer_object_memory(struct gl_context *ctx)
{
GLuint total = 0;
_mesa_HashWalk(ctx->Shared->BufferObjects, count_buffer_size, &total);
_mesa_HashWalkMaybeLocked(ctx->Shared->BufferObjects, count_buffer_size,
&total, ctx->BufferObjectsLocked);
return total;
}
@@ -969,7 +970,9 @@ _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_handle, buf != NULL);
_mesa_HashInsertMaybeLocked(ctx->Shared->BufferObjects, buffer,
*buf_handle, buf != NULL,
ctx->BufferObjectsLocked);
}
return true;
@@ -1042,7 +1045,8 @@ _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer)
return NULL;
else
return (struct gl_buffer_object *)
_mesa_HashLookup(ctx->Shared->BufferObjects, buffer);
_mesa_HashLookupMaybeLocked(ctx->Shared->BufferObjects, buffer,
ctx->BufferObjectsLocked);
}
@@ -1454,7 +1458,8 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids)
{
FLUSH_VERTICES(ctx, 0);
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
for (GLsizei i = 0; i < n; i++) {
struct gl_buffer_object *bufObj =
@@ -1585,7 +1590,8 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids)
}
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}
@@ -1627,7 +1633,8 @@ create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
/*
* This must be atomic (generation and allocation of buffer object IDs)
*/
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
_mesa_HashFindFreeKeys(ctx->Shared->BufferObjects, buffers, n);
@@ -1641,7 +1648,8 @@ create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
buf = ctx->Driver.NewBufferObject(ctx, buffers[i]);
if (!buf) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCreateBuffers");
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
return;
}
}
@@ -1651,7 +1659,8 @@ create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
_mesa_HashInsertLocked(ctx->Shared->BufferObjects, buffers[i], buf, true);
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}
@@ -4058,7 +4067,8 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count,
* parameters are valid and no other error occurs."
*/
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
for (int i = 0; i < count; i++) {
struct gl_buffer_binding *binding =
@@ -4109,7 +4119,8 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count,
USAGE_UNIFORM_BUFFER);
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}
static void
@@ -4159,7 +4170,8 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
* parameters are valid and no other error occurs."
*/
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
for (int i = 0; i < count; i++) {
struct gl_buffer_binding *binding =
@@ -4210,7 +4222,8 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
USAGE_SHADER_STORAGE_BUFFER);
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}
static bool
@@ -4325,7 +4338,8 @@ bind_xfb_buffers(struct gl_context *ctx,
* parameters are valid and no other error occurs."
*/
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
for (int i = 0; i < count; i++) {
const GLuint index = first + i;
@@ -4392,7 +4406,8 @@ bind_xfb_buffers(struct gl_context *ctx,
offset, size);
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}
static bool
@@ -4484,7 +4499,8 @@ bind_atomic_buffers(struct gl_context *ctx,
* parameters are valid and no other error occurs."
*/
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
for (int i = 0; i < count; i++) {
struct gl_buffer_binding *binding =
@@ -4532,7 +4548,8 @@ bind_atomic_buffers(struct gl_context *ctx,
USAGE_ATOMIC_COUNTER_BUFFER);
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}
static ALWAYS_INLINE void
+7
View File
@@ -52,6 +52,9 @@ glthread_unmarshal_batch(void *job, int thread_index)
_glapi_set_dispatch(ctx->CurrentServerDispatch);
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
ctx->BufferObjectsLocked = true;
while (pos < used) {
const struct marshal_cmd_base *cmd =
(const struct marshal_cmd_base *)&buffer[pos];
@@ -60,12 +63,16 @@ glthread_unmarshal_batch(void *job, int thread_index)
pos += cmd->cmd_size;
}
ctx->BufferObjectsLocked = false;
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
assert(pos == used);
batch->used = 0;
unsigned batch_index = batch - ctx->GLThread.batches;
/* Atomically set this to -1 if it's equal to batch_index. */
p_atomic_cmpxchg(&ctx->GLThread.LastProgramChangeBatch, batch_index, -1);
}
static void
+45
View File
@@ -188,5 +188,50 @@ extern void _mesa_test_hash_functions(void);
extern void _mesa_HashEnableNameReuse(struct _mesa_HashTable *table);
static inline void
_mesa_HashWalkMaybeLocked(const struct _mesa_HashTable *table,
void (*callback)(void *data, void *userData),
void *userData, bool locked)
{
if (locked)
_mesa_HashWalkLocked(table, callback, userData);
else
_mesa_HashWalk(table, callback, userData);
}
static inline struct gl_buffer_object *
_mesa_HashLookupMaybeLocked(struct _mesa_HashTable *table, GLuint key,
bool locked)
{
if (locked)
return _mesa_HashLookupLocked(table, key);
else
return _mesa_HashLookup(table, key);
}
static inline void
_mesa_HashInsertMaybeLocked(struct _mesa_HashTable *table,
GLuint key, void *data, GLboolean isGenName,
bool locked)
{
if (locked)
_mesa_HashInsertLocked(table, key, data, isGenName);
else
_mesa_HashInsert(table, key, data, isGenName);
}
static inline void
_mesa_HashLockMaybeLocked(struct _mesa_HashTable *table, bool locked)
{
if (!locked)
_mesa_HashLockMutex(table);
}
static inline void
_mesa_HashUnlockMaybeLocked(struct _mesa_HashTable *table, bool locked)
{
if (!locked)
_mesa_HashUnlockMutex(table);
}
#endif
+3
View File
@@ -4926,6 +4926,9 @@ struct gl_context
/** State possibly shared with other contexts in the address space */
struct gl_shared_state *Shared;
/** Whether Shared->BufferObjects has already been locked for this context. */
bool BufferObjectsLocked;
/** \name API function pointer tables */
/*@{*/
gl_api API;
+4 -2
View File
@@ -3130,7 +3130,8 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
* their parameters are valid and no other error occurs."
*/
_mesa_HashLockMutex(ctx->Shared->BufferObjects);
_mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
for (i = 0; i < count; i++) {
struct gl_buffer_object *vbo;
@@ -3187,7 +3188,8 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
vbo, offsets[i], strides[i], false, false);
}
_mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
_mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects,
ctx->BufferObjectsLocked);
}