diff options
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp index 886f693..767d0bf 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp @@ -17,6 +17,17 @@ bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) { return false; } +void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) { + for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) { + if (i->index.id == symbol->getId()) { + ASSERT(i->loop != NULL); + i->loop->setUnrollFlag(true); + return; + } + } + UNREACHABLE(); +} + // Traverses a node to check if it represents a constant index expression. // Definition: // constant-index-expressions are a superset of constant-expressions. @@ -42,18 +53,46 @@ public: IsLoopIndex(symbol, mLoopStack); } } - virtual void visitConstantUnion(TIntermConstantUnion*) {} - virtual bool visitBinary(Visit, TIntermBinary*) { return true; } - virtual bool visitUnary(Visit, TIntermUnary*) { return true; } - virtual bool visitSelection(Visit, TIntermSelection*) { return true; } - virtual bool visitAggregate(Visit, TIntermAggregate*) { return true; } - virtual bool visitLoop(Visit, TIntermLoop*) { return true; } - virtual bool visitBranch(Visit, TIntermBranch*) { return true; } private: bool mValid; const TLoopStack& mLoopStack; }; + +// Traverses a node to check if it uses a loop index. +// If an int loop index is used in its body as a sampler array index, +// mark the loop for unroll. +class ValidateLoopIndexExpr : public TIntermTraverser { +public: + ValidateLoopIndexExpr(TLoopStack& stack) + : mUsesFloatLoopIndex(false), + mUsesIntLoopIndex(false), + mLoopStack(stack) {} + + bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; } + bool usesIntLoopIndex() const { return mUsesIntLoopIndex; } + + virtual void visitSymbol(TIntermSymbol* symbol) { + if (IsLoopIndex(symbol, mLoopStack)) { + switch (symbol->getBasicType()) { + case EbtFloat: + mUsesFloatLoopIndex = true; + break; + case EbtInt: + mUsesIntLoopIndex = true; + MarkLoopForUnroll(symbol, mLoopStack); + break; + default: + UNREACHABLE(); + } + } + } + +private: + bool mUsesFloatLoopIndex; + bool mUsesIntLoopIndex; + TLoopStack& mLoopStack; +}; } // namespace ValidateLimitations::ValidateLimitations(ShShaderType shaderType, @@ -64,14 +103,6 @@ ValidateLimitations::ValidateLimitations(ShShaderType shaderType, { } -void ValidateLimitations::visitSymbol(TIntermSymbol*) -{ -} - -void ValidateLimitations::visitConstantUnion(TIntermConstantUnion*) -{ -} - bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node) { // Check if loop index is modified in the loop body. @@ -80,7 +111,28 @@ bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node) // Check indexing. switch (node->getOp()) { case EOpIndexDirect: + validateIndexing(node); + break; case EOpIndexIndirect: +#if defined(__APPLE__) + // Loop unrolling is a work-around for a Mac Cg compiler bug where it + // crashes when a sampler array's index is also the loop index. + // Once Apple fixes this bug, we should remove the code in this CL. + // See http://codereview.appspot.com/4331048/. + if ((node->getLeft() != NULL) && (node->getRight() != NULL) && + (node->getLeft()->getAsSymbolNode())) { + TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode(); + if (IsSampler(symbol->getBasicType()) && symbol->isArray()) { + ValidateLoopIndexExpr validate(mLoopStack); + node->getRight()->traverse(&validate); + if (validate.usesFloatLoopIndex()) { + error(node->getLine(), + "sampler array index is float loop index", + "for"); + } + } + } +#endif validateIndexing(node); break; default: break; @@ -96,11 +148,6 @@ bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node) return true; } -bool ValidateLimitations::visitSelection(Visit, TIntermSelection*) -{ - return true; -} - bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node) { switch (node->getOp()) { @@ -120,6 +167,7 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node) TLoopInfo info; memset(&info, 0, sizeof(TLoopInfo)); + info.loop = node; if (!validateForLoopHeader(node, &info)) return false; @@ -134,11 +182,6 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node) return false; } -bool ValidateLimitations::visitBranch(Visit, TIntermBranch*) -{ - return true; -} - void ValidateLimitations::error(TSourceLoc loc, const char *reason, const char* token) { |