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

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2016 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             : // Implementation of texelFetchOffset translation issue workaround.
       7             : // See header for more info.
       8             : 
       9             : #include "compiler/translator/RewriteTexelFetchOffset.h"
      10             : 
      11             : #include "common/angleutils.h"
      12             : #include "compiler/translator/IntermNode.h"
      13             : #include "compiler/translator/SymbolTable.h"
      14             : 
      15             : namespace sh
      16             : {
      17             : 
      18             : namespace
      19             : {
      20             : 
      21           0 : class Traverser : public TIntermTraverser
      22             : {
      23             :   public:
      24             :     static void Apply(TIntermNode *root,
      25             :                       const TSymbolTable &symbolTable,
      26             :                       int shaderVersion);
      27             : 
      28             :   private:
      29             :     Traverser(const TSymbolTable &symbolTable, int shaderVersion);
      30             :     bool visitAggregate(Visit visit, TIntermAggregate *node) override;
      31             :     void nextIteration();
      32             : 
      33             :     const TSymbolTable *symbolTable;
      34             :     const int shaderVersion;
      35             :     bool mFound = false;
      36             : };
      37             : 
      38           0 : Traverser::Traverser(const TSymbolTable &symbolTable, int shaderVersion)
      39           0 :     : TIntermTraverser(true, false, false), symbolTable(&symbolTable), shaderVersion(shaderVersion)
      40             : {
      41           0 : }
      42             : 
      43             : // static
      44           0 : void Traverser::Apply(TIntermNode *root,
      45             :                       const TSymbolTable &symbolTable,
      46             :                       int shaderVersion)
      47             : {
      48           0 :     Traverser traverser(symbolTable, shaderVersion);
      49           0 :     do
      50             :     {
      51           0 :         traverser.nextIteration();
      52           0 :         root->traverse(&traverser);
      53           0 :         if (traverser.mFound)
      54             :         {
      55           0 :             traverser.updateTree();
      56             :         }
      57           0 :     } while (traverser.mFound);
      58           0 : }
      59             : 
      60           0 : void Traverser::nextIteration()
      61             : {
      62           0 :     mFound = false;
      63           0 : }
      64             : 
      65           0 : bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
      66             : {
      67           0 :     if (mFound)
      68             :     {
      69           0 :         return false;
      70             :     }
      71             : 
      72             :     // Decide if the node represents the call of texelFetchOffset.
      73           0 :     if (node->getOp() != EOpFunctionCall || node->isUserDefined())
      74             :     {
      75           0 :         return true;
      76             :     }
      77             : 
      78           0 :     if (node->getFunctionSymbolInfo()->getName().compare(0, 16, "texelFetchOffset") != 0)
      79             :     {
      80           0 :         return true;
      81             :     }
      82             : 
      83             :     // Potential problem case detected, apply workaround.
      84           0 :     const TIntermSequence *sequence = node->getSequence();
      85           0 :     ASSERT(sequence->size() == 4u);
      86             : 
      87             :     // Decide if there is a 2DArray sampler.
      88           0 :     bool is2DArray = node->getFunctionSymbolInfo()->getName().find("s2a1") != TString::npos;
      89             : 
      90             :     // Create new argument list from node->getName().
      91             :     // e.g. Get "(is2a1;vi3;i1;" from "texelFetchOffset(is2a1;vi3;i1;vi2;"
      92           0 :     TString newArgs = node->getFunctionSymbolInfo()->getName().substr(
      93           0 :         16, node->getFunctionSymbolInfo()->getName().length() - 20);
      94           0 :     TString newName           = "texelFetch" + newArgs;
      95           0 :     TSymbol *texelFetchSymbol = symbolTable->findBuiltIn(newName, shaderVersion);
      96           0 :     ASSERT(texelFetchSymbol);
      97           0 :     int uniqueId = texelFetchSymbol->getUniqueId();
      98             : 
      99             :     // Create new node that represents the call of function texelFetch.
     100             :     // Its argument list will be: texelFetch(sampler, Position+offset, lod).
     101           0 :     TIntermAggregate *texelFetchNode = new TIntermAggregate(EOpFunctionCall);
     102           0 :     texelFetchNode->getFunctionSymbolInfo()->setName(newName);
     103           0 :     texelFetchNode->getFunctionSymbolInfo()->setId(uniqueId);
     104           0 :     texelFetchNode->setType(node->getType());
     105           0 :     texelFetchNode->setLine(node->getLine());
     106             : 
     107             :     // sampler
     108           0 :     texelFetchNode->getSequence()->push_back(sequence->at(0));
     109             : 
     110             :     // Position
     111           0 :     TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
     112           0 :     ASSERT(texCoordNode);
     113             : 
     114             :     // offset
     115           0 :     TIntermTyped *offsetNode = nullptr;
     116           0 :     ASSERT(sequence->at(3)->getAsTyped());
     117           0 :     if (is2DArray)
     118             :     {
     119             :         // For 2DArray samplers, Position is ivec3 and offset is ivec2;
     120             :         // So offset must be converted into an ivec3 before being added to Position.
     121           0 :         TIntermAggregate *constructIVec3Node = new TIntermAggregate(EOpConstructIVec3);
     122           0 :         constructIVec3Node->setLine(texCoordNode->getLine());
     123           0 :         constructIVec3Node->setType(texCoordNode->getType());
     124             : 
     125           0 :         constructIVec3Node->getSequence()->push_back(sequence->at(3)->getAsTyped());
     126             : 
     127           0 :         TConstantUnion *zero = new TConstantUnion();
     128           0 :         zero->setIConst(0);
     129           0 :         TType *intType = new TType(EbtInt);
     130             : 
     131           0 :         TIntermConstantUnion *zeroNode = new TIntermConstantUnion(zero, *intType);
     132           0 :         constructIVec3Node->getSequence()->push_back(zeroNode);
     133             : 
     134           0 :         offsetNode = constructIVec3Node;
     135             :     }
     136             :     else
     137             :     {
     138           0 :         offsetNode = sequence->at(3)->getAsTyped();
     139             :     }
     140             : 
     141             :     // Position+offset
     142           0 :     TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
     143           0 :     add->setLine(texCoordNode->getLine());
     144           0 :     texelFetchNode->getSequence()->push_back(add);
     145             : 
     146             :     // lod
     147           0 :     texelFetchNode->getSequence()->push_back(sequence->at(2));
     148             : 
     149           0 :     ASSERT(texelFetchNode->getSequence()->size() == 3u);
     150             : 
     151             :     // Replace the old node by this new node.
     152           0 :     queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED);
     153           0 :     mFound = true;
     154           0 :     return false;
     155             : }
     156             : 
     157             : }  // anonymous namespace
     158             : 
     159           0 : void RewriteTexelFetchOffset(TIntermNode *root,
     160             :                              const TSymbolTable &symbolTable,
     161             :                              int shaderVersion)
     162             : {
     163             :     // texelFetchOffset is only valid in GLSL 3.0 and later.
     164           0 :     if (shaderVersion < 300)
     165           0 :         return;
     166             : 
     167           0 :     Traverser::Apply(root, symbolTable, shaderVersion);
     168             : }
     169             : 
     170             : }  // namespace sh

Generated by: LCOV version 1.13