diff options
Diffstat (limited to 'chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp')
-rw-r--r-- | chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp b/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp new file mode 100644 index 00000000000..5cb51645593 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ForLoopUnroll.cpp @@ -0,0 +1,82 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/ForLoopUnroll.h" + +bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node) +{ + if (mUnrollCondition != kSamplerArrayIndex) + return true; + + // If a sampler array index is also the loop index, + // 1) if the index type is integer, mark the loop for unrolling; + // 2) if the index type if float, set a flag to later fail compile. + switch (node->getOp()) + { + case EOpIndexIndirect: + if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode()) + { + TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode(); + if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty()) + { + mVisitSamplerArrayIndexNodeInsideLoop = true; + node->getRight()->traverse(this); + mVisitSamplerArrayIndexNodeInsideLoop = false; + // We have already visited all the children. + return false; + } + } + break; + default: + break; + } + return true; +} + +bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) +{ + if (mUnrollCondition == kIntegerIndex) + { + // Check if loop index type is integer. + // This is called after ValidateLimitations pass, so all the calls + // should be valid. See ValidateLimitations::validateForLoopInit(). + TIntermSequence& declSeq = node->getInit()->getAsAggregate()->getSequence(); + TIntermSymbol* symbol = declSeq[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); + if (symbol->getBasicType() == EbtInt) + node->setUnrollFlag(true); + } + + TIntermNode *body = node->getBody(); + if (body != NULL) + { + mLoopStack.push(node); + body->traverse(this); + mLoopStack.pop(); + } + // The loop is fully processed - no need to visit children. + return false; +} + +void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol) +{ + if (!mVisitSamplerArrayIndexNodeInsideLoop) + return; + TIntermLoop *loop = mLoopStack.findLoop(symbol); + if (loop) + { + switch (symbol->getBasicType()) + { + case EbtFloat: + mSamplerArrayIndexIsFloatLoopIndex = true; + break; + case EbtInt: + loop->setUnrollFlag(true); + break; + default: + UNREACHABLE(); + } + } +} |