Add a new invariant declaration operator.
BUG=angle:711
Change-Id: I54a48b636a68c317b8d44ee2d578847b80095289
Reviewed-on: https://chromium-review.googlesource.com/213500
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index 7260799..324b066 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -69,7 +69,6 @@
EbtStruct,
EbtInterfaceBlock,
EbtAddress, // should be deprecated??
- EbtInvariant // used as a type when qualifying a previously declared variable as being invariant
};
const char* getBasicString(TBasicType t);
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 892f284..ec440da 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -37,6 +37,7 @@
EOpParameters, // an aggregate listing the parameters to a function
EOpDeclaration,
+ EOpInvariantDeclaration, // Specialized declarations for attributing invariance
EOpPrototype,
//
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 09f7ad9..6d07ccc 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -81,8 +81,7 @@
{
TInfoSinkBase &out = objSink();
TQualifier qualifier = type.getQualifier();
- if (qualifier != EvqTemporary && qualifier != EvqGlobal &&
- type.getBasicType() != EbtInvariant)
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
out << type.getQualifierString() << " ";
}
@@ -650,6 +649,17 @@
mDeclaringVariables = false;
}
break;
+ case EOpInvariantDeclaration: {
+ // Invariant declaration.
+ ASSERT(visit == PreVisit);
+ const TIntermSequence *sequence = node->getSequence();
+ ASSERT(sequence && sequence->size() == 1);
+ const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
+ ASSERT(symbol);
+ out << "invariant " << symbol->getSymbol() << ";";
+ visitChildren = false;
+ break;
+ }
case EOpConstructFloat:
writeTriplet(visit, "float(", NULL, ")");
break;
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 93994ba..e0a90ec 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1937,12 +1937,6 @@
}
else if (variable && IsVaryingOut(variable->getQualifier()))
{
- // Skip translation of invariant declarations
- if (variable->getBasicType() == EbtInvariant)
- {
- return false;
- }
-
for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
{
TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
@@ -1966,6 +1960,9 @@
out << ", ";
}
break;
+ case EOpInvariantDeclaration:
+ // Do not do any translation
+ return false;
case EOpPrototype:
if (visit == PreVisit)
{
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 04797da..ff0a496 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1089,6 +1089,8 @@
// Initializers show up in several places in the grammar. Have one set of
// code to handle them here.
//
+// Returns true on error, false if no error
+//
bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
{
@@ -1352,6 +1354,7 @@
const TString *identifier,
const TSymbol *symbol)
{
+ // invariant declaration
if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
{
recover();
@@ -1366,21 +1369,20 @@
}
else
{
- TType type(EbtInvariant);
- type.setQualifier(EvqInvariantVaryingOut);
- TIntermSymbol *symbol = intermediate.addSymbol(0, *identifier, type, identifierLoc);
- return intermediate.makeAggregate(symbol, identifierLoc);
+ const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
+ ASSERT(variable);
+ const TType &type = variable->getType();
+ TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
+ *identifier, type, identifierLoc);
+
+ TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
+ aggregate->setOp(EOpInvariantDeclaration);
+ return aggregate;
}
}
TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
{
- if (publicType.type == EbtInvariant && !identifierSymbol)
- {
- error(identifierLocation, "undeclared identifier declared as invariant", identifier.c_str());
- recover();
- }
-
TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
diff --git a/src/compiler/translator/Types.cpp b/src/compiler/translator/Types.cpp
index d39ab01..d36936f 100644
--- a/src/compiler/translator/Types.cpp
+++ b/src/compiler/translator/Types.cpp
@@ -41,7 +41,6 @@
case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
case EbtStruct: return "structure"; break;
case EbtInterfaceBlock: return "interface block"; break;
- case EbtInvariant: return "invariant"; break;
default: UNREACHABLE(); return "unknown type";
}
}
diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp
index 0bd95cb..54129d4 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -346,12 +346,7 @@
visitInfoList(sequence, mUniforms);
break;
default:
- // do not traverse invariant declarations such as
- // "invariant gl_Position;"
- if (typedNode.getBasicType() != EbtInvariant)
- {
- visitInfoList(sequence, mVaryings);
- }
+ visitInfoList(sequence, mVaryings);
break;
}
diff --git a/src/compiler/translator/VersionGLSL.cpp b/src/compiler/translator/VersionGLSL.cpp
index 12dc9e0..8edbd00 100644
--- a/src/compiler/translator/VersionGLSL.cpp
+++ b/src/compiler/translator/VersionGLSL.cpp
@@ -67,6 +67,9 @@
}
break;
}
+ case EOpInvariantDeclaration:
+ updateVersion(GLSL_VERSION_120);
+ break;
case EOpParameters:
{
const TIntermSequence ¶ms = *(node->getSequence());
diff --git a/src/compiler/translator/glslang.y b/src/compiler/translator/glslang.y
index c0479f6..5c945ad 100644
--- a/src/compiler/translator/glslang.y
+++ b/src/compiler/translator/glslang.y
@@ -1072,8 +1072,7 @@
$$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4);
}
| INVARIANT IDENTIFIER {
- VERTEX_ONLY("invariant declaration", @1);
- $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
+ // $$.type is not used in invariant declarations.
$$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol);
}
;
diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp
index 2fb9089..6d483b1 100644
--- a/src/compiler/translator/glslang_tab.cpp
+++ b/src/compiler/translator/glslang_tab.cpp
@@ -805,22 +805,22 @@
730, 733, 744, 752, 760, 787, 793, 804, 808, 812,
816, 823, 879, 882, 889, 897, 918, 939, 949, 977,
982, 992, 997, 1007, 1010, 1013, 1016, 1022, 1029, 1032,
- 1036, 1040, 1044, 1051, 1055, 1059, 1066, 1070, 1074, 1082,
- 1091, 1097, 1100, 1106, 1112, 1119, 1128, 1137, 1145, 1148,
- 1155, 1159, 1166, 1169, 1173, 1177, 1186, 1195, 1203, 1213,
- 1225, 1228, 1231, 1237, 1244, 1247, 1253, 1256, 1259, 1265,
- 1268, 1283, 1287, 1291, 1295, 1299, 1303, 1308, 1313, 1318,
- 1323, 1328, 1333, 1338, 1343, 1348, 1353, 1358, 1363, 1368,
- 1373, 1378, 1383, 1388, 1393, 1398, 1403, 1408, 1412, 1416,
- 1420, 1424, 1428, 1432, 1436, 1440, 1444, 1448, 1452, 1456,
- 1460, 1464, 1468, 1476, 1484, 1488, 1501, 1501, 1504, 1504,
- 1510, 1513, 1529, 1532, 1541, 1545, 1551, 1558, 1573, 1577,
- 1581, 1582, 1588, 1589, 1590, 1591, 1592, 1596, 1597, 1597,
- 1597, 1607, 1608, 1612, 1612, 1613, 1613, 1618, 1621, 1631,
- 1634, 1640, 1641, 1645, 1653, 1657, 1667, 1672, 1689, 1689,
- 1694, 1694, 1701, 1701, 1709, 1712, 1718, 1721, 1727, 1731,
- 1738, 1745, 1752, 1759, 1770, 1779, 1783, 1790, 1793, 1799,
- 1799
+ 1036, 1040, 1044, 1051, 1055, 1059, 1066, 1070, 1074, 1081,
+ 1090, 1096, 1099, 1105, 1111, 1118, 1127, 1136, 1144, 1147,
+ 1154, 1158, 1165, 1168, 1172, 1176, 1185, 1194, 1202, 1212,
+ 1224, 1227, 1230, 1236, 1243, 1246, 1252, 1255, 1258, 1264,
+ 1267, 1282, 1286, 1290, 1294, 1298, 1302, 1307, 1312, 1317,
+ 1322, 1327, 1332, 1337, 1342, 1347, 1352, 1357, 1362, 1367,
+ 1372, 1377, 1382, 1387, 1392, 1397, 1402, 1407, 1411, 1415,
+ 1419, 1423, 1427, 1431, 1435, 1439, 1443, 1447, 1451, 1455,
+ 1459, 1463, 1467, 1475, 1483, 1487, 1500, 1500, 1503, 1503,
+ 1509, 1512, 1528, 1531, 1540, 1544, 1550, 1557, 1572, 1576,
+ 1580, 1581, 1587, 1588, 1589, 1590, 1591, 1595, 1596, 1596,
+ 1596, 1606, 1607, 1611, 1611, 1612, 1612, 1617, 1620, 1630,
+ 1633, 1639, 1640, 1644, 1652, 1656, 1666, 1671, 1688, 1688,
+ 1693, 1693, 1700, 1700, 1708, 1711, 1717, 1720, 1726, 1730,
+ 1737, 1744, 1751, 1758, 1769, 1778, 1782, 1789, 1792, 1798,
+ 1798
};
#endif
@@ -3689,8 +3689,7 @@
case 108:
{
- VERTEX_ONLY("invariant declaration", (yylsp[(1) - (2)]));
- (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yylsp[(2) - (2)]));
+ // $$.type is not used in invariant declarations.
(yyval.interm).intermAggregate = context->parseInvariantDeclaration((yylsp[(1) - (2)]), (yylsp[(2) - (2)]), (yyvsp[(2) - (2)].lex).string, (yyvsp[(2) - (2)].lex).symbol);
}
break;
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index 52a6f51..56340c6 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -342,6 +342,7 @@
case EOpMul: out << "component-wise multiply"; break;
case EOpDeclaration: out << "Declaration: "; break;
+ case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
default:
out.prefix(EPrefixError);