blob: 04860486864d92375448243eff65e388f011f347 [file] [log] [blame]
alokp@chromium.org07620a52010-09-23 17:53:56 +00001//
shannonwoods@chromium.orge429ab72013-05-30 00:12:52 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org07620a52010-09-23 17:53:56 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
Olli Etuaho78ed6cd2017-08-09 16:19:00 +03006// CollectVariables.cpp: Collect lists of shader interface variables based on the AST.
alokp@chromium.org07620a52010-09-23 17:53:56 +00007
Olli Etuaho78ed6cd2017-08-09 16:19:00 +03008#include "compiler/translator/CollectVariables.h"
Olli Etuaho19515012017-06-26 18:00:17 +03009
10#include "angle_gl.h"
Jamie Madilld5512cd2014-07-10 17:50:08 -040011#include "common/utilities.h"
Olli Etuahocccf2b02017-07-05 14:50:54 +030012#include "compiler/translator/HashNames.h"
13#include "compiler/translator/IntermTraverse.h"
Olli Etuaho19515012017-06-26 18:00:17 +030014#include "compiler/translator/SymbolTable.h"
15#include "compiler/translator/util.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000016
Jamie Madilla2fbb842014-09-03 09:40:47 -040017namespace sh
18{
19
Jamie Madill54ad4f82014-09-03 09:40:46 -040020namespace
21{
Zhenyao Mod2d340b2013-09-23 14:57:05 -040022
Jamie Madilla2fbb842014-09-03 09:40:47 -040023BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
Jamie Madill54ad4f82014-09-03 09:40:46 -040024{
25 switch (blockStorage)
26 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050027 case EbsPacked:
28 return BLOCKLAYOUT_PACKED;
29 case EbsShared:
30 return BLOCKLAYOUT_SHARED;
31 case EbsStd140:
32 return BLOCKLAYOUT_STANDARD;
33 default:
34 UNREACHABLE();
35 return BLOCKLAYOUT_SHARED;
Jamie Madill54ad4f82014-09-03 09:40:46 -040036 }
37}
38
Jiawei Shaod8105a02017-08-08 09:54:36 +080039// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
Jiajia Qin9b11ea42017-07-11 16:50:08 +080040BlockType GetBlockType(TQualifier qualifier)
41{
42 switch (qualifier)
43 {
44 case EvqUniform:
45 return BlockType::BLOCK_UNIFORM;
46 case EvqBuffer:
47 return BlockType::BLOCK_BUFFER;
Jiawei Shaod8105a02017-08-08 09:54:36 +080048 case EvqPerVertexIn:
49 return BlockType::BLOCK_IN;
Jiajia Qin9b11ea42017-07-11 16:50:08 +080050 default:
51 UNREACHABLE();
52 return BlockType::BLOCK_UNIFORM;
53 }
54}
55
Jamie Madilla718c1e2014-07-02 15:31:22 -040056template <class VarT>
Jamie Madilld7b1ab52016-12-12 14:42:19 -050057VarT *FindVariable(const TString &name, std::vector<VarT> *infoList)
Zhenyao Mod2d340b2013-09-23 14:57:05 -040058{
59 // TODO(zmo): optimize this function.
Jamie Madilla718c1e2014-07-02 15:31:22 -040060 for (size_t ii = 0; ii < infoList->size(); ++ii)
Zhenyao Mod2d340b2013-09-23 14:57:05 -040061 {
Jamie Madill23a8a432014-07-09 13:27:42 -040062 if ((*infoList)[ii].name.c_str() == name)
Jamie Madilla718c1e2014-07-02 15:31:22 -040063 return &((*infoList)[ii]);
Zhenyao Mod2d340b2013-09-23 14:57:05 -040064 }
Jamie Madilld5512cd2014-07-10 17:50:08 -040065
Yunchao Hef81ce4a2017-04-24 10:49:17 +080066 return nullptr;
Zhenyao Mod2d340b2013-09-23 14:57:05 -040067}
Jamie Madill54ad4f82014-09-03 09:40:46 -040068
Olli Etuaho06a06f52017-07-12 12:22:15 +030069// Note that this shouldn't be called for interface blocks - static use information is collected for
70// individual fields in case of interface blocks.
71void MarkStaticallyUsed(ShaderVariable *variable)
72{
73 if (!variable->staticUse)
74 {
75 if (variable->isStruct())
76 {
77 // Conservatively assume all fields are statically used as well.
78 for (auto &field : variable->fields)
79 {
80 MarkStaticallyUsed(&field);
81 }
82 }
83 variable->staticUse = true;
84 }
85}
86
Olli Etuaho19515012017-06-26 18:00:17 +030087// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
88// and interface blocks.
89class CollectVariablesTraverser : public TIntermTraverser
90{
91 public:
92 CollectVariablesTraverser(std::vector<Attribute> *attribs,
93 std::vector<OutputVariable> *outputVariables,
94 std::vector<Uniform> *uniforms,
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +080095 std::vector<Varying> *inputVaryings,
96 std::vector<Varying> *outputVaryings,
Jiajia Qin9b11ea42017-07-11 16:50:08 +080097 std::vector<InterfaceBlock> *uniformBlocks,
98 std::vector<InterfaceBlock> *shaderStorageBlocks,
Jiawei Shaod8105a02017-08-08 09:54:36 +080099 std::vector<InterfaceBlock> *inBlocks,
Olli Etuaho19515012017-06-26 18:00:17 +0300100 ShHashFunction64 hashFunction,
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300101 TSymbolTable *symbolTable,
Olli Etuaho19515012017-06-26 18:00:17 +0300102 int shaderVersion,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800103 GLenum shaderType,
Olli Etuaho19515012017-06-26 18:00:17 +0300104 const TExtensionBehavior &extensionBehavior);
105
106 void visitSymbol(TIntermSymbol *symbol) override;
107 bool visitDeclaration(Visit, TIntermDeclaration *node) override;
108 bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
109
110 private:
111 void setCommonVariableProperties(const TType &type,
112 const TString &name,
113 ShaderVariable *variableOut) const;
114
115 Attribute recordAttribute(const TIntermSymbol &variable) const;
116 OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
117 Varying recordVarying(const TIntermSymbol &variable) const;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800118 void recordInterfaceBlock(const TType &interfaceBlockType,
119 InterfaceBlock *interfaceBlock) const;
Olli Etuaho19515012017-06-26 18:00:17 +0300120 Uniform recordUniform(const TIntermSymbol &variable) const;
121
122 void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info);
123
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800124 void recordBuiltInVaryingUsed(const char *name,
125 bool *addedFlag,
126 std::vector<Varying> *varyings);
Olli Etuaho19515012017-06-26 18:00:17 +0300127 void recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag);
128 void recordBuiltInAttributeUsed(const char *name, bool *addedFlag);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800129 InterfaceBlock *recordGLInUsed(const TType &glInType);
130 InterfaceBlock *findNamedInterfaceBlock(const TString &name) const;
Olli Etuaho19515012017-06-26 18:00:17 +0300131
132 std::vector<Attribute> *mAttribs;
133 std::vector<OutputVariable> *mOutputVariables;
134 std::vector<Uniform> *mUniforms;
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800135 std::vector<Varying> *mInputVaryings;
136 std::vector<Varying> *mOutputVaryings;
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800137 std::vector<InterfaceBlock> *mUniformBlocks;
138 std::vector<InterfaceBlock> *mShaderStorageBlocks;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800139 std::vector<InterfaceBlock> *mInBlocks;
Olli Etuaho19515012017-06-26 18:00:17 +0300140
141 std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
142
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800143 // Shader uniforms
Olli Etuaho19515012017-06-26 18:00:17 +0300144 bool mDepthRangeAdded;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800145
146 // Vertex Shader builtins
147 bool mInstanceIDAdded;
148 bool mVertexIDAdded;
149 bool mPointSizeAdded;
150
151 // Vertex Shader and Geometry Shader builtins
152 bool mPositionAdded;
153
154 // Fragment Shader builtins
Olli Etuaho19515012017-06-26 18:00:17 +0300155 bool mPointCoordAdded;
156 bool mFrontFacingAdded;
157 bool mFragCoordAdded;
Olli Etuaho19515012017-06-26 18:00:17 +0300158 bool mLastFragDataAdded;
159 bool mFragColorAdded;
160 bool mFragDataAdded;
161 bool mFragDepthEXTAdded;
162 bool mFragDepthAdded;
163 bool mSecondaryFragColorEXTAdded;
164 bool mSecondaryFragDataEXTAdded;
165
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800166 // Geometry Shader builtins
Jiawei Shaod8105a02017-08-08 09:54:36 +0800167 bool mPerVertexInAdded;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800168 bool mPrimitiveIDInAdded;
169 bool mInvocationIDAdded;
170
171 // Geometry Shader and Fragment Shader builtins
172 bool mPrimitiveIDAdded;
173 bool mLayerAdded;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800174
Olli Etuaho19515012017-06-26 18:00:17 +0300175 ShHashFunction64 mHashFunction;
176
Olli Etuaho19515012017-06-26 18:00:17 +0300177 int mShaderVersion;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800178 GLenum mShaderType;
Olli Etuaho19515012017-06-26 18:00:17 +0300179 const TExtensionBehavior &mExtensionBehavior;
180};
181
182CollectVariablesTraverser::CollectVariablesTraverser(
183 std::vector<sh::Attribute> *attribs,
184 std::vector<sh::OutputVariable> *outputVariables,
185 std::vector<sh::Uniform> *uniforms,
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800186 std::vector<sh::Varying> *inputVaryings,
187 std::vector<sh::Varying> *outputVaryings,
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800188 std::vector<sh::InterfaceBlock> *uniformBlocks,
189 std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800190 std::vector<sh::InterfaceBlock> *inBlocks,
Olli Etuaho19515012017-06-26 18:00:17 +0300191 ShHashFunction64 hashFunction,
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300192 TSymbolTable *symbolTable,
Olli Etuaho19515012017-06-26 18:00:17 +0300193 int shaderVersion,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800194 GLenum shaderType,
Olli Etuaho19515012017-06-26 18:00:17 +0300195 const TExtensionBehavior &extensionBehavior)
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300196 : TIntermTraverser(true, false, false, symbolTable),
Olli Etuaho3d0d9a42015-06-01 12:16:36 +0300197 mAttribs(attribs),
Jamie Madilld5512cd2014-07-10 17:50:08 -0400198 mOutputVariables(outputVariables),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000199 mUniforms(uniforms),
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800200 mInputVaryings(inputVaryings),
201 mOutputVaryings(outputVaryings),
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800202 mUniformBlocks(uniformBlocks),
203 mShaderStorageBlocks(shaderStorageBlocks),
Jiawei Shaod8105a02017-08-08 09:54:36 +0800204 mInBlocks(inBlocks),
Jamie Madill55def582015-05-04 11:24:57 -0400205 mDepthRangeAdded(false),
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800206 mInstanceIDAdded(false),
207 mVertexIDAdded(false),
208 mPointSizeAdded(false),
209 mPositionAdded(false),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400210 mPointCoordAdded(false),
211 mFrontFacingAdded(false),
212 mFragCoordAdded(false),
Erik Dahlströmea7a2122014-11-17 16:15:57 +0100213 mLastFragDataAdded(false),
Kimmo Kinnunen0932df62015-07-21 14:35:11 +0300214 mFragColorAdded(false),
215 mFragDataAdded(false),
Kimmo Kinnunen5f0246c2015-07-22 10:30:35 +0300216 mFragDepthEXTAdded(false),
Kimmo Kinnunen0932df62015-07-21 14:35:11 +0300217 mFragDepthAdded(false),
Kimmo Kinnunenb18609b2015-07-16 14:13:11 +0300218 mSecondaryFragColorEXTAdded(false),
219 mSecondaryFragDataEXTAdded(false),
Jiawei Shaod8105a02017-08-08 09:54:36 +0800220 mPerVertexInAdded(false),
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800221 mPrimitiveIDInAdded(false),
222 mInvocationIDAdded(false),
223 mPrimitiveIDAdded(false),
224 mLayerAdded(false),
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700225 mHashFunction(hashFunction),
Olli Etuaho19515012017-06-26 18:00:17 +0300226 mShaderVersion(shaderVersion),
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800227 mShaderType(shaderType),
Zhenyao Mof178d0b2016-07-23 06:59:00 -0700228 mExtensionBehavior(extensionBehavior)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000229{
230}
231
Olli Etuaho19515012017-06-26 18:00:17 +0300232void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
233 ShaderVariable *info)
234{
235 TVariable *symbolTableVar =
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300236 reinterpret_cast<TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
Olli Etuaho19515012017-06-26 18:00:17 +0300237 ASSERT(symbolTableVar);
238 const TType &type = symbolTableVar->getType();
239
240 info->name = name;
241 info->mappedName = name;
242 info->type = GLVariableType(type);
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300243 ASSERT(!type.isArrayOfArrays());
244 info->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
245 info->precision = GLVariablePrecision(type);
Olli Etuaho19515012017-06-26 18:00:17 +0300246}
247
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800248void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name,
249 bool *addedFlag,
250 std::vector<Varying> *varyings)
Olli Etuaho19515012017-06-26 18:00:17 +0300251{
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800252 ASSERT(varyings);
Olli Etuaho19515012017-06-26 18:00:17 +0300253 if (!(*addedFlag))
254 {
255 Varying info;
256 setBuiltInInfoFromSymbolTable(name, &info);
257 info.staticUse = true;
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300258 info.isInvariant = mSymbolTable->isVaryingInvariant(name);
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800259 varyings->push_back(info);
Olli Etuaho19515012017-06-26 18:00:17 +0300260 (*addedFlag) = true;
261 }
262}
263
264void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag)
265{
266 if (!(*addedFlag))
267 {
268 OutputVariable info;
269 setBuiltInInfoFromSymbolTable(name, &info);
270 info.staticUse = true;
271 mOutputVariables->push_back(info);
272 (*addedFlag) = true;
273 }
274}
275
276void CollectVariablesTraverser::recordBuiltInAttributeUsed(const char *name, bool *addedFlag)
277{
278 if (!(*addedFlag))
279 {
280 Attribute info;
281 setBuiltInInfoFromSymbolTable(name, &info);
282 info.staticUse = true;
283 info.location = -1;
284 mAttribs->push_back(info);
285 (*addedFlag) = true;
286 }
287}
288
Jiawei Shaod8105a02017-08-08 09:54:36 +0800289InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType)
290{
291 if (!mPerVertexInAdded)
292 {
293 ASSERT(glInType.getQualifier() == EvqPerVertexIn);
294 InterfaceBlock info;
295 recordInterfaceBlock(glInType, &info);
296 info.staticUse = true;
297
298 mPerVertexInAdded = true;
299 mInBlocks->push_back(info);
300 return &mInBlocks->back();
301 }
302 else
303 {
304 return FindVariable("gl_PerVertex", mInBlocks);
305 }
306}
307
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400308// We want to check whether a uniform/varying is statically used
309// because we only count the used ones in packing computing.
310// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
311// toward varying counting if they are statically used in a fragment
312// shader.
Olli Etuaho19515012017-06-26 18:00:17 +0300313void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000314{
Yunchao He4f285442017-04-21 12:15:49 +0800315 ASSERT(symbol != nullptr);
Olli Etuaho34d20072017-07-18 20:07:18 +0300316
317 if (symbol->getName().isInternal())
318 {
319 // Internal variables are not collected.
320 return;
321 }
322
Yunchao Hed7297bf2017-04-19 15:27:10 +0800323 ShaderVariable *var = nullptr;
Olli Etuaho34d20072017-07-18 20:07:18 +0300324 const TString &symbolName = symbol->getName().getString();
Jamie Madill4667c452014-07-08 15:02:36 -0400325
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800326 if (IsVaryingIn(symbol->getQualifier()))
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400327 {
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800328 var = FindVariable(symbolName, mInputVaryings);
329 }
330 else if (IsVaryingOut(symbol->getQualifier()))
331 {
332 var = FindVariable(symbolName, mOutputVaryings);
Jamie Madill4667c452014-07-08 15:02:36 -0400333 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400334 else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
335 {
336 UNREACHABLE();
337 }
Jamie Madill55def582015-05-04 11:24:57 -0400338 else if (symbolName == "gl_DepthRange")
339 {
340 ASSERT(symbol->getQualifier() == EvqUniform);
341
342 if (!mDepthRangeAdded)
343 {
344 Uniform info;
345 const char kName[] = "gl_DepthRange";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500346 info.name = kName;
347 info.mappedName = kName;
348 info.type = GL_STRUCT_ANGLEX;
349 info.arraySize = 0;
350 info.precision = GL_NONE;
351 info.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400352
353 ShaderVariable nearInfo;
354 const char kNearName[] = "near";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500355 nearInfo.name = kNearName;
356 nearInfo.mappedName = kNearName;
357 nearInfo.type = GL_FLOAT;
358 nearInfo.arraySize = 0;
359 nearInfo.precision = GL_HIGH_FLOAT;
360 nearInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400361
362 ShaderVariable farInfo;
363 const char kFarName[] = "far";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500364 farInfo.name = kFarName;
365 farInfo.mappedName = kFarName;
366 farInfo.type = GL_FLOAT;
367 farInfo.arraySize = 0;
368 farInfo.precision = GL_HIGH_FLOAT;
369 farInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400370
371 ShaderVariable diffInfo;
372 const char kDiffName[] = "diff";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500373 diffInfo.name = kDiffName;
374 diffInfo.mappedName = kDiffName;
375 diffInfo.type = GL_FLOAT;
376 diffInfo.arraySize = 0;
377 diffInfo.precision = GL_HIGH_FLOAT;
378 diffInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400379
380 info.fields.push_back(nearInfo);
381 info.fields.push_back(farInfo);
382 info.fields.push_back(diffInfo);
383
384 mUniforms->push_back(info);
385 mDepthRangeAdded = true;
386 }
387 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400388 else
Jamie Madill4667c452014-07-08 15:02:36 -0400389 {
390 switch (symbol->getQualifier())
Jamie Madilla718c1e2014-07-02 15:31:22 -0400391 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500392 case EvqAttribute:
393 case EvqVertexIn:
394 var = FindVariable(symbolName, mAttribs);
395 break;
396 case EvqFragmentOut:
397 var = FindVariable(symbolName, mOutputVariables);
398 break;
399 case EvqUniform:
Jamie Madilld5512cd2014-07-10 17:50:08 -0400400 {
401 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
402 if (interfaceBlock)
403 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500404 InterfaceBlock *namedBlock =
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800405 FindVariable(interfaceBlock->name(), mUniformBlocks);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400406 ASSERT(namedBlock);
407 var = FindVariable(symbolName, &namedBlock->fields);
408
409 // Set static use on the parent interface block here
410 namedBlock->staticUse = true;
411 }
412 else
413 {
414 var = FindVariable(symbolName, mUniforms);
415 }
416
417 // It's an internal error to reference an undefined user uniform
Jamie Madill55def582015-05-04 11:24:57 -0400418 ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400419 }
Jamie Madill4667c452014-07-08 15:02:36 -0400420 break;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500421 case EvqFragCoord:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800422 recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500423 return;
424 case EvqFrontFacing:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800425 recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500426 return;
427 case EvqPointCoord:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800428 recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500429 return;
430 case EvqInstanceID:
Martin Radev115fc552017-07-05 17:11:06 +0300431 // Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set,
432 // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
433 // InstanceID. gl_InstanceID is not added to the symbol table for ESSL1 shaders
434 // which makes it necessary to populate the type information explicitly instead of
435 // extracting it from the symbol table.
436 if (!mInstanceIDAdded)
437 {
438 Attribute info;
439 const char kName[] = "gl_InstanceID";
440 info.name = kName;
441 info.mappedName = kName;
442 info.type = GL_INT;
443 info.arraySize = 0;
444 info.precision = GL_HIGH_INT; // Defined by spec.
445 info.staticUse = true;
446 info.location = -1;
447 mAttribs->push_back(info);
448 mInstanceIDAdded = true;
449 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500450 return;
451 case EvqVertexID:
Olli Etuaho19515012017-06-26 18:00:17 +0300452 recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500453 return;
454 case EvqPosition:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800455 recordBuiltInVaryingUsed("gl_Position", &mPositionAdded, mOutputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500456 return;
457 case EvqPointSize:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800458 recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded, mOutputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500459 return;
460 case EvqLastFragData:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800461 recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500462 return;
463 case EvqFragColor:
Olli Etuaho19515012017-06-26 18:00:17 +0300464 recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500465 return;
466 case EvqFragData:
467 if (!mFragDataAdded)
468 {
469 OutputVariable info;
Olli Etuaho19515012017-06-26 18:00:17 +0300470 setBuiltInInfoFromSymbolTable("gl_FragData", &info);
471 if (!::IsExtensionEnabled(mExtensionBehavior, "GL_EXT_draw_buffers"))
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500472 {
473 info.arraySize = 1;
474 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500475 info.staticUse = true;
476 mOutputVariables->push_back(info);
477 mFragDataAdded = true;
478 }
479 return;
480 case EvqFragDepthEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300481 recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500482 return;
483 case EvqFragDepth:
Olli Etuaho19515012017-06-26 18:00:17 +0300484 recordBuiltInFragmentOutputUsed("gl_FragDepth", &mFragDepthAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500485 return;
486 case EvqSecondaryFragColorEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300487 recordBuiltInFragmentOutputUsed("gl_SecondaryFragColorEXT",
488 &mSecondaryFragColorEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500489 return;
490 case EvqSecondaryFragDataEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300491 recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT",
492 &mSecondaryFragDataEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500493 return;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800494 case EvqInvocationID:
495 recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings);
496 break;
497 case EvqPrimitiveIDIn:
498 recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings);
499 break;
500 case EvqPrimitiveID:
501 if (mShaderType == GL_GEOMETRY_SHADER_OES)
502 {
503 recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings);
504 }
505 else
506 {
507 ASSERT(mShaderType == GL_FRAGMENT_SHADER);
508 recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings);
509 }
510 break;
511 case EvqLayer:
512 if (mShaderType == GL_GEOMETRY_SHADER_OES)
513 {
514 recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings);
515 }
516 else if (mShaderType == GL_FRAGMENT_SHADER)
517 {
518 recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings);
519 }
520 else
521 {
522 ASSERT(mShaderType == GL_VERTEX_SHADER &&
Martin Radev97577622017-08-28 11:31:06 +0300523 (IsExtensionEnabled(mExtensionBehavior, "GL_OVR_multiview") ||
524 IsExtensionEnabled(mExtensionBehavior, "GL_OVR_multiview2")));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800525 }
526 break;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500527 default:
528 break;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400529 }
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400530 }
531 if (var)
Jamie Madilla718c1e2014-07-02 15:31:22 -0400532 {
Olli Etuaho06a06f52017-07-12 12:22:15 +0300533 MarkStaticallyUsed(var);
Jamie Madilla718c1e2014-07-02 15:31:22 -0400534 }
535}
536
Olli Etuaho19515012017-06-26 18:00:17 +0300537void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
538 const TString &name,
539 ShaderVariable *variableOut) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400540{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000541 ASSERT(variableOut);
542
543 const TStructure *structure = type.getStruct();
544
545 if (!structure)
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500546 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000547 variableOut->type = GLVariableType(type);
548 variableOut->precision = GLVariablePrecision(type);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500549 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000550 else
Jamie Madill23a8a432014-07-09 13:27:42 -0400551 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000552 // Note: this enum value is not exposed outside ANGLE
553 variableOut->type = GL_STRUCT_ANGLEX;
554 variableOut->structName = structure->name().c_str();
555
556 const TFieldList &fields = structure->fields();
557
558 for (TField *field : fields)
559 {
560 // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
561 // ShaderVariable objects.
562 ShaderVariable fieldVariable;
563 setCommonVariableProperties(*field->type(), field->name(), &fieldVariable);
564 variableOut->fields.push_back(fieldVariable);
565 }
Jamie Madill23a8a432014-07-09 13:27:42 -0400566 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000567 variableOut->name = name.c_str();
Olli Etuahocccf2b02017-07-05 14:50:54 +0300568 variableOut->mappedName = HashName(name, mHashFunction).c_str();
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300569
570 // TODO(oetuaho@nvidia.com): Uniforms can be arrays of arrays, so this assert will need to be
571 // removed.
572 ASSERT(!type.isArrayOfArrays());
573 variableOut->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000574}
Jamie Madill23a8a432014-07-09 13:27:42 -0400575
Olli Etuaho19515012017-06-26 18:00:17 +0300576Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400577{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000578 const TType &type = variable.getType();
Jamie Madill23a8a432014-07-09 13:27:42 -0400579 ASSERT(!type.getStruct());
580
Jamie Madilla2fbb842014-09-03 09:40:47 -0400581 Attribute attribute;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000582 setCommonVariableProperties(type, variable.getSymbol(), &attribute);
Jamie Madill23a8a432014-07-09 13:27:42 -0400583
Olli Etuahoa55102c2017-02-24 12:36:50 +0000584 attribute.location = type.getLayoutQualifier().location;
585 return attribute;
Jamie Madill23a8a432014-07-09 13:27:42 -0400586}
587
Olli Etuaho19515012017-06-26 18:00:17 +0300588OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
Jamie Madilla0a9e122015-09-02 15:54:30 -0400589{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000590 const TType &type = variable.getType();
Jamie Madilla0a9e122015-09-02 15:54:30 -0400591 ASSERT(!type.getStruct());
592
Olli Etuahoa55102c2017-02-24 12:36:50 +0000593 OutputVariable outputVariable;
594 setCommonVariableProperties(type, variable.getSymbol(), &outputVariable);
Jamie Madilla0a9e122015-09-02 15:54:30 -0400595
Olli Etuahoa55102c2017-02-24 12:36:50 +0000596 outputVariable.location = type.getLayoutQualifier().location;
597 return outputVariable;
Jamie Madilla0a9e122015-09-02 15:54:30 -0400598}
599
Olli Etuaho19515012017-06-26 18:00:17 +0300600Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
Jamie Madilld5512cd2014-07-10 17:50:08 -0400601{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000602 const TType &type = variable.getType();
603
604 Varying varying;
605 setCommonVariableProperties(type, variable.getSymbol(), &varying);
606
607 switch (type.getQualifier())
608 {
609 case EvqVaryingIn:
610 case EvqVaryingOut:
611 case EvqVertexOut:
612 case EvqSmoothOut:
613 case EvqFlatOut:
614 case EvqCentroidOut:
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300615 if (mSymbolTable->isVaryingInvariant(std::string(variable.getSymbol().c_str())) ||
Olli Etuahoa55102c2017-02-24 12:36:50 +0000616 type.isInvariant())
617 {
618 varying.isInvariant = true;
619 }
620 break;
621 default:
622 break;
623 }
624
625 varying.interpolation = GetInterpolationType(type.getQualifier());
626 return varying;
627}
628
Jiawei Shaod8105a02017-08-08 09:54:36 +0800629// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
630void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlockType,
631 InterfaceBlock *interfaceBlock) const
Olli Etuahoa55102c2017-02-24 12:36:50 +0000632{
Jiawei Shaod8105a02017-08-08 09:54:36 +0800633 ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
634 ASSERT(interfaceBlock);
635
636 const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
Jamie Madill42bcf322014-08-25 16:20:46 -0400637 ASSERT(blockType);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400638
Jiawei Shaod8105a02017-08-08 09:54:36 +0800639 interfaceBlock->name = blockType->name().c_str();
640 interfaceBlock->mappedName = HashName(blockType->name().c_str(), mHashFunction).c_str();
641 interfaceBlock->instanceName =
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500642 (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300643 ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
644 interfaceBlock->arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800645
646 interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
647 if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM ||
648 interfaceBlock->blockType == BlockType::BLOCK_BUFFER)
649 {
650 interfaceBlock->isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
651 interfaceBlock->binding = blockType->blockBinding();
652 interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage());
653 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400654
Jamie Madilla6f267f2014-08-27 11:44:15 -0400655 // Gather field information
Jamie Madill39046162016-02-08 15:05:17 -0500656 for (const TField *field : blockType->fields())
Jamie Madill54ad4f82014-09-03 09:40:46 -0400657 {
Jamie Madill39046162016-02-08 15:05:17 -0500658 const TType &fieldType = *field->type();
Jamie Madill54ad4f82014-09-03 09:40:46 -0400659
Olli Etuahoa55102c2017-02-24 12:36:50 +0000660 InterfaceBlockField fieldVariable;
661 setCommonVariableProperties(fieldType, field->name(), &fieldVariable);
662 fieldVariable.isRowMajorLayout =
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500663 (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800664 interfaceBlock->fields.push_back(fieldVariable);
Jamie Madill54ad4f82014-09-03 09:40:46 -0400665 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400666}
667
Olli Etuaho19515012017-06-26 18:00:17 +0300668Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
Jamie Madill4667c452014-07-08 15:02:36 -0400669{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000670 Uniform uniform;
671 setCommonVariableProperties(variable.getType(), variable.getSymbol(), &uniform);
Olli Etuaho78ed6cd2017-08-09 16:19:00 +0300672 uniform.binding = variable.getType().getLayoutQualifier().binding;
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000673 uniform.location = variable.getType().getLayoutQualifier().location;
jchen104cdac9e2017-05-08 11:01:20 +0800674 uniform.offset = variable.getType().getLayoutQualifier().offset;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000675 return uniform;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000676}
677
Olli Etuaho19515012017-06-26 18:00:17 +0300678bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000679{
Olli Etuaho13389b62016-10-16 11:48:18 +0100680 const TIntermSequence &sequence = *(node->getSequence());
681 ASSERT(!sequence.empty());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000682
Olli Etuaho13389b62016-10-16 11:48:18 +0100683 const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
684 TQualifier qualifier = typedNode.getQualifier();
685
Olli Etuahoa55102c2017-02-24 12:36:50 +0000686 bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn ||
687 qualifier == EvqFragmentOut || qualifier == EvqUniform ||
688 IsVarying(qualifier);
689
690 if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000691 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000692 return true;
Olli Etuaho13389b62016-10-16 11:48:18 +0100693 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000694
695 for (TIntermNode *variableNode : sequence)
Olli Etuaho13389b62016-10-16 11:48:18 +0100696 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000697 // The only case in which the sequence will not contain a TIntermSymbol node is
698 // initialization. It will contain a TInterBinary node in that case. Since attributes,
699 // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
700 // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
701 const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
Olli Etuaho34d20072017-07-18 20:07:18 +0300702 if (variable.getName().isInternal())
703 {
704 // Internal variables are not collected.
705 continue;
706 }
707
Jiawei Shaod8105a02017-08-08 09:54:36 +0800708 // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
Olli Etuahoa55102c2017-02-24 12:36:50 +0000709 if (typedNode.getBasicType() == EbtInterfaceBlock)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000710 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800711 InterfaceBlock interfaceBlock;
712 recordInterfaceBlock(variable.getType(), &interfaceBlock);
713
714 switch (qualifier)
Jiajia Qinbc585152017-06-23 15:42:17 +0800715 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800716 case EvqUniform:
717 mUniformBlocks->push_back(interfaceBlock);
718 break;
719 case EvqBuffer:
720 mShaderStorageBlocks->push_back(interfaceBlock);
721 break;
722 default:
723 UNREACHABLE();
Jiajia Qinbc585152017-06-23 15:42:17 +0800724 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000725 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000726 else
727 {
728 switch (qualifier)
729 {
730 case EvqAttribute:
731 case EvqVertexIn:
732 mAttribs->push_back(recordAttribute(variable));
733 break;
734 case EvqFragmentOut:
735 mOutputVariables->push_back(recordOutputVariable(variable));
736 break;
737 case EvqUniform:
738 mUniforms->push_back(recordUniform(variable));
739 break;
740 default:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800741 if (IsVaryingIn(qualifier))
742 {
743 mInputVaryings->push_back(recordVarying(variable));
744 }
745 else
746 {
747 ASSERT(IsVaryingOut(qualifier));
748 mOutputVaryings->push_back(recordVarying(variable));
749 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000750 break;
751 }
752 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000753 }
754
Olli Etuahoa55102c2017-02-24 12:36:50 +0000755 // None of the recorded variables can have initializers, so we don't need to traverse the
756 // declarators.
757 return false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000758}
Jamie Madill23a8a432014-07-09 13:27:42 -0400759
Jiawei Shaod8105a02017-08-08 09:54:36 +0800760// TODO(jiawei.shao@intel.com): add search on mInBlocks and mOutBlocks when implementing
761// GL_OES_shader_io_blocks.
762InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(const TString &blockName) const
763{
764 InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
765 if (!namedBlock)
766 {
767 namedBlock = FindVariable(blockName, mShaderStorageBlocks);
768 }
769 return namedBlock;
770}
771
Olli Etuaho19515012017-06-26 18:00:17 +0300772bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
Jamie Madillb547ddf2014-08-25 16:20:46 -0400773{
774 if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
775 {
Jamie Madilla6f267f2014-08-27 11:44:15 -0400776 // NOTE: we do not determine static use for individual blocks of an array
777 TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
778 ASSERT(blockNode);
Jamie Madillb547ddf2014-08-25 16:20:46 -0400779
780 TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
781 ASSERT(constantUnion);
782
Jiawei Shaod8105a02017-08-08 09:54:36 +0800783 InterfaceBlock *namedBlock = nullptr;
784
785 bool traverseIndexExpression = false;
786 TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
787 if (interfaceIndexingNode)
788 {
789 TIntermTyped *interfaceNode = interfaceIndexingNode->getLeft()->getAsTyped();
790 ASSERT(interfaceNode);
791
792 const TType &interfaceType = interfaceNode->getType();
793 if (interfaceType.getQualifier() == EvqPerVertexIn)
794 {
795 namedBlock = recordGLInUsed(interfaceType);
796 ASSERT(namedBlock);
797
798 // We need to continue traversing to collect useful variables in the index
799 // expression of gl_in.
800 traverseIndexExpression = true;
801 }
802 }
803
Jamie Madilla6f267f2014-08-27 11:44:15 -0400804 const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800805 if (!namedBlock)
Jiajia Qinbc585152017-06-23 15:42:17 +0800806 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800807 namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
Jiajia Qinbc585152017-06-23 15:42:17 +0800808 }
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800809 ASSERT(namedBlock);
810 namedBlock->staticUse = true;
811 unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
812 ASSERT(fieldIndex < namedBlock->fields.size());
813 namedBlock->fields[fieldIndex].staticUse = true;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800814
815 if (traverseIndexExpression)
816 {
817 ASSERT(interfaceIndexingNode);
818 interfaceIndexingNode->getRight()->traverse(this);
819 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400820 return false;
821 }
822
823 return true;
824}
825
Olli Etuaho19515012017-06-26 18:00:17 +0300826} // anonymous namespace
827
828void CollectVariables(TIntermBlock *root,
829 std::vector<Attribute> *attributes,
830 std::vector<OutputVariable> *outputVariables,
831 std::vector<Uniform> *uniforms,
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800832 std::vector<Varying> *inputVaryings,
833 std::vector<Varying> *outputVaryings,
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800834 std::vector<InterfaceBlock> *uniformBlocks,
835 std::vector<InterfaceBlock> *shaderStorageBlocks,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800836 std::vector<InterfaceBlock> *inBlocks,
Olli Etuaho19515012017-06-26 18:00:17 +0300837 ShHashFunction64 hashFunction,
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300838 TSymbolTable *symbolTable,
Olli Etuaho19515012017-06-26 18:00:17 +0300839 int shaderVersion,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800840 GLenum shaderType,
Olli Etuaho19515012017-06-26 18:00:17 +0300841 const TExtensionBehavior &extensionBehavior)
842{
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800843 CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800844 outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800845 hashFunction, symbolTable, shaderVersion, shaderType,
846 extensionBehavior);
Olli Etuaho19515012017-06-26 18:00:17 +0300847 root->traverse(&collect);
848}
849
Olli Etuaho19515012017-06-26 18:00:17 +0300850} // namespace sh