LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - RemovePow.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 35 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2002-2015 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             : // RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a
       7             : // constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series
       8             : // OpenGL drivers.
       9             : //
      10             : 
      11             : #include "compiler/translator/RemovePow.h"
      12             : 
      13             : #include "compiler/translator/InfoSink.h"
      14             : #include "compiler/translator/IntermNode.h"
      15             : 
      16             : namespace sh
      17             : {
      18             : 
      19             : namespace
      20             : {
      21             : 
      22           0 : bool IsProblematicPow(TIntermTyped *node)
      23             : {
      24           0 :     TIntermAggregate *agg = node->getAsAggregate();
      25           0 :     if (agg != nullptr && agg->getOp() == EOpPow)
      26             :     {
      27           0 :         ASSERT(agg->getSequence()->size() == 2);
      28           0 :         return agg->getSequence()->at(1)->getAsConstantUnion() != nullptr;
      29             :     }
      30           0 :     return false;
      31             : }
      32             : 
      33             : // Traverser that converts all pow operations simultaneously.
      34           0 : class RemovePowTraverser : public TIntermTraverser
      35             : {
      36             :   public:
      37             :     RemovePowTraverser();
      38             : 
      39             :     bool visitAggregate(Visit visit, TIntermAggregate *node) override;
      40             : 
      41           0 :     void nextIteration() { mNeedAnotherIteration = false; }
      42           0 :     bool needAnotherIteration() const { return mNeedAnotherIteration; }
      43             : 
      44             :   protected:
      45             :     bool mNeedAnotherIteration;
      46             : };
      47             : 
      48           0 : RemovePowTraverser::RemovePowTraverser()
      49             :     : TIntermTraverser(true, false, false),
      50           0 :       mNeedAnotherIteration(false)
      51             : {
      52           0 : }
      53             : 
      54           0 : bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
      55             : {
      56           0 :     if (IsProblematicPow(node))
      57             :     {
      58           0 :         TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
      59           0 :         TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
      60             : 
      61           0 :         TIntermUnary *log = new TIntermUnary(EOpLog2, x);
      62           0 :         log->setLine(node->getLine());
      63             : 
      64           0 :         TOperator op       = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
      65           0 :         TIntermBinary *mul = new TIntermBinary(op, y, log);
      66           0 :         mul->setLine(node->getLine());
      67             : 
      68           0 :         TIntermUnary *exp = new TIntermUnary(EOpExp2, mul);
      69           0 :         exp->setLine(node->getLine());
      70             : 
      71           0 :         queueReplacement(node, exp, OriginalNode::IS_DROPPED);
      72             : 
      73             :         // If the x parameter also needs to be replaced, we need to do that in another traversal,
      74             :         // since it's parent node will change in a way that's not handled correctly by updateTree().
      75           0 :         if (IsProblematicPow(x))
      76             :         {
      77           0 :             mNeedAnotherIteration = true;
      78           0 :             return false;
      79             :         }
      80             :     }
      81           0 :     return true;
      82             : }
      83             : 
      84             : } // namespace
      85             : 
      86           0 : void RemovePow(TIntermNode *root)
      87             : {
      88           0 :     RemovePowTraverser traverser;
      89             :     // Iterate as necessary, and reset the traverser between iterations.
      90           0 :     do
      91             :     {
      92           0 :         traverser.nextIteration();
      93           0 :         root->traverse(&traverser);
      94           0 :         traverser.updateTree();
      95             :     }
      96             :     while (traverser.needAnotherIteration());
      97           0 : }
      98             : 
      99             : }  // namespace sh

Generated by: LCOV version 1.13