bool
intrastage_match(ir_variable *a,
ir_variable *b,
- struct gl_shader_program *prog)
+ struct gl_shader_program *prog,
+ bool match_precision)
{
/* Types must match. */
if (a->get_interface_type() != b->get_interface_type()) {
return false;
}
+ bool type_match = (match_precision ?
+ a->type == b->type :
+ a->type->compare_no_precision(b->type));
+
/* If a block is an array then it must match across the shader.
* Unsized arrays are also processed and matched agaist sized arrays.
*/
- if (b->type != a->type && (b->type->is_array() || a->type->is_array()) &&
+ if (!type_match && (b->type->is_array() || a->type->is_array()) &&
(b->is_interface_instance() || a->is_interface_instance()) &&
- !validate_intrastage_arrays(prog, b, a))
+ !validate_intrastage_arrays(prog, b, a, match_precision))
return false;
return true;
* it into the appropriate data structure.
*/
definitions->store(var);
- } else if (!intrastage_match(prev_def, var, prog)) {
+ } else if (!intrastage_match(prev_def, var, prog,
+ true /* match_precision */)) {
linker_error(prog, "definitions of interface block `%s' do not"
" match\n", iface_type->name);
return;
* uniform matchin rules (for uniforms, it is as though all
* shaders are in the same shader stage).
*/
- if (!intrastage_match(old_def, var, prog)) {
+ if (!intrastage_match(old_def, var, prog, false /* precision */)) {
linker_error(prog, "definitions of uniform block `%s' do not "
"match\n", var->get_interface_type()->name);
return;
bool
validate_intrastage_arrays(struct gl_shader_program *prog,
ir_variable *const var,
- ir_variable *const existing)
+ ir_variable *const existing,
+ bool match_precision)
{
/* Consider the types to be "the same" if both types are arrays
* of the same type and one of the arrays is implicitly sized.
* explicitly sized array.
*/
if (var->type->is_array() && existing->type->is_array()) {
- if ((var->type->fields.array == existing->type->fields.array) &&
+ const glsl_type *no_array_var = var->type->fields.array;
+ const glsl_type *no_array_existing = existing->type->fields.array;
+ bool type_matches;
+
+ type_matches = (match_precision ?
+ no_array_var == no_array_existing :
+ no_array_var->compare_no_precision(no_array_existing));
+
+ if (type_matches &&
((var->type->length == 0)|| (existing->type->length == 0))) {
if (var->type->length != 0) {
if ((int)var->type->length <= existing->data.max_array_access) {