summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
index 822c558c9b..3098a7f0c9 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
@@ -9,6 +9,8 @@
#include <GLSLANG/ShaderLang.h>
+#include "compiler/translator/compilerdebug.h"
+
namespace sh
{
@@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
return *this;
}
+bool ShaderVariable::operator==(const ShaderVariable &other) const
+{
+ if (type != other.type ||
+ precision != other.precision ||
+ name != other.name ||
+ mappedName != other.mappedName ||
+ arraySize != other.arraySize ||
+ staticUse != other.staticUse ||
+ fields.size() != other.fields.size() ||
+ structName != other.structName)
+ {
+ return false;
+ }
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (fields[ii] != other.fields[ii])
+ return false;
+ }
+ return true;
+}
+
+bool ShaderVariable::findInfoByMappedName(
+ const std::string &mappedFullName,
+ const ShaderVariable **leafVar, std::string *originalFullName) const
+{
+ ASSERT(leafVar && originalFullName);
+ // There are three cases:
+ // 1) the top variable is of struct type;
+ // 2) the top variable is an array;
+ // 3) otherwise.
+ size_t pos = mappedFullName.find_first_of(".[");
+ std::string topName;
+
+ if (pos == std::string::npos)
+ {
+ // Case 3.
+ if (mappedFullName != this->mappedName)
+ return false;
+ *originalFullName = this->name;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ std::string topName = mappedFullName.substr(0, pos);
+ if (topName != this->mappedName)
+ return false;
+ std::string originalName = this->name;
+ std::string remaining;
+ if (mappedFullName[pos] == '[')
+ {
+ // Case 2.
+ size_t closePos = mappedFullName.find_first_of(']');
+ if (closePos < pos || closePos == std::string::npos)
+ return false;
+ // Append '[index]'.
+ originalName += mappedFullName.substr(pos, closePos - pos + 1);
+ if (closePos + 1 == mappedFullName.size())
+ {
+ *originalFullName = originalName;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ // In the form of 'a[0].b', so after ']', '.' is expected.
+ if (mappedFullName[closePos + 1] != '.')
+ return false;
+ remaining = mappedFullName.substr(closePos + 2); // Skip "]."
+ }
+ }
+ else
+ {
+ // Case 1.
+ remaining = mappedFullName.substr(pos + 1); // Skip "."
+ }
+ for (size_t ii = 0; ii < this->fields.size(); ++ii)
+ {
+ const ShaderVariable *fieldVar = NULL;
+ std::string originalFieldName;
+ bool found = fields[ii].findInfoByMappedName(
+ remaining, &fieldVar, &originalFieldName);
+ if (found)
+ {
+ *originalFullName = originalName + "." + originalFieldName;
+ *leafVar = fieldVar;
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+bool ShaderVariable::isSameVariableAtLinkTime(
+ const ShaderVariable &other, bool matchPrecision) const
+{
+ if (type != other.type)
+ return false;
+ if (matchPrecision && precision != other.precision)
+ return false;
+ if (name != other.name)
+ return false;
+ ASSERT(mappedName == other.mappedName);
+ if (arraySize != other.arraySize)
+ return false;
+ if (fields.size() != other.fields.size())
+ return false;
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
+ matchPrecision))
+ {
+ return false;
+ }
+ }
+ if (structName != other.structName)
+ return false;
+ return true;
+}
+
Uniform::Uniform()
{}
@@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other)
return *this;
}
+bool Uniform::operator==(const Uniform &other) const
+{
+ return ShaderVariable::operator==(other);
+}
+
+bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
+{
+ return ShaderVariable::isSameVariableAtLinkTime(other, true);
+}
+
Attribute::Attribute()
: location(-1)
{}
@@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other)
return *this;
}
+bool Attribute::operator==(const Attribute &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ location == other.location);
+}
+
InterfaceBlockField::InterfaceBlockField()
: isRowMajorLayout(false)
{}
@@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o
return *this;
}
+bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ isRowMajorLayout == other.isRowMajorLayout);
+}
+
+bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
+ const InterfaceBlockField &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
+ isRowMajorLayout == other.isRowMajorLayout);
+}
+
Varying::Varying()
: interpolation(INTERPOLATION_SMOOTH),
isInvariant(false)
@@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other)
return *this;
}
+bool Varying::operator==(const Varying &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ interpolation == other.interpolation &&
+ isInvariant == other.isInvariant);
+}
+
+bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
+ interpolation == other.interpolation &&
+ isInvariant == other.isInvariant);
+}
+
InterfaceBlock::InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),