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