glsl/linker: Make precision matching optional in intrastage_match
authorNeil Roberts <nroberts@igalia.com>
Tue, 23 Apr 2019 14:52:36 +0000 (16:52 +0200)
committerNeil Roberts <nroberts@igalia.com>
Fri, 14 Jun 2019 07:29:53 +0000 (09:29 +0200)
This function is confusingly also used to match interstage interfaces
as well as intrastage. In the interstage case it needs to avoid
comparing the precisions. This patch adds a parameter to specify
whether to take the precision into account or not so that it can be
used for both cases.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/compiler/glsl/link_interface_blocks.cpp
src/compiler/glsl/linker.cpp
src/compiler/glsl/linker.h

index 801fbcd..d7d228e 100644 (file)
@@ -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;
index c1e1698..7445def 100644 (file)
@@ -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) {
index be92dbf..037b0ef 100644 (file)
@@ -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,