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.
7 #include "compiler/VariableInfo.h"
9 static TString arrayBrackets(int index)
12 stream << "[" << index << "]";
16 // Returns the data type for an attribute or uniform.
17 static ShDataType getVariableDataType(const TType& type)
19 switch (type.getBasicType()) {
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();
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();
39 if (type.isMatrix()) {
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();
52 if (type.isMatrix()) {
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();
64 case EbtSampler2D: return SH_SAMPLER_2D;
65 case EbtSamplerCube: return SH_SAMPLER_CUBE;
66 default: UNREACHABLE();
71 static void getBuiltInVariableInfo(const TType& type,
73 const TString& mappedName,
74 TVariableInfoList& infoList);
75 static void getUserDefinedVariableInfo(const TType& type,
77 const TString& mappedName,
78 TVariableInfoList& infoList);
80 // Returns info for an attribute or uniform.
81 static void getVariableInfo(const TType& type,
83 const TString& mappedName,
84 TVariableInfoList& infoList)
86 if (type.getBasicType() == EbtStruct) {
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);
94 getUserDefinedVariableInfo(type, name, mappedName, infoList);
97 getBuiltInVariableInfo(type, name, mappedName, infoList);
101 void getBuiltInVariableInfo(const TType& type,
103 const TString& mappedName,
104 TVariableInfoList& infoList)
106 ASSERT(type.getBasicType() != EbtStruct);
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();
114 varInfo.name = name.c_str();
115 varInfo.mappedName = mappedName.c_str();
118 varInfo.type = getVariableDataType(type);
119 infoList.push_back(varInfo);
122 void getUserDefinedVariableInfo(const TType& type,
124 const TString& mappedName,
125 TVariableInfoList& infoList)
127 ASSERT(type.getBasicType() == EbtStruct);
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(),
139 CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
140 TVariableInfoList& uniforms)
146 // We are only interested in attribute and uniform variable declaration.
147 void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
151 void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
155 bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
160 bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
165 bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
170 bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
172 bool visitChildren = false;
174 switch (node->getOp())
177 // We need to visit sequence children to get to variable declarations.
178 visitChildren = true;
180 case EOpDeclaration: {
181 const TIntermSequence& sequence = node->getSequence();
182 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
183 if (qualifier == EvqAttribute || qualifier == EvqUniform)
185 TVariableInfoList& infoList = qualifier == EvqAttribute ?
186 mAttribs : mUniforms;
187 for (TIntermSequence::const_iterator i = sequence.begin();
188 i != sequence.end(); ++i)
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(),
208 return visitChildren;
211 bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
216 bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)