Treat return statements in loops as loop discontinuities.

This is so that texture2D is converted to texture2DLod in loops with return statements. HLSL does not seem to allow gradient operations in loops with return statements. It considers them to be breaks. Review URL: https://codereview.appspot.com/7131057 git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1788 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 51817d40
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 1 #define MINOR_VERSION 1
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1719 #define BUILD_REVISION 1722
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -16,11 +16,26 @@ namespace sh ...@@ -16,11 +16,26 @@ namespace sh
{ {
bool DetectLoopDiscontinuity::traverse(TIntermNode *node) bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
{ {
mLoopDepth = 0;
mLoopDiscontinuity = false; mLoopDiscontinuity = false;
node->traverse(this); node->traverse(this);
return mLoopDiscontinuity; return mLoopDiscontinuity;
} }
bool DetectLoopDiscontinuity::visitLoop(Visit visit, TIntermLoop *loop)
{
if (visit == PreVisit)
{
++mLoopDepth;
}
else if (visit == PostVisit)
{
--mLoopDepth;
}
return true;
}
bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node) bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
{ {
if (mLoopDiscontinuity) if (mLoopDiscontinuity)
...@@ -28,14 +43,19 @@ bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node) ...@@ -28,14 +43,19 @@ bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
return false; return false;
} }
if (!mLoopDepth)
{
return true;
}
switch (node->getFlowOp()) switch (node->getFlowOp())
{ {
case EOpKill: case EOpKill:
break; break;
case EOpBreak: case EOpBreak:
case EOpContinue: case EOpContinue:
mLoopDiscontinuity = true;
case EOpReturn: case EOpReturn:
mLoopDiscontinuity = true;
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
......
...@@ -23,8 +23,10 @@ class DetectLoopDiscontinuity : public TIntermTraverser ...@@ -23,8 +23,10 @@ class DetectLoopDiscontinuity : public TIntermTraverser
protected: protected:
bool visitBranch(Visit visit, TIntermBranch *node); bool visitBranch(Visit visit, TIntermBranch *node);
bool visitLoop(Visit visit, TIntermLoop *loop);
bool visitAggregate(Visit visit, TIntermAggregate *node); bool visitAggregate(Visit visit, TIntermAggregate *node);
int mLoopDepth;
bool mLoopDiscontinuity; bool mLoopDiscontinuity;
}; };
......
...@@ -118,7 +118,7 @@ OutputHLSL::~OutputHLSL() ...@@ -118,7 +118,7 @@ OutputHLSL::~OutputHLSL()
void OutputHLSL::output() void OutputHLSL::output()
{ {
mContainsLoopDiscontinuity = containsLoopDiscontinuity(mContext.treeRoot); mContainsLoopDiscontinuity = mContext.shaderType == SH_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header
header(); header();
...@@ -2075,7 +2075,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) ...@@ -2075,7 +2075,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{ {
bool wasDiscontinuous = mInsideDiscontinuousLoop; bool wasDiscontinuous = mInsideDiscontinuousLoop;
if (!mInsideDiscontinuousLoop) if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop)
{ {
mInsideDiscontinuousLoop = containsLoopDiscontinuity(node); mInsideDiscontinuousLoop = containsLoopDiscontinuity(node);
} }
......
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