1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // mathutil.h: Math and bit manipulation functions.
16 
17 #ifndef LIBGLESV2_MATHUTIL_H_
18 #define LIBGLESV2_MATHUTIL_H_
19 
20 #include "common/debug.h"
21 #include "Common/Math.hpp"
22 
23 namespace es2
24 {
isPow2(int x)25 inline bool isPow2(int x)
26 {
27 	return (x & (x - 1)) == 0 && (x != 0);
28 }
29 
log2(int x)30 inline int log2(int x)
31 {
32 	int r = 0;
33 	while((x >> r) > 1) r++;
34 	return r;
35 }
36 
ceilPow2(unsigned int x)37 inline unsigned int ceilPow2(unsigned int x)
38 {
39 	if(x != 0) x--;
40 	x |= x >> 1;
41 	x |= x >> 2;
42 	x |= x >> 4;
43 	x |= x >> 8;
44 	x |= x >> 16;
45 	x++;
46 
47 	return x;
48 }
49 
50 using sw::swap;
51 using sw::clamp;
52 using sw::clamp01;
53 
54 template<const int n>
unorm(float x)55 inline unsigned int unorm(float x)
56 {
57 	const unsigned int max = 0xFFFFFFFF >> (32 - n);
58 
59 	if(x > 1)
60 	{
61 		return max;
62 	}
63 	else if(x < 0)
64 	{
65 		return 0;
66 	}
67 	else
68 	{
69 		return (unsigned int)(max * x + 0.5f);
70 	}
71 }
72 
73 // Converts floating-point values to the nearest representable integer
convert_float_int(float x)74 inline int convert_float_int(float x)
75 {
76 	// The largest positive integer value that is exactly representable in IEEE 754 binary32 is 0x7FFFFF80.
77 	// The next floating-point value is 128 larger and thus needs clamping to 0x7FFFFFFF.
78 	static_assert(std::numeric_limits<float>::is_iec559, "Unsupported floating-point format");
79 
80 	if(x > 0x7FFFFF80)
81 	{
82 		return 0x7FFFFFFF;
83 	}
84 
85 	if(x < (signed)0x80000000)
86 	{
87 		return 0x80000000;
88 	}
89 
90 	return static_cast<int>(roundf(x));
91 }
92 }
93 
94 #endif   // LIBGLESV2_MATHUTIL_H_
95