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
parent adf02846
......@@ -50,6 +50,7 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mUsesEqualBVec2 = false;
mUsesEqualBVec3 = false;
mUsesEqualBVec4 = false;
mUsesAtan2 = false;
mArgumentIndex = 0;
}
......@@ -675,6 +676,15 @@ void OutputHLSL::header()
" 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 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
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;
......
......@@ -89,6 +89,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesEqualBVec2;
bool mUsesEqualBVec3;
bool mUsesEqualBVec4;
bool mUsesAtan2;
struct Constructor // Describes a constructor signature
{
......
......@@ -895,7 +895,7 @@ ID3DXBuffer *Program::compileToBinary(const char *hlsl, const char *profile, ID3
ID3DXBuffer *binary = NULL;
ID3DXBuffer *errorMessage = NULL;
HRESULT result = D3DXCompileShader(hlsl, (UINT)strlen(hlsl), NULL, 0, "main", profile, 0, &binary, &errorMessage, constantTable);
HRESULT result = D3DXCompileShader(hlsl, (UINT)strlen(hlsl), NULL, NULL, "main", profile, 0, &binary, &errorMessage, constantTable);
if (SUCCEEDED(result))
{
......
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