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