summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp155
1 files changed, 83 insertions, 72 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp
index 31bfae9966..b04fc28259 100644
--- a/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -9,8 +9,12 @@
#include "compiler/translator/ASTMetadataHLSL.h"
#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/SymbolTable.h"
+namespace sh
+{
+
namespace
{
@@ -29,9 +33,22 @@ class PullGradient : public TIntermTraverser
mDag(dag)
{
ASSERT(index < metadataList->size());
+
+ // ESSL 100 builtin gradient functions
+ mGradientBuiltinFunctions.insert("texture2D");
+ mGradientBuiltinFunctions.insert("texture2DProj");
+ mGradientBuiltinFunctions.insert("textureCube");
+
+ // ESSL 300 builtin gradient functions
+ mGradientBuiltinFunctions.insert("texture");
+ mGradientBuiltinFunctions.insert("textureProj");
+ mGradientBuiltinFunctions.insert("textureOffset");
+ mGradientBuiltinFunctions.insert("textureProjOffset");
+
+ // ESSL 310 doesn't add builtin gradient functions
}
- void traverse(TIntermAggregate *node)
+ void traverse(TIntermFunctionDefinition *node)
{
node->traverse(this);
ASSERT(mParents.empty());
@@ -59,7 +76,7 @@ class PullGradient : public TIntermTraverser
ASSERT(mParents.back() == node);
mParents.pop_back();
// A control flow's using a gradient means its parents are too.
- if (mMetadata->mControlFlowsContainingGradient.count(node)> 0 && !mParents.empty())
+ if (mMetadata->mControlFlowsContainingGradient.count(node) > 0 && !mParents.empty())
{
mMetadata->mControlFlowsContainingGradient.insert(mParents.back());
}
@@ -72,9 +89,9 @@ class PullGradient : public TIntermTraverser
return true;
}
- bool visitSelection(Visit visit, TIntermSelection *selection) override
+ bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
{
- visitControlFlow(visit, selection);
+ visitControlFlow(visit, ifElse);
return true;
}
@@ -84,11 +101,12 @@ class PullGradient : public TIntermTraverser
{
switch (node->getOp())
{
- case EOpDFdx:
- case EOpDFdy:
- onGradient();
- default:
- break;
+ case EOpDFdx:
+ case EOpDFdy:
+ case EOpFwidth:
+ onGradient();
+ default:
+ break;
}
}
@@ -99,28 +117,22 @@ class PullGradient : public TIntermTraverser
{
if (visit == PreVisit)
{
- if (node->getOp() == EOpFunctionCall)
+ if (node->getOp() == EOpCallFunctionInAST)
{
- if (node->isUserDefined())
- {
- size_t calleeIndex = mDag.findIndex(node);
- ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
- UNUSED_ASSERTION_VARIABLE(mIndex);
+ size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
- if ((*mMetadataList)[calleeIndex].mUsesGradient) {
- onGradient();
- }
+ if ((*mMetadataList)[calleeIndex].mUsesGradient)
+ {
+ onGradient();
}
- else
+ }
+ else if (node->getOp() == EOpCallBuiltInFunction)
+ {
+ if (mGradientBuiltinFunctions.find(node->getFunctionSymbolInfo()->getName()) !=
+ mGradientBuiltinFunctions.end())
{
- TString name = TFunction::unmangleName(node->getName());
-
- if (name == "texture2D" ||
- name == "texture2DProj" ||
- name == "textureCube")
- {
- onGradient();
- }
+ onGradient();
}
}
}
@@ -136,7 +148,10 @@ class PullGradient : public TIntermTraverser
// Contains a stack of the control flow nodes that are parents of the node being
// currently visited. It is used to mark control flows using a gradient.
- std::vector<TIntermNode*> mParents;
+ std::vector<TIntermNode *> mParents;
+
+ // A list of builtin functions that use gradients
+ std::set<TString> mGradientBuiltinFunctions;
};
// Traverses the AST of a function definition to compute the the discontinuous loops
@@ -157,7 +172,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
{
}
- void traverse(TIntermAggregate *node)
+ void traverse(TIntermFunctionDefinition *node)
{
node->traverse(this);
ASSERT(mLoopsAndSwitches.empty());
@@ -196,7 +211,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
return true;
}
- bool visitSelection(Visit visit, TIntermSelection *node) override
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override
{
if (visit == PreVisit)
{
@@ -222,7 +237,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
{
switch (node->getFlowOp())
{
- case EOpBreak:
+ case EOpBreak:
{
ASSERT(!mLoopsAndSwitches.empty());
TIntermLoop *loop = mLoopsAndSwitches.back()->getAsLoopNode();
@@ -232,11 +247,11 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
}
}
break;
- case EOpContinue:
+ case EOpContinue:
{
ASSERT(!mLoopsAndSwitches.empty());
TIntermLoop *loop = nullptr;
- size_t i = mLoopsAndSwitches.size();
+ size_t i = mLoopsAndSwitches.size();
while (loop == nullptr && i > 0)
{
--i;
@@ -246,23 +261,23 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
mMetadata->mDiscontinuousLoops.insert(loop);
}
break;
- case EOpKill:
- case EOpReturn:
- // A return or discard jumps out of all the enclosing loops
- if (!mLoopsAndSwitches.empty())
- {
- for (TIntermNode *intermNode : mLoopsAndSwitches)
+ case EOpKill:
+ case EOpReturn:
+ // A return or discard jumps out of all the enclosing loops
+ if (!mLoopsAndSwitches.empty())
{
- TIntermLoop *loop = intermNode->getAsLoopNode();
- if (loop)
+ for (TIntermNode *intermNode : mLoopsAndSwitches)
{
- mMetadata->mDiscontinuousLoops.insert(loop);
+ TIntermLoop *loop = intermNode->getAsLoopNode();
+ if (loop)
+ {
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
}
}
- }
- break;
- default:
- UNREACHABLE();
+ break;
+ default:
+ UNREACHABLE();
}
}
@@ -271,18 +286,14 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
bool visitAggregate(Visit visit, TIntermAggregate *node) override
{
- if (visit == PreVisit && node->getOp() == EOpFunctionCall)
+ if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST)
{
- if (node->isUserDefined())
- {
- size_t calleeIndex = mDag.findIndex(node);
- ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
- UNUSED_ASSERTION_VARIABLE(mIndex);
+ size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
- if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
- {
- onGradientLoop();
- }
+ if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
+ {
+ onGradientLoop();
}
}
@@ -309,8 +320,8 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
size_t mIndex;
const CallDAG &mDag;
- std::vector<TIntermNode*> mLoopsAndSwitches;
- std::vector<TIntermSelection*> mIfs;
+ std::vector<TIntermNode *> mLoopsAndSwitches;
+ std::vector<TIntermIfElse *> mIfs;
};
// Tags all the functions called in a discontinuous loop
@@ -327,7 +338,7 @@ class PushDiscontinuousLoops : public TIntermTraverser
{
}
- void traverse(TIntermAggregate *node)
+ void traverse(TIntermFunctionDefinition *node)
{
node->traverse(this);
ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
@@ -353,18 +364,17 @@ class PushDiscontinuousLoops : public TIntermTraverser
{
switch (node->getOp())
{
- case EOpFunctionCall:
- if (visit == PreVisit && node->isUserDefined() && mNestedDiscont > 0)
- {
- size_t calleeIndex = mDag.findIndex(node);
- ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
- UNUSED_ASSERTION_VARIABLE(mIndex);
+ case EOpCallFunctionInAST:
+ if (visit == PreVisit && mNestedDiscont > 0)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
- (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
- }
- break;
- default:
- break;
+ (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
+ }
+ break;
+ default:
+ break;
}
return true;
}
@@ -377,7 +387,6 @@ class PushDiscontinuousLoops : public TIntermTraverser
int mNestedDiscont;
};
-
}
bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
@@ -385,7 +394,7 @@ bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
return mControlFlowsContainingGradient.count(node) > 0;
}
-bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node)
+bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
{
return mIfsContainingGradientLoop.count(node) > 0;
}
@@ -449,3 +458,5 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
return metadataList;
}
+
+} // namespace sh