blob: a1f41addf275307508b857ec5030ad5409ccf54d [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.org09e09882013-05-30 00:18:25 +000022 switch (type.getRows()) {
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000023 case 2: return SH_FLOAT_MAT2;
24 case 3: return SH_FLOAT_MAT3;
25 case 4: return SH_FLOAT_MAT4;
26 default: UNREACHABLE();
27 }
28 } else if (type.isVector()) {
29 switch (type.getNominalSize()) {
30 case 2: return SH_FLOAT_VEC2;
31 case 3: return SH_FLOAT_VEC3;
32 case 4: return SH_FLOAT_VEC4;
33 default: UNREACHABLE();
34 }
35 } else {
36 return SH_FLOAT;
37 }
38 case EbtInt:
39 if (type.isMatrix()) {
40 UNREACHABLE();
41 } else if (type.isVector()) {
42 switch (type.getNominalSize()) {
43 case 2: return SH_INT_VEC2;
44 case 3: return SH_INT_VEC3;
45 case 4: return SH_INT_VEC4;
46 default: UNREACHABLE();
47 }
48 } else {
49 return SH_INT;
50 }
51 case EbtBool:
52 if (type.isMatrix()) {
53 UNREACHABLE();
54 } else if (type.isVector()) {
55 switch (type.getNominalSize()) {
56 case 2: return SH_BOOL_VEC2;
57 case 3: return SH_BOOL_VEC3;
58 case 4: return SH_BOOL_VEC4;
59 default: UNREACHABLE();
60 }
61 } else {
62 return SH_BOOL;
63 }
64 case EbtSampler2D: return SH_SAMPLER_2D;
65 case EbtSamplerCube: return SH_SAMPLER_CUBE;
apatrick@chromium.org65756022012-01-17 21:45:38 +000066 case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
kbr@chromium.org205fef32011-11-22 20:50:02 +000067 case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000068 default: UNREACHABLE();
69 }
70 return SH_NONE;
71}
72
73static void getBuiltInVariableInfo(const TType& type,
74 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +000075 const TString& mappedName,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000076 TVariableInfoList& infoList);
77static void getUserDefinedVariableInfo(const TType& type,
78 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +000079 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +000080 TVariableInfoList& infoList,
81 ShHashFunction64 hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000082
83// Returns info for an attribute or uniform.
84static void getVariableInfo(const TType& type,
85 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +000086 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +000087 TVariableInfoList& infoList,
88 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000089{
90 if (type.getBasicType() == EbtStruct) {
91 if (type.isArray()) {
92 for (int i = 0; i < type.getArraySize(); ++i) {
93 TString lname = name + arrayBrackets(i);
zmo@google.comfd747b82011-04-23 01:30:07 +000094 TString lmappedName = mappedName + arrayBrackets(i);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +000095 getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000096 }
97 } else {
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +000098 getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +000099 }
100 } else {
zmo@google.comfd747b82011-04-23 01:30:07 +0000101 getBuiltInVariableInfo(type, name, mappedName, infoList);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000102 }
103}
104
105void getBuiltInVariableInfo(const TType& type,
106 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000107 const TString& mappedName,
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000108 TVariableInfoList& infoList)
109{
110 ASSERT(type.getBasicType() != EbtStruct);
111
112 TVariableInfo varInfo;
113 if (type.isArray()) {
114 varInfo.name = (name + "[0]").c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000115 varInfo.mappedName = (mappedName + "[0]").c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000116 varInfo.size = type.getArraySize();
117 } else {
118 varInfo.name = name.c_str();
zmo@google.comfd747b82011-04-23 01:30:07 +0000119 varInfo.mappedName = mappedName.c_str();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000120 varInfo.size = 1;
121 }
122 varInfo.type = getVariableDataType(type);
123 infoList.push_back(varInfo);
124}
125
126void getUserDefinedVariableInfo(const TType& type,
127 const TString& name,
zmo@google.comfd747b82011-04-23 01:30:07 +0000128 const TString& mappedName,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000129 TVariableInfoList& infoList,
130 ShHashFunction64 hashFunction)
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000131{
132 ASSERT(type.getBasicType() == EbtStruct);
133
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000134 const TTypeList* structure = type.getStruct();
135 for (size_t i = 0; i < structure->size(); ++i) {
136 const TType* fieldType = (*structure)[i].type;
137 getVariableInfo(*fieldType,
zmo@google.comfd747b82011-04-23 01:30:07 +0000138 name + "." + fieldType->getFieldName(),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000139 mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
140 infoList,
141 hashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000142 }
143}
144
gman@chromium.org8d804792012-10-17 21:33:48 +0000145TVariableInfo::TVariableInfo()
146{
147}
148
149TVariableInfo::TVariableInfo(ShDataType type, int size)
150 : type(type),
151 size(size)
152{
153}
154
alokp@chromium.org07620a52010-09-23 17:53:56 +0000155CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000156 TVariableInfoList& uniforms,
157 ShHashFunction64 hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000158 : mAttribs(attribs),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000159 mUniforms(uniforms),
160 mHashFunction(hashFunction)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000161{
162}
163
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000164// We are only interested in attribute and uniform variable declaration.
alokp@chromium.org07620a52010-09-23 17:53:56 +0000165void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
166{
167}
168
169void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
170{
171}
172
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000173bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000174{
175 return false;
176}
177
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000178bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000179{
180 return false;
181}
182
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000183bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000184{
185 return false;
186}
187
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000188bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
189{
190 bool visitChildren = false;
191
192 switch (node->getOp())
193 {
194 case EOpSequence:
195 // We need to visit sequence children to get to variable declarations.
196 visitChildren = true;
197 break;
198 case EOpDeclaration: {
199 const TIntermSequence& sequence = node->getSequence();
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000200 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000201 if (qualifier == EvqAttribute || qualifier == EvqUniform)
202 {
203 TVariableInfoList& infoList = qualifier == EvqAttribute ?
204 mAttribs : mUniforms;
205 for (TIntermSequence::const_iterator i = sequence.begin();
206 i != sequence.end(); ++i)
207 {
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000208 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
209 // The only case in which the sequence will not contain a
210 // TIntermSymbol node is initialization. It will contain a
shannonwoods@chromium.orge429ab72013-05-30 00:12:52 +0000211 // TIntermBinary node in that case. Since attributes and uniforms
alokp@chromium.org10e6e9e2010-09-27 21:03:45 +0000212 // cannot be initialized in a shader, we must have only
213 // TIntermSymbol nodes in the sequence.
214 ASSERT(variable != NULL);
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000215 TString processedSymbol;
216 if (mHashFunction == NULL)
217 processedSymbol = variable->getSymbol();
218 else
219 processedSymbol = TIntermTraverser::hash(variable->getOriginalSymbol(), mHashFunction);
zmo@google.comfd747b82011-04-23 01:30:07 +0000220 getVariableInfo(variable->getType(),
221 variable->getOriginalSymbol(),
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000222 processedSymbol,
223 infoList,
224 mHashFunction);
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000225 }
226 }
227 break;
228 }
229 default: break;
230 }
231
232 return visitChildren;
233}
234
235bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000236{
237 return false;
238}
239
alokp@chromium.orgee76f6a2010-09-27 19:28:55 +0000240bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000241{
242 return false;
243}
244