blob: 26378dc5faf1437b8f51a67426e22048dadb9e8f [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.precision = GL_NONE;
357 info.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400358
Olli Etuahoe7c28572017-10-23 16:29:33 +0300359 ShaderVariable nearInfo(GL_FLOAT);
Jamie Madill55def582015-05-04 11:24:57 -0400360 const char kNearName[] = "near";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500361 nearInfo.name = kNearName;
362 nearInfo.mappedName = kNearName;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500363 nearInfo.precision = GL_HIGH_FLOAT;
364 nearInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400365
Olli Etuahoe7c28572017-10-23 16:29:33 +0300366 ShaderVariable farInfo(GL_FLOAT);
Jamie Madill55def582015-05-04 11:24:57 -0400367 const char kFarName[] = "far";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500368 farInfo.name = kFarName;
369 farInfo.mappedName = kFarName;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500370 farInfo.precision = GL_HIGH_FLOAT;
371 farInfo.staticUse = true;
Jamie Madill55def582015-05-04 11:24:57 -0400372
Olli Etuahoe7c28572017-10-23 16:29:33 +0300373 ShaderVariable diffInfo(GL_FLOAT);
Jamie Madill55def582015-05-04 11:24:57 -0400374 const char kDiffName[] = "diff";
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500375 diffInfo.name = kDiffName;
376 diffInfo.mappedName = kDiffName;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500377 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;
Martin Radev115fc552017-07-05 17:11:06 +0300443 info.precision = GL_HIGH_INT; // Defined by spec.
444 info.staticUse = true;
445 info.location = -1;
446 mAttribs->push_back(info);
447 mInstanceIDAdded = true;
448 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500449 return;
450 case EvqVertexID:
Olli Etuaho19515012017-06-26 18:00:17 +0300451 recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500452 return;
453 case EvqPosition:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800454 recordBuiltInVaryingUsed("gl_Position", &mPositionAdded, mOutputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500455 return;
456 case EvqPointSize:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800457 recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded, mOutputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500458 return;
459 case EvqLastFragData:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800460 recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded, mInputVaryings);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 return;
462 case EvqFragColor:
Olli Etuaho19515012017-06-26 18:00:17 +0300463 recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500464 return;
465 case EvqFragData:
466 if (!mFragDataAdded)
467 {
468 OutputVariable info;
Olli Etuaho19515012017-06-26 18:00:17 +0300469 setBuiltInInfoFromSymbolTable("gl_FragData", &info);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300470 if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500471 {
472 info.arraySize = 1;
473 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500474 info.staticUse = true;
475 mOutputVariables->push_back(info);
476 mFragDataAdded = true;
477 }
478 return;
479 case EvqFragDepthEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300480 recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500481 return;
482 case EvqFragDepth:
Olli Etuaho19515012017-06-26 18:00:17 +0300483 recordBuiltInFragmentOutputUsed("gl_FragDepth", &mFragDepthAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500484 return;
485 case EvqSecondaryFragColorEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300486 recordBuiltInFragmentOutputUsed("gl_SecondaryFragColorEXT",
487 &mSecondaryFragColorEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500488 return;
489 case EvqSecondaryFragDataEXT:
Olli Etuaho19515012017-06-26 18:00:17 +0300490 recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT",
491 &mSecondaryFragDataEXTAdded);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500492 return;
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800493 case EvqInvocationID:
494 recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings);
495 break;
496 case EvqPrimitiveIDIn:
497 recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings);
498 break;
499 case EvqPrimitiveID:
500 if (mShaderType == GL_GEOMETRY_SHADER_OES)
501 {
502 recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings);
503 }
504 else
505 {
506 ASSERT(mShaderType == GL_FRAGMENT_SHADER);
507 recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings);
508 }
509 break;
510 case EvqLayer:
511 if (mShaderType == GL_GEOMETRY_SHADER_OES)
512 {
513 recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings);
514 }
515 else if (mShaderType == GL_FRAGMENT_SHADER)
516 {
517 recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings);
518 }
519 else
520 {
521 ASSERT(mShaderType == GL_VERTEX_SHADER &&
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300522 IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800523 }
524 break;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500525 default:
526 break;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400527 }
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400528 }
529 if (var)
Jamie Madilla718c1e2014-07-02 15:31:22 -0400530 {
Olli Etuaho06a06f52017-07-12 12:22:15 +0300531 MarkStaticallyUsed(var);
Jamie Madilla718c1e2014-07-02 15:31:22 -0400532 }
533}
534
Olli Etuaho19515012017-06-26 18:00:17 +0300535void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
Olli Etuaho855d9642017-05-17 14:05:06 +0300536 const TName &name,
Olli Etuaho19515012017-06-26 18:00:17 +0300537 ShaderVariable *variableOut) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400538{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000539 ASSERT(variableOut);
540
541 const TStructure *structure = type.getStruct();
542
543 if (!structure)
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500544 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000545 variableOut->type = GLVariableType(type);
546 variableOut->precision = GLVariablePrecision(type);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500547 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000548 else
Jamie Madill23a8a432014-07-09 13:27:42 -0400549 {
Jamie Madillf00f7ff2017-08-31 14:39:15 -0400550 // Structures use a NONE type that isn't exposed outside ANGLE.
551 variableOut->type = GL_NONE;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000552 variableOut->structName = structure->name().c_str();
553
554 const TFieldList &fields = structure->fields();
555
556 for (TField *field : fields)
557 {
558 // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
559 // ShaderVariable objects.
560 ShaderVariable fieldVariable;
Olli Etuaho855d9642017-05-17 14:05:06 +0300561 setCommonVariableProperties(*field->type(), TName(field->name()), &fieldVariable);
Olli Etuahoa55102c2017-02-24 12:36:50 +0000562 variableOut->fields.push_back(fieldVariable);
563 }
Jamie Madill23a8a432014-07-09 13:27:42 -0400564 }
Olli Etuaho855d9642017-05-17 14:05:06 +0300565 variableOut->name = name.getString().c_str();
566 variableOut->mappedName = getMappedName(name);
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300567
568 // TODO(oetuaho@nvidia.com): Uniforms can be arrays of arrays, so this assert will need to be
569 // removed.
570 ASSERT(!type.isArrayOfArrays());
571 variableOut->arraySize = type.isArray() ? type.getOutermostArraySize() : 0;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000572}
Jamie Madill23a8a432014-07-09 13:27:42 -0400573
Olli Etuaho19515012017-06-26 18:00:17 +0300574Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400575{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000576 const TType &type = variable.getType();
Jamie Madill23a8a432014-07-09 13:27:42 -0400577 ASSERT(!type.getStruct());
578
Jamie Madilla2fbb842014-09-03 09:40:47 -0400579 Attribute attribute;
Olli Etuaho855d9642017-05-17 14:05:06 +0300580 setCommonVariableProperties(type, variable.getName(), &attribute);
Jamie Madill23a8a432014-07-09 13:27:42 -0400581
Olli Etuahoa55102c2017-02-24 12:36:50 +0000582 attribute.location = type.getLayoutQualifier().location;
583 return attribute;
Jamie Madill23a8a432014-07-09 13:27:42 -0400584}
585
Olli Etuaho19515012017-06-26 18:00:17 +0300586OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
Jamie Madilla0a9e122015-09-02 15:54:30 -0400587{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000588 const TType &type = variable.getType();
Jamie Madilla0a9e122015-09-02 15:54:30 -0400589 ASSERT(!type.getStruct());
590
Olli Etuahoa55102c2017-02-24 12:36:50 +0000591 OutputVariable outputVariable;
Olli Etuaho855d9642017-05-17 14:05:06 +0300592 setCommonVariableProperties(type, variable.getName(), &outputVariable);
Jamie Madilla0a9e122015-09-02 15:54:30 -0400593
Olli Etuahoa55102c2017-02-24 12:36:50 +0000594 outputVariable.location = type.getLayoutQualifier().location;
595 return outputVariable;
Jamie Madilla0a9e122015-09-02 15:54:30 -0400596}
597
Olli Etuaho19515012017-06-26 18:00:17 +0300598Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
Jamie Madilld5512cd2014-07-10 17:50:08 -0400599{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000600 const TType &type = variable.getType();
601
602 Varying varying;
Olli Etuaho855d9642017-05-17 14:05:06 +0300603 setCommonVariableProperties(type, variable.getName(), &varying);
Jiawei Shao4cc89e22017-08-31 14:25:54 +0800604 varying.location = type.getLayoutQualifier().location;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000605
606 switch (type.getQualifier())
607 {
608 case EvqVaryingIn:
609 case EvqVaryingOut:
610 case EvqVertexOut:
611 case EvqSmoothOut:
612 case EvqFlatOut:
613 case EvqCentroidOut:
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300614 if (mSymbolTable->isVaryingInvariant(std::string(variable.getSymbol().c_str())) ||
Olli Etuahoa55102c2017-02-24 12:36:50 +0000615 type.isInvariant())
616 {
617 varying.isInvariant = true;
618 }
619 break;
620 default:
621 break;
622 }
623
624 varying.interpolation = GetInterpolationType(type.getQualifier());
625 return varying;
626}
627
Jiawei Shaod8105a02017-08-08 09:54:36 +0800628// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
629void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlockType,
630 InterfaceBlock *interfaceBlock) const
Olli Etuahoa55102c2017-02-24 12:36:50 +0000631{
Jiawei Shaod8105a02017-08-08 09:54:36 +0800632 ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
633 ASSERT(interfaceBlock);
634
635 const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
Jamie Madill42bcf322014-08-25 16:20:46 -0400636 ASSERT(blockType);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400637
Jiawei Shaod8105a02017-08-08 09:54:36 +0800638 interfaceBlock->name = blockType->name().c_str();
Olli Etuaho855d9642017-05-17 14:05:06 +0300639 interfaceBlock->mappedName = getMappedName(TName(blockType->name()));
Jiawei Shaod8105a02017-08-08 09:54:36 +0800640 interfaceBlock->instanceName =
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500641 (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300642 ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
643 interfaceBlock->arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800644
645 interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
646 if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM ||
647 interfaceBlock->blockType == BlockType::BLOCK_BUFFER)
648 {
649 interfaceBlock->isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
650 interfaceBlock->binding = blockType->blockBinding();
651 interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage());
652 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400653
Jamie Madilla6f267f2014-08-27 11:44:15 -0400654 // Gather field information
Jamie Madill39046162016-02-08 15:05:17 -0500655 for (const TField *field : blockType->fields())
Jamie Madill54ad4f82014-09-03 09:40:46 -0400656 {
Jamie Madill39046162016-02-08 15:05:17 -0500657 const TType &fieldType = *field->type();
Jamie Madill54ad4f82014-09-03 09:40:46 -0400658
Olli Etuahoa55102c2017-02-24 12:36:50 +0000659 InterfaceBlockField fieldVariable;
Olli Etuaho855d9642017-05-17 14:05:06 +0300660 setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
Olli Etuahoa55102c2017-02-24 12:36:50 +0000661 fieldVariable.isRowMajorLayout =
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500662 (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800663 interfaceBlock->fields.push_back(fieldVariable);
Jamie Madill54ad4f82014-09-03 09:40:46 -0400664 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400665}
666
Olli Etuaho19515012017-06-26 18:00:17 +0300667Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
Jamie Madill4667c452014-07-08 15:02:36 -0400668{
Olli Etuahoa55102c2017-02-24 12:36:50 +0000669 Uniform uniform;
Olli Etuaho855d9642017-05-17 14:05:06 +0300670 setCommonVariableProperties(variable.getType(), variable.getName(), &uniform);
Olli Etuaho78ed6cd2017-08-09 16:19:00 +0300671 uniform.binding = variable.getType().getLayoutQualifier().binding;
Olli Etuaho6ca2b652017-02-19 18:05:10 +0000672 uniform.location = variable.getType().getLayoutQualifier().location;
jchen104cdac9e2017-05-08 11:01:20 +0800673 uniform.offset = variable.getType().getLayoutQualifier().offset;
Olli Etuahoa55102c2017-02-24 12:36:50 +0000674 return uniform;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000675}
676
Olli Etuaho19515012017-06-26 18:00:17 +0300677bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000678{
Olli Etuaho13389b62016-10-16 11:48:18 +0100679 const TIntermSequence &sequence = *(node->getSequence());
680 ASSERT(!sequence.empty());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000681
Olli Etuaho13389b62016-10-16 11:48:18 +0100682 const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
683 TQualifier qualifier = typedNode.getQualifier();
684
Olli Etuahoa55102c2017-02-24 12:36:50 +0000685 bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn ||
686 qualifier == EvqFragmentOut || qualifier == EvqUniform ||
687 IsVarying(qualifier);
688
689 if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000690 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000691 return true;
Olli Etuaho13389b62016-10-16 11:48:18 +0100692 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000693
694 for (TIntermNode *variableNode : sequence)
Olli Etuaho13389b62016-10-16 11:48:18 +0100695 {
Olli Etuahoa55102c2017-02-24 12:36:50 +0000696 // The only case in which the sequence will not contain a TIntermSymbol node is
697 // initialization. It will contain a TInterBinary node in that case. Since attributes,
698 // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
699 // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
700 const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
Olli Etuaho34d20072017-07-18 20:07:18 +0300701 if (variable.getName().isInternal())
702 {
703 // Internal variables are not collected.
704 continue;
705 }
706
Jiawei Shaod8105a02017-08-08 09:54:36 +0800707 // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks.
Olli Etuahoa55102c2017-02-24 12:36:50 +0000708 if (typedNode.getBasicType() == EbtInterfaceBlock)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000709 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800710 InterfaceBlock interfaceBlock;
711 recordInterfaceBlock(variable.getType(), &interfaceBlock);
712
713 switch (qualifier)
Jiajia Qinbc585152017-06-23 15:42:17 +0800714 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800715 case EvqUniform:
716 mUniformBlocks->push_back(interfaceBlock);
717 break;
718 case EvqBuffer:
719 mShaderStorageBlocks->push_back(interfaceBlock);
720 break;
721 default:
722 UNREACHABLE();
Jiajia Qinbc585152017-06-23 15:42:17 +0800723 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000724 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000725 else
726 {
727 switch (qualifier)
728 {
729 case EvqAttribute:
730 case EvqVertexIn:
731 mAttribs->push_back(recordAttribute(variable));
732 break;
733 case EvqFragmentOut:
734 mOutputVariables->push_back(recordOutputVariable(variable));
735 break;
736 case EvqUniform:
737 mUniforms->push_back(recordUniform(variable));
738 break;
739 default:
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800740 if (IsVaryingIn(qualifier))
741 {
742 mInputVaryings->push_back(recordVarying(variable));
743 }
744 else
745 {
746 ASSERT(IsVaryingOut(qualifier));
747 mOutputVaryings->push_back(recordVarying(variable));
748 }
Olli Etuahoa55102c2017-02-24 12:36:50 +0000749 break;
750 }
751 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000752 }
753
Olli Etuahoa55102c2017-02-24 12:36:50 +0000754 // None of the recorded variables can have initializers, so we don't need to traverse the
755 // declarators.
756 return false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000757}
Jamie Madill23a8a432014-07-09 13:27:42 -0400758
Jiawei Shaod8105a02017-08-08 09:54:36 +0800759// TODO(jiawei.shao@intel.com): add search on mInBlocks and mOutBlocks when implementing
760// GL_OES_shader_io_blocks.
761InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(const TString &blockName) const
762{
763 InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
764 if (!namedBlock)
765 {
766 namedBlock = FindVariable(blockName, mShaderStorageBlocks);
767 }
768 return namedBlock;
769}
770
Olli Etuaho19515012017-06-26 18:00:17 +0300771bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
Jamie Madillb547ddf2014-08-25 16:20:46 -0400772{
773 if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
774 {
Jamie Madilla6f267f2014-08-27 11:44:15 -0400775 // NOTE: we do not determine static use for individual blocks of an array
776 TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
777 ASSERT(blockNode);
Jamie Madillb547ddf2014-08-25 16:20:46 -0400778
779 TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
780 ASSERT(constantUnion);
781
Jiawei Shaod8105a02017-08-08 09:54:36 +0800782 InterfaceBlock *namedBlock = nullptr;
783
784 bool traverseIndexExpression = false;
785 TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
786 if (interfaceIndexingNode)
787 {
788 TIntermTyped *interfaceNode = interfaceIndexingNode->getLeft()->getAsTyped();
789 ASSERT(interfaceNode);
790
791 const TType &interfaceType = interfaceNode->getType();
792 if (interfaceType.getQualifier() == EvqPerVertexIn)
793 {
794 namedBlock = recordGLInUsed(interfaceType);
795 ASSERT(namedBlock);
796
797 // We need to continue traversing to collect useful variables in the index
798 // expression of gl_in.
799 traverseIndexExpression = true;
800 }
801 }
802
Jamie Madilla6f267f2014-08-27 11:44:15 -0400803 const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800804 if (!namedBlock)
Jiajia Qinbc585152017-06-23 15:42:17 +0800805 {
Jiawei Shaod8105a02017-08-08 09:54:36 +0800806 namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
Jiajia Qinbc585152017-06-23 15:42:17 +0800807 }
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800808 ASSERT(namedBlock);
809 namedBlock->staticUse = true;
810 unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
811 ASSERT(fieldIndex < namedBlock->fields.size());
812 namedBlock->fields[fieldIndex].staticUse = true;
Jiawei Shaod8105a02017-08-08 09:54:36 +0800813
814 if (traverseIndexExpression)
815 {
816 ASSERT(interfaceIndexingNode);
817 interfaceIndexingNode->getRight()->traverse(this);
818 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400819 return false;
820 }
821
822 return true;
823}
824
Olli Etuaho19515012017-06-26 18:00:17 +0300825} // anonymous namespace
826
827void CollectVariables(TIntermBlock *root,
828 std::vector<Attribute> *attributes,
829 std::vector<OutputVariable> *outputVariables,
830 std::vector<Uniform> *uniforms,
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800831 std::vector<Varying> *inputVaryings,
832 std::vector<Varying> *outputVaryings,
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800833 std::vector<InterfaceBlock> *uniformBlocks,
834 std::vector<InterfaceBlock> *shaderStorageBlocks,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800835 std::vector<InterfaceBlock> *inBlocks,
Olli Etuaho19515012017-06-26 18:00:17 +0300836 ShHashFunction64 hashFunction,
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300837 TSymbolTable *symbolTable,
Olli Etuaho19515012017-06-26 18:00:17 +0300838 int shaderVersion,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800839 GLenum shaderType,
Olli Etuaho19515012017-06-26 18:00:17 +0300840 const TExtensionBehavior &extensionBehavior)
841{
Jiawei-Shaodf7d7c92017-07-31 09:34:04 +0800842 CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800843 outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800844 hashFunction, symbolTable, shaderVersion, shaderType,
845 extensionBehavior);
Olli Etuaho19515012017-06-26 18:00:17 +0300846 root->traverse(&collect);
847}
848
Olli Etuaho19515012017-06-26 18:00:17 +0300849} // namespace sh