diff options
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r-- | src/compiler/glsl/link_interface_blocks.cpp | 16 | ||||
-rw-r--r-- | src/compiler/glsl/linker.cpp | 13 | ||||
-rw-r--r-- | src/compiler/glsl/linker.h | 3 |
3 files changed, 24 insertions, 8 deletions
diff --git a/src/compiler/glsl/link_interface_blocks.cpp b/src/compiler/glsl/link_interface_blocks.cpp index 801fbcd5d9f..d7d228ee1a5 100644 --- a/src/compiler/glsl/link_interface_blocks.cpp +++ b/src/compiler/glsl/link_interface_blocks.cpp @@ -106,7 +106,8 @@ interstage_member_mismatch(struct gl_shader_program *prog, 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()) { @@ -136,12 +137,16 @@ intrastage_match(ir_variable *a, 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; @@ -337,7 +342,8 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog, * 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; @@ -467,7 +473,7 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog, * 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; diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index c1e16983de6..7445def6aa4 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -854,7 +854,8 @@ validate_geometry_shader_emissions(struct gl_context *ctx, 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. @@ -862,7 +863,15 @@ validate_intrastage_arrays(struct gl_shader_program *prog, * 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) { diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h index be92dbf983c..037b0ef4725 100644 --- a/src/compiler/glsl/linker.h +++ b/src/compiler/glsl/linker.h @@ -65,7 +65,8 @@ link_uniform_blocks(void *mem_ctx, bool validate_intrastage_arrays(struct gl_shader_program *prog, ir_variable *const var, - ir_variable *const existing); + ir_variable *const existing, + bool match_precision = true); void validate_intrastage_interface_blocks(struct gl_shader_program *prog, |