1 //
2 // Copyright 2013 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 // FlagStd140Structs.cpp: Find structs in std140 blocks, where the padding added in the translator
7 // conflicts with the "natural" unpadded type.
8
9 #include "compiler/translator/FlagStd140Structs.h"
10
11 #include "compiler/translator/SymbolTable.h"
12 #include "compiler/translator/tree_util/IntermTraverse.h"
13
14 namespace sh
15 {
16
17 namespace
18 {
19
20 class FlagStd140StructsTraverser : public TIntermTraverser
21 {
22 public:
FlagStd140StructsTraverser()23 FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {}
24
getMappedStructs() const25 const std::vector<MappedStruct> getMappedStructs() const { return mMappedStructs; }
26
27 protected:
28 bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
29
30 private:
31 void mapBlockStructMembers(TIntermSymbol *blockDeclarator, const TInterfaceBlock *block);
32
33 std::vector<MappedStruct> mMappedStructs;
34 };
35
mapBlockStructMembers(TIntermSymbol * blockDeclarator,const TInterfaceBlock * block)36 void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator,
37 const TInterfaceBlock *block)
38 {
39 for (auto *field : block->fields())
40 {
41 if (field->type()->getBasicType() == EbtStruct)
42 {
43 MappedStruct mappedStruct;
44 mappedStruct.blockDeclarator = blockDeclarator;
45 mappedStruct.field = field;
46 mMappedStructs.push_back(mappedStruct);
47 }
48 }
49 }
50
visitDeclaration(Visit visit,TIntermDeclaration * node)51 bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
52 {
53 TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
54 if (declarator->getBasicType() == EbtInterfaceBlock)
55 {
56 const TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
57 if (block->blockStorage() == EbsStd140)
58 {
59 mapBlockStructMembers(declarator->getAsSymbolNode(), block);
60 }
61 }
62 return false;
63 }
64
65 } // anonymous namespace
66
FlagStd140Structs(TIntermNode * node)67 std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node)
68 {
69 FlagStd140StructsTraverser flaggingTraversal;
70
71 node->traverse(&flaggingTraversal);
72
73 return flaggingTraversal.getMappedStructs();
74 }
75
76 } // namespace sh
77