blob: f6be24011443757462a26451c0fed4ff00df2880 [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
7#include "compiler/VariableInfo.h"
8
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +00009static TString arrayBrackets(int index)
10{
11 TStringStream stream;
12 stream << "[" << index << "]";
13 return stream.str();
14}
15
16// Returns the data type for an attribute or uniform.
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000017static ShDataType getVariableDataType(const TType& type)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000018{
19 switch (type.getBasicType()) {
20 case EbtFloat:
21 if (type.isMatrix()) {
shannonwoods@chromium.org8da034c2013-05-30 00:19:15 +000022 switch (type.getCols())
23 {
24 case 2:
25 switch (type.getRows())
26 {
27 case 2: return SH_FLOAT_MAT2;
28 case 3: return SH_FLOAT_MAT2x3;
29 case 4: return SH_FLOAT_MAT2x4;
30 default: UNREACHABLE();
31 }
32 case 3:
33 switch (type.getRows())
34 {
35 case 2: return SH_FLOAT_MAT3x2;
36 case 3: return SH_FLOAT_MAT3;
37 case 4: return SH_FLOAT_MAT3x4;
38 default: UNREACHABLE();
39 }
40 case 4:
41 switch (type.getRows())
42 {
43 case 2: return SH_FLOAT_MAT4x2;
44 case 3: return SH_FLOAT_MAT4x3;
45 case 4: return SH_FLOAT_MAT4;
46 default: UNREACHABLE();
47 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000048 }
49 } else if (type.isVector()) {
50 switch (type.getNominalSize()) {
51 case 2: return SH_FLOAT_VEC2;
52 case 3: return SH_FLOAT_VEC3;
53 case 4: return SH_FLOAT_VEC4;
54 default: UNREACHABLE();
55 }
56 } else {
57 return SH_FLOAT;
58 }
59 case EbtInt:
60 if (type.isMatrix()) {
61 UNREACHABLE();
62 } else if (type.isVector()) {
63 switch (type.getNominalSize()) {
64 case 2: return SH_INT_VEC2;
65 case 3: return SH_INT_VEC3;
66 case 4: return SH_INT_VEC4;
67 default: UNREACHABLE();
68 }
69 } else {
70 return SH_INT;
71 }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000072 case EbtUInt:
73 if (type.isMatrix()) {
74 UNREACHABLE();
75 } else if (type.isVector()) {
Jamie Madill22d63da2013-06-07 12:45:12 -040076 switch (type.getNominalSize()) {
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000077 case 2: return SH_UNSIGNED_INT_VEC2;
78 case 3: return SH_UNSIGNED_INT_VEC3;
79 case 4: return SH_UNSIGNED_INT_VEC4;
80 default: UNREACHABLE();
81 }
82 } else {
83 return SH_UNSIGNED_INT;
84 }
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000085 case EbtBool:
86 if (type.isMatrix()) {
87 UNREACHABLE();
88 } else if (type.isVector()) {
89 switch (type.getNominalSize()) {
90 case 2: return SH_BOOL_VEC2;
91 case 3: return SH_BOOL_VEC3;
92 case 4: return SH_BOOL_VEC4;
93 default: UNREACHABLE();
94 }
95 } else {
96 return SH_BOOL;
97 }
98 case EbtSampler2D: return SH_SAMPLER_2D;
Nicolas Capens8772b582013-06-24 16:14:19 -040099 case EbtSampler3D: return SH_SAMPLER_3D;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000100 case EbtSamplerCube: return SH_SAMPLER_CUBE;
apatrick@chromium.org65756022012-01-17 21:45:38 +0000101 case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
kbr@chromium.org205fef32011-11-22 20:50:02 +0000102 case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
Nicolas Capens8772b582013-06-24 16:14:19 -0400103 case EbtSampler2DArray: return SH_SAMPLER_2D_ARRAY;
Nicolas Capens344e7142013-06-24 15:39:21 -0400104 case EbtISampler2D: return SH_INT_SAMPLER_2D;
Nicolas Capens8772b582013-06-24 16:14:19 -0400105 case EbtISampler3D: return SH_INT_SAMPLER_3D;
Nicolas Capens344e7142013-06-24 15:39:21 -0400106 case EbtISamplerCube: return SH_INT_SAMPLER_CUBE;
Nicolas Capens8772b582013-06-24 16:14:19 -0400107 case EbtISampler2DArray: return SH_INT_SAMPLER_2D_ARRAY;
Nicolas Capens2ffe0bb2013-06-24 15:56:19 -0400108 case EbtUSampler2D: return SH_UNSIGNED_INT_SAMPLER_2D;
Nicolas Capens8772b582013-06-24 16:14:19 -0400109 case EbtUSampler3D: return SH_UNSIGNED_INT_SAMPLER_3D;
Nicolas Capens2ffe0bb2013-06-24 15:56:19 -0400110 case EbtUSamplerCube: return SH_UNSIGNED_INT_SAMPLER_CUBE;
Nicolas Capens8772b582013-06-24 16:14:19 -0400111 case EbtUSampler2DArray: return SH_UNSIGNED_INT_SAMPLER_2D_ARRAY;
Nicolas Capens2a1d8a32013-07-18 11:49:40 -0400112 case EbtSampler2DShadow: return SH_SAMPLER_2D_SHADOW;
113 case EbtSamplerCubeShadow: return SH_SAMPLER_CUBE_SHADOW;
114 case EbtSampler2DArrayShadow: return SH_SAMPLER_2D_ARRAY_SHADOW;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000115 default: UNREACHABLE();
116 }
117 return SH_NONE;
118}
119
120static void getBuiltInVariableInfo(const TType& type,
121 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000122 const TString& mappedName,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000123 TVariableInfoList& infoList);
124static void getUserDefinedVariableInfo(const TType& type,
125 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000126 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000127 TVariableInfoList& infoList,
128 ShHashFunction64 hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000129
130// Returns info for an attribute or uniform.
131static void getVariableInfo(const TType& type,
132 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000133 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000134 TVariableInfoList& infoList,
135 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000136{
137 if (type.getBasicType() == EbtStruct) {
138 if (type.isArray()) {
139 for (int i = 0; i < type.getArraySize(); ++i) {
140 TString lname = name + arrayBrackets(i);
zmo@google.comfd747b82011-04-23 01:30:07 +0000141 TString lmappedName = mappedName + arrayBrackets(i);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000142 getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000143 }
144 } else {
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000145 getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000146 }
147 } else {
zmo@google.comfd747b82011-04-23 01:30:07 +0000148 getBuiltInVariableInfo(type, name, mappedName, infoList);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000149 }
150}
151
152void getBuiltInVariableInfo(const TType& type,
153 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000154 const TString& mappedName,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000155 TVariableInfoList& infoList)
156{
157 ASSERT(type.getBasicType() != EbtStruct);
158
159 TVariableInfo varInfo;
160 if (type.isArray()) {
161 varInfo.name = (name + "[0]").c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000162 varInfo.mappedName = (mappedName + "[0]").c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000163 varInfo.size = type.getArraySize();
164 } else {
165 varInfo.name = name.c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000166 varInfo.mappedName = mappedName.c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000167 varInfo.size = 1;
168 }
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400169 varInfo.precision = type.getPrecision();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000170 varInfo.type = getVariableDataType(type);
171 infoList.push_back(varInfo);
172}
173
174void getUserDefinedVariableInfo(const TType& type,
175 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000176 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000177 TVariableInfoList& infoList,
178 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000179{
Jamie Madill98493dd2013-07-08 14:39:03 -0400180 ASSERT(type.getBasicType() == EbtStruct || type.isInterfaceBlock());
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000181
Jamie Madill98493dd2013-07-08 14:39:03 -0400182 const TFieldList& fields = type.getStruct()->fields();
183 for (size_t i = 0; i < fields.size(); ++i) {
184 const TType& fieldType = *(fields[i]->type());
185 const TString& fieldName = fields[i]->name();
186 getVariableInfo(fieldType,
187 name + "." + fieldName,
188 mappedName + "." + TIntermTraverser::hash(fieldName, hashFunction),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000189 infoList,
190 hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000191 }
192}
193
gman@chromium.org8d804792012-10-17 21:33:48 +0000194TVariableInfo::TVariableInfo()
195{
196}
197
198TVariableInfo::TVariableInfo(ShDataType type, int size)
199 : type(type),
200 size(size)
201{
202}
203
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400204CollectVariables::CollectVariables(TVariableInfoList& attribs,
205 TVariableInfoList& uniforms,
206 TVariableInfoList& varyings,
207 ShHashFunction64 hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000208 : mAttribs(attribs),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000209 mUniforms(uniforms),
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400210 mVaryings(varyings),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000211 mHashFunction(hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000212{
213}
214
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000215// We are only interested in attribute and uniform variable declaration.
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400216void CollectVariables::visitSymbol(TIntermSymbol*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000217{
218}
219
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400220void CollectVariables::visitConstantUnion(TIntermConstantUnion*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000221{
222}
223
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400224bool CollectVariables::visitBinary(Visit, TIntermBinary*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000225{
226 return false;
227}
228
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400229bool CollectVariables::visitUnary(Visit, TIntermUnary*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000230{
231 return false;
232}
233
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400234bool CollectVariables::visitSelection(Visit, TIntermSelection*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000235{
236 return false;
237}
238
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400239bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000240{
241 bool visitChildren = false;
242
243 switch (node->getOp())
244 {
245 case EOpSequence:
246 // We need to visit sequence children to get to variable declarations.
247 visitChildren = true;
248 break;
249 case EOpDeclaration: {
250 const TIntermSequence& sequence = node->getSequence();
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000251 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400252 if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqUniform ||
253 qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
254 qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000255 {
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400256 TVariableInfoList *infoList = NULL;
257
258 switch (qualifier)
259 {
260 case EvqAttribute:
261 case EvqVertexIn:
262 infoList = &mAttribs;
263 break;
264 case EvqUniform:
265 infoList = &mUniforms;
266 break;
267 default:
268 infoList = &mVaryings;
269 break;
270 }
271
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000272 for (TIntermSequence::const_iterator i = sequence.begin();
273 i != sequence.end(); ++i)
274 {
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000275 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
276 // The only case in which the sequence will not contain a
277 // TIntermSymbol node is initialization. It will contain a
shannonwoods@chromium.orge429ab72013-05-30 00:12:52 +0000278 // TIntermBinary node in that case. Since attributes and uniforms
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000279 // cannot be initialized in a shader, we must have only
280 // TIntermSymbol nodes in the sequence.
281 ASSERT(variable != NULL);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000282 TString processedSymbol;
283 if (mHashFunction == NULL)
284 processedSymbol = variable->getSymbol();
285 else
286 processedSymbol = TIntermTraverser::hash(variable->getOriginalSymbol(), mHashFunction);
zmo@google.comfd747b82011-04-23 01:30:07 +0000287 getVariableInfo(variable->getType(),
288 variable->getOriginalSymbol(),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000289 processedSymbol,
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400290 *infoList,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000291 mHashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000292 }
293 }
294 break;
295 }
296 default: break;
297 }
298
299 return visitChildren;
300}
301
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400302bool CollectVariables::visitLoop(Visit, TIntermLoop*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000303{
304 return false;
305}
306
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400307bool CollectVariables::visitBranch(Visit, TIntermBranch*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000308{
309 return false;
310}
311