diff --git a/.pick_status.json b/.pick_status.json index f82e8391900..c6f37bad8df 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/mesa/main/shader_types.h b/src/mesa/main/shader_types.h index 0e27dc7dac0..ec6863c66bd 100644 --- a/src/mesa/main/shader_types.h +++ b/src/mesa/main/shader_types.h @@ -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 diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index 296d023c9d1..b23e28140dc 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -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); 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,