LCOV - code coverage report
Current view: top level - gfx/angle/src/common - mathutil.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 76 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2002-2013 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 <limits>
      13             : #include <algorithm>
      14             : #include <math.h>
      15             : #include <string.h>
      16             : #include <stdint.h>
      17             : #include <stdlib.h>
      18             : 
      19             : #include <base/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             : }
      29             : 
      30             : namespace gl
      31             : {
      32             : 
      33             : const unsigned int Float32One = 0x3F800000;
      34             : const unsigned short Float16One = 0x3C00;
      35             : 
      36             : inline bool isPow2(int x)
      37             : {
      38             :     return (x & (x - 1)) == 0 && (x != 0);
      39             : }
      40             : 
      41             : inline int log2(int x)
      42             : {
      43             :     int r = 0;
      44             :     while ((x >> r) > 1) r++;
      45             :     return r;
      46             : }
      47             : 
      48             : inline unsigned int ceilPow2(unsigned int x)
      49             : {
      50             :     if (x != 0) x--;
      51             :     x |= x >> 1;
      52             :     x |= x >> 2;
      53             :     x |= x >> 4;
      54             :     x |= x >> 8;
      55             :     x |= x >> 16;
      56             :     x++;
      57             : 
      58             :     return x;
      59             : }
      60             : 
      61             : inline int clampToInt(unsigned int x)
      62             : {
      63             :     return static_cast<int>(std::min(x, static_cast<unsigned int>(std::numeric_limits<int>::max())));
      64             : }
      65             : 
      66             : template <typename DestT, typename SrcT>
      67             : inline DestT clampCast(SrcT value)
      68             : {
      69             :     static const DestT destLo = std::numeric_limits<DestT>::min();
      70             :     static const DestT destHi = std::numeric_limits<DestT>::max();
      71             :     static const SrcT srcLo = static_cast<SrcT>(destLo);
      72             :     static const SrcT srcHi = static_cast<SrcT>(destHi);
      73             : 
      74             :     // When value is outside of or equal to the limits for DestT we use the DestT limit directly.
      75             :     // This avoids undefined behaviors due to loss of precision when converting from floats to
      76             :     // integers:
      77             :     //    destHi for ints is 2147483647 but the closest float number is around 2147483648, so when
      78             :     //  doing a conversion from float to int we run into an UB because the float is outside of the
      79             :     //  range representable by the int.
      80             :     if (value <= srcLo)
      81             :     {
      82             :         return destLo;
      83             :     }
      84             :     else if (value >= srcHi)
      85             :     {
      86             :         return destHi;
      87             :     }
      88             :     else
      89             :     {
      90             :         return static_cast<DestT>(value);
      91             :     }
      92             : }
      93             : 
      94             : template<typename T, typename MIN, typename MAX>
      95           0 : inline T clamp(T x, MIN min, MAX max)
      96             : {
      97             :     // Since NaNs fail all comparison tests, a NaN value will default to min
      98           0 :     return x > min ? (x > max ? max : x) : min;
      99             : }
     100             : 
     101             : inline float clamp01(float x)
     102             : {
     103             :     return clamp(x, 0.0f, 1.0f);
     104             : }
     105             : 
     106             : template<const int n>
     107             : inline unsigned int unorm(float x)
     108             : {
     109             :     const unsigned int max = 0xFFFFFFFF >> (32 - n);
     110             : 
     111             :     if (x > 1)
     112             :     {
     113             :         return max;
     114             :     }
     115             :     else if (x < 0)
     116             :     {
     117             :         return 0;
     118             :     }
     119             :     else
     120             :     {
     121             :         return (unsigned int)(max * x + 0.5f);
     122             :     }
     123             : }
     124             : 
     125             : inline bool supportsSSE2()
     126             : {
     127             : #if defined(ANGLE_USE_SSE)
     128             :     static bool checked = false;
     129             :     static bool supports = false;
     130             : 
     131             :     if (checked)
     132             :     {
     133             :         return supports;
     134             :     }
     135             : 
     136             : #if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
     137             :     {
     138             :         int info[4];
     139             :         __cpuid(info, 0);
     140             : 
     141             :         if (info[0] >= 1)
     142             :         {
     143             :             __cpuid(info, 1);
     144             : 
     145             :             supports = (info[3] >> 26) & 1;
     146             :         }
     147             :     }
     148             : #endif  // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
     149             :     checked = true;
     150             :     return supports;
     151             : #else  // defined(ANGLE_USE_SSE)
     152             :     return false;
     153             : #endif
     154             : }
     155             : 
     156             : template <typename destType, typename sourceType>
     157           0 : destType bitCast(const sourceType &source)
     158             : {
     159           0 :     size_t copySize = std::min(sizeof(destType), sizeof(sourceType));
     160             :     destType output;
     161           0 :     memcpy(&output, &source, copySize);
     162           0 :     return output;
     163             : }
     164             : 
     165           0 : inline unsigned short float32ToFloat16(float fp32)
     166             : {
     167           0 :     unsigned int fp32i = bitCast<unsigned int>(fp32);
     168           0 :     unsigned int sign = (fp32i & 0x80000000) >> 16;
     169           0 :     unsigned int abs = fp32i & 0x7FFFFFFF;
     170             : 
     171           0 :     if(abs > 0x47FFEFFF)   // Infinity
     172             :     {
     173           0 :         return static_cast<unsigned short>(sign | 0x7FFF);
     174             :     }
     175           0 :     else if(abs < 0x38800000)   // Denormal
     176             :     {
     177           0 :         unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
     178           0 :         int e = 113 - (abs >> 23);
     179             : 
     180           0 :         if(e < 24)
     181             :         {
     182           0 :             abs = mantissa >> e;
     183             :         }
     184             :         else
     185             :         {
     186           0 :             abs = 0;
     187             :         }
     188             : 
     189           0 :         return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
     190             :     }
     191             :     else
     192             :     {
     193           0 :         return static_cast<unsigned short>(sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
     194             :     }
     195             : }
     196             : 
     197             : float float16ToFloat32(unsigned short h);
     198             : 
     199             : unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
     200             : void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);
     201             : 
     202             : inline unsigned short float32ToFloat11(float fp32)
     203             : {
     204             :     const unsigned int float32MantissaMask = 0x7FFFFF;
     205             :     const unsigned int float32ExponentMask = 0x7F800000;
     206             :     const unsigned int float32SignMask = 0x80000000;
     207             :     const unsigned int float32ValueMask = ~float32SignMask;
     208             :     const unsigned int float32ExponentFirstBit = 23;
     209             :     const unsigned int float32ExponentBias = 127;
     210             : 
     211             :     const unsigned short float11Max = 0x7BF;
     212             :     const unsigned short float11MantissaMask = 0x3F;
     213             :     const unsigned short float11ExponentMask = 0x7C0;
     214             :     const unsigned short float11BitMask = 0x7FF;
     215             :     const unsigned int float11ExponentBias = 14;
     216             : 
     217             :     const unsigned int float32Maxfloat11 = 0x477E0000;
     218             :     const unsigned int float32Minfloat11 = 0x38800000;
     219             : 
     220             :     const unsigned int float32Bits = bitCast<unsigned int>(fp32);
     221             :     const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
     222             : 
     223             :     unsigned int float32Val = float32Bits & float32ValueMask;
     224             : 
     225             :     if ((float32Val & float32ExponentMask) == float32ExponentMask)
     226             :     {
     227             :         // INF or NAN
     228             :         if ((float32Val & float32MantissaMask) != 0)
     229             :         {
     230             :             return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & float11MantissaMask);
     231             :         }
     232             :         else if (float32Sign)
     233             :         {
     234             :             // -INF is clamped to 0 since float11 is positive only
     235             :             return 0;
     236             :         }
     237             :         else
     238             :         {
     239             :             return float11ExponentMask;
     240             :         }
     241             :     }
     242             :     else if (float32Sign)
     243             :     {
     244             :         // float11 is positive only, so clamp to zero
     245             :         return 0;
     246             :     }
     247             :     else if (float32Val > float32Maxfloat11)
     248             :     {
     249             :         // The number is too large to be represented as a float11, set to max
     250             :         return float11Max;
     251             :     }
     252             :     else
     253             :     {
     254             :         if (float32Val < float32Minfloat11)
     255             :         {
     256             :             // The number is too small to be represented as a normalized float11
     257             :             // Convert it to a denormalized value.
     258             :             const unsigned int shift = (float32ExponentBias - float11ExponentBias) - (float32Val >> float32ExponentFirstBit);
     259             :             float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
     260             :         }
     261             :         else
     262             :         {
     263             :             // Rebias the exponent to represent the value as a normalized float11
     264             :             float32Val += 0xC8000000;
     265             :         }
     266             : 
     267             :         return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
     268             :     }
     269             : }
     270             : 
     271             : inline unsigned short float32ToFloat10(float fp32)
     272             : {
     273             :     const unsigned int float32MantissaMask = 0x7FFFFF;
     274             :     const unsigned int float32ExponentMask = 0x7F800000;
     275             :     const unsigned int float32SignMask = 0x80000000;
     276             :     const unsigned int float32ValueMask = ~float32SignMask;
     277             :     const unsigned int float32ExponentFirstBit = 23;
     278             :     const unsigned int float32ExponentBias = 127;
     279             : 
     280             :     const unsigned short float10Max = 0x3DF;
     281             :     const unsigned short float10MantissaMask = 0x1F;
     282             :     const unsigned short float10ExponentMask = 0x3E0;
     283             :     const unsigned short float10BitMask = 0x3FF;
     284             :     const unsigned int float10ExponentBias = 14;
     285             : 
     286             :     const unsigned int float32Maxfloat10 = 0x477C0000;
     287             :     const unsigned int float32Minfloat10 = 0x38800000;
     288             : 
     289             :     const unsigned int float32Bits = bitCast<unsigned int>(fp32);
     290             :     const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
     291             : 
     292             :     unsigned int float32Val = float32Bits & float32ValueMask;
     293             : 
     294             :     if ((float32Val & float32ExponentMask) == float32ExponentMask)
     295             :     {
     296             :         // INF or NAN
     297             :         if ((float32Val & float32MantissaMask) != 0)
     298             :         {
     299             :             return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & float10MantissaMask);
     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 float10ExponentMask;
     309             :         }
     310             :     }
     311             :     else if (float32Sign)
     312             :     {
     313             :         // float10 is positive only, so clamp to zero
     314             :         return 0;
     315             :     }
     316             :     else if (float32Val > float32Maxfloat10)
     317             :     {
     318             :         // The number is too large to be represented as a float11, set to max
     319             :         return float10Max;
     320             :     }
     321             :     else
     322             :     {
     323             :         if (float32Val < float32Minfloat10)
     324             :         {
     325             :             // The number is too small to be represented as a normalized float11
     326             :             // Convert it to a denormalized value.
     327             :             const unsigned int shift = (float32ExponentBias - float10ExponentBias) - (float32Val >> float32ExponentFirstBit);
     328             :             float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
     329             :         }
     330             :         else
     331             :         {
     332             :             // Rebias the exponent to represent the value as a normalized float11
     333             :             float32Val += 0xC8000000;
     334             :         }
     335             : 
     336             :         return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
     337             :     }
     338             : }
     339             : 
     340             : inline float float11ToFloat32(unsigned short fp11)
     341             : {
     342             :     unsigned short exponent = (fp11 >> 6) & 0x1F;
     343             :     unsigned short mantissa = fp11 & 0x3F;
     344             : 
     345             :     if (exponent == 0x1F)
     346             :     {
     347             :         // INF or NAN
     348             :         return bitCast<float>(0x7f800000 | (mantissa << 17));
     349             :     }
     350             :     else
     351             :     {
     352             :         if (exponent != 0)
     353             :         {
     354             :             // normalized
     355             :         }
     356             :         else if (mantissa != 0)
     357             :         {
     358             :             // The value is denormalized
     359             :             exponent = 1;
     360             : 
     361             :             do
     362             :             {
     363             :                 exponent--;
     364             :                 mantissa <<= 1;
     365             :             }
     366             :             while ((mantissa & 0x40) == 0);
     367             : 
     368             :             mantissa = mantissa & 0x3F;
     369             :         }
     370             :         else // The value is zero
     371             :         {
     372             :             exponent = static_cast<unsigned short>(-112);
     373             :         }
     374             : 
     375             :         return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
     376             :     }
     377             : }
     378             : 
     379             : inline float float10ToFloat32(unsigned short fp11)
     380             : {
     381             :     unsigned short exponent = (fp11 >> 5) & 0x1F;
     382             :     unsigned short mantissa = fp11 & 0x1F;
     383             : 
     384             :     if (exponent == 0x1F)
     385             :     {
     386             :         // INF or NAN
     387             :         return bitCast<float>(0x7f800000 | (mantissa << 17));
     388             :     }
     389             :     else
     390             :     {
     391             :         if (exponent != 0)
     392             :         {
     393             :             // normalized
     394             :         }
     395             :         else if (mantissa != 0)
     396             :         {
     397             :             // The value is denormalized
     398             :             exponent = 1;
     399             : 
     400             :             do
     401             :             {
     402             :                 exponent--;
     403             :                 mantissa <<= 1;
     404             :             }
     405             :             while ((mantissa & 0x20) == 0);
     406             : 
     407             :             mantissa = mantissa & 0x1F;
     408             :         }
     409             :         else // The value is zero
     410             :         {
     411             :             exponent = static_cast<unsigned short>(-112);
     412             :         }
     413             : 
     414             :         return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
     415             :     }
     416             : }
     417             : 
     418             : template <typename T>
     419             : inline float normalizedToFloat(T input)
     420             : {
     421             :     static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
     422             : 
     423             :     const float inverseMax = 1.0f / std::numeric_limits<T>::max();
     424             :     return input * inverseMax;
     425             : }
     426             : 
     427             : template <unsigned int inputBitCount, typename T>
     428             : inline float normalizedToFloat(T input)
     429             : {
     430             :     static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
     431             :     static_assert(inputBitCount < (sizeof(T) * 8), "T must have more bits than inputBitCount.");
     432             : 
     433             :     const float inverseMax = 1.0f / ((1 << inputBitCount) - 1);
     434             :     return input * inverseMax;
     435             : }
     436             : 
     437             : template <typename T>
     438             : inline T floatToNormalized(float input)
     439             : {
     440             :     return static_cast<T>(std::numeric_limits<T>::max() * input + 0.5f);
     441             : }
     442             : 
     443             : template <unsigned int outputBitCount, typename T>
     444             : inline T floatToNormalized(float input)
     445             : {
     446             :     static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount.");
     447             :     return static_cast<T>(((1 << outputBitCount) - 1) * input + 0.5f);
     448             : }
     449             : 
     450             : template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
     451             : inline T getShiftedData(T input)
     452             : {
     453             :     static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
     454             :                   "T must have at least as many bits as inputBitCount + inputBitStart.");
     455             :     const T mask = (1 << inputBitCount) - 1;
     456             :     return (input >> inputBitStart) & mask;
     457             : }
     458             : 
     459             : template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
     460             : inline T shiftData(T input)
     461             : {
     462             :     static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
     463             :                   "T must have at least as many bits as inputBitCount + inputBitStart.");
     464             :     const T mask = (1 << inputBitCount) - 1;
     465             :     return (input & mask) << inputBitStart;
     466             : }
     467             : 
     468             : inline unsigned int CountLeadingZeros(uint32_t x)
     469             : {
     470             :     // Use binary search to find the amount of leading zeros.
     471             :     unsigned int zeros = 32u;
     472             :     uint32_t y;
     473             : 
     474             :     y = x >> 16u;
     475             :     if (y != 0)
     476             :     {
     477             :         zeros = zeros - 16u;
     478             :         x     = y;
     479             :     }
     480             :     y = x >> 8u;
     481             :     if (y != 0)
     482             :     {
     483             :         zeros = zeros - 8u;
     484             :         x     = y;
     485             :     }
     486             :     y = x >> 4u;
     487             :     if (y != 0)
     488             :     {
     489             :         zeros = zeros - 4u;
     490             :         x     = y;
     491             :     }
     492             :     y = x >> 2u;
     493             :     if (y != 0)
     494             :     {
     495             :         zeros = zeros - 2u;
     496             :         x     = y;
     497             :     }
     498             :     y = x >> 1u;
     499             :     if (y != 0)
     500             :     {
     501             :         return zeros - 2u;
     502             :     }
     503             :     return zeros - x;
     504             : }
     505             : 
     506             : inline unsigned char average(unsigned char a, unsigned char b)
     507             : {
     508             :     return ((a ^ b) >> 1) + (a & b);
     509             : }
     510             : 
     511             : inline signed char average(signed char a, signed char b)
     512             : {
     513             :     return ((short)a + (short)b) / 2;
     514             : }
     515             : 
     516             : inline unsigned short average(unsigned short a, unsigned short b)
     517             : {
     518             :     return ((a ^ b) >> 1) + (a & b);
     519             : }
     520             : 
     521             : inline signed short average(signed short a, signed short b)
     522             : {
     523             :     return ((int)a + (int)b) / 2;
     524             : }
     525             : 
     526             : inline unsigned int average(unsigned int a, unsigned int b)
     527             : {
     528             :     return ((a ^ b) >> 1) + (a & b);
     529             : }
     530             : 
     531             : inline int average(int a, int b)
     532             : {
     533             :     long long average = (static_cast<long long>(a) + static_cast<long long>(b)) / 2ll;
     534             :     return static_cast<int>(average);
     535             : }
     536             : 
     537             : inline float average(float a, float b)
     538             : {
     539             :     return (a + b) * 0.5f;
     540             : }
     541             : 
     542             : inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
     543             : {
     544             :     return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
     545             : }
     546             : 
     547             : inline unsigned int averageFloat11(unsigned int a, unsigned int b)
     548             : {
     549             :     return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) + float11ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
     550             : }
     551             : 
     552             : inline unsigned int averageFloat10(unsigned int a, unsigned int b)
     553             : {
     554             :     return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) + float10ToFloat32(static_cast<unsigned short>(b))) * 0.5f);
     555             : }
     556             : 
     557             : template <typename T>
     558             : struct Range
     559             : {
     560             :     Range() {}
     561             :     Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
     562             : 
     563             :     T start;
     564             :     T end;
     565             : 
     566             :     T length() const { return end - start; }
     567             : 
     568             :     bool intersects(Range<T> other)
     569             :     {
     570             :         if (start <= other.start)
     571             :         {
     572             :             return other.start < end;
     573             :         }
     574             :         else
     575             :         {
     576             :             return start < other.end;
     577             :         }
     578             :     }
     579             : 
     580             :     void extend(T value)
     581             :     {
     582             :         start = value > start ? value : start;
     583             :         end = value < end ? value : end;
     584             :     }
     585             : 
     586             :     bool empty() const
     587             :     {
     588             :         return end <= start;
     589             :     }
     590             : };
     591             : 
     592             : typedef Range<int> RangeI;
     593             : typedef Range<unsigned int> RangeUI;
     594             : 
     595             : struct IndexRange
     596             : {
     597             :     IndexRange() : IndexRange(0, 0, 0) {}
     598           0 :     IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_)
     599           0 :         : start(start_), end(end_), vertexIndexCount(vertexIndexCount_)
     600             :     {
     601           0 :         ASSERT(start <= end);
     602           0 :     }
     603             : 
     604             :     // Number of vertices in the range.
     605             :     size_t vertexCount() const { return (end - start) + 1; }
     606             : 
     607             :     // Inclusive range of indices that are not primitive restart
     608             :     size_t start;
     609             :     size_t end;
     610             : 
     611             :     // Number of non-primitive restart indices
     612             :     size_t vertexIndexCount;
     613             : };
     614             : 
     615             : // First, both normalized floating-point values are converted into 16-bit integer values.
     616             : // Then, the results are packed into the returned 32-bit unsigned integer.
     617             : // The first float value will be written to the least significant bits of the output;
     618             : // the last float value will be written to the most significant bits.
     619             : // The conversion of each value to fixed point is done as follows :
     620             : // packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
     621           0 : inline uint32_t packSnorm2x16(float f1, float f2)
     622             : {
     623           0 :     int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
     624           0 :     int16_t mostSignificantBits = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
     625           0 :     return static_cast<uint32_t>(mostSignificantBits) << 16 |
     626           0 :            (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
     627             : }
     628             : 
     629             : // First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
     630             : // component is converted to a normalized floating-point value to generate the returned two float values.
     631             : // The first float value will be extracted from the least significant bits of the input;
     632             : // the last float value will be extracted from the most-significant bits.
     633             : // The conversion for unpacked fixed-point value to floating point is done as follows:
     634             : // unpackSnorm2x16 : clamp(f / 32767.0, -1, +1)
     635           0 : inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2)
     636             : {
     637           0 :     int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF);
     638           0 :     int16_t mostSignificantBits = static_cast<int16_t>(u >> 16);
     639           0 :     *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f);
     640           0 :     *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f);
     641           0 : }
     642             : 
     643             : // First, both normalized floating-point values are converted into 16-bit integer values.
     644             : // Then, the results are packed into the returned 32-bit unsigned integer.
     645             : // The first float value will be written to the least significant bits of the output;
     646             : // the last float value will be written to the most significant bits.
     647             : // The conversion of each value to fixed point is done as follows:
     648             : // packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0)
     649           0 : inline uint32_t packUnorm2x16(float f1, float f2)
     650             : {
     651           0 :     uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f));
     652           0 :     uint16_t mostSignificantBits = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
     653           0 :     return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
     654             : }
     655             : 
     656             : // First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each
     657             : // component is converted to a normalized floating-point value to generate the returned two float values.
     658             : // The first float value will be extracted from the least significant bits of the input;
     659             : // the last float value will be extracted from the most-significant bits.
     660             : // The conversion for unpacked fixed-point value to floating point is done as follows:
     661             : // unpackUnorm2x16 : f / 65535.0
     662           0 : inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2)
     663             : {
     664           0 :     uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
     665           0 :     uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
     666           0 :     *f1 = static_cast<float>(leastSignificantBits) / 65535.0f;
     667           0 :     *f2 = static_cast<float>(mostSignificantBits) / 65535.0f;
     668           0 : }
     669             : 
     670             : // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
     671             : // floating-point representation found in the OpenGL ES Specification, and then packing these
     672             : // two 16-bit integers into a 32-bit unsigned integer.
     673             : // f1: The 16 least-significant bits of the result;
     674             : // f2: The 16 most-significant bits.
     675           0 : inline uint32_t packHalf2x16(float f1, float f2)
     676             : {
     677           0 :     uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1));
     678           0 :     uint16_t mostSignificantBits = static_cast<uint16_t>(float32ToFloat16(f2));
     679           0 :     return static_cast<uint32_t>(mostSignificantBits) << 16 | static_cast<uint32_t>(leastSignificantBits);
     680             : }
     681             : 
     682             : // Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values,
     683             : // interpreting those values as 16-bit floating-point numbers according to the OpenGL ES Specification,
     684             : // and converting them to 32-bit floating-point values.
     685             : // The first float value is obtained from the 16 least-significant bits of u;
     686             : // the second component is obtained from the 16 most-significant bits of u.
     687           0 : inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
     688             : {
     689           0 :     uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
     690           0 :     uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
     691             : 
     692           0 :     *f1 = float16ToFloat32(leastSignificantBits);
     693           0 :     *f2 = float16ToFloat32(mostSignificantBits);
     694           0 : }
     695             : 
     696             : // Returns whether the argument is Not a Number.
     697             : // IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - non-zero.
     698           0 : inline bool isNaN(float f)
     699             : {
     700             :     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     701             :     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
     702           0 :     return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && (bitCast<uint32_t>(f) & 0x7fffffu);
     703             : }
     704             : 
     705             : // Returns whether the argument is infinity.
     706             : // IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - zero.
     707           0 : inline bool isInf(float f)
     708             : {
     709             :     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     710             :     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
     711           0 :     return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast<uint32_t>(f) & 0x7fffffu);
     712             : }
     713             : 
     714             : namespace priv
     715             : {
     716             : template <unsigned int N, unsigned int R>
     717             : struct iSquareRoot
     718             : {
     719             :     static constexpr unsigned int solve()
     720             :     {
     721             :         return (R * R > N)
     722             :                    ? 0
     723             :                    : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value));
     724             :     }
     725             :     enum Result
     726             :     {
     727             :         value = iSquareRoot::solve()
     728             :     };
     729             : };
     730             : 
     731             : template <unsigned int N>
     732             : struct iSquareRoot<N, N>
     733             : {
     734             :     enum result
     735             :     {
     736             :         value = N
     737             :     };
     738             : };
     739             : 
     740             : }  // namespace priv
     741             : 
     742             : template <unsigned int N>
     743             : constexpr unsigned int iSquareRoot()
     744             : {
     745             :     return priv::iSquareRoot<N, 1>::value;
     746             : }
     747             : 
     748             : // Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow.
     749             : //
     750             : // Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow
     751             : // behavior is undefined.
     752             : 
     753             : template <typename T>
     754           0 : inline T WrappingSum(T lhs, T rhs)
     755             : {
     756           0 :     uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
     757           0 :     uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
     758           0 :     return static_cast<T>(lhsUnsigned + rhsUnsigned);
     759             : }
     760             : 
     761             : template <typename T>
     762           0 : inline T WrappingDiff(T lhs, T rhs)
     763             : {
     764           0 :     uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
     765           0 :     uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
     766           0 :     return static_cast<T>(lhsUnsigned - rhsUnsigned);
     767             : }
     768             : 
     769           0 : inline int32_t WrappingMul(int32_t lhs, int32_t rhs)
     770             : {
     771           0 :     int64_t lhsWide = static_cast<int64_t>(lhs);
     772           0 :     int64_t rhsWide = static_cast<int64_t>(rhs);
     773             :     // The multiplication is guaranteed not to overflow.
     774           0 :     int64_t resultWide = lhsWide * rhsWide;
     775             :     // Implement the desired wrapping behavior by masking out the high-order 32 bits.
     776           0 :     resultWide = resultWide & 0xffffffffll;
     777             :     // Casting to a narrower signed type is fine since the casted value is representable in the
     778             :     // narrower type.
     779           0 :     return static_cast<int32_t>(resultWide);
     780             : }
     781             : 
     782             : }  // namespace gl
     783             : 
     784             : namespace rx
     785             : {
     786             : 
     787             : template <typename T>
     788           0 : T roundUp(const T value, const T alignment)
     789             : {
     790           0 :     auto temp = value + alignment - static_cast<T>(1);
     791           0 :     return temp - temp % alignment;
     792             : }
     793             : 
     794             : template <typename T>
     795             : angle::CheckedNumeric<T> CheckedRoundUp(const T value, const T alignment)
     796             : {
     797             :     angle::CheckedNumeric<T> checkedValue(value);
     798             :     angle::CheckedNumeric<T> checkedAlignment(alignment);
     799             :     return roundUp(checkedValue, checkedAlignment);
     800             : }
     801             : 
     802             : inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
     803             : {
     804             :     unsigned int divided = value / divisor;
     805             :     return (divided + ((value % divisor == 0) ? 0 : 1));
     806             : }
     807             : 
     808             : #if defined(_MSC_VER)
     809             : 
     810             : #define ANGLE_ROTL(x,y) _rotl(x,y)
     811             : #define ANGLE_ROTR16(x,y) _rotr16(x,y)
     812             : 
     813             : #else
     814             : 
     815             : inline uint32_t RotL(uint32_t x, int8_t r)
     816             : {
     817             :     return (x << r) | (x >> (32 - r));
     818             : }
     819             : 
     820             : inline uint16_t RotR16(uint16_t x, int8_t r)
     821             : {
     822             :     return (x >> r) | (x << (16 - r));
     823             : }
     824             : 
     825             : #define ANGLE_ROTL(x, y) ::rx::RotL(x, y)
     826             : #define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y)
     827             : 
     828             : #endif // namespace rx
     829             : 
     830             : }
     831             : 
     832             : #endif   // COMMON_MATHUTIL_H_

Generated by: LCOV version 1.13