Added a traverser for detecting gradient operations.

TRAC #20737 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@1121 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e2095642
......@@ -10,29 +10,110 @@
#include "compiler/DetectDiscontinuity.h"
#include "compiler/ParseHelper.h"
namespace sh
{
bool DetectDiscontinuity::traverse(TIntermNode *node)
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
{
mDiscontinuity = false;
mLoopDiscontinuity = false;
node->traverse(this);
return mDiscontinuity;
return mLoopDiscontinuity;
}
bool DetectDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
{
if (mLoopDiscontinuity)
{
return false;
}
switch (node->getFlowOp())
{
case EOpKill:
break;
case EOpBreak:
case EOpContinue:
mDiscontinuity = true;
mLoopDiscontinuity = true;
case EOpReturn:
break;
default: UNREACHABLE();
}
return !mDiscontinuity;
return !mLoopDiscontinuity;
}
bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node)
{
return !mLoopDiscontinuity;
}
bool containsLoopDiscontinuity(TIntermNode *node)
{
DetectLoopDiscontinuity detectLoopDiscontinuity;
return detectLoopDiscontinuity.traverse(node);
}
bool DetectGradientOperation::traverse(TIntermNode *node)
{
mGradientOperation = false;
node->traverse(this);
return mGradientOperation;
}
bool DetectGradientOperation::visitUnary(Visit visit, TIntermUnary *node)
{
if (mGradientOperation)
{
return false;
}
switch (node->getOp())
{
case EOpDFdx:
case EOpDFdy:
mGradientOperation = true;
default:
break;
}
return !mGradientOperation;
}
bool DetectGradientOperation::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (mGradientOperation)
{
return false;
}
if (node->getOp() == EOpFunctionCall)
{
if (!node->isUserDefined())
{
TString name = TFunction::unmangleName(node->getName());
if (name == "texture2D" ||
name == "texture2DProj" ||
name == "textureCube")
{
mGradientOperation = true;
}
}
else
{
// When a user defined function is called, we have to
// conservatively assume it to contain gradient operations
mGradientOperation = true;
}
}
return !mGradientOperation;
}
bool containsGradientOperation(TIntermNode *node)
{
DetectGradientOperation detectGradientOperation;
return detectGradientOperation.traverse(node);
}
}
......@@ -15,22 +15,36 @@
namespace sh
{
class DetectDiscontinuity : public TIntermTraverser
// Checks whether a loop can run for a variable number of iterations
class DetectLoopDiscontinuity : public TIntermTraverser
{
public:
bool traverse(TIntermNode *node);
protected:
bool visitBranch(Visit visit, TIntermBranch *node);
bool visitAggregate(Visit visit, TIntermAggregate *node);
bool mDiscontinuity;
bool mLoopDiscontinuity;
};
bool containsDiscontinuity(TIntermNode *node)
bool containsLoopDiscontinuity(TIntermNode *node);
// Checks for intrinsic functions which compute gradients
class DetectGradientOperation : public TIntermTraverser
{
DetectDiscontinuity detectDiscontinuity;
return detectDiscontinuity.traverse(node);
}
public:
bool traverse(TIntermNode *node);
protected:
bool visitUnary(Visit visit, TIntermUnary *node);
bool visitAggregate(Visit visit, TIntermAggregate *node);
bool mGradientOperation;
};
bool containsGradientOperation(TIntermNode *node);
}
#endif // COMPILER_DETECTDISCONTINUITY_H_
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