util.cpp (29670B)
1 // 2 // Copyright 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 "common/utilities.h" 12 #include "compiler/preprocessor/numeric_lex.h" 13 #include "compiler/translator/ImmutableStringBuilder.h" 14 #include "compiler/translator/SymbolTable.h" 15 16 bool atoi_clamp(const char *str, unsigned int *value) 17 { 18 bool success = angle::pp::numeric_lex_int(str, value); 19 if (!success) 20 *value = std::numeric_limits<unsigned int>::max(); 21 return success; 22 } 23 24 namespace sh 25 { 26 27 namespace 28 { 29 // [primarySize-1][secondarySize-1] is the GL type with a basic type of float. 30 constexpr GLenum kFloatGLType[4][4] = { 31 // float1xS only makes sense for S == 1 32 { 33 GL_FLOAT, 34 GL_NONE, 35 GL_NONE, 36 GL_NONE, 37 }, 38 // float2xS is vec2 for S == 1, and mat2xS o.w. 39 { 40 GL_FLOAT_VEC2, 41 GL_FLOAT_MAT2, 42 GL_FLOAT_MAT2x3, 43 GL_FLOAT_MAT2x4, 44 }, 45 // float3xS is vec3 for S == 1, and mat3xS o.w. 46 { 47 GL_FLOAT_VEC3, 48 GL_FLOAT_MAT3x2, 49 GL_FLOAT_MAT3, 50 GL_FLOAT_MAT3x4, 51 }, 52 // float4xS is vec4 for S == 1, and mat4xS o.w. 53 { 54 GL_FLOAT_VEC4, 55 GL_FLOAT_MAT4x2, 56 GL_FLOAT_MAT4x3, 57 GL_FLOAT_MAT4, 58 }, 59 }; 60 // [primarySize-1] is the GL type with a basic type of int. 61 constexpr GLenum kIntGLType[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4}; 62 // [primarySize-1] is the GL type with a basic type of uint. 63 constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, 64 GL_UNSIGNED_INT_VEC4}; 65 // [primarySize-1] is the GL type with a basic type of bool. 66 constexpr GLenum kBoolGLType[4] = {GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4}; 67 68 bool IsInterpolationIn(TQualifier qualifier) 69 { 70 switch (qualifier) 71 { 72 case EvqSmoothIn: 73 case EvqFlatIn: 74 case EvqNoPerspectiveIn: 75 case EvqCentroidIn: 76 case EvqSampleIn: 77 return true; 78 default: 79 return false; 80 } 81 } 82 83 bool IsInterpolationOut(TQualifier qualifier) 84 { 85 switch (qualifier) 86 { 87 case EvqSmoothOut: 88 case EvqFlatOut: 89 case EvqNoPerspectiveOut: 90 case EvqCentroidOut: 91 case EvqSampleOut: 92 return true; 93 default: 94 return false; 95 } 96 } 97 } // anonymous namespace 98 99 float NumericLexFloat32OutOfRangeToInfinity(const std::string &str) 100 { 101 // Parses a decimal string using scientific notation into a floating point number. 102 // Out-of-range values are converted to infinity. Values that are too small to be 103 // represented are converted to zero. 104 105 // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not 106 // matter. 107 unsigned int decimalMantissa = 0; 108 size_t i = 0; 109 bool decimalPointSeen = false; 110 bool nonZeroSeenInMantissa = false; 111 112 // The exponent offset reflects the position of the decimal point. 113 int exponentOffset = -1; 114 115 // This is just a counter for how many decimal digits are written to decimalMantissa. 116 int mantissaDecimalDigits = 0; 117 118 while (i < str.length()) 119 { 120 const char c = str[i]; 121 if (c == 'e' || c == 'E') 122 { 123 break; 124 } 125 if (c == '.') 126 { 127 decimalPointSeen = true; 128 ++i; 129 continue; 130 } 131 132 unsigned int digit = static_cast<unsigned int>(c - '0'); 133 ASSERT(digit < 10u); 134 if (digit != 0u) 135 { 136 nonZeroSeenInMantissa = true; 137 } 138 if (nonZeroSeenInMantissa) 139 { 140 // Add bits to the mantissa until space runs out in 32-bit int. This should be 141 // enough precision to make the resulting binary mantissa accurate to 1 ULP. 142 if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u) 143 { 144 decimalMantissa = decimalMantissa * 10u + digit; 145 ++mantissaDecimalDigits; 146 } 147 if (!decimalPointSeen) 148 { 149 ++exponentOffset; 150 } 151 } 152 else if (decimalPointSeen) 153 { 154 --exponentOffset; 155 } 156 ++i; 157 } 158 if (decimalMantissa == 0) 159 { 160 return 0.0f; 161 } 162 int exponent = 0; 163 if (i < str.length()) 164 { 165 ASSERT(str[i] == 'e' || str[i] == 'E'); 166 ++i; 167 bool exponentOutOfRange = false; 168 bool negativeExponent = false; 169 if (str[i] == '-') 170 { 171 negativeExponent = true; 172 ++i; 173 } 174 else if (str[i] == '+') 175 { 176 ++i; 177 } 178 while (i < str.length()) 179 { 180 const char c = str[i]; 181 unsigned int digit = static_cast<unsigned int>(c - '0'); 182 ASSERT(digit < 10u); 183 if (exponent <= (std::numeric_limits<int>::max() - 9) / 10) 184 { 185 exponent = exponent * 10 + digit; 186 } 187 else 188 { 189 exponentOutOfRange = true; 190 } 191 ++i; 192 } 193 if (negativeExponent) 194 { 195 exponent = -exponent; 196 } 197 if (exponentOutOfRange) 198 { 199 if (negativeExponent) 200 { 201 return 0.0f; 202 } 203 else 204 { 205 return std::numeric_limits<float>::infinity(); 206 } 207 } 208 } 209 // Do the calculation in 64-bit to avoid overflow. 210 long long exponentLong = 211 static_cast<long long>(exponent) + static_cast<long long>(exponentOffset); 212 if (exponentLong > std::numeric_limits<float>::max_exponent10) 213 { 214 return std::numeric_limits<float>::infinity(); 215 } 216 else if (exponentLong < std::numeric_limits<float>::min_exponent10) 217 { 218 return 0.0f; 219 } 220 // The exponent is in range, so we need to actually evaluate the float. 221 exponent = static_cast<int>(exponentLong); 222 double value = decimalMantissa; 223 224 // Calculate the exponent offset to normalize the mantissa. 225 int normalizationExponentOffset = 1 - mantissaDecimalDigits; 226 // Apply the exponent. 227 value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset)); 228 if (value > static_cast<double>(std::numeric_limits<float>::max())) 229 { 230 return std::numeric_limits<float>::infinity(); 231 } 232 if (value < static_cast<double>(std::numeric_limits<float>::min())) 233 { 234 return 0.0f; 235 } 236 return static_cast<float>(value); 237 } 238 239 bool strtof_clamp(const std::string &str, float *value) 240 { 241 // Custom float parsing that can handle the following corner cases: 242 // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting 243 // number inside the float range. 244 // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting 245 // number inside the float range. 246 // 3. The value is out-of-range and should be evaluated as infinity. 247 // 4. The value is too small and should be evaluated as zero. 248 // See ESSL 3.00.6 section 4.1.4 for the relevant specification. 249 *value = NumericLexFloat32OutOfRangeToInfinity(str); 250 return !gl::isInf(*value); 251 } 252 253 GLenum GLVariableType(const TType &type) 254 { 255 switch (type.getBasicType()) 256 { 257 case EbtFloat: 258 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4); 259 ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4); 260 261 return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1]; 262 263 case EbtInt: 264 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4); 265 ASSERT(type.getSecondarySize() == 1); 266 267 return kIntGLType[type.getNominalSize() - 1]; 268 269 case EbtUInt: 270 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4); 271 ASSERT(type.getSecondarySize() == 1); 272 273 return kUIntGLType[type.getNominalSize() - 1]; 274 275 case EbtBool: 276 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4); 277 ASSERT(type.getSecondarySize() == 1); 278 279 return kBoolGLType[type.getNominalSize() - 1]; 280 281 case EbtSampler2D: 282 return GL_SAMPLER_2D; 283 case EbtSampler3D: 284 return GL_SAMPLER_3D; 285 case EbtSamplerCube: 286 return GL_SAMPLER_CUBE; 287 case EbtSamplerExternalOES: 288 return GL_SAMPLER_EXTERNAL_OES; 289 case EbtSamplerExternal2DY2YEXT: 290 return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT; 291 case EbtSampler2DRect: 292 return GL_SAMPLER_2D_RECT_ANGLE; 293 case EbtSampler2DArray: 294 return GL_SAMPLER_2D_ARRAY; 295 case EbtSampler2DMS: 296 return GL_SAMPLER_2D_MULTISAMPLE; 297 case EbtSampler2DMSArray: 298 return GL_SAMPLER_2D_MULTISAMPLE_ARRAY; 299 case EbtSamplerCubeArray: 300 return GL_SAMPLER_CUBE_MAP_ARRAY; 301 case EbtSamplerBuffer: 302 return GL_SAMPLER_BUFFER; 303 case EbtISampler2D: 304 return GL_INT_SAMPLER_2D; 305 case EbtISampler3D: 306 return GL_INT_SAMPLER_3D; 307 case EbtISamplerCube: 308 return GL_INT_SAMPLER_CUBE; 309 case EbtISampler2DArray: 310 return GL_INT_SAMPLER_2D_ARRAY; 311 case EbtISampler2DMS: 312 return GL_INT_SAMPLER_2D_MULTISAMPLE; 313 case EbtISampler2DMSArray: 314 return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY; 315 case EbtISamplerCubeArray: 316 return GL_INT_SAMPLER_CUBE_MAP_ARRAY; 317 case EbtISamplerBuffer: 318 return GL_INT_SAMPLER_BUFFER; 319 case EbtUSampler2D: 320 return GL_UNSIGNED_INT_SAMPLER_2D; 321 case EbtUSampler3D: 322 return GL_UNSIGNED_INT_SAMPLER_3D; 323 case EbtUSamplerCube: 324 return GL_UNSIGNED_INT_SAMPLER_CUBE; 325 case EbtUSampler2DArray: 326 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; 327 case EbtUSampler2DMS: 328 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE; 329 case EbtUSampler2DMSArray: 330 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY; 331 case EbtUSamplerCubeArray: 332 return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY; 333 case EbtUSamplerBuffer: 334 return GL_UNSIGNED_INT_SAMPLER_BUFFER; 335 case EbtSampler2DShadow: 336 return GL_SAMPLER_2D_SHADOW; 337 case EbtSamplerCubeShadow: 338 return GL_SAMPLER_CUBE_SHADOW; 339 case EbtSampler2DArrayShadow: 340 return GL_SAMPLER_2D_ARRAY_SHADOW; 341 case EbtSamplerCubeArrayShadow: 342 return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW; 343 case EbtImage2D: 344 return GL_IMAGE_2D; 345 case EbtIImage2D: 346 return GL_INT_IMAGE_2D; 347 case EbtUImage2D: 348 return GL_UNSIGNED_INT_IMAGE_2D; 349 case EbtImage2DArray: 350 return GL_IMAGE_2D_ARRAY; 351 case EbtIImage2DArray: 352 return GL_INT_IMAGE_2D_ARRAY; 353 case EbtUImage2DArray: 354 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY; 355 case EbtImage3D: 356 return GL_IMAGE_3D; 357 case EbtIImage3D: 358 return GL_INT_IMAGE_3D; 359 case EbtUImage3D: 360 return GL_UNSIGNED_INT_IMAGE_3D; 361 case EbtImageCube: 362 return GL_IMAGE_CUBE; 363 case EbtIImageCube: 364 return GL_INT_IMAGE_CUBE; 365 case EbtUImageCube: 366 return GL_UNSIGNED_INT_IMAGE_CUBE; 367 case EbtImageCubeArray: 368 return GL_IMAGE_CUBE_MAP_ARRAY; 369 case EbtIImageCubeArray: 370 return GL_INT_IMAGE_CUBE_MAP_ARRAY; 371 case EbtUImageCubeArray: 372 return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY; 373 case EbtImageBuffer: 374 return GL_IMAGE_BUFFER; 375 case EbtIImageBuffer: 376 return GL_INT_IMAGE_BUFFER; 377 case EbtUImageBuffer: 378 return GL_UNSIGNED_INT_IMAGE_BUFFER; 379 case EbtAtomicCounter: 380 return GL_UNSIGNED_INT_ATOMIC_COUNTER; 381 case EbtSamplerVideoWEBGL: 382 return GL_SAMPLER_VIDEO_IMAGE_WEBGL; 383 case EbtPixelLocalANGLE: 384 case EbtIPixelLocalANGLE: 385 case EbtUPixelLocalANGLE: 386 // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images 387 // before anyone calls into here. 388 [[fallthrough]]; 389 default: 390 UNREACHABLE(); 391 return GL_NONE; 392 } 393 } 394 395 GLenum GLVariablePrecision(const TType &type) 396 { 397 if (type.getBasicType() == EbtFloat) 398 { 399 switch (type.getPrecision()) 400 { 401 case EbpHigh: 402 return GL_HIGH_FLOAT; 403 case EbpMedium: 404 return GL_MEDIUM_FLOAT; 405 case EbpLow: 406 return GL_LOW_FLOAT; 407 case EbpUndefined: 408 // Desktop specs do not use precision 409 return GL_NONE; 410 default: 411 UNREACHABLE(); 412 } 413 } 414 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt) 415 { 416 switch (type.getPrecision()) 417 { 418 case EbpHigh: 419 return GL_HIGH_INT; 420 case EbpMedium: 421 return GL_MEDIUM_INT; 422 case EbpLow: 423 return GL_LOW_INT; 424 case EbpUndefined: 425 // Desktop specs do not use precision 426 return GL_NONE; 427 default: 428 UNREACHABLE(); 429 } 430 } 431 432 // Other types (boolean, sampler) don't have a precision 433 return GL_NONE; 434 } 435 436 ImmutableString ArrayString(const TType &type) 437 { 438 if (!type.isArray()) 439 return ImmutableString(""); 440 441 const TSpan<const unsigned int> &arraySizes = type.getArraySizes(); 442 constexpr const size_t kMaxDecimalDigitsPerSize = 10u; 443 ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u)); 444 for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend(); 445 ++arraySizeIter) 446 { 447 arrayString << "["; 448 if (*arraySizeIter > 0) 449 { 450 arrayString.appendDecimal(*arraySizeIter); 451 } 452 arrayString << "]"; 453 } 454 return arrayString; 455 } 456 457 ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap) 458 { 459 if (type.getBasicType() == EbtStruct) 460 return HashName(type.getStruct(), hashFunction, nameMap); 461 else 462 return ImmutableString(type.getBuiltInTypeNameString()); 463 } 464 465 bool IsVaryingOut(TQualifier qualifier) 466 { 467 switch (qualifier) 468 { 469 case EvqVaryingOut: 470 case EvqSmoothOut: 471 case EvqFlatOut: 472 case EvqNoPerspectiveOut: 473 case EvqCentroidOut: 474 case EvqVertexOut: 475 case EvqGeometryOut: 476 case EvqTessControlOut: 477 case EvqTessEvaluationOut: 478 case EvqSampleOut: 479 case EvqPatchOut: 480 return true; 481 482 default: 483 break; 484 } 485 486 return false; 487 } 488 489 bool IsVaryingIn(TQualifier qualifier) 490 { 491 switch (qualifier) 492 { 493 case EvqVaryingIn: 494 case EvqSmoothIn: 495 case EvqFlatIn: 496 case EvqNoPerspectiveIn: 497 case EvqCentroidIn: 498 case EvqFragmentIn: 499 case EvqGeometryIn: 500 case EvqTessControlIn: 501 case EvqTessEvaluationIn: 502 case EvqSampleIn: 503 case EvqPatchIn: 504 return true; 505 506 default: 507 break; 508 } 509 510 return false; 511 } 512 513 bool IsVarying(TQualifier qualifier) 514 { 515 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier); 516 } 517 518 bool IsMatrixGLType(GLenum type) 519 { 520 switch (type) 521 { 522 case GL_FLOAT_MAT2: 523 case GL_FLOAT_MAT3: 524 case GL_FLOAT_MAT4: 525 case GL_FLOAT_MAT2x3: 526 case GL_FLOAT_MAT2x4: 527 case GL_FLOAT_MAT3x2: 528 case GL_FLOAT_MAT3x4: 529 case GL_FLOAT_MAT4x2: 530 case GL_FLOAT_MAT4x3: 531 return true; 532 default: 533 return false; 534 } 535 } 536 537 bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier) 538 { 539 return (qualifier == EvqGeometryIn) || 540 ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier)); 541 } 542 543 bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier) 544 { 545 return qualifier == EvqTessControlIn || 546 ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationIn(qualifier)); 547 } 548 549 bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier) 550 { 551 return qualifier == EvqTessControlOut || 552 ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationOut(qualifier)); 553 } 554 555 bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier) 556 { 557 return qualifier == EvqTessEvaluationIn || 558 ((shaderType == GL_TESS_EVALUATION_SHADER) && IsInterpolationIn(qualifier)); 559 } 560 561 InterpolationType GetInterpolationType(TQualifier qualifier) 562 { 563 switch (qualifier) 564 { 565 case EvqFlatIn: 566 case EvqFlatOut: 567 // The auxiliary storage qualifier patch is not used for interpolation 568 // it is a compile-time error to use interpolation qualifiers with patch 569 case EvqPatchIn: 570 case EvqPatchOut: 571 return INTERPOLATION_FLAT; 572 573 case EvqNoPerspectiveIn: 574 case EvqNoPerspectiveOut: 575 return INTERPOLATION_NOPERSPECTIVE; 576 577 case EvqSmoothIn: 578 case EvqSmoothOut: 579 case EvqVertexOut: 580 case EvqFragmentIn: 581 case EvqVaryingIn: 582 case EvqVaryingOut: 583 case EvqGeometryIn: 584 case EvqGeometryOut: 585 case EvqTessControlIn: 586 case EvqTessControlOut: 587 case EvqTessEvaluationIn: 588 case EvqTessEvaluationOut: 589 return INTERPOLATION_SMOOTH; 590 591 case EvqCentroidIn: 592 case EvqCentroidOut: 593 return INTERPOLATION_CENTROID; 594 595 case EvqSampleIn: 596 case EvqSampleOut: 597 return INTERPOLATION_SAMPLE; 598 default: 599 UNREACHABLE(); 600 return INTERPOLATION_SMOOTH; 601 } 602 } 603 604 // a field may not have qualifer without in or out. 605 InterpolationType GetFieldInterpolationType(TQualifier qualifier) 606 { 607 switch (qualifier) 608 { 609 case EvqFlat: 610 return INTERPOLATION_FLAT; 611 case EvqNoPerspective: 612 return INTERPOLATION_NOPERSPECTIVE; 613 case EvqSmooth: 614 return INTERPOLATION_SMOOTH; 615 case EvqCentroid: 616 return INTERPOLATION_CENTROID; 617 default: 618 return GetInterpolationType(qualifier); 619 } 620 } 621 622 TType GetShaderVariableBasicType(const sh::ShaderVariable &var) 623 { 624 switch (var.type) 625 { 626 case GL_BOOL: 627 return TType(EbtBool); 628 case GL_BOOL_VEC2: 629 return TType(EbtBool, 2); 630 case GL_BOOL_VEC3: 631 return TType(EbtBool, 3); 632 case GL_BOOL_VEC4: 633 return TType(EbtBool, 4); 634 case GL_FLOAT: 635 return TType(EbtFloat); 636 case GL_FLOAT_VEC2: 637 return TType(EbtFloat, 2); 638 case GL_FLOAT_VEC3: 639 return TType(EbtFloat, 3); 640 case GL_FLOAT_VEC4: 641 return TType(EbtFloat, 4); 642 case GL_FLOAT_MAT2: 643 return TType(EbtFloat, 2, 2); 644 case GL_FLOAT_MAT3: 645 return TType(EbtFloat, 3, 3); 646 case GL_FLOAT_MAT4: 647 return TType(EbtFloat, 4, 4); 648 case GL_FLOAT_MAT2x3: 649 return TType(EbtFloat, 2, 3); 650 case GL_FLOAT_MAT2x4: 651 return TType(EbtFloat, 2, 4); 652 case GL_FLOAT_MAT3x2: 653 return TType(EbtFloat, 3, 2); 654 case GL_FLOAT_MAT3x4: 655 return TType(EbtFloat, 3, 4); 656 case GL_FLOAT_MAT4x2: 657 return TType(EbtFloat, 4, 2); 658 case GL_FLOAT_MAT4x3: 659 return TType(EbtFloat, 4, 3); 660 case GL_INT: 661 return TType(EbtInt); 662 case GL_INT_VEC2: 663 return TType(EbtInt, 2); 664 case GL_INT_VEC3: 665 return TType(EbtInt, 3); 666 case GL_INT_VEC4: 667 return TType(EbtInt, 4); 668 case GL_UNSIGNED_INT: 669 return TType(EbtUInt); 670 case GL_UNSIGNED_INT_VEC2: 671 return TType(EbtUInt, 2); 672 case GL_UNSIGNED_INT_VEC3: 673 return TType(EbtUInt, 3); 674 case GL_UNSIGNED_INT_VEC4: 675 return TType(EbtUInt, 4); 676 default: 677 UNREACHABLE(); 678 return TType(); 679 } 680 } 681 682 void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable) 683 { 684 TIntermDeclaration *declaration = new TIntermDeclaration(); 685 declaration->appendDeclarator(new TIntermSymbol(variable)); 686 687 TIntermSequence *globalSequence = root->getSequence(); 688 globalSequence->insert(globalSequence->begin(), declaration); 689 } 690 691 // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier 692 bool CanBeInvariantESSL1(TQualifier qualifier) 693 { 694 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) || 695 IsBuiltinOutputVariable(qualifier) || 696 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing); 697 } 698 699 // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier 700 // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier 701 bool CanBeInvariantESSL3OrGreater(TQualifier qualifier) 702 { 703 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut || 704 IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut; 705 } 706 707 bool IsBuiltinOutputVariable(TQualifier qualifier) 708 { 709 switch (qualifier) 710 { 711 case EvqPosition: 712 case EvqPointSize: 713 case EvqFragDepth: 714 case EvqFragColor: 715 case EvqSecondaryFragColorEXT: 716 case EvqFragData: 717 case EvqSecondaryFragDataEXT: 718 case EvqClipDistance: 719 case EvqCullDistance: 720 case EvqLastFragData: 721 case EvqSampleMask: 722 return true; 723 default: 724 break; 725 } 726 return false; 727 } 728 729 bool IsBuiltinFragmentInputVariable(TQualifier qualifier) 730 { 731 switch (qualifier) 732 { 733 case EvqFragCoord: 734 case EvqPointCoord: 735 case EvqFrontFacing: 736 case EvqHelperInvocation: 737 case EvqLastFragData: 738 return true; 739 default: 740 break; 741 } 742 return false; 743 } 744 745 bool IsShaderOutput(TQualifier qualifier) 746 { 747 return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier); 748 } 749 750 bool IsFragmentOutput(TQualifier qualifier) 751 { 752 switch (qualifier) 753 { 754 case EvqFragmentOut: 755 case EvqFragmentInOut: 756 return true; 757 default: 758 return false; 759 } 760 } 761 762 bool IsOutputESSL(ShShaderOutput output) 763 { 764 return output == SH_ESSL_OUTPUT; 765 } 766 767 bool IsOutputGLSL(ShShaderOutput output) 768 { 769 switch (output) 770 { 771 case SH_GLSL_130_OUTPUT: 772 case SH_GLSL_140_OUTPUT: 773 case SH_GLSL_150_CORE_OUTPUT: 774 case SH_GLSL_330_CORE_OUTPUT: 775 case SH_GLSL_400_CORE_OUTPUT: 776 case SH_GLSL_410_CORE_OUTPUT: 777 case SH_GLSL_420_CORE_OUTPUT: 778 case SH_GLSL_430_CORE_OUTPUT: 779 case SH_GLSL_440_CORE_OUTPUT: 780 case SH_GLSL_450_CORE_OUTPUT: 781 case SH_GLSL_COMPATIBILITY_OUTPUT: 782 return true; 783 default: 784 break; 785 } 786 return false; 787 } 788 bool IsOutputHLSL(ShShaderOutput output) 789 { 790 switch (output) 791 { 792 case SH_HLSL_3_0_OUTPUT: 793 case SH_HLSL_4_1_OUTPUT: 794 case SH_HLSL_4_0_FL9_3_OUTPUT: 795 return true; 796 default: 797 break; 798 } 799 return false; 800 } 801 bool IsOutputVulkan(ShShaderOutput output) 802 { 803 return output == SH_SPIRV_VULKAN_OUTPUT; 804 } 805 bool IsOutputMetal(ShShaderOutput output) 806 { 807 return output == SH_SPIRV_METAL_OUTPUT; 808 } 809 bool IsOutputMetalDirect(ShShaderOutput output) 810 { 811 return output == SH_MSL_METAL_OUTPUT; 812 } 813 814 bool IsInShaderStorageBlock(TIntermTyped *node) 815 { 816 TIntermSwizzle *swizzleNode = node->getAsSwizzleNode(); 817 if (swizzleNode) 818 { 819 return IsInShaderStorageBlock(swizzleNode->getOperand()); 820 } 821 822 TIntermBinary *binaryNode = node->getAsBinaryNode(); 823 if (binaryNode) 824 { 825 switch (binaryNode->getOp()) 826 { 827 case EOpIndexDirectInterfaceBlock: 828 case EOpIndexIndirect: 829 case EOpIndexDirect: 830 case EOpIndexDirectStruct: 831 return IsInShaderStorageBlock(binaryNode->getLeft()); 832 default: 833 return false; 834 } 835 } 836 837 const TType &type = node->getType(); 838 return type.getQualifier() == EvqBuffer; 839 } 840 841 GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq) 842 { 843 switch (iifq) 844 { 845 case EiifRGBA32F: 846 return GL_RGBA32F; 847 case EiifRGBA16F: 848 return GL_RGBA16F; 849 case EiifR32F: 850 return GL_R32F; 851 case EiifRGBA32UI: 852 return GL_RGBA32UI; 853 case EiifRGBA16UI: 854 return GL_RGBA16UI; 855 case EiifRGBA8UI: 856 return GL_RGBA8UI; 857 case EiifR32UI: 858 return GL_R32UI; 859 case EiifRGBA32I: 860 return GL_RGBA32I; 861 case EiifRGBA16I: 862 return GL_RGBA16I; 863 case EiifRGBA8I: 864 return GL_RGBA8I; 865 case EiifR32I: 866 return GL_R32I; 867 case EiifRGBA8: 868 return GL_RGBA8; 869 case EiifRGBA8_SNORM: 870 return GL_RGBA8_SNORM; 871 default: 872 return GL_NONE; 873 } 874 } 875 876 bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion) 877 { 878 return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec)); 879 } 880 881 ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2) 882 { 883 if (t1 == t2) 884 return ImplicitTypeConversion::Same; 885 886 switch (t1) 887 { 888 case EbtInt: 889 switch (t2) 890 { 891 case EbtInt: 892 UNREACHABLE(); 893 break; 894 case EbtUInt: 895 return ImplicitTypeConversion::Invalid; 896 case EbtFloat: 897 return ImplicitTypeConversion::Left; 898 default: 899 return ImplicitTypeConversion::Invalid; 900 } 901 break; 902 case EbtUInt: 903 switch (t2) 904 { 905 case EbtInt: 906 return ImplicitTypeConversion::Invalid; 907 case EbtUInt: 908 UNREACHABLE(); 909 break; 910 case EbtFloat: 911 return ImplicitTypeConversion::Left; 912 default: 913 return ImplicitTypeConversion::Invalid; 914 } 915 break; 916 case EbtFloat: 917 switch (t2) 918 { 919 case EbtInt: 920 case EbtUInt: 921 return ImplicitTypeConversion::Right; 922 case EbtFloat: 923 UNREACHABLE(); 924 break; 925 default: 926 return ImplicitTypeConversion::Invalid; 927 } 928 break; 929 default: 930 return ImplicitTypeConversion::Invalid; 931 } 932 return ImplicitTypeConversion::Invalid; 933 } 934 935 bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op) 936 { 937 switch (conversion) 938 { 939 case sh::ImplicitTypeConversion::Same: 940 return true; 941 case sh::ImplicitTypeConversion::Left: 942 switch (op) 943 { 944 case EOpEqual: 945 case EOpNotEqual: 946 case EOpLessThan: 947 case EOpGreaterThan: 948 case EOpLessThanEqual: 949 case EOpGreaterThanEqual: 950 case EOpAdd: 951 case EOpSub: 952 case EOpMul: 953 case EOpDiv: 954 return true; 955 default: 956 break; 957 } 958 break; 959 case sh::ImplicitTypeConversion::Right: 960 switch (op) 961 { 962 case EOpAssign: 963 case EOpInitialize: 964 case EOpEqual: 965 case EOpNotEqual: 966 case EOpLessThan: 967 case EOpGreaterThan: 968 case EOpLessThanEqual: 969 case EOpGreaterThanEqual: 970 case EOpAdd: 971 case EOpSub: 972 case EOpMul: 973 case EOpDiv: 974 case EOpAddAssign: 975 case EOpSubAssign: 976 case EOpMulAssign: 977 case EOpDivAssign: 978 return true; 979 default: 980 break; 981 } 982 break; 983 case sh::ImplicitTypeConversion::Invalid: 984 break; 985 } 986 return false; 987 } 988 989 bool IsPrecisionApplicableToType(TBasicType type) 990 { 991 switch (type) 992 { 993 case EbtInt: 994 case EbtUInt: 995 case EbtFloat: 996 // TODO: find all types where precision is applicable; for example samplers. 997 // http://anglebug.com/6132 998 return true; 999 default: 1000 return false; 1001 } 1002 } 1003 1004 bool IsRedeclarableBuiltIn(const ImmutableString &name) 1005 { 1006 return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" || 1007 name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize"; 1008 } 1009 1010 size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName) 1011 { 1012 for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex) 1013 { 1014 if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0) 1015 { 1016 return fieldIndex; 1017 } 1018 } 1019 UNREACHABLE(); 1020 return 0; 1021 } 1022 1023 } // namespace sh