Commit 214c2d8e by Olli Etuaho

Separate invariance from qualifiers

ESSL3 makes it possible to combine invariant with several more different qualifiers. To avoid combinatorial explosion of the qualifier enum, track invariance with a separate boolean. TEST=WebGL conformance tests, angle_unittests BUG=angleproject:987 Change-Id: I0c6629e5ca2ded06db9ac9e5bab2fb6480299a5a Reviewed-on: https://chromium-review.googlesource.com/267662Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent bab4c08f
...@@ -290,8 +290,6 @@ enum TQualifier ...@@ -290,8 +290,6 @@ enum TQualifier
EvqAttribute, // Readonly EvqAttribute, // Readonly
EvqVaryingIn, // readonly, fragment shaders only EvqVaryingIn, // readonly, fragment shaders only
EvqVaryingOut, // vertex shaders only read/write EvqVaryingOut, // vertex shaders only read/write
EvqInvariantVaryingIn, // readonly, fragment shaders only
EvqInvariantVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment EvqUniform, // Readonly, vertex and fragment
EvqVertexIn, // Vertex shader input EvqVertexIn, // Vertex shader input
...@@ -392,8 +390,6 @@ inline const char* getQualifierString(TQualifier q) ...@@ -392,8 +390,6 @@ inline const char* getQualifierString(TQualifier q)
case EvqAttribute: return "attribute"; break; case EvqAttribute: return "attribute"; break;
case EvqVaryingIn: return "varying"; break; case EvqVaryingIn: return "varying"; break;
case EvqVaryingOut: return "varying"; break; case EvqVaryingOut: return "varying"; break;
case EvqInvariantVaryingIn: return "invariant varying"; break;
case EvqInvariantVaryingOut:return "invariant varying"; break;
case EvqUniform: return "uniform"; break; case EvqUniform: return "uniform"; break;
case EvqVertexIn: return "in"; break; case EvqVertexIn: return "in"; break;
case EvqFragmentOut: return "out"; break; case EvqFragmentOut: return "out"; break;
......
...@@ -123,7 +123,6 @@ class TIntermTyped : public TIntermNode ...@@ -123,7 +123,6 @@ class TIntermTyped : public TIntermNode
bool isScalar() const { return mType.isScalar(); } bool isScalar() const { return mType.isScalar(); }
bool isScalarInt() const { return mType.isScalarInt(); } bool isScalarInt() const { return mType.isScalarInt(); }
const char *getBasicString() const { return mType.getBasicString(); } const char *getBasicString() const { return mType.getBasicString(); }
const char *getQualifierString() const { return mType.getQualifierString(); }
TString getCompleteString() const { return mType.getCompleteString(); } TString getCompleteString() const { return mType.getCompleteString(); }
int getArraySize() const { return mType.getArraySize(); } int getArraySize() const { return mType.getArraySize(); }
......
...@@ -92,6 +92,10 @@ void TOutputGLSLBase::writeBuiltInFunctionTriplet( ...@@ -92,6 +92,10 @@ void TOutputGLSLBase::writeBuiltInFunctionTriplet(
void TOutputGLSLBase::writeVariableType(const TType &type) void TOutputGLSLBase::writeVariableType(const TType &type)
{ {
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
if (type.isInvariant())
{
out << "invariant ";
}
TQualifier qualifier = type.getQualifier(); TQualifier qualifier = type.getQualifier();
if (qualifier != EvqTemporary && qualifier != EvqGlobal) if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{ {
...@@ -100,19 +104,13 @@ void TOutputGLSLBase::writeVariableType(const TType &type) ...@@ -100,19 +104,13 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
switch (qualifier) switch (qualifier)
{ {
case EvqAttribute: case EvqAttribute:
out << "in" << " "; out << "in ";
break; break;
case EvqVaryingIn: case EvqVaryingIn:
out << "in" << " "; out << "in ";
break; break;
case EvqVaryingOut: case EvqVaryingOut:
out << "out" << " "; out << "out ";
break;
case EvqInvariantVaryingIn:
out << "invariant in" << " ";
break;
case EvqInvariantVaryingOut:
out << "invariant out" << " ";
break; break;
default: default:
out << type.getQualifierString() << " "; out << type.getQualifierString() << " ";
......
...@@ -1183,10 +1183,12 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) ...@@ -1183,10 +1183,12 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
return allConstant; return allConstant;
} }
TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier) TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier,
const TPublicType& typeSpecifier)
{ {
TPublicType returnType = typeSpecifier; TPublicType returnType = typeSpecifier;
returnType.qualifier = qualifier; returnType.qualifier = qualifier;
returnType.invariant = invariant;
returnType.layoutQualifier = layoutQualifier; returnType.layoutQualifier = layoutQualifier;
if (typeSpecifier.array) if (typeSpecifier.array)
......
...@@ -124,8 +124,8 @@ struct TParseContext { ...@@ -124,8 +124,8 @@ struct TParseContext {
bool executeInitializer(const TSourceLoc &line, const TString &identifier, TPublicType &pType, bool executeInitializer(const TSourceLoc &line, const TString &identifier, TPublicType &pType,
TIntermTyped *initializer, TIntermNode **intermNode); TIntermTyped *initializer, TIntermNode **intermNode);
TPublicType addFullySpecifiedType(TQualifier qualifier, const TPublicType& typeSpecifier); TPublicType addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier,
TPublicType addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier); const TPublicType& typeSpecifier);
TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, TIntermAggregate *parseSingleDeclaration(TPublicType &publicType,
const TSourceLoc &identifierOrTypeLocation, const TString &identifier); const TSourceLoc &identifierOrTypeLocation, const TString &identifier);
......
...@@ -46,9 +46,9 @@ const char* getBasicString(TBasicType t) ...@@ -46,9 +46,9 @@ const char* getBasicString(TBasicType t)
} }
TType::TType(const TPublicType &p) TType::TType(const TPublicType &p)
: type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier), : type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant),
primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), layoutQualifier(p.layoutQualifier), primarySize(p.primarySize), secondarySize(p.secondarySize),
interfaceBlock(0), structure(0) array(p.array), arraySize(p.arraySize), interfaceBlock(0), structure(0)
{ {
if (p.userDef) if (p.userDef)
structure = p.userDef->getStruct(); structure = p.userDef->getStruct();
......
...@@ -233,7 +233,7 @@ class TType ...@@ -233,7 +233,7 @@ class TType
{ {
} }
TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
: type(t), precision(EbpUndefined), qualifier(EvqGlobal), : type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false),
layoutQualifier(TLayoutQualifier::create()), layoutQualifier(TLayoutQualifier::create()),
primarySize(ps), secondarySize(ss), array(false), arraySize(0), primarySize(ps), secondarySize(ss), array(false), arraySize(0),
interfaceBlock(0), structure(0) interfaceBlock(0), structure(0)
...@@ -241,7 +241,7 @@ class TType ...@@ -241,7 +241,7 @@ class TType
} }
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary,
unsigned char ps = 1, unsigned char ss = 1, bool a = false) unsigned char ps = 1, unsigned char ss = 1, bool a = false)
: type(t), precision(p), qualifier(q), : type(t), precision(p), qualifier(q), invariant(false),
layoutQualifier(TLayoutQualifier::create()), layoutQualifier(TLayoutQualifier::create()),
primarySize(ps), secondarySize(ss), array(a), arraySize(0), primarySize(ps), secondarySize(ss), array(a), arraySize(0),
interfaceBlock(0), structure(0) interfaceBlock(0), structure(0)
...@@ -249,7 +249,7 @@ class TType ...@@ -249,7 +249,7 @@ class TType
} }
explicit TType(const TPublicType &p); explicit TType(const TPublicType &p);
TType(TStructure *userDef, TPrecision p = EbpUndefined) TType(TStructure *userDef, TPrecision p = EbpUndefined)
: type(EbtStruct), precision(p), qualifier(EvqTemporary), : type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false),
layoutQualifier(TLayoutQualifier::create()), layoutQualifier(TLayoutQualifier::create()),
primarySize(1), secondarySize(1), array(false), arraySize(0), primarySize(1), secondarySize(1), array(false), arraySize(0),
interfaceBlock(0), structure(userDef) interfaceBlock(0), structure(userDef)
...@@ -258,7 +258,7 @@ class TType ...@@ -258,7 +258,7 @@ class TType
TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn, TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
TLayoutQualifier layoutQualifierIn, int arraySizeIn) TLayoutQualifier layoutQualifierIn, int arraySizeIn)
: type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
layoutQualifier(layoutQualifierIn), invariant(false), layoutQualifier(layoutQualifierIn),
primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn),
interfaceBlock(interfaceBlockIn), structure(0) interfaceBlock(interfaceBlockIn), structure(0)
{ {
...@@ -291,6 +291,11 @@ class TType ...@@ -291,6 +291,11 @@ class TType
qualifier = q; qualifier = q;
} }
bool isInvariant() const
{
return invariant;
}
TLayoutQualifier getLayoutQualifier() const TLayoutQualifier getLayoutQualifier() const
{ {
return layoutQualifier; return layoutQualifier;
...@@ -494,6 +499,7 @@ class TType ...@@ -494,6 +499,7 @@ class TType
TBasicType type; TBasicType type;
TPrecision precision; TPrecision precision;
TQualifier qualifier; TQualifier qualifier;
bool invariant;
TLayoutQualifier layoutQualifier; TLayoutQualifier layoutQualifier;
unsigned char primarySize; // size of vector or cols matrix unsigned char primarySize; // size of vector or cols matrix
unsigned char secondarySize; // rows of a matrix unsigned char secondarySize; // rows of a matrix
...@@ -523,6 +529,7 @@ struct TPublicType ...@@ -523,6 +529,7 @@ struct TPublicType
TBasicType type; TBasicType type;
TLayoutQualifier layoutQualifier; TLayoutQualifier layoutQualifier;
TQualifier qualifier; TQualifier qualifier;
bool invariant;
TPrecision precision; TPrecision precision;
unsigned char primarySize; // size of vector or cols of matrix unsigned char primarySize; // size of vector or cols of matrix
unsigned char secondarySize; // rows of matrix unsigned char secondarySize; // rows of matrix
...@@ -536,6 +543,7 @@ struct TPublicType ...@@ -536,6 +543,7 @@ struct TPublicType
type = bt; type = bt;
layoutQualifier = TLayoutQualifier::create(); layoutQualifier = TLayoutQualifier::create();
qualifier = q; qualifier = q;
invariant = false;
precision = EbpUndefined; precision = EbpUndefined;
primarySize = 1; primarySize = 1;
secondarySize = 1; secondarySize = 1;
......
...@@ -217,13 +217,11 @@ TString InterpolationString(TQualifier qualifier) ...@@ -217,13 +217,11 @@ TString InterpolationString(TQualifier qualifier)
{ {
case EvqVaryingIn: return ""; case EvqVaryingIn: return "";
case EvqFragmentIn: return ""; case EvqFragmentIn: return "";
case EvqInvariantVaryingIn: return "";
case EvqSmoothIn: return "linear"; case EvqSmoothIn: return "linear";
case EvqFlatIn: return "nointerpolation"; case EvqFlatIn: return "nointerpolation";
case EvqCentroidIn: return "centroid"; case EvqCentroidIn: return "centroid";
case EvqVaryingOut: return ""; case EvqVaryingOut: return "";
case EvqVertexOut: return ""; case EvqVertexOut: return "";
case EvqInvariantVaryingOut: return "";
case EvqSmoothOut: return "linear"; case EvqSmoothOut: return "linear";
case EvqFlatOut: return "nointerpolation"; case EvqFlatOut: return "nointerpolation";
case EvqCentroidOut: return "centroid"; case EvqCentroidOut: return "centroid";
......
...@@ -74,9 +74,7 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) ...@@ -74,9 +74,7 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
case EOpDeclaration: case EOpDeclaration:
{ {
const TIntermSequence &sequence = *(node->getSequence()); const TIntermSequence &sequence = *(node->getSequence());
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier(); if (sequence.front()->getAsTyped()->getType().isInvariant())
if ((qualifier == EvqInvariantVaryingIn) ||
(qualifier == EvqInvariantVaryingOut))
{ {
updateVersion(GLSL_VERSION_120); updateVersion(GLSL_VERSION_120);
} }
......
...@@ -940,7 +940,7 @@ fully_specified_type ...@@ -940,7 +940,7 @@ fully_specified_type
} }
} }
| type_qualifier type_specifier { | type_qualifier type_specifier {
$$ = context->addFullySpecifiedType($1.qualifier, $1.layoutQualifier, $2); $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2);
} }
; ;
...@@ -981,9 +981,10 @@ type_qualifier ...@@ -981,9 +981,10 @@ type_qualifier
if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover(); context->recover();
if (context->shaderType == GL_VERTEX_SHADER) if (context->shaderType == GL_VERTEX_SHADER)
$$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1); $$.setBasic(EbtVoid, EvqVaryingOut, @1);
else else
$$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1); $$.setBasic(EbtVoid, EvqVaryingIn, @1);
$$.invariant = true;
} }
| storage_qualifier { | storage_qualifier {
if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) {
......
...@@ -706,21 +706,21 @@ static const yytype_uint16 yyrline[] = ...@@ -706,21 +706,21 @@ static const yytype_uint16 yyrline[] =
760, 781, 791, 819, 824, 834, 839, 849, 852, 855, 760, 781, 791, 819, 824, 834, 839, 849, 852, 855,
858, 864, 871, 874, 878, 882, 887, 892, 899, 903, 858, 864, 871, 874, 878, 882, 887, 892, 899, 903,
907, 911, 916, 921, 925, 932, 942, 948, 951, 957, 907, 911, 916, 921, 925, 932, 942, 948, 951, 957,
963, 970, 979, 988, 996, 999, 1006, 1010, 1017, 1020, 963, 970, 979, 989, 997, 1000, 1007, 1011, 1018, 1021,
1024, 1028, 1037, 1046, 1054, 1064, 1076, 1079, 1082, 1088, 1025, 1029, 1038, 1047, 1055, 1065, 1077, 1080, 1083, 1089,
1095, 1098, 1104, 1107, 1110, 1116, 1119, 1124, 1139, 1143, 1096, 1099, 1105, 1108, 1111, 1117, 1120, 1125, 1140, 1144,
1147, 1151, 1155, 1159, 1164, 1169, 1174, 1179, 1184, 1189, 1148, 1152, 1156, 1160, 1165, 1170, 1175, 1180, 1185, 1190,
1194, 1199, 1204, 1209, 1214, 1219, 1224, 1229, 1234, 1239, 1195, 1200, 1205, 1210, 1215, 1220, 1225, 1230, 1235, 1240,
1244, 1249, 1254, 1259, 1264, 1268, 1272, 1276, 1280, 1284, 1245, 1250, 1255, 1260, 1265, 1269, 1273, 1277, 1281, 1285,
1288, 1292, 1296, 1300, 1304, 1308, 1312, 1316, 1320, 1324, 1289, 1293, 1297, 1301, 1305, 1309, 1313, 1317, 1321, 1325,
1332, 1340, 1344, 1357, 1357, 1360, 1360, 1366, 1369, 1385, 1333, 1341, 1345, 1358, 1358, 1361, 1361, 1367, 1370, 1386,
1388, 1397, 1401, 1407, 1414, 1429, 1433, 1437, 1438, 1444, 1389, 1398, 1402, 1408, 1415, 1430, 1434, 1438, 1439, 1445,
1445, 1446, 1447, 1448, 1449, 1450, 1454, 1455, 1455, 1455, 1446, 1447, 1448, 1449, 1450, 1451, 1455, 1456, 1456, 1456,
1465, 1466, 1470, 1470, 1471, 1471, 1476, 1479, 1489, 1492, 1466, 1467, 1471, 1471, 1472, 1472, 1477, 1480, 1490, 1493,
1498, 1499, 1503, 1511, 1515, 1522, 1522, 1529, 1532, 1539, 1499, 1500, 1504, 1512, 1516, 1523, 1523, 1530, 1533, 1540,
1544, 1559, 1559, 1564, 1564, 1571, 1571, 1579, 1582, 1588, 1545, 1560, 1560, 1565, 1565, 1572, 1572, 1580, 1583, 1589,
1591, 1597, 1601, 1608, 1611, 1614, 1617, 1620, 1629, 1633, 1592, 1598, 1602, 1609, 1612, 1615, 1618, 1621, 1630, 1634,
1640, 1643, 1649, 1649 1641, 1644, 1650, 1650
}; };
#endif #endif
...@@ -3553,7 +3553,7 @@ yyreduce: ...@@ -3553,7 +3553,7 @@ yyreduce:
case 126: case 126:
{ {
(yyval.interm.type) = context->addFullySpecifiedType((yyvsp[-1].interm.type).qualifier, (yyvsp[-1].interm.type).layoutQualifier, (yyvsp[0].interm.type)); (yyval.interm.type) = context->addFullySpecifiedType((yyvsp[-1].interm.type).qualifier, (yyvsp[-1].interm.type).invariant, (yyvsp[-1].interm.type).layoutQualifier, (yyvsp[0].interm.type));
} }
break; break;
...@@ -3615,9 +3615,10 @@ yyreduce: ...@@ -3615,9 +3615,10 @@ yyreduce:
if (context->globalErrorCheck((yylsp[-1]), context->symbolTable.atGlobalLevel(), "invariant varying")) if (context->globalErrorCheck((yylsp[-1]), context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover(); context->recover();
if (context->shaderType == GL_VERTEX_SHADER) if (context->shaderType == GL_VERTEX_SHADER)
(yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yylsp[-1])); (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[-1]));
else else
(yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yylsp[-1])); (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[-1]));
(yyval.interm.type).invariant = true;
} }
break; break;
......
...@@ -61,6 +61,8 @@ TString TType::getCompleteString() const ...@@ -61,6 +61,8 @@ TString TType::getCompleteString() const
{ {
TStringStream stream; TStringStream stream;
if (invariant)
stream << "invariant ";
if (qualifier != EvqTemporary && qualifier != EvqGlobal) if (qualifier != EvqTemporary && qualifier != EvqGlobal)
stream << getQualifierString() << " "; stream << getQualifierString() << " ";
if (precision != EbpUndefined) if (precision != EbpUndefined)
......
...@@ -219,7 +219,6 @@ bool IsVaryingOut(TQualifier qualifier) ...@@ -219,7 +219,6 @@ bool IsVaryingOut(TQualifier qualifier)
switch (qualifier) switch (qualifier)
{ {
case EvqVaryingOut: case EvqVaryingOut:
case EvqInvariantVaryingOut:
case EvqSmoothOut: case EvqSmoothOut:
case EvqFlatOut: case EvqFlatOut:
case EvqCentroidOut: case EvqCentroidOut:
...@@ -237,7 +236,6 @@ bool IsVaryingIn(TQualifier qualifier) ...@@ -237,7 +236,6 @@ bool IsVaryingIn(TQualifier qualifier)
switch (qualifier) switch (qualifier)
{ {
case EvqVaryingIn: case EvqVaryingIn:
case EvqInvariantVaryingIn:
case EvqSmoothIn: case EvqSmoothIn:
case EvqFlatIn: case EvqFlatIn:
case EvqCentroidIn: case EvqCentroidIn:
...@@ -269,8 +267,6 @@ InterpolationType GetInterpolationType(TQualifier qualifier) ...@@ -269,8 +267,6 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
case EvqFragmentIn: case EvqFragmentIn:
case EvqVaryingIn: case EvqVaryingIn:
case EvqVaryingOut: case EvqVaryingOut:
case EvqInvariantVaryingIn:
case EvqInvariantVaryingOut:
return INTERPOLATION_SMOOTH; return INTERPOLATION_SMOOTH;
case EvqCentroidIn: case EvqCentroidIn:
...@@ -301,13 +297,9 @@ void GetVariableTraverser::setTypeSpecificInfo( ...@@ -301,13 +297,9 @@ void GetVariableTraverser::setTypeSpecificInfo(
ASSERT(variable); ASSERT(variable);
switch (type.getQualifier()) switch (type.getQualifier())
{ {
case EvqInvariantVaryingIn:
case EvqInvariantVaryingOut:
variable->isInvariant = true;
break;
case EvqVaryingIn: case EvqVaryingIn:
case EvqVaryingOut: case EvqVaryingOut:
if (mSymbolTable.isVaryingInvariant(std::string(name.c_str()))) if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant())
{ {
variable->isInvariant = true; variable->isInvariant = true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment