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/SymbolTable.h"
12#include "compiler/translator/tree_util/IntermTraverse.h"
13
14namespace sh
15{
16
17namespace
18{
19
20class FlagStd140StructsTraverser : public TIntermTraverser
21{
22 public:
23 FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {}
24
25 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
36void 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
51bool 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
67std::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