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 :
9 0 : static TString arrayBrackets(int index)
10 : {
11 0 : TStringStream stream;
12 0 : stream << "[" << index << "]";
13 0 : return stream.str();
14 : }
15 :
16 : // Returns the data type for an attribute or uniform.
17 0 : static ShDataType getVariableDataType(const TType& type)
18 : {
19 0 : switch (type.getBasicType()) {
20 : case EbtFloat:
21 0 : if (type.isMatrix()) {
22 0 : switch (type.getNominalSize()) {
23 0 : case 2: return SH_FLOAT_MAT2;
24 0 : case 3: return SH_FLOAT_MAT3;
25 0 : case 4: return SH_FLOAT_MAT4;
26 0 : default: UNREACHABLE();
27 : }
28 0 : } else if (type.isVector()) {
29 0 : switch (type.getNominalSize()) {
30 0 : case 2: return SH_FLOAT_VEC2;
31 0 : case 3: return SH_FLOAT_VEC3;
32 0 : case 4: return SH_FLOAT_VEC4;
33 0 : default: UNREACHABLE();
34 : }
35 : } else {
36 0 : return SH_FLOAT;
37 : }
38 : case EbtInt:
39 0 : if (type.isMatrix()) {
40 0 : UNREACHABLE();
41 0 : } else if (type.isVector()) {
42 0 : switch (type.getNominalSize()) {
43 0 : case 2: return SH_INT_VEC2;
44 0 : case 3: return SH_INT_VEC3;
45 0 : case 4: return SH_INT_VEC4;
46 0 : default: UNREACHABLE();
47 : }
48 : } else {
49 0 : return SH_INT;
50 : }
51 : case EbtBool:
52 0 : if (type.isMatrix()) {
53 0 : UNREACHABLE();
54 0 : } else if (type.isVector()) {
55 0 : switch (type.getNominalSize()) {
56 0 : case 2: return SH_BOOL_VEC2;
57 0 : case 3: return SH_BOOL_VEC3;
58 0 : case 4: return SH_BOOL_VEC4;
59 0 : default: UNREACHABLE();
60 : }
61 : } else {
62 0 : return SH_BOOL;
63 : }
64 0 : case EbtSampler2D: return SH_SAMPLER_2D;
65 0 : case EbtSamplerCube: return SH_SAMPLER_CUBE;
66 0 : case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
67 0 : case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
68 0 : default: UNREACHABLE();
69 : }
70 : return SH_NONE;
71 : }
72 :
73 : static void getBuiltInVariableInfo(const TType& type,
74 : const TString& name,
75 : const TString& mappedName,
76 : TVariableInfoList& infoList);
77 : static void getUserDefinedVariableInfo(const TType& type,
78 : const TString& name,
79 : const TString& mappedName,
80 : TVariableInfoList& infoList);
81 :
82 : // Returns info for an attribute or uniform.
83 0 : static void getVariableInfo(const TType& type,
84 : const TString& name,
85 : const TString& mappedName,
86 : TVariableInfoList& infoList)
87 : {
88 0 : if (type.getBasicType() == EbtStruct) {
89 0 : if (type.isArray()) {
90 0 : for (int i = 0; i < type.getArraySize(); ++i) {
91 0 : TString lname = name + arrayBrackets(i);
92 0 : TString lmappedName = mappedName + arrayBrackets(i);
93 0 : getUserDefinedVariableInfo(type, lname, lmappedName, infoList);
94 : }
95 : } else {
96 0 : getUserDefinedVariableInfo(type, name, mappedName, infoList);
97 : }
98 : } else {
99 0 : getBuiltInVariableInfo(type, name, mappedName, infoList);
100 : }
101 0 : }
102 :
103 0 : void getBuiltInVariableInfo(const TType& type,
104 : const TString& name,
105 : const TString& mappedName,
106 : TVariableInfoList& infoList)
107 : {
108 0 : ASSERT(type.getBasicType() != EbtStruct);
109 :
110 0 : TVariableInfo varInfo;
111 0 : if (type.isArray()) {
112 0 : varInfo.name = (name + "[0]").c_str();
113 0 : varInfo.mappedName = (mappedName + "[0]").c_str();
114 0 : varInfo.size = type.getArraySize();
115 : } else {
116 0 : varInfo.name = name.c_str();
117 0 : varInfo.mappedName = mappedName.c_str();
118 0 : varInfo.size = 1;
119 : }
120 0 : varInfo.type = getVariableDataType(type);
121 0 : infoList.push_back(varInfo);
122 0 : }
123 :
124 0 : void getUserDefinedVariableInfo(const TType& type,
125 : const TString& name,
126 : const TString& mappedName,
127 : TVariableInfoList& infoList)
128 : {
129 0 : ASSERT(type.getBasicType() == EbtStruct);
130 :
131 0 : const TTypeList* structure = type.getStruct();
132 0 : for (size_t i = 0; i < structure->size(); ++i) {
133 0 : const TType* fieldType = (*structure)[i].type;
134 : getVariableInfo(*fieldType,
135 0 : name + "." + fieldType->getFieldName(),
136 0 : mappedName + "." + fieldType->getFieldName(),
137 0 : infoList);
138 : }
139 0 : }
140 :
141 0 : CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
142 : TVariableInfoList& uniforms)
143 : : mAttribs(attribs),
144 0 : mUniforms(uniforms)
145 : {
146 0 : }
147 :
148 : // We are only interested in attribute and uniform variable declaration.
149 0 : void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
150 : {
151 0 : }
152 :
153 0 : void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
154 : {
155 0 : }
156 :
157 0 : bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
158 : {
159 0 : return false;
160 : }
161 :
162 0 : bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
163 : {
164 0 : return false;
165 : }
166 :
167 0 : bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
168 : {
169 0 : return false;
170 : }
171 :
172 0 : bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
173 : {
174 0 : bool visitChildren = false;
175 :
176 0 : switch (node->getOp())
177 : {
178 : case EOpSequence:
179 : // We need to visit sequence children to get to variable declarations.
180 0 : visitChildren = true;
181 0 : break;
182 : case EOpDeclaration: {
183 0 : const TIntermSequence& sequence = node->getSequence();
184 0 : TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
185 0 : if (qualifier == EvqAttribute || qualifier == EvqUniform)
186 : {
187 : TVariableInfoList& infoList = qualifier == EvqAttribute ?
188 0 : mAttribs : mUniforms;
189 0 : for (TIntermSequence::const_iterator i = sequence.begin();
190 0 : i != sequence.end(); ++i)
191 : {
192 0 : const TIntermSymbol* variable = (*i)->getAsSymbolNode();
193 : // The only case in which the sequence will not contain a
194 : // TIntermSymbol node is initialization. It will contain a
195 : // TInterBinary node in that case. Since attributes and unifroms
196 : // cannot be initialized in a shader, we must have only
197 : // TIntermSymbol nodes in the sequence.
198 0 : ASSERT(variable != NULL);
199 0 : getVariableInfo(variable->getType(),
200 0 : variable->getOriginalSymbol(),
201 0 : variable->getSymbol(),
202 0 : infoList);
203 : }
204 : }
205 0 : break;
206 : }
207 0 : default: break;
208 : }
209 :
210 0 : return visitChildren;
211 : }
212 :
213 0 : bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
214 : {
215 0 : return false;
216 : }
217 :
218 0 : bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
219 : {
220 0 : return false;
221 : }
222 :
|