xref: /aosp_15_r20/external/angle/src/compiler/translator/blocklayout.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // blocklayout.h:
7*8975f5c5SAndroid Build Coastguard Worker //   Methods and classes related to uniform layout and packing in GLSL and HLSL.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #ifndef COMMON_BLOCKLAYOUT_H_
11*8975f5c5SAndroid Build Coastguard Worker #define COMMON_BLOCKLAYOUT_H_
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include <cstddef>
14*8975f5c5SAndroid Build Coastguard Worker #include <map>
15*8975f5c5SAndroid Build Coastguard Worker #include <vector>
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker #include <GLSLANG/ShaderLang.h>
18*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker namespace sh
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker struct ShaderVariable;
23*8975f5c5SAndroid Build Coastguard Worker struct InterfaceBlock;
24*8975f5c5SAndroid Build Coastguard Worker 
25*8975f5c5SAndroid Build Coastguard Worker struct BlockMemberInfo
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker     constexpr BlockMemberInfo() = default;
28*8975f5c5SAndroid Build Coastguard Worker     // This constructor is used by the HLSL backend
BlockMemberInfoBlockMemberInfo29*8975f5c5SAndroid Build Coastguard Worker     constexpr BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
30*8975f5c5SAndroid Build Coastguard Worker         : type(GL_INVALID_ENUM),
31*8975f5c5SAndroid Build Coastguard Worker           isRowMajorMatrix(isRowMajorMatrix),
32*8975f5c5SAndroid Build Coastguard Worker           offset(offset),
33*8975f5c5SAndroid Build Coastguard Worker           arrayStride(arrayStride),
34*8975f5c5SAndroid Build Coastguard Worker           matrixStride(matrixStride),
35*8975f5c5SAndroid Build Coastguard Worker           arraySize(-1)
36*8975f5c5SAndroid Build Coastguard Worker     {}
37*8975f5c5SAndroid Build Coastguard Worker 
BlockMemberInfoBlockMemberInfo38*8975f5c5SAndroid Build Coastguard Worker     constexpr BlockMemberInfo(int offset,
39*8975f5c5SAndroid Build Coastguard Worker                               int arrayStride,
40*8975f5c5SAndroid Build Coastguard Worker                               int matrixStride,
41*8975f5c5SAndroid Build Coastguard Worker                               bool isRowMajorMatrix,
42*8975f5c5SAndroid Build Coastguard Worker                               int topLevelArrayStride)
43*8975f5c5SAndroid Build Coastguard Worker         : type(GL_INVALID_ENUM),
44*8975f5c5SAndroid Build Coastguard Worker           isRowMajorMatrix(isRowMajorMatrix),
45*8975f5c5SAndroid Build Coastguard Worker           offset(offset),
46*8975f5c5SAndroid Build Coastguard Worker           arrayStride(arrayStride),
47*8975f5c5SAndroid Build Coastguard Worker           matrixStride(matrixStride),
48*8975f5c5SAndroid Build Coastguard Worker           arraySize(-1),
49*8975f5c5SAndroid Build Coastguard Worker           topLevelArrayStride(topLevelArrayStride)
50*8975f5c5SAndroid Build Coastguard Worker     {}
51*8975f5c5SAndroid Build Coastguard Worker 
BlockMemberInfoBlockMemberInfo52*8975f5c5SAndroid Build Coastguard Worker     constexpr BlockMemberInfo(GLenum type,
53*8975f5c5SAndroid Build Coastguard Worker                               int offset,
54*8975f5c5SAndroid Build Coastguard Worker                               int arrayStride,
55*8975f5c5SAndroid Build Coastguard Worker                               int matrixStride,
56*8975f5c5SAndroid Build Coastguard Worker                               int arraySize,
57*8975f5c5SAndroid Build Coastguard Worker                               bool isRowMajorMatrix)
58*8975f5c5SAndroid Build Coastguard Worker         : type(static_cast<uint16_t>(type)),
59*8975f5c5SAndroid Build Coastguard Worker           isRowMajorMatrix(isRowMajorMatrix),
60*8975f5c5SAndroid Build Coastguard Worker           offset(offset),
61*8975f5c5SAndroid Build Coastguard Worker           arrayStride(arrayStride),
62*8975f5c5SAndroid Build Coastguard Worker           matrixStride(matrixStride),
63*8975f5c5SAndroid Build Coastguard Worker           arraySize(arraySize)
64*8975f5c5SAndroid Build Coastguard Worker     {}
65*8975f5c5SAndroid Build Coastguard Worker 
BlockMemberInfoBlockMemberInfo66*8975f5c5SAndroid Build Coastguard Worker     constexpr BlockMemberInfo(GLenum type,
67*8975f5c5SAndroid Build Coastguard Worker                               int offset,
68*8975f5c5SAndroid Build Coastguard Worker                               int arrayStride,
69*8975f5c5SAndroid Build Coastguard Worker                               int matrixStride,
70*8975f5c5SAndroid Build Coastguard Worker                               int arraySize,
71*8975f5c5SAndroid Build Coastguard Worker                               bool isRowMajorMatrix,
72*8975f5c5SAndroid Build Coastguard Worker                               int topLevelArrayStride)
73*8975f5c5SAndroid Build Coastguard Worker         : type(static_cast<uint16_t>(type)),
74*8975f5c5SAndroid Build Coastguard Worker           isRowMajorMatrix(isRowMajorMatrix),
75*8975f5c5SAndroid Build Coastguard Worker           offset(offset),
76*8975f5c5SAndroid Build Coastguard Worker           arrayStride(arrayStride),
77*8975f5c5SAndroid Build Coastguard Worker           matrixStride(matrixStride),
78*8975f5c5SAndroid Build Coastguard Worker           arraySize(arraySize),
79*8975f5c5SAndroid Build Coastguard Worker           topLevelArrayStride(topLevelArrayStride)
80*8975f5c5SAndroid Build Coastguard Worker     {}
81*8975f5c5SAndroid Build Coastguard Worker 
82*8975f5c5SAndroid Build Coastguard Worker     uint16_t type = GL_INVALID_ENUM;
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker     // A single integer identifying whether an active variable is a row-major matrix.
85*8975f5c5SAndroid Build Coastguard Worker     uint8_t isRowMajorMatrix = false;
86*8975f5c5SAndroid Build Coastguard Worker     uint8_t pad              = 0;
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     // A single integer identifying the offset of an active variable.
89*8975f5c5SAndroid Build Coastguard Worker     int32_t offset = -1;
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker     // A single integer identifying the stride between array elements in an active variable.
92*8975f5c5SAndroid Build Coastguard Worker     int32_t arrayStride = -1;
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker     // A single integer identifying the stride between columns of a column-major matrix or rows of a
95*8975f5c5SAndroid Build Coastguard Worker     // row-major matrix.
96*8975f5c5SAndroid Build Coastguard Worker     int32_t matrixStride = -1;
97*8975f5c5SAndroid Build Coastguard Worker 
98*8975f5c5SAndroid Build Coastguard Worker     // A single integer, identifying the length of an array variable.
99*8975f5c5SAndroid Build Coastguard Worker     int32_t arraySize = -1;
100*8975f5c5SAndroid Build Coastguard Worker 
101*8975f5c5SAndroid Build Coastguard Worker     // A single integer identifying the number of active array elements of the top-level shader
102*8975f5c5SAndroid Build Coastguard Worker     // storage block member containing the active variable.
103*8975f5c5SAndroid Build Coastguard Worker     int32_t topLevelArrayStride = -1;
104*8975f5c5SAndroid Build Coastguard Worker };
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker bool operator==(const BlockMemberInfo &lhs, const BlockMemberInfo &rhs);
107*8975f5c5SAndroid Build Coastguard Worker 
ComponentAlignment(size_t numComponents)108*8975f5c5SAndroid Build Coastguard Worker constexpr size_t ComponentAlignment(size_t numComponents)
109*8975f5c5SAndroid Build Coastguard Worker {
110*8975f5c5SAndroid Build Coastguard Worker     return (numComponents == 3u ? 4u : numComponents);
111*8975f5c5SAndroid Build Coastguard Worker }
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker constexpr BlockMemberInfo kDefaultBlockMemberInfo;
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker class BlockLayoutEncoder
116*8975f5c5SAndroid Build Coastguard Worker {
117*8975f5c5SAndroid Build Coastguard Worker   public:
118*8975f5c5SAndroid Build Coastguard Worker     BlockLayoutEncoder();
~BlockLayoutEncoder()119*8975f5c5SAndroid Build Coastguard Worker     virtual ~BlockLayoutEncoder() {}
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker     virtual BlockMemberInfo encodeType(GLenum type,
122*8975f5c5SAndroid Build Coastguard Worker                                        const std::vector<unsigned int> &arraySizes,
123*8975f5c5SAndroid Build Coastguard Worker                                        bool isRowMajorMatrix);
124*8975f5c5SAndroid Build Coastguard Worker     // Advance the offset based on struct size and array dimensions.  Size can be calculated with
125*8975f5c5SAndroid Build Coastguard Worker     // getShaderVariableSize() or equivalent.  |enterAggregateType|/|exitAggregateType| is necessary
126*8975f5c5SAndroid Build Coastguard Worker     // around this call.
127*8975f5c5SAndroid Build Coastguard Worker     virtual BlockMemberInfo encodeArrayOfPreEncodedStructs(
128*8975f5c5SAndroid Build Coastguard Worker         size_t size,
129*8975f5c5SAndroid Build Coastguard Worker         const std::vector<unsigned int> &arraySizes);
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker     virtual size_t getCurrentOffset() const;
132*8975f5c5SAndroid Build Coastguard Worker     virtual size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
133*8975f5c5SAndroid Build Coastguard Worker 
134*8975f5c5SAndroid Build Coastguard Worker     // Called when entering/exiting a structure variable.
135*8975f5c5SAndroid Build Coastguard Worker     virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
136*8975f5c5SAndroid Build Coastguard Worker     virtual void exitAggregateType(const ShaderVariable &structVar)  = 0;
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     static constexpr size_t kBytesPerComponent           = 4u;
139*8975f5c5SAndroid Build Coastguard Worker     static constexpr unsigned int kComponentsPerRegister = 4u;
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker     static size_t GetBlockRegister(const BlockMemberInfo &info);
142*8975f5c5SAndroid Build Coastguard Worker     static size_t GetBlockRegisterElement(const BlockMemberInfo &info);
143*8975f5c5SAndroid Build Coastguard Worker 
144*8975f5c5SAndroid Build Coastguard Worker   protected:
145*8975f5c5SAndroid Build Coastguard Worker     void align(size_t baseAlignment);
146*8975f5c5SAndroid Build Coastguard Worker 
147*8975f5c5SAndroid Build Coastguard Worker     virtual void getBlockLayoutInfo(GLenum type,
148*8975f5c5SAndroid Build Coastguard Worker                                     const std::vector<unsigned int> &arraySizes,
149*8975f5c5SAndroid Build Coastguard Worker                                     bool isRowMajorMatrix,
150*8975f5c5SAndroid Build Coastguard Worker                                     int *arrayStrideOut,
151*8975f5c5SAndroid Build Coastguard Worker                                     int *matrixStrideOut) = 0;
152*8975f5c5SAndroid Build Coastguard Worker     virtual void advanceOffset(GLenum type,
153*8975f5c5SAndroid Build Coastguard Worker                                const std::vector<unsigned int> &arraySizes,
154*8975f5c5SAndroid Build Coastguard Worker                                bool isRowMajorMatrix,
155*8975f5c5SAndroid Build Coastguard Worker                                int arrayStride,
156*8975f5c5SAndroid Build Coastguard Worker                                int matrixStride)          = 0;
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker     size_t mCurrentOffset;
159*8975f5c5SAndroid Build Coastguard Worker };
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker // Will return default values for everything.
162*8975f5c5SAndroid Build Coastguard Worker class StubBlockEncoder : public BlockLayoutEncoder
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker   public:
165*8975f5c5SAndroid Build Coastguard Worker     StubBlockEncoder() = default;
166*8975f5c5SAndroid Build Coastguard Worker 
enterAggregateType(const ShaderVariable & structVar)167*8975f5c5SAndroid Build Coastguard Worker     void enterAggregateType(const ShaderVariable &structVar) override {}
exitAggregateType(const ShaderVariable & structVar)168*8975f5c5SAndroid Build Coastguard Worker     void exitAggregateType(const ShaderVariable &structVar) override {}
169*8975f5c5SAndroid Build Coastguard Worker 
170*8975f5c5SAndroid Build Coastguard Worker   protected:
171*8975f5c5SAndroid Build Coastguard Worker     void getBlockLayoutInfo(GLenum type,
172*8975f5c5SAndroid Build Coastguard Worker                             const std::vector<unsigned int> &arraySizes,
173*8975f5c5SAndroid Build Coastguard Worker                             bool isRowMajorMatrix,
174*8975f5c5SAndroid Build Coastguard Worker                             int *arrayStrideOut,
175*8975f5c5SAndroid Build Coastguard Worker                             int *matrixStrideOut) override;
176*8975f5c5SAndroid Build Coastguard Worker 
advanceOffset(GLenum type,const std::vector<unsigned int> & arraySizes,bool isRowMajorMatrix,int arrayStride,int matrixStride)177*8975f5c5SAndroid Build Coastguard Worker     void advanceOffset(GLenum type,
178*8975f5c5SAndroid Build Coastguard Worker                        const std::vector<unsigned int> &arraySizes,
179*8975f5c5SAndroid Build Coastguard Worker                        bool isRowMajorMatrix,
180*8975f5c5SAndroid Build Coastguard Worker                        int arrayStride,
181*8975f5c5SAndroid Build Coastguard Worker                        int matrixStride) override
182*8975f5c5SAndroid Build Coastguard Worker     {}
183*8975f5c5SAndroid Build Coastguard Worker };
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker // Block layout according to the std140 block layout
186*8975f5c5SAndroid Build Coastguard Worker // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker class Std140BlockEncoder : public BlockLayoutEncoder
189*8975f5c5SAndroid Build Coastguard Worker {
190*8975f5c5SAndroid Build Coastguard Worker   public:
191*8975f5c5SAndroid Build Coastguard Worker     Std140BlockEncoder();
192*8975f5c5SAndroid Build Coastguard Worker 
193*8975f5c5SAndroid Build Coastguard Worker     void enterAggregateType(const ShaderVariable &structVar) override;
194*8975f5c5SAndroid Build Coastguard Worker     void exitAggregateType(const ShaderVariable &structVar) override;
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker   protected:
197*8975f5c5SAndroid Build Coastguard Worker     void getBlockLayoutInfo(GLenum type,
198*8975f5c5SAndroid Build Coastguard Worker                             const std::vector<unsigned int> &arraySizes,
199*8975f5c5SAndroid Build Coastguard Worker                             bool isRowMajorMatrix,
200*8975f5c5SAndroid Build Coastguard Worker                             int *arrayStrideOut,
201*8975f5c5SAndroid Build Coastguard Worker                             int *matrixStrideOut) override;
202*8975f5c5SAndroid Build Coastguard Worker     void advanceOffset(GLenum type,
203*8975f5c5SAndroid Build Coastguard Worker                        const std::vector<unsigned int> &arraySizes,
204*8975f5c5SAndroid Build Coastguard Worker                        bool isRowMajorMatrix,
205*8975f5c5SAndroid Build Coastguard Worker                        int arrayStride,
206*8975f5c5SAndroid Build Coastguard Worker                        int matrixStride) override;
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker     virtual size_t getBaseAlignment(const ShaderVariable &variable) const;
209*8975f5c5SAndroid Build Coastguard Worker     virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
210*8975f5c5SAndroid Build Coastguard Worker };
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker class Std430BlockEncoder : public Std140BlockEncoder
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker   public:
215*8975f5c5SAndroid Build Coastguard Worker     Std430BlockEncoder();
216*8975f5c5SAndroid Build Coastguard Worker 
217*8975f5c5SAndroid Build Coastguard Worker   protected:
218*8975f5c5SAndroid Build Coastguard Worker     size_t getBaseAlignment(const ShaderVariable &variable) const override;
219*8975f5c5SAndroid Build Coastguard Worker     size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
220*8975f5c5SAndroid Build Coastguard Worker };
221*8975f5c5SAndroid Build Coastguard Worker 
222*8975f5c5SAndroid Build Coastguard Worker using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
225*8975f5c5SAndroid Build Coastguard Worker                            const std::string &prefix,
226*8975f5c5SAndroid Build Coastguard Worker                            BlockLayoutEncoder *encoder,
227*8975f5c5SAndroid Build Coastguard Worker                            BlockLayoutMap *blockInfoOut);
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker // Used for laying out the default uniform block on the Vulkan backend.
230*8975f5c5SAndroid Build Coastguard Worker void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
231*8975f5c5SAndroid Build Coastguard Worker                                const std::string &prefix,
232*8975f5c5SAndroid Build Coastguard Worker                                BlockLayoutEncoder *encoder,
233*8975f5c5SAndroid Build Coastguard Worker                                BlockLayoutMap *blockInfoOut);
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker class ShaderVariableVisitor
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker   public:
~ShaderVariableVisitor()238*8975f5c5SAndroid Build Coastguard Worker     virtual ~ShaderVariableVisitor() {}
239*8975f5c5SAndroid Build Coastguard Worker 
enterStruct(const ShaderVariable & structVar)240*8975f5c5SAndroid Build Coastguard Worker     virtual void enterStruct(const ShaderVariable &structVar) {}
exitStruct(const ShaderVariable & structVar)241*8975f5c5SAndroid Build Coastguard Worker     virtual void exitStruct(const ShaderVariable &structVar) {}
242*8975f5c5SAndroid Build Coastguard Worker 
enterStructAccess(const ShaderVariable & structVar,bool isRowMajor)243*8975f5c5SAndroid Build Coastguard Worker     virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
exitStructAccess(const ShaderVariable & structVar,bool isRowMajor)244*8975f5c5SAndroid Build Coastguard Worker     virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
245*8975f5c5SAndroid Build Coastguard Worker 
enterArray(const ShaderVariable & arrayVar)246*8975f5c5SAndroid Build Coastguard Worker     virtual void enterArray(const ShaderVariable &arrayVar) {}
exitArray(const ShaderVariable & arrayVar)247*8975f5c5SAndroid Build Coastguard Worker     virtual void exitArray(const ShaderVariable &arrayVar) {}
248*8975f5c5SAndroid Build Coastguard Worker 
enterArrayElement(const ShaderVariable & arrayVar,unsigned int arrayElement)249*8975f5c5SAndroid Build Coastguard Worker     virtual void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
exitArrayElement(const ShaderVariable & arrayVar,unsigned int arrayElement)250*8975f5c5SAndroid Build Coastguard Worker     virtual void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
251*8975f5c5SAndroid Build Coastguard Worker 
visitOpaqueObject(const sh::ShaderVariable & variable)252*8975f5c5SAndroid Build Coastguard Worker     virtual void visitOpaqueObject(const sh::ShaderVariable &variable) {}
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     virtual void visitVariable(const ShaderVariable &variable, bool isRowMajor) = 0;
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker   protected:
ShaderVariableVisitor()257*8975f5c5SAndroid Build Coastguard Worker     ShaderVariableVisitor() {}
258*8975f5c5SAndroid Build Coastguard Worker };
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker class VariableNameVisitor : public ShaderVariableVisitor
261*8975f5c5SAndroid Build Coastguard Worker {
262*8975f5c5SAndroid Build Coastguard Worker   public:
263*8975f5c5SAndroid Build Coastguard Worker     VariableNameVisitor(const std::string &namePrefix, const std::string &mappedNamePrefix);
264*8975f5c5SAndroid Build Coastguard Worker     ~VariableNameVisitor() override;
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker     void enterStruct(const ShaderVariable &structVar) override;
267*8975f5c5SAndroid Build Coastguard Worker     void exitStruct(const ShaderVariable &structVar) override;
268*8975f5c5SAndroid Build Coastguard Worker     void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
269*8975f5c5SAndroid Build Coastguard Worker     void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
270*8975f5c5SAndroid Build Coastguard Worker     void enterArray(const ShaderVariable &arrayVar) override;
271*8975f5c5SAndroid Build Coastguard Worker     void exitArray(const ShaderVariable &arrayVar) override;
272*8975f5c5SAndroid Build Coastguard Worker     void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
273*8975f5c5SAndroid Build Coastguard Worker     void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker   protected:
visitNamedOpaqueObject(const sh::ShaderVariable & variable,const std::string & name,const std::string & mappedName,const std::vector<unsigned int> & arraySizes)276*8975f5c5SAndroid Build Coastguard Worker     virtual void visitNamedOpaqueObject(const sh::ShaderVariable &variable,
277*8975f5c5SAndroid Build Coastguard Worker                                         const std::string &name,
278*8975f5c5SAndroid Build Coastguard Worker                                         const std::string &mappedName,
279*8975f5c5SAndroid Build Coastguard Worker                                         const std::vector<unsigned int> &arraySizes)
280*8975f5c5SAndroid Build Coastguard Worker     {}
281*8975f5c5SAndroid Build Coastguard Worker     virtual void visitNamedVariable(const ShaderVariable &variable,
282*8975f5c5SAndroid Build Coastguard Worker                                     bool isRowMajor,
283*8975f5c5SAndroid Build Coastguard Worker                                     const std::string &name,
284*8975f5c5SAndroid Build Coastguard Worker                                     const std::string &mappedName,
285*8975f5c5SAndroid Build Coastguard Worker                                     const std::vector<unsigned int> &arraySizes) = 0;
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker     std::string collapseNameStack() const;
288*8975f5c5SAndroid Build Coastguard Worker     std::string collapseMappedNameStack() const;
289*8975f5c5SAndroid Build Coastguard Worker 
290*8975f5c5SAndroid Build Coastguard Worker   private:
291*8975f5c5SAndroid Build Coastguard Worker     void visitOpaqueObject(const sh::ShaderVariable &variable) final;
292*8975f5c5SAndroid Build Coastguard Worker     void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;
293*8975f5c5SAndroid Build Coastguard Worker 
294*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mNameStack;
295*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mMappedNameStack;
296*8975f5c5SAndroid Build Coastguard Worker     std::vector<unsigned int> mArraySizeStack;
297*8975f5c5SAndroid Build Coastguard Worker };
298*8975f5c5SAndroid Build Coastguard Worker 
299*8975f5c5SAndroid Build Coastguard Worker class BlockEncoderVisitor : public VariableNameVisitor
300*8975f5c5SAndroid Build Coastguard Worker {
301*8975f5c5SAndroid Build Coastguard Worker   public:
302*8975f5c5SAndroid Build Coastguard Worker     BlockEncoderVisitor(const std::string &namePrefix,
303*8975f5c5SAndroid Build Coastguard Worker                         const std::string &mappedNamePrefix,
304*8975f5c5SAndroid Build Coastguard Worker                         BlockLayoutEncoder *encoder);
305*8975f5c5SAndroid Build Coastguard Worker     ~BlockEncoderVisitor() override;
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker     void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
308*8975f5c5SAndroid Build Coastguard Worker     void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
309*8975f5c5SAndroid Build Coastguard Worker     void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
310*8975f5c5SAndroid Build Coastguard Worker     void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
311*8975f5c5SAndroid Build Coastguard Worker 
312*8975f5c5SAndroid Build Coastguard Worker     void visitNamedVariable(const ShaderVariable &variable,
313*8975f5c5SAndroid Build Coastguard Worker                             bool isRowMajor,
314*8975f5c5SAndroid Build Coastguard Worker                             const std::string &name,
315*8975f5c5SAndroid Build Coastguard Worker                             const std::string &mappedName,
316*8975f5c5SAndroid Build Coastguard Worker                             const std::vector<unsigned int> &arraySizes) override;
317*8975f5c5SAndroid Build Coastguard Worker 
encodeVariable(const ShaderVariable & variable,const BlockMemberInfo & variableInfo,const std::string & name,const std::string & mappedName)318*8975f5c5SAndroid Build Coastguard Worker     virtual void encodeVariable(const ShaderVariable &variable,
319*8975f5c5SAndroid Build Coastguard Worker                                 const BlockMemberInfo &variableInfo,
320*8975f5c5SAndroid Build Coastguard Worker                                 const std::string &name,
321*8975f5c5SAndroid Build Coastguard Worker                                 const std::string &mappedName)
322*8975f5c5SAndroid Build Coastguard Worker     {}
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker   protected:
325*8975f5c5SAndroid Build Coastguard Worker     int mTopLevelArraySize           = 1;
326*8975f5c5SAndroid Build Coastguard Worker     int mTopLevelArrayStride         = 0;
327*8975f5c5SAndroid Build Coastguard Worker     bool mIsTopLevelArrayStrideReady = true;
328*8975f5c5SAndroid Build Coastguard Worker     bool mSkipEnabled                = false;
329*8975f5c5SAndroid Build Coastguard Worker 
330*8975f5c5SAndroid Build Coastguard Worker   private:
331*8975f5c5SAndroid Build Coastguard Worker     BlockLayoutEncoder *mEncoder;
332*8975f5c5SAndroid Build Coastguard Worker     unsigned int mStructStackSize = 0;
333*8975f5c5SAndroid Build Coastguard Worker };
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker void TraverseShaderVariable(const ShaderVariable &variable,
336*8975f5c5SAndroid Build Coastguard Worker                             bool isRowMajorLayout,
337*8975f5c5SAndroid Build Coastguard Worker                             ShaderVariableVisitor *visitor);
338*8975f5c5SAndroid Build Coastguard Worker 
339*8975f5c5SAndroid Build Coastguard Worker template <typename T>
TraverseShaderVariables(const std::vector<T> & vars,bool isRowMajorLayout,ShaderVariableVisitor * visitor)340*8975f5c5SAndroid Build Coastguard Worker void TraverseShaderVariables(const std::vector<T> &vars,
341*8975f5c5SAndroid Build Coastguard Worker                              bool isRowMajorLayout,
342*8975f5c5SAndroid Build Coastguard Worker                              ShaderVariableVisitor *visitor)
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker     for (const T &var : vars)
345*8975f5c5SAndroid Build Coastguard Worker     {
346*8975f5c5SAndroid Build Coastguard Worker         TraverseShaderVariable(var, isRowMajorLayout, visitor);
347*8975f5c5SAndroid Build Coastguard Worker     }
348*8975f5c5SAndroid Build Coastguard Worker }
349*8975f5c5SAndroid Build Coastguard Worker 
350*8975f5c5SAndroid Build Coastguard Worker template <typename T>
TraverseActiveShaderVariables(const std::vector<T> & vars,bool isRowMajorLayout,ShaderVariableVisitor * visitor)351*8975f5c5SAndroid Build Coastguard Worker void TraverseActiveShaderVariables(const std::vector<T> &vars,
352*8975f5c5SAndroid Build Coastguard Worker                                    bool isRowMajorLayout,
353*8975f5c5SAndroid Build Coastguard Worker                                    ShaderVariableVisitor *visitor)
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker     for (const T &var : vars)
356*8975f5c5SAndroid Build Coastguard Worker     {
357*8975f5c5SAndroid Build Coastguard Worker         if (var.active)
358*8975f5c5SAndroid Build Coastguard Worker         {
359*8975f5c5SAndroid Build Coastguard Worker             TraverseShaderVariable(var, isRowMajorLayout, visitor);
360*8975f5c5SAndroid Build Coastguard Worker         }
361*8975f5c5SAndroid Build Coastguard Worker     }
362*8975f5c5SAndroid Build Coastguard Worker }
363*8975f5c5SAndroid Build Coastguard Worker }  // namespace sh
364*8975f5c5SAndroid Build Coastguard Worker 
365*8975f5c5SAndroid Build Coastguard Worker #endif  // COMMON_BLOCKLAYOUT_H_
366