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