glsl/linker: fix output variable overlap check

Prevent an overflow caused by too many output variables. To limit the
scope of the issue, write to the assigned array only for the non-ES
fragment shader path, which is the only place where it's needed.

Since the function will bail with an error when output variables with
overlapping components are found, (max # of FS outputs) * 4 is an upper
limit to the space we need.

Found by address sanitizer.

Fixes dEQP-GLES3.functional.attribute_location.bind_aliasing.*

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
(cherry picked from commit 15cae12804)

Squashed with commit:

glsl/linker: properly fix output variable overlap check

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102904
Fixes: 15cae12804 ("glsl/linker: fix output variable overlap check")
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
(cherry picked from commit df8767a14e)

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
This commit is contained in:
Nicolai Hähnle 2017-09-17 18:25:39 +02:00 committed by Juan A. Suarez Romero
parent 6121bc3150
commit 46cfefc5be

View file

@ -2661,12 +2661,14 @@ assign_attribute_or_color_locations(void *mem_ctx,
} to_assign[32];
assert(max_index <= 32);
/* Temporary array for the set of attributes that have locations assigned.
/* Temporary array for the set of attributes that have locations assigned,
* for the purpose of checking overlapping slots/components of (non-ES)
* fragment shader outputs.
*/
ir_variable *assigned[16];
ir_variable *assigned[12 * 4]; /* (max # of FS outputs) * # components */
unsigned assigned_attr = 0;
unsigned num_attr = 0;
unsigned assigned_attr = 0;
foreach_in_list(ir_instruction, node, sh->ir) {
ir_variable *const var = node->as_variable();
@ -2905,6 +2907,18 @@ assign_attribute_or_color_locations(void *mem_ctx,
}
}
if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) {
/* Only track assigned variables for non-ES fragment shaders
* to avoid overflowing the array.
*
* At most one variable per fragment output component should
* reach this.
*/
assert(assigned_attr < ARRAY_SIZE(assigned));
assigned[assigned_attr] = var;
assigned_attr++;
}
used_locations |= (use_mask << attr);
/* From the GL 4.5 core spec, section 11.1.1 (Vertex Attributes):
@ -2931,9 +2945,6 @@ assign_attribute_or_color_locations(void *mem_ctx,
double_storage_locations |= (use_mask << attr);
}
assigned[assigned_attr] = var;
assigned_attr++;
continue;
}