diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index cf5a0f0a0c0..d72b58022ae 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -5483,7 +5483,7 @@
-
+
diff --git a/src/mesa/main/glthread_shaderobj.c b/src/mesa/main/glthread_shaderobj.c
index bbe12140feb..c25eb4ecb6c 100644
--- a/src/mesa/main/glthread_shaderobj.c
+++ b/src/mesa/main/glthread_shaderobj.c
@@ -136,6 +136,17 @@ _mesa_unmarshal_GetActiveUniform(struct gl_context *ctx,
return 0;
}
+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);
+ }
+}
+
void GLAPIENTRY
_mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize,
GLsizei *length, GLint *size, GLenum *type,
@@ -143,12 +154,7 @@ _mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize,
{
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);
- }
+ wait_for_glLinkProgram(ctx);
/* We can execute glGetActiveUniform without syncing if we are sync'd to
* the last calls of glLinkProgram and glDeleteProgram because shader
@@ -160,3 +166,23 @@ _mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize,
_mesa_GetActiveUniform_impl(program, index, bufSize, length, size, type,
name, true);
}
+
+uint32_t
+_mesa_unmarshal_GetUniformLocation(struct gl_context *ctx,
+ const struct marshal_cmd_GetUniformLocation *cmd,
+ const uint64_t *last)
+{
+ unreachable("never executed");
+ return 0;
+}
+
+GLint GLAPIENTRY
+_mesa_marshal_GetUniformLocation(GLuint program, const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ wait_for_glLinkProgram(ctx);
+
+ /* This is thread-safe. See the comment in _mesa_marshal_GetActiveUniform. */
+ return _mesa_GetUniformLocation_impl(program, name, true);
+}
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index 7172cbd0ae4..ee0209ec455 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -996,15 +996,16 @@ _mesa_GetUniformui64vARB(GLuint program, GLint location, GLuint64 *params)
}
-GLint GLAPIENTRY
-_mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
+GLint
+_mesa_GetUniformLocation_impl(GLuint programObj, const GLcharARB *name,
+ bool glthread)
{
struct gl_shader_program *shProg;
GET_CURRENT_CONTEXT(ctx);
- shProg = _mesa_lookup_shader_program_err(ctx, programObj,
- "glGetUniformLocation");
+ shProg = _mesa_lookup_shader_program_err_glthread(ctx, programObj, glthread,
+ "glGetUniformLocation");
if (!shProg || !name)
return -1;
@@ -1014,14 +1015,20 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
* INVALID_OPERATION is generated."
*/
if (shProg->data->LinkStatus == LINKING_FAILURE) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetUniformLocation(program not linked)");
+ _mesa_error_glthread_safe(ctx, GL_INVALID_OPERATION, glthread,
+ "glGetUniformLocation(program not linked)");
return -1;
}
return _mesa_program_resource_location(shProg, GL_UNIFORM, name);
}
+GLint GLAPIENTRY
+_mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
+{
+ return _mesa_GetUniformLocation_impl(programObj, name, false);
+}
+
GLint GLAPIENTRY
_mesa_GetUniformLocation_no_error(GLuint programObj, const GLcharARB *name)
{
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index 70d13b82577..e20dd5acd6b 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -222,6 +222,8 @@ void GLAPIENTRY
_mesa_GetnUniformdvARB(GLuint, GLint, GLsizei, GLdouble *);
void GLAPIENTRY
_mesa_GetUniformdv(GLuint, GLint, GLdouble *);
+GLint
+_mesa_GetUniformLocation_impl(GLuint, const GLcharARB *, bool glthread);
GLint GLAPIENTRY
_mesa_GetUniformLocation(GLuint, const GLcharARB *);
GLint GLAPIENTRY