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