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
19namespace gl
20{
21
22const unsigned int Float32One = 0x3F800000;
23const unsigned short Float16One = 0x3C00;
24
25struct 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
36inline bool isPow2(int x)
37{
38    return (x & (x - 1)) == 0 && (x != 0);
39}
40
41inline int log2(int x)
42{
43    int r = 0;
44    while ((x >> r) > 1) r++;
45    return r;
46}
47
48inline 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
61inline 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
66template <typename DestT, typename SrcT>
67inline 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
79template<typename T, typename MIN, typename MAX>
80inline 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
86inline float clamp01(float x)
87{
88    return clamp(x, 0.0f, 1.0f);
89}
90
91template<const int n>
92inline 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
110inline 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
140template <typename destType, typename sourceType>
141destType 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
149inline 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
181float float16ToFloat32(unsigned short h);
182
183unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
184void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);
185
186inline 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
255inline 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
324inline 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
363inline 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
402template <typename T>
403inline 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
411template <unsigned int inputBitCount, typename T>
412inline 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
421template <typename T>
422inline T floatToNormalized(float input)
423{
424    return std::numeric_limits<T>::max() * input + 0.5f;
425}
426
427template <unsigned int outputBitCount, typename T>
428inline T floatToNormalized(float input)
429{
430    META_ASSERT(outputBitCount < (sizeof(T) * 8));
431    return ((1 << outputBitCount) - 1) * input + 0.5f;
432}
433
434template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
435inline 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
442template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
443inline 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
451inline unsigned char average(unsigned char a, unsigned char b)
452{
453    return ((a ^ b) >> 1) + (a & b);
454}
455
456inline signed char average(signed char a, signed char b)
457{
458    return ((short)a + (short)b) / 2;
459}
460
461inline unsigned short average(unsigned short a, unsigned short b)
462{
463    return ((a ^ b) >> 1) + (a & b);
464}
465
466inline signed short average(signed short a, signed short b)
467{
468    return ((int)a + (int)b) / 2;
469}
470
471inline unsigned int average(unsigned int a, unsigned int b)
472{
473    return ((a ^ b) >> 1) + (a & b);
474}
475
476inline signed int average(signed int a, signed int b)
477{
478    return ((long long)a + (long long)b) / 2;
479}
480
481inline float average(float a, float b)
482{
483    return (a + b) * 0.5f;
484}
485
486inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
487{
488    return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
489}
490
491inline unsigned int averageFloat11(unsigned int a, unsigned int b)
492{
493    return float32ToFloat11((float11ToFloat32(a) + float11ToFloat32(b)) * 0.5f);
494}
495
496inline unsigned int averageFloat10(unsigned int a, unsigned int b)
497{
498    return float32ToFloat10((float10ToFloat32(a) + float10ToFloat32(b)) * 0.5f);
499}
500
501}
502
503namespace rx
504{
505
506template <typename T>
507struct 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
518typedef Range<int> RangeI;
519typedef Range<unsigned int> RangeUI;
520
521template <typename T>
522T roundUp(const T value, const T alignment)
523{
524    return value + alignment - 1 - (value - 1) % alignment;
525}
526
527inline 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
533template <class T>
534inline 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
540template <class T>
541inline 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
547template <class SmallIntT, class BigIntT>
548inline 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