blob: b9cf3a4fe858daa96b768755ce4efb36c16417db [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//
6
Jamie Madill4667c452014-07-08 15:02:36 -04007#include "angle_gl.h"
Zhenyao Mo94ac7b72014-10-15 18:22:08 -07008#include "compiler/translator/SymbolTable.h"
Geoff Lang17732822013-08-29 13:46:49 -04009#include "compiler/translator/VariableInfo.h"
Jamie Madillaa72d782014-07-02 15:31:19 -040010#include "compiler/translator/util.h"
Jamie Madilld5512cd2014-07-10 17:50:08 -040011#include "common/utilities.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000012
Jamie Madilla2fbb842014-09-03 09:40:47 -040013namespace sh
14{
15
Jamie Madill54ad4f82014-09-03 09:40:46 -040016namespace
17{
Zhenyao Mod2d340b2013-09-23 14:57:05 -040018
Jamie Madill54ad4f82014-09-03 09:40:46 -040019TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field)
20{
21 if (interfaceBlock.hasInstanceName())
22 {
23 return interfaceBlock.name() + "." + field.name();
24 }
25 else
26 {
27 return field.name();
28 }
29}
30
Jamie Madilla2fbb842014-09-03 09:40:47 -040031BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
Jamie Madill54ad4f82014-09-03 09:40:46 -040032{
33 switch (blockStorage)
34 {
Jamie Madilla2fbb842014-09-03 09:40:47 -040035 case EbsPacked: return BLOCKLAYOUT_PACKED;
36 case EbsShared: return BLOCKLAYOUT_SHARED;
37 case EbsStd140: return BLOCKLAYOUT_STANDARD;
38 default: UNREACHABLE(); return BLOCKLAYOUT_SHARED;
Jamie Madill54ad4f82014-09-03 09:40:46 -040039 }
40}
41
Jamie Madilla2fbb842014-09-03 09:40:47 -040042void ExpandUserDefinedVariable(const ShaderVariable &variable,
Jamie Madill54ad4f82014-09-03 09:40:46 -040043 const std::string &name,
44 const std::string &mappedName,
45 bool markStaticUse,
Jamie Madilla2fbb842014-09-03 09:40:47 -040046 std::vector<ShaderVariable> *expanded);
Jamie Madill54ad4f82014-09-03 09:40:46 -040047
Jamie Madilla2fbb842014-09-03 09:40:47 -040048void ExpandVariable(const ShaderVariable &variable,
Jamie Madill54ad4f82014-09-03 09:40:46 -040049 const std::string &name,
50 const std::string &mappedName,
51 bool markStaticUse,
Jamie Madilla2fbb842014-09-03 09:40:47 -040052 std::vector<ShaderVariable> *expanded)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000053{
Jamie Madill23a8a432014-07-09 13:27:42 -040054 if (variable.isStruct())
Jamie Madill4667c452014-07-08 15:02:36 -040055 {
Jamie Madill23a8a432014-07-09 13:27:42 -040056 if (variable.isArray())
57 {
58 for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++)
59 {
Jamie Madilla2fbb842014-09-03 09:40:47 -040060 std::string lname = name + ::ArrayString(elementIndex);
61 std::string lmappedName = mappedName + ::ArrayString(elementIndex);
Jamie Madill23a8a432014-07-09 13:27:42 -040062 ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded);
63 }
64 }
65 else
66 {
67 ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded);
68 }
Jamie Madill4667c452014-07-08 15:02:36 -040069 }
70 else
71 {
Jamie Madilla2fbb842014-09-03 09:40:47 -040072 ShaderVariable expandedVar = variable;
Jamie Madill23a8a432014-07-09 13:27:42 -040073
74 expandedVar.name = name;
75 expandedVar.mappedName = mappedName;
76
77 // Mark all expanded fields as used if the parent is used
78 if (markStaticUse)
79 {
80 expandedVar.staticUse = true;
81 }
82
83 if (expandedVar.isArray())
84 {
85 expandedVar.name += "[0]";
86 expandedVar.mappedName += "[0]";
87 }
88
89 expanded->push_back(expandedVar);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000090 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000091}
92
Jamie Madilla2fbb842014-09-03 09:40:47 -040093void ExpandUserDefinedVariable(const ShaderVariable &variable,
Jamie Madill54ad4f82014-09-03 09:40:46 -040094 const std::string &name,
95 const std::string &mappedName,
96 bool markStaticUse,
Jamie Madilla2fbb842014-09-03 09:40:47 -040097 std::vector<ShaderVariable> *expanded)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000098{
Jamie Madill23a8a432014-07-09 13:27:42 -040099 ASSERT(variable.isStruct());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000100
Jamie Madilla2fbb842014-09-03 09:40:47 -0400101 const std::vector<ShaderVariable> &fields = variable.fields;
Jamie Madill23a8a432014-07-09 13:27:42 -0400102
103 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
Jamie Madill4667c452014-07-08 15:02:36 -0400104 {
Jamie Madilla2fbb842014-09-03 09:40:47 -0400105 const ShaderVariable &field = fields[fieldIndex];
Jamie Madill23a8a432014-07-09 13:27:42 -0400106 ExpandVariable(field,
107 name + "." + field.name,
108 mappedName + "." + field.mappedName,
109 markStaticUse,
110 expanded);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000111 }
112}
113
Jamie Madilla718c1e2014-07-02 15:31:22 -0400114template <class VarT>
Jamie Madill54ad4f82014-09-03 09:40:46 -0400115VarT *FindVariable(const TString &name,
116 std::vector<VarT> *infoList)
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400117{
118 // TODO(zmo): optimize this function.
Jamie Madilla718c1e2014-07-02 15:31:22 -0400119 for (size_t ii = 0; ii < infoList->size(); ++ii)
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400120 {
Jamie Madill23a8a432014-07-09 13:27:42 -0400121 if ((*infoList)[ii].name.c_str() == name)
Jamie Madilla718c1e2014-07-02 15:31:22 -0400122 return &((*infoList)[ii]);
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400123 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400124
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400125 return NULL;
126}
127
Jamie Madill54ad4f82014-09-03 09:40:46 -0400128}
129
Jamie Madilla718c1e2014-07-02 15:31:22 -0400130CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
Jamie Madilld5512cd2014-07-10 17:50:08 -0400131 std::vector<sh::Attribute> *outputVariables,
Jamie Madilla718c1e2014-07-02 15:31:22 -0400132 std::vector<sh::Uniform> *uniforms,
133 std::vector<sh::Varying> *varyings,
Jamie Madilld5512cd2014-07-10 17:50:08 -0400134 std::vector<sh::InterfaceBlock> *interfaceBlocks,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700135 ShHashFunction64 hashFunction,
136 const TSymbolTable &symbolTable)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000137 : mAttribs(attribs),
Jamie Madilld5512cd2014-07-10 17:50:08 -0400138 mOutputVariables(outputVariables),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000139 mUniforms(uniforms),
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400140 mVaryings(varyings),
Jamie Madilld5512cd2014-07-10 17:50:08 -0400141 mInterfaceBlocks(interfaceBlocks),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400142 mPointCoordAdded(false),
143 mFrontFacingAdded(false),
144 mFragCoordAdded(false),
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000145 mInstanceIDAdded(false),
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700146 mPositionAdded(false),
147 mPointSizeAdded(false),
Erik Dahlströmea7a2122014-11-17 16:15:57 +0100148 mLastFragDataAdded(false),
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700149 mHashFunction(hashFunction),
150 mSymbolTable(symbolTable)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000151{
152}
153
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400154// We want to check whether a uniform/varying is statically used
155// because we only count the used ones in packing computing.
156// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
157// toward varying counting if they are statically used in a fragment
158// shader.
Jamie Madill4667c452014-07-08 15:02:36 -0400159void CollectVariables::visitSymbol(TIntermSymbol *symbol)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000160{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400161 ASSERT(symbol != NULL);
Jamie Madilla2fbb842014-09-03 09:40:47 -0400162 ShaderVariable *var = NULL;
Jamie Madilld5512cd2014-07-10 17:50:08 -0400163 const TString &symbolName = symbol->getSymbol();
Jamie Madill4667c452014-07-08 15:02:36 -0400164
Jamie Madilla2fbb842014-09-03 09:40:47 -0400165 if (IsVarying(symbol->getQualifier()))
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400166 {
Jamie Madilld5512cd2014-07-10 17:50:08 -0400167 var = FindVariable(symbolName, mVaryings);
Jamie Madill4667c452014-07-08 15:02:36 -0400168 }
Jamie Madillb547ddf2014-08-25 16:20:46 -0400169 else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
170 {
171 UNREACHABLE();
172 }
173 else
Jamie Madill4667c452014-07-08 15:02:36 -0400174 {
175 switch (symbol->getQualifier())
Jamie Madilla718c1e2014-07-02 15:31:22 -0400176 {
Jamie Madilld5512cd2014-07-10 17:50:08 -0400177 case EvqAttribute:
178 case EvqVertexIn:
179 var = FindVariable(symbolName, mAttribs);
180 break;
181 case EvqFragmentOut:
182 var = FindVariable(symbolName, mOutputVariables);
183 break;
Jamie Madill4667c452014-07-08 15:02:36 -0400184 case EvqUniform:
Jamie Madilld5512cd2014-07-10 17:50:08 -0400185 {
186 const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
187 if (interfaceBlock)
188 {
Jamie Madilla2fbb842014-09-03 09:40:47 -0400189 InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400190 ASSERT(namedBlock);
191 var = FindVariable(symbolName, &namedBlock->fields);
192
193 // Set static use on the parent interface block here
194 namedBlock->staticUse = true;
Jamie Madillb547ddf2014-08-25 16:20:46 -0400195
Jamie Madilld5512cd2014-07-10 17:50:08 -0400196 }
197 else
198 {
199 var = FindVariable(symbolName, mUniforms);
200 }
201
202 // It's an internal error to reference an undefined user uniform
203 ASSERT(symbolName.compare(0, 3, "gl_") == 0 || var);
204 }
Jamie Madill4667c452014-07-08 15:02:36 -0400205 break;
206 case EvqFragCoord:
207 if (!mFragCoordAdded)
208 {
Jamie Madilla2fbb842014-09-03 09:40:47 -0400209 Varying info;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700210 const char kName[] = "gl_FragCoord";
211 info.name = kName;
212 info.mappedName = kName;
Jamie Madill4667c452014-07-08 15:02:36 -0400213 info.type = GL_FLOAT_VEC4;
214 info.arraySize = 0;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700215 info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
Jamie Madill4667c452014-07-08 15:02:36 -0400216 info.staticUse = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700217 info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
Jamie Madill4667c452014-07-08 15:02:36 -0400218 mVaryings->push_back(info);
219 mFragCoordAdded = true;
220 }
221 return;
222 case EvqFrontFacing:
223 if (!mFrontFacingAdded)
224 {
Jamie Madilla2fbb842014-09-03 09:40:47 -0400225 Varying info;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700226 const char kName[] = "gl_FrontFacing";
227 info.name = kName;
228 info.mappedName = kName;
Jamie Madill4667c452014-07-08 15:02:36 -0400229 info.type = GL_BOOL;
230 info.arraySize = 0;
231 info.precision = GL_NONE;
232 info.staticUse = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700233 info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
Jamie Madill4667c452014-07-08 15:02:36 -0400234 mVaryings->push_back(info);
235 mFrontFacingAdded = true;
236 }
237 return;
238 case EvqPointCoord:
239 if (!mPointCoordAdded)
240 {
Jamie Madilla2fbb842014-09-03 09:40:47 -0400241 Varying info;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700242 const char kName[] = "gl_PointCoord";
243 info.name = kName;
244 info.mappedName = kName;
Jamie Madill4667c452014-07-08 15:02:36 -0400245 info.type = GL_FLOAT_VEC2;
246 info.arraySize = 0;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700247 info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
Jamie Madill4667c452014-07-08 15:02:36 -0400248 info.staticUse = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700249 info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
Jamie Madill4667c452014-07-08 15:02:36 -0400250 mVaryings->push_back(info);
251 mPointCoordAdded = true;
252 }
253 return;
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000254 case EvqInstanceID:
255 if (!mInstanceIDAdded)
256 {
257 Attribute info;
258 const char kName[] = "gl_InstanceID";
259 info.name = kName;
260 info.mappedName = kName;
261 info.type = GL_INT;
262 info.arraySize = 0;
263 info.precision = GL_HIGH_INT; // Defined by spec.
264 info.staticUse = true;
265 info.location = -1;
266 mAttribs->push_back(info);
267 mInstanceIDAdded = true;
268 }
269 return;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700270 case EvqPosition:
271 if (!mPositionAdded)
272 {
273 Varying info;
274 const char kName[] = "gl_Position";
275 info.name = kName;
276 info.mappedName = kName;
277 info.type = GL_FLOAT_VEC4;
278 info.arraySize = 0;
279 info.precision = GL_HIGH_FLOAT; // Defined by spec.
280 info.staticUse = true;
281 info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
282 mVaryings->push_back(info);
283 mPositionAdded = true;
284 }
285 return;
286 case EvqPointSize:
287 if (!mPointSizeAdded)
288 {
289 Varying info;
290 const char kName[] = "gl_PointSize";
291 info.name = kName;
292 info.mappedName = kName;
293 info.type = GL_FLOAT;
294 info.arraySize = 0;
295 info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
296 info.staticUse = true;
297 info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
298 mVaryings->push_back(info);
299 mPointSizeAdded = true;
300 }
301 return;
Erik Dahlströmea7a2122014-11-17 16:15:57 +0100302 case EvqLastFragData:
303 if (!mLastFragDataAdded)
304 {
305 Varying info;
306 const char kName[] = "gl_LastFragData";
307 info.name = kName;
308 info.mappedName = kName;
309 info.type = GL_FLOAT_VEC4;
310 info.arraySize = static_cast<const TVariable*>(mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))->getConstPointer()->getIConst();
311 info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
312 info.staticUse = true;
313 info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
314 mVaryings->push_back(info);
315 mLastFragDataAdded = true;
316 }
317 return;
Jamie Madill4667c452014-07-08 15:02:36 -0400318 default:
319 break;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400320 }
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400321 }
322 if (var)
Jamie Madilla718c1e2014-07-02 15:31:22 -0400323 {
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400324 var->staticUse = true;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400325 }
326}
327
Jamie Madilla2fbb842014-09-03 09:40:47 -0400328class NameHashingTraverser : public GetVariableTraverser
Jamie Madill23a8a432014-07-09 13:27:42 -0400329{
330 public:
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700331 NameHashingTraverser(ShHashFunction64 hashFunction,
332 const TSymbolTable &symbolTable)
333 : GetVariableTraverser(symbolTable),
334 mHashFunction(hashFunction)
Jamie Madill23a8a432014-07-09 13:27:42 -0400335 {}
336
337 private:
Jamie Madill42bcf322014-08-25 16:20:46 -0400338 DISALLOW_COPY_AND_ASSIGN(NameHashingTraverser);
339
Jamie Madilla2fbb842014-09-03 09:40:47 -0400340 virtual void visitVariable(ShaderVariable *variable)
Jamie Madill23a8a432014-07-09 13:27:42 -0400341 {
342 TString stringName = TString(variable->name.c_str());
343 variable->mappedName = TIntermTraverser::hash(stringName, mHashFunction).c_str();
344 }
345
346 ShHashFunction64 mHashFunction;
347};
348
349// Attributes, which cannot have struct fields, are a special case
350template <>
351void CollectVariables::visitVariable(const TIntermSymbol *variable,
Jamie Madilla2fbb842014-09-03 09:40:47 -0400352 std::vector<Attribute> *infoList) const
Jamie Madill23a8a432014-07-09 13:27:42 -0400353{
354 ASSERT(variable);
355 const TType &type = variable->getType();
356 ASSERT(!type.getStruct());
357
Jamie Madilla2fbb842014-09-03 09:40:47 -0400358 Attribute attribute;
Jamie Madill23a8a432014-07-09 13:27:42 -0400359
Jamie Madilla2fbb842014-09-03 09:40:47 -0400360 attribute.type = GLVariableType(type);
361 attribute.precision = GLVariablePrecision(type);
Jamie Madill23a8a432014-07-09 13:27:42 -0400362 attribute.name = variable->getSymbol().c_str();
363 attribute.arraySize = static_cast<unsigned int>(type.getArraySize());
364 attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
365 attribute.location = variable->getType().getLayoutQualifier().location;
366
367 infoList->push_back(attribute);
368}
369
Jamie Madilld5512cd2014-07-10 17:50:08 -0400370template <>
371void CollectVariables::visitVariable(const TIntermSymbol *variable,
Jamie Madilla2fbb842014-09-03 09:40:47 -0400372 std::vector<InterfaceBlock> *infoList) const
Jamie Madilld5512cd2014-07-10 17:50:08 -0400373{
Jamie Madilla2fbb842014-09-03 09:40:47 -0400374 InterfaceBlock interfaceBlock;
Jamie Madilld5512cd2014-07-10 17:50:08 -0400375 const TInterfaceBlock *blockType = variable->getType().getInterfaceBlock();
Jamie Madill42bcf322014-08-25 16:20:46 -0400376 ASSERT(blockType);
Jamie Madilld5512cd2014-07-10 17:50:08 -0400377
378 interfaceBlock.name = blockType->name().c_str();
379 interfaceBlock.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str();
Jamie Madill42bcf322014-08-25 16:20:46 -0400380 interfaceBlock.instanceName = (blockType->hasInstanceName() ? blockType->instanceName().c_str() : "");
Jamie Madilld5512cd2014-07-10 17:50:08 -0400381 interfaceBlock.arraySize = variable->getArraySize();
Jamie Madill42bcf322014-08-25 16:20:46 -0400382 interfaceBlock.isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor);
Jamie Madill54ad4f82014-09-03 09:40:46 -0400383 interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage());
Jamie Madilld5512cd2014-07-10 17:50:08 -0400384
Jamie Madilla6f267f2014-08-27 11:44:15 -0400385 // Gather field information
Jamie Madill54ad4f82014-09-03 09:40:46 -0400386 const TFieldList &fieldList = blockType->fields();
387
388 for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
389 {
390 const TField &field = *fieldList[fieldIndex];
391 const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
392 const TType &fieldType = *field.type();
393
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700394 GetVariableTraverser traverser(mSymbolTable);
Jamie Madill54ad4f82014-09-03 09:40:46 -0400395 traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
396
397 interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
398 }
Jamie Madilld5512cd2014-07-10 17:50:08 -0400399
400 infoList->push_back(interfaceBlock);
401}
402
Jamie Madill23a8a432014-07-09 13:27:42 -0400403template <typename VarT>
Jamie Madill4667c452014-07-08 15:02:36 -0400404void CollectVariables::visitVariable(const TIntermSymbol *variable,
405 std::vector<VarT> *infoList) const
406{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700407 NameHashingTraverser traverser(mHashFunction, mSymbolTable);
Jamie Madill42bcf322014-08-25 16:20:46 -0400408 traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
Jamie Madill4667c452014-07-08 15:02:36 -0400409}
410
411template <typename VarT>
412void CollectVariables::visitInfoList(const TIntermSequence &sequence,
413 std::vector<VarT> *infoList) const
Jamie Madilla718c1e2014-07-02 15:31:22 -0400414{
415 for (size_t seqIndex = 0; seqIndex < sequence.size(); seqIndex++)
416 {
Jamie Madill4667c452014-07-08 15:02:36 -0400417 const TIntermSymbol *variable = sequence[seqIndex]->getAsSymbolNode();
Jamie Madilla718c1e2014-07-02 15:31:22 -0400418 // The only case in which the sequence will not contain a
419 // TIntermSymbol node is initialization. It will contain a
420 // TInterBinary node in that case. Since attributes, uniforms,
421 // and varyings cannot be initialized in a shader, we must have
422 // only TIntermSymbol nodes in the sequence.
423 ASSERT(variable != NULL);
Jamie Madill4667c452014-07-08 15:02:36 -0400424 visitVariable(variable, infoList);
Jamie Madilla718c1e2014-07-02 15:31:22 -0400425 }
alokp@chromium.org07620a52010-09-23 17:53:56 +0000426}
427
Jamie Madill4667c452014-07-08 15:02:36 -0400428bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000429{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400430 bool visitChildren = true;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000431
432 switch (node->getOp())
433 {
Jamie Madill4667c452014-07-08 15:02:36 -0400434 case EOpDeclaration:
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000435 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700436 const TIntermSequence &sequence = *(node->getSequence());
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400437 ASSERT(!sequence.empty());
438
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700439 const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
Jamie Madilld5512cd2014-07-10 17:50:08 -0400440 TQualifier qualifier = typedNode.getQualifier();
441
442 if (typedNode.getBasicType() == EbtInterfaceBlock)
443 {
444 visitInfoList(sequence, mInterfaceBlocks);
Jamie Madillb547ddf2014-08-25 16:20:46 -0400445 visitChildren = false;
Jamie Madilld5512cd2014-07-10 17:50:08 -0400446 }
447 else if (qualifier == EvqAttribute || qualifier == EvqVertexIn ||
448 qualifier == EvqFragmentOut || qualifier == EvqUniform ||
Jamie Madilla2fbb842014-09-03 09:40:47 -0400449 IsVarying(qualifier))
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400450 {
Jamie Madill4667c452014-07-08 15:02:36 -0400451 switch (qualifier)
452 {
453 case EvqAttribute:
454 case EvqVertexIn:
455 visitInfoList(sequence, mAttribs);
456 break;
Jamie Madilld5512cd2014-07-10 17:50:08 -0400457 case EvqFragmentOut:
458 visitInfoList(sequence, mOutputVariables);
459 break;
Jamie Madill4667c452014-07-08 15:02:36 -0400460 case EvqUniform:
461 visitInfoList(sequence, mUniforms);
462 break;
463 default:
Jamie Madill3b5c2da2014-08-19 15:23:32 -0400464 visitInfoList(sequence, mVaryings);
Jamie Madill4667c452014-07-08 15:02:36 -0400465 break;
466 }
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400467
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400468 visitChildren = false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000469 }
Jamie Madill4667c452014-07-08 15:02:36 -0400470 break;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000471 }
Jamie Madill4667c452014-07-08 15:02:36 -0400472 default: break;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000473 }
474
475 return visitChildren;
476}
Jamie Madill23a8a432014-07-09 13:27:42 -0400477
Jamie Madillb547ddf2014-08-25 16:20:46 -0400478bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
479{
480 if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
481 {
Jamie Madilla6f267f2014-08-27 11:44:15 -0400482 // NOTE: we do not determine static use for individual blocks of an array
483 TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
484 ASSERT(blockNode);
Jamie Madillb547ddf2014-08-25 16:20:46 -0400485
486 TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
487 ASSERT(constantUnion);
488
Jamie Madilla6f267f2014-08-27 11:44:15 -0400489 const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
Jamie Madilla2fbb842014-09-03 09:40:47 -0400490 InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
Jamie Madillb547ddf2014-08-25 16:20:46 -0400491 ASSERT(namedBlock);
492 namedBlock->staticUse = true;
493
494 unsigned int fieldIndex = constantUnion->getUConst(0);
495 ASSERT(fieldIndex < namedBlock->fields.size());
496 namedBlock->fields[fieldIndex].staticUse = true;
497 return false;
498 }
499
500 return true;
501}
502
Zhenyao Mo409078f2014-10-28 13:23:18 -0700503void ExpandUniforms(const std::vector<Uniform> &compact,
504 std::vector<ShaderVariable> *expanded)
Jamie Madill23a8a432014-07-09 13:27:42 -0400505{
506 for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
507 {
Jamie Madilla2fbb842014-09-03 09:40:47 -0400508 const ShaderVariable &variable = compact[variableIndex];
Jamie Madill23a8a432014-07-09 13:27:42 -0400509 ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
510 }
511}
512
Jamie Madilla2fbb842014-09-03 09:40:47 -0400513}