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 LIBGLESV2_MATHUTIL_H_ 10 #define LIBGLESV2_MATHUTIL_H_ 11 12 #include "common/debug.h" 13 #include "common/platform.h" 14 15 #include <limits> 16 #include <algorithm> 17 #include <string.h> 18 19 namespace gl 20 { 21 22 const unsigned int Float32One = 0x3F800000; 23 const unsigned short Float16One = 0x3C00; 24 25 struct Vector4 26 { 27 Vector4() {} 28 Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} 29 30 float x; 31 float y; 32 float z; 33 float w; 34 }; 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 // This assumes SrcT can properly represent DestT::min/max 70 // Unfortunately we can't use META_ASSERT without C++11 constexpr support 71 ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::min())) == std::numeric_limits<DestT>::min()); 72 ASSERT(static_cast<DestT>(static_cast<SrcT>(std::numeric_limits<DestT>::max())) == std::numeric_limits<DestT>::max()); 73 74 SrcT lo = static_cast<SrcT>(std::numeric_limits<DestT>::min()); 75 SrcT hi = static_cast<SrcT>(std::numeric_limits<DestT>::max()); 76 return static_cast<DestT>(value > lo ? (value > hi ? hi : value) : lo); 77 } 78 79 template<typename T, typename MIN, typename MAX> 80 inline T clamp(T x, MIN min, MAX max) 81 { 82 // Since NaNs fail all comparison tests, a NaN value will default to min 83 return x > min ? (x > max ? max : x) : min; 84 } 85 86 inline float clamp01(float x) 87 { 88 return clamp(x, 0.0f, 1.0f); 89 } 90 91 template<const int n> 92 inline unsigned int unorm(float x) 93 { 94 const unsigned int max = 0xFFFFFFFF >> (32 - n); 95 96 if (x > 1) 97 { 98 return max; 99 } 100 else if (x < 0) 101 { 102 return 0; 103 } 104 else 105 { 106 return (unsigned int)(max * x + 0.5f); 107 } 108 } 109 110 inline bool supportsSSE2() 111 { 112 #ifdef ANGLE_PLATFORM_WINDOWS 113 static bool checked = false; 114 static bool supports = false; 115 116 if (checked) 117 { 118 return supports; 119 } 120 121 int info[4]; 122 __cpuid(info, 0); 123 124 if (info[0] >= 1) 125 { 126 __cpuid(info, 1); 127 128 supports = (info[3] >> 26) & 1; 129 } 130 131 checked = true; 132 133 return supports; 134 #else 135 UNIMPLEMENTED(); 136 return false; 137 #endif 138 } 139 140 template <typename destType, typename sourceType> 141 destType bitCast(const sourceType &source) 142 { 143 size_t copySize = std::min(sizeof(destType), sizeof(sourceType)); 144 destType output; 145 memcpy(&output, &source, copySize); 146 return output; 147 } 148 149 inline unsigned short float32ToFloat16(float fp32) 150 { 151 unsigned int fp32i = (unsigned int&)fp32; 152 unsigned int sign = (fp32i & 0x80000000) >> 16; 153 unsigned int abs = fp32i & 0x7FFFFFFF; 154 155 if(abs > 0x47FFEFFF) // Infinity 156 { 157 return sign | 0x7FFF; 158 } 159 else if(abs < 0x38800000) // Denormal 160 { 161 unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000; 162 int e = 113 - (abs >> 23); 163 164 if(e < 24) 165 { 166 abs = mantissa >> e; 167 } 168 else 169 { 170 abs = 0; 171 } 172 173 return sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13; 174 } 175 else 176 { 177 return sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13; 178 } 179 } 180 181 float float16ToFloat32(unsigned short h); 182 183 unsigned int convertRGBFloatsTo999E5(float red, float green, float blue); 184 void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue); 185 186 inline unsigned short float32ToFloat11(float fp32) 187 { 188 const unsigned int float32MantissaMask = 0x7FFFFF; 189 const unsigned int float32ExponentMask = 0x7F800000; 190 const unsigned int float32SignMask = 0x80000000; 191 const unsigned int float32ValueMask = ~float32SignMask; 192 const unsigned int float32ExponentFirstBit = 23; 193 const unsigned int float32ExponentBias = 127; 194 195 const unsigned short float11Max = 0x7BF; 196 const unsigned short float11MantissaMask = 0x3F; 197 const unsigned short float11ExponentMask = 0x7C0; 198 const unsigned short float11BitMask = 0x7FF; 199 const unsigned int float11ExponentBias = 14; 200 201 const unsigned int float32Maxfloat11 = 0x477E0000; 202 const unsigned int float32Minfloat11 = 0x38800000; 203 204 const unsigned int float32Bits = bitCast<unsigned int>(fp32); 205 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; 206 207 unsigned int float32Val = float32Bits & float32ValueMask; 208 209 if ((float32Val & float32ExponentMask) == float32ExponentMask) 210 { 211 // INF or NAN 212 if ((float32Val & float32MantissaMask) != 0) 213 { 214 return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & float11MantissaMask); 215 } 216 else if (float32Sign) 217 { 218 // -INF is clamped to 0 since float11 is positive only 219 return 0; 220 } 221 else 222 { 223 return float11ExponentMask; 224 } 225 } 226 else if (float32Sign) 227 { 228 // float11 is positive only, so clamp to zero 229 return 0; 230 } 231 else if (float32Val > float32Maxfloat11) 232 { 233 // The number is too large to be represented as a float11, set to max 234 return float11Max; 235 } 236 else 237 { 238 if (float32Val < float32Minfloat11) 239 { 240 // The number is too small to be represented as a normalized float11 241 // Convert it to a denormalized value. 242 const unsigned int shift = (float32ExponentBias - float11ExponentBias) - (float32Val >> float32ExponentFirstBit); 243 float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift; 244 } 245 else 246 { 247 // Rebias the exponent to represent the value as a normalized float11 248 float32Val += 0xC8000000; 249 } 250 251 return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask; 252 } 253 } 254 255 inline unsigned short float32ToFloat10(float fp32) 256 { 257 const unsigned int float32MantissaMask = 0x7FFFFF; 258 const unsigned int float32ExponentMask = 0x7F800000; 259 const unsigned int float32SignMask = 0x80000000; 260 const unsigned int float32ValueMask = ~float32SignMask; 261 const unsigned int float32ExponentFirstBit = 23; 262 const unsigned int float32ExponentBias = 127; 263 264 const unsigned short float10Max = 0x3DF; 265 const unsigned short float10MantissaMask = 0x1F; 266 const unsigned short float10ExponentMask = 0x3E0; 267 const unsigned short float10BitMask = 0x3FF; 268 const unsigned int float10ExponentBias = 14; 269 270 const unsigned int float32Maxfloat10 = 0x477C0000; 271 const unsigned int float32Minfloat10 = 0x38800000; 272 273 const unsigned int float32Bits = bitCast<unsigned int>(fp32); 274 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; 275 276 unsigned int float32Val = float32Bits & float32ValueMask; 277 278 if ((float32Val & float32ExponentMask) == float32ExponentMask) 279 { 280 // INF or NAN 281 if ((float32Val & float32MantissaMask) != 0) 282 { 283 return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & float10MantissaMask); 284 } 285 else if (float32Sign) 286 { 287 // -INF is clamped to 0 since float11 is positive only 288 return 0; 289 } 290 else 291 { 292 return float10ExponentMask; 293 } 294 } 295 else if (float32Sign) 296 { 297 // float10 is positive only, so clamp to zero 298 return 0; 299 } 300 else if (float32Val > float32Maxfloat10) 301 { 302 // The number is too large to be represented as a float11, set to max 303 return float10Max; 304 } 305 else 306 { 307 if (float32Val < float32Minfloat10) 308 { 309 // The number is too small to be represented as a normalized float11 310 // Convert it to a denormalized value. 311 const unsigned int shift = (float32ExponentBias - float10ExponentBias) - (float32Val >> float32ExponentFirstBit); 312 float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift; 313 } 314 else 315 { 316 // Rebias the exponent to represent the value as a normalized float11 317 float32Val += 0xC8000000; 318 } 319 320 return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask; 321 } 322 } 323 324 inline float float11ToFloat32(unsigned short fp11) 325 { 326 unsigned short exponent = (fp11 >> 6) & 0x1F; 327 unsigned short mantissa = fp11 & 0x3F; 328 329 if (exponent == 0x1F) 330 { 331 // INF or NAN 332 return bitCast<float>(0x7f800000 | (mantissa << 17)); 333 } 334 else 335 { 336 if (exponent != 0) 337 { 338 // normalized 339 } 340 else if (mantissa != 0) 341 { 342 // The value is denormalized 343 exponent = 1; 344 345 do 346 { 347 exponent--; 348 mantissa <<= 1; 349 } 350 while ((mantissa & 0x40) == 0); 351 352 mantissa = mantissa & 0x3F; 353 } 354 else // The value is zero 355 { 356 exponent = -112; 357 } 358 359 return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17)); 360 } 361 } 362 363 inline float float10ToFloat32(unsigned short fp11) 364 { 365 unsigned short exponent = (fp11 >> 5) & 0x1F; 366 unsigned short mantissa = fp11 & 0x1F; 367 368 if (exponent == 0x1F) 369 { 370 // INF or NAN 371 return bitCast<float>(0x7f800000 | (mantissa << 17)); 372 } 373 else 374 { 375 if (exponent != 0) 376 { 377 // normalized 378 } 379 else if (mantissa != 0) 380 { 381 // The value is denormalized 382 exponent = 1; 383 384 do 385 { 386 exponent--; 387 mantissa <<= 1; 388 } 389 while ((mantissa & 0x20) == 0); 390 391 mantissa = mantissa & 0x1F; 392 } 393 else // The value is zero 394 { 395 exponent = -112; 396 } 397 398 return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18)); 399 } 400 } 401 402 template <typename T> 403 inline float normalizedToFloat(T input) 404 { 405 META_ASSERT(std::numeric_limits<T>::is_integer); 406 407 const float inverseMax = 1.0f / std::numeric_limits<T>::max(); 408 return input * inverseMax; 409 } 410 411 template <unsigned int inputBitCount, typename T> 412 inline float normalizedToFloat(T input) 413 { 414 META_ASSERT(std::numeric_limits<T>::is_integer); 415 META_ASSERT(inputBitCount < (sizeof(T) * 8)); 416 417 const float inverseMax = 1.0f / ((1 << inputBitCount) - 1); 418 return input * inverseMax; 419 } 420 421 template <typename T> 422 inline T floatToNormalized(float input) 423 { 424 return std::numeric_limits<T>::max() * input + 0.5f; 425 } 426 427 template <unsigned int outputBitCount, typename T> 428 inline T floatToNormalized(float input) 429 { 430 META_ASSERT(outputBitCount < (sizeof(T) * 8)); 431 return ((1 << outputBitCount) - 1) * input + 0.5f; 432 } 433 434 template <unsigned int inputBitCount, unsigned int inputBitStart, typename T> 435 inline T getShiftedData(T input) 436 { 437 META_ASSERT(inputBitCount + inputBitStart <= (sizeof(T) * 8)); 438 const T mask = (1 << inputBitCount) - 1; 439 return (input >> inputBitStart) & mask; 440 } 441 442 template <unsigned int inputBitCount, unsigned int inputBitStart, typename T> 443 inline T shiftData(T input) 444 { 445 META_ASSERT(inputBitCount + inputBitStart <= (sizeof(T) * 8)); 446 const T mask = (1 << inputBitCount) - 1; 447 return (input & mask) << inputBitStart; 448 } 449 450 451 inline unsigned char average(unsigned char a, unsigned char b) 452 { 453 return ((a ^ b) >> 1) + (a & b); 454 } 455 456 inline signed char average(signed char a, signed char b) 457 { 458 return ((short)a + (short)b) / 2; 459 } 460 461 inline unsigned short average(unsigned short a, unsigned short b) 462 { 463 return ((a ^ b) >> 1) + (a & b); 464 } 465 466 inline signed short average(signed short a, signed short b) 467 { 468 return ((int)a + (int)b) / 2; 469 } 470 471 inline unsigned int average(unsigned int a, unsigned int b) 472 { 473 return ((a ^ b) >> 1) + (a & b); 474 } 475 476 inline signed int average(signed int a, signed int b) 477 { 478 return ((long long)a + (long long)b) / 2; 479 } 480 481 inline float average(float a, float b) 482 { 483 return (a + b) * 0.5f; 484 } 485 486 inline unsigned short averageHalfFloat(unsigned short a, unsigned short b) 487 { 488 return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f); 489 } 490 491 inline unsigned int averageFloat11(unsigned int a, unsigned int b) 492 { 493 return float32ToFloat11((float11ToFloat32(a) + float11ToFloat32(b)) * 0.5f); 494 } 495 496 inline unsigned int averageFloat10(unsigned int a, unsigned int b) 497 { 498 return float32ToFloat10((float10ToFloat32(a) + float10ToFloat32(b)) * 0.5f); 499 } 500 501 } 502 503 namespace rx 504 { 505 506 template <typename T> 507 struct Range 508 { 509 Range() {} 510 Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); } 511 512 T start; 513 T end; 514 515 T length() const { return end - start; } 516 }; 517 518 typedef Range<int> RangeI; 519 typedef Range<unsigned int> RangeUI; 520 521 template <typename T> 522 T roundUp(const T value, const T alignment) 523 { 524 return value + alignment - 1 - (value - 1) % alignment; 525 } 526 527 inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor) 528 { 529 unsigned int divided = value / divisor; 530 return (divided + ((value % divisor == 0) ? 0 : 1)); 531 } 532 533 template <class T> 534 inline bool IsUnsignedAdditionSafe(T lhs, T rhs) 535 { 536 META_ASSERT(!std::numeric_limits<T>::is_signed); 537 return (rhs <= std::numeric_limits<T>::max() - lhs); 538 } 539 540 template <class T> 541 inline bool IsUnsignedMultiplicationSafe(T lhs, T rhs) 542 { 543 META_ASSERT(!std::numeric_limits<T>::is_signed); 544 return (lhs == T(0) || rhs == T(0) || (rhs <= std::numeric_limits<T>::max() / lhs)); 545 } 546 547 template <class SmallIntT, class BigIntT> 548 inline bool IsIntegerCastSafe(BigIntT bigValue) 549 { 550 return (static_cast<BigIntT>(static_cast<SmallIntT>(bigValue)) == bigValue); 551 } 552 553 } 554 555 #endif // LIBGLESV2_MATHUTIL_H_ 556