summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/util.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.cpp780
1 files changed, 567 insertions, 213 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/util.cpp b/src/3rdparty/angle/src/compiler/translator/util.cpp
index 0131137206..9738370c47 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/util.cpp
@@ -8,17 +8,9 @@
#include <limits>
+#include "common/utilities.h"
#include "compiler/preprocessor/numeric_lex.h"
#include "compiler/translator/SymbolTable.h"
-#include "common/utilities.h"
-
-bool strtof_clamp(const std::string &str, float *value)
-{
- bool success = pp::numeric_lex_float(str, value);
- if (!success)
- *value = std::numeric_limits<float>::max();
- return success;
-}
bool atoi_clamp(const char *str, unsigned int *value)
{
@@ -31,135 +23,392 @@ bool atoi_clamp(const char *str, unsigned int *value)
namespace sh
{
-GLenum GLVariableType(const TType &type)
+namespace
{
- if (type.getBasicType() == EbtFloat)
+
+bool IsInterpolationIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqCentroidIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // anonymous namespace
+
+float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
+{
+ // Parses a decimal string using scientific notation into a floating point number.
+ // Out-of-range values are converted to infinity. Values that are too small to be
+ // represented are converted to zero.
+
+ // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
+ // matter.
+ unsigned int decimalMantissa = 0;
+ size_t i = 0;
+ bool decimalPointSeen = false;
+ bool nonZeroSeenInMantissa = false;
+
+ // The exponent offset reflects the position of the decimal point.
+ int exponentOffset = -1;
+ while (i < str.length())
{
- if (type.isScalar())
+ const char c = str[i];
+ if (c == 'e' || c == 'E')
{
- return GL_FLOAT;
+ break;
+ }
+ if (c == '.')
+ {
+ decimalPointSeen = true;
+ ++i;
+ continue;
+ }
+
+ unsigned int digit = static_cast<unsigned int>(c - '0');
+ ASSERT(digit < 10u);
+ if (digit != 0u)
+ {
+ nonZeroSeenInMantissa = true;
}
- else if (type.isVector())
+ if (nonZeroSeenInMantissa)
+ {
+ // Add bits to the mantissa until space runs out in 32-bit int. This should be
+ // enough precision to make the resulting binary mantissa accurate to 1 ULP.
+ if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
+ {
+ decimalMantissa = decimalMantissa * 10u + digit;
+ }
+ if (!decimalPointSeen)
+ {
+ ++exponentOffset;
+ }
+ }
+ else if (decimalPointSeen)
+ {
+ --exponentOffset;
+ }
+ ++i;
+ }
+ if (decimalMantissa == 0)
+ {
+ return 0.0f;
+ }
+ int exponent = 0;
+ if (i < str.length())
+ {
+ ASSERT(str[i] == 'e' || str[i] == 'E');
+ ++i;
+ bool exponentOutOfRange = false;
+ bool negativeExponent = false;
+ if (str[i] == '-')
+ {
+ negativeExponent = true;
+ ++i;
+ }
+ else if (str[i] == '+')
+ {
+ ++i;
+ }
+ while (i < str.length())
+ {
+ const char c = str[i];
+ unsigned int digit = static_cast<unsigned int>(c - '0');
+ ASSERT(digit < 10u);
+ if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
+ {
+ exponent = exponent * 10 + digit;
+ }
+ else
+ {
+ exponentOutOfRange = true;
+ }
+ ++i;
+ }
+ if (negativeExponent)
+ {
+ exponent = -exponent;
+ }
+ if (exponentOutOfRange)
+ {
+ if (negativeExponent)
+ {
+ return 0.0f;
+ }
+ else
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ }
+ }
+ // Do the calculation in 64-bit to avoid overflow.
+ long long exponentLong =
+ static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
+ if (exponentLong > std::numeric_limits<float>::max_exponent10)
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ else if (exponentLong < std::numeric_limits<float>::min_exponent10)
+ {
+ return 0.0f;
+ }
+ // The exponent is in range, so we need to actually evaluate the float.
+ exponent = static_cast<int>(exponentLong);
+ double value = decimalMantissa;
+
+ // Calculate the exponent offset to normalize the mantissa.
+ int normalizationExponentOffset = 0;
+ while (decimalMantissa >= 10u)
+ {
+ --normalizationExponentOffset;
+ decimalMantissa /= 10u;
+ }
+ // Apply the exponent.
+ value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
+ if (value > static_cast<double>(std::numeric_limits<float>::max()))
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ if (value < static_cast<double>(std::numeric_limits<float>::min()))
+ {
+ return 0.0f;
+ }
+ return static_cast<float>(value);
+}
+
+bool strtof_clamp(const std::string &str, float *value)
+{
+ // Try the standard float parsing path first.
+ bool success = pp::numeric_lex_float(str, value);
+
+ // If the standard path doesn't succeed, take the path that can handle the following corner
+ // cases:
+ // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
+ // number inside the float range.
+ // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
+ // number inside the float range.
+ // 3. The value is out-of-range and should be evaluated as infinity.
+ // 4. The value is too small and should be evaluated as zero.
+ // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
+ if (!success)
+ *value = NumericLexFloat32OutOfRangeToInfinity(str);
+ return !gl::isInf(*value);
+}
+
+GLenum GLVariableType(const TType &type)
+{
+ if (type.getBasicType() == EbtFloat)
+ {
+ if (type.isVector())
{
switch (type.getNominalSize())
{
- case 2: return GL_FLOAT_VEC2;
- case 3: return GL_FLOAT_VEC3;
- case 4: return GL_FLOAT_VEC4;
- default: UNREACHABLE();
+ case 2:
+ return GL_FLOAT_VEC2;
+ case 3:
+ return GL_FLOAT_VEC3;
+ case 4:
+ return GL_FLOAT_VEC4;
+ default:
+ UNREACHABLE();
}
}
else if (type.isMatrix())
{
switch (type.getCols())
{
- case 2:
- switch (type.getRows())
- {
- case 2: return GL_FLOAT_MAT2;
- case 3: return GL_FLOAT_MAT2x3;
- case 4: return GL_FLOAT_MAT2x4;
- default: UNREACHABLE();
- }
-
- case 3:
- switch (type.getRows())
- {
- case 2: return GL_FLOAT_MAT3x2;
- case 3: return GL_FLOAT_MAT3;
- case 4: return GL_FLOAT_MAT3x4;
- default: UNREACHABLE();
- }
-
- case 4:
- switch (type.getRows())
- {
- case 2: return GL_FLOAT_MAT4x2;
- case 3: return GL_FLOAT_MAT4x3;
- case 4: return GL_FLOAT_MAT4;
- default: UNREACHABLE();
- }
-
- default: UNREACHABLE();
+ case 2:
+ switch (type.getRows())
+ {
+ case 2:
+ return GL_FLOAT_MAT2;
+ case 3:
+ return GL_FLOAT_MAT2x3;
+ case 4:
+ return GL_FLOAT_MAT2x4;
+ default:
+ UNREACHABLE();
+ }
+
+ case 3:
+ switch (type.getRows())
+ {
+ case 2:
+ return GL_FLOAT_MAT3x2;
+ case 3:
+ return GL_FLOAT_MAT3;
+ case 4:
+ return GL_FLOAT_MAT3x4;
+ default:
+ UNREACHABLE();
+ }
+
+ case 4:
+ switch (type.getRows())
+ {
+ case 2:
+ return GL_FLOAT_MAT4x2;
+ case 3:
+ return GL_FLOAT_MAT4x3;
+ case 4:
+ return GL_FLOAT_MAT4;
+ default:
+ UNREACHABLE();
+ }
+
+ default:
+ UNREACHABLE();
}
}
- else UNREACHABLE();
+ else
+ {
+ return GL_FLOAT;
+ }
}
else if (type.getBasicType() == EbtInt)
{
- if (type.isScalar())
- {
- return GL_INT;
- }
- else if (type.isVector())
+ if (type.isVector())
{
switch (type.getNominalSize())
{
- case 2: return GL_INT_VEC2;
- case 3: return GL_INT_VEC3;
- case 4: return GL_INT_VEC4;
- default: UNREACHABLE();
+ case 2:
+ return GL_INT_VEC2;
+ case 3:
+ return GL_INT_VEC3;
+ case 4:
+ return GL_INT_VEC4;
+ default:
+ UNREACHABLE();
}
}
- else UNREACHABLE();
+ else
+ {
+ ASSERT(!type.isMatrix());
+ return GL_INT;
+ }
}
else if (type.getBasicType() == EbtUInt)
{
- if (type.isScalar())
- {
- return GL_UNSIGNED_INT;
- }
- else if (type.isVector())
+ if (type.isVector())
{
switch (type.getNominalSize())
{
- case 2: return GL_UNSIGNED_INT_VEC2;
- case 3: return GL_UNSIGNED_INT_VEC3;
- case 4: return GL_UNSIGNED_INT_VEC4;
- default: UNREACHABLE();
+ case 2:
+ return GL_UNSIGNED_INT_VEC2;
+ case 3:
+ return GL_UNSIGNED_INT_VEC3;
+ case 4:
+ return GL_UNSIGNED_INT_VEC4;
+ default:
+ UNREACHABLE();
}
}
- else UNREACHABLE();
+ else
+ {
+ ASSERT(!type.isMatrix());
+ return GL_UNSIGNED_INT;
+ }
}
else if (type.getBasicType() == EbtBool)
{
- if (type.isScalar())
- {
- return GL_BOOL;
- }
- else if (type.isVector())
+ if (type.isVector())
{
switch (type.getNominalSize())
{
- case 2: return GL_BOOL_VEC2;
- case 3: return GL_BOOL_VEC3;
- case 4: return GL_BOOL_VEC4;
- default: UNREACHABLE();
+ case 2:
+ return GL_BOOL_VEC2;
+ case 3:
+ return GL_BOOL_VEC3;
+ case 4:
+ return GL_BOOL_VEC4;
+ default:
+ UNREACHABLE();
}
}
- else UNREACHABLE();
+ else
+ {
+ ASSERT(!type.isMatrix());
+ return GL_BOOL;
+ }
}
switch (type.getBasicType())
{
- case EbtSampler2D: return GL_SAMPLER_2D;
- case EbtSampler3D: return GL_SAMPLER_3D;
- case EbtSamplerCube: return GL_SAMPLER_CUBE;
- case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES;
- case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB;
- case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY;
- case EbtISampler2D: return GL_INT_SAMPLER_2D;
- case EbtISampler3D: return GL_INT_SAMPLER_3D;
- case EbtISamplerCube: return GL_INT_SAMPLER_CUBE;
- case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY;
- case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D;
- case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D;
- case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE;
- case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
- case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW;
- case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW;
- case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
- default: UNREACHABLE();
+ case EbtSampler2D:
+ return GL_SAMPLER_2D;
+ case EbtSampler3D:
+ return GL_SAMPLER_3D;
+ case EbtSamplerCube:
+ return GL_SAMPLER_CUBE;
+ case EbtSamplerExternalOES:
+ return GL_SAMPLER_EXTERNAL_OES;
+ case EbtSamplerExternal2DY2YEXT:
+ return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
+ case EbtSampler2DRect:
+ return GL_SAMPLER_2D_RECT_ANGLE;
+ case EbtSampler2DArray:
+ return GL_SAMPLER_2D_ARRAY;
+ case EbtSampler2DMS:
+ return GL_SAMPLER_2D_MULTISAMPLE;
+ case EbtISampler2D:
+ return GL_INT_SAMPLER_2D;
+ case EbtISampler3D:
+ return GL_INT_SAMPLER_3D;
+ case EbtISamplerCube:
+ return GL_INT_SAMPLER_CUBE;
+ case EbtISampler2DArray:
+ return GL_INT_SAMPLER_2D_ARRAY;
+ case EbtISampler2DMS:
+ return GL_INT_SAMPLER_2D_MULTISAMPLE;
+ case EbtUSampler2D:
+ return GL_UNSIGNED_INT_SAMPLER_2D;
+ case EbtUSampler3D:
+ return GL_UNSIGNED_INT_SAMPLER_3D;
+ case EbtUSamplerCube:
+ return GL_UNSIGNED_INT_SAMPLER_CUBE;
+ case EbtUSampler2DArray:
+ return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
+ case EbtUSampler2DMS:
+ return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
+ case EbtSampler2DShadow:
+ return GL_SAMPLER_2D_SHADOW;
+ case EbtSamplerCubeShadow:
+ return GL_SAMPLER_CUBE_SHADOW;
+ case EbtSampler2DArrayShadow:
+ return GL_SAMPLER_2D_ARRAY_SHADOW;
+ case EbtImage2D:
+ return GL_IMAGE_2D;
+ case EbtIImage2D:
+ return GL_INT_IMAGE_2D;
+ case EbtUImage2D:
+ return GL_UNSIGNED_INT_IMAGE_2D;
+ case EbtImage2DArray:
+ return GL_IMAGE_2D_ARRAY;
+ case EbtIImage2DArray:
+ return GL_INT_IMAGE_2D_ARRAY;
+ case EbtUImage2DArray:
+ return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
+ case EbtImage3D:
+ return GL_IMAGE_3D;
+ case EbtIImage3D:
+ return GL_INT_IMAGE_3D;
+ case EbtUImage3D:
+ return GL_UNSIGNED_INT_IMAGE_3D;
+ case EbtImageCube:
+ return GL_IMAGE_CUBE;
+ case EbtIImageCube:
+ return GL_INT_IMAGE_CUBE;
+ case EbtUImageCube:
+ return GL_UNSIGNED_INT_IMAGE_CUBE;
+ case EbtAtomicCounter:
+ return GL_UNSIGNED_INT_ATOMIC_COUNTER;
+ default:
+ UNREACHABLE();
}
return GL_NONE;
@@ -171,32 +420,32 @@ GLenum GLVariablePrecision(const TType &type)
{
switch (type.getPrecision())
{
- case EbpHigh:
- return GL_HIGH_FLOAT;
- case EbpMedium:
- return GL_MEDIUM_FLOAT;
- case EbpLow:
- return GL_LOW_FLOAT;
- case EbpUndefined:
- // Should be defined as the default precision by the parser
- default:
- UNREACHABLE();
+ case EbpHigh:
+ return GL_HIGH_FLOAT;
+ case EbpMedium:
+ return GL_MEDIUM_FLOAT;
+ case EbpLow:
+ return GL_LOW_FLOAT;
+ case EbpUndefined:
+ // Should be defined as the default precision by the parser
+ default:
+ UNREACHABLE();
}
}
else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
{
switch (type.getPrecision())
{
- case EbpHigh:
- return GL_HIGH_INT;
- case EbpMedium:
- return GL_MEDIUM_INT;
- case EbpLow:
- return GL_LOW_INT;
- case EbpUndefined:
- // Should be defined as the default precision by the parser
- default:
- UNREACHABLE();
+ case EbpHigh:
+ return GL_HIGH_INT;
+ case EbpMedium:
+ return GL_MEDIUM_INT;
+ case EbpLow:
+ return GL_LOW_INT;
+ case EbpUndefined:
+ // Should be defined as the default precision by the parser
+ default:
+ UNREACHABLE();
}
}
@@ -206,26 +455,46 @@ GLenum GLVariablePrecision(const TType &type)
TString ArrayString(const TType &type)
{
+ TStringStream arrayString;
if (!type.isArray())
+ return arrayString.str();
+
+ const TVector<unsigned int> &arraySizes = *type.getArraySizes();
+ for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
+ ++arraySizeIter)
{
- return "";
+ arrayString << "[";
+ if (*arraySizeIter > 0)
+ {
+ arrayString << (*arraySizeIter);
+ }
+ arrayString << "]";
}
+ return arrayString.str();
+}
- return "[" + str(type.getArraySize()) + "]";
+TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+ if (type.getBasicType() == EbtStruct)
+ return HashName(TName(type.getStruct()->name()), hashFunction, nameMap);
+ else
+ return type.getBuiltInTypeNameString();
}
bool IsVaryingOut(TQualifier qualifier)
{
switch (qualifier)
{
- case EvqVaryingOut:
- case EvqSmoothOut:
- case EvqFlatOut:
- case EvqCentroidOut:
- case EvqVertexOut:
- return true;
-
- default: break;
+ case EvqVaryingOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqCentroidOut:
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ return true;
+
+ default:
+ break;
}
return false;
@@ -235,14 +504,16 @@ bool IsVaryingIn(TQualifier qualifier)
{
switch (qualifier)
{
- case EvqVaryingIn:
- case EvqSmoothIn:
- case EvqFlatIn:
- case EvqCentroidIn:
- case EvqFragmentIn:
- return true;
-
- default: break;
+ case EvqVaryingIn:
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqCentroidIn:
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ return true;
+
+ default:
+ break;
}
return false;
@@ -253,108 +524,191 @@ bool IsVarying(TQualifier qualifier)
return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
}
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return (qualifier == EvqGeometryIn) ||
+ ((shaderType == GL_GEOMETRY_SHADER_OES) && IsInterpolationIn(qualifier));
+}
+
InterpolationType GetInterpolationType(TQualifier qualifier)
{
switch (qualifier)
{
- case EvqFlatIn:
- case EvqFlatOut:
- return INTERPOLATION_FLAT;
-
- case EvqSmoothIn:
- case EvqSmoothOut:
- case EvqVertexOut:
- case EvqFragmentIn:
- case EvqVaryingIn:
- case EvqVaryingOut:
- return INTERPOLATION_SMOOTH;
-
- case EvqCentroidIn:
- case EvqCentroidOut:
- return INTERPOLATION_CENTROID;
-
- default: UNREACHABLE();
- return INTERPOLATION_SMOOTH;
+ case EvqFlatIn:
+ case EvqFlatOut:
+ return INTERPOLATION_FLAT;
+
+ case EvqSmoothIn:
+ case EvqSmoothOut:
+ case EvqVertexOut:
+ case EvqFragmentIn:
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ return INTERPOLATION_SMOOTH;
+
+ case EvqCentroidIn:
+ case EvqCentroidOut:
+ return INTERPOLATION_CENTROID;
+
+ default:
+ UNREACHABLE();
+ return INTERPOLATION_SMOOTH;
+ }
+}
+
+TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
+{
+ switch (var.type)
+ {
+ case GL_BOOL:
+ return TType(EbtBool);
+ case GL_BOOL_VEC2:
+ return TType(EbtBool, 2);
+ case GL_BOOL_VEC3:
+ return TType(EbtBool, 3);
+ case GL_BOOL_VEC4:
+ return TType(EbtBool, 4);
+ case GL_FLOAT:
+ return TType(EbtFloat);
+ case GL_FLOAT_VEC2:
+ return TType(EbtFloat, 2);
+ case GL_FLOAT_VEC3:
+ return TType(EbtFloat, 3);
+ case GL_FLOAT_VEC4:
+ return TType(EbtFloat, 4);
+ case GL_FLOAT_MAT2:
+ return TType(EbtFloat, 2, 2);
+ case GL_FLOAT_MAT3:
+ return TType(EbtFloat, 3, 3);
+ case GL_FLOAT_MAT4:
+ return TType(EbtFloat, 4, 4);
+ case GL_FLOAT_MAT2x3:
+ return TType(EbtFloat, 2, 3);
+ case GL_FLOAT_MAT2x4:
+ return TType(EbtFloat, 2, 4);
+ case GL_FLOAT_MAT3x2:
+ return TType(EbtFloat, 3, 2);
+ case GL_FLOAT_MAT3x4:
+ return TType(EbtFloat, 3, 4);
+ case GL_FLOAT_MAT4x2:
+ return TType(EbtFloat, 4, 2);
+ case GL_FLOAT_MAT4x3:
+ return TType(EbtFloat, 4, 3);
+ case GL_INT:
+ return TType(EbtInt);
+ case GL_INT_VEC2:
+ return TType(EbtInt, 2);
+ case GL_INT_VEC3:
+ return TType(EbtInt, 3);
+ case GL_INT_VEC4:
+ return TType(EbtInt, 4);
+ case GL_UNSIGNED_INT:
+ return TType(EbtUInt);
+ case GL_UNSIGNED_INT_VEC2:
+ return TType(EbtUInt, 2);
+ case GL_UNSIGNED_INT_VEC3:
+ return TType(EbtUInt, 3);
+ case GL_UNSIGNED_INT_VEC4:
+ return TType(EbtUInt, 4);
+ default:
+ UNREACHABLE();
+ return TType();
}
}
-GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
- : mSymbolTable(symbolTable)
+// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
+bool CanBeInvariantESSL1(TQualifier qualifier)
{
+ return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
+ IsBuiltinOutputVariable(qualifier) ||
+ (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
}
-template void GetVariableTraverser::setTypeSpecificInfo(
- const TType &type, const TString& name, InterfaceBlockField *variable);
-template void GetVariableTraverser::setTypeSpecificInfo(
- const TType &type, const TString& name, ShaderVariable *variable);
-template void GetVariableTraverser::setTypeSpecificInfo(
- const TType &type, const TString& name, Uniform *variable);
+// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
+// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
+bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
+{
+ return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
+ IsBuiltinOutputVariable(qualifier);
+}
-template<>
-void GetVariableTraverser::setTypeSpecificInfo(
- const TType &type, const TString& name, Varying *variable)
+bool IsBuiltinOutputVariable(TQualifier qualifier)
{
- ASSERT(variable);
- switch (type.getQualifier())
+ switch (qualifier)
{
- case EvqVaryingIn:
- case EvqVaryingOut:
- case EvqVertexOut:
- case EvqSmoothOut:
- case EvqFlatOut:
- case EvqCentroidOut:
- if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant())
- {
- variable->isInvariant = true;
- }
- break;
- default:
- break;
+ case EvqPosition:
+ case EvqPointSize:
+ case EvqFragDepth:
+ case EvqFragDepthEXT:
+ case EvqFragColor:
+ case EvqSecondaryFragColorEXT:
+ case EvqFragData:
+ case EvqSecondaryFragDataEXT:
+ return true;
+ default:
+ break;
}
-
- variable->interpolation = GetInterpolationType(type.getQualifier());
+ return false;
}
-template <typename VarT>
-void GetVariableTraverser::traverse(const TType &type,
- const TString &name,
- std::vector<VarT> *output)
+bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
{
- const TStructure *structure = type.getStruct();
+ switch (qualifier)
+ {
+ case EvqFragCoord:
+ case EvqPointCoord:
+ case EvqFrontFacing:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
- VarT variable;
- variable.name = name.c_str();
- variable.arraySize = static_cast<unsigned int>(type.getArraySize());
+bool IsOutputESSL(ShShaderOutput output)
+{
+ return output == SH_ESSL_OUTPUT;
+}
- if (!structure)
+bool IsOutputGLSL(ShShaderOutput output)
+{
+ switch (output)
{
- variable.type = GLVariableType(type);
- variable.precision = GLVariablePrecision(type);
+ case SH_GLSL_130_OUTPUT:
+ case SH_GLSL_140_OUTPUT:
+ case SH_GLSL_150_CORE_OUTPUT:
+ case SH_GLSL_330_CORE_OUTPUT:
+ case SH_GLSL_400_CORE_OUTPUT:
+ case SH_GLSL_410_CORE_OUTPUT:
+ case SH_GLSL_420_CORE_OUTPUT:
+ case SH_GLSL_430_CORE_OUTPUT:
+ case SH_GLSL_440_CORE_OUTPUT:
+ case SH_GLSL_450_CORE_OUTPUT:
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
+ return true;
+ default:
+ break;
}
- else
+ return false;
+}
+bool IsOutputHLSL(ShShaderOutput output)
+{
+ switch (output)
{
- // Note: this enum value is not exposed outside ANGLE
- variable.type = GL_STRUCT_ANGLEX;
- variable.structName = structure->name().c_str();
-
- const TFieldList &fields = structure->fields();
-
- for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
- {
- TField *field = fields[fieldIndex];
- traverse(*field->type(), field->name(), &variable.fields);
- }
+ case SH_HLSL_3_0_OUTPUT:
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
+ return true;
+ default:
+ break;
}
- setTypeSpecificInfo(type, name, &variable);
- visitVariable(&variable);
-
- ASSERT(output);
- output->push_back(variable);
+ return false;
}
-
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
-
+bool IsOutputVulkan(ShShaderOutput output)
+{
+ return output == SH_GLSL_VULKAN_OUTPUT;
}
+
+} // namespace sh