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_
|