mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 07:20:10 +01:00
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 commit34db720660)
This commit is contained in:
parent
fa480da7fd
commit
712cbacf51
4 changed files with 33 additions and 5 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue