LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - UseInterfaceBlockFields.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 65 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 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             : 
       7             : // UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
       8             : // the beginning of main. This is to work around a Mac driver that treats unused standard/shared
       9             : // uniform blocks as inactive.
      10             : 
      11             : #include "compiler/translator/UseInterfaceBlockFields.h"
      12             : 
      13             : #include "compiler/translator/IntermNode.h"
      14             : #include "compiler/translator/SymbolTable.h"
      15             : #include "compiler/translator/util.h"
      16             : 
      17             : namespace sh
      18             : {
      19             : 
      20             : namespace
      21             : {
      22             : 
      23           0 : class UseUniformBlockMembers : public TIntermTraverser
      24             : {
      25             :   public:
      26           0 :     UseUniformBlockMembers(const InterfaceBlockList &blocks, const TSymbolTable &symbolTable)
      27           0 :         : TIntermTraverser(true, false, false),
      28             :           mBlocks(blocks),
      29             :           mSymbolTable(symbolTable),
      30           0 :           mCodeInserted(false)
      31             :     {
      32           0 :         ASSERT(mSymbolTable.atGlobalLevel());
      33           0 :     }
      34             : 
      35             :   protected:
      36           0 :     bool visitAggregate(Visit visit, TIntermAggregate *node) override { return !mCodeInserted; }
      37             :     bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
      38             : 
      39             :   private:
      40             :     void insertUseCode(TIntermSequence *sequence);
      41             :     void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence);
      42             : 
      43             :     const InterfaceBlockList &mBlocks;
      44             :     const TSymbolTable &mSymbolTable;
      45             :     bool mCodeInserted;
      46             : };
      47             : 
      48           0 : bool UseUniformBlockMembers::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
      49             : {
      50           0 :     ASSERT(visit == PreVisit);
      51           0 :     if (node->getFunctionSymbolInfo()->isMain())
      52             :     {
      53           0 :         TIntermBlock *body = node->getBody();
      54           0 :         ASSERT(body);
      55           0 :         insertUseCode(body->getSequence());
      56           0 :         mCodeInserted = true;
      57           0 :         return false;
      58             :     }
      59           0 :     return !mCodeInserted;
      60             : }
      61             : 
      62           0 : void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
      63             :                                                    TIntermSequence *sequence)
      64             : {
      65           0 :     TString name = TString(var.name.c_str());
      66           0 :     if (var.isArray())
      67             :     {
      68           0 :         size_t pos = name.find_last_of('[');
      69           0 :         if (pos != TString::npos)
      70             :         {
      71           0 :             name = name.substr(0, pos);
      72             :         }
      73             :     }
      74             :     const TType *type;
      75           0 :     TType basicType;
      76           0 :     if (var.isStruct())
      77             :     {
      78           0 :         TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
      79           0 :         ASSERT(structInfo);
      80           0 :         const TType &structType = structInfo->getType();
      81           0 :         type                    = &structType;
      82             :     }
      83             :     else
      84             :     {
      85           0 :         basicType = sh::GetShaderVariableBasicType(var);
      86           0 :         type      = &basicType;
      87             :     }
      88           0 :     ASSERT(type);
      89             : 
      90           0 :     TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
      91           0 :     if (var.isArray())
      92             :     {
      93           0 :         for (unsigned int i = 0; i < var.arraySize; ++i)
      94             :         {
      95             :             TIntermBinary *element =
      96           0 :                 new TIntermBinary(EOpIndexDirect, symbol, TIntermTyped::CreateIndexNode(i));
      97           0 :             sequence->insert(sequence->begin(), element);
      98             :         }
      99             :     }
     100             :     else
     101             :     {
     102           0 :         sequence->insert(sequence->begin(), symbol);
     103             :     }
     104           0 : }
     105             : 
     106           0 : void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
     107             : {
     108           0 :     for (const auto &block : mBlocks)
     109             :     {
     110           0 :         if (block.instanceName.empty())
     111             :         {
     112           0 :             for (const auto &var : block.fields)
     113             :             {
     114           0 :                 AddFieldUseStatements(var, sequence);
     115             :             }
     116             :         }
     117           0 :         else if (block.arraySize > 0)
     118             :         {
     119           0 :             TString name      = TString(block.instanceName.c_str());
     120           0 :             TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
     121           0 :             ASSERT(ubInfo);
     122           0 :             TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
     123           0 :             for (unsigned int i = 0; i < block.arraySize; ++i)
     124             :             {
     125             :                 TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
     126           0 :                                                                   TIntermTyped::CreateIndexNode(i));
     127           0 :                 for (unsigned int j = 0; j < block.fields.size(); ++j)
     128             :                 {
     129             :                     TIntermBinary *element =
     130             :                         new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol,
     131           0 :                                           TIntermTyped::CreateIndexNode(j));
     132           0 :                     sequence->insert(sequence->begin(), element);
     133             :                 }
     134             :             }
     135             :         }
     136             :         else
     137             :         {
     138           0 :             TString name      = TString(block.instanceName.c_str());
     139           0 :             TVariable *ubInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
     140           0 :             ASSERT(ubInfo);
     141           0 :             TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
     142           0 :             for (unsigned int i = 0; i < block.fields.size(); ++i)
     143             :             {
     144             :                 TIntermBinary *element = new TIntermBinary(
     145           0 :                     EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i));
     146             : 
     147           0 :                 sequence->insert(sequence->begin(), element);
     148             :             }
     149             :         }
     150             :     }
     151           0 : }
     152             : 
     153             : }  // namespace anonymous
     154             : 
     155           0 : void UseInterfaceBlockFields(TIntermNode *root,
     156             :                              const InterfaceBlockList &blocks,
     157             :                              const TSymbolTable &symbolTable)
     158             : {
     159           0 :     UseUniformBlockMembers useUniformBlock(blocks, symbolTable);
     160           0 :     root->traverse(&useUniformBlock);
     161           0 : }
     162             : 
     163             : }  // namespace sh

Generated by: LCOV version 1.13