blob: 8662bf51c72e6aad3b72d023f9e23764a6d5cd34 [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:
Olli Etuaho855d9642017-05-17 14:05:06 +0300111 std::string getMappedName(const TName &name) const;
112
Olli Etuaho19515012017-06-26 18:00:17 +0300113 void setCommonVariableProperties(const TType &type,
Olli Etuaho855d9642017-05-17 14:05:06 +0300114 const TName &name,
Olli Etuaho19515012017-06-26 18:00:17 +0300115 ShaderVariable *variableOut) const;
116
117 Attribute recordAttribute(const TIntermSymbol &variable) const;
118 OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
119 Varying recordVarying(const TIntermSymbol &variable) const;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800120 void recordInterfaceBlock(const TType &interfaceBlockType,
121 InterfaceBlock *interfaceBlock) const;
Olli Etuaho19515012017-06-26 18:00:17 +0300122 Uniform recordUniform(const TIntermSymbol &variable) const;
123
124 void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info);
125
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800126 void recordBuiltInVaryingUsed(const char *name,
127 bool *addedFlag,
128 std::vector<Varying> *varyings);
Olli Etuaho19515012017-06-26 18:00:17 +0300129 void recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag);
130 void recordBuiltInAttributeUsed(const char *name, bool *addedFlag);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800131 InterfaceBlock *recordGLInUsed(const TType &glInType);
132 InterfaceBlock *findNamedInterfaceBlock(const TString &name) const;
Olli Etuaho19515012017-06-26 18:00:17 +0300133
134 std::vector<Attribute> *mAttribs;
135 std::vector<OutputVariable> *mOutputVariables;
136 std::vector<Uniform> *mUniforms;
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800137 std::vector<Varying> *mInputVaryings;
138 std::vector<Varying> *mOutputVaryings;
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800139 std::vector<InterfaceBlock> *mUniformBlocks;
140 std::vector<InterfaceBlock> *mShaderStorageBlocks;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800141 std::vector<InterfaceBlock> *mInBlocks;
Olli Etuaho19515012017-06-26 18:00:17 +0300142
143 std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
144
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800145 // Shader uniforms
Olli Etuaho19515012017-06-26 18:00:17 +0300146 bool mDepthRangeAdded;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800147
148 // Vertex Shader builtins
149 bool mInstanceIDAdded;
150 bool mVertexIDAdded;
151 bool mPointSizeAdded;
152
153 // Vertex Shader and Geometry Shader builtins
154 bool mPositionAdded;
155
156 // Fragment Shader builtins
Olli Etuaho19515012017-06-26 18:00:17 +0300157 bool mPointCoordAdded;
158 bool mFrontFacingAdded;
159 bool mFragCoordAdded;
Olli Etuaho19515012017-06-26 18:00:17 +0300160 bool mLastFragDataAdded;
161 bool mFragColorAdded;
162 bool mFragDataAdded;
163 bool mFragDepthEXTAdded;
164 bool mFragDepthAdded;
165 bool mSecondaryFragColorEXTAdded;
166 bool mSecondaryFragDataEXTAdded;
167
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800168 // Geometry Shader builtins
Jiawei Shaod8105a02017-08-08 09:54:36 +0800169 bool mPerVertexInAdded;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800170 bool mPrimitiveIDInAdded;
171 bool mInvocationIDAdded;
172
173 // Geometry Shader and Fragment Shader builtins
174 bool mPrimitiveIDAdded;
175 bool mLayerAdded;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800176
Olli Etuaho19515012017-06-26 18:00:17 +0300177 ShHashFunction64 mHashFunction;
178
Olli Etuaho19515012017-06-26 18:00:17 +0300179 int mShaderVersion;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800180 GLenum mShaderType;
Olli Etuaho19515012017-06-26 18:00:17 +0300181 const TExtensionBehavior &mExtensionBehavior;
182};
183
184CollectVariablesTraverser::CollectVariablesTraverser(
185 std::vector<sh::Attribute> *attribs,
186 std::vector<sh::OutputVariable> *outputVariables,
187 std::vector<sh::Uniform> *uniforms,
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800188 std::vector<sh::Varying> *inputVaryings,
189 std::vector<sh::Varying> *outputVaryings,
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800190 std::vector<sh::InterfaceBlock> *uniformBlocks,
191 std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800192 std::vector<sh::InterfaceBlock> *inBlocks,
Olli Etuaho19515012017-06-26 18:00:17 +0300193 ShHashFunction64 hashFunction,
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300194 TSymbolTable *symbolTable,
Olli Etuaho19515012017-06-26 18:00:17 +0300195 int shaderVersion,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800196 GLenum shaderType,
Olli Etuaho19515012017-06-26 18:00:17 +0300197 const TExtensionBehavior &extensionBehavior)
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300198 : TIntermTraverser(true, false, false, symbolTable),
Olli Etuaho3d0d9a42015-06-01 12:16:36 +0300199 mAttribs(attribs),
Jamie Madilld5512cd2014-07-10 17:50:08 -0400200 mOutputVariables(outputVariables),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000201 mUniforms(uniforms),
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800202 mInputVaryings(inputVaryings),
203 mOutputVaryings(outputVaryings),
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800204 mUniformBlocks(uniformBlocks),
205 mShaderStorageBlocks(shaderStorageBlocks),
Jiawei Shaod8105a02017-08-08 09:54:36 +0800206 mInBlocks(inBlocks),
Jamie Madill55def582015-05-04 11:24:57 -0400207 mDepthRangeAdded(false),
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800208 mInstanceIDAdded(false),
209 mVertexIDAdded(false),
210 mPointSizeAdded(false),
211 mPositionAdded(false),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400212 mPointCoordAdded(false),
213 mFrontFacingAdded(false),
214 mFragCoordAdded(false),
Erik Dahlströmea7a2122014-11-17 16:15:57 +0100215 mLastFragDataAdded(false),
Kimmo Kinnunen0932df62015-07-21 14:35:11 +0300216 mFragColorAdded(false),
217 mFragDataAdded(false),
Kimmo Kinnunen5f0246c2015-07-22 10:30:35 +0300218 mFragDepthEXTAdded(false),
Kimmo Kinnunen0932df62015-07-21 14:35:11 +0300219 mFragDepthAdded(false),
Kimmo Kinnunenb18609b2015-07-16 14:13:11 +0300220 mSecondaryFragColorEXTAdded(false),
221 mSecondaryFragDataEXTAdded(false),
Jiawei Shaod8105a02017-08-08 09:54:36 +0800222 mPerVertexInAdded(false),
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800223 mPrimitiveIDInAdded(false),
224 mInvocationIDAdded(false),
225 mPrimitiveIDAdded(false),
226 mLayerAdded(false),
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700227 mHashFunction(hashFunction),
Olli Etuaho19515012017-06-26 18:00:17 +0300228 mShaderVersion(shaderVersion),
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800229 mShaderType(shaderType),
Zhenyao Mof178d0b2016-07-23 06:59:00 -0700230 mExtensionBehavior(extensionBehavior)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000231{
232}
233
Olli Etuaho855d9642017-05-17 14:05:06 +0300234std::string CollectVariablesTraverser::getMappedName(const TName &name) const
235{
236 return HashName(name, mHashFunction, nullptr).c_str();
237}
238
Olli Etuaho19515012017-06-26 18:00:17 +0300239void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
240 ShaderVariable *info)
241{
242 TVariable *symbolTableVar =
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300243 reinterpret_cast<TVariable *>(mSymbolTable->findBuiltIn(name, mShaderVersion));
Olli Etuaho19515012017-06-26 18:00:17 +0300244 ASSERT(symbolTableVar);
245 const TType &type = symbolTableVar->getType();
246
247 info->name = name;
248 info->mappedName = name;
249 info->type = GLVariableType(type);
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300250 ASSERT(!type.isArrayOfArrays());
251 info->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
252 info->precision = GLVariablePrecision(type);
Olli Etuaho19515012017-06-26 18:00:17 +0300253}
254
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800255void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name,
256 bool *addedFlag,
257 std::vector<Varying> *varyings)
Olli Etuaho19515012017-06-26 18:00:17 +0300258{
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800259 ASSERT(varyings);
Olli Etuaho19515012017-06-26 18:00:17 +0300260 if (!(*addedFlag))
261 {
262 Varying info;
263 setBuiltInInfoFromSymbolTable(name, &info);
264 info.staticUse = true;
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300265 info.isInvariant = mSymbolTable->isVaryingInvariant(name);
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800266 varyings->push_back(info);
Olli Etuaho19515012017-06-26 18:00:17 +0300267 (*addedFlag) = true;
268 }
269}
270
271void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag)
272{
273 if (!(*addedFlag))
274 {
275 OutputVariable info;
276 setBuiltInInfoFromSymbolTable(name, &info);
277 info.staticUse = true;
278 mOutputVariables->push_back(info);
279 (*addedFlag) = true;
280 }
281}
282
283void CollectVariablesTraverser::recordBuiltInAttributeUsed(const char *name, bool *addedFlag)
284{
285 if (!(*addedFlag))
286 {
287 Attribute info;
288 setBuiltInInfoFromSymbolTable(name, &info);
289 info.staticUse = true;
290 info.location = -1;
291 mAttribs->push_back(info);
292 (*addedFlag) = true;
293 }
294}
295
Jiawei Shaod8105a02017-08-08 09:54:36 +0800296InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType)
297{
298 if (!mPerVertexInAdded)
299 {
300 ASSERT(glInType.getQualifier() == EvqPerVertexIn);
301 InterfaceBlock info;
302 recordInterfaceBlock(glInType, &info);
303 info.staticUse = true;
304
305 mPerVertexInAdded = true;
306 mInBlocks->push_back(info);
307 return &mInBlocks->back();
308 }
309 else
310 {
311 return FindVariable("gl_PerVertex", mInBlocks);
312 }
313}
314
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400315// We want to check whether a uniform/varying is statically used
316// because we only count the used ones in packing computing.
317// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
318// toward varying counting if they are statically used in a fragment
319// shader.
Olli Etuaho19515012017-06-26 18:00:17 +0300320void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000321{
Yunchao He4f285442017-04-21 12:15:49 +0800322 ASSERT(symbol != nullptr);
Olli Etuaho34d20072017-07-18 20:07:18 +0300323
324 if (symbol->getName().isInternal())
325 {
326 // Internal variables are not collected.
327 return;
328 }
329
Yunchao Hed7297bf2017-04-19 15:27:10 +0800330 ShaderVariable *var = nullptr;
Olli Etuaho34d20072017-07-18 20:07:18 +0300331 const TString &symbolName = symbol->getName().getString();
Jamie Madill4667c452014-07-08 15:02:36 -0400332
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800333 if (IsVaryingIn(symbol->getQualifier()))
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400334 {
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800335 var = FindVariable(symbolName, mInputVaryings);
336 }
337 else if (IsVaryingOut(symbol->getQualifier()))
338 {
339 var = FindVariable(symbolName, mOutputVaryings);
Jamie Madill4667c452014-07-08 15:02:36 -0400340 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400341 else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
342 {
343 UNREACHABLE();
344 }
Jamie Madill55def582015-05-04 11:24:57 -0400345 else if (symbolName == "gl_DepthRange")
346 {
347 ASSERT(symbol->getQualifier() == EvqUniform);
348
349 if (!mDepthRangeAdded)
350 {
351 Uniform info;
352 const char kName[] = "gl_DepthRange";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500353 info.name = kName;
354 info.mappedName = kName;
Jamie Madillf00f7ff2017-08-31 14:39:15 -0400355 info.type = GL_NONE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500356 info.arraySize = 0;
357 info.precision = GL_NONE;
358 info.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400359
360 ShaderVariable nearInfo;
361 const char kNearName[] = "near";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500362 nearInfo.name = kNearName;
363 nearInfo.mappedName = kNearName;
364 nearInfo.type = GL_FLOAT;
365 nearInfo.arraySize = 0;
366 nearInfo.precision = GL_HIGH_FLOAT;
367 nearInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400368
369 ShaderVariable farInfo;
370 const char kFarName[] = "far";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500371 farInfo.name = kFarName;
372 farInfo.mappedName = kFarName;
373 farInfo.type = GL_FLOAT;
374 farInfo.arraySize = 0;
375 farInfo.precision = GL_HIGH_FLOAT;
376 farInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400377
378 ShaderVariable diffInfo;
379 const char kDiffName[] = "diff";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500380 diffInfo.name = kDiffName;
381 diffInfo.mappedName = kDiffName;
382 diffInfo.type = GL_FLOAT;
383 diffInfo.arraySize = 0;
384 diffInfo.precision = GL_HIGH_FLOAT;
385 diffInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400386
387 info.fields.push_back(nearInfo);
388 info.fields.push_back(farInfo);
389 info.fields.push_back(diffInfo);
390
391 mUniforms->push_back(info);
392 mDepthRangeAdded = true;
393 }
394 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400395 else
Jamie Madill4667c452014-07-08 15:02:36 -0400396 {
397 switch (symbol->getQualifier())
Jamie Madilla718c1e2014-07-02 15:31:22 -0400398 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500399 case EvqAttribute:
400 case EvqVertexIn:
401 var = FindVariable(symbolName, mAttribs);
402 break;
403 case EvqFragmentOut:
404 var = FindVariable(symbolName, mOutputVariables);
405 break;
406 case EvqUniform:
Jamie Madilld5512cd2014-07-10 17:50:08 -0400407 {
408 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
409 if (interfaceBlock)
410 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500411 InterfaceBlock *namedBlock =
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800412 FindVariable(interfaceBlock->name(), mUniformBlocks);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400413 ASSERT(namedBlock);
414 var = FindVariable(symbolName, &namedBlock->fields);
415
416 // Set static use on the parent interface block here
417 namedBlock->staticUse = true;
418 }
419 else
420 {
421 var = FindVariable(symbolName, mUniforms);
422 }
423
424 // It's an internal error to reference an undefined user uniform
Jamie Madill55def582015-05-04 11:24:57 -0400425 ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400426 }
Jamie Madill4667c452014-07-08 15:02:36 -0400427 break;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500428 case EvqFragCoord:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800429 recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500430 return;
431 case EvqFrontFacing:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800432 recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500433 return;
434 case EvqPointCoord:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800435 recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500436 return;
437 case EvqInstanceID:
Martin Radev115fc552017-07-05 17:11:06 +0300438 // Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set,
439 // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
440 // InstanceID. gl_InstanceID is not added to the symbol table for ESSL1 shaders
441 // which makes it necessary to populate the type information explicitly instead of
442 // extracting it from the symbol table.
443 if (!mInstanceIDAdded)
444 {
445 Attribute info;
446 const char kName[] = "gl_InstanceID";
447 info.name = kName;
448 info.mappedName = kName;
449 info.type = GL_INT;
450 info.arraySize = 0;
451 info.precision = GL_HIGH_INT; // Defined by spec.
452 info.staticUse = true;
453 info.location = -1;
454 mAttribs->push_back(info);
455 mInstanceIDAdded = true;
456 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500457 return;
458 case EvqVertexID:
Olli Etuaho19515012017-06-26 18:00:17 +0300459 recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500460 return;
461 case EvqPosition:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800462 recordBuiltInVaryingUsed("gl_Position", &mPositionAdded, mOutputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500463 return;
464 case EvqPointSize:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800465 recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded, mOutputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500466 return;
467 case EvqLastFragData:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800468 recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500469 return;
470 case EvqFragColor:
Olli Etuaho19515012017-06-26 18:00:17 +0300471 recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500472 return;
473 case EvqFragData:
474 if (!mFragDataAdded)
475 {
476 OutputVariable info;
Olli Etuaho19515012017-06-26 18:00:17 +0300477 setBuiltInInfoFromSymbolTable("gl_FragData", &info);
478 if (!::IsExtensionEnabled(mExtensionBehavior, "GL_EXT_draw_buffers"))
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500479 {
480 info.arraySize = 1;
481 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500482 info.staticUse = true;
483 mOutputVariables->push_back(info);
484 mFragDataAdded = true;
485 }
486 return;
487 case EvqFragDepthEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300488 recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500489 return;
490 case EvqFragDepth:
Olli Etuaho19515012017-06-26 18:00:17 +0300491 recordBuiltInFragmentOutputUsed("gl_FragDepth", &mFragDepthAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500492 return;
493 case EvqSecondaryFragColorEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300494 recordBuiltInFragmentOutputUsed("gl_SecondaryFragColorEXT",
495 &mSecondaryFragColorEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500496 return;
497 case EvqSecondaryFragDataEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300498 recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT",
499 &mSecondaryFragDataEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500500 return;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800501 case EvqInvocationID:
502 recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings);
503 break;
504 case EvqPrimitiveIDIn:
505 recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings);
506 break;
507 case EvqPrimitiveID:
508 if (mShaderType == GL_GEOMETRY_SHADER_OES)
509 {
510 recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings);
511 }
512 else
513 {
514 ASSERT(mShaderType == GL_FRAGMENT_SHADER);
515 recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings);
516 }
517 break;
518 case EvqLayer:
519 if (mShaderType == GL_GEOMETRY_SHADER_OES)
520 {
521 recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings);
522 }
523 else if (mShaderType == GL_FRAGMENT_SHADER)
524 {
525 recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings);
526 }
527 else
528 {
529 ASSERT(mShaderType == GL_VERTEX_SHADER &&
Olli Etuahoec3a9cb2017-09-07 12:18:01 +0300530 IsExtensionEnabled(mExtensionBehavior, "GL_OVR_multiview"));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800531 }
532 break;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500533 default:
534 break;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400535 }
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400536 }
537 if (var)
Jamie Madilla718c1e2014-07-02 15:31:22 -0400538 {
Olli Etuaho06a06f52017-07-12 12:22:15 +0300539 MarkStaticallyUsed(var);
Jamie Madilla718c1e2014-07-02 15:31:22 -0400540 }
541}
542
Olli Etuaho19515012017-06-26 18:00:17 +0300543void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
Olli Etuaho855d9642017-05-17 14:05:06 +0300544 const TName &name,
Olli Etuaho19515012017-06-26 18:00:17 +0300545 ShaderVariable *variableOut) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400546{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000547 ASSERT(variableOut);
548
549 const TStructure *structure = type.getStruct();
550
551 if (!structure)
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500552 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000553 variableOut->type = GLVariableType(type);
554 variableOut->precision = GLVariablePrecision(type);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500555 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000556 else
Jamie Madill23a8a432014-07-09 13:27:42 -0400557 {
Jamie Madillf00f7ff2017-08-31 14:39:15 -0400558 // Structures use a NONE type that isn't exposed outside ANGLE.
559 variableOut->type = GL_NONE;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000560 variableOut->structName = structure->name().c_str();
561
562 const TFieldList &fields = structure->fields();
563
564 for (TField *field : fields)
565 {
566 // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
567 // ShaderVariable objects.
568 ShaderVariable fieldVariable;
Olli Etuaho855d9642017-05-17 14:05:06 +0300569 setCommonVariableProperties(*field->type(), TName(field->name()), &fieldVariable);
Olli Etuahoa55102c2017-02-24 12:36:50 +0000570 variableOut->fields.push_back(fieldVariable);
571 }
Jamie Madill23a8a432014-07-09 13:27:42 -0400572 }
Olli Etuaho855d9642017-05-17 14:05:06 +0300573 variableOut->name = name.getString().c_str();
574 variableOut->mappedName = getMappedName(name);
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300575
576 // TODO(oetuaho@nvidia.com): Uniforms can be arrays of arrays, so this assert will need to be
577 // removed.
578 ASSERT(!type.isArrayOfArrays());
579 variableOut->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000580}
Jamie Madill23a8a432014-07-09 13:27:42 -0400581
Olli Etuaho19515012017-06-26 18:00:17 +0300582Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400583{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000584 const TType &type = variable.getType();
Jamie Madill23a8a432014-07-09 13:27:42 -0400585 ASSERT(!type.getStruct());
586
Jamie Madilla2fbb842014-09-03 09:40:47 -0400587 Attribute attribute;
Olli Etuaho855d9642017-05-17 14:05:06 +0300588 setCommonVariableProperties(type, variable.getName(), &attribute);
Jamie Madill23a8a432014-07-09 13:27:42 -0400589
Olli Etuahoa55102c2017-02-24 12:36:50 +0000590 attribute.location = type.getLayoutQualifier().location;
591 return attribute;
Jamie Madill23a8a432014-07-09 13:27:42 -0400592}
593
Olli Etuaho19515012017-06-26 18:00:17 +0300594OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
Jamie Madilla0a9e122015-09-02 15:54:30 -0400595{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000596 const TType &type = variable.getType();
Jamie Madilla0a9e122015-09-02 15:54:30 -0400597 ASSERT(!type.getStruct());
598
Olli Etuahoa55102c2017-02-24 12:36:50 +0000599 OutputVariable outputVariable;
Olli Etuaho855d9642017-05-17 14:05:06 +0300600 setCommonVariableProperties(type, variable.getName(), &outputVariable);
Jamie Madilla0a9e122015-09-02 15:54:30 -0400601
Olli Etuahoa55102c2017-02-24 12:36:50 +0000602 outputVariable.location = type.getLayoutQualifier().location;
603 return outputVariable;
Jamie Madilla0a9e122015-09-02 15:54:30 -0400604}
605
Olli Etuaho19515012017-06-26 18:00:17 +0300606Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
Jamie Madilld5512cd2014-07-10 17:50:08 -0400607{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000608 const TType &type = variable.getType();
609
610 Varying varying;
Olli Etuaho855d9642017-05-17 14:05:06 +0300611 setCommonVariableProperties(type, variable.getName(), &varying);
Olli Etuahoa55102c2017-02-24 12:36:50 +0000612
613 switch (type.getQualifier())
614 {
615 case EvqVaryingIn:
616 case EvqVaryingOut:
617 case EvqVertexOut:
618 case EvqSmoothOut:
619 case EvqFlatOut:
620 case EvqCentroidOut:
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300621 if (mSymbolTable->isVaryingInvariant(std::string(variable.getSymbol().c_str())) ||
Olli Etuahoa55102c2017-02-24 12:36:50 +0000622 type.isInvariant())
623 {
624 varying.isInvariant = true;
625 }
626 break;
627 default:
628 break;
629 }
630
631 varying.interpolation = GetInterpolationType(type.getQualifier());
632 return varying;
633}
634
Jiawei Shaod8105a02017-08-08 09:54:36 +0800635// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
636void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlockType,
637 InterfaceBlock *interfaceBlock) const
Olli Etuahoa55102c2017-02-24 12:36:50 +0000638{
Jiawei Shaod8105a02017-08-08 09:54:36 +0800639 ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
640 ASSERT(interfaceBlock);
641
642 const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
Jamie Madill42bcf322014-08-25 16:20:46 -0400643 ASSERT(blockType);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400644
Jiawei Shaod8105a02017-08-08 09:54:36 +0800645 interfaceBlock->name = blockType->name().c_str();
Olli Etuaho855d9642017-05-17 14:05:06 +0300646 interfaceBlock->mappedName = getMappedName(TName(blockType->name()));
Jiawei Shaod8105a02017-08-08 09:54:36 +0800647 interfaceBlock->instanceName =
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500648 (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300649 ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
650 interfaceBlock->arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800651
652 interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
653 if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM ||
654 interfaceBlock->blockType == BlockType::BLOCK_BUFFER)
655 {
656 interfaceBlock->isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
657 interfaceBlock->binding = blockType->blockBinding();
658 interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage());
659 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400660
Jamie Madilla6f267f2014-08-27 11:44:15 -0400661 // Gather field information
Jamie Madill39046162016-02-08 15:05:17 -0500662 for (const TField *field : blockType->fields())
Jamie Madill54ad4f82014-09-03 09:40:46 -0400663 {
Jamie Madill39046162016-02-08 15:05:17 -0500664 const TType &fieldType = *field->type();
Jamie Madill54ad4f82014-09-03 09:40:46 -0400665
Olli Etuahoa55102c2017-02-24 12:36:50 +0000666 InterfaceBlockField fieldVariable;
Olli Etuaho855d9642017-05-17 14:05:06 +0300667 setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
Olli Etuahoa55102c2017-02-24 12:36:50 +0000668 fieldVariable.isRowMajorLayout =
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500669 (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800670 interfaceBlock->fields.push_back(fieldVariable);
Jamie Madill54ad4f82014-09-03 09:40:46 -0400671 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400672}
673
Olli Etuaho19515012017-06-26 18:00:17 +0300674Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
Jamie Madill4667c452014-07-08 15:02:36 -0400675{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000676 Uniform uniform;
Olli Etuaho855d9642017-05-17 14:05:06 +0300677 setCommonVariableProperties(variable.getType(), variable.getName(), &uniform);
Olli Etuaho78ed6cd2017-08-09 16:19:00 +0300678 uniform.binding = variable.getType().getLayoutQualifier().binding;
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000679 uniform.location = variable.getType().getLayoutQualifier().location;
jchen104cdac9e2017-05-08 11:01:20 +0800680 uniform.offset = variable.getType().getLayoutQualifier().offset;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000681 return uniform;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000682}
683
Olli Etuaho19515012017-06-26 18:00:17 +0300684bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000685{
Olli Etuaho13389b62016-10-16 11:48:18 +0100686 const TIntermSequence &sequence = *(node->getSequence());
687 ASSERT(!sequence.empty());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000688
Olli Etuaho13389b62016-10-16 11:48:18 +0100689 const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
690 TQualifier qualifier = typedNode.getQualifier();
691
Olli Etuahoa55102c2017-02-24 12:36:50 +0000692 bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn ||
693 qualifier == EvqFragmentOut || qualifier == EvqUniform ||
694 IsVarying(qualifier);
695
696 if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000697 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000698 return true;
Olli Etuaho13389b62016-10-16 11:48:18 +0100699 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000700
701 for (TIntermNode *variableNode : sequence)
Olli Etuaho13389b62016-10-16 11:48:18 +0100702 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000703 // The only case in which the sequence will not contain a TIntermSymbol node is
704 // initialization. It will contain a TInterBinary node in that case. Since attributes,
705 // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
706 // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
707 const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
Olli Etuaho34d20072017-07-18 20:07:18 +0300708 if (variable.getName().isInternal())
709 {
710 // Internal variables are not collected.
711 continue;
712 }
713
Jiawei Shaod8105a02017-08-08 09:54:36 +0800714 // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
Olli Etuahoa55102c2017-02-24 12:36:50 +0000715 if (typedNode.getBasicType() == EbtInterfaceBlock)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000716 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800717 InterfaceBlock interfaceBlock;
718 recordInterfaceBlock(variable.getType(), &interfaceBlock);
719
720 switch (qualifier)
Jiajia Qinbc585152017-06-23 15:42:17 +0800721 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800722 case EvqUniform:
723 mUniformBlocks->push_back(interfaceBlock);
724 break;
725 case EvqBuffer:
726 mShaderStorageBlocks->push_back(interfaceBlock);
727 break;
728 default:
729 UNREACHABLE();
Jiajia Qinbc585152017-06-23 15:42:17 +0800730 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000731 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000732 else
733 {
734 switch (qualifier)
735 {
736 case EvqAttribute:
737 case EvqVertexIn:
738 mAttribs->push_back(recordAttribute(variable));
739 break;
740 case EvqFragmentOut:
741 mOutputVariables->push_back(recordOutputVariable(variable));
742 break;
743 case EvqUniform:
744 mUniforms->push_back(recordUniform(variable));
745 break;
746 default:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800747 if (IsVaryingIn(qualifier))
748 {
749 mInputVaryings->push_back(recordVarying(variable));
750 }
751 else
752 {
753 ASSERT(IsVaryingOut(qualifier));
754 mOutputVaryings->push_back(recordVarying(variable));
755 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000756 break;
757 }
758 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000759 }
760
Olli Etuahoa55102c2017-02-24 12:36:50 +0000761 // None of the recorded variables can have initializers, so we don't need to traverse the
762 // declarators.
763 return false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000764}
Jamie Madill23a8a432014-07-09 13:27:42 -0400765
Jiawei Shaod8105a02017-08-08 09:54:36 +0800766// TODO(jiawei.shao@intel.com): add search on mInBlocks and mOutBlocks when implementing
767// GL_OES_shader_io_blocks.
768InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(const TString &blockName) const
769{
770 InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
771 if (!namedBlock)
772 {
773 namedBlock = FindVariable(blockName, mShaderStorageBlocks);
774 }
775 return namedBlock;
776}
777
Olli Etuaho19515012017-06-26 18:00:17 +0300778bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
Jamie Madillb547ddf2014-08-25 16:20:46 -0400779{
780 if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
781 {
Jamie Madilla6f267f2014-08-27 11:44:15 -0400782 // NOTE: we do not determine static use for individual blocks of an array
783 TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
784 ASSERT(blockNode);
Jamie Madillb547ddf2014-08-25 16:20:46 -0400785
786 TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
787 ASSERT(constantUnion);
788
Jiawei Shaod8105a02017-08-08 09:54:36 +0800789 InterfaceBlock *namedBlock = nullptr;
790
791 bool traverseIndexExpression = false;
792 TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
793 if (interfaceIndexingNode)
794 {
795 TIntermTyped *interfaceNode = interfaceIndexingNode->getLeft()->getAsTyped();
796 ASSERT(interfaceNode);
797
798 const TType &interfaceType = interfaceNode->getType();
799 if (interfaceType.getQualifier() == EvqPerVertexIn)
800 {
801 namedBlock = recordGLInUsed(interfaceType);
802 ASSERT(namedBlock);
803
804 // We need to continue traversing to collect useful variables in the index
805 // expression of gl_in.
806 traverseIndexExpression = true;
807 }
808 }
809
Jamie Madilla6f267f2014-08-27 11:44:15 -0400810 const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800811 if (!namedBlock)
Jiajia Qinbc585152017-06-23 15:42:17 +0800812 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800813 namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
Jiajia Qinbc585152017-06-23 15:42:17 +0800814 }
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800815 ASSERT(namedBlock);
816 namedBlock->staticUse = true;
817 unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
818 ASSERT(fieldIndex < namedBlock->fields.size());
819 namedBlock->fields[fieldIndex].staticUse = true;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800820
821 if (traverseIndexExpression)
822 {
823 ASSERT(interfaceIndexingNode);
824 interfaceIndexingNode->getRight()->traverse(this);
825 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400826 return false;
827 }
828
829 return true;
830}
831
Olli Etuaho19515012017-06-26 18:00:17 +0300832} // anonymous namespace
833
834void CollectVariables(TIntermBlock *root,
835 std::vector<Attribute> *attributes,
836 std::vector<OutputVariable> *outputVariables,
837 std::vector<Uniform> *uniforms,
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800838 std::vector<Varying> *inputVaryings,
839 std::vector<Varying> *outputVaryings,
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800840 std::vector<InterfaceBlock> *uniformBlocks,
841 std::vector<InterfaceBlock> *shaderStorageBlocks,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800842 std::vector<InterfaceBlock> *inBlocks,
Olli Etuaho19515012017-06-26 18:00:17 +0300843 ShHashFunction64 hashFunction,
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300844 TSymbolTable *symbolTable,
Olli Etuaho19515012017-06-26 18:00:17 +0300845 int shaderVersion,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800846 GLenum shaderType,
Olli Etuaho19515012017-06-26 18:00:17 +0300847 const TExtensionBehavior &extensionBehavior)
848{
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800849 CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800850 outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800851 hashFunction, symbolTable, shaderVersion, shaderType,
852 extensionBehavior);
Olli Etuaho19515012017-06-26 18:00:17 +0300853 root->traverse(&collect);
854}
855
Olli Etuaho19515012017-06-26 18:00:17 +0300856} // namespace sh