1 // 2 // Copyright (c) 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/translator/util.h" 8 9 #include <limits> 10 11 #include "compiler/preprocessor/numeric_lex.h" 12 #include "common/utilities.h" 13 14 bool atof_clamp(const char *str, float *value) 15 { 16 bool success = pp::numeric_lex_float(str, value); 17 if (!success) 18 *value = std::numeric_limits<float>::max(); 19 return success; 20 } 21 22 bool atoi_clamp(const char *str, int *value) 23 { 24 bool success = pp::numeric_lex_int(str, value); 25 if (!success) 26 *value = std::numeric_limits<int>::max(); 27 return success; 28 } 29 30 namespace sh 31 { 32 33 GLenum GLVariableType(const TType &type) 34 { 35 if (type.getBasicType() == EbtFloat) 36 { 37 if (type.isScalar()) 38 { 39 return GL_FLOAT; 40 } 41 else if (type.isVector()) 42 { 43 switch (type.getNominalSize()) 44 { 45 case 2: return GL_FLOAT_VEC2; 46 case 3: return GL_FLOAT_VEC3; 47 case 4: return GL_FLOAT_VEC4; 48 default: UNREACHABLE(); 49 } 50 } 51 else if (type.isMatrix()) 52 { 53 switch (type.getCols()) 54 { 55 case 2: 56 switch (type.getRows()) 57 { 58 case 2: return GL_FLOAT_MAT2; 59 case 3: return GL_FLOAT_MAT2x3; 60 case 4: return GL_FLOAT_MAT2x4; 61 default: UNREACHABLE(); 62 } 63 64 case 3: 65 switch (type.getRows()) 66 { 67 case 2: return GL_FLOAT_MAT3x2; 68 case 3: return GL_FLOAT_MAT3; 69 case 4: return GL_FLOAT_MAT3x4; 70 default: UNREACHABLE(); 71 } 72 73 case 4: 74 switch (type.getRows()) 75 { 76 case 2: return GL_FLOAT_MAT4x2; 77 case 3: return GL_FLOAT_MAT4x3; 78 case 4: return GL_FLOAT_MAT4; 79 default: UNREACHABLE(); 80 } 81 82 default: UNREACHABLE(); 83 } 84 } 85 else UNREACHABLE(); 86 } 87 else if (type.getBasicType() == EbtInt) 88 { 89 if (type.isScalar()) 90 { 91 return GL_INT; 92 } 93 else if (type.isVector()) 94 { 95 switch (type.getNominalSize()) 96 { 97 case 2: return GL_INT_VEC2; 98 case 3: return GL_INT_VEC3; 99 case 4: return GL_INT_VEC4; 100 default: UNREACHABLE(); 101 } 102 } 103 else UNREACHABLE(); 104 } 105 else if (type.getBasicType() == EbtUInt) 106 { 107 if (type.isScalar()) 108 { 109 return GL_UNSIGNED_INT; 110 } 111 else if (type.isVector()) 112 { 113 switch (type.getNominalSize()) 114 { 115 case 2: return GL_UNSIGNED_INT_VEC2; 116 case 3: return GL_UNSIGNED_INT_VEC3; 117 case 4: return GL_UNSIGNED_INT_VEC4; 118 default: UNREACHABLE(); 119 } 120 } 121 else UNREACHABLE(); 122 } 123 else if (type.getBasicType() == EbtBool) 124 { 125 if (type.isScalar()) 126 { 127 return GL_BOOL; 128 } 129 else if (type.isVector()) 130 { 131 switch (type.getNominalSize()) 132 { 133 case 2: return GL_BOOL_VEC2; 134 case 3: return GL_BOOL_VEC3; 135 case 4: return GL_BOOL_VEC4; 136 default: UNREACHABLE(); 137 } 138 } 139 else UNREACHABLE(); 140 } 141 142 switch (type.getBasicType()) 143 { 144 case EbtSampler2D: return GL_SAMPLER_2D; 145 case EbtSampler3D: return GL_SAMPLER_3D; 146 case EbtSamplerCube: return GL_SAMPLER_CUBE; 147 case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES; 148 case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB; 149 case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY; 150 case EbtISampler2D: return GL_INT_SAMPLER_2D; 151 case EbtISampler3D: return GL_INT_SAMPLER_3D; 152 case EbtISamplerCube: return GL_INT_SAMPLER_CUBE; 153 case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY; 154 case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D; 155 case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D; 156 case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE; 157 case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; 158 case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW; 159 case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW; 160 case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW; 161 default: UNREACHABLE(); 162 } 163 164 return GL_NONE; 165 } 166 167 GLenum GLVariablePrecision(const TType &type) 168 { 169 if (type.getBasicType() == EbtFloat) 170 { 171 switch (type.getPrecision()) 172 { 173 case EbpHigh: 174 return GL_HIGH_FLOAT; 175 case EbpMedium: 176 return GL_MEDIUM_FLOAT; 177 case EbpLow: 178 return GL_LOW_FLOAT; 179 case EbpUndefined: 180 // Should be defined as the default precision by the parser 181 default: 182 UNREACHABLE(); 183 } 184 } 185 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt) 186 { 187 switch (type.getPrecision()) 188 { 189 case EbpHigh: 190 return GL_HIGH_INT; 191 case EbpMedium: 192 return GL_MEDIUM_INT; 193 case EbpLow: 194 return GL_LOW_INT; 195 case EbpUndefined: 196 // Should be defined as the default precision by the parser 197 default: 198 UNREACHABLE(); 199 } 200 } 201 202 // Other types (boolean, sampler) don't have a precision 203 return GL_NONE; 204 } 205 206 TString ArrayString(const TType &type) 207 { 208 if (!type.isArray()) 209 { 210 return ""; 211 } 212 213 return "[" + str(type.getArraySize()) + "]"; 214 } 215 216 bool IsVaryingOut(TQualifier qualifier) 217 { 218 switch (qualifier) 219 { 220 case EvqVaryingOut: 221 case EvqInvariantVaryingOut: 222 case EvqSmoothOut: 223 case EvqFlatOut: 224 case EvqCentroidOut: 225 case EvqVertexOut: 226 return true; 227 228 default: break; 229 } 230 231 return false; 232 } 233 234 bool IsVaryingIn(TQualifier qualifier) 235 { 236 switch (qualifier) 237 { 238 case EvqVaryingIn: 239 case EvqInvariantVaryingIn: 240 case EvqSmoothIn: 241 case EvqFlatIn: 242 case EvqCentroidIn: 243 case EvqFragmentIn: 244 return true; 245 246 default: break; 247 } 248 249 return false; 250 } 251 252 bool IsVarying(TQualifier qualifier) 253 { 254 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier); 255 } 256 257 InterpolationType GetInterpolationType(TQualifier qualifier) 258 { 259 switch (qualifier) 260 { 261 case EvqFlatIn: 262 case EvqFlatOut: 263 return INTERPOLATION_FLAT; 264 265 case EvqSmoothIn: 266 case EvqSmoothOut: 267 case EvqVertexOut: 268 case EvqFragmentIn: 269 case EvqVaryingIn: 270 case EvqVaryingOut: 271 case EvqInvariantVaryingIn: 272 case EvqInvariantVaryingOut: 273 return INTERPOLATION_SMOOTH; 274 275 case EvqCentroidIn: 276 case EvqCentroidOut: 277 return INTERPOLATION_CENTROID; 278 279 default: UNREACHABLE(); 280 return INTERPOLATION_SMOOTH; 281 } 282 } 283 284 template <typename VarT> 285 void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output) 286 { 287 const TStructure *structure = type.getStruct(); 288 289 VarT variable; 290 variable.name = name.c_str(); 291 variable.arraySize = static_cast<unsigned int>(type.getArraySize()); 292 293 if (!structure) 294 { 295 variable.type = GLVariableType(type); 296 variable.precision = GLVariablePrecision(type); 297 } 298 else 299 { 300 // Note: this enum value is not exposed outside ANGLE 301 variable.type = GL_STRUCT_ANGLEX; 302 variable.structName = structure->name().c_str(); 303 304 const TFieldList &fields = structure->fields(); 305 306 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) 307 { 308 TField *field = fields[fieldIndex]; 309 traverse(*field->type(), field->name(), &variable.fields); 310 } 311 } 312 313 visitVariable(&variable); 314 315 ASSERT(output); 316 output->push_back(variable); 317 } 318 319 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *); 320 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *); 321 template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *); 322 323 } 324