1 //
2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3 // 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
arrayBrackets(int index)9 static 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.
getVariableDataType(const TType & type)17 static ShDataType getVariableDataType(const TType& type)
18 {
19 switch (type.getBasicType()) {
20 case EbtFloat:
21 if (type.isMatrix()) {
22 switch (type.getNominalSize()) {
23 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;
66 default: UNREACHABLE();
67 }
68 return SH_NONE;
69 }
70
71 static void getBuiltInVariableInfo(const TType& type,
72 const TString& name,
73 TVariableInfoList& infoList);
74 static void getUserDefinedVariableInfo(const TType& type,
75 const TString& name,
76 TVariableInfoList& infoList);
77
78 // Returns info for an attribute or uniform.
getVariableInfo(const TType & type,const TString & name,TVariableInfoList & infoList)79 static void getVariableInfo(const TType& type,
80 const TString& name,
81 TVariableInfoList& infoList)
82 {
83 if (type.getBasicType() == EbtStruct) {
84 if (type.isArray()) {
85 for (int i = 0; i < type.getArraySize(); ++i) {
86 TString lname = name + arrayBrackets(i);
87 getUserDefinedVariableInfo(type, lname, infoList);
88 }
89 } else {
90 getUserDefinedVariableInfo(type, name, infoList);
91 }
92 } else {
93 getBuiltInVariableInfo(type, name, infoList);
94 }
95 }
96
getBuiltInVariableInfo(const TType & type,const TString & name,TVariableInfoList & infoList)97 void getBuiltInVariableInfo(const TType& type,
98 const TString& name,
99 TVariableInfoList& infoList)
100 {
101 ASSERT(type.getBasicType() != EbtStruct);
102
103 TVariableInfo varInfo;
104 if (type.isArray()) {
105 varInfo.name = (name + "[0]").c_str();
106 varInfo.size = type.getArraySize();
107 } else {
108 varInfo.name = name.c_str();
109 varInfo.size = 1;
110 }
111 varInfo.type = getVariableDataType(type);
112 infoList.push_back(varInfo);
113 }
114
getUserDefinedVariableInfo(const TType & type,const TString & name,TVariableInfoList & infoList)115 void getUserDefinedVariableInfo(const TType& type,
116 const TString& name,
117 TVariableInfoList& infoList)
118 {
119 ASSERT(type.getBasicType() == EbtStruct);
120
121 TString lname = name + ".";
122 const TTypeList* structure = type.getStruct();
123 for (size_t i = 0; i < structure->size(); ++i) {
124 const TType* fieldType = (*structure)[i].type;
125 getVariableInfo(*fieldType,
126 lname + fieldType->getFieldName(),
127 infoList);
128 }
129 }
130
CollectAttribsUniforms(TVariableInfoList & attribs,TVariableInfoList & uniforms)131 CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
132 TVariableInfoList& uniforms)
133 : mAttribs(attribs),
134 mUniforms(uniforms)
135 {
136 }
137
138 // We are only interested in attribute and uniform variable declaration.
visitSymbol(TIntermSymbol *)139 void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
140 {
141 }
142
visitConstantUnion(TIntermConstantUnion *)143 void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
144 {
145 }
146
visitBinary(Visit,TIntermBinary *)147 bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
148 {
149 return false;
150 }
151
visitUnary(Visit,TIntermUnary *)152 bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
153 {
154 return false;
155 }
156
visitSelection(Visit,TIntermSelection *)157 bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
158 {
159 return false;
160 }
161
visitAggregate(Visit,TIntermAggregate * node)162 bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
163 {
164 bool visitChildren = false;
165
166 switch (node->getOp())
167 {
168 case EOpSequence:
169 // We need to visit sequence children to get to variable declarations.
170 visitChildren = true;
171 break;
172 case EOpDeclaration: {
173 const TIntermSequence& sequence = node->getSequence();
174 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
175 if (qualifier == EvqAttribute || qualifier == EvqUniform)
176 {
177 TVariableInfoList& infoList = qualifier == EvqAttribute ?
178 mAttribs : mUniforms;
179 for (TIntermSequence::const_iterator i = sequence.begin();
180 i != sequence.end(); ++i)
181 {
182 const TIntermSymbol* variable = (*i)->getAsSymbolNode();
183 // The only case in which the sequence will not contain a
184 // TIntermSymbol node is initialization. It will contain a
185 // TInterBinary node in that case. Since attributes and unifroms
186 // cannot be initialized in a shader, we must have only
187 // TIntermSymbol nodes in the sequence.
188 ASSERT(variable != NULL);
189 getVariableInfo(variable->getType(), variable->getSymbol(),
190 infoList);
191 }
192 }
193 break;
194 }
195 default: break;
196 }
197
198 return visitChildren;
199 }
200
visitLoop(Visit,TIntermLoop *)201 bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
202 {
203 return false;
204 }
205
visitBranch(Visit,TIntermBranch *)206 bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
207 {
208 return false;
209 }
210
211