• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 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 // NameEmbeddedUniformStructs: Gives nameless uniform struct internal names.
7 //
8 
9 #include "compiler/translator/tree_ops/NameEmbeddedUniformStructs.h"
10 
11 #include "compiler/translator/SymbolTable.h"
12 #include "compiler/translator/tree_util/IntermTraverse.h"
13 
14 namespace sh
15 {
16 namespace
17 {
18 // This traverser translates embedded uniform structs into a specifier and declaration.
19 // This makes the declarations easier to move into uniform blocks.
20 class Traverser : public TIntermTraverser
21 {
22   public:
Traverser(TSymbolTable * symbolTable)23     explicit Traverser(TSymbolTable *symbolTable)
24         : TIntermTraverser(true, false, false, symbolTable)
25     {}
26 
visitDeclaration(Visit visit,TIntermDeclaration * decl)27     bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
28     {
29         ASSERT(visit == PreVisit);
30 
31         if (!mInGlobalScope)
32         {
33             return false;
34         }
35 
36         const TIntermSequence &sequence = *(decl->getSequence());
37         ASSERT(sequence.size() == 1);
38         TIntermTyped *declarator = sequence.front()->getAsTyped();
39         const TType &type        = declarator->getType();
40 
41         if (type.isStructSpecifier() && type.getQualifier() == EvqUniform)
42         {
43             const TStructure *structure = type.getStruct();
44 
45             if (structure->symbolType() == SymbolType::Empty)
46             {
47                 doReplacement(decl, declarator, structure);
48             }
49         }
50 
51         return false;
52     }
53 
54   private:
doReplacement(TIntermDeclaration * decl,TIntermTyped * declarator,const TStructure * oldStructure)55     void doReplacement(TIntermDeclaration *decl,
56                        TIntermTyped *declarator,
57                        const TStructure *oldStructure)
58     {
59         // struct <structName> { ... };
60         TStructure *structure = new TStructure(mSymbolTable, kEmptyImmutableString,
61                                                &oldStructure->fields(), SymbolType::AngleInternal);
62         TType *namedType      = new TType(structure, true);
63         namedType->setQualifier(EvqGlobal);
64 
65         TVariable *structVariable =
66             new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
67         TIntermSymbol *structDeclarator       = new TIntermSymbol(structVariable);
68         TIntermDeclaration *structDeclaration = new TIntermDeclaration;
69         structDeclaration->appendDeclarator(structDeclarator);
70 
71         TIntermSequence *newSequence = new TIntermSequence;
72         newSequence->push_back(structDeclaration);
73 
74         // uniform <structName> <structUniformName>;
75         TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
76         if (asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty)
77         {
78             TIntermDeclaration *namedDecl = new TIntermDeclaration;
79             TType *uniformType            = new TType(structure, false);
80             uniformType->setQualifier(EvqUniform);
81 
82             TVariable *newVar        = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
83                                               asSymbol->variable().symbolType());
84             TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
85             namedDecl->appendDeclarator(newSymbol);
86 
87             newSequence->push_back(namedDecl);
88         }
89 
90         mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl, *newSequence);
91     }
92 };
93 }  // anonymous namespace
94 
NameEmbeddedStructUniforms(TCompiler * compiler,TIntermBlock * root,TSymbolTable * symbolTable)95 bool NameEmbeddedStructUniforms(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
96 {
97     Traverser nameStructs(symbolTable);
98     root->traverse(&nameStructs);
99     return nameStructs.updateTree(compiler, root);
100 }
101 }  // namespace sh
102