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