From: Neil Roberts Date: Wed, 24 Apr 2019 10:28:51 +0000 (+0200) Subject: compiler/types: Making comparing record precision optional X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=230d1e8d863f917db42a4afd2623b3eeb28844c3;p=mesa.git compiler/types: Making comparing record precision optional 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 --- diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 8e5087e2e1a..ce6bec7150e 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -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 diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index 9e8b093c9de..23d2ee00fdf 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -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.