Commit 80bacde5 by Corentin Wallez

Use the [[flatten]] attribute only when a loop is present.

Flattening branch-heavy shaders that contained no loops caused regressions. As a temporary workaround we only flatten ifs when there exists a loop. BUG=395048 Change-Id: I95c40f0249643b98c62304a0f2a4563561d1fbbc Reviewed-on: https://chromium-review.googlesource.com/228722Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 560eef16
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
namespace sh namespace sh
{ {
// Detect Loop Discontinuity
bool DetectLoopDiscontinuity::traverse(TIntermNode *node) bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
{ {
mLoopDepth = 0; mLoopDepth = 0;
...@@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node) ...@@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node)
return detectLoopDiscontinuity.traverse(node); return detectLoopDiscontinuity.traverse(node);
} }
// Detect Any Loop
bool DetectAnyLoop::traverse(TIntermNode *node)
{
mHasLoop = false;
node->traverse(this);
return mHasLoop;
}
bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop)
{
mHasLoop = true;
return false;
}
// The following definitions stop all traversal when we have found a loop
bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *)
{
return !mHasLoop;
}
bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *)
{
return !mHasLoop;
}
bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *)
{
return !mHasLoop;
}
bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *)
{
return !mHasLoop;
}
bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *)
{
return !mHasLoop;
}
bool containsAnyLoop(TIntermNode *node)
{
DetectAnyLoop detectAnyLoop;
return detectAnyLoop.traverse(node);
}
// Detect Gradient Operation
bool DetectGradientOperation::traverse(TIntermNode *node) bool DetectGradientOperation::traverse(TIntermNode *node)
{ {
mGradientOperation = false; mGradientOperation = false;
......
...@@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser ...@@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser
bool containsLoopDiscontinuity(TIntermNode *node); bool containsLoopDiscontinuity(TIntermNode *node);
// Checks for the existence of any loop
class DetectAnyLoop : public TIntermTraverser
{
public:
bool traverse(TIntermNode *node);
protected:
bool visitBinary(Visit, TIntermBinary *);
bool visitUnary(Visit, TIntermUnary *);
bool visitSelection(Visit, TIntermSelection *);
bool visitAggregate(Visit, TIntermAggregate *);
bool visitLoop(Visit, TIntermLoop *);
bool visitBranch(Visit, TIntermBranch *);
bool mHasLoop;
};
bool containsAnyLoop(TIntermNode *node);
// Checks for intrinsic functions which compute gradients // Checks for intrinsic functions which compute gradients
class DetectGradientOperation : public TIntermTraverser class DetectGradientOperation : public TIntermTraverser
{ {
......
...@@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator) ...@@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
mUniqueIndex = 0; mUniqueIndex = 0;
mContainsLoopDiscontinuity = false; mContainsLoopDiscontinuity = false;
mContainsAnyLoop = false;
mOutputLod0Function = false; mOutputLod0Function = false;
mInsideDiscontinuousLoop = false; mInsideDiscontinuousLoop = false;
mNestedLoopDepth = 0; mNestedLoopDepth = 0;
...@@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL() ...@@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL()
void OutputHLSL::output() void OutputHLSL::output()
{ {
mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot); mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot); const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
makeFlaggedStructMaps(flaggedStructs); makeFlaggedStructMaps(flaggedStructs);
...@@ -2301,7 +2303,16 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) ...@@ -2301,7 +2303,16 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{ {
mUnfoldShortCircuit->traverse(node->getCondition()); mUnfoldShortCircuit->traverse(node->getCondition());
out << "FLATTEN if ("; // D3D errors when there is a gradient operation in a loop in an unflattened if
// however flattening all the ifs in branch heavy shaders made D3D error too.
// As a temporary workaround we flatten the ifs only if there is at least a loop
// present somewhere in the shader.
if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
{
out << "FLATTEN ";
}
out << "if (";
node->getCondition()->traverse(this); node->getCondition()->traverse(this);
......
...@@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser
int mUniqueIndex; // For creating unique names int mUniqueIndex; // For creating unique names
bool mContainsLoopDiscontinuity; bool mContainsLoopDiscontinuity;
bool mContainsAnyLoop;
bool mOutputLod0Function; bool mOutputLod0Function;
bool mInsideDiscontinuousLoop; bool mInsideDiscontinuousLoop;
int mNestedLoopDepth; int mNestedLoopDepth;
......
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