From 230d1e8d863f917db42a4afd2623b3eeb28844c3 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Wed, 24 Apr 2019 12:28:51 +0200 Subject: [PATCH] compiler/types: Making comparing record precision optional MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/compiler/glsl_types.cpp | 46 +++++++++++++++++++++++++++++++++++++++++---- src/compiler/glsl_types.h | 12 +++++++++++- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 8e5087e..ce6bec7 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 9e8b093..23d2ee0 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -939,6 +939,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. * * This is useful for matching record types declared on the same shader @@ -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. -- 2.7.4