Mesa (master): glthread: make glGetActiveUniform return without syncing

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Nov 21 21:21:13 UTC 2020


Module: Mesa
Branch: master
Commit: b8684672ff39d49bc2db3564b8c77784606a5d9d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8684672ff39d49bc2db3564b8c77784606a5d9d

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sat Oct  3 16:11:07 2020 -0400

glthread: make glGetActiveUniform return without syncing

We just need to track glLinkProgram and glDeleteProgram.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7053>

---

 src/mapi/glapi/gen/gl_API.xml      | 11 ++++++----
 src/mesa/main/glthread.c           |  4 ++++
 src/mesa/main/glthread.h           |  7 +++++++
 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);
+}



More information about the mesa-commit mailing list