Commit d68924e5 by Olli Etuaho Committed by Commit Bot

Use GetOperatorString when writing GLSL unary built-in calls

GetOperatorString is now used when writing GLSL for built-in calls that fall under TIntermUnary. Component-wise not TOperator enum is renamed for consistency. This also cleans up some unnecessary creation of string objects when writing built-in functions. BUG=angleproject:1682 TEST=angle_unittests, angle_end2end_tests, WebGL conformance tests Change-Id: I89b2ef222bf5af479d4977417f320789b58ace85 Reviewed-on: https://chromium-review.googlesource.com/424552 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent a1325179
......@@ -228,10 +228,10 @@ void BuiltInFunctionEmulator::Cleanup()
}
// static
TString BuiltInFunctionEmulator::GetEmulatedFunctionName(const TString &name)
void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
{
ASSERT(name[name.length() - 1] == '(');
return "webgl_" + name.substr(0, name.length() - 1) + "_emu(";
ASSERT(name[strlen(name) - 1] != '(');
out << "webgl_" << name << "_emu";
}
BuiltInFunctionEmulator::FunctionId::FunctionId()
......
......@@ -27,8 +27,8 @@ class BuiltInFunctionEmulator
void Cleanup();
// "name(" becomes "webgl_name_emu(".
static TString GetEmulatedFunctionName(const TString &name);
// "name" gets written as "webgl_name_emu".
static void WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name);
bool IsOutputEmpty() const;
......
......@@ -676,12 +676,12 @@ bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative:
case EOpVectorLogicalNot:
case EOpLogicalNot:
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
case EOpPreDecrement:
case EOpLogicalNotComponentWise:
break;
default:
if (canRoundFloat(node->getType()) && visit == PreVisit)
......
......@@ -272,7 +272,7 @@ void InsertBuiltInFunctions(sh::GLenum type,
bvec);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAny, bool1, "any", bvec);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, "not", bvec);
const TType *sampler2D = TCache::getType(EbtSampler2D);
const TType *samplerCube = TCache::getType(EbtSamplerCube);
......
......@@ -2123,7 +2123,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
}
break;
case EOpVectorLogicalNot:
case EOpLogicalNotComponentWise:
ASSERT(getType().getBasicType() == EbtBool);
resultArray[i].setBConst(!operandArray[i].getBConst());
break;
......
......@@ -18,8 +18,6 @@ const char *GetOperatorString(TOperator op)
return "+";
case EOpLogicalNot:
return "!";
case EOpVectorLogicalNot:
return "not";
case EOpBitwiseNot:
return "~";
......@@ -251,6 +249,8 @@ const char *GetOperatorString(TOperator op)
return "any";
case EOpAll:
return "all";
case EOpLogicalNotComponentWise:
return "not";
case EOpKill:
return "kill";
......
......@@ -25,7 +25,6 @@ enum TOperator
EOpNegative,
EOpPositive,
EOpLogicalNot,
EOpVectorLogicalNot,
EOpBitwiseNot,
EOpPostIncrement,
......@@ -34,7 +33,8 @@ enum TOperator
EOpPreDecrement,
//
// binary operations
// binary operations (ones with special GLSL syntax are used in TIntermBinary nodes, others in
// TIntermAggregate nodes)
//
EOpAdd,
......@@ -82,7 +82,7 @@ enum TOperator
EOpIndexDirectInterfaceBlock,
//
// Built-in functions potentially mapped to operators
// Built-in functions mapped to operators (either unary or with multiple parameters)
//
EOpRadians,
......@@ -161,6 +161,7 @@ enum TOperator
EOpAny,
EOpAll,
EOpLogicalNotComponentWise,
//
// Branch
......
......@@ -143,13 +143,24 @@ void TOutputGLSLBase::writeBuiltInFunctionTriplet(Visit visit,
TOperator op,
bool useEmulatedFunction)
{
TString opStr(GetOperatorString(op));
opStr += "(";
TInfoSinkBase &out = objSink();
if (visit == PreVisit)
{
const char *opStr(GetOperatorString(op));
if (useEmulatedFunction)
{
opStr = BuiltInFunctionEmulator::GetEmulatedFunctionName(opStr);
BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, opStr);
}
else
{
out << opStr;
}
out << "(";
}
else
{
writeTriplet(visit, nullptr, ", ", ")");
}
writeTriplet(visit, opStr.c_str(), ", ", ")");
}
void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
......@@ -641,9 +652,6 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
case EOpPositive:
preString = "(+";
break;
case EOpVectorLogicalNot:
preString = "not(";
break;
case EOpLogicalNot:
preString = "(!";
break;
......@@ -667,171 +675,62 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
break;
case EOpRadians:
preString = "radians(";
break;
case EOpDegrees:
preString = "degrees(";
break;
case EOpSin:
preString = "sin(";
break;
case EOpCos:
preString = "cos(";
break;
case EOpTan:
preString = "tan(";
break;
case EOpAsin:
preString = "asin(";
break;
case EOpAcos:
preString = "acos(";
break;
case EOpAtan:
preString = "atan(";
break;
case EOpSinh:
preString = "sinh(";
break;
case EOpCosh:
preString = "cosh(";
break;
case EOpTanh:
preString = "tanh(";
break;
case EOpAsinh:
preString = "asinh(";
break;
case EOpAcosh:
preString = "acosh(";
break;
case EOpAtanh:
preString = "atanh(";
break;
case EOpExp:
preString = "exp(";
break;
case EOpLog:
preString = "log(";
break;
case EOpExp2:
preString = "exp2(";
break;
case EOpLog2:
preString = "log2(";
break;
case EOpSqrt:
preString = "sqrt(";
break;
case EOpInverseSqrt:
preString = "inversesqrt(";
break;
case EOpAbs:
preString = "abs(";
break;
case EOpSign:
preString = "sign(";
break;
case EOpFloor:
preString = "floor(";
break;
case EOpTrunc:
preString = "trunc(";
break;
case EOpRound:
preString = "round(";
break;
case EOpRoundEven:
preString = "roundEven(";
break;
case EOpCeil:
preString = "ceil(";
break;
case EOpFract:
preString = "fract(";
break;
case EOpIsNan:
preString = "isnan(";
break;
case EOpIsInf:
preString = "isinf(";
break;
case EOpFloatBitsToInt:
preString = "floatBitsToInt(";
break;
case EOpFloatBitsToUint:
preString = "floatBitsToUint(";
break;
case EOpIntBitsToFloat:
preString = "intBitsToFloat(";
break;
case EOpUintBitsToFloat:
preString = "uintBitsToFloat(";
break;
case EOpPackSnorm2x16:
preString = "packSnorm2x16(";
break;
case EOpPackUnorm2x16:
preString = "packUnorm2x16(";
break;
case EOpPackHalf2x16:
preString = "packHalf2x16(";
break;
case EOpUnpackSnorm2x16:
preString = "unpackSnorm2x16(";
break;
case EOpUnpackUnorm2x16:
preString = "unpackUnorm2x16(";
break;
case EOpUnpackHalf2x16:
preString = "unpackHalf2x16(";
break;
case EOpLength:
preString = "length(";
break;
case EOpNormalize:
preString = "normalize(";
break;
case EOpDFdx:
preString = "dFdx(";
break;
case EOpDFdy:
preString = "dFdy(";
break;
case EOpFwidth:
preString = "fwidth(";
break;
case EOpTranspose:
preString = "transpose(";
break;
case EOpDeterminant:
preString = "determinant(";
break;
case EOpInverse:
preString = "inverse(";
break;
case EOpAny:
preString = "any(";
break;
case EOpAll:
preString = "all(";
break;
case EOpLogicalNotComponentWise:
writeBuiltInFunctionTriplet(visit, node->getOp(), node->getUseEmulatedFunction());
return true;
default:
UNREACHABLE();
}
if (visit == PreVisit && node->getUseEmulatedFunction())
preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
writeTriplet(visit, preString.c_str(), NULL, postString.c_str());
return true;
......@@ -976,7 +875,6 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
TInfoSinkBase &out = objSink();
bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction());
switch (node->getOp())
{
case EOpPrototype:
......@@ -1074,7 +972,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpMemoryBarrierImage:
case EOpMemoryBarrierShared:
case EOpGroupMemoryBarrier:
writeBuiltInFunctionTriplet(visit, node->getOp(), useEmulatedFunction);
writeBuiltInFunctionTriplet(visit, node->getOp(), node->getUseEmulatedFunction());
break;
default:
UNREACHABLE();
......
......@@ -1199,9 +1199,6 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpPositive:
outputTriplet(out, visit, "(+", "", ")");
break;
case EOpVectorLogicalNot:
outputTriplet(out, visit, "(!", "", ")");
break;
case EOpLogicalNot:
outputTriplet(out, visit, "(!", "", ")");
break;
......@@ -1254,16 +1251,10 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
outputTriplet(out, visit, "tanh(", "", ")");
break;
case EOpAsinh:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "asinh(");
break;
case EOpAcosh:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "acosh(");
break;
case EOpAtanh:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "atanh(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpExp:
outputTriplet(out, visit, "exp(", "", ")");
......@@ -1300,7 +1291,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
break;
case EOpRoundEven:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "roundEven(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpCeil:
outputTriplet(out, visit, "ceil(", "", ")");
......@@ -1310,7 +1301,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
break;
case EOpIsNan:
if (node->getUseEmulatedFunction())
writeEmulatedFunctionTriplet(out, visit, "isnan(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
else
outputTriplet(out, visit, "isnan(", "", ")");
mRequiresIEEEStrictCompiling = true;
......@@ -1331,28 +1322,13 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
outputTriplet(out, visit, "asfloat(", "", ")");
break;
case EOpPackSnorm2x16:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "packSnorm2x16(");
break;
case EOpPackUnorm2x16:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "packUnorm2x16(");
break;
case EOpPackHalf2x16:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "packHalf2x16(");
break;
case EOpUnpackSnorm2x16:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "unpackSnorm2x16(");
break;
case EOpUnpackUnorm2x16:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "unpackUnorm2x16(");
break;
case EOpUnpackHalf2x16:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "unpackHalf2x16(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpLength:
outputTriplet(out, visit, "length(", "", ")");
......@@ -1398,7 +1374,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
break;
case EOpInverse:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "inverse(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpAny:
......@@ -1407,6 +1383,9 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpAll:
outputTriplet(out, visit, "all(", "", ")");
break;
case EOpLogicalNotComponentWise:
outputTriplet(out, visit, "(!", "", ")");
break;
default:
UNREACHABLE();
}
......@@ -1866,7 +1845,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
break;
case EOpMod:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "mod(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpModf:
outputTriplet(out, visit, "modf(", ", ", ")");
......@@ -1877,7 +1856,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpAtan:
ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "atan(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpMin:
outputTriplet(out, visit, "min(", ", ", ")");
......@@ -1897,7 +1876,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
// y, genBType a)",
// so use emulated version.
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "mix(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
}
else
{
......@@ -1922,7 +1901,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
break;
case EOpFaceForward:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "faceforward(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpReflect:
outputTriplet(out, visit, "reflect(", ", ", ")");
......@@ -1932,7 +1911,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
break;
case EOpOuterProduct:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, "outerProduct(");
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;
case EOpMulMatrixComponentWise:
outputTriplet(out, visit, "(", " * ", ")");
......@@ -2634,10 +2613,18 @@ const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out,
return constUnionIterated;
}
void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr)
void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, TOperator op)
{
TString preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr);
outputTriplet(out, visit, preString.c_str(), ", ", ")");
if (visit == PreVisit)
{
const char *opStr = GetOperatorString(op);
BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, opStr);
out << "(";
}
else
{
outputTriplet(out, visit, nullptr, ", ", ")");
}
}
bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out,
......
......@@ -109,7 +109,7 @@ class OutputHLSL : public TIntermTraverser
void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr);
void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, TOperator op);
void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
// Returns true if it found a 'same symbol' initializer (initializer that references the
......@@ -122,7 +122,6 @@ class OutputHLSL : public TIntermTraverser
TIntermSymbol *symbolNode,
TIntermTyped *expression);
void writeDeferredGlobalInitializers(TInfoSinkBase &out);
void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node);
// Returns the function name
......
......@@ -300,9 +300,8 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
case EOpPositive:
out << "Positive sign";
break;
case EOpVectorLogicalNot:
case EOpLogicalNot:
out << "Negate conditional";
out << "negation";
break;
case EOpBitwiseNot:
out << "bit-wise not";
......@@ -474,6 +473,9 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
case EOpAll:
out << "all";
break;
case EOpLogicalNotComponentWise:
out << "component-wise not";
break;
default:
out.prefix(SH_ERROR);
......
......@@ -197,7 +197,7 @@ TEST_F(TypeTrackingTest, BuiltInBoolFunctionResultType)
ASSERT_FALSE(foundErrorInIntermediateTree());
ASSERT_TRUE(foundInIntermediateTree("any (bool)"));
ASSERT_TRUE(foundInIntermediateTree("all (bool)"));
ASSERT_TRUE(foundInIntermediateTree("Negate conditional (4-component vector of bool)"));
ASSERT_TRUE(foundInIntermediateTree("component-wise not (4-component vector of bool)"));
}
TEST_F(TypeTrackingTest, BuiltInVecToBoolFunctionResultType)
......
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