blob: 536aa14332fb40446bbbca5565c311dcecb5090b [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"
Jamie Madill53221f52014-06-25 16:04:59 -04008#include "angle_gl.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +00009
Zhenyao Mod2d340b2013-09-23 14:57:05 -040010namespace {
11
12TString arrayBrackets(int index)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000013{
14 TStringStream stream;
15 stream << "[" << index << "]";
16 return stream.str();
17}
18
Zhenyao Mod2d340b2013-09-23 14:57:05 -040019// Returns the data type for an attribute, uniform, or varying.
Jamie Madill53221f52014-06-25 16:04:59 -040020sh::GLenum getVariableDataType(const TType& type)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000021{
22 switch (type.getBasicType()) {
23 case EbtFloat:
24 if (type.isMatrix()) {
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000025 switch (type.getCols())
26 {
27 case 2:
28 switch (type.getRows())
29 {
Jamie Madill53221f52014-06-25 16:04:59 -040030 case 2: return GL_FLOAT_MAT2;
31 case 3: return GL_FLOAT_MAT2x3;
32 case 4: return GL_FLOAT_MAT2x4;
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000033 default: UNREACHABLE();
34 }
35 case 3:
36 switch (type.getRows())
37 {
Jamie Madill53221f52014-06-25 16:04:59 -040038 case 2: return GL_FLOAT_MAT3x2;
39 case 3: return GL_FLOAT_MAT3;
40 case 4: return GL_FLOAT_MAT3x4;
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000041 default: UNREACHABLE();
42 }
43 case 4:
44 switch (type.getRows())
45 {
Jamie Madill53221f52014-06-25 16:04:59 -040046 case 2: return GL_FLOAT_MAT4x2;
47 case 3: return GL_FLOAT_MAT4x3;
48 case 4: return GL_FLOAT_MAT4;
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000049 default: UNREACHABLE();
50 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000051 }
52 } else if (type.isVector()) {
53 switch (type.getNominalSize()) {
Jamie Madill53221f52014-06-25 16:04:59 -040054 case 2: return GL_FLOAT_VEC2;
55 case 3: return GL_FLOAT_VEC3;
56 case 4: return GL_FLOAT_VEC4;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000057 default: UNREACHABLE();
58 }
59 } else {
Jamie Madill53221f52014-06-25 16:04:59 -040060 return GL_FLOAT;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000061 }
62 case EbtInt:
63 if (type.isMatrix()) {
64 UNREACHABLE();
65 } else if (type.isVector()) {
66 switch (type.getNominalSize()) {
Jamie Madill53221f52014-06-25 16:04:59 -040067 case 2: return GL_INT_VEC2;
68 case 3: return GL_INT_VEC3;
69 case 4: return GL_INT_VEC4;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000070 default: UNREACHABLE();
71 }
72 } else {
Jamie Madill53221f52014-06-25 16:04:59 -040073 return GL_INT;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000074 }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000075 case EbtUInt:
76 if (type.isMatrix()) {
77 UNREACHABLE();
78 } else if (type.isVector()) {
Jamie Madill22d63da2013-06-07 12:45:12 -040079 switch (type.getNominalSize()) {
Jamie Madill53221f52014-06-25 16:04:59 -040080 case 2: return GL_UNSIGNED_INT_VEC2;
81 case 3: return GL_UNSIGNED_INT_VEC3;
82 case 4: return GL_UNSIGNED_INT_VEC4;
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000083 default: UNREACHABLE();
84 }
85 } else {
Jamie Madill53221f52014-06-25 16:04:59 -040086 return GL_UNSIGNED_INT;
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000087 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000088 case EbtBool:
89 if (type.isMatrix()) {
90 UNREACHABLE();
91 } else if (type.isVector()) {
92 switch (type.getNominalSize()) {
Jamie Madill53221f52014-06-25 16:04:59 -040093 case 2: return GL_BOOL_VEC2;
94 case 3: return GL_BOOL_VEC3;
95 case 4: return GL_BOOL_VEC4;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000096 default: UNREACHABLE();
97 }
98 } else {
Jamie Madill53221f52014-06-25 16:04:59 -040099 return GL_BOOL;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000100 }
Jamie Madill53221f52014-06-25 16:04:59 -0400101 case EbtSampler2D: return GL_SAMPLER_2D;
102 case EbtSampler3D: return GL_SAMPLER_3D;
103 case EbtSamplerCube: return GL_SAMPLER_CUBE;
104 case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES;
105 case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB;
106 case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY;
107 case EbtISampler2D: return GL_INT_SAMPLER_2D;
108 case EbtISampler3D: return GL_INT_SAMPLER_3D;
109 case EbtISamplerCube: return GL_INT_SAMPLER_CUBE;
110 case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY;
111 case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D;
112 case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D;
113 case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE;
114 case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
115 case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW;
116 case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW;
117 case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000118 default: UNREACHABLE();
119 }
Jamie Madill53221f52014-06-25 16:04:59 -0400120 return GL_NONE;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000121}
122
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400123void getBuiltInVariableInfo(const TType& type,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000124 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000125 const TString& mappedName,
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400126 TVariableInfoList& infoList);
127void getUserDefinedVariableInfo(const TType& type,
128 const TString& name,
129 const TString& mappedName,
130 TVariableInfoList& infoList,
131 ShHashFunction64 hashFunction);
132
133// Returns info for an attribute, uniform, or varying.
134void getVariableInfo(const TType& type,
135 const TString& name,
136 const TString& mappedName,
137 TVariableInfoList& infoList,
138 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000139{
Dan Glastonburyb66feb32014-05-14 15:38:55 +1000140 if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000141 if (type.isArray()) {
142 for (int i = 0; i < type.getArraySize(); ++i) {
143 TString lname = name + arrayBrackets(i);
zmo@google.comfd747b82011-04-23 01:30:07 +0000144 TString lmappedName = mappedName + arrayBrackets(i);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000145 getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000146 }
147 } else {
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000148 getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000149 }
150 } else {
zmo@google.comfd747b82011-04-23 01:30:07 +0000151 getBuiltInVariableInfo(type, name, mappedName, infoList);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000152 }
153}
154
155void getBuiltInVariableInfo(const TType& type,
156 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000157 const TString& mappedName,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000158 TVariableInfoList& infoList)
159{
160 ASSERT(type.getBasicType() != EbtStruct);
161
162 TVariableInfo varInfo;
163 if (type.isArray()) {
164 varInfo.name = (name + "[0]").c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000165 varInfo.mappedName = (mappedName + "[0]").c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000166 varInfo.size = type.getArraySize();
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800167 varInfo.isArray = true;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000168 } else {
169 varInfo.name = name.c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000170 varInfo.mappedName = mappedName.c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000171 varInfo.size = 1;
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800172 varInfo.isArray = false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000173 }
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400174 varInfo.precision = type.getPrecision();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000175 varInfo.type = getVariableDataType(type);
176 infoList.push_back(varInfo);
177}
178
179void getUserDefinedVariableInfo(const TType& type,
180 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000181 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000182 TVariableInfoList& infoList,
183 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000184{
Jamie Madill98493dd2013-07-08 14:39:03 -0400185 ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000186
Dan Glastonburyb66feb32014-05-14 15:38:55 +1000187 const TFieldList& fields = type.isInterfaceBlock() ?
188 type.getInterfaceBlock()->fields() :
189 type.getStruct()->fields();
Jamie Madill98493dd2013-07-08 14:39:03 -0400190 for (size_t i = 0; i < fields.size(); ++i) {
191 const TType& fieldType = *(fields[i]->type());
192 const TString& fieldName = fields[i]->name();
193 getVariableInfo(fieldType,
194 name + "." + fieldName,
195 mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000196 infoList,
197 hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000198 }
199}
200
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400201TVariableInfo* findVariable(const TType& type,
202 const TString& name,
203 TVariableInfoList& infoList)
204{
205 // TODO(zmo): optimize this function.
206 TString myName = name;
207 if (type.isArray())
208 myName += "[0]";
209 for (size_t ii = 0; ii < infoList.size(); ++ii)
210 {
211 if (infoList[ii].name.c_str() == myName)
212 return &(infoList[ii]);
213 }
214 return NULL;
215}
216
217} // namespace anonymous
218
gman@chromium.org8d804792012-10-17 21:33:48 +0000219TVariableInfo::TVariableInfo()
Jamie Madill53221f52014-06-25 16:04:59 -0400220 : type(GL_NONE),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400221 size(0),
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800222 isArray(false),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400223 precision(EbpUndefined),
224 staticUse(false)
gman@chromium.org8d804792012-10-17 21:33:48 +0000225{
226}
227
Jamie Madill53221f52014-06-25 16:04:59 -0400228TVariableInfo::TVariableInfo(sh::GLenum type, int size)
gman@chromium.org8d804792012-10-17 21:33:48 +0000229 : type(type),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400230 size(size),
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800231 isArray(false),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400232 precision(EbpUndefined),
233 staticUse(false)
gman@chromium.org8d804792012-10-17 21:33:48 +0000234{
235}
236
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400237CollectVariables::CollectVariables(TVariableInfoList& attribs,
238 TVariableInfoList& uniforms,
239 TVariableInfoList& varyings,
240 ShHashFunction64 hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000241 : mAttribs(attribs),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000242 mUniforms(uniforms),
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400243 mVaryings(varyings),
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400244 mPointCoordAdded(false),
245 mFrontFacingAdded(false),
246 mFragCoordAdded(false),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000247 mHashFunction(hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000248{
249}
250
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400251// We want to check whether a uniform/varying is statically used
252// because we only count the used ones in packing computing.
253// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
254// toward varying counting if they are statically used in a fragment
255// shader.
256void CollectVariables::visitSymbol(TIntermSymbol* symbol)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000257{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400258 ASSERT(symbol != NULL);
259 TVariableInfo* var = NULL;
260 switch (symbol->getQualifier())
261 {
262 case EvqVaryingOut:
263 case EvqInvariantVaryingOut:
264 case EvqVaryingIn:
265 case EvqInvariantVaryingIn:
266 var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings);
267 break;
268 case EvqUniform:
269 var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms);
270 break;
271 case EvqFragCoord:
272 if (!mFragCoordAdded) {
273 TVariableInfo info;
274 info.name = "gl_FragCoord";
275 info.mappedName = "gl_FragCoord";
Jamie Madill53221f52014-06-25 16:04:59 -0400276 info.type = GL_FLOAT_VEC4;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400277 info.size = 1;
278 info.precision = EbpMedium; // Use mediump as it doesn't really matter.
279 info.staticUse = true;
280 mVaryings.push_back(info);
281 mFragCoordAdded = true;
282 }
283 return;
284 case EvqFrontFacing:
285 if (!mFrontFacingAdded) {
286 TVariableInfo info;
287 info.name = "gl_FrontFacing";
288 info.mappedName = "gl_FrontFacing";
Jamie Madill53221f52014-06-25 16:04:59 -0400289 info.type = GL_BOOL;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400290 info.size = 1;
291 info.precision = EbpUndefined;
292 info.staticUse = true;
293 mVaryings.push_back(info);
294 mFrontFacingAdded = true;
295 }
296 return;
297 case EvqPointCoord:
298 if (!mPointCoordAdded) {
299 TVariableInfo info;
300 info.name = "gl_PointCoord";
301 info.mappedName = "gl_PointCoord";
Jamie Madill53221f52014-06-25 16:04:59 -0400302 info.type = GL_FLOAT_VEC2;
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400303 info.size = 1;
304 info.precision = EbpMedium; // Use mediump as it doesn't really matter.
305 info.staticUse = true;
306 mVaryings.push_back(info);
307 mPointCoordAdded = true;
308 }
309 return;
310 default:
311 break;
312 }
313 if (var)
314 var->staticUse = true;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000315}
316
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400317bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000318{
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400319 bool visitChildren = true;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000320
321 switch (node->getOp())
322 {
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000323 case EOpDeclaration: {
324 const TIntermSequence& sequence = node->getSequence();
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000325 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400326 if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqUniform ||
327 qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
328 qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000329 {
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400330 TVariableInfoList *infoList = NULL;
331
332 switch (qualifier)
333 {
334 case EvqAttribute:
335 case EvqVertexIn:
336 infoList = &mAttribs;
337 break;
338 case EvqUniform:
339 infoList = &mUniforms;
340 break;
341 default:
342 infoList = &mVaryings;
343 break;
344 }
345
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000346 for (TIntermSequence::const_iterator i = sequence.begin();
347 i != sequence.end(); ++i)
348 {
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000349 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
350 // The only case in which the sequence will not contain a
351 // TIntermSymbol node is initialization. It will contain a
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400352 // TInterBinary node in that case. Since attributes, uniforms,
353 // and varyings cannot be initialized in a shader, we must have
354 // only TIntermSymbol nodes in the sequence.
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000355 ASSERT(variable != NULL);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000356 TString processedSymbol;
357 if (mHashFunction == NULL)
358 processedSymbol = variable->getSymbol();
359 else
Zhenyao Mo3cdfcce2014-03-07 13:00:08 -0800360 processedSymbol = TIntermTraverser::hash(variable->getSymbol(), mHashFunction);
zmo@google.comfd747b82011-04-23 01:30:07 +0000361 getVariableInfo(variable->getType(),
Zhenyao Mo3cdfcce2014-03-07 13:00:08 -0800362 variable->getSymbol(),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000363 processedSymbol,
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400364 *infoList,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000365 mHashFunction);
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400366 visitChildren = false;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000367 }
368 }
369 break;
370 }
371 default: break;
372 }
373
374 return visitChildren;
375}