Prevent atan2 from generating a NaN
TRAC #12184
This is necessary because a NaN generated in flattened conditional code fails to get discarded on certain devices.
Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@248 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 55f35ae..9f49a76 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -50,6 +50,7 @@
mUsesEqualBVec2 = false;
mUsesEqualBVec3 = false;
mUsesEqualBVec4 = false;
+ mUsesAtan2 = false;
mArgumentIndex = 0;
}
@@ -675,6 +676,15 @@
" return v.x == u.x && v.y == u.y && v.z == u.z && v.w == u.w;\n"
"}\n";
}
+
+ if (mUsesAtan2)
+ {
+ out << "float atanyx(float y, float x)\n"
+ "{\n"
+ " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN
+ " return atan2(y, x);\n"
+ "}\n";
+ }
}
void OutputHLSL::footer()
@@ -1450,15 +1460,9 @@
case EOpMod: outputTriplet(visit, "mod(", ", ", ")"); break;
case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break;
case EOpAtan:
- if (node->getSequence().size() == 1)
- {
- outputTriplet(visit, "atan(", ", ", ")");
- }
- else if (node->getSequence().size() == 2)
- {
- outputTriplet(visit, "atan2(", ", ", ")");
- }
- else UNREACHABLE();
+ ASSERT(node->getSequence().size() == 2); // atan(x) is a unary operator
+ mUsesAtan2 = true;
+ outputTriplet(visit, "atanyx(", ", ", ")");
break;
case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break;
case EOpMax: outputTriplet(visit, "max(", ", ", ")"); break;