Commit b6e07a6a by Olli Etuaho

Implement ESSL3 modf

This is the first built-in function that has an out parameter, so l-value checks are added for built-ins. BUG=angle:918 Change-Id: Ifd5befe955224f706f864e25107879c9cdce9e9f Reviewed-on: https://chromium-review.googlesource.com/250780Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 481373d8
......@@ -290,6 +290,20 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float1, float1, float3);
symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float1, float1, float4);
TType *outFloat1 = new TType(EbtFloat);
TType *outFloat2 = new TType(EbtFloat, 2);
TType *outFloat3 = new TType(EbtFloat, 3);
TType *outFloat4 = new TType(EbtFloat, 4);
outFloat1->setQualifier(EvqOut);
outFloat2->setQualifier(EvqOut);
outFloat3->setQualifier(EvqOut);
outFloat4->setQualifier(EvqOut);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "modf", float1, outFloat1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "modf", float2, outFloat2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "modf", float3, outFloat3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "modf", float4, outFloat4);
TType *bool1 = new TType(EbtBool);
TType *bool2 = new TType(EbtBool, 2);
TType *bool3 = new TType(EbtBool, 3);
......@@ -905,6 +919,7 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
symbolTable.relateToOperator(ESSL3_BUILTINS, "abs", EOpAbs);
symbolTable.relateToOperator(ESSL3_BUILTINS, "sign", EOpSign);
symbolTable.relateToOperator(ESSL3_BUILTINS, "modf", EOpModf);
symbolTable.relateToOperator(ESSL3_BUILTINS, "min", EOpMin);
symbolTable.relateToOperator(ESSL3_BUILTINS, "max", EOpMax);
symbolTable.relateToOperator(ESSL3_BUILTINS, "clamp", EOpClamp);
......
......@@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op)
case EOpCeil: return "ceil";
case EOpFract: return "fract";
case EOpMod: return "mod";
case EOpModf: return "modf";
case EOpMin: return "min";
case EOpMax: return "max";
case EOpClamp: return "clamp";
......
......@@ -114,6 +114,7 @@ enum TOperator
EOpCeil,
EOpFract,
EOpMod,
EOpModf,
EOpMin,
EOpMax,
EOpClamp,
......
......@@ -864,6 +864,9 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpMod:
writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
break;
case EOpModf:
writeBuiltInFunctionTriplet(visit, "modf(", useEmulatedFunction);
break;
case EOpPow:
writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction);
break;
......
......@@ -2139,6 +2139,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(visit, "mod(");
break;
case EOpModf: outputTriplet(visit, "modf(", ", ", ")"); break;
case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break;
case EOpAtan:
ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
......
......@@ -991,6 +991,26 @@ bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const T
return false;
}
bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
{
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
{
TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut)
{
TIntermTyped *node = (*(aggregate->getSequence()))[i]->getAsTyped();
if (lValueErrorCheck(node->getLine(), "assign", node))
{
error(node->getLine(),
"Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
recover();
return true;
}
}
}
return false;
}
bool TParseContext::supportsExtension(const char* extension)
{
const TExtensionBehavior& extbehavior = extensionBehavior();
......
......@@ -108,6 +108,7 @@ struct TParseContext {
bool extensionErrorCheck(const TSourceLoc& line, const TString&);
bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
const TPragma& pragma() const { return directiveHandler.pragma(); }
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
......
......@@ -360,6 +360,9 @@ function_call
aggregate->setType(fnCandidate->getReturnType());
aggregate->setPrecisionFromChildren();
$$ = aggregate;
// Some built-in functions have out parameters too.
context->functionCallLValueErrorCheck(fnCandidate, aggregate);
}
} else {
// This is a real function call
......@@ -380,16 +383,7 @@ function_call
$$ = aggregate;
TQualifier qual;
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut) {
if (context->lValueErrorCheck($$->getLine(), "assign", (*($$->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
context->recover();
}
}
}
context->functionCallLValueErrorCheck(fnCandidate, aggregate);
}
} else {
// error message was put out by PaFindFunction()
......
......@@ -688,32 +688,32 @@ static const yytype_uint8 yytranslate[] =
static const yytype_uint16 yyrline[] =
{
0, 205, 205, 206, 209, 233, 236, 241, 246, 251,
256, 262, 265, 268, 271, 274, 277, 283, 291, 408,
411, 419, 422, 428, 432, 439, 445, 454, 462, 465,
475, 478, 481, 484, 494, 495, 496, 497, 505, 506,
509, 512, 519, 520, 523, 529, 530, 534, 541, 542,
545, 548, 551, 557, 558, 561, 567, 568, 575, 576,
583, 584, 591, 592, 598, 599, 605, 606, 612, 613,
630, 631, 644, 645, 646, 647, 651, 652, 653, 657,
661, 665, 669, 676, 679, 690, 698, 706, 733, 739,
750, 754, 758, 762, 769, 825, 828, 835, 843, 864,
885, 895, 923, 928, 938, 943, 953, 956, 959, 962,
968, 975, 978, 982, 986, 990, 997, 1001, 1005, 1012,
1016, 1020, 1027, 1036, 1042, 1045, 1051, 1057, 1064, 1073,
1082, 1090, 1093, 1100, 1104, 1111, 1114, 1118, 1122, 1131,
1140, 1148, 1158, 1170, 1173, 1176, 1182, 1189, 1192, 1198,
1201, 1204, 1210, 1213, 1228, 1232, 1236, 1240, 1244, 1248,
1253, 1258, 1263, 1268, 1273, 1278, 1283, 1288, 1293, 1298,
1303, 1308, 1313, 1318, 1323, 1328, 1333, 1338, 1343, 1348,
1353, 1357, 1361, 1365, 1369, 1373, 1377, 1381, 1385, 1389,
1393, 1397, 1401, 1405, 1409, 1413, 1421, 1429, 1433, 1446,
1446, 1449, 1449, 1455, 1458, 1474, 1477, 1486, 1490, 1496,
1503, 1518, 1522, 1526, 1527, 1533, 1534, 1535, 1536, 1537,
1541, 1542, 1542, 1542, 1552, 1553, 1557, 1557, 1558, 1558,
1563, 1566, 1576, 1579, 1585, 1586, 1590, 1598, 1602, 1612,
1617, 1634, 1634, 1639, 1639, 1646, 1646, 1654, 1657, 1663,
1666, 1672, 1676, 1683, 1690, 1697, 1704, 1715, 1724, 1728,
1735, 1738, 1744, 1744
256, 262, 265, 268, 271, 274, 277, 283, 291, 402,
405, 413, 416, 422, 426, 433, 439, 448, 456, 459,
469, 472, 475, 478, 488, 489, 490, 491, 499, 500,
503, 506, 513, 514, 517, 523, 524, 528, 535, 536,
539, 542, 545, 551, 552, 555, 561, 562, 569, 570,
577, 578, 585, 586, 592, 593, 599, 600, 606, 607,
624, 625, 638, 639, 640, 641, 645, 646, 647, 651,
655, 659, 663, 670, 673, 684, 692, 700, 727, 733,
744, 748, 752, 756, 763, 819, 822, 829, 837, 858,
879, 889, 917, 922, 932, 937, 947, 950, 953, 956,
962, 969, 972, 976, 980, 984, 991, 995, 999, 1006,
1010, 1014, 1021, 1030, 1036, 1039, 1045, 1051, 1058, 1067,
1076, 1084, 1087, 1094, 1098, 1105, 1108, 1112, 1116, 1125,
1134, 1142, 1152, 1164, 1167, 1170, 1176, 1183, 1186, 1192,
1195, 1198, 1204, 1207, 1222, 1226, 1230, 1234, 1238, 1242,
1247, 1252, 1257, 1262, 1267, 1272, 1277, 1282, 1287, 1292,
1297, 1302, 1307, 1312, 1317, 1322, 1327, 1332, 1337, 1342,
1347, 1351, 1355, 1359, 1363, 1367, 1371, 1375, 1379, 1383,
1387, 1391, 1395, 1399, 1403, 1407, 1415, 1423, 1427, 1440,
1440, 1443, 1443, 1449, 1452, 1468, 1471, 1480, 1484, 1490,
1497, 1512, 1516, 1520, 1521, 1527, 1528, 1529, 1530, 1531,
1535, 1536, 1536, 1536, 1546, 1547, 1551, 1551, 1552, 1552,
1557, 1560, 1570, 1573, 1579, 1580, 1584, 1592, 1596, 1606,
1611, 1628, 1628, 1633, 1633, 1640, 1640, 1648, 1651, 1657,
1660, 1666, 1670, 1677, 1684, 1691, 1698, 1709, 1718, 1722,
1729, 1732, 1738, 1738
};
#endif
......@@ -2525,6 +2525,9 @@ yyreduce:
aggregate->setType(fnCandidate->getReturnType());
aggregate->setPrecisionFromChildren();
(yyval.interm.intermTypedNode) = aggregate;
// Some built-in functions have out parameters too.
context->functionCallLValueErrorCheck(fnCandidate, aggregate);
}
} else {
// This is a real function call
......@@ -2545,16 +2548,7 @@ yyreduce:
(yyval.interm.intermTypedNode) = aggregate;
TQualifier qual;
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut) {
if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (*((yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
context->error((yyvsp[0].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
context->recover();
}
}
}
context->functionCallLValueErrorCheck(fnCandidate, aggregate);
}
} else {
// error message was put out by PaFindFunction()
......
......@@ -421,6 +421,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorNotEqual: out << "NotEqual"; break;
case EOpMod: out << "mod"; break;
case EOpModf: out << "modf"; break;
case EOpPow: out << "pow"; break;
case EOpAtan: out << "arc tangent"; break;
......
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