mathutil.h (43593B)
1 // 2 // Copyright 2002 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 // mathutil.h: Math and bit manipulation functions. 8 9 #ifndef COMMON_MATHUTIL_H_ 10 #define COMMON_MATHUTIL_H_ 11 12 #include <math.h> 13 #include <stdint.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <algorithm> 17 #include <limits> 18 19 #include <anglebase/numerics/safe_math.h> 20 21 #include "common/debug.h" 22 #include "common/platform.h" 23 24 namespace angle 25 { 26 using base::CheckedNumeric; 27 using base::IsValueInRangeForNumericType; 28 } // namespace angle 29 30 namespace gl 31 { 32 33 const unsigned int Float32One = 0x3F800000; 34 const unsigned short Float16One = 0x3C00; 35 36 template <typename T> 37 inline constexpr bool isPow2(T x) 38 { 39 static_assert(std::is_integral<T>::value, "isPow2 must be called on an integer type."); 40 return (x & (x - 1)) == 0 && (x != 0); 41 } 42 43 template <typename T> 44 inline int log2(T x) 45 { 46 static_assert(std::is_integral<T>::value, "log2 must be called on an integer type."); 47 int r = 0; 48 while ((x >> r) > 1) 49 r++; 50 return r; 51 } 52 53 inline unsigned int ceilPow2(unsigned int x) 54 { 55 if (x != 0) 56 x--; 57 x |= x >> 1; 58 x |= x >> 2; 59 x |= x >> 4; 60 x |= x >> 8; 61 x |= x >> 16; 62 x++; 63 64 return x; 65 } 66 67 template <typename DestT, typename SrcT> 68 inline DestT clampCast(SrcT value) 69 { 70 // For floating-point types with denormalization, min returns the minimum positive normalized 71 // value. To find the value that has no values less than it, use numeric_limits::lowest. 72 constexpr const long double destLo = 73 static_cast<long double>(std::numeric_limits<DestT>::lowest()); 74 constexpr const long double destHi = 75 static_cast<long double>(std::numeric_limits<DestT>::max()); 76 constexpr const long double srcLo = 77 static_cast<long double>(std::numeric_limits<SrcT>::lowest()); 78 constexpr long double srcHi = static_cast<long double>(std::numeric_limits<SrcT>::max()); 79 80 if (destHi < srcHi) 81 { 82 DestT destMax = std::numeric_limits<DestT>::max(); 83 if (value >= static_cast<SrcT>(destMax)) 84 { 85 return destMax; 86 } 87 } 88 89 if (destLo > srcLo) 90 { 91 DestT destLow = std::numeric_limits<DestT>::lowest(); 92 if (value <= static_cast<SrcT>(destLow)) 93 { 94 return destLow; 95 } 96 } 97 98 return static_cast<DestT>(value); 99 } 100 101 // Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max 102 // value is casted to the source type. 103 template <> 104 inline unsigned int clampCast(bool value) 105 { 106 return static_cast<unsigned int>(value); 107 } 108 109 template <> 110 inline int clampCast(bool value) 111 { 112 return static_cast<int>(value); 113 } 114 115 template <typename T, typename MIN, typename MAX> 116 inline T clamp(T x, MIN min, MAX max) 117 { 118 // Since NaNs fail all comparison tests, a NaN value will default to min 119 return x > min ? (x > max ? max : x) : min; 120 } 121 122 template <typename T> 123 T clampForBitCount(T value, size_t bitCount) 124 { 125 static_assert(std::numeric_limits<T>::is_integer, "T must be an integer."); 126 127 if (bitCount == 0) 128 { 129 constexpr T kZero = 0; 130 return kZero; 131 } 132 ASSERT(bitCount <= sizeof(T) * 8); 133 134 constexpr bool kIsSigned = std::numeric_limits<T>::is_signed; 135 ASSERT((bitCount > 1) || !kIsSigned); 136 137 T min = 0; 138 T max = 0; 139 if (bitCount == sizeof(T) * 8) 140 { 141 min = std::numeric_limits<T>::min(); 142 max = std::numeric_limits<T>::max(); 143 } 144 else 145 { 146 constexpr T kOne = 1; 147 min = (kIsSigned) ? -1 * (kOne << (bitCount - 1)) : 0; 148 max = (kIsSigned) ? (kOne << (bitCount - 1)) - 1 : (kOne << bitCount) - 1; 149 } 150 151 return gl::clamp(value, min, max); 152 } 153 154 inline float clamp01(float x) 155 { 156 return clamp(x, 0.0f, 1.0f); 157 } 158 159 template <const int n> 160 inline unsigned int unorm(float x) 161 { 162 const unsigned int max = 0xFFFFFFFF >> (32 - n); 163 164 if (x > 1) 165 { 166 return max; 167 } 168 else if (x < 0) 169 { 170 return 0; 171 } 172 else 173 { 174 return (unsigned int)(max * x + 0.5f); 175 } 176 } 177 178 inline bool supportsSSE2() 179 { 180 #if defined(ANGLE_USE_SSE) 181 static bool checked = false; 182 static bool supports = false; 183 184 if (checked) 185 { 186 return supports; 187 } 188 189 # if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) 190 { 191 int info[4]; 192 __cpuid(info, 0); 193 194 if (info[0] >= 1) 195 { 196 __cpuid(info, 1); 197 198 supports = (info[3] >> 26) & 1; 199 } 200 } 201 # endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) 202 checked = true; 203 return supports; 204 #else // defined(ANGLE_USE_SSE) 205 return false; 206 #endif 207 } 208 209 template <typename destType, typename sourceType> 210 destType bitCast(const sourceType &source) 211 { 212 size_t copySize = std::min(sizeof(destType), sizeof(sourceType)); 213 destType output; 214 memcpy(&output, &source, copySize); 215 return output; 216 } 217 218 // https://stackoverflow.com/a/37581284 219 template <typename T> 220 static constexpr double normalize(T value) 221 { 222 return value < 0 ? -static_cast<double>(value) / std::numeric_limits<T>::min() 223 : static_cast<double>(value) / std::numeric_limits<T>::max(); 224 } 225 226 inline unsigned short float32ToFloat16(float fp32) 227 { 228 unsigned int fp32i = bitCast<unsigned int>(fp32); 229 unsigned int sign = (fp32i & 0x80000000) >> 16; 230 unsigned int abs = fp32i & 0x7FFFFFFF; 231 232 if (abs > 0x7F800000) 233 { // NaN 234 return 0x7FFF; 235 } 236 else if (abs > 0x47FFEFFF) 237 { // Infinity 238 return static_cast<uint16_t>(sign | 0x7C00); 239 } 240 else if (abs < 0x38800000) // Denormal 241 { 242 unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000; 243 int e = 113 - (abs >> 23); 244 245 if (e < 24) 246 { 247 abs = mantissa >> e; 248 } 249 else 250 { 251 abs = 0; 252 } 253 254 return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13); 255 } 256 else 257 { 258 return static_cast<unsigned short>( 259 sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13); 260 } 261 } 262 263 float float16ToFloat32(unsigned short h); 264 265 unsigned int convertRGBFloatsTo999E5(float red, float green, float blue); 266 void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue); 267 268 inline unsigned short float32ToFloat11(float fp32) 269 { 270 const unsigned int float32MantissaMask = 0x7FFFFF; 271 const unsigned int float32ExponentMask = 0x7F800000; 272 const unsigned int float32SignMask = 0x80000000; 273 const unsigned int float32ValueMask = ~float32SignMask; 274 const unsigned int float32ExponentFirstBit = 23; 275 const unsigned int float32ExponentBias = 127; 276 277 const unsigned short float11Max = 0x7BF; 278 const unsigned short float11MantissaMask = 0x3F; 279 const unsigned short float11ExponentMask = 0x7C0; 280 const unsigned short float11BitMask = 0x7FF; 281 const unsigned int float11ExponentBias = 14; 282 283 const unsigned int float32Maxfloat11 = 0x477E0000; 284 const unsigned int float32MinNormfloat11 = 0x38800000; 285 const unsigned int float32MinDenormfloat11 = 0x35000080; 286 287 const unsigned int float32Bits = bitCast<unsigned int>(fp32); 288 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; 289 290 unsigned int float32Val = float32Bits & float32ValueMask; 291 292 if ((float32Val & float32ExponentMask) == float32ExponentMask) 293 { 294 // INF or NAN 295 if ((float32Val & float32MantissaMask) != 0) 296 { 297 return float11ExponentMask | 298 (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & 299 float11MantissaMask); 300 } 301 else if (float32Sign) 302 { 303 // -INF is clamped to 0 since float11 is positive only 304 return 0; 305 } 306 else 307 { 308 return float11ExponentMask; 309 } 310 } 311 else if (float32Sign) 312 { 313 // float11 is positive only, so clamp to zero 314 return 0; 315 } 316 else if (float32Val > float32Maxfloat11) 317 { 318 // The number is too large to be represented as a float11, set to max 319 return float11Max; 320 } 321 else if (float32Val < float32MinDenormfloat11) 322 { 323 // The number is too small to be represented as a denormalized float11, set to 0 324 return 0; 325 } 326 else 327 { 328 if (float32Val < float32MinNormfloat11) 329 { 330 // The number is too small to be represented as a normalized float11 331 // Convert it to a denormalized value. 332 const unsigned int shift = (float32ExponentBias - float11ExponentBias) - 333 (float32Val >> float32ExponentFirstBit); 334 ASSERT(shift < 32); 335 float32Val = 336 ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift; 337 } 338 else 339 { 340 // Rebias the exponent to represent the value as a normalized float11 341 float32Val += 0xC8000000; 342 } 343 344 return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask; 345 } 346 } 347 348 inline unsigned short float32ToFloat10(float fp32) 349 { 350 const unsigned int float32MantissaMask = 0x7FFFFF; 351 const unsigned int float32ExponentMask = 0x7F800000; 352 const unsigned int float32SignMask = 0x80000000; 353 const unsigned int float32ValueMask = ~float32SignMask; 354 const unsigned int float32ExponentFirstBit = 23; 355 const unsigned int float32ExponentBias = 127; 356 357 const unsigned short float10Max = 0x3DF; 358 const unsigned short float10MantissaMask = 0x1F; 359 const unsigned short float10ExponentMask = 0x3E0; 360 const unsigned short float10BitMask = 0x3FF; 361 const unsigned int float10ExponentBias = 14; 362 363 const unsigned int float32Maxfloat10 = 0x477C0000; 364 const unsigned int float32MinNormfloat10 = 0x38800000; 365 const unsigned int float32MinDenormfloat10 = 0x35800040; 366 367 const unsigned int float32Bits = bitCast<unsigned int>(fp32); 368 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; 369 370 unsigned int float32Val = float32Bits & float32ValueMask; 371 372 if ((float32Val & float32ExponentMask) == float32ExponentMask) 373 { 374 // INF or NAN 375 if ((float32Val & float32MantissaMask) != 0) 376 { 377 return float10ExponentMask | 378 (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & 379 float10MantissaMask); 380 } 381 else if (float32Sign) 382 { 383 // -INF is clamped to 0 since float10 is positive only 384 return 0; 385 } 386 else 387 { 388 return float10ExponentMask; 389 } 390 } 391 else if (float32Sign) 392 { 393 // float10 is positive only, so clamp to zero 394 return 0; 395 } 396 else if (float32Val > float32Maxfloat10) 397 { 398 // The number is too large to be represented as a float10, set to max 399 return float10Max; 400 } 401 else if (float32Val < float32MinDenormfloat10) 402 { 403 // The number is too small to be represented as a denormalized float10, set to 0 404 return 0; 405 } 406 else 407 { 408 if (float32Val < float32MinNormfloat10) 409 { 410 // The number is too small to be represented as a normalized float10 411 // Convert it to a denormalized value. 412 const unsigned int shift = (float32ExponentBias - float10ExponentBias) - 413 (float32Val >> float32ExponentFirstBit); 414 ASSERT(shift < 32); 415 float32Val = 416 ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift; 417 } 418 else 419 { 420 // Rebias the exponent to represent the value as a normalized float10 421 float32Val += 0xC8000000; 422 } 423 424 return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask; 425 } 426 } 427 428 inline float float11ToFloat32(unsigned short fp11) 429 { 430 unsigned short exponent = (fp11 >> 6) & 0x1F; 431 unsigned short mantissa = fp11 & 0x3F; 432 433 if (exponent == 0x1F) 434 { 435 // INF or NAN 436 return bitCast<float>(0x7f800000 | (mantissa << 17)); 437 } 438 else 439 { 440 if (exponent != 0) 441 { 442 // normalized 443 } 444 else if (mantissa != 0) 445 { 446 // The value is denormalized 447 exponent = 1; 448 449 do 450 { 451 exponent--; 452 mantissa <<= 1; 453 } while ((mantissa & 0x40) == 0); 454 455 mantissa = mantissa & 0x3F; 456 } 457 else // The value is zero 458 { 459 exponent = static_cast<unsigned short>(-112); 460 } 461 462 return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17)); 463 } 464 } 465 466 inline float float10ToFloat32(unsigned short fp10) 467 { 468 unsigned short exponent = (fp10 >> 5) & 0x1F; 469 unsigned short mantissa = fp10 & 0x1F; 470 471 if (exponent == 0x1F) 472 { 473 // INF or NAN 474 return bitCast<float>(0x7f800000 | (mantissa << 17)); 475 } 476 else 477 { 478 if (exponent != 0) 479 { 480 // normalized 481 } 482 else if (mantissa != 0) 483 { 484 // The value is denormalized 485 exponent = 1; 486 487 do 488 { 489 exponent--; 490 mantissa <<= 1; 491 } while ((mantissa & 0x20) == 0); 492 493 mantissa = mantissa & 0x1F; 494 } 495 else // The value is zero 496 { 497 exponent = static_cast<unsigned short>(-112); 498 } 499 500 return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18)); 501 } 502 } 503 504 // Converts to and from float and 16.16 fixed point format. 505 inline float ConvertFixedToFloat(int32_t fixedInput) 506 { 507 return static_cast<float>(fixedInput) / 65536.0f; 508 } 509 510 inline uint32_t ConvertFloatToFixed(float floatInput) 511 { 512 static constexpr uint32_t kHighest = 32767 * 65536 + 65535; 513 static constexpr uint32_t kLowest = static_cast<uint32_t>(-32768 * 65536 + 65535); 514 515 if (floatInput > 32767.65535) 516 { 517 return kHighest; 518 } 519 else if (floatInput < -32768.65535) 520 { 521 return kLowest; 522 } 523 else 524 { 525 return static_cast<uint32_t>(floatInput * 65536); 526 } 527 } 528 529 template <typename T> 530 inline float normalizedToFloat(T input) 531 { 532 static_assert(std::numeric_limits<T>::is_integer, "T must be an integer."); 533 534 if (sizeof(T) > 2) 535 { 536 // float has only a 23 bit mantissa, so we need to do the calculation in double precision 537 constexpr double inverseMax = 1.0 / std::numeric_limits<T>::max(); 538 return static_cast<float>(input * inverseMax); 539 } 540 else 541 { 542 constexpr float inverseMax = 1.0f / std::numeric_limits<T>::max(); 543 return input * inverseMax; 544 } 545 } 546 547 template <unsigned int inputBitCount, typename T> 548 inline float normalizedToFloat(T input) 549 { 550 static_assert(std::numeric_limits<T>::is_integer, "T must be an integer."); 551 static_assert(inputBitCount < (sizeof(T) * 8), "T must have more bits than inputBitCount."); 552 ASSERT((input & ~((1 << inputBitCount) - 1)) == 0); 553 554 if (inputBitCount > 23) 555 { 556 // float has only a 23 bit mantissa, so we need to do the calculation in double precision 557 constexpr double inverseMax = 1.0 / ((1 << inputBitCount) - 1); 558 return static_cast<float>(input * inverseMax); 559 } 560 else 561 { 562 constexpr float inverseMax = 1.0f / ((1 << inputBitCount) - 1); 563 return input * inverseMax; 564 } 565 } 566 567 template <typename T> 568 inline T floatToNormalized(float input) 569 { 570 if constexpr (sizeof(T) > 2) 571 { 572 // float has only a 23 bit mantissa, so we need to do the calculation in double precision 573 return static_cast<T>(std::numeric_limits<T>::max() * static_cast<double>(input) + 0.5); 574 } 575 else 576 { 577 return static_cast<T>(std::numeric_limits<T>::max() * input + 0.5f); 578 } 579 } 580 581 template <unsigned int outputBitCount, typename T> 582 inline T floatToNormalized(float input) 583 { 584 static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount."); 585 586 if (outputBitCount > 23) 587 { 588 // float has only a 23 bit mantissa, so we need to do the calculation in double precision 589 return static_cast<T>(((1 << outputBitCount) - 1) * static_cast<double>(input) + 0.5); 590 } 591 else 592 { 593 return static_cast<T>(((1 << outputBitCount) - 1) * input + 0.5f); 594 } 595 } 596 597 template <unsigned int inputBitCount, unsigned int inputBitStart, typename T> 598 inline T getShiftedData(T input) 599 { 600 static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8), 601 "T must have at least as many bits as inputBitCount + inputBitStart."); 602 const T mask = (1 << inputBitCount) - 1; 603 return (input >> inputBitStart) & mask; 604 } 605 606 template <unsigned int inputBitCount, unsigned int inputBitStart, typename T> 607 inline T shiftData(T input) 608 { 609 static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8), 610 "T must have at least as many bits as inputBitCount + inputBitStart."); 611 const T mask = (1 << inputBitCount) - 1; 612 return (input & mask) << inputBitStart; 613 } 614 615 inline unsigned int CountLeadingZeros(uint32_t x) 616 { 617 // Use binary search to find the amount of leading zeros. 618 unsigned int zeros = 32u; 619 uint32_t y; 620 621 y = x >> 16u; 622 if (y != 0) 623 { 624 zeros = zeros - 16u; 625 x = y; 626 } 627 y = x >> 8u; 628 if (y != 0) 629 { 630 zeros = zeros - 8u; 631 x = y; 632 } 633 y = x >> 4u; 634 if (y != 0) 635 { 636 zeros = zeros - 4u; 637 x = y; 638 } 639 y = x >> 2u; 640 if (y != 0) 641 { 642 zeros = zeros - 2u; 643 x = y; 644 } 645 y = x >> 1u; 646 if (y != 0) 647 { 648 return zeros - 2u; 649 } 650 return zeros - x; 651 } 652 653 inline unsigned char average(unsigned char a, unsigned char b) 654 { 655 return ((a ^ b) >> 1) + (a & b); 656 } 657 658 inline signed char average(signed char a, signed char b) 659 { 660 return ((short)a + (short)b) / 2; 661 } 662 663 inline unsigned short average(unsigned short a, unsigned short b) 664 { 665 return ((a ^ b) >> 1) + (a & b); 666 } 667 668 inline signed short average(signed short a, signed short b) 669 { 670 return ((int)a + (int)b) / 2; 671 } 672 673 inline unsigned int average(unsigned int a, unsigned int b) 674 { 675 return ((a ^ b) >> 1) + (a & b); 676 } 677 678 inline int average(int a, int b) 679 { 680 long long average = (static_cast<long long>(a) + static_cast<long long>(b)) / 2LL; 681 return static_cast<int>(average); 682 } 683 684 inline float average(float a, float b) 685 { 686 return (a + b) * 0.5f; 687 } 688 689 inline unsigned short averageHalfFloat(unsigned short a, unsigned short b) 690 { 691 return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f); 692 } 693 694 inline unsigned int averageFloat11(unsigned int a, unsigned int b) 695 { 696 return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) + 697 float11ToFloat32(static_cast<unsigned short>(b))) * 698 0.5f); 699 } 700 701 inline unsigned int averageFloat10(unsigned int a, unsigned int b) 702 { 703 return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) + 704 float10ToFloat32(static_cast<unsigned short>(b))) * 705 0.5f); 706 } 707 708 template <typename T> 709 class Range 710 { 711 public: 712 Range() {} 713 Range(T lo, T hi) : mLow(lo), mHigh(hi) {} 714 715 T length() const { return (empty() ? 0 : (mHigh - mLow)); } 716 717 bool intersects(Range<T> other) 718 { 719 if (mLow <= other.mLow) 720 { 721 return other.mLow < mHigh; 722 } 723 else 724 { 725 return mLow < other.mHigh; 726 } 727 } 728 729 // Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6. 730 void extend(T value) 731 { 732 mLow = value < mLow ? value : mLow; 733 mHigh = value >= mHigh ? (value + 1) : mHigh; 734 } 735 736 bool empty() const { return mHigh <= mLow; } 737 738 bool contains(T value) const { return value >= mLow && value < mHigh; } 739 740 class Iterator final 741 { 742 public: 743 Iterator(T value) : mCurrent(value) {} 744 745 Iterator &operator++() 746 { 747 mCurrent++; 748 return *this; 749 } 750 bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; } 751 bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; } 752 T operator*() const { return mCurrent; } 753 754 private: 755 T mCurrent; 756 }; 757 758 Iterator begin() const { return Iterator(mLow); } 759 760 Iterator end() const { return Iterator(mHigh); } 761 762 T low() const { return mLow; } 763 T high() const { return mHigh; } 764 765 void invalidate() 766 { 767 mLow = std::numeric_limits<T>::max(); 768 mHigh = std::numeric_limits<T>::min(); 769 } 770 771 private: 772 T mLow; 773 T mHigh; 774 }; 775 776 typedef Range<int> RangeI; 777 typedef Range<unsigned int> RangeUI; 778 779 struct IndexRange 780 { 781 struct Undefined 782 {}; 783 IndexRange(Undefined) {} 784 IndexRange() : IndexRange(0, 0, 0) {} 785 IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_) 786 : start(start_), end(end_), vertexIndexCount(vertexIndexCount_) 787 { 788 ASSERT(start <= end); 789 } 790 791 // Number of vertices in the range. 792 size_t vertexCount() const { return (end - start) + 1; } 793 794 // Inclusive range of indices that are not primitive restart 795 size_t start; 796 size_t end; 797 798 // Number of non-primitive restart indices 799 size_t vertexIndexCount; 800 }; 801 802 // Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a 803 // floating-point value. As in GLSL ldexp() built-in. 804 inline float Ldexp(float x, int exp) 805 { 806 if (exp > 128) 807 { 808 return std::numeric_limits<float>::infinity(); 809 } 810 if (exp < -126) 811 { 812 return 0.0f; 813 } 814 double result = static_cast<double>(x) * std::pow(2.0, static_cast<double>(exp)); 815 return static_cast<float>(result); 816 } 817 818 // First, both normalized floating-point values are converted into 16-bit integer values. 819 // Then, the results are packed into the returned 32-bit unsigned integer. 820 // The first float value will be written to the least significant bits of the output; 821 // the last float value will be written to the most significant bits. 822 // The conversion of each value to fixed point is done as follows : 823 // packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0) 824 inline uint32_t packSnorm2x16(float f1, float f2) 825 { 826 int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f)); 827 int16_t mostSignificantBits = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f)); 828 return static_cast<uint32_t>(mostSignificantBits) << 16 | 829 (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF); 830 } 831 832 // First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, 833 // each component is converted to a normalized floating-point value to generate the returned two 834 // float values. The first float value will be extracted from the least significant bits of the 835 // input; the last float value will be extracted from the most-significant bits. The conversion for 836 // unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f / 837 // 32767.0, -1, +1) 838 inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2) 839 { 840 int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF); 841 int16_t mostSignificantBits = static_cast<int16_t>(u >> 16); 842 *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f); 843 *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f); 844 } 845 846 // First, both normalized floating-point values are converted into 16-bit integer values. 847 // Then, the results are packed into the returned 32-bit unsigned integer. 848 // The first float value will be written to the least significant bits of the output; 849 // the last float value will be written to the most significant bits. 850 // The conversion of each value to fixed point is done as follows: 851 // packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0) 852 inline uint32_t packUnorm2x16(float f1, float f2) 853 { 854 uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f)); 855 uint16_t mostSignificantBits = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f)); 856 return static_cast<uint32_t>(mostSignificantBits) << 16 | 857 static_cast<uint32_t>(leastSignificantBits); 858 } 859 860 // First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, 861 // each component is converted to a normalized floating-point value to generate the returned two 862 // float values. The first float value will be extracted from the least significant bits of the 863 // input; the last float value will be extracted from the most-significant bits. The conversion for 864 // unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0 865 inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2) 866 { 867 uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF); 868 uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16); 869 *f1 = static_cast<float>(leastSignificantBits) / 65535.0f; 870 *f2 = static_cast<float>(mostSignificantBits) / 65535.0f; 871 } 872 873 // Helper functions intended to be used only here. 874 namespace priv 875 { 876 877 inline uint8_t ToPackedUnorm8(float f) 878 { 879 return static_cast<uint8_t>(roundf(clamp(f, 0.0f, 1.0f) * 255.0f)); 880 } 881 882 inline int8_t ToPackedSnorm8(float f) 883 { 884 return static_cast<int8_t>(roundf(clamp(f, -1.0f, 1.0f) * 127.0f)); 885 } 886 887 } // namespace priv 888 889 // Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works 890 // similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the 891 // unsigned integer starting from the least significant bits. 892 inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4) 893 { 894 uint8_t bits[4]; 895 bits[0] = priv::ToPackedUnorm8(f1); 896 bits[1] = priv::ToPackedUnorm8(f2); 897 bits[2] = priv::ToPackedUnorm8(f3); 898 bits[3] = priv::ToPackedUnorm8(f4); 899 uint32_t result = 0u; 900 for (int i = 0; i < 4; ++i) 901 { 902 int shift = i * 8; 903 result |= (static_cast<uint32_t>(bits[i]) << shift); 904 } 905 return result; 906 } 907 908 // Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f. 909 // Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant 910 // bits. 911 inline void UnpackUnorm4x8(uint32_t u, float *f) 912 { 913 for (int i = 0; i < 4; ++i) 914 { 915 int shift = i * 8; 916 uint8_t bits = static_cast<uint8_t>((u >> shift) & 0xFF); 917 f[i] = static_cast<float>(bits) / 255.0f; 918 } 919 } 920 921 // Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats 922 // are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least 923 // significant bits. 924 inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4) 925 { 926 int8_t bits[4]; 927 bits[0] = priv::ToPackedSnorm8(f1); 928 bits[1] = priv::ToPackedSnorm8(f2); 929 bits[2] = priv::ToPackedSnorm8(f3); 930 bits[3] = priv::ToPackedSnorm8(f4); 931 uint32_t result = 0u; 932 for (int i = 0; i < 4; ++i) 933 { 934 int shift = i * 8; 935 result |= ((static_cast<uint32_t>(bits[i]) & 0xFF) << shift); 936 } 937 return result; 938 } 939 940 // Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f. 941 // Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant 942 // bits, and clamped to the range -1.0 to 1.0. 943 inline void UnpackSnorm4x8(uint32_t u, float *f) 944 { 945 for (int i = 0; i < 4; ++i) 946 { 947 int shift = i * 8; 948 int8_t bits = static_cast<int8_t>((u >> shift) & 0xFF); 949 f[i] = clamp(static_cast<float>(bits) / 127.0f, -1.0f, 1.0f); 950 } 951 } 952 953 // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit 954 // floating-point representation found in the OpenGL ES Specification, and then packing these 955 // two 16-bit integers into a 32-bit unsigned integer. 956 // f1: The 16 least-significant bits of the result; 957 // f2: The 16 most-significant bits. 958 inline uint32_t packHalf2x16(float f1, float f2) 959 { 960 uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1)); 961 uint16_t mostSignificantBits = static_cast<uint16_t>(float32ToFloat16(f2)); 962 return static_cast<uint32_t>(mostSignificantBits) << 16 | 963 static_cast<uint32_t>(leastSignificantBits); 964 } 965 966 // Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of 967 // 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL 968 // ES Specification, and converting them to 32-bit floating-point values. The first float value is 969 // obtained from the 16 least-significant bits of u; the second component is obtained from the 16 970 // most-significant bits of u. 971 inline void unpackHalf2x16(uint32_t u, float *f1, float *f2) 972 { 973 uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF); 974 uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16); 975 976 *f1 = float16ToFloat32(leastSignificantBits); 977 *f2 = float16ToFloat32(mostSignificantBits); 978 } 979 980 inline uint8_t sRGBToLinear(uint8_t srgbValue) 981 { 982 float value = srgbValue / 255.0f; 983 if (value <= 0.04045f) 984 { 985 value = value / 12.92f; 986 } 987 else 988 { 989 value = std::pow((value + 0.055f) / 1.055f, 2.4f); 990 } 991 return static_cast<uint8_t>(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f)); 992 } 993 994 inline uint8_t linearToSRGB(uint8_t linearValue) 995 { 996 float value = linearValue / 255.0f; 997 if (value <= 0.0f) 998 { 999 value = 0.0f; 1000 } 1001 else if (value < 0.0031308f) 1002 { 1003 value = value * 12.92f; 1004 } 1005 else if (value < 1.0f) 1006 { 1007 value = std::pow(value, 0.41666f) * 1.055f - 0.055f; 1008 } 1009 else 1010 { 1011 value = 1.0f; 1012 } 1013 return static_cast<uint8_t>(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f)); 1014 } 1015 1016 // Reverse the order of the bits. 1017 inline uint32_t BitfieldReverse(uint32_t value) 1018 { 1019 // TODO(oetuaho@nvidia.com): Optimize this if needed. There don't seem to be compiler intrinsics 1020 // for this, and right now it's not used in performance-critical paths. 1021 uint32_t result = 0u; 1022 for (size_t j = 0u; j < 32u; ++j) 1023 { 1024 result |= (((value >> j) & 1u) << (31u - j)); 1025 } 1026 return result; 1027 } 1028 1029 // Count the 1 bits. 1030 #if defined(_MSC_VER) && !defined(__clang__) 1031 # if defined(_M_IX86) || defined(_M_X64) 1032 namespace priv 1033 { 1034 // Check POPCNT instruction support and cache the result. 1035 // https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64#remarks 1036 static const bool kHasPopcnt = [] { 1037 int info[4]; 1038 __cpuid(&info[0], 1); 1039 return static_cast<bool>(info[2] & 0x800000); 1040 }(); 1041 } // namespace priv 1042 1043 // Polyfills for x86/x64 CPUs without POPCNT. 1044 // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel 1045 inline int BitCountPolyfill(uint32_t bits) 1046 { 1047 bits = bits - ((bits >> 1) & 0x55555555); 1048 bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); 1049 bits = ((bits + (bits >> 4) & 0x0F0F0F0F) * 0x01010101) >> 24; 1050 return static_cast<int>(bits); 1051 } 1052 1053 inline int BitCountPolyfill(uint64_t bits) 1054 { 1055 bits = bits - ((bits >> 1) & 0x5555555555555555ull); 1056 bits = (bits & 0x3333333333333333ull) + ((bits >> 2) & 0x3333333333333333ull); 1057 bits = ((bits + (bits >> 4) & 0x0F0F0F0F0F0F0F0Full) * 0x0101010101010101ull) >> 56; 1058 return static_cast<int>(bits); 1059 } 1060 1061 inline int BitCount(uint32_t bits) 1062 { 1063 if (priv::kHasPopcnt) 1064 { 1065 return static_cast<int>(__popcnt(bits)); 1066 } 1067 return BitCountPolyfill(bits); 1068 } 1069 1070 inline int BitCount(uint64_t bits) 1071 { 1072 if (priv::kHasPopcnt) 1073 { 1074 # if defined(_M_X64) 1075 return static_cast<int>(__popcnt64(bits)); 1076 # else // x86 1077 return static_cast<int>(__popcnt(static_cast<uint32_t>(bits >> 32)) + 1078 __popcnt(static_cast<uint32_t>(bits))); 1079 # endif // defined(_M_X64) 1080 } 1081 return BitCountPolyfill(bits); 1082 } 1083 1084 # elif defined(_M_ARM) || defined(_M_ARM64) 1085 1086 // MSVC's _CountOneBits* intrinsics are not defined for ARM64, moreover they do not use dedicated 1087 // NEON instructions. 1088 1089 inline int BitCount(uint32_t bits) 1090 { 1091 // cast bits to 8x8 datatype and use VCNT on it 1092 const uint8x8_t vsum = vcnt_u8(vcreate_u8(static_cast<uint64_t>(bits))); 1093 1094 // pairwise sums: 8x8 -> 16x4 -> 32x2 1095 return static_cast<int>(vget_lane_u32(vpaddl_u16(vpaddl_u8(vsum)), 0)); 1096 } 1097 1098 inline int BitCount(uint64_t bits) 1099 { 1100 // cast bits to 8x8 datatype and use VCNT on it 1101 const uint8x8_t vsum = vcnt_u8(vcreate_u8(bits)); 1102 1103 // pairwise sums: 8x8 -> 16x4 -> 32x2 -> 64x1 1104 return static_cast<int>(vget_lane_u64(vpaddl_u32(vpaddl_u16(vpaddl_u8(vsum))), 0)); 1105 } 1106 # endif // defined(_M_IX86) || defined(_M_X64) 1107 #endif // defined(_MSC_VER) && !defined(__clang__) 1108 1109 #if defined(ANGLE_PLATFORM_POSIX) || defined(__clang__) 1110 inline int BitCount(uint32_t bits) 1111 { 1112 return __builtin_popcount(bits); 1113 } 1114 1115 inline int BitCount(uint64_t bits) 1116 { 1117 return __builtin_popcountll(bits); 1118 } 1119 #endif // defined(ANGLE_PLATFORM_POSIX) || defined(__clang__) 1120 1121 inline int BitCount(uint8_t bits) 1122 { 1123 return BitCount(static_cast<uint32_t>(bits)); 1124 } 1125 1126 inline int BitCount(uint16_t bits) 1127 { 1128 return BitCount(static_cast<uint32_t>(bits)); 1129 } 1130 1131 #if defined(ANGLE_PLATFORM_WINDOWS) 1132 // Return the index of the least significant bit set. Indexing is such that bit 0 is the least 1133 // significant bit. Implemented for different bit widths on different platforms. 1134 inline unsigned long ScanForward(uint32_t bits) 1135 { 1136 ASSERT(bits != 0u); 1137 unsigned long firstBitIndex = 0ul; 1138 unsigned char ret = _BitScanForward(&firstBitIndex, bits); 1139 ASSERT(ret != 0u); 1140 return firstBitIndex; 1141 } 1142 1143 inline unsigned long ScanForward(uint64_t bits) 1144 { 1145 ASSERT(bits != 0u); 1146 unsigned long firstBitIndex = 0ul; 1147 # if defined(ANGLE_IS_64_BIT_CPU) 1148 unsigned char ret = _BitScanForward64(&firstBitIndex, bits); 1149 # else 1150 unsigned char ret; 1151 if (static_cast<uint32_t>(bits) == 0) 1152 { 1153 ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits >> 32)); 1154 firstBitIndex += 32ul; 1155 } 1156 else 1157 { 1158 ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits)); 1159 } 1160 # endif // defined(ANGLE_IS_64_BIT_CPU) 1161 ASSERT(ret != 0u); 1162 return firstBitIndex; 1163 } 1164 1165 // Return the index of the most significant bit set. Indexing is such that bit 0 is the least 1166 // significant bit. 1167 inline unsigned long ScanReverse(uint32_t bits) 1168 { 1169 ASSERT(bits != 0u); 1170 unsigned long lastBitIndex = 0ul; 1171 unsigned char ret = _BitScanReverse(&lastBitIndex, bits); 1172 ASSERT(ret != 0u); 1173 return lastBitIndex; 1174 } 1175 1176 inline unsigned long ScanReverse(uint64_t bits) 1177 { 1178 ASSERT(bits != 0u); 1179 unsigned long lastBitIndex = 0ul; 1180 # if defined(ANGLE_IS_64_BIT_CPU) 1181 unsigned char ret = _BitScanReverse64(&lastBitIndex, bits); 1182 # else 1183 unsigned char ret; 1184 if (static_cast<uint32_t>(bits >> 32) == 0) 1185 { 1186 ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits)); 1187 } 1188 else 1189 { 1190 ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits >> 32)); 1191 lastBitIndex += 32ul; 1192 } 1193 # endif // defined(ANGLE_IS_64_BIT_CPU) 1194 ASSERT(ret != 0u); 1195 return lastBitIndex; 1196 } 1197 #endif // defined(ANGLE_PLATFORM_WINDOWS) 1198 1199 #if defined(ANGLE_PLATFORM_POSIX) 1200 inline unsigned long ScanForward(uint32_t bits) 1201 { 1202 ASSERT(bits != 0u); 1203 return static_cast<unsigned long>(__builtin_ctz(bits)); 1204 } 1205 1206 inline unsigned long ScanForward(uint64_t bits) 1207 { 1208 ASSERT(bits != 0u); 1209 # if defined(ANGLE_IS_64_BIT_CPU) 1210 return static_cast<unsigned long>(__builtin_ctzll(bits)); 1211 # else 1212 return static_cast<unsigned long>(static_cast<uint32_t>(bits) == 0 1213 ? __builtin_ctz(static_cast<uint32_t>(bits >> 32)) + 32 1214 : __builtin_ctz(static_cast<uint32_t>(bits))); 1215 # endif // defined(ANGLE_IS_64_BIT_CPU) 1216 } 1217 1218 inline unsigned long ScanReverse(uint32_t bits) 1219 { 1220 ASSERT(bits != 0u); 1221 return static_cast<unsigned long>(sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(bits)); 1222 } 1223 1224 inline unsigned long ScanReverse(uint64_t bits) 1225 { 1226 ASSERT(bits != 0u); 1227 # if defined(ANGLE_IS_64_BIT_CPU) 1228 return static_cast<unsigned long>(sizeof(uint64_t) * CHAR_BIT - 1 - __builtin_clzll(bits)); 1229 # else 1230 if (static_cast<uint32_t>(bits >> 32) == 0) 1231 { 1232 return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits)); 1233 } 1234 else 1235 { 1236 return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits >> 32)) + 1237 32; 1238 } 1239 # endif // defined(ANGLE_IS_64_BIT_CPU) 1240 } 1241 #endif // defined(ANGLE_PLATFORM_POSIX) 1242 1243 inline unsigned long ScanForward(uint8_t bits) 1244 { 1245 return ScanForward(static_cast<uint32_t>(bits)); 1246 } 1247 1248 inline unsigned long ScanForward(uint16_t bits) 1249 { 1250 return ScanForward(static_cast<uint32_t>(bits)); 1251 } 1252 1253 inline unsigned long ScanReverse(uint8_t bits) 1254 { 1255 return ScanReverse(static_cast<uint32_t>(bits)); 1256 } 1257 1258 inline unsigned long ScanReverse(uint16_t bits) 1259 { 1260 return ScanReverse(static_cast<uint32_t>(bits)); 1261 } 1262 1263 // Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL. 1264 template <typename T> 1265 int FindLSB(T bits) 1266 { 1267 static_assert(std::is_integral<T>::value, "must be integral type."); 1268 if (bits == 0u) 1269 { 1270 return -1; 1271 } 1272 else 1273 { 1274 return static_cast<int>(ScanForward(bits)); 1275 } 1276 } 1277 1278 // Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL. 1279 template <typename T> 1280 int FindMSB(T bits) 1281 { 1282 static_assert(std::is_integral<T>::value, "must be integral type."); 1283 if (bits == 0u) 1284 { 1285 return -1; 1286 } 1287 else 1288 { 1289 return static_cast<int>(ScanReverse(bits)); 1290 } 1291 } 1292 1293 // Returns whether the argument is Not a Number. 1294 // IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - 1295 // non-zero. 1296 inline bool isNaN(float f) 1297 { 1298 // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u 1299 // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu 1300 return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && 1301 (bitCast<uint32_t>(f) & 0x7fffffu); 1302 } 1303 1304 // Returns whether the argument is infinity. 1305 // IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - 1306 // zero. 1307 inline bool isInf(float f) 1308 { 1309 // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u 1310 // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu 1311 return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && 1312 !(bitCast<uint32_t>(f) & 0x7fffffu); 1313 } 1314 1315 namespace priv 1316 { 1317 template <unsigned int N, unsigned int R> 1318 struct iSquareRoot 1319 { 1320 static constexpr unsigned int solve() 1321 { 1322 return (R * R > N) 1323 ? 0 1324 : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value)); 1325 } 1326 enum Result 1327 { 1328 value = iSquareRoot::solve() 1329 }; 1330 }; 1331 1332 template <unsigned int N> 1333 struct iSquareRoot<N, N> 1334 { 1335 enum result 1336 { 1337 value = N 1338 }; 1339 }; 1340 1341 } // namespace priv 1342 1343 template <unsigned int N> 1344 constexpr unsigned int iSquareRoot() 1345 { 1346 return priv::iSquareRoot<N, 1>::value; 1347 } 1348 1349 // Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow. 1350 // 1351 // Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow 1352 // behavior is undefined. 1353 1354 template <typename T> 1355 inline T WrappingSum(T lhs, T rhs) 1356 { 1357 uint32_t lhsUnsigned = static_cast<uint32_t>(lhs); 1358 uint32_t rhsUnsigned = static_cast<uint32_t>(rhs); 1359 return static_cast<T>(lhsUnsigned + rhsUnsigned); 1360 } 1361 1362 template <typename T> 1363 inline T WrappingDiff(T lhs, T rhs) 1364 { 1365 uint32_t lhsUnsigned = static_cast<uint32_t>(lhs); 1366 uint32_t rhsUnsigned = static_cast<uint32_t>(rhs); 1367 return static_cast<T>(lhsUnsigned - rhsUnsigned); 1368 } 1369 1370 inline int32_t WrappingMul(int32_t lhs, int32_t rhs) 1371 { 1372 int64_t lhsWide = static_cast<int64_t>(lhs); 1373 int64_t rhsWide = static_cast<int64_t>(rhs); 1374 // The multiplication is guaranteed not to overflow. 1375 int64_t resultWide = lhsWide * rhsWide; 1376 // Implement the desired wrapping behavior by masking out the high-order 32 bits. 1377 resultWide = resultWide & 0xffffffffLL; 1378 // Casting to a narrower signed type is fine since the casted value is representable in the 1379 // narrower type. 1380 return static_cast<int32_t>(resultWide); 1381 } 1382 1383 inline float scaleScreenDimensionToNdc(float dimensionScreen, float viewportDimension) 1384 { 1385 return 2.0f * dimensionScreen / viewportDimension; 1386 } 1387 1388 inline float scaleScreenCoordinateToNdc(float coordinateScreen, float viewportDimension) 1389 { 1390 float halfShifted = coordinateScreen / viewportDimension; 1391 return 2.0f * (halfShifted - 0.5f); 1392 } 1393 1394 } // namespace gl 1395 1396 namespace rx 1397 { 1398 1399 template <typename T> 1400 T roundUp(const T value, const T alignment) 1401 { 1402 auto temp = value + alignment - static_cast<T>(1); 1403 return temp - temp % alignment; 1404 } 1405 1406 template <typename T> 1407 constexpr T roundUpPow2(const T value, const T alignment) 1408 { 1409 ASSERT(gl::isPow2(alignment)); 1410 return (value + alignment - 1) & ~(alignment - 1); 1411 } 1412 1413 template <typename T> 1414 constexpr T roundDownPow2(const T value, const T alignment) 1415 { 1416 ASSERT(gl::isPow2(alignment)); 1417 return value & ~(alignment - 1); 1418 } 1419 1420 template <typename T> 1421 angle::CheckedNumeric<T> CheckedRoundUp(const T value, const T alignment) 1422 { 1423 angle::CheckedNumeric<T> checkedValue(value); 1424 angle::CheckedNumeric<T> checkedAlignment(alignment); 1425 return roundUp(checkedValue, checkedAlignment); 1426 } 1427 1428 inline constexpr unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor) 1429 { 1430 unsigned int divided = value / divisor; 1431 return (divided + ((value % divisor == 0) ? 0 : 1)); 1432 } 1433 1434 #if defined(__has_builtin) 1435 # define ANGLE_HAS_BUILTIN(x) __has_builtin(x) 1436 #else 1437 # define ANGLE_HAS_BUILTIN(x) 0 1438 #endif 1439 1440 #if defined(_MSC_VER) 1441 1442 # define ANGLE_ROTL(x, y) _rotl(x, y) 1443 # define ANGLE_ROTL64(x, y) _rotl64(x, y) 1444 # define ANGLE_ROTR16(x, y) _rotr16(x, y) 1445 1446 #elif defined(__clang__) && ANGLE_HAS_BUILTIN(__builtin_rotateleft32) && \ 1447 ANGLE_HAS_BUILTIN(__builtin_rotateleft64) && ANGLE_HAS_BUILTIN(__builtin_rotateright16) 1448 1449 # define ANGLE_ROTL(x, y) __builtin_rotateleft32(x, y) 1450 # define ANGLE_ROTL64(x, y) __builtin_rotateleft64(x, y) 1451 # define ANGLE_ROTR16(x, y) __builtin_rotateright16(x, y) 1452 1453 #else 1454 1455 inline uint32_t RotL(uint32_t x, int8_t r) 1456 { 1457 return (x << r) | (x >> (32 - r)); 1458 } 1459 1460 inline uint64_t RotL64(uint64_t x, int8_t r) 1461 { 1462 return (x << r) | (x >> (64 - r)); 1463 } 1464 1465 inline uint16_t RotR16(uint16_t x, int8_t r) 1466 { 1467 return (x >> r) | (x << (16 - r)); 1468 } 1469 1470 # define ANGLE_ROTL(x, y) ::rx::RotL(x, y) 1471 # define ANGLE_ROTL64(x, y) ::rx::RotL64(x, y) 1472 # define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y) 1473 1474 #endif // namespace rx 1475 1476 constexpr unsigned int Log2(unsigned int bytes) 1477 { 1478 return bytes == 1 ? 0 : (1 + Log2(bytes / 2)); 1479 } 1480 } // namespace rx 1481 1482 #endif // COMMON_MATHUTIL_H_