glthread: add proper helpers for call fences

These wait for a GL call to be processed by the consumer thread.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26916>
This commit is contained in:
Marek Olšák 2023-07-17 08:03:31 -04:00 committed by Marge Bot
parent 56b4d199a0
commit 4ee32ced41
3 changed files with 42 additions and 23 deletions

View file

@ -150,9 +150,8 @@ glthread_unmarshal_batch(void *job, void *gdata, int thread_index)
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);
p_atomic_cmpxchg(&ctx->GLThread.LastDListChangeBatchIndex, batch_index, -1);
_mesa_glthread_signal_call(&ctx->GLThread.LastProgramChangeBatch, batch_index);
_mesa_glthread_signal_call(&ctx->GLThread.LastDListChangeBatchIndex, batch_index);
p_atomic_inc(&ctx->GLThread.stats.num_batches);
}
@ -222,7 +221,8 @@ _mesa_glthread_init(struct gl_context *ctx)
glthread->used = 0;
glthread->stats.queue = &glthread->queue;
glthread->LastDListChangeBatchIndex = -1;
_mesa_glthread_init_call_fence(&glthread->LastProgramChangeBatch);
_mesa_glthread_init_call_fence(&glthread->LastDListChangeBatchIndex);
/* glthread takes over all L3 pinning */
ctx->st->pin_thread_counter = ST_L3_PINNING_DISABLED;

View file

@ -725,6 +725,39 @@ _mesa_glthread_ListBase(struct gl_context *ctx, GLuint base)
ctx->GLThread.ListBase = base;
}
static inline void
_mesa_glthread_init_call_fence(int *last_batch_index_where_called)
{
*last_batch_index_where_called = -1;
}
static inline void
_mesa_glthread_fence_call(struct gl_context *ctx,
int *last_batch_index_where_called)
{
p_atomic_set(last_batch_index_where_called, ctx->GLThread.next);
/* Flush, so that the fenced call is last in the batch. */
_mesa_glthread_flush_batch(ctx);
}
static inline void
_mesa_glthread_signal_call(int *last_batch_index_where_called, int batch_index)
{
/* Atomically set this to -1 if it's equal to batch_index. */
p_atomic_cmpxchg(last_batch_index_where_called, batch_index, -1);
}
static inline void
_mesa_glthread_wait_for_call(struct gl_context *ctx,
int *last_batch_index_where_called)
{
int batch = p_atomic_read(last_batch_index_where_called);
if (batch != -1) {
util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
assert(p_atomic_read(last_batch_index_where_called) == -1);
}
}
static inline void
_mesa_glthread_CallList(struct gl_context *ctx, GLuint list)
{
@ -735,11 +768,7 @@ _mesa_glthread_CallList(struct gl_context *ctx, GLuint list)
* all display lists are up to date and the driver thread is not
* modifiying them. We will be executing them in the application thread.
*/
int batch = p_atomic_read(&ctx->GLThread.LastDListChangeBatchIndex);
if (batch != -1) {
util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, -1);
}
_mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
if (!ctx->Shared->DisplayListsAffectGLThread)
return;
@ -767,11 +796,7 @@ _mesa_glthread_CallLists(struct gl_context *ctx, GLsizei n, GLenum type,
* all display lists are up to date and the driver thread is not
* modifiying them. We will be executing them in the application thread.
*/
int batch = p_atomic_read(&ctx->GLThread.LastDListChangeBatchIndex);
if (batch != -1) {
util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, -1);
}
_mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
/* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */
unsigned saved_mode = ctx->GLThread.ListMode;
@ -871,8 +896,7 @@ _mesa_glthread_EndList(struct gl_context *ctx)
ctx->GLThread.ListMode = 0;
/* Track the last display list change. */
p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next);
_mesa_glthread_flush_batch(ctx);
_mesa_glthread_fence_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
}
static inline void
@ -882,8 +906,7 @@ _mesa_glthread_DeleteLists(struct gl_context *ctx, GLsizei range)
return;
/* Track the last display list change. */
p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next);
_mesa_glthread_flush_batch(ctx);
_mesa_glthread_fence_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex);
}
static inline void

View file

@ -48,11 +48,7 @@ static void
wait_for_glLinkProgram(struct gl_context *ctx)
{
/* Wait for the last glLinkProgram call. */
int batch = p_atomic_read(&ctx->GLThread.LastProgramChangeBatch);
if (batch != -1) {
util_queue_fence_wait(&ctx->GLThread.batches[batch].fence);
assert(p_atomic_read(&ctx->GLThread.LastProgramChangeBatch) == -1);
}
_mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastProgramChangeBatch);
}
void GLAPIENTRY