mesa: skip redundant uniform update optimisation if unsafe

If multiple contexts are updating uniform values we can't assume
a uniform update can skip flushing.

Fixes: b32e20e630 ("mesa: skip redundant uniform updates for glUniformHandle")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14129

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38101>
(cherry picked from commit 34db720660)
This commit is contained in:
Timothy Arceri 2025-10-28 12:02:31 +11:00 committed by Eric Engestrom
parent fa480da7fd
commit 712cbacf51
4 changed files with 33 additions and 5 deletions

View file

@ -2284,7 +2284,7 @@
"description": "mesa: skip redundant uniform update optimisation if unsafe",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "b32e20e6301f2c1bfb25a939bddfeaa41d43c8c9",
"notes": null

View file

@ -778,6 +778,9 @@ struct gl_opaque_uniform_index {
struct gl_uniform_storage {
struct gl_resource_name name;
/* The context that first set any uniform values */
struct gl_context *first_set_by;
/** Type of this uniform data stored.
*
* In the case of an array, it's the type of a single array element.
@ -864,6 +867,11 @@ struct gl_uniform_storage {
*/
bool is_shader_storage;
/* Set to true if the uniform storage has been updated by more than one
* context.
*/
bool unknown_src_ctx;
/**
* Index within gl_shader_program::AtomicBuffers[] of the atomic
* counter buffer this uniform is stored in, or -1 if this is not

View file

@ -1257,7 +1257,7 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values,
void
_mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
const struct gl_uniform_storage *uni)
struct gl_uniform_storage *uni)
{
/* Opaque uniforms have no storage unless they are bindless */
if (!uni->is_bindless && glsl_contains_opaque(uni->type)) {
@ -1279,6 +1279,16 @@ _mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS, 0);
ctx->NewDriverState |= new_driver_state;
/* If we are updating the uniform from multiple contexts we cant be sure
* if a context needs to be flushed so set the unknown_src_ctx flag which
* will cause the "redundant uniform update" optimisation to be skipped.
*/
if (uni->first_set_by) {
if (uni->first_set_by != ctx)
uni->unknown_src_ctx = true;
} else
uni->first_set_by = ctx;
}
static bool
@ -1294,6 +1304,11 @@ copy_uniforms_to_storage(gl_constant_value *storage,
(glsl_type_is_sampler(uni->type) || glsl_type_is_image(uni->type));
bool copy_to_float16 = uni->type->base_type == GLSL_TYPE_FLOAT16;
if (flush && uni->unknown_src_ctx) {
_mesa_flush_vertices_for_uniforms(ctx, uni);
flush = false;
}
if (!glsl_type_is_boolean(uni->type) && !copy_as_uint64 && !copy_to_float16) {
unsigned size = sizeof(storage[0]) * components * count * size_mul;
@ -1634,6 +1649,11 @@ copy_uniform_matrix_to_storage(struct gl_context *ctx,
const unsigned elements = components * vectors;
const unsigned size = sizeof(storage[0]) * elements * count * size_mul;
if (flush && uni->unknown_src_ctx) {
_mesa_flush_vertices_for_uniforms(ctx, uni);
flush = false;
}
if (uni->type->base_type == GLSL_TYPE_FLOAT16) {
assert(ctx->Const.PackedDriverUniformStorage);
const unsigned dst_components = align(components, 2);
@ -2087,7 +2107,7 @@ _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
uni->driver_storage[s].data + (size_mul * offset * components);
unsigned size = sizeof(uni->storage[0]) * components * count * size_mul;
if (!memcmp(storage, values, size))
if (!uni->unknown_src_ctx && !memcmp(storage, values, size))
continue;
if (!flushed) {
@ -2102,7 +2122,7 @@ _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
void *storage = &uni->storage[size_mul * components * offset];
unsigned size = sizeof(uni->storage[0]) * components * count * size_mul;
if (!memcmp(storage, values, size))
if (!uni->unknown_src_ctx && !memcmp(storage, values, size))
return;
_mesa_flush_vertices_for_uniforms(ctx, uni);

View file

@ -91,7 +91,7 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *);
extern void
_mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
const struct gl_uniform_storage *uni);
struct gl_uniform_storage *uni);
extern GLint
_mesa_GetUniformLocation_impl(GLuint programObj, const GLcharARB *name,