diff --git a/.pick_status.json b/.pick_status.json index 6fbd4b3c300..7dc8b9241ba 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1094,7 +1094,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 diff --git a/src/mesa/main/shader_types.h b/src/mesa/main/shader_types.h index f60917fa235..3bd6f1395a8 100644 --- a/src/mesa/main/shader_types.h +++ b/src/mesa/main/shader_types.h @@ -791,6 +791,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. @@ -877,6 +880,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 diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index fc7708f2796..89031914d65 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -1261,7 +1261,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)) { @@ -1283,6 +1283,16 @@ _mesa_flush_vertices_for_uniforms(struct gl_context *ctx, FLUSH_VERTICES(ctx, BITSET_IS_EMPTY(new_driver_state) ? _NEW_PROGRAM_CONSTANTS : 0, 0); ST_SET_STATES(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 @@ -1298,6 +1308,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; @@ -1638,6 +1653,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); @@ -2094,7 +2114,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) { @@ -2109,7 +2129,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); diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index 7d8e7601ca1..a4036a3924e 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -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,