compiler/types: Making comparing record precision optional
authorNeil Roberts <nroberts@igalia.com>
Wed, 24 Apr 2019 10:28:51 +0000 (12:28 +0200)
committerNeil Roberts <nroberts@igalia.com>
Fri, 14 Jun 2019 07:29:53 +0000 (09:29 +0200)
On GLES, the interface between vertex and fragment shaders doesn’t
need to have matching precision. This adds an extra argument to
glsl_types::record_compare to disable the precision comparison. This
will later be used for the shader interface check.

In order to make this work this patch also adds a helper function to
recursively compare types while ignoring the precision.

v2: Call record_compare from within compare_no_precision to avoid
    duplicating code (Eric Anholt).

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

index 8e5087e2e1ab61d03767e63e36975a657806e26f..ce6bec7150ef77e8fddb23dfba6bf6ed771009ba 100644 (file)
@@ -1028,10 +1028,40 @@ glsl_type::get_array_instance(const glsl_type *base,
    return (glsl_type *) entry->data;
 }
 
+bool
+glsl_type::compare_no_precision(const glsl_type *b) const
+{
+   if (this == b)
+      return true;
+
+   if (this->is_array()) {
+      if (!b->is_array() || this->length != b->length)
+         return false;
+
+      const glsl_type *b_no_array = b->fields.array;
+
+      return this->fields.array->compare_no_precision(b_no_array);
+   }
+
+   if (this->is_struct()) {
+      if (!b->is_struct())
+         return false;
+   } else if (this->is_interface()) {
+      if (!b->is_interface())
+         return false;
+   } else {
+      return false;
+   }
+
+   return record_compare(b,
+                         true, /* match_name */
+                         true, /* match_locations */
+                         false /* match_precision */);
+}
 
 bool
 glsl_type::record_compare(const glsl_type *b, bool match_name,
-                          bool match_locations) const
+                          bool match_locations, bool match_precision) const
 {
    if (this->length != b->length)
       return false;
@@ -1060,8 +1090,15 @@ glsl_type::record_compare(const glsl_type *b, bool match_name,
          return false;
 
    for (unsigned i = 0; i < this->length; i++) {
-      if (this->fields.structure[i].type != b->fields.structure[i].type)
-         return false;
+      if (match_precision) {
+         if (this->fields.structure[i].type != b->fields.structure[i].type)
+            return false;
+      } else {
+         const glsl_type *ta = this->fields.structure[i].type;
+         const glsl_type *tb = b->fields.structure[i].type;
+         if (!ta->compare_no_precision(tb))
+            return false;
+      }
       if (strcmp(this->fields.structure[i].name,
                  b->fields.structure[i].name) != 0)
          return false;
@@ -1104,7 +1141,8 @@ glsl_type::record_compare(const glsl_type *b, bool match_name,
       if (this->fields.structure[i].image_format
           != b->fields.structure[i].image_format)
          return false;
-      if (this->fields.structure[i].precision
+      if (match_precision &&
+          this->fields.structure[i].precision
           != b->fields.structure[i].precision)
          return false;
       if (this->fields.structure[i].explicit_xfb_buffer
index 9e8b093c9de78b470c76bdf54aa8f36e746d67ba..23d2ee00fdf547378c40eed5eb85a4982d3db5b4 100644 (file)
@@ -938,6 +938,15 @@ public:
     */
    int coordinate_components() const;
 
+   /**
+    * Compares whether this type matches another type without taking into
+    * account the precision in structures.
+    *
+    * This is applied recursively so that structures containing structure
+    * members can also ignore the precision.
+    */
+   bool compare_no_precision(const glsl_type *b) const;
+
    /**
     * Compare a record type against another record type.
     *
@@ -949,7 +958,8 @@ public:
     * same struct is defined in a block which has a location set on it.
     */
    bool record_compare(const glsl_type *b, bool match_name,
-                       bool match_locations = true) const;
+                       bool match_locations = true,
+                       bool match_precision = true) const;
 
    /**
     * Get the type interface packing.