Implement trunc, round, roundEven (Emulated roundEven)
BUG=angle:934
Change-Id: If33256bf3707f3f0202147276c71f08c65518205
Reviewed-on: https://chromium-review.googlesource.com/254842
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
index 0068249..52f75d0 100644
--- a/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
+++ b/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -194,6 +194,35 @@
" return 0.5 * log((1.0 + x) / (1.0 - x));\n"
"}\n");
+ AddEmulatedFunction(EOpRoundEven, float1,
+ "float webgl_roundEven_emu(in float x) {\n"
+ " return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
+ "}\n");
+ AddEmulatedFunction(EOpRoundEven, float2,
+ "float2 webgl_roundEven_emu(in float2 x) {\n"
+ " float2 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " return v;\n"
+ "}\n");
+ AddEmulatedFunction(EOpRoundEven, float3,
+ "float3 webgl_roundEven_emu(in float3 x) {\n"
+ " float3 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
+ " return v;\n"
+ "}\n");
+ AddEmulatedFunction(EOpRoundEven, float4,
+ "float4 webgl_roundEven_emu(in float4 x) {\n"
+ " float4 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
+ " v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n"
+ " return v;\n"
+ "}\n");
+
AddEmulatedFunction(EOpPackSnorm2x16, float2,
"int webgl_toSnorm(in float x) {\n"
" return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index 6c87c61..7832c86 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -69,6 +69,9 @@
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSign, genType, "sign", genType);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSign, genIType, "sign", genIType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFloor, genType, "floor", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTrunc, genType, "trunc", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRound, genType, "round", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRoundEven, genType, "roundEven", genType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCeil, genType, "ceil", genType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFract, genType, "fract", genType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, float1);
diff --git a/src/compiler/translator/Operator.cpp b/src/compiler/translator/Operator.cpp
index ef78607..ae4512b 100644
--- a/src/compiler/translator/Operator.cpp
+++ b/src/compiler/translator/Operator.cpp
@@ -91,6 +91,9 @@
case EOpAbs: return "abs";
case EOpSign: return "sign";
case EOpFloor: return "floor";
+ case EOpTrunc: return "trunc";
+ case EOpRound: return "round";
+ case EOpRoundEven: return "roundEven";
case EOpCeil: return "ceil";
case EOpFract: return "fract";
case EOpMod: return "mod";
diff --git a/src/compiler/translator/Operator.h b/src/compiler/translator/Operator.h
index 4884f1c..8290f95 100644
--- a/src/compiler/translator/Operator.h
+++ b/src/compiler/translator/Operator.h
@@ -111,6 +111,9 @@
EOpAbs,
EOpSign,
EOpFloor,
+ EOpTrunc,
+ EOpRound,
+ EOpRoundEven,
EOpCeil,
EOpFract,
EOpMod,
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index cea2b4a..4827ee1 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -549,6 +549,15 @@
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;
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index fce12f1..faa760f 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1680,6 +1680,12 @@
case EOpAbs: outputTriplet(visit, "abs(", "", ")"); break;
case EOpSign: outputTriplet(visit, "sign(", "", ")"); break;
case EOpFloor: outputTriplet(visit, "floor(", "", ")"); break;
+ case EOpTrunc: outputTriplet(visit, "trunc(", "", ")"); break;
+ case EOpRound: outputTriplet(visit, "round(", "", ")"); break;
+ case EOpRoundEven:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "roundEven(");
+ break;
case EOpCeil: outputTriplet(visit, "ceil(", "", ")"); break;
case EOpFract: outputTriplet(visit, "frac(", "", ")"); break;
case EOpIsNan: outputTriplet(visit, "isnan(", "", ")"); break;
diff --git a/src/compiler/translator/intermOut.cpp b/src/compiler/translator/intermOut.cpp
index 614cdc4..07c50f0 100644
--- a/src/compiler/translator/intermOut.cpp
+++ b/src/compiler/translator/intermOut.cpp
@@ -327,6 +327,9 @@
case EOpAbs: out << "Absolute value"; break;
case EOpSign: out << "Sign"; break;
case EOpFloor: out << "Floor"; break;
+ case EOpTrunc: out << "Truncate"; break;
+ case EOpRound: out << "Round"; break;
+ case EOpRoundEven: out << "Round half even"; break;
case EOpCeil: out << "Ceiling"; break;
case EOpFract: out << "Fraction"; break;
case EOpIsNan: out << "Is not a number"; break;