1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 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 // CollectVariables.cpp: Collect lists of shader interface variables based on the AST.
7*8975f5c5SAndroid Build Coastguard Worker
8*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/CollectVariables.h"
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/HashNames.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/SymbolTable.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_util/IntermTraverse.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/util.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker namespace sh
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker namespace
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker
GetBlockLayoutType(TLayoutBlockStorage blockStorage)23*8975f5c5SAndroid Build Coastguard Worker BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker switch (blockStorage)
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker case EbsPacked:
28*8975f5c5SAndroid Build Coastguard Worker return BLOCKLAYOUT_PACKED;
29*8975f5c5SAndroid Build Coastguard Worker case EbsShared:
30*8975f5c5SAndroid Build Coastguard Worker return BLOCKLAYOUT_SHARED;
31*8975f5c5SAndroid Build Coastguard Worker case EbsStd140:
32*8975f5c5SAndroid Build Coastguard Worker return BLOCKLAYOUT_STD140;
33*8975f5c5SAndroid Build Coastguard Worker case EbsStd430:
34*8975f5c5SAndroid Build Coastguard Worker return BLOCKLAYOUT_STD430;
35*8975f5c5SAndroid Build Coastguard Worker default:
36*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
37*8975f5c5SAndroid Build Coastguard Worker return BLOCKLAYOUT_SHARED;
38*8975f5c5SAndroid Build Coastguard Worker }
39*8975f5c5SAndroid Build Coastguard Worker }
40*8975f5c5SAndroid Build Coastguard Worker
GetBlockType(TQualifier qualifier)41*8975f5c5SAndroid Build Coastguard Worker BlockType GetBlockType(TQualifier qualifier)
42*8975f5c5SAndroid Build Coastguard Worker {
43*8975f5c5SAndroid Build Coastguard Worker switch (qualifier)
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker case EvqUniform:
46*8975f5c5SAndroid Build Coastguard Worker return BlockType::kBlockUniform;
47*8975f5c5SAndroid Build Coastguard Worker case EvqBuffer:
48*8975f5c5SAndroid Build Coastguard Worker return BlockType::kBlockBuffer;
49*8975f5c5SAndroid Build Coastguard Worker case EvqPixelLocalEXT:
50*8975f5c5SAndroid Build Coastguard Worker return BlockType::kPixelLocalExt;
51*8975f5c5SAndroid Build Coastguard Worker default:
52*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
53*8975f5c5SAndroid Build Coastguard Worker return BlockType::kBlockUniform;
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker template <class VarT>
FindVariable(const ImmutableString & name,std::vector<VarT> * infoList)58*8975f5c5SAndroid Build Coastguard Worker VarT *FindVariable(const ImmutableString &name, std::vector<VarT> *infoList)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker // TODO(zmo): optimize this function.
61*8975f5c5SAndroid Build Coastguard Worker for (size_t ii = 0; ii < infoList->size(); ++ii)
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker if (name == (*infoList)[ii].name)
64*8975f5c5SAndroid Build Coastguard Worker return &((*infoList)[ii]);
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker return nullptr;
68*8975f5c5SAndroid Build Coastguard Worker }
69*8975f5c5SAndroid Build Coastguard Worker
MarkActive(ShaderVariable * variable)70*8975f5c5SAndroid Build Coastguard Worker void MarkActive(ShaderVariable *variable)
71*8975f5c5SAndroid Build Coastguard Worker {
72*8975f5c5SAndroid Build Coastguard Worker if (!variable->active)
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker if (variable->isStruct())
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker // Conservatively assume all fields are statically used as well.
77*8975f5c5SAndroid Build Coastguard Worker for (auto &field : variable->fields)
78*8975f5c5SAndroid Build Coastguard Worker {
79*8975f5c5SAndroid Build Coastguard Worker MarkActive(&field);
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker }
82*8975f5c5SAndroid Build Coastguard Worker variable->staticUse = true;
83*8975f5c5SAndroid Build Coastguard Worker variable->active = true;
84*8975f5c5SAndroid Build Coastguard Worker }
85*8975f5c5SAndroid Build Coastguard Worker }
86*8975f5c5SAndroid Build Coastguard Worker
FindVariableInInterfaceBlock(const ImmutableString & name,const TInterfaceBlock * interfaceBlock,std::vector<InterfaceBlock> * infoList)87*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *FindVariableInInterfaceBlock(const ImmutableString &name,
88*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *interfaceBlock,
89*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *infoList)
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker ASSERT(interfaceBlock);
92*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList);
93*8975f5c5SAndroid Build Coastguard Worker ASSERT(namedBlock);
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker // Set static use on the parent interface block here
96*8975f5c5SAndroid Build Coastguard Worker namedBlock->staticUse = true;
97*8975f5c5SAndroid Build Coastguard Worker namedBlock->active = true;
98*8975f5c5SAndroid Build Coastguard Worker return FindVariable(name, &namedBlock->fields);
99*8975f5c5SAndroid Build Coastguard Worker }
100*8975f5c5SAndroid Build Coastguard Worker
FindShaderIOBlockVariable(const ImmutableString & blockName,std::vector<ShaderVariable> * infoList)101*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *FindShaderIOBlockVariable(const ImmutableString &blockName,
102*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *infoList)
103*8975f5c5SAndroid Build Coastguard Worker {
104*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < infoList->size(); ++index)
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker if (blockName == (*infoList)[index].structOrBlockName)
107*8975f5c5SAndroid Build Coastguard Worker return &(*infoList)[index];
108*8975f5c5SAndroid Build Coastguard Worker }
109*8975f5c5SAndroid Build Coastguard Worker
110*8975f5c5SAndroid Build Coastguard Worker return nullptr;
111*8975f5c5SAndroid Build Coastguard Worker }
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker // Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
114*8975f5c5SAndroid Build Coastguard Worker // shared data and interface blocks.
115*8975f5c5SAndroid Build Coastguard Worker class CollectVariablesTraverser : public TIntermTraverser
116*8975f5c5SAndroid Build Coastguard Worker {
117*8975f5c5SAndroid Build Coastguard Worker public:
118*8975f5c5SAndroid Build Coastguard Worker CollectVariablesTraverser(std::vector<ShaderVariable> *attribs,
119*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *outputVariables,
120*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *uniforms,
121*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *inputVaryings,
122*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *outputVaryings,
123*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *sharedVariables,
124*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *uniformBlocks,
125*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *shaderStorageBlocks,
126*8975f5c5SAndroid Build Coastguard Worker ShHashFunction64 hashFunction,
127*8975f5c5SAndroid Build Coastguard Worker TSymbolTable *symbolTable,
128*8975f5c5SAndroid Build Coastguard Worker GLenum shaderType,
129*8975f5c5SAndroid Build Coastguard Worker const TExtensionBehavior &extensionBehavior,
130*8975f5c5SAndroid Build Coastguard Worker const ShBuiltInResources &resources,
131*8975f5c5SAndroid Build Coastguard Worker int tessControlShaderOutputVertices);
132*8975f5c5SAndroid Build Coastguard Worker
133*8975f5c5SAndroid Build Coastguard Worker bool visitGlobalQualifierDeclaration(Visit visit,
134*8975f5c5SAndroid Build Coastguard Worker TIntermGlobalQualifierDeclaration *node) override;
135*8975f5c5SAndroid Build Coastguard Worker void visitSymbol(TIntermSymbol *symbol) override;
136*8975f5c5SAndroid Build Coastguard Worker bool visitDeclaration(Visit, TIntermDeclaration *node) override;
137*8975f5c5SAndroid Build Coastguard Worker bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker private:
140*8975f5c5SAndroid Build Coastguard Worker std::string getMappedName(const TSymbol *symbol) const;
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Worker void setFieldOrVariableProperties(const TType &type,
143*8975f5c5SAndroid Build Coastguard Worker bool staticUse,
144*8975f5c5SAndroid Build Coastguard Worker bool isShaderIOBlock,
145*8975f5c5SAndroid Build Coastguard Worker bool isPatch,
146*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *variableOut) const;
147*8975f5c5SAndroid Build Coastguard Worker void setFieldProperties(const TType &type,
148*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name,
149*8975f5c5SAndroid Build Coastguard Worker bool staticUse,
150*8975f5c5SAndroid Build Coastguard Worker bool isShaderIOBlock,
151*8975f5c5SAndroid Build Coastguard Worker bool isPatch,
152*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType,
153*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *variableOut) const;
154*8975f5c5SAndroid Build Coastguard Worker void setCommonVariableProperties(const TType &type,
155*8975f5c5SAndroid Build Coastguard Worker const TVariable &variable,
156*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *variableOut) const;
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Worker ShaderVariable recordAttribute(const TIntermSymbol &variable) const;
159*8975f5c5SAndroid Build Coastguard Worker ShaderVariable recordOutputVariable(const TIntermSymbol &variable) const;
160*8975f5c5SAndroid Build Coastguard Worker ShaderVariable recordVarying(const TIntermSymbol &variable) const;
161*8975f5c5SAndroid Build Coastguard Worker void recordInterfaceBlock(const char *instanceName,
162*8975f5c5SAndroid Build Coastguard Worker const TType &interfaceBlockType,
163*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *interfaceBlock) const;
164*8975f5c5SAndroid Build Coastguard Worker ShaderVariable recordUniform(const TIntermSymbol &variable) const;
165*8975f5c5SAndroid Build Coastguard Worker
166*8975f5c5SAndroid Build Coastguard Worker void setBuiltInInfoFromSymbol(const TVariable &variable, ShaderVariable *info);
167*8975f5c5SAndroid Build Coastguard Worker
168*8975f5c5SAndroid Build Coastguard Worker void recordBuiltInVaryingUsed(const TVariable &variable,
169*8975f5c5SAndroid Build Coastguard Worker bool *addedFlag,
170*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *varyings);
171*8975f5c5SAndroid Build Coastguard Worker void recordBuiltInFragmentOutputUsed(const TVariable &variable, bool *addedFlag);
172*8975f5c5SAndroid Build Coastguard Worker void recordBuiltInAttributeUsed(const TVariable &variable, bool *addedFlag);
173*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *mAttribs;
176*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *mOutputVariables;
177*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *mUniforms;
178*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *mInputVaryings;
179*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *mOutputVaryings;
180*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *mSharedVariables;
181*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *mUniformBlocks;
182*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *mShaderStorageBlocks;
183*8975f5c5SAndroid Build Coastguard Worker
184*8975f5c5SAndroid Build Coastguard Worker std::map<std::string, ShaderVariable *> mInterfaceBlockFields;
185*8975f5c5SAndroid Build Coastguard Worker
186*8975f5c5SAndroid Build Coastguard Worker // Shader uniforms
187*8975f5c5SAndroid Build Coastguard Worker bool mDepthRangeAdded;
188*8975f5c5SAndroid Build Coastguard Worker bool mNumSamplesAdded;
189*8975f5c5SAndroid Build Coastguard Worker
190*8975f5c5SAndroid Build Coastguard Worker // Compute Shader builtins
191*8975f5c5SAndroid Build Coastguard Worker bool mNumWorkGroupsAdded;
192*8975f5c5SAndroid Build Coastguard Worker bool mWorkGroupIDAdded;
193*8975f5c5SAndroid Build Coastguard Worker bool mLocalInvocationIDAdded;
194*8975f5c5SAndroid Build Coastguard Worker bool mGlobalInvocationIDAdded;
195*8975f5c5SAndroid Build Coastguard Worker bool mLocalInvocationIndexAdded;
196*8975f5c5SAndroid Build Coastguard Worker
197*8975f5c5SAndroid Build Coastguard Worker // Vertex Shader builtins
198*8975f5c5SAndroid Build Coastguard Worker bool mInstanceIDAdded;
199*8975f5c5SAndroid Build Coastguard Worker bool mVertexIDAdded;
200*8975f5c5SAndroid Build Coastguard Worker bool mPointSizeAdded;
201*8975f5c5SAndroid Build Coastguard Worker bool mDrawIDAdded;
202*8975f5c5SAndroid Build Coastguard Worker
203*8975f5c5SAndroid Build Coastguard Worker // Vertex Shader and Geometry Shader builtins
204*8975f5c5SAndroid Build Coastguard Worker bool mPositionAdded;
205*8975f5c5SAndroid Build Coastguard Worker bool mClipDistanceAdded;
206*8975f5c5SAndroid Build Coastguard Worker bool mCullDistanceAdded;
207*8975f5c5SAndroid Build Coastguard Worker
208*8975f5c5SAndroid Build Coastguard Worker // Fragment Shader builtins
209*8975f5c5SAndroid Build Coastguard Worker bool mPointCoordAdded;
210*8975f5c5SAndroid Build Coastguard Worker bool mFrontFacingAdded;
211*8975f5c5SAndroid Build Coastguard Worker bool mHelperInvocationAdded;
212*8975f5c5SAndroid Build Coastguard Worker bool mFragCoordAdded;
213*8975f5c5SAndroid Build Coastguard Worker bool mLastFragDataAdded;
214*8975f5c5SAndroid Build Coastguard Worker bool mLastFragColorAdded;
215*8975f5c5SAndroid Build Coastguard Worker bool mFragColorAdded;
216*8975f5c5SAndroid Build Coastguard Worker bool mFragDataAdded;
217*8975f5c5SAndroid Build Coastguard Worker bool mFragDepthAdded;
218*8975f5c5SAndroid Build Coastguard Worker bool mSecondaryFragColorEXTAdded;
219*8975f5c5SAndroid Build Coastguard Worker bool mSecondaryFragDataEXTAdded;
220*8975f5c5SAndroid Build Coastguard Worker bool mSampleIDAdded;
221*8975f5c5SAndroid Build Coastguard Worker bool mSamplePositionAdded;
222*8975f5c5SAndroid Build Coastguard Worker bool mSampleMaskAdded;
223*8975f5c5SAndroid Build Coastguard Worker bool mSampleMaskInAdded;
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker // Geometry and Tessellation Shader builtins
226*8975f5c5SAndroid Build Coastguard Worker bool mPerVertexInAdded;
227*8975f5c5SAndroid Build Coastguard Worker bool mPerVertexOutAdded;
228*8975f5c5SAndroid Build Coastguard Worker
229*8975f5c5SAndroid Build Coastguard Worker // Geometry Shader builtins
230*8975f5c5SAndroid Build Coastguard Worker bool mPrimitiveIDInAdded;
231*8975f5c5SAndroid Build Coastguard Worker bool mInvocationIDAdded;
232*8975f5c5SAndroid Build Coastguard Worker
233*8975f5c5SAndroid Build Coastguard Worker // Geometry Shader and Fragment Shader builtins
234*8975f5c5SAndroid Build Coastguard Worker bool mPrimitiveIDAdded;
235*8975f5c5SAndroid Build Coastguard Worker bool mLayerAdded;
236*8975f5c5SAndroid Build Coastguard Worker
237*8975f5c5SAndroid Build Coastguard Worker // Shared memory variables
238*8975f5c5SAndroid Build Coastguard Worker bool mSharedVariableAdded;
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker // Tessellation Shader builtins
241*8975f5c5SAndroid Build Coastguard Worker bool mPatchVerticesInAdded;
242*8975f5c5SAndroid Build Coastguard Worker bool mTessLevelOuterAdded;
243*8975f5c5SAndroid Build Coastguard Worker bool mTessLevelInnerAdded;
244*8975f5c5SAndroid Build Coastguard Worker bool mBoundingBoxAdded;
245*8975f5c5SAndroid Build Coastguard Worker bool mTessCoordAdded;
246*8975f5c5SAndroid Build Coastguard Worker const int mTessControlShaderOutputVertices;
247*8975f5c5SAndroid Build Coastguard Worker
248*8975f5c5SAndroid Build Coastguard Worker ShHashFunction64 mHashFunction;
249*8975f5c5SAndroid Build Coastguard Worker
250*8975f5c5SAndroid Build Coastguard Worker GLenum mShaderType;
251*8975f5c5SAndroid Build Coastguard Worker const TExtensionBehavior &mExtensionBehavior;
252*8975f5c5SAndroid Build Coastguard Worker const ShBuiltInResources &mResources;
253*8975f5c5SAndroid Build Coastguard Worker };
254*8975f5c5SAndroid Build Coastguard Worker
CollectVariablesTraverser(std::vector<sh::ShaderVariable> * attribs,std::vector<sh::ShaderVariable> * outputVariables,std::vector<sh::ShaderVariable> * uniforms,std::vector<sh::ShaderVariable> * inputVaryings,std::vector<sh::ShaderVariable> * outputVaryings,std::vector<sh::ShaderVariable> * sharedVariables,std::vector<sh::InterfaceBlock> * uniformBlocks,std::vector<sh::InterfaceBlock> * shaderStorageBlocks,ShHashFunction64 hashFunction,TSymbolTable * symbolTable,GLenum shaderType,const TExtensionBehavior & extensionBehavior,const ShBuiltInResources & resources,int tessControlShaderOutputVertices)255*8975f5c5SAndroid Build Coastguard Worker CollectVariablesTraverser::CollectVariablesTraverser(
256*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *attribs,
257*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *outputVariables,
258*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *uniforms,
259*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *inputVaryings,
260*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *outputVaryings,
261*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *sharedVariables,
262*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::InterfaceBlock> *uniformBlocks,
263*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
264*8975f5c5SAndroid Build Coastguard Worker ShHashFunction64 hashFunction,
265*8975f5c5SAndroid Build Coastguard Worker TSymbolTable *symbolTable,
266*8975f5c5SAndroid Build Coastguard Worker GLenum shaderType,
267*8975f5c5SAndroid Build Coastguard Worker const TExtensionBehavior &extensionBehavior,
268*8975f5c5SAndroid Build Coastguard Worker const ShBuiltInResources &resources,
269*8975f5c5SAndroid Build Coastguard Worker int tessControlShaderOutputVertices)
270*8975f5c5SAndroid Build Coastguard Worker : TIntermTraverser(true, false, false, symbolTable),
271*8975f5c5SAndroid Build Coastguard Worker mAttribs(attribs),
272*8975f5c5SAndroid Build Coastguard Worker mOutputVariables(outputVariables),
273*8975f5c5SAndroid Build Coastguard Worker mUniforms(uniforms),
274*8975f5c5SAndroid Build Coastguard Worker mInputVaryings(inputVaryings),
275*8975f5c5SAndroid Build Coastguard Worker mOutputVaryings(outputVaryings),
276*8975f5c5SAndroid Build Coastguard Worker mSharedVariables(sharedVariables),
277*8975f5c5SAndroid Build Coastguard Worker mUniformBlocks(uniformBlocks),
278*8975f5c5SAndroid Build Coastguard Worker mShaderStorageBlocks(shaderStorageBlocks),
279*8975f5c5SAndroid Build Coastguard Worker mDepthRangeAdded(false),
280*8975f5c5SAndroid Build Coastguard Worker mNumSamplesAdded(false),
281*8975f5c5SAndroid Build Coastguard Worker mNumWorkGroupsAdded(false),
282*8975f5c5SAndroid Build Coastguard Worker mWorkGroupIDAdded(false),
283*8975f5c5SAndroid Build Coastguard Worker mLocalInvocationIDAdded(false),
284*8975f5c5SAndroid Build Coastguard Worker mGlobalInvocationIDAdded(false),
285*8975f5c5SAndroid Build Coastguard Worker mLocalInvocationIndexAdded(false),
286*8975f5c5SAndroid Build Coastguard Worker mInstanceIDAdded(false),
287*8975f5c5SAndroid Build Coastguard Worker mVertexIDAdded(false),
288*8975f5c5SAndroid Build Coastguard Worker mPointSizeAdded(false),
289*8975f5c5SAndroid Build Coastguard Worker mDrawIDAdded(false),
290*8975f5c5SAndroid Build Coastguard Worker mPositionAdded(false),
291*8975f5c5SAndroid Build Coastguard Worker mClipDistanceAdded(false),
292*8975f5c5SAndroid Build Coastguard Worker mCullDistanceAdded(false),
293*8975f5c5SAndroid Build Coastguard Worker mPointCoordAdded(false),
294*8975f5c5SAndroid Build Coastguard Worker mFrontFacingAdded(false),
295*8975f5c5SAndroid Build Coastguard Worker mHelperInvocationAdded(false),
296*8975f5c5SAndroid Build Coastguard Worker mFragCoordAdded(false),
297*8975f5c5SAndroid Build Coastguard Worker mLastFragDataAdded(false),
298*8975f5c5SAndroid Build Coastguard Worker mLastFragColorAdded(false),
299*8975f5c5SAndroid Build Coastguard Worker mFragColorAdded(false),
300*8975f5c5SAndroid Build Coastguard Worker mFragDataAdded(false),
301*8975f5c5SAndroid Build Coastguard Worker mFragDepthAdded(false),
302*8975f5c5SAndroid Build Coastguard Worker mSecondaryFragColorEXTAdded(false),
303*8975f5c5SAndroid Build Coastguard Worker mSecondaryFragDataEXTAdded(false),
304*8975f5c5SAndroid Build Coastguard Worker mSampleIDAdded(false),
305*8975f5c5SAndroid Build Coastguard Worker mSamplePositionAdded(false),
306*8975f5c5SAndroid Build Coastguard Worker mSampleMaskAdded(false),
307*8975f5c5SAndroid Build Coastguard Worker mSampleMaskInAdded(false),
308*8975f5c5SAndroid Build Coastguard Worker mPerVertexInAdded(false),
309*8975f5c5SAndroid Build Coastguard Worker mPerVertexOutAdded(false),
310*8975f5c5SAndroid Build Coastguard Worker mPrimitiveIDInAdded(false),
311*8975f5c5SAndroid Build Coastguard Worker mInvocationIDAdded(false),
312*8975f5c5SAndroid Build Coastguard Worker mPrimitiveIDAdded(false),
313*8975f5c5SAndroid Build Coastguard Worker mLayerAdded(false),
314*8975f5c5SAndroid Build Coastguard Worker mSharedVariableAdded(false),
315*8975f5c5SAndroid Build Coastguard Worker mPatchVerticesInAdded(false),
316*8975f5c5SAndroid Build Coastguard Worker mTessLevelOuterAdded(false),
317*8975f5c5SAndroid Build Coastguard Worker mTessLevelInnerAdded(false),
318*8975f5c5SAndroid Build Coastguard Worker mBoundingBoxAdded(false),
319*8975f5c5SAndroid Build Coastguard Worker mTessCoordAdded(false),
320*8975f5c5SAndroid Build Coastguard Worker mTessControlShaderOutputVertices(tessControlShaderOutputVertices),
321*8975f5c5SAndroid Build Coastguard Worker mHashFunction(hashFunction),
322*8975f5c5SAndroid Build Coastguard Worker mShaderType(shaderType),
323*8975f5c5SAndroid Build Coastguard Worker mExtensionBehavior(extensionBehavior),
324*8975f5c5SAndroid Build Coastguard Worker mResources(resources)
325*8975f5c5SAndroid Build Coastguard Worker {}
326*8975f5c5SAndroid Build Coastguard Worker
getMappedName(const TSymbol * symbol) const327*8975f5c5SAndroid Build Coastguard Worker std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
328*8975f5c5SAndroid Build Coastguard Worker {
329*8975f5c5SAndroid Build Coastguard Worker return HashName(symbol, mHashFunction, nullptr).data();
330*8975f5c5SAndroid Build Coastguard Worker }
331*8975f5c5SAndroid Build Coastguard Worker
setBuiltInInfoFromSymbol(const TVariable & variable,ShaderVariable * info)332*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::setBuiltInInfoFromSymbol(const TVariable &variable,
333*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *info)
334*8975f5c5SAndroid Build Coastguard Worker {
335*8975f5c5SAndroid Build Coastguard Worker const TType &type = variable.getType();
336*8975f5c5SAndroid Build Coastguard Worker
337*8975f5c5SAndroid Build Coastguard Worker info->name = variable.name().data();
338*8975f5c5SAndroid Build Coastguard Worker info->mappedName = variable.name().data();
339*8975f5c5SAndroid Build Coastguard Worker
340*8975f5c5SAndroid Build Coastguard Worker bool isShaderIOBlock =
341*8975f5c5SAndroid Build Coastguard Worker IsShaderIoBlock(type.getQualifier()) && type.getInterfaceBlock() != nullptr;
342*8975f5c5SAndroid Build Coastguard Worker bool isPatch = type.getQualifier() == EvqTessLevelInner ||
343*8975f5c5SAndroid Build Coastguard Worker type.getQualifier() == EvqTessLevelOuter ||
344*8975f5c5SAndroid Build Coastguard Worker type.getQualifier() == EvqBoundingBox;
345*8975f5c5SAndroid Build Coastguard Worker
346*8975f5c5SAndroid Build Coastguard Worker setFieldOrVariableProperties(type, true, isShaderIOBlock, isPatch, info);
347*8975f5c5SAndroid Build Coastguard Worker }
348*8975f5c5SAndroid Build Coastguard Worker
recordBuiltInVaryingUsed(const TVariable & variable,bool * addedFlag,std::vector<ShaderVariable> * varyings)349*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::recordBuiltInVaryingUsed(const TVariable &variable,
350*8975f5c5SAndroid Build Coastguard Worker bool *addedFlag,
351*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *varyings)
352*8975f5c5SAndroid Build Coastguard Worker {
353*8975f5c5SAndroid Build Coastguard Worker ASSERT(varyings);
354*8975f5c5SAndroid Build Coastguard Worker if (!(*addedFlag))
355*8975f5c5SAndroid Build Coastguard Worker {
356*8975f5c5SAndroid Build Coastguard Worker ShaderVariable info;
357*8975f5c5SAndroid Build Coastguard Worker setBuiltInInfoFromSymbol(variable, &info);
358*8975f5c5SAndroid Build Coastguard Worker info.active = true;
359*8975f5c5SAndroid Build Coastguard Worker info.isInvariant = mSymbolTable->isVaryingInvariant(variable);
360*8975f5c5SAndroid Build Coastguard Worker
361*8975f5c5SAndroid Build Coastguard Worker varyings->push_back(info);
362*8975f5c5SAndroid Build Coastguard Worker (*addedFlag) = true;
363*8975f5c5SAndroid Build Coastguard Worker }
364*8975f5c5SAndroid Build Coastguard Worker }
365*8975f5c5SAndroid Build Coastguard Worker
recordBuiltInFragmentOutputUsed(const TVariable & variable,bool * addedFlag)366*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const TVariable &variable,
367*8975f5c5SAndroid Build Coastguard Worker bool *addedFlag)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker if (!(*addedFlag))
370*8975f5c5SAndroid Build Coastguard Worker {
371*8975f5c5SAndroid Build Coastguard Worker ShaderVariable info;
372*8975f5c5SAndroid Build Coastguard Worker setBuiltInInfoFromSymbol(variable, &info);
373*8975f5c5SAndroid Build Coastguard Worker info.active = true;
374*8975f5c5SAndroid Build Coastguard Worker mOutputVariables->push_back(info);
375*8975f5c5SAndroid Build Coastguard Worker (*addedFlag) = true;
376*8975f5c5SAndroid Build Coastguard Worker }
377*8975f5c5SAndroid Build Coastguard Worker }
378*8975f5c5SAndroid Build Coastguard Worker
recordBuiltInAttributeUsed(const TVariable & variable,bool * addedFlag)379*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::recordBuiltInAttributeUsed(const TVariable &variable,
380*8975f5c5SAndroid Build Coastguard Worker bool *addedFlag)
381*8975f5c5SAndroid Build Coastguard Worker {
382*8975f5c5SAndroid Build Coastguard Worker if (!(*addedFlag))
383*8975f5c5SAndroid Build Coastguard Worker {
384*8975f5c5SAndroid Build Coastguard Worker ShaderVariable info;
385*8975f5c5SAndroid Build Coastguard Worker setBuiltInInfoFromSymbol(variable, &info);
386*8975f5c5SAndroid Build Coastguard Worker info.active = true;
387*8975f5c5SAndroid Build Coastguard Worker info.location = -1;
388*8975f5c5SAndroid Build Coastguard Worker mAttribs->push_back(info);
389*8975f5c5SAndroid Build Coastguard Worker (*addedFlag) = true;
390*8975f5c5SAndroid Build Coastguard Worker }
391*8975f5c5SAndroid Build Coastguard Worker }
392*8975f5c5SAndroid Build Coastguard Worker
visitGlobalQualifierDeclaration(Visit visit,TIntermGlobalQualifierDeclaration * node)393*8975f5c5SAndroid Build Coastguard Worker bool CollectVariablesTraverser::visitGlobalQualifierDeclaration(
394*8975f5c5SAndroid Build Coastguard Worker Visit visit,
395*8975f5c5SAndroid Build Coastguard Worker TIntermGlobalQualifierDeclaration *node)
396*8975f5c5SAndroid Build Coastguard Worker {
397*8975f5c5SAndroid Build Coastguard Worker // We should not mark variables as active just based on an invariant/precise declaration, so we
398*8975f5c5SAndroid Build Coastguard Worker // don't traverse the symbols declared invariant.
399*8975f5c5SAndroid Build Coastguard Worker return false;
400*8975f5c5SAndroid Build Coastguard Worker }
401*8975f5c5SAndroid Build Coastguard Worker
402*8975f5c5SAndroid Build Coastguard Worker // We want to check whether a uniform/varying is active because we need to skip updating inactive
403*8975f5c5SAndroid Build Coastguard Worker // ones. We also only count the active ones in packing computing. Also, gl_FragCoord, gl_PointCoord,
404*8975f5c5SAndroid Build Coastguard Worker // and gl_FrontFacing count toward varying counting if they are active in a fragment shader.
visitSymbol(TIntermSymbol * symbol)405*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker ASSERT(symbol != nullptr);
408*8975f5c5SAndroid Build Coastguard Worker
409*8975f5c5SAndroid Build Coastguard Worker if (symbol->variable().symbolType() == SymbolType::AngleInternal ||
410*8975f5c5SAndroid Build Coastguard Worker symbol->variable().symbolType() == SymbolType::Empty)
411*8975f5c5SAndroid Build Coastguard Worker {
412*8975f5c5SAndroid Build Coastguard Worker // Internal variables or nameless variables are not collected.
413*8975f5c5SAndroid Build Coastguard Worker return;
414*8975f5c5SAndroid Build Coastguard Worker }
415*8975f5c5SAndroid Build Coastguard Worker
416*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *var = nullptr;
417*8975f5c5SAndroid Build Coastguard Worker
418*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &symbolName = symbol->getName();
419*8975f5c5SAndroid Build Coastguard Worker
420*8975f5c5SAndroid Build Coastguard Worker // Check the qualifier from the variable, not from the symbol node. The node may have a
421*8975f5c5SAndroid Build Coastguard Worker // different qualifier if it's the result of a folded ternary node.
422*8975f5c5SAndroid Build Coastguard Worker TQualifier qualifier = symbol->variable().getType().getQualifier();
423*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
424*8975f5c5SAndroid Build Coastguard Worker
425*8975f5c5SAndroid Build Coastguard Worker if (IsVaryingIn(qualifier))
426*8975f5c5SAndroid Build Coastguard Worker {
427*8975f5c5SAndroid Build Coastguard Worker if (interfaceBlock)
428*8975f5c5SAndroid Build Coastguard Worker {
429*8975f5c5SAndroid Build Coastguard Worker var = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
430*8975f5c5SAndroid Build Coastguard Worker }
431*8975f5c5SAndroid Build Coastguard Worker else
432*8975f5c5SAndroid Build Coastguard Worker {
433*8975f5c5SAndroid Build Coastguard Worker var = FindVariable(symbolName, mInputVaryings);
434*8975f5c5SAndroid Build Coastguard Worker }
435*8975f5c5SAndroid Build Coastguard Worker }
436*8975f5c5SAndroid Build Coastguard Worker else if (IsVaryingOut(qualifier))
437*8975f5c5SAndroid Build Coastguard Worker {
438*8975f5c5SAndroid Build Coastguard Worker if (interfaceBlock)
439*8975f5c5SAndroid Build Coastguard Worker {
440*8975f5c5SAndroid Build Coastguard Worker var = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
441*8975f5c5SAndroid Build Coastguard Worker }
442*8975f5c5SAndroid Build Coastguard Worker else
443*8975f5c5SAndroid Build Coastguard Worker {
444*8975f5c5SAndroid Build Coastguard Worker var = FindVariable(symbolName, mOutputVaryings);
445*8975f5c5SAndroid Build Coastguard Worker }
446*8975f5c5SAndroid Build Coastguard Worker }
447*8975f5c5SAndroid Build Coastguard Worker else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
448*8975f5c5SAndroid Build Coastguard Worker {
449*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
450*8975f5c5SAndroid Build Coastguard Worker }
451*8975f5c5SAndroid Build Coastguard Worker else if (symbolName == "gl_DepthRange")
452*8975f5c5SAndroid Build Coastguard Worker {
453*8975f5c5SAndroid Build Coastguard Worker ASSERT(qualifier == EvqUniform);
454*8975f5c5SAndroid Build Coastguard Worker
455*8975f5c5SAndroid Build Coastguard Worker if (!mDepthRangeAdded)
456*8975f5c5SAndroid Build Coastguard Worker {
457*8975f5c5SAndroid Build Coastguard Worker ShaderVariable info;
458*8975f5c5SAndroid Build Coastguard Worker const char kName[] = "gl_DepthRange";
459*8975f5c5SAndroid Build Coastguard Worker info.name = kName;
460*8975f5c5SAndroid Build Coastguard Worker info.mappedName = kName;
461*8975f5c5SAndroid Build Coastguard Worker info.type = GL_NONE;
462*8975f5c5SAndroid Build Coastguard Worker info.precision = GL_NONE;
463*8975f5c5SAndroid Build Coastguard Worker info.staticUse = true;
464*8975f5c5SAndroid Build Coastguard Worker info.active = true;
465*8975f5c5SAndroid Build Coastguard Worker
466*8975f5c5SAndroid Build Coastguard Worker ShaderVariable nearInfo(GL_FLOAT);
467*8975f5c5SAndroid Build Coastguard Worker const char kNearName[] = "near";
468*8975f5c5SAndroid Build Coastguard Worker nearInfo.name = kNearName;
469*8975f5c5SAndroid Build Coastguard Worker nearInfo.mappedName = kNearName;
470*8975f5c5SAndroid Build Coastguard Worker nearInfo.precision = GL_HIGH_FLOAT;
471*8975f5c5SAndroid Build Coastguard Worker nearInfo.staticUse = true;
472*8975f5c5SAndroid Build Coastguard Worker nearInfo.active = true;
473*8975f5c5SAndroid Build Coastguard Worker
474*8975f5c5SAndroid Build Coastguard Worker ShaderVariable farInfo(GL_FLOAT);
475*8975f5c5SAndroid Build Coastguard Worker const char kFarName[] = "far";
476*8975f5c5SAndroid Build Coastguard Worker farInfo.name = kFarName;
477*8975f5c5SAndroid Build Coastguard Worker farInfo.mappedName = kFarName;
478*8975f5c5SAndroid Build Coastguard Worker farInfo.precision = GL_HIGH_FLOAT;
479*8975f5c5SAndroid Build Coastguard Worker farInfo.staticUse = true;
480*8975f5c5SAndroid Build Coastguard Worker farInfo.active = true;
481*8975f5c5SAndroid Build Coastguard Worker
482*8975f5c5SAndroid Build Coastguard Worker ShaderVariable diffInfo(GL_FLOAT);
483*8975f5c5SAndroid Build Coastguard Worker const char kDiffName[] = "diff";
484*8975f5c5SAndroid Build Coastguard Worker diffInfo.name = kDiffName;
485*8975f5c5SAndroid Build Coastguard Worker diffInfo.mappedName = kDiffName;
486*8975f5c5SAndroid Build Coastguard Worker diffInfo.precision = GL_HIGH_FLOAT;
487*8975f5c5SAndroid Build Coastguard Worker diffInfo.staticUse = true;
488*8975f5c5SAndroid Build Coastguard Worker diffInfo.active = true;
489*8975f5c5SAndroid Build Coastguard Worker
490*8975f5c5SAndroid Build Coastguard Worker info.fields.push_back(nearInfo);
491*8975f5c5SAndroid Build Coastguard Worker info.fields.push_back(farInfo);
492*8975f5c5SAndroid Build Coastguard Worker info.fields.push_back(diffInfo);
493*8975f5c5SAndroid Build Coastguard Worker
494*8975f5c5SAndroid Build Coastguard Worker mUniforms->push_back(info);
495*8975f5c5SAndroid Build Coastguard Worker mDepthRangeAdded = true;
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker }
498*8975f5c5SAndroid Build Coastguard Worker else if (symbolName == "gl_NumSamples")
499*8975f5c5SAndroid Build Coastguard Worker {
500*8975f5c5SAndroid Build Coastguard Worker ASSERT(qualifier == EvqUniform);
501*8975f5c5SAndroid Build Coastguard Worker
502*8975f5c5SAndroid Build Coastguard Worker if (!mNumSamplesAdded)
503*8975f5c5SAndroid Build Coastguard Worker {
504*8975f5c5SAndroid Build Coastguard Worker ShaderVariable info;
505*8975f5c5SAndroid Build Coastguard Worker const char kName[] = "gl_NumSamples";
506*8975f5c5SAndroid Build Coastguard Worker info.name = kName;
507*8975f5c5SAndroid Build Coastguard Worker info.mappedName = kName;
508*8975f5c5SAndroid Build Coastguard Worker info.type = GL_INT;
509*8975f5c5SAndroid Build Coastguard Worker info.precision = GL_LOW_INT;
510*8975f5c5SAndroid Build Coastguard Worker info.staticUse = true;
511*8975f5c5SAndroid Build Coastguard Worker info.active = true;
512*8975f5c5SAndroid Build Coastguard Worker
513*8975f5c5SAndroid Build Coastguard Worker mUniforms->push_back(info);
514*8975f5c5SAndroid Build Coastguard Worker mNumSamplesAdded = true;
515*8975f5c5SAndroid Build Coastguard Worker }
516*8975f5c5SAndroid Build Coastguard Worker }
517*8975f5c5SAndroid Build Coastguard Worker else
518*8975f5c5SAndroid Build Coastguard Worker {
519*8975f5c5SAndroid Build Coastguard Worker switch (qualifier)
520*8975f5c5SAndroid Build Coastguard Worker {
521*8975f5c5SAndroid Build Coastguard Worker case EvqAttribute:
522*8975f5c5SAndroid Build Coastguard Worker case EvqVertexIn:
523*8975f5c5SAndroid Build Coastguard Worker var = FindVariable(symbolName, mAttribs);
524*8975f5c5SAndroid Build Coastguard Worker break;
525*8975f5c5SAndroid Build Coastguard Worker case EvqFragmentOut:
526*8975f5c5SAndroid Build Coastguard Worker case EvqFragmentInOut:
527*8975f5c5SAndroid Build Coastguard Worker var = FindVariable(symbolName, mOutputVariables);
528*8975f5c5SAndroid Build Coastguard Worker var->isFragmentInOut = qualifier == EvqFragmentInOut;
529*8975f5c5SAndroid Build Coastguard Worker break;
530*8975f5c5SAndroid Build Coastguard Worker case EvqUniform:
531*8975f5c5SAndroid Build Coastguard Worker {
532*8975f5c5SAndroid Build Coastguard Worker if (interfaceBlock)
533*8975f5c5SAndroid Build Coastguard Worker {
534*8975f5c5SAndroid Build Coastguard Worker var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks);
535*8975f5c5SAndroid Build Coastguard Worker }
536*8975f5c5SAndroid Build Coastguard Worker else
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker var = FindVariable(symbolName, mUniforms);
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker
541*8975f5c5SAndroid Build Coastguard Worker // It's an internal error to reference an undefined user uniform
542*8975f5c5SAndroid Build Coastguard Worker ASSERT(!gl::IsBuiltInName(symbolName.data()) || var);
543*8975f5c5SAndroid Build Coastguard Worker }
544*8975f5c5SAndroid Build Coastguard Worker break;
545*8975f5c5SAndroid Build Coastguard Worker case EvqBuffer:
546*8975f5c5SAndroid Build Coastguard Worker {
547*8975f5c5SAndroid Build Coastguard Worker var =
548*8975f5c5SAndroid Build Coastguard Worker FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
549*8975f5c5SAndroid Build Coastguard Worker }
550*8975f5c5SAndroid Build Coastguard Worker break;
551*8975f5c5SAndroid Build Coastguard Worker case EvqFragCoord:
552*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mFragCoordAdded, mInputVaryings);
553*8975f5c5SAndroid Build Coastguard Worker return;
554*8975f5c5SAndroid Build Coastguard Worker case EvqFrontFacing:
555*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mFrontFacingAdded, mInputVaryings);
556*8975f5c5SAndroid Build Coastguard Worker return;
557*8975f5c5SAndroid Build Coastguard Worker case EvqHelperInvocation:
558*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mHelperInvocationAdded,
559*8975f5c5SAndroid Build Coastguard Worker mInputVaryings);
560*8975f5c5SAndroid Build Coastguard Worker return;
561*8975f5c5SAndroid Build Coastguard Worker case EvqPointCoord:
562*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPointCoordAdded, mInputVaryings);
563*8975f5c5SAndroid Build Coastguard Worker return;
564*8975f5c5SAndroid Build Coastguard Worker case EvqNumWorkGroups:
565*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mNumWorkGroupsAdded);
566*8975f5c5SAndroid Build Coastguard Worker return;
567*8975f5c5SAndroid Build Coastguard Worker case EvqWorkGroupID:
568*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mWorkGroupIDAdded);
569*8975f5c5SAndroid Build Coastguard Worker return;
570*8975f5c5SAndroid Build Coastguard Worker case EvqLocalInvocationID:
571*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mLocalInvocationIDAdded);
572*8975f5c5SAndroid Build Coastguard Worker return;
573*8975f5c5SAndroid Build Coastguard Worker case EvqGlobalInvocationID:
574*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mGlobalInvocationIDAdded);
575*8975f5c5SAndroid Build Coastguard Worker return;
576*8975f5c5SAndroid Build Coastguard Worker case EvqLocalInvocationIndex:
577*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mLocalInvocationIndexAdded);
578*8975f5c5SAndroid Build Coastguard Worker return;
579*8975f5c5SAndroid Build Coastguard Worker case EvqInstanceID:
580*8975f5c5SAndroid Build Coastguard Worker // Whenever the initializeBuiltinsForInstancedMultiview option is set,
581*8975f5c5SAndroid Build Coastguard Worker // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
582*8975f5c5SAndroid Build Coastguard Worker // InstanceID. Note that gl_InstanceID is not added to the symbol table for ESSL1
583*8975f5c5SAndroid Build Coastguard Worker // shaders.
584*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mInstanceIDAdded);
585*8975f5c5SAndroid Build Coastguard Worker return;
586*8975f5c5SAndroid Build Coastguard Worker case EvqVertexID:
587*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mVertexIDAdded);
588*8975f5c5SAndroid Build Coastguard Worker return;
589*8975f5c5SAndroid Build Coastguard Worker case EvqPosition:
590*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPositionAdded, mOutputVaryings);
591*8975f5c5SAndroid Build Coastguard Worker return;
592*8975f5c5SAndroid Build Coastguard Worker case EvqPointSize:
593*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPointSizeAdded, mOutputVaryings);
594*8975f5c5SAndroid Build Coastguard Worker return;
595*8975f5c5SAndroid Build Coastguard Worker case EvqDrawID:
596*8975f5c5SAndroid Build Coastguard Worker recordBuiltInAttributeUsed(symbol->variable(), &mDrawIDAdded);
597*8975f5c5SAndroid Build Coastguard Worker return;
598*8975f5c5SAndroid Build Coastguard Worker case EvqLastFragData:
599*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mLastFragDataAdded, mInputVaryings);
600*8975f5c5SAndroid Build Coastguard Worker return;
601*8975f5c5SAndroid Build Coastguard Worker case EvqLastFragColor:
602*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mLastFragColorAdded, mInputVaryings);
603*8975f5c5SAndroid Build Coastguard Worker return;
604*8975f5c5SAndroid Build Coastguard Worker case EvqFragColor:
605*8975f5c5SAndroid Build Coastguard Worker recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragColorAdded);
606*8975f5c5SAndroid Build Coastguard Worker return;
607*8975f5c5SAndroid Build Coastguard Worker case EvqFragData:
608*8975f5c5SAndroid Build Coastguard Worker recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDataAdded);
609*8975f5c5SAndroid Build Coastguard Worker return;
610*8975f5c5SAndroid Build Coastguard Worker case EvqFragDepth:
611*8975f5c5SAndroid Build Coastguard Worker recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthAdded);
612*8975f5c5SAndroid Build Coastguard Worker return;
613*8975f5c5SAndroid Build Coastguard Worker case EvqSecondaryFragColorEXT:
614*8975f5c5SAndroid Build Coastguard Worker recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragColorEXTAdded);
615*8975f5c5SAndroid Build Coastguard Worker return;
616*8975f5c5SAndroid Build Coastguard Worker case EvqSecondaryFragDataEXT:
617*8975f5c5SAndroid Build Coastguard Worker recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragDataEXTAdded);
618*8975f5c5SAndroid Build Coastguard Worker return;
619*8975f5c5SAndroid Build Coastguard Worker case EvqInvocationID:
620*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mInvocationIDAdded, mInputVaryings);
621*8975f5c5SAndroid Build Coastguard Worker break;
622*8975f5c5SAndroid Build Coastguard Worker case EvqPrimitiveIDIn:
623*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDInAdded, mInputVaryings);
624*8975f5c5SAndroid Build Coastguard Worker break;
625*8975f5c5SAndroid Build Coastguard Worker case EvqPrimitiveID:
626*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_GEOMETRY_SHADER_EXT)
627*8975f5c5SAndroid Build Coastguard Worker {
628*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
629*8975f5c5SAndroid Build Coastguard Worker mOutputVaryings);
630*8975f5c5SAndroid Build Coastguard Worker }
631*8975f5c5SAndroid Build Coastguard Worker else
632*8975f5c5SAndroid Build Coastguard Worker {
633*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType == GL_FRAGMENT_SHADER ||
634*8975f5c5SAndroid Build Coastguard Worker mShaderType == GL_TESS_CONTROL_SHADER ||
635*8975f5c5SAndroid Build Coastguard Worker mShaderType == GL_TESS_EVALUATION_SHADER);
636*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
637*8975f5c5SAndroid Build Coastguard Worker mInputVaryings);
638*8975f5c5SAndroid Build Coastguard Worker }
639*8975f5c5SAndroid Build Coastguard Worker break;
640*8975f5c5SAndroid Build Coastguard Worker case EvqLayerOut:
641*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_GEOMETRY_SHADER_EXT)
642*8975f5c5SAndroid Build Coastguard Worker {
643*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mOutputVaryings);
644*8975f5c5SAndroid Build Coastguard Worker }
645*8975f5c5SAndroid Build Coastguard Worker else
646*8975f5c5SAndroid Build Coastguard Worker {
647*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType == GL_VERTEX_SHADER &&
648*8975f5c5SAndroid Build Coastguard Worker (IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview2) ||
649*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview)));
650*8975f5c5SAndroid Build Coastguard Worker }
651*8975f5c5SAndroid Build Coastguard Worker break;
652*8975f5c5SAndroid Build Coastguard Worker case EvqLayerIn:
653*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType == GL_FRAGMENT_SHADER);
654*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mInputVaryings);
655*8975f5c5SAndroid Build Coastguard Worker break;
656*8975f5c5SAndroid Build Coastguard Worker case EvqShared:
657*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_COMPUTE_SHADER)
658*8975f5c5SAndroid Build Coastguard Worker {
659*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mSharedVariableAdded,
660*8975f5c5SAndroid Build Coastguard Worker mSharedVariables);
661*8975f5c5SAndroid Build Coastguard Worker }
662*8975f5c5SAndroid Build Coastguard Worker break;
663*8975f5c5SAndroid Build Coastguard Worker case EvqClipDistance:
664*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(
665*8975f5c5SAndroid Build Coastguard Worker symbol->variable(), &mClipDistanceAdded,
666*8975f5c5SAndroid Build Coastguard Worker mShaderType == GL_FRAGMENT_SHADER ? mInputVaryings : mOutputVaryings);
667*8975f5c5SAndroid Build Coastguard Worker return;
668*8975f5c5SAndroid Build Coastguard Worker case EvqCullDistance:
669*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(
670*8975f5c5SAndroid Build Coastguard Worker symbol->variable(), &mCullDistanceAdded,
671*8975f5c5SAndroid Build Coastguard Worker mShaderType == GL_FRAGMENT_SHADER ? mInputVaryings : mOutputVaryings);
672*8975f5c5SAndroid Build Coastguard Worker return;
673*8975f5c5SAndroid Build Coastguard Worker case EvqSampleID:
674*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mSampleIDAdded, mInputVaryings);
675*8975f5c5SAndroid Build Coastguard Worker return;
676*8975f5c5SAndroid Build Coastguard Worker case EvqSamplePosition:
677*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mSamplePositionAdded, mInputVaryings);
678*8975f5c5SAndroid Build Coastguard Worker return;
679*8975f5c5SAndroid Build Coastguard Worker case EvqSampleMaskIn:
680*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mSampleMaskInAdded, mInputVaryings);
681*8975f5c5SAndroid Build Coastguard Worker return;
682*8975f5c5SAndroid Build Coastguard Worker case EvqSampleMask:
683*8975f5c5SAndroid Build Coastguard Worker recordBuiltInFragmentOutputUsed(symbol->variable(), &mSampleMaskAdded);
684*8975f5c5SAndroid Build Coastguard Worker return;
685*8975f5c5SAndroid Build Coastguard Worker case EvqPatchVerticesIn:
686*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mPatchVerticesInAdded,
687*8975f5c5SAndroid Build Coastguard Worker mInputVaryings);
688*8975f5c5SAndroid Build Coastguard Worker break;
689*8975f5c5SAndroid Build Coastguard Worker case EvqTessCoord:
690*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mTessCoordAdded, mInputVaryings);
691*8975f5c5SAndroid Build Coastguard Worker break;
692*8975f5c5SAndroid Build Coastguard Worker case EvqTessLevelOuter:
693*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_TESS_CONTROL_SHADER)
694*8975f5c5SAndroid Build Coastguard Worker {
695*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelOuterAdded,
696*8975f5c5SAndroid Build Coastguard Worker mOutputVaryings);
697*8975f5c5SAndroid Build Coastguard Worker }
698*8975f5c5SAndroid Build Coastguard Worker else
699*8975f5c5SAndroid Build Coastguard Worker {
700*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType == GL_TESS_EVALUATION_SHADER);
701*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelOuterAdded,
702*8975f5c5SAndroid Build Coastguard Worker mInputVaryings);
703*8975f5c5SAndroid Build Coastguard Worker }
704*8975f5c5SAndroid Build Coastguard Worker break;
705*8975f5c5SAndroid Build Coastguard Worker case EvqTessLevelInner:
706*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_TESS_CONTROL_SHADER)
707*8975f5c5SAndroid Build Coastguard Worker {
708*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelInnerAdded,
709*8975f5c5SAndroid Build Coastguard Worker mOutputVaryings);
710*8975f5c5SAndroid Build Coastguard Worker }
711*8975f5c5SAndroid Build Coastguard Worker else
712*8975f5c5SAndroid Build Coastguard Worker {
713*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType == GL_TESS_EVALUATION_SHADER);
714*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelInnerAdded,
715*8975f5c5SAndroid Build Coastguard Worker mInputVaryings);
716*8975f5c5SAndroid Build Coastguard Worker }
717*8975f5c5SAndroid Build Coastguard Worker break;
718*8975f5c5SAndroid Build Coastguard Worker case EvqBoundingBox:
719*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbol->variable(), &mBoundingBoxAdded, mOutputVaryings);
720*8975f5c5SAndroid Build Coastguard Worker break;
721*8975f5c5SAndroid Build Coastguard Worker default:
722*8975f5c5SAndroid Build Coastguard Worker break;
723*8975f5c5SAndroid Build Coastguard Worker }
724*8975f5c5SAndroid Build Coastguard Worker }
725*8975f5c5SAndroid Build Coastguard Worker if (var)
726*8975f5c5SAndroid Build Coastguard Worker {
727*8975f5c5SAndroid Build Coastguard Worker MarkActive(var);
728*8975f5c5SAndroid Build Coastguard Worker }
729*8975f5c5SAndroid Build Coastguard Worker }
730*8975f5c5SAndroid Build Coastguard Worker
setFieldOrVariableProperties(const TType & type,bool staticUse,bool isShaderIOBlock,bool isPatch,ShaderVariable * variableOut) const731*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
732*8975f5c5SAndroid Build Coastguard Worker bool staticUse,
733*8975f5c5SAndroid Build Coastguard Worker bool isShaderIOBlock,
734*8975f5c5SAndroid Build Coastguard Worker bool isPatch,
735*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *variableOut) const
736*8975f5c5SAndroid Build Coastguard Worker {
737*8975f5c5SAndroid Build Coastguard Worker ASSERT(variableOut);
738*8975f5c5SAndroid Build Coastguard Worker
739*8975f5c5SAndroid Build Coastguard Worker variableOut->staticUse = staticUse;
740*8975f5c5SAndroid Build Coastguard Worker variableOut->isShaderIOBlock = isShaderIOBlock;
741*8975f5c5SAndroid Build Coastguard Worker variableOut->isPatch = isPatch;
742*8975f5c5SAndroid Build Coastguard Worker
743*8975f5c5SAndroid Build Coastguard Worker const TStructure *structure = type.getStruct();
744*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
745*8975f5c5SAndroid Build Coastguard Worker if (structure)
746*8975f5c5SAndroid Build Coastguard Worker {
747*8975f5c5SAndroid Build Coastguard Worker // Structures use a NONE type that isn't exposed outside ANGLE.
748*8975f5c5SAndroid Build Coastguard Worker variableOut->type = GL_NONE;
749*8975f5c5SAndroid Build Coastguard Worker // Anonymous structs are given name from AngleInternal namespace.
750*8975f5c5SAndroid Build Coastguard Worker if (structure->symbolType() != SymbolType::Empty &&
751*8975f5c5SAndroid Build Coastguard Worker structure->symbolType() != SymbolType::AngleInternal)
752*8975f5c5SAndroid Build Coastguard Worker {
753*8975f5c5SAndroid Build Coastguard Worker variableOut->structOrBlockName = structure->name().data();
754*8975f5c5SAndroid Build Coastguard Worker }
755*8975f5c5SAndroid Build Coastguard Worker
756*8975f5c5SAndroid Build Coastguard Worker const TFieldList &fields = structure->fields();
757*8975f5c5SAndroid Build Coastguard Worker
758*8975f5c5SAndroid Build Coastguard Worker for (const TField *field : fields)
759*8975f5c5SAndroid Build Coastguard Worker {
760*8975f5c5SAndroid Build Coastguard Worker // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
761*8975f5c5SAndroid Build Coastguard Worker // ShaderVariable objects.
762*8975f5c5SAndroid Build Coastguard Worker ShaderVariable fieldVariable;
763*8975f5c5SAndroid Build Coastguard Worker setFieldProperties(*field->type(), field->name(), staticUse, isShaderIOBlock, isPatch,
764*8975f5c5SAndroid Build Coastguard Worker field->symbolType(), &fieldVariable);
765*8975f5c5SAndroid Build Coastguard Worker variableOut->fields.push_back(fieldVariable);
766*8975f5c5SAndroid Build Coastguard Worker }
767*8975f5c5SAndroid Build Coastguard Worker }
768*8975f5c5SAndroid Build Coastguard Worker else if (interfaceBlock && isShaderIOBlock)
769*8975f5c5SAndroid Build Coastguard Worker {
770*8975f5c5SAndroid Build Coastguard Worker const bool isPerVertex = (interfaceBlock->name() == "gl_PerVertex");
771*8975f5c5SAndroid Build Coastguard Worker variableOut->type = GL_NONE;
772*8975f5c5SAndroid Build Coastguard Worker if (interfaceBlock->symbolType() != SymbolType::Empty)
773*8975f5c5SAndroid Build Coastguard Worker {
774*8975f5c5SAndroid Build Coastguard Worker variableOut->structOrBlockName = interfaceBlock->name().data();
775*8975f5c5SAndroid Build Coastguard Worker variableOut->mappedStructOrBlockName =
776*8975f5c5SAndroid Build Coastguard Worker isPerVertex ? interfaceBlock->name().data()
777*8975f5c5SAndroid Build Coastguard Worker : HashName(interfaceBlock->name(), mHashFunction, nullptr).data();
778*8975f5c5SAndroid Build Coastguard Worker }
779*8975f5c5SAndroid Build Coastguard Worker const TFieldList &fields = interfaceBlock->fields();
780*8975f5c5SAndroid Build Coastguard Worker for (const TField *field : fields)
781*8975f5c5SAndroid Build Coastguard Worker {
782*8975f5c5SAndroid Build Coastguard Worker ShaderVariable fieldVariable;
783*8975f5c5SAndroid Build Coastguard Worker
784*8975f5c5SAndroid Build Coastguard Worker setFieldProperties(*field->type(), field->name(), staticUse, true, isPatch,
785*8975f5c5SAndroid Build Coastguard Worker field->symbolType(), &fieldVariable);
786*8975f5c5SAndroid Build Coastguard Worker fieldVariable.isShaderIOBlock = true;
787*8975f5c5SAndroid Build Coastguard Worker variableOut->fields.push_back(fieldVariable);
788*8975f5c5SAndroid Build Coastguard Worker }
789*8975f5c5SAndroid Build Coastguard Worker }
790*8975f5c5SAndroid Build Coastguard Worker else
791*8975f5c5SAndroid Build Coastguard Worker {
792*8975f5c5SAndroid Build Coastguard Worker variableOut->type = GLVariableType(type);
793*8975f5c5SAndroid Build Coastguard Worker variableOut->precision = GLVariablePrecision(type);
794*8975f5c5SAndroid Build Coastguard Worker }
795*8975f5c5SAndroid Build Coastguard Worker
796*8975f5c5SAndroid Build Coastguard Worker const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
797*8975f5c5SAndroid Build Coastguard Worker if (!arraySizes.empty())
798*8975f5c5SAndroid Build Coastguard Worker {
799*8975f5c5SAndroid Build Coastguard Worker variableOut->arraySizes.assign(arraySizes.begin(), arraySizes.end());
800*8975f5c5SAndroid Build Coastguard Worker
801*8975f5c5SAndroid Build Coastguard Worker if (arraySizes[0] == 0)
802*8975f5c5SAndroid Build Coastguard Worker {
803*8975f5c5SAndroid Build Coastguard Worker // Tessellation Control & Evaluation shader inputs:
804*8975f5c5SAndroid Build Coastguard Worker // Declaring an array size is optional. If no size is specified, it will be taken from
805*8975f5c5SAndroid Build Coastguard Worker // the implementation-dependent maximum patch size (gl_MaxPatchVertices).
806*8975f5c5SAndroid Build Coastguard Worker if (type.getQualifier() == EvqTessControlIn ||
807*8975f5c5SAndroid Build Coastguard Worker type.getQualifier() == EvqTessEvaluationIn)
808*8975f5c5SAndroid Build Coastguard Worker {
809*8975f5c5SAndroid Build Coastguard Worker variableOut->arraySizes[0] = mResources.MaxPatchVertices;
810*8975f5c5SAndroid Build Coastguard Worker }
811*8975f5c5SAndroid Build Coastguard Worker
812*8975f5c5SAndroid Build Coastguard Worker // Tessellation Control shader outputs:
813*8975f5c5SAndroid Build Coastguard Worker // Declaring an array size is optional. If no size is specified, it will be taken from
814*8975f5c5SAndroid Build Coastguard Worker // output patch size declared in the shader.
815*8975f5c5SAndroid Build Coastguard Worker if (type.getQualifier() == EvqTessControlOut)
816*8975f5c5SAndroid Build Coastguard Worker {
817*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTessControlShaderOutputVertices > 0);
818*8975f5c5SAndroid Build Coastguard Worker variableOut->arraySizes[0] = mTessControlShaderOutputVertices;
819*8975f5c5SAndroid Build Coastguard Worker }
820*8975f5c5SAndroid Build Coastguard Worker }
821*8975f5c5SAndroid Build Coastguard Worker }
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker
setFieldProperties(const TType & type,const ImmutableString & name,bool staticUse,bool isShaderIOBlock,bool isPatch,SymbolType symbolType,ShaderVariable * variableOut) const824*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::setFieldProperties(const TType &type,
825*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &name,
826*8975f5c5SAndroid Build Coastguard Worker bool staticUse,
827*8975f5c5SAndroid Build Coastguard Worker bool isShaderIOBlock,
828*8975f5c5SAndroid Build Coastguard Worker bool isPatch,
829*8975f5c5SAndroid Build Coastguard Worker SymbolType symbolType,
830*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *variableOut) const
831*8975f5c5SAndroid Build Coastguard Worker {
832*8975f5c5SAndroid Build Coastguard Worker ASSERT(variableOut);
833*8975f5c5SAndroid Build Coastguard Worker setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
834*8975f5c5SAndroid Build Coastguard Worker variableOut->name.assign(name.data(), name.length());
835*8975f5c5SAndroid Build Coastguard Worker variableOut->mappedName = (symbolType == SymbolType::BuiltIn)
836*8975f5c5SAndroid Build Coastguard Worker ? name.data()
837*8975f5c5SAndroid Build Coastguard Worker : HashName(name, mHashFunction, nullptr).data();
838*8975f5c5SAndroid Build Coastguard Worker }
839*8975f5c5SAndroid Build Coastguard Worker
setCommonVariableProperties(const TType & type,const TVariable & variable,ShaderVariable * variableOut) const840*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
841*8975f5c5SAndroid Build Coastguard Worker const TVariable &variable,
842*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *variableOut) const
843*8975f5c5SAndroid Build Coastguard Worker {
844*8975f5c5SAndroid Build Coastguard Worker ASSERT(variableOut);
845*8975f5c5SAndroid Build Coastguard Worker ASSERT(type.getInterfaceBlock() == nullptr || IsShaderIoBlock(type.getQualifier()) ||
846*8975f5c5SAndroid Build Coastguard Worker type.getQualifier() == EvqPatchIn || type.getQualifier() == EvqPatchOut);
847*8975f5c5SAndroid Build Coastguard Worker
848*8975f5c5SAndroid Build Coastguard Worker const bool staticUse = mSymbolTable->isStaticallyUsed(variable);
849*8975f5c5SAndroid Build Coastguard Worker const bool isShaderIOBlock = type.getInterfaceBlock() != nullptr;
850*8975f5c5SAndroid Build Coastguard Worker const bool isPatch = type.getQualifier() == EvqPatchIn || type.getQualifier() == EvqPatchOut;
851*8975f5c5SAndroid Build Coastguard Worker
852*8975f5c5SAndroid Build Coastguard Worker setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
853*8975f5c5SAndroid Build Coastguard Worker
854*8975f5c5SAndroid Build Coastguard Worker const bool isNamed = variable.symbolType() != SymbolType::Empty;
855*8975f5c5SAndroid Build Coastguard Worker
856*8975f5c5SAndroid Build Coastguard Worker ASSERT(isNamed || isShaderIOBlock);
857*8975f5c5SAndroid Build Coastguard Worker if (isNamed)
858*8975f5c5SAndroid Build Coastguard Worker {
859*8975f5c5SAndroid Build Coastguard Worker variableOut->name.assign(variable.name().data(), variable.name().length());
860*8975f5c5SAndroid Build Coastguard Worker variableOut->mappedName = getMappedName(&variable);
861*8975f5c5SAndroid Build Coastguard Worker }
862*8975f5c5SAndroid Build Coastguard Worker
863*8975f5c5SAndroid Build Coastguard Worker // For I/O blocks, additionally store the name of the block as blockName. If the variable is
864*8975f5c5SAndroid Build Coastguard Worker // unnamed, this name will be used instead for the purpose of interface matching.
865*8975f5c5SAndroid Build Coastguard Worker if (isShaderIOBlock)
866*8975f5c5SAndroid Build Coastguard Worker {
867*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
868*8975f5c5SAndroid Build Coastguard Worker ASSERT(interfaceBlock);
869*8975f5c5SAndroid Build Coastguard Worker
870*8975f5c5SAndroid Build Coastguard Worker variableOut->structOrBlockName.assign(interfaceBlock->name().data(),
871*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->name().length());
872*8975f5c5SAndroid Build Coastguard Worker variableOut->mappedStructOrBlockName =
873*8975f5c5SAndroid Build Coastguard Worker HashName(interfaceBlock->name(), mHashFunction, nullptr).data();
874*8975f5c5SAndroid Build Coastguard Worker variableOut->isShaderIOBlock = true;
875*8975f5c5SAndroid Build Coastguard Worker }
876*8975f5c5SAndroid Build Coastguard Worker }
877*8975f5c5SAndroid Build Coastguard Worker
recordAttribute(const TIntermSymbol & variable) const878*8975f5c5SAndroid Build Coastguard Worker ShaderVariable CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
879*8975f5c5SAndroid Build Coastguard Worker {
880*8975f5c5SAndroid Build Coastguard Worker const TType &type = variable.getType();
881*8975f5c5SAndroid Build Coastguard Worker ASSERT(!type.getStruct());
882*8975f5c5SAndroid Build Coastguard Worker
883*8975f5c5SAndroid Build Coastguard Worker ShaderVariable attribute;
884*8975f5c5SAndroid Build Coastguard Worker setCommonVariableProperties(type, variable.variable(), &attribute);
885*8975f5c5SAndroid Build Coastguard Worker
886*8975f5c5SAndroid Build Coastguard Worker attribute.location = type.getLayoutQualifier().location;
887*8975f5c5SAndroid Build Coastguard Worker return attribute;
888*8975f5c5SAndroid Build Coastguard Worker }
889*8975f5c5SAndroid Build Coastguard Worker
recordOutputVariable(const TIntermSymbol & variable) const890*8975f5c5SAndroid Build Coastguard Worker ShaderVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
891*8975f5c5SAndroid Build Coastguard Worker {
892*8975f5c5SAndroid Build Coastguard Worker const TType &type = variable.getType();
893*8975f5c5SAndroid Build Coastguard Worker ASSERT(!type.getStruct());
894*8975f5c5SAndroid Build Coastguard Worker
895*8975f5c5SAndroid Build Coastguard Worker ShaderVariable outputVariable;
896*8975f5c5SAndroid Build Coastguard Worker setCommonVariableProperties(type, variable.variable(), &outputVariable);
897*8975f5c5SAndroid Build Coastguard Worker
898*8975f5c5SAndroid Build Coastguard Worker outputVariable.location = type.getLayoutQualifier().location;
899*8975f5c5SAndroid Build Coastguard Worker outputVariable.index = type.getLayoutQualifier().index;
900*8975f5c5SAndroid Build Coastguard Worker outputVariable.yuv = type.getLayoutQualifier().yuv;
901*8975f5c5SAndroid Build Coastguard Worker return outputVariable;
902*8975f5c5SAndroid Build Coastguard Worker }
903*8975f5c5SAndroid Build Coastguard Worker
recordVarying(const TIntermSymbol & variable) const904*8975f5c5SAndroid Build Coastguard Worker ShaderVariable CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
905*8975f5c5SAndroid Build Coastguard Worker {
906*8975f5c5SAndroid Build Coastguard Worker const TType &type = variable.getType();
907*8975f5c5SAndroid Build Coastguard Worker
908*8975f5c5SAndroid Build Coastguard Worker ShaderVariable varying;
909*8975f5c5SAndroid Build Coastguard Worker setCommonVariableProperties(type, variable.variable(), &varying);
910*8975f5c5SAndroid Build Coastguard Worker varying.location = type.getLayoutQualifier().location;
911*8975f5c5SAndroid Build Coastguard Worker
912*8975f5c5SAndroid Build Coastguard Worker switch (type.getQualifier())
913*8975f5c5SAndroid Build Coastguard Worker {
914*8975f5c5SAndroid Build Coastguard Worker case EvqVaryingIn:
915*8975f5c5SAndroid Build Coastguard Worker case EvqVaryingOut:
916*8975f5c5SAndroid Build Coastguard Worker case EvqVertexOut:
917*8975f5c5SAndroid Build Coastguard Worker case EvqSmoothOut:
918*8975f5c5SAndroid Build Coastguard Worker case EvqFlatOut:
919*8975f5c5SAndroid Build Coastguard Worker case EvqNoPerspectiveOut:
920*8975f5c5SAndroid Build Coastguard Worker case EvqCentroidOut:
921*8975f5c5SAndroid Build Coastguard Worker case EvqSampleOut:
922*8975f5c5SAndroid Build Coastguard Worker case EvqNoPerspectiveCentroidOut:
923*8975f5c5SAndroid Build Coastguard Worker case EvqNoPerspectiveSampleOut:
924*8975f5c5SAndroid Build Coastguard Worker case EvqGeometryOut:
925*8975f5c5SAndroid Build Coastguard Worker if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant())
926*8975f5c5SAndroid Build Coastguard Worker {
927*8975f5c5SAndroid Build Coastguard Worker varying.isInvariant = true;
928*8975f5c5SAndroid Build Coastguard Worker }
929*8975f5c5SAndroid Build Coastguard Worker break;
930*8975f5c5SAndroid Build Coastguard Worker case EvqPatchIn:
931*8975f5c5SAndroid Build Coastguard Worker case EvqPatchOut:
932*8975f5c5SAndroid Build Coastguard Worker varying.isPatch = true;
933*8975f5c5SAndroid Build Coastguard Worker break;
934*8975f5c5SAndroid Build Coastguard Worker default:
935*8975f5c5SAndroid Build Coastguard Worker break;
936*8975f5c5SAndroid Build Coastguard Worker }
937*8975f5c5SAndroid Build Coastguard Worker
938*8975f5c5SAndroid Build Coastguard Worker varying.interpolation = GetInterpolationType(type.getQualifier());
939*8975f5c5SAndroid Build Coastguard Worker
940*8975f5c5SAndroid Build Coastguard Worker // Shader I/O block properties
941*8975f5c5SAndroid Build Coastguard Worker if (type.getBasicType() == EbtInterfaceBlock)
942*8975f5c5SAndroid Build Coastguard Worker {
943*8975f5c5SAndroid Build Coastguard Worker bool isBlockImplicitLocation = false;
944*8975f5c5SAndroid Build Coastguard Worker int location = type.getLayoutQualifier().location;
945*8975f5c5SAndroid Build Coastguard Worker
946*8975f5c5SAndroid Build Coastguard Worker // when a interface has not location in layout, assign to the zero.
947*8975f5c5SAndroid Build Coastguard Worker if (location < 0)
948*8975f5c5SAndroid Build Coastguard Worker {
949*8975f5c5SAndroid Build Coastguard Worker location = 0;
950*8975f5c5SAndroid Build Coastguard Worker isBlockImplicitLocation = true;
951*8975f5c5SAndroid Build Coastguard Worker }
952*8975f5c5SAndroid Build Coastguard Worker
953*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *blockType = type.getInterfaceBlock();
954*8975f5c5SAndroid Build Coastguard Worker ASSERT(blockType->fields().size() == varying.fields.size());
955*8975f5c5SAndroid Build Coastguard Worker
956*8975f5c5SAndroid Build Coastguard Worker for (size_t fieldIndex = 0; fieldIndex < varying.fields.size(); ++fieldIndex)
957*8975f5c5SAndroid Build Coastguard Worker {
958*8975f5c5SAndroid Build Coastguard Worker const TField *blockField = blockType->fields()[fieldIndex];
959*8975f5c5SAndroid Build Coastguard Worker ShaderVariable &fieldVariable = varying.fields[fieldIndex];
960*8975f5c5SAndroid Build Coastguard Worker const TType &fieldType = *blockField->type();
961*8975f5c5SAndroid Build Coastguard Worker
962*8975f5c5SAndroid Build Coastguard Worker fieldVariable.hasImplicitLocation = isBlockImplicitLocation;
963*8975f5c5SAndroid Build Coastguard Worker fieldVariable.isPatch = varying.isPatch;
964*8975f5c5SAndroid Build Coastguard Worker
965*8975f5c5SAndroid Build Coastguard Worker int fieldLocation = fieldType.getLayoutQualifier().location;
966*8975f5c5SAndroid Build Coastguard Worker if (fieldLocation >= 0)
967*8975f5c5SAndroid Build Coastguard Worker {
968*8975f5c5SAndroid Build Coastguard Worker fieldVariable.hasImplicitLocation = false;
969*8975f5c5SAndroid Build Coastguard Worker fieldVariable.location = fieldLocation;
970*8975f5c5SAndroid Build Coastguard Worker location = fieldLocation;
971*8975f5c5SAndroid Build Coastguard Worker }
972*8975f5c5SAndroid Build Coastguard Worker else
973*8975f5c5SAndroid Build Coastguard Worker {
974*8975f5c5SAndroid Build Coastguard Worker fieldVariable.location = location;
975*8975f5c5SAndroid Build Coastguard Worker location += fieldType.getLocationCount();
976*8975f5c5SAndroid Build Coastguard Worker }
977*8975f5c5SAndroid Build Coastguard Worker
978*8975f5c5SAndroid Build Coastguard Worker if (fieldType.getQualifier() != EvqGlobal)
979*8975f5c5SAndroid Build Coastguard Worker {
980*8975f5c5SAndroid Build Coastguard Worker fieldVariable.interpolation = GetFieldInterpolationType(fieldType.getQualifier());
981*8975f5c5SAndroid Build Coastguard Worker }
982*8975f5c5SAndroid Build Coastguard Worker }
983*8975f5c5SAndroid Build Coastguard Worker }
984*8975f5c5SAndroid Build Coastguard Worker
985*8975f5c5SAndroid Build Coastguard Worker return varying;
986*8975f5c5SAndroid Build Coastguard Worker }
987*8975f5c5SAndroid Build Coastguard Worker
recordInterfaceBlock(const char * instanceName,const TType & interfaceBlockType,InterfaceBlock * interfaceBlock) const988*8975f5c5SAndroid Build Coastguard Worker void CollectVariablesTraverser::recordInterfaceBlock(const char *instanceName,
989*8975f5c5SAndroid Build Coastguard Worker const TType &interfaceBlockType,
990*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *interfaceBlock) const
991*8975f5c5SAndroid Build Coastguard Worker {
992*8975f5c5SAndroid Build Coastguard Worker ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
993*8975f5c5SAndroid Build Coastguard Worker ASSERT(interfaceBlock);
994*8975f5c5SAndroid Build Coastguard Worker
995*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
996*8975f5c5SAndroid Build Coastguard Worker ASSERT(blockType);
997*8975f5c5SAndroid Build Coastguard Worker
998*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->name = blockType->name().data();
999*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->mappedName = getMappedName(blockType);
1000*8975f5c5SAndroid Build Coastguard Worker
1001*8975f5c5SAndroid Build Coastguard Worker const bool isGLInBuiltin = (instanceName != nullptr) && strncmp(instanceName, "gl_in", 5u) == 0;
1002*8975f5c5SAndroid Build Coastguard Worker if (instanceName != nullptr)
1003*8975f5c5SAndroid Build Coastguard Worker {
1004*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->instanceName = instanceName;
1005*8975f5c5SAndroid Build Coastguard Worker const TSymbol *blockSymbol = nullptr;
1006*8975f5c5SAndroid Build Coastguard Worker if (isGLInBuiltin)
1007*8975f5c5SAndroid Build Coastguard Worker {
1008*8975f5c5SAndroid Build Coastguard Worker blockSymbol = mSymbolTable->getGlInVariableWithArraySize();
1009*8975f5c5SAndroid Build Coastguard Worker }
1010*8975f5c5SAndroid Build Coastguard Worker else
1011*8975f5c5SAndroid Build Coastguard Worker {
1012*8975f5c5SAndroid Build Coastguard Worker blockSymbol = mSymbolTable->findGlobal(ImmutableString(instanceName));
1013*8975f5c5SAndroid Build Coastguard Worker }
1014*8975f5c5SAndroid Build Coastguard Worker ASSERT(blockSymbol && blockSymbol->isVariable());
1015*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->staticUse =
1016*8975f5c5SAndroid Build Coastguard Worker mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(blockSymbol));
1017*8975f5c5SAndroid Build Coastguard Worker }
1018*8975f5c5SAndroid Build Coastguard Worker
1019*8975f5c5SAndroid Build Coastguard Worker ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
1020*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->arraySize =
1021*8975f5c5SAndroid Build Coastguard Worker interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
1022*8975f5c5SAndroid Build Coastguard Worker
1023*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
1024*8975f5c5SAndroid Build Coastguard Worker if (interfaceBlock->blockType == BlockType::kBlockUniform ||
1025*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->blockType == BlockType::kBlockBuffer)
1026*8975f5c5SAndroid Build Coastguard Worker {
1027*8975f5c5SAndroid Build Coastguard Worker // TODO(oetuaho): Remove setting isRowMajorLayout.
1028*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->isRowMajorLayout = false;
1029*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->binding = blockType->blockBinding();
1030*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage());
1031*8975f5c5SAndroid Build Coastguard Worker }
1032*8975f5c5SAndroid Build Coastguard Worker
1033*8975f5c5SAndroid Build Coastguard Worker // Consider an SSBO readonly if all its fields are readonly. Note that ANGLE doesn't keep the
1034*8975f5c5SAndroid Build Coastguard Worker // readonly qualifier applied to the interface block itself, but rather applies it to the
1035*8975f5c5SAndroid Build Coastguard Worker // fields.
1036*8975f5c5SAndroid Build Coastguard Worker ASSERT(!interfaceBlockType.getMemoryQualifier().readonly);
1037*8975f5c5SAndroid Build Coastguard Worker bool isReadOnly = true;
1038*8975f5c5SAndroid Build Coastguard Worker
1039*8975f5c5SAndroid Build Coastguard Worker // Gather field information
1040*8975f5c5SAndroid Build Coastguard Worker bool anyFieldStaticallyUsed = false;
1041*8975f5c5SAndroid Build Coastguard Worker
1042*8975f5c5SAndroid Build Coastguard Worker for (const TField *field : blockType->fields())
1043*8975f5c5SAndroid Build Coastguard Worker {
1044*8975f5c5SAndroid Build Coastguard Worker const TType &fieldType = *field->type();
1045*8975f5c5SAndroid Build Coastguard Worker
1046*8975f5c5SAndroid Build Coastguard Worker bool staticUse = false;
1047*8975f5c5SAndroid Build Coastguard Worker if (instanceName == nullptr)
1048*8975f5c5SAndroid Build Coastguard Worker {
1049*8975f5c5SAndroid Build Coastguard Worker // Static use of individual fields has been recorded, since they are present in the
1050*8975f5c5SAndroid Build Coastguard Worker // symbol table as variables.
1051*8975f5c5SAndroid Build Coastguard Worker const TSymbol *fieldSymbol = mSymbolTable->findGlobal(field->name());
1052*8975f5c5SAndroid Build Coastguard Worker ASSERT(fieldSymbol && fieldSymbol->isVariable());
1053*8975f5c5SAndroid Build Coastguard Worker staticUse =
1054*8975f5c5SAndroid Build Coastguard Worker mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(fieldSymbol));
1055*8975f5c5SAndroid Build Coastguard Worker if (staticUse)
1056*8975f5c5SAndroid Build Coastguard Worker {
1057*8975f5c5SAndroid Build Coastguard Worker anyFieldStaticallyUsed = true;
1058*8975f5c5SAndroid Build Coastguard Worker }
1059*8975f5c5SAndroid Build Coastguard Worker }
1060*8975f5c5SAndroid Build Coastguard Worker
1061*8975f5c5SAndroid Build Coastguard Worker ShaderVariable fieldVariable;
1062*8975f5c5SAndroid Build Coastguard Worker setFieldProperties(fieldType, field->name(), staticUse, false, false, field->symbolType(),
1063*8975f5c5SAndroid Build Coastguard Worker &fieldVariable);
1064*8975f5c5SAndroid Build Coastguard Worker fieldVariable.isRowMajorLayout =
1065*8975f5c5SAndroid Build Coastguard Worker (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
1066*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->fields.push_back(fieldVariable);
1067*8975f5c5SAndroid Build Coastguard Worker
1068*8975f5c5SAndroid Build Coastguard Worker // The SSBO is not readonly if any field is not readonly.
1069*8975f5c5SAndroid Build Coastguard Worker if (!fieldType.getMemoryQualifier().readonly)
1070*8975f5c5SAndroid Build Coastguard Worker {
1071*8975f5c5SAndroid Build Coastguard Worker isReadOnly = false;
1072*8975f5c5SAndroid Build Coastguard Worker }
1073*8975f5c5SAndroid Build Coastguard Worker }
1074*8975f5c5SAndroid Build Coastguard Worker if (anyFieldStaticallyUsed)
1075*8975f5c5SAndroid Build Coastguard Worker {
1076*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->staticUse = true;
1077*8975f5c5SAndroid Build Coastguard Worker }
1078*8975f5c5SAndroid Build Coastguard Worker if (interfaceBlock->blockType == BlockType::kBlockBuffer)
1079*8975f5c5SAndroid Build Coastguard Worker {
1080*8975f5c5SAndroid Build Coastguard Worker interfaceBlock->isReadOnly = isReadOnly;
1081*8975f5c5SAndroid Build Coastguard Worker }
1082*8975f5c5SAndroid Build Coastguard Worker }
1083*8975f5c5SAndroid Build Coastguard Worker
recordUniform(const TIntermSymbol & variable) const1084*8975f5c5SAndroid Build Coastguard Worker ShaderVariable CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
1085*8975f5c5SAndroid Build Coastguard Worker {
1086*8975f5c5SAndroid Build Coastguard Worker ShaderVariable uniform;
1087*8975f5c5SAndroid Build Coastguard Worker setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
1088*8975f5c5SAndroid Build Coastguard Worker uniform.binding = variable.getType().getLayoutQualifier().binding;
1089*8975f5c5SAndroid Build Coastguard Worker uniform.imageUnitFormat =
1090*8975f5c5SAndroid Build Coastguard Worker GetImageInternalFormatType(variable.getType().getLayoutQualifier().imageInternalFormat);
1091*8975f5c5SAndroid Build Coastguard Worker uniform.location = variable.getType().getLayoutQualifier().location;
1092*8975f5c5SAndroid Build Coastguard Worker uniform.offset = variable.getType().getLayoutQualifier().offset;
1093*8975f5c5SAndroid Build Coastguard Worker uniform.rasterOrdered = variable.getType().getLayoutQualifier().rasterOrdered;
1094*8975f5c5SAndroid Build Coastguard Worker uniform.readonly = variable.getType().getMemoryQualifier().readonly;
1095*8975f5c5SAndroid Build Coastguard Worker uniform.writeonly = variable.getType().getMemoryQualifier().writeonly;
1096*8975f5c5SAndroid Build Coastguard Worker return uniform;
1097*8975f5c5SAndroid Build Coastguard Worker }
1098*8975f5c5SAndroid Build Coastguard Worker
visitDeclaration(Visit,TIntermDeclaration * node)1099*8975f5c5SAndroid Build Coastguard Worker bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
1100*8975f5c5SAndroid Build Coastguard Worker {
1101*8975f5c5SAndroid Build Coastguard Worker const TIntermSequence &sequence = *(node->getSequence());
1102*8975f5c5SAndroid Build Coastguard Worker ASSERT(!sequence.empty());
1103*8975f5c5SAndroid Build Coastguard Worker
1104*8975f5c5SAndroid Build Coastguard Worker const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
1105*8975f5c5SAndroid Build Coastguard Worker TQualifier qualifier = typedNode.getQualifier();
1106*8975f5c5SAndroid Build Coastguard Worker
1107*8975f5c5SAndroid Build Coastguard Worker bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn ||
1108*8975f5c5SAndroid Build Coastguard Worker qualifier == EvqFragmentOut || qualifier == EvqFragmentInOut ||
1109*8975f5c5SAndroid Build Coastguard Worker qualifier == EvqUniform || IsVarying(qualifier);
1110*8975f5c5SAndroid Build Coastguard Worker
1111*8975f5c5SAndroid Build Coastguard Worker if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable)
1112*8975f5c5SAndroid Build Coastguard Worker {
1113*8975f5c5SAndroid Build Coastguard Worker return true;
1114*8975f5c5SAndroid Build Coastguard Worker }
1115*8975f5c5SAndroid Build Coastguard Worker
1116*8975f5c5SAndroid Build Coastguard Worker for (TIntermNode *variableNode : sequence)
1117*8975f5c5SAndroid Build Coastguard Worker {
1118*8975f5c5SAndroid Build Coastguard Worker // The only case in which the sequence will not contain a TIntermSymbol node is
1119*8975f5c5SAndroid Build Coastguard Worker // initialization. It will contain a TInterBinary node in that case. Since attributes,
1120*8975f5c5SAndroid Build Coastguard Worker // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
1121*8975f5c5SAndroid Build Coastguard Worker // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
1122*8975f5c5SAndroid Build Coastguard Worker const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
1123*8975f5c5SAndroid Build Coastguard Worker if (variable.variable().symbolType() == SymbolType::AngleInternal)
1124*8975f5c5SAndroid Build Coastguard Worker {
1125*8975f5c5SAndroid Build Coastguard Worker // Internal variables are not collected.
1126*8975f5c5SAndroid Build Coastguard Worker continue;
1127*8975f5c5SAndroid Build Coastguard Worker }
1128*8975f5c5SAndroid Build Coastguard Worker
1129*8975f5c5SAndroid Build Coastguard Worker // SpirvTransformer::transform uses a map of ShaderVariables, it needs member variables and
1130*8975f5c5SAndroid Build Coastguard Worker // (named or unnamed) structure as ShaderVariable. at link between two shaders, validation
1131*8975f5c5SAndroid Build Coastguard Worker // between of named and unnamed, needs the same structure, its members, and members order
1132*8975f5c5SAndroid Build Coastguard Worker // except instance name.
1133*8975f5c5SAndroid Build Coastguard Worker if (typedNode.getBasicType() == EbtInterfaceBlock && !IsShaderIoBlock(qualifier) &&
1134*8975f5c5SAndroid Build Coastguard Worker qualifier != EvqPatchIn && qualifier != EvqPatchOut)
1135*8975f5c5SAndroid Build Coastguard Worker {
1136*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock interfaceBlock;
1137*8975f5c5SAndroid Build Coastguard Worker bool isUnnamed = variable.variable().symbolType() == SymbolType::Empty;
1138*8975f5c5SAndroid Build Coastguard Worker const TType &type = variable.getType();
1139*8975f5c5SAndroid Build Coastguard Worker recordInterfaceBlock(isUnnamed ? nullptr : variable.getName().data(), type,
1140*8975f5c5SAndroid Build Coastguard Worker &interfaceBlock);
1141*8975f5c5SAndroid Build Coastguard Worker
1142*8975f5c5SAndroid Build Coastguard Worker // all fields in interface block will be added for updating interface variables because
1143*8975f5c5SAndroid Build Coastguard Worker // the temporal structure variable will be ignored.
1144*8975f5c5SAndroid Build Coastguard Worker switch (qualifier)
1145*8975f5c5SAndroid Build Coastguard Worker {
1146*8975f5c5SAndroid Build Coastguard Worker case EvqUniform:
1147*8975f5c5SAndroid Build Coastguard Worker mUniformBlocks->push_back(interfaceBlock);
1148*8975f5c5SAndroid Build Coastguard Worker break;
1149*8975f5c5SAndroid Build Coastguard Worker case EvqBuffer:
1150*8975f5c5SAndroid Build Coastguard Worker mShaderStorageBlocks->push_back(interfaceBlock);
1151*8975f5c5SAndroid Build Coastguard Worker break;
1152*8975f5c5SAndroid Build Coastguard Worker case EvqPixelLocalEXT:
1153*8975f5c5SAndroid Build Coastguard Worker // EXT_shader_pixel_local_storage is completely self-contained within the
1154*8975f5c5SAndroid Build Coastguard Worker // shader, so we don't need to gather any info on it.
1155*8975f5c5SAndroid Build Coastguard Worker break;
1156*8975f5c5SAndroid Build Coastguard Worker default:
1157*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1158*8975f5c5SAndroid Build Coastguard Worker }
1159*8975f5c5SAndroid Build Coastguard Worker }
1160*8975f5c5SAndroid Build Coastguard Worker else
1161*8975f5c5SAndroid Build Coastguard Worker {
1162*8975f5c5SAndroid Build Coastguard Worker ASSERT(variable.variable().symbolType() != SymbolType::Empty ||
1163*8975f5c5SAndroid Build Coastguard Worker IsShaderIoBlock(qualifier) || qualifier == EvqPatchIn ||
1164*8975f5c5SAndroid Build Coastguard Worker qualifier == EvqPatchOut);
1165*8975f5c5SAndroid Build Coastguard Worker switch (qualifier)
1166*8975f5c5SAndroid Build Coastguard Worker {
1167*8975f5c5SAndroid Build Coastguard Worker case EvqAttribute:
1168*8975f5c5SAndroid Build Coastguard Worker case EvqVertexIn:
1169*8975f5c5SAndroid Build Coastguard Worker mAttribs->push_back(recordAttribute(variable));
1170*8975f5c5SAndroid Build Coastguard Worker break;
1171*8975f5c5SAndroid Build Coastguard Worker case EvqFragmentOut:
1172*8975f5c5SAndroid Build Coastguard Worker case EvqFragmentInOut:
1173*8975f5c5SAndroid Build Coastguard Worker mOutputVariables->push_back(recordOutputVariable(variable));
1174*8975f5c5SAndroid Build Coastguard Worker break;
1175*8975f5c5SAndroid Build Coastguard Worker case EvqUniform:
1176*8975f5c5SAndroid Build Coastguard Worker mUniforms->push_back(recordUniform(variable));
1177*8975f5c5SAndroid Build Coastguard Worker break;
1178*8975f5c5SAndroid Build Coastguard Worker default:
1179*8975f5c5SAndroid Build Coastguard Worker if (IsVaryingIn(qualifier))
1180*8975f5c5SAndroid Build Coastguard Worker {
1181*8975f5c5SAndroid Build Coastguard Worker mInputVaryings->push_back(recordVarying(variable));
1182*8975f5c5SAndroid Build Coastguard Worker }
1183*8975f5c5SAndroid Build Coastguard Worker else
1184*8975f5c5SAndroid Build Coastguard Worker {
1185*8975f5c5SAndroid Build Coastguard Worker ASSERT(IsVaryingOut(qualifier));
1186*8975f5c5SAndroid Build Coastguard Worker mOutputVaryings->push_back(recordVarying(variable));
1187*8975f5c5SAndroid Build Coastguard Worker }
1188*8975f5c5SAndroid Build Coastguard Worker break;
1189*8975f5c5SAndroid Build Coastguard Worker }
1190*8975f5c5SAndroid Build Coastguard Worker }
1191*8975f5c5SAndroid Build Coastguard Worker }
1192*8975f5c5SAndroid Build Coastguard Worker
1193*8975f5c5SAndroid Build Coastguard Worker // None of the recorded variables can have initializers, so we don't need to traverse the
1194*8975f5c5SAndroid Build Coastguard Worker // declarators.
1195*8975f5c5SAndroid Build Coastguard Worker return false;
1196*8975f5c5SAndroid Build Coastguard Worker }
1197*8975f5c5SAndroid Build Coastguard Worker
findNamedInterfaceBlock(const ImmutableString & blockName) const1198*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(
1199*8975f5c5SAndroid Build Coastguard Worker const ImmutableString &blockName) const
1200*8975f5c5SAndroid Build Coastguard Worker {
1201*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
1202*8975f5c5SAndroid Build Coastguard Worker if (!namedBlock)
1203*8975f5c5SAndroid Build Coastguard Worker {
1204*8975f5c5SAndroid Build Coastguard Worker namedBlock = FindVariable(blockName, mShaderStorageBlocks);
1205*8975f5c5SAndroid Build Coastguard Worker }
1206*8975f5c5SAndroid Build Coastguard Worker return namedBlock;
1207*8975f5c5SAndroid Build Coastguard Worker }
1208*8975f5c5SAndroid Build Coastguard Worker
visitBinary(Visit,TIntermBinary * binaryNode)1209*8975f5c5SAndroid Build Coastguard Worker bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
1210*8975f5c5SAndroid Build Coastguard Worker {
1211*8975f5c5SAndroid Build Coastguard Worker if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
1212*8975f5c5SAndroid Build Coastguard Worker {
1213*8975f5c5SAndroid Build Coastguard Worker // NOTE: we do not determine static use / activeness for individual blocks of an array.
1214*8975f5c5SAndroid Build Coastguard Worker TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
1215*8975f5c5SAndroid Build Coastguard Worker ASSERT(blockNode);
1216*8975f5c5SAndroid Build Coastguard Worker
1217*8975f5c5SAndroid Build Coastguard Worker TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
1218*8975f5c5SAndroid Build Coastguard Worker ASSERT(constantUnion);
1219*8975f5c5SAndroid Build Coastguard Worker
1220*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock *namedBlock = nullptr;
1221*8975f5c5SAndroid Build Coastguard Worker
1222*8975f5c5SAndroid Build Coastguard Worker bool traverseIndexExpression = false;
1223*8975f5c5SAndroid Build Coastguard Worker TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
1224*8975f5c5SAndroid Build Coastguard Worker if (interfaceIndexingNode)
1225*8975f5c5SAndroid Build Coastguard Worker {
1226*8975f5c5SAndroid Build Coastguard Worker ASSERT(interfaceIndexingNode->getOp() == EOpIndexDirect ||
1227*8975f5c5SAndroid Build Coastguard Worker interfaceIndexingNode->getOp() == EOpIndexIndirect);
1228*8975f5c5SAndroid Build Coastguard Worker traverseIndexExpression = true;
1229*8975f5c5SAndroid Build Coastguard Worker blockNode = interfaceIndexingNode->getLeft();
1230*8975f5c5SAndroid Build Coastguard Worker }
1231*8975f5c5SAndroid Build Coastguard Worker
1232*8975f5c5SAndroid Build Coastguard Worker const TType &interfaceNodeType = blockNode->getType();
1233*8975f5c5SAndroid Build Coastguard Worker const TInterfaceBlock *interfaceBlock = interfaceNodeType.getInterfaceBlock();
1234*8975f5c5SAndroid Build Coastguard Worker const TQualifier qualifier = interfaceNodeType.getQualifier();
1235*8975f5c5SAndroid Build Coastguard Worker
1236*8975f5c5SAndroid Build Coastguard Worker // If it's a shader I/O block, look in varyings
1237*8975f5c5SAndroid Build Coastguard Worker ShaderVariable *ioBlockVar = nullptr;
1238*8975f5c5SAndroid Build Coastguard Worker if (qualifier == EvqPerVertexIn)
1239*8975f5c5SAndroid Build Coastguard Worker {
1240*8975f5c5SAndroid Build Coastguard Worker TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
1241*8975f5c5SAndroid Build Coastguard Worker ASSERT(symbolNode);
1242*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexInAdded, mInputVaryings);
1243*8975f5c5SAndroid Build Coastguard Worker ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
1244*8975f5c5SAndroid Build Coastguard Worker }
1245*8975f5c5SAndroid Build Coastguard Worker else if (IsVaryingIn(qualifier))
1246*8975f5c5SAndroid Build Coastguard Worker {
1247*8975f5c5SAndroid Build Coastguard Worker ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
1248*8975f5c5SAndroid Build Coastguard Worker }
1249*8975f5c5SAndroid Build Coastguard Worker else if (qualifier == EvqPerVertexOut)
1250*8975f5c5SAndroid Build Coastguard Worker {
1251*8975f5c5SAndroid Build Coastguard Worker TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
1252*8975f5c5SAndroid Build Coastguard Worker ASSERT(symbolNode);
1253*8975f5c5SAndroid Build Coastguard Worker recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexOutAdded, mOutputVaryings);
1254*8975f5c5SAndroid Build Coastguard Worker ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
1255*8975f5c5SAndroid Build Coastguard Worker }
1256*8975f5c5SAndroid Build Coastguard Worker else if (IsVaryingOut(qualifier))
1257*8975f5c5SAndroid Build Coastguard Worker {
1258*8975f5c5SAndroid Build Coastguard Worker ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
1259*8975f5c5SAndroid Build Coastguard Worker }
1260*8975f5c5SAndroid Build Coastguard Worker
1261*8975f5c5SAndroid Build Coastguard Worker if (ioBlockVar)
1262*8975f5c5SAndroid Build Coastguard Worker {
1263*8975f5c5SAndroid Build Coastguard Worker MarkActive(ioBlockVar);
1264*8975f5c5SAndroid Build Coastguard Worker }
1265*8975f5c5SAndroid Build Coastguard Worker else if (qualifier != EvqPixelLocalEXT)
1266*8975f5c5SAndroid Build Coastguard Worker {
1267*8975f5c5SAndroid Build Coastguard Worker
1268*8975f5c5SAndroid Build Coastguard Worker if (!namedBlock)
1269*8975f5c5SAndroid Build Coastguard Worker {
1270*8975f5c5SAndroid Build Coastguard Worker namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
1271*8975f5c5SAndroid Build Coastguard Worker }
1272*8975f5c5SAndroid Build Coastguard Worker ASSERT(namedBlock);
1273*8975f5c5SAndroid Build Coastguard Worker ASSERT(namedBlock->staticUse);
1274*8975f5c5SAndroid Build Coastguard Worker namedBlock->active = true;
1275*8975f5c5SAndroid Build Coastguard Worker unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
1276*8975f5c5SAndroid Build Coastguard Worker ASSERT(fieldIndex < namedBlock->fields.size());
1277*8975f5c5SAndroid Build Coastguard Worker // TODO(oetuaho): Would be nicer to record static use of fields of named interface
1278*8975f5c5SAndroid Build Coastguard Worker // blocks more accurately at parse time - now we only mark the fields statically used if
1279*8975f5c5SAndroid Build Coastguard Worker // they are active. http://anglebug.com/42261150 We need to mark this field and all of
1280*8975f5c5SAndroid Build Coastguard Worker // its sub-fields, as static/active
1281*8975f5c5SAndroid Build Coastguard Worker MarkActive(&namedBlock->fields[fieldIndex]);
1282*8975f5c5SAndroid Build Coastguard Worker }
1283*8975f5c5SAndroid Build Coastguard Worker
1284*8975f5c5SAndroid Build Coastguard Worker if (traverseIndexExpression)
1285*8975f5c5SAndroid Build Coastguard Worker {
1286*8975f5c5SAndroid Build Coastguard Worker ASSERT(interfaceIndexingNode);
1287*8975f5c5SAndroid Build Coastguard Worker interfaceIndexingNode->getRight()->traverse(this);
1288*8975f5c5SAndroid Build Coastguard Worker }
1289*8975f5c5SAndroid Build Coastguard Worker return false;
1290*8975f5c5SAndroid Build Coastguard Worker }
1291*8975f5c5SAndroid Build Coastguard Worker
1292*8975f5c5SAndroid Build Coastguard Worker return true;
1293*8975f5c5SAndroid Build Coastguard Worker }
1294*8975f5c5SAndroid Build Coastguard Worker
1295*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
1296*8975f5c5SAndroid Build Coastguard Worker
CollectVariables(TIntermBlock * root,std::vector<ShaderVariable> * attributes,std::vector<ShaderVariable> * outputVariables,std::vector<ShaderVariable> * uniforms,std::vector<ShaderVariable> * inputVaryings,std::vector<ShaderVariable> * outputVaryings,std::vector<ShaderVariable> * sharedVariables,std::vector<InterfaceBlock> * uniformBlocks,std::vector<InterfaceBlock> * shaderStorageBlocks,ShHashFunction64 hashFunction,TSymbolTable * symbolTable,GLenum shaderType,const TExtensionBehavior & extensionBehavior,const ShBuiltInResources & resources,int tessControlShaderOutputVertices)1297*8975f5c5SAndroid Build Coastguard Worker void CollectVariables(TIntermBlock *root,
1298*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *attributes,
1299*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *outputVariables,
1300*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *uniforms,
1301*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *inputVaryings,
1302*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *outputVaryings,
1303*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *sharedVariables,
1304*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *uniformBlocks,
1305*8975f5c5SAndroid Build Coastguard Worker std::vector<InterfaceBlock> *shaderStorageBlocks,
1306*8975f5c5SAndroid Build Coastguard Worker ShHashFunction64 hashFunction,
1307*8975f5c5SAndroid Build Coastguard Worker TSymbolTable *symbolTable,
1308*8975f5c5SAndroid Build Coastguard Worker GLenum shaderType,
1309*8975f5c5SAndroid Build Coastguard Worker const TExtensionBehavior &extensionBehavior,
1310*8975f5c5SAndroid Build Coastguard Worker const ShBuiltInResources &resources,
1311*8975f5c5SAndroid Build Coastguard Worker int tessControlShaderOutputVertices)
1312*8975f5c5SAndroid Build Coastguard Worker {
1313*8975f5c5SAndroid Build Coastguard Worker CollectVariablesTraverser collect(
1314*8975f5c5SAndroid Build Coastguard Worker attributes, outputVariables, uniforms, inputVaryings, outputVaryings, sharedVariables,
1315*8975f5c5SAndroid Build Coastguard Worker uniformBlocks, shaderStorageBlocks, hashFunction, symbolTable, shaderType,
1316*8975f5c5SAndroid Build Coastguard Worker extensionBehavior, resources, tessControlShaderOutputVertices);
1317*8975f5c5SAndroid Build Coastguard Worker root->traverse(&collect);
1318*8975f5c5SAndroid Build Coastguard Worker }
1319*8975f5c5SAndroid Build Coastguard Worker
1320*8975f5c5SAndroid Build Coastguard Worker } // namespace sh
1321