diff options
author | Marek Olšák <marek.olsak@amd.com> | 2020-10-03 16:11:07 -0400 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2020-11-21 21:02:56 +0000 |
commit | b8684672ff39d49bc2db3564b8c77784606a5d9d (patch) | |
tree | 701946ba7129be5108bcb9de86f4a937de7caa26 | |
parent | 5f820b38d41a3bea956fd79ec6930fea860b50d9 (diff) |
glthread: make glGetActiveUniform return without syncing
We just need to track glLinkProgram and glDeleteProgram.
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7053>
-rw-r--r-- | src/mapi/glapi/gen/gl_API.xml | 11 | ||||
-rw-r--r-- | src/mesa/main/glthread.c | 4 | ||||
-rw-r--r-- | src/mesa/main/glthread.h | 7 | ||||
-rw-r--r-- | src/mesa/main/glthread_shaderobj.c | 43 |
4 files changed, 61 insertions, 4 deletions
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index 15905bb029e..dcdbe80290c 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -5353,7 +5353,8 @@ <glx ignore="true"/> </function> - <function name="DeleteProgram" es2="2.0"> + <function name="DeleteProgram" es2="2.0" + marshal_call_after="_mesa_glthread_ProgramChanged(ctx);"> <param name="program" type="GLuint"/> <glx ignore="true"/> </function> @@ -5394,7 +5395,7 @@ <glx ignore="true"/> </function> - <function name="GetActiveUniform" es2="2.0"> + <function name="GetActiveUniform" es2="2.0" marshal="custom"> <param name="program" type="GLuint"/> <param name="index" type="GLuint"/> <param name="bufSize" type="GLsizei"/> @@ -5523,7 +5524,8 @@ <glx ignore="true"/> </function> - <function name="LinkProgram" es2="2.0" no_error="true"> + <function name="LinkProgram" es2="2.0" no_error="true" + marshal_call_after="_mesa_glthread_ProgramChanged(ctx);"> <param name="program" type="GLuint"/> <glx ignore="true"/> </function> @@ -7701,7 +7703,8 @@ <type name="charARB" size="1" glx_name="CARD8"/> <type name="handleARB" size="4" glx_name="CARD32"/> - <function name="DeleteObjectARB"> + <function name="DeleteObjectARB" + marshal_call_after="_mesa_glthread_ProgramChanged(ctx);"> <param name="obj" type="GLhandleARB"/> <glx ignore="true"/> </function> diff --git a/src/mesa/main/glthread.c b/src/mesa/main/glthread.c index 0c0895b27b7..53d9f03a252 100644 --- a/src/mesa/main/glthread.c +++ b/src/mesa/main/glthread.c @@ -62,6 +62,10 @@ glthread_unmarshal_batch(void *job, int thread_index) 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 diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h index 0f489fb7638..677cbe672ea 100644 --- a/src/mesa/main/glthread.h +++ b/src/mesa/main/glthread.h @@ -182,6 +182,12 @@ struct glthread_state /** Currently-bound buffer object IDs. */ GLuint CurrentArrayBufferName; GLuint CurrentDrawIndirectBufferName; + + /** + * The batch index of the last occurence of glLinkProgram or + * glDeleteProgram or -1 if there is no such enqueued call. + */ + int LastProgramChangeBatch; }; void _mesa_glthread_init(struct gl_context *ctx); @@ -255,6 +261,7 @@ void _mesa_glthread_PopClientAttrib(struct gl_context *ctx); void _mesa_glthread_ClientAttribDefault(struct gl_context *ctx, GLbitfield mask); void _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format, GLsizei stride, const GLvoid *pointer); +void _mesa_glthread_ProgramChanged(struct gl_context *ctx); #ifdef __cplusplus } diff --git a/src/mesa/main/glthread_shaderobj.c b/src/mesa/main/glthread_shaderobj.c index 535485699c9..7c47860390c 100644 --- a/src/mesa/main/glthread_shaderobj.c +++ b/src/mesa/main/glthread_shaderobj.c @@ -23,6 +23,7 @@ #include "glthread_marshal.h" #include "dispatch.h" +#include "uniforms.h" struct marshal_cmd_ShaderSource { @@ -113,3 +114,45 @@ _mesa_marshal_ShaderSource(GLuint shader, GLsizei count, } free(length_tmp); } + +void +_mesa_glthread_ProgramChanged(struct gl_context *ctx) +{ + struct glthread_state *glthread = &ctx->GLThread; + + /* Track the last change. */ + p_atomic_set(&glthread->LastProgramChangeBatch, glthread->next); + _mesa_glthread_flush_batch(ctx); +} + +void +_mesa_unmarshal_GetActiveUniform(struct gl_context *ctx, + const struct marshal_cmd_GetActiveUniform *cmd) +{ + unreachable("never executed"); +} + +void GLAPIENTRY +_mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, + GLsizei *length, GLint *size, GLenum *type, + GLchar * name) +{ + GET_CURRENT_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); + } + + /* We can execute glGetActiveUniform without syncing if we are sync'd to + * the last calls of glLinkProgram and glDeleteProgram because shader + * object IDs and their contents are immutable after those calls and + * also thread-safe because they are shared between contexts. + * glCreateShaderProgram calls glLinkProgram internally and it always + * syncs, so it doesn't need any handling. + */ + _mesa_GetActiveUniform_impl(program, index, bufSize, length, size, type, + name, true); +} |