• 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 // NameEmbeddedUniformStructsMetal: Gives nameless uniform struct internal names.
7 //
8 
9 #include "compiler/translator/tree_ops/msl/NameEmbeddedUniformStructsMetal.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 
23   public:
24     std::unordered_map<int, TIntermSymbol *> replacements;
Traverser(TSymbolTable * symbolTable)25     explicit Traverser(TSymbolTable *symbolTable)
26         : TIntermTraverser(true, false, false, symbolTable)
27     {}
28 
visitDeclaration(Visit visit,TIntermDeclaration * decl)29     bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
30     {
31         ASSERT(visit == PreVisit);
32 
33         if (!mInGlobalScope)
34         {
35             return false;
36         }
37 
38         const TIntermSequence &sequence = *(decl->getSequence());
39         ASSERT(sequence.size() == 1);
40         TIntermTyped *declarator = sequence.front()->getAsTyped();
41         const TType &type        = declarator->getType();
42 
43         if (type.isStructSpecifier() && type.getStruct()->symbolType() == SymbolType::Empty)
44         {
45             doReplacement(decl, declarator, type);
46         }
47 
48         return false;
49     }
visitSymbol(TIntermSymbol * decl)50     void visitSymbol(TIntermSymbol *decl) override
51     {
52         auto symbol = replacements.find(decl->uniqueId().get());
53         if (symbol != replacements.end())
54         {
55             queueReplacement(symbol->second->deepCopy(), OriginalNode::IS_DROPPED);
56         }
57     }
58 
59   private:
doReplacement(TIntermDeclaration * decl,TIntermTyped * declarator,const TType & oldType)60     void doReplacement(TIntermDeclaration *decl, TIntermTyped *declarator, const TType &oldType)
61     {
62         const TStructure *oldStructure = oldType.getStruct();
63         // struct <structName> { ... };
64         TStructure *structure = new TStructure(mSymbolTable, kEmptyImmutableString,
65                                                &oldStructure->fields(), SymbolType::AngleInternal);
66         TType *namedType      = new TType(structure, true);
67         namedType->setQualifier(EvqGlobal);
68 
69         TVariable *structVariable =
70             new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
71         TIntermSymbol *structDeclarator       = new TIntermSymbol(structVariable);
72         TIntermDeclaration *structDeclaration = new TIntermDeclaration;
73         structDeclaration->appendDeclarator(structDeclarator);
74 
75         TIntermSequence *newSequence = new TIntermSequence;
76         newSequence->push_back(structDeclaration);
77 
78         // uniform <structName> <structUniformName>;
79         TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
80         if (asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty)
81         {
82             TIntermDeclaration *namedDecl = new TIntermDeclaration;
83             TType *uniformType            = new TType(structure, false);
84             uniformType->setQualifier(EvqUniform);
85             uniformType->makeArrays(oldType.getArraySizes());
86 
87             TVariable *newVar        = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
88                                                      asSymbol->variable().symbolType());
89             TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
90             replacements[asSymbol->uniqueId().get()] = newSymbol;
91             namedDecl->appendDeclarator(newSymbol);
92 
93             newSequence->push_back(namedDecl);
94         }
95 
96         mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
97                                         std::move(*newSequence));
98     }
99 };
100 }  // anonymous namespace
101 
NameEmbeddedStructUniformsMetal(TCompiler * compiler,TIntermBlock * root,TSymbolTable * symbolTable)102 bool NameEmbeddedStructUniformsMetal(TCompiler *compiler,
103                                      TIntermBlock *root,
104                                      TSymbolTable *symbolTable)
105 {
106     Traverser nameStructs(symbolTable);
107     root->traverse(&nameStructs);
108     return nameStructs.updateTree(compiler, root);
109 }
110 }  // namespace sh
111