blob: d0b19907f4c02500c6a4981ef4006528fd733730 [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
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/VariableInfo.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +00008
Zhenyao Mod2d340b2013-09-23 14:57:05 -04009namespace {
10
11TString arrayBrackets(int index)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000012{
13 TStringStream stream;
14 stream << "[" << index << "]";
15 return stream.str();
16}
17
Zhenyao Mod2d340b2013-09-23 14:57:05 -040018// Returns the data type for an attribute, uniform, or varying.
Jamie Madillce505552014-06-26 14:56:33 -040019ShDataType getVariableDataType(const TType& type)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000020{
21 switch (type.getBasicType()) {
22 case EbtFloat:
23 if (type.isMatrix()) {
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000024 switch (type.getCols())
25 {
26 case 2:
27 switch (type.getRows())
28 {
Jamie Madillce505552014-06-26 14:56:33 -040029 case 2: return SH_FLOAT_MAT2;
30 case 3: return SH_FLOAT_MAT2x3;
31 case 4: return SH_FLOAT_MAT2x4;
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000032 default: UNREACHABLE();
33 }
34 case 3:
35 switch (type.getRows())
36 {
Jamie Madillce505552014-06-26 14:56:33 -040037 case 2: return SH_FLOAT_MAT3x2;
38 case 3: return SH_FLOAT_MAT3;
39 case 4: return SH_FLOAT_MAT3x4;
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000040 default: UNREACHABLE();
41 }
42 case 4:
43 switch (type.getRows())
44 {
Jamie Madillce505552014-06-26 14:56:33 -040045 case 2: return SH_FLOAT_MAT4x2;
46 case 3: return SH_FLOAT_MAT4x3;
47 case 4: return SH_FLOAT_MAT4;
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000048 default: UNREACHABLE();
49 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000050 }
51 } else if (type.isVector()) {
52 switch (type.getNominalSize()) {
Jamie Madillce505552014-06-26 14:56:33 -040053 case 2: return SH_FLOAT_VEC2;
54 case 3: return SH_FLOAT_VEC3;
55 case 4: return SH_FLOAT_VEC4;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000056 default: UNREACHABLE();
57 }
58 } else {
Jamie Madillce505552014-06-26 14:56:33 -040059 return SH_FLOAT;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000060 }
61 case EbtInt:
62 if (type.isMatrix()) {
63 UNREACHABLE();
64 } else if (type.isVector()) {
65 switch (type.getNominalSize()) {
Jamie Madillce505552014-06-26 14:56:33 -040066 case 2: return SH_INT_VEC2;
67 case 3: return SH_INT_VEC3;
68 case 4: return SH_INT_VEC4;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000069 default: UNREACHABLE();
70 }
71 } else {
Jamie Madillce505552014-06-26 14:56:33 -040072 return SH_INT;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000073 }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000074 case EbtUInt:
75 if (type.isMatrix()) {
76 UNREACHABLE();
77 } else if (type.isVector()) {
Jamie Madill22d63da2013-06-07 12:45:12 -040078 switch (type.getNominalSize()) {
Jamie Madillce505552014-06-26 14:56:33 -040079 case 2: return SH_UNSIGNED_INT_VEC2;
80 case 3: return SH_UNSIGNED_INT_VEC3;
81 case 4: return SH_UNSIGNED_INT_VEC4;
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000082 default: UNREACHABLE();
83 }
84 } else {
Jamie Madillce505552014-06-26 14:56:33 -040085 return SH_UNSIGNED_INT;
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000086 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000087 case EbtBool:
88 if (type.isMatrix()) {
89 UNREACHABLE();
90 } else if (type.isVector()) {
91 switch (type.getNominalSize()) {
Jamie Madillce505552014-06-26 14:56:33 -040092 case 2: return SH_BOOL_VEC2;
93 case 3: return SH_BOOL_VEC3;
94 case 4: return SH_BOOL_VEC4;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000095 default: UNREACHABLE();
96 }
97 } else {
Jamie Madillce505552014-06-26 14:56:33 -040098 return SH_BOOL;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000099 }
Jamie Madillce505552014-06-26 14:56:33 -0400100 case EbtSampler2D: return SH_SAMPLER_2D;
101 case EbtSampler3D: return SH_SAMPLER_3D;
102 case EbtSamplerCube: return SH_SAMPLER_CUBE;
103 case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
104 case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
105 case EbtSampler2DArray: return SH_SAMPLER_2D_ARRAY;
106 case EbtISampler2D: return SH_INT_SAMPLER_2D;
107 case EbtISampler3D: return SH_INT_SAMPLER_3D;
108 case EbtISamplerCube: return SH_INT_SAMPLER_CUBE;
109 case EbtISampler2DArray: return SH_INT_SAMPLER_2D_ARRAY;
110 case EbtUSampler2D: return SH_UNSIGNED_INT_SAMPLER_2D;
111 case EbtUSampler3D: return SH_UNSIGNED_INT_SAMPLER_3D;
112 case EbtUSamplerCube: return SH_UNSIGNED_INT_SAMPLER_CUBE;
113 case EbtUSampler2DArray: return SH_UNSIGNED_INT_SAMPLER_2D_ARRAY;
114 case EbtSampler2DShadow: return SH_SAMPLER_2D_SHADOW;
115 case EbtSamplerCubeShadow: return SH_SAMPLER_CUBE_SHADOW;
116 case EbtSampler2DArrayShadow: return SH_SAMPLER_2D_ARRAY_SHADOW;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000117 default: UNREACHABLE();
118 }
Jamie Madillce505552014-06-26 14:56:33 -0400119 return SH_NONE;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000120}
121
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400122void getBuiltInVariableInfo(const TType& type,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000123 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000124 const TString& mappedName,
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400125 TVariableInfoList& infoList);
126void getUserDefinedVariableInfo(const TType& type,
127 const TString& name,
128 const TString& mappedName,
129 TVariableInfoList& infoList,
130 ShHashFunction64 hashFunction);
131
132// Returns info for an attribute, uniform, or varying.
133void getVariableInfo(const TType& type,
134 const TString& name,
135 const TString& mappedName,
136 TVariableInfoList& infoList,
137 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000138{
Dan Glastonburyb66feb32014-05-14 15:38:55 +1000139 if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000140 if (type.isArray()) {
141 for (int i = 0; i < type.getArraySize(); ++i) {
142 TString lname = name + arrayBrackets(i);
zmo@google.comfd747b82011-04-23 01:30:07 +0000143 TString lmappedName = mappedName + arrayBrackets(i);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000144 getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000145 }
146 } else {
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000147 getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000148 }
149 } else {
zmo@google.comfd747b82011-04-23 01:30:07 +0000150 getBuiltInVariableInfo(type, name, mappedName, infoList);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000151 }
152}
153
154void getBuiltInVariableInfo(const TType& type,
155 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000156 const TString& mappedName,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000157 TVariableInfoList& infoList)
158{
159 ASSERT(type.getBasicType() != EbtStruct);
160
161 TVariableInfo varInfo;
162 if (type.isArray()) {
163 varInfo.name = (name + "[0]").c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000164 varInfo.mappedName = (mappedName + "[0]").c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000165 varInfo.size = type.getArraySize();
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800166 varInfo.isArray = true;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000167 } else {
168 varInfo.name = name.c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000169 varInfo.mappedName = mappedName.c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000170 varInfo.size = 1;
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800171 varInfo.isArray = false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000172 }
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400173 varInfo.precision = type.getPrecision();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000174 varInfo.type = getVariableDataType(type);
175 infoList.push_back(varInfo);
176}
177
178void getUserDefinedVariableInfo(const TType& type,
179 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000180 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000181 TVariableInfoList& infoList,
182 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000183{
Jamie Madill98493dd2013-07-08 14:39:03 -0400184 ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000185
Dan Glastonburyb66feb32014-05-14 15:38:55 +1000186 const TFieldList& fields = type.isInterfaceBlock() ?
187 type.getInterfaceBlock()->fields() :
188 type.getStruct()->fields();
Jamie Madill98493dd2013-07-08 14:39:03 -0400189 for (size_t i = 0; i < fields.size(); ++i) {
190 const TType& fieldType = *(fields[i]->type());
191 const TString& fieldName = fields[i]->name();
192 getVariableInfo(fieldType,
193 name + "." + fieldName,
194 mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000195 infoList,
196 hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000197 }
198}
199
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400200TVariableInfo* findVariable(const TType& type,
201 const TString& name,
202 TVariableInfoList& infoList)
203{
204 // TODO(zmo): optimize this function.
205 TString myName = name;
206 if (type.isArray())
207 myName += "[0]";
208 for (size_t ii = 0; ii < infoList.size(); ++ii)
209 {
210 if (infoList[ii].name.c_str() == myName)
211 return &(infoList[ii]);
212 }
213 return NULL;
214}
215
216} // namespace anonymous
217
gman@chromium.org8d804792012-10-17 21:33:48 +0000218TVariableInfo::TVariableInfo()
Jamie Madillce505552014-06-26 14:56:33 -0400219 : type(SH_NONE),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400220 size(0),
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800221 isArray(false),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400222 precision(EbpUndefined),
223 staticUse(false)
gman@chromium.org8d804792012-10-17 21:33:48 +0000224{
225}
226
Jamie Madillce505552014-06-26 14:56:33 -0400227TVariableInfo::TVariableInfo(ShDataType type, int size)
gman@chromium.org8d804792012-10-17 21:33:48 +0000228 : type(type),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400229 size(size),
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800230 isArray(false),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400231 precision(EbpUndefined),
232 staticUse(false)
gman@chromium.org8d804792012-10-17 21:33:48 +0000233{
234}
235
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400236CollectVariables::CollectVariables(TVariableInfoList& attribs,
237 TVariableInfoList& uniforms,
238 TVariableInfoList& varyings,
239 ShHashFunction64 hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000240 : mAttribs(attribs),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000241 mUniforms(uniforms),
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400242 mVaryings(varyings),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400243 mPointCoordAdded(false),
244 mFrontFacingAdded(false),
245 mFragCoordAdded(false),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000246 mHashFunction(hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000247{
248}
249
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400250// We want to check whether a uniform/varying is statically used
251// because we only count the used ones in packing computing.
252// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
253// toward varying counting if they are statically used in a fragment
254// shader.
255void CollectVariables::visitSymbol(TIntermSymbol* symbol)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000256{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400257 ASSERT(symbol != NULL);
258 TVariableInfo* var = NULL;
259 switch (symbol->getQualifier())
260 {
261 case EvqVaryingOut:
262 case EvqInvariantVaryingOut:
263 case EvqVaryingIn:
264 case EvqInvariantVaryingIn:
265 var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings);
266 break;
267 case EvqUniform:
268 var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms);
269 break;
270 case EvqFragCoord:
271 if (!mFragCoordAdded) {
272 TVariableInfo info;
273 info.name = "gl_FragCoord";
274 info.mappedName = "gl_FragCoord";
Jamie Madillce505552014-06-26 14:56:33 -0400275 info.type = SH_FLOAT_VEC4;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400276 info.size = 1;
277 info.precision = EbpMedium; // Use mediump as it doesn't really matter.
278 info.staticUse = true;
279 mVaryings.push_back(info);
280 mFragCoordAdded = true;
281 }
282 return;
283 case EvqFrontFacing:
284 if (!mFrontFacingAdded) {
285 TVariableInfo info;
286 info.name = "gl_FrontFacing";
287 info.mappedName = "gl_FrontFacing";
Jamie Madillce505552014-06-26 14:56:33 -0400288 info.type = SH_BOOL;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400289 info.size = 1;
290 info.precision = EbpUndefined;
291 info.staticUse = true;
292 mVaryings.push_back(info);
293 mFrontFacingAdded = true;
294 }
295 return;
296 case EvqPointCoord:
297 if (!mPointCoordAdded) {
298 TVariableInfo info;
299 info.name = "gl_PointCoord";
300 info.mappedName = "gl_PointCoord";
Jamie Madillce505552014-06-26 14:56:33 -0400301 info.type = SH_FLOAT_VEC2;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400302 info.size = 1;
303 info.precision = EbpMedium; // Use mediump as it doesn't really matter.
304 info.staticUse = true;
305 mVaryings.push_back(info);
306 mPointCoordAdded = true;
307 }
308 return;
309 default:
310 break;
311 }
312 if (var)
313 var->staticUse = true;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000314}
315
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400316bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000317{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400318 bool visitChildren = true;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000319
320 switch (node->getOp())
321 {
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000322 case EOpDeclaration: {
323 const TIntermSequence& sequence = node->getSequence();
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000324 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400325 if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqUniform ||
326 qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
327 qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000328 {
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400329 TVariableInfoList *infoList = NULL;
330
331 switch (qualifier)
332 {
333 case EvqAttribute:
334 case EvqVertexIn:
335 infoList = &mAttribs;
336 break;
337 case EvqUniform:
338 infoList = &mUniforms;
339 break;
340 default:
341 infoList = &mVaryings;
342 break;
343 }
344
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000345 for (TIntermSequence::const_iterator i = sequence.begin();
346 i != sequence.end(); ++i)
347 {
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000348 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
349 // The only case in which the sequence will not contain a
350 // TIntermSymbol node is initialization. It will contain a
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400351 // TInterBinary node in that case. Since attributes, uniforms,
352 // and varyings cannot be initialized in a shader, we must have
353 // only TIntermSymbol nodes in the sequence.
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000354 ASSERT(variable != NULL);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000355 TString processedSymbol;
356 if (mHashFunction == NULL)
357 processedSymbol = variable->getSymbol();
358 else
Zhenyao Mo3cdfcce2014-03-07 13:00:08 -0800359 processedSymbol = TIntermTraverser::hash(variable->getSymbol(), mHashFunction);
zmo@google.comfd747b82011-04-23 01:30:07 +0000360 getVariableInfo(variable->getType(),
Zhenyao Mo3cdfcce2014-03-07 13:00:08 -0800361 variable->getSymbol(),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000362 processedSymbol,
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400363 *infoList,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000364 mHashFunction);
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400365 visitChildren = false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000366 }
367 }
368 break;
369 }
370 default: break;
371 }
372
373 return visitChildren;
374}