diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp | 167 |
1 files changed, 0 insertions, 167 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp b/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp deleted file mode 100644 index 5233a29f19..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// -// Copyright (c) 2002-2015 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. -// -// During parsing, all constant expressions are folded to constant union nodes. The expressions that -// have been folded may have had precision qualifiers, which should affect the precision of the -// consuming operation. If the folded constant union nodes are written to output as such they won't -// have any precision qualifiers, and their effect on the precision of the consuming operation is -// lost. -// -// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants -// and hoists the constants outside the containing expression as precision qualified named variables -// in case that is required for correct precision propagation. -// - -#include "compiler/translator/RecordConstantPrecision.h" - -#include "compiler/translator/InfoSink.h" -#include "compiler/translator/IntermTraverse.h" - -namespace sh -{ - -namespace -{ - -class RecordConstantPrecisionTraverser : public TIntermTraverser -{ - public: - RecordConstantPrecisionTraverser(TSymbolTable *symbolTable); - - void visitConstantUnion(TIntermConstantUnion *node) override; - - void nextIteration(); - - bool foundHigherPrecisionConstant() const { return mFoundHigherPrecisionConstant; } - protected: - bool operandAffectsParentOperationPrecision(TIntermTyped *operand); - - bool mFoundHigherPrecisionConstant; -}; - -RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser(TSymbolTable *symbolTable) - : TIntermTraverser(true, false, true, symbolTable), mFoundHigherPrecisionConstant(false) -{ -} - -bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand) -{ - if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock()) - { - return false; - } - - const TIntermBinary *parentAsBinary = getParentNode()->getAsBinaryNode(); - if (parentAsBinary != nullptr) - { - // If the constant is assigned or is used to initialize a variable, or if it's an index, - // its precision has no effect. - switch (parentAsBinary->getOp()) - { - case EOpInitialize: - case EOpAssign: - case EOpIndexDirect: - case EOpIndexDirectStruct: - case EOpIndexDirectInterfaceBlock: - case EOpIndexIndirect: - return false; - default: - break; - } - - TIntermTyped *otherOperand = parentAsBinary->getRight(); - if (otherOperand == operand) - { - otherOperand = parentAsBinary->getLeft(); - } - // If the precision of the other child is at least as high as the precision of the constant, - // the precision of the constant has no effect. - if (otherOperand->getAsConstantUnion() == nullptr && - otherOperand->getPrecision() >= operand->getPrecision()) - { - return false; - } - } - - TIntermAggregate *parentAsAggregate = getParentNode()->getAsAggregate(); - if (parentAsAggregate != nullptr) - { - if (!parentAsAggregate->gotPrecisionFromChildren()) - { - // This can be either: - // * a call to an user-defined function - // * a call to a texture function - // * some other kind of aggregate - // In any of these cases the constant precision has no effect. - return false; - } - if (parentAsAggregate->isConstructor() && parentAsAggregate->getBasicType() == EbtBool) - { - return false; - } - // If the precision of operands does affect the result, but the precision of any of the - // other children has a precision that's at least as high as the precision of the constant, - // the precision of the constant has no effect. - TIntermSequence *parameters = parentAsAggregate->getSequence(); - for (TIntermNode *parameter : *parameters) - { - const TIntermTyped *typedParameter = parameter->getAsTyped(); - if (parameter != operand && typedParameter != nullptr && - parameter->getAsConstantUnion() == nullptr && - typedParameter->getPrecision() >= operand->getPrecision()) - { - return false; - } - } - } - return true; -} - -void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion *node) -{ - if (mFoundHigherPrecisionConstant) - return; - - // If the constant has lowp or undefined precision, it can't increase the precision of consuming - // operations. - if (node->getPrecision() < EbpMedium) - return; - - // It's possible the node has no effect on the precision of the consuming expression, depending - // on the consuming expression, and the precision of the other parameters of the expression. - if (!operandAffectsParentOperationPrecision(node)) - return; - - // Make the constant a precision-qualified named variable to make sure it affects the precision - // of the consuming expression. - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(node, EvqConst)); - insertStatementsInParentBlock(insertions); - queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); - mFoundHigherPrecisionConstant = true; -} - -void RecordConstantPrecisionTraverser::nextIteration() -{ - nextTemporaryId(); - mFoundHigherPrecisionConstant = false; -} - -} // namespace - -void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable) -{ - RecordConstantPrecisionTraverser traverser(symbolTable); - // Iterate as necessary, and reset the traverser between iterations. - do - { - traverser.nextIteration(); - root->traverse(&traverser); - if (traverser.foundHigherPrecisionConstant()) - traverser.updateTree(); - } while (traverser.foundHigherPrecisionConstant()); -} - -} // namespace sh |