1// 2// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5// 6 7#include "compiler/translator/ForLoopUnroll.h" 8 9bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node) 10{ 11 if (mUnrollCondition != kSamplerArrayIndex) 12 return true; 13 14 // If a sampler array index is also the loop index, 15 // 1) if the index type is integer, mark the loop for unrolling; 16 // 2) if the index type if float, set a flag to later fail compile. 17 switch (node->getOp()) 18 { 19 case EOpIndexIndirect: 20 if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode()) 21 { 22 TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode(); 23 if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty()) 24 { 25 mVisitSamplerArrayIndexNodeInsideLoop = true; 26 node->getRight()->traverse(this); 27 mVisitSamplerArrayIndexNodeInsideLoop = false; 28 // We have already visited all the children. 29 return false; 30 } 31 } 32 break; 33 default: 34 break; 35 } 36 return true; 37} 38 39bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) 40{ 41 if (mUnrollCondition == kIntegerIndex) 42 { 43 // Check if loop index type is integer. 44 // This is called after ValidateLimitations pass, so all the calls 45 // should be valid. See ValidateLimitations::validateForLoopInit(). 46 TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence(); 47 TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); 48 if (symbol->getBasicType() == EbtInt) 49 node->setUnrollFlag(true); 50 } 51 52 TIntermNode *body = node->getBody(); 53 if (body != NULL) 54 { 55 mLoopStack.push(node); 56 body->traverse(this); 57 mLoopStack.pop(); 58 } 59 // The loop is fully processed - no need to visit children. 60 return false; 61} 62 63void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol) 64{ 65 if (!mVisitSamplerArrayIndexNodeInsideLoop) 66 return; 67 TIntermLoop *loop = mLoopStack.findLoop(symbol); 68 if (loop) 69 { 70 switch (symbol->getBasicType()) 71 { 72 case EbtFloat: 73 mSamplerArrayIndexIsFloatLoopIndex = true; 74 break; 75 case EbtInt: 76 loop->setUnrollFlag(true); 77 break; 78 default: 79 UNREACHABLE(); 80 } 81 } 82} 83