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 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. 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 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 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 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. 139 void CollectAttribsUniforms::visitSymbol(TIntermSymbol*) 140 { 141 } 142 143 void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*) 144 { 145 } 146 147 bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*) 148 { 149 return false; 150 } 151 152 bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*) 153 { 154 return false; 155 } 156 157 bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*) 158 { 159 return false; 160 } 161 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 201 bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*) 202 { 203 return false; 204 } 205 206 bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*) 207 { 208 return false; 209 } 210 211