diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp | 155 |
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 |