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.cpp397
1 files changed, 291 insertions, 106 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
index 8f931b9bdd..4ab574e935 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
@@ -10,6 +10,7 @@
#include <GLSLANG/ShaderLang.h>
#include "common/debug.h"
+#include "common/utilities.h"
namespace sh
{
@@ -21,7 +22,6 @@ InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolati
{
return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
}
-
}
// The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
// on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
@@ -32,55 +32,58 @@ bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
}
ShaderVariable::ShaderVariable()
- : type(0),
- precision(0),
- arraySize(0),
- staticUse(false)
-{}
+ : type(0), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+{
+}
+
+ShaderVariable::ShaderVariable(GLenum typeIn)
+ : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+{
+}
ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
- : type(typeIn),
- precision(0),
- arraySize(arraySizeIn),
- staticUse(false)
-{}
+ : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false)
+{
+ ASSERT(arraySizeIn != 0);
+ arraySizes.push_back(arraySizeIn);
+}
ShaderVariable::~ShaderVariable()
-{}
+{
+}
ShaderVariable::ShaderVariable(const ShaderVariable &other)
: type(other.type),
precision(other.precision),
name(other.name),
mappedName(other.mappedName),
- arraySize(other.arraySize),
+ arraySizes(other.arraySizes),
+ flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays),
staticUse(other.staticUse),
fields(other.fields),
structName(other.structName)
-{}
+{
+}
ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
{
- type = other.type;
- precision = other.precision;
- name = other.name;
+ type = other.type;
+ precision = other.precision;
+ name = other.name;
mappedName = other.mappedName;
- arraySize = other.arraySize;
- staticUse = other.staticUse;
- fields = other.fields;
+ arraySizes = other.arraySizes;
+ staticUse = other.staticUse;
+ flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
+ fields = other.fields;
structName = other.structName;
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() ||
+ if (type != other.type || precision != other.precision || name != other.name ||
+ mappedName != other.mappedName || arraySizes != other.arraySizes ||
+ staticUse != other.staticUse || fields.size() != other.fields.size() ||
structName != other.structName)
{
return false;
@@ -93,9 +96,52 @@ bool ShaderVariable::operator==(const ShaderVariable &other) const
return true;
}
-bool ShaderVariable::findInfoByMappedName(
- const std::string &mappedFullName,
- const ShaderVariable **leafVar, std::string *originalFullName) const
+void ShaderVariable::setArraySize(unsigned int size)
+{
+ arraySizes.clear();
+ if (size != 0)
+ {
+ arraySizes.push_back(size);
+ }
+}
+
+unsigned int ShaderVariable::getArraySizeProduct() const
+{
+ return gl::ArraySizeProduct(arraySizes);
+}
+
+void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
+{
+ ASSERT(isArray());
+ flattenedOffsetInParentArrays =
+ arrayIndex + getOutermostArraySize() * flattenedOffsetInParentArrays;
+ arraySizes.pop_back();
+}
+
+unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
+{
+ ASSERT(arraySizes.size() > arrayNestingIndex);
+ return arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
+}
+
+unsigned int ShaderVariable::getBasicTypeElementCount() const
+{
+ // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated
+ // for each array element when dealing with an array of arrays or an array of structs.
+ ASSERT(!isArrayOfArrays());
+ ASSERT(!isStruct() || !isArray());
+
+ // GLES 3.1 Nov 2016 page 82.
+ if (isArray())
+ {
+ return getOutermostArraySize();
+ }
+ return 1u;
+}
+
+bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string *originalFullName) const
{
ASSERT(leafVar && originalFullName);
// There are three cases:
@@ -110,7 +156,7 @@ bool ShaderVariable::findInfoByMappedName(
if (mappedFullName != this->mappedName)
return false;
*originalFullName = this->name;
- *leafVar = this;
+ *leafVar = this;
return true;
}
else
@@ -131,13 +177,13 @@ bool ShaderVariable::findInfoByMappedName(
if (closePos + 1 == mappedFullName.size())
{
*originalFullName = originalName;
- *leafVar = this;
+ *leafVar = this;
return true;
}
else
{
// In the form of 'a[0].b', so after ']', '.' is expected.
- if (mappedFullName[closePos + 1] != '.')
+ if (mappedFullName[closePos + 1] != '.')
return false;
remaining = mappedFullName.substr(closePos + 2); // Skip "]."
}
@@ -149,14 +195,13 @@ bool ShaderVariable::findInfoByMappedName(
}
for (size_t ii = 0; ii < this->fields.size(); ++ii)
{
- const ShaderVariable *fieldVar = NULL;
+ const ShaderVariable *fieldVar = nullptr;
std::string originalFieldName;
- bool found = fields[ii].findInfoByMappedName(
- remaining, &fieldVar, &originalFieldName);
+ bool found = fields[ii].findInfoByMappedName(remaining, &fieldVar, &originalFieldName);
if (found)
{
*originalFullName = originalName + "." + originalFieldName;
- *leafVar = fieldVar;
+ *leafVar = fieldVar;
return true;
}
}
@@ -164,24 +209,33 @@ bool ShaderVariable::findInfoByMappedName(
}
}
-bool ShaderVariable::isSameVariableAtLinkTime(
- const ShaderVariable &other, bool matchPrecision) const
+bool ShaderVariable::isBuiltIn() const
+{
+ return (name.size() >= 4 && name[0] == 'g' && name[1] == 'l' && name[2] == '_');
+}
+
+bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision,
+ bool matchName) const
{
if (type != other.type)
return false;
if (matchPrecision && precision != other.precision)
return false;
- if (name != other.name)
+ if (matchName && name != other.name)
return false;
- ASSERT(mappedName == other.mappedName);
- if (arraySize != other.arraySize)
+ ASSERT(!matchName || mappedName == other.mappedName);
+ if (arraySizes != other.arraySizes)
return false;
if (fields.size() != other.fields.size())
return false;
+
+ // [OpenGL ES 3.1 SPEC Chapter 7.4.1]
+ // Variables declared as structures are considered to match in type if and only if structure
+ // members match in name, type, qualification, and declaration order.
for (size_t ii = 0; ii < fields.size(); ++ii)
{
- if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
- matchPrecision))
+ if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], matchPrecision, true))
{
return false;
}
@@ -191,53 +245,75 @@ bool ShaderVariable::isSameVariableAtLinkTime(
return true;
}
-Uniform::Uniform()
-{}
+Uniform::Uniform() : binding(-1), offset(-1)
+{
+}
Uniform::~Uniform()
-{}
+{
+}
Uniform::Uniform(const Uniform &other)
- : ShaderVariable(other)
-{}
+ : VariableWithLocation(other), binding(other.binding), offset(other.offset)
+{
+}
Uniform &Uniform::operator=(const Uniform &other)
{
- ShaderVariable::operator=(other);
+ VariableWithLocation::operator=(other);
+ binding = other.binding;
+ offset = other.offset;
return *this;
}
bool Uniform::operator==(const Uniform &other) const
{
- return ShaderVariable::operator==(other);
+ return VariableWithLocation::operator==(other) && binding == other.binding &&
+ offset == other.offset;
}
bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
{
- return ShaderVariable::isSameVariableAtLinkTime(other, true);
+ // Enforce a consistent match.
+ // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
+ if (binding != -1 && other.binding != -1 && binding != other.binding)
+ {
+ return false;
+ }
+ if (location != -1 && other.location != -1 && location != other.location)
+ {
+ return false;
+ }
+ if (offset != other.offset)
+ {
+ return false;
+ }
+ return VariableWithLocation::isSameVariableAtLinkTime(other, true, true);
}
-InterfaceVariable::InterfaceVariable() : location(-1)
-{}
+VariableWithLocation::VariableWithLocation() : location(-1)
+{
+}
-InterfaceVariable::~InterfaceVariable()
-{}
+VariableWithLocation::~VariableWithLocation()
+{
+}
-InterfaceVariable::InterfaceVariable(const InterfaceVariable &other)
+VariableWithLocation::VariableWithLocation(const VariableWithLocation &other)
: ShaderVariable(other), location(other.location)
-{}
+{
+}
-InterfaceVariable &InterfaceVariable::operator=(const InterfaceVariable &other)
+VariableWithLocation &VariableWithLocation::operator=(const VariableWithLocation &other)
{
ShaderVariable::operator=(other);
- location = other.location;
+ location = other.location;
return *this;
}
-bool InterfaceVariable::operator==(const InterfaceVariable &other) const
+bool VariableWithLocation::operator==(const VariableWithLocation &other) const
{
- return (ShaderVariable::operator==(other) &&
- location == other.location);
+ return (ShaderVariable::operator==(other) && location == other.location);
}
Attribute::Attribute()
@@ -248,19 +324,19 @@ Attribute::~Attribute()
{
}
-Attribute::Attribute(const Attribute &other) : InterfaceVariable(other)
+Attribute::Attribute(const Attribute &other) : VariableWithLocation(other)
{
}
Attribute &Attribute::operator=(const Attribute &other)
{
- InterfaceVariable::operator=(other);
+ VariableWithLocation::operator=(other);
return *this;
}
bool Attribute::operator==(const Attribute &other) const
{
- return InterfaceVariable::operator==(other);
+ return VariableWithLocation::operator==(other);
}
OutputVariable::OutputVariable()
@@ -271,79 +347,79 @@ OutputVariable::~OutputVariable()
{
}
-OutputVariable::OutputVariable(const OutputVariable &other) : InterfaceVariable(other)
+OutputVariable::OutputVariable(const OutputVariable &other) : VariableWithLocation(other)
{
}
OutputVariable &OutputVariable::operator=(const OutputVariable &other)
{
- InterfaceVariable::operator=(other);
+ VariableWithLocation::operator=(other);
return *this;
}
bool OutputVariable::operator==(const OutputVariable &other) const
{
- return InterfaceVariable::operator==(other);
+ return VariableWithLocation::operator==(other);
}
-InterfaceBlockField::InterfaceBlockField()
- : isRowMajorLayout(false)
-{}
+InterfaceBlockField::InterfaceBlockField() : isRowMajorLayout(false)
+{
+}
InterfaceBlockField::~InterfaceBlockField()
-{}
+{
+}
InterfaceBlockField::InterfaceBlockField(const InterfaceBlockField &other)
- : ShaderVariable(other),
- isRowMajorLayout(other.isRowMajorLayout)
-{}
+ : ShaderVariable(other), isRowMajorLayout(other.isRowMajorLayout)
+{
+}
InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &other)
{
ShaderVariable::operator=(other);
- isRowMajorLayout = other.isRowMajorLayout;
+ isRowMajorLayout = other.isRowMajorLayout;
return *this;
}
bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
{
- return (ShaderVariable::operator==(other) &&
- isRowMajorLayout == other.isRowMajorLayout);
+ return (ShaderVariable::operator==(other) && isRowMajorLayout == other.isRowMajorLayout);
}
bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
const InterfaceBlockField &other) const
{
- return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
+ return (ShaderVariable::isSameVariableAtLinkTime(other, true, true) &&
isRowMajorLayout == other.isRowMajorLayout);
}
-Varying::Varying()
- : interpolation(INTERPOLATION_SMOOTH),
- isInvariant(false)
-{}
+Varying::Varying() : interpolation(INTERPOLATION_SMOOTH), isInvariant(false)
+{
+}
Varying::~Varying()
-{}
+{
+}
Varying::Varying(const Varying &other)
- : ShaderVariable(other),
+ : VariableWithLocation(other),
interpolation(other.interpolation),
isInvariant(other.isInvariant)
-{}
+{
+}
Varying &Varying::operator=(const Varying &other)
{
- ShaderVariable::operator=(other);
- interpolation = other.interpolation;
- isInvariant = other.isInvariant;
+ VariableWithLocation::operator=(other);
+ interpolation = other.interpolation;
+ isInvariant = other.isInvariant;
return *this;
}
bool Varying::operator==(const Varying &other) const
{
- return (ShaderVariable::operator==(other) &&
- interpolation == other.interpolation &&
+ return (VariableWithLocation::operator==(other) && interpolation == other.interpolation &&
isInvariant == other.isInvariant);
}
@@ -354,20 +430,26 @@ bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
bool Varying::isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const
{
- return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
- interpolation == other.interpolation &&
- (shaderVersion >= 300 || isInvariant == other.isInvariant));
+ return (ShaderVariable::isSameVariableAtLinkTime(other, false, false) &&
+ InterpolationTypesMatch(interpolation, other.interpolation) &&
+ (shaderVersion >= 300 || isInvariant == other.isInvariant) &&
+ (location == other.location) &&
+ (name == other.name || (shaderVersion >= 310 && location >= 0)));
}
InterfaceBlock::InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),
isRowMajorLayout(false),
- staticUse(false)
-{}
+ binding(-1),
+ staticUse(false),
+ blockType(BlockType::BLOCK_UNIFORM)
+{
+}
InterfaceBlock::~InterfaceBlock()
-{}
+{
+}
InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
: name(other.name),
@@ -376,20 +458,25 @@ InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
arraySize(other.arraySize),
layout(other.layout),
isRowMajorLayout(other.isRowMajorLayout),
+ binding(other.binding),
staticUse(other.staticUse),
+ blockType(other.blockType),
fields(other.fields)
-{}
+{
+}
InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
{
- name = other.name;
- mappedName = other.mappedName;
- instanceName = other.instanceName;
- arraySize = other.arraySize;
- layout = other.layout;
+ name = other.name;
+ mappedName = other.mappedName;
+ instanceName = other.instanceName;
+ arraySize = other.arraySize;
+ layout = other.layout;
isRowMajorLayout = other.isRowMajorLayout;
- staticUse = other.staticUse;
- fields = other.fields;
+ binding = other.binding;
+ staticUse = other.staticUse;
+ blockType = other.blockType;
+ fields = other.fields;
return *this;
}
@@ -398,4 +485,102 @@ std::string InterfaceBlock::fieldPrefix() const
return instanceName.empty() ? "" : name;
}
+std::string InterfaceBlock::fieldMappedPrefix() const
+{
+ return instanceName.empty() ? "" : mappedName;
+}
+
+bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const
+{
+ if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize ||
+ layout != other.layout || isRowMajorLayout != other.isRowMajorLayout ||
+ binding != other.binding || blockType != other.blockType ||
+ fields.size() != other.fields.size())
+ {
+ return false;
+ }
+
+ for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex)
+ {
+ if (!fields[fieldIndex].isSameInterfaceBlockFieldAtLinkTime(other.fields[fieldIndex]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool InterfaceBlock::isBuiltIn() const
+{
+ return (name.size() >= 4 && name[0] == 'g' && name[1] == 'l' && name[2] == '_');
+}
+
+void WorkGroupSize::fill(int fillValue)
+{
+ localSizeQualifiers[0] = fillValue;
+ localSizeQualifiers[1] = fillValue;
+ localSizeQualifiers[2] = fillValue;
+}
+
+void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ)
+{
+ localSizeQualifiers[0] = localSizeX;
+ localSizeQualifiers[1] = localSizeY;
+ localSizeQualifiers[2] = localSizeZ;
+}
+
+// check that if one of them is less than 1, then all of them are.
+// Or if one is positive, then all of them are positive.
+bool WorkGroupSize::isLocalSizeValid() const
+{
+ return (
+ (localSizeQualifiers[0] < 1 && localSizeQualifiers[1] < 1 && localSizeQualifiers[2] < 1) ||
+ (localSizeQualifiers[0] > 0 && localSizeQualifiers[1] > 0 && localSizeQualifiers[2] > 0));
+}
+
+bool WorkGroupSize::isAnyValueSet() const
+{
+ return localSizeQualifiers[0] > 0 || localSizeQualifiers[1] > 0 || localSizeQualifiers[2] > 0;
+}
+
+bool WorkGroupSize::isDeclared() const
+{
+ bool localSizeDeclared = localSizeQualifiers[0] > 0;
+ ASSERT(isLocalSizeValid());
+ return localSizeDeclared;
+}
+
+bool WorkGroupSize::isWorkGroupSizeMatching(const WorkGroupSize &right) const
+{
+ for (size_t i = 0u; i < size(); ++i)
+ {
+ bool result = (localSizeQualifiers[i] == right.localSizeQualifiers[i] ||
+ (localSizeQualifiers[i] == 1 && right.localSizeQualifiers[i] == -1) ||
+ (localSizeQualifiers[i] == -1 && right.localSizeQualifiers[i] == 1));
+ if (!result)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+int &WorkGroupSize::operator[](size_t index)
+{
+ ASSERT(index < size());
+ return localSizeQualifiers[index];
+}
+
+int WorkGroupSize::operator[](size_t index) const
+{
+ ASSERT(index < size());
+ return localSizeQualifiers[index];
+}
+
+size_t WorkGroupSize::size() const
+{
+ return 3u;
+}
+
} // namespace sh