xref: /aosp_15_r20/external/swiftshader/src/System/Math.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #ifndef sw_Math_hpp
16*03ce13f7SAndroid Build Coastguard Worker #define sw_Math_hpp
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "Debug.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "Types.hpp"
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker #include <cmath>
22*03ce13f7SAndroid Build Coastguard Worker #if defined(_MSC_VER)
23*03ce13f7SAndroid Build Coastguard Worker #	include <intrin.h>
24*03ce13f7SAndroid Build Coastguard Worker #endif
25*03ce13f7SAndroid Build Coastguard Worker 
26*03ce13f7SAndroid Build Coastguard Worker namespace sw {
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker using std::abs;
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker #undef min
31*03ce13f7SAndroid Build Coastguard Worker #undef max
32*03ce13f7SAndroid Build Coastguard Worker 
33*03ce13f7SAndroid Build Coastguard Worker template<class T>
max(T a,T b)34*03ce13f7SAndroid Build Coastguard Worker inline T constexpr max(T a, T b)
35*03ce13f7SAndroid Build Coastguard Worker {
36*03ce13f7SAndroid Build Coastguard Worker 	return a > b ? a : b;
37*03ce13f7SAndroid Build Coastguard Worker }
38*03ce13f7SAndroid Build Coastguard Worker 
39*03ce13f7SAndroid Build Coastguard Worker template<class T>
min(T a,T b)40*03ce13f7SAndroid Build Coastguard Worker inline constexpr T min(T a, T b)
41*03ce13f7SAndroid Build Coastguard Worker {
42*03ce13f7SAndroid Build Coastguard Worker 	return a < b ? a : b;
43*03ce13f7SAndroid Build Coastguard Worker }
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker template<class T>
max(T a,T b,T c)46*03ce13f7SAndroid Build Coastguard Worker inline constexpr T max(T a, T b, T c)
47*03ce13f7SAndroid Build Coastguard Worker {
48*03ce13f7SAndroid Build Coastguard Worker 	return max(max(a, b), c);
49*03ce13f7SAndroid Build Coastguard Worker }
50*03ce13f7SAndroid Build Coastguard Worker 
51*03ce13f7SAndroid Build Coastguard Worker template<class T>
min(T a,T b,T c)52*03ce13f7SAndroid Build Coastguard Worker inline constexpr T min(T a, T b, T c)
53*03ce13f7SAndroid Build Coastguard Worker {
54*03ce13f7SAndroid Build Coastguard Worker 	return min(min(a, b), c);
55*03ce13f7SAndroid Build Coastguard Worker }
56*03ce13f7SAndroid Build Coastguard Worker 
57*03ce13f7SAndroid Build Coastguard Worker template<class T>
max(T a,T b,T c,T d)58*03ce13f7SAndroid Build Coastguard Worker inline constexpr T max(T a, T b, T c, T d)
59*03ce13f7SAndroid Build Coastguard Worker {
60*03ce13f7SAndroid Build Coastguard Worker 	return max(max(a, b), max(c, d));
61*03ce13f7SAndroid Build Coastguard Worker }
62*03ce13f7SAndroid Build Coastguard Worker 
63*03ce13f7SAndroid Build Coastguard Worker template<class T>
min(T a,T b,T c,T d)64*03ce13f7SAndroid Build Coastguard Worker inline constexpr T min(T a, T b, T c, T d)
65*03ce13f7SAndroid Build Coastguard Worker {
66*03ce13f7SAndroid Build Coastguard Worker 	return min(min(a, b), min(c, d));
67*03ce13f7SAndroid Build Coastguard Worker }
68*03ce13f7SAndroid Build Coastguard Worker 
69*03ce13f7SAndroid Build Coastguard Worker template<typename destType, typename sourceType>
bit_cast(const sourceType & source)70*03ce13f7SAndroid Build Coastguard Worker destType bit_cast(const sourceType &source)
71*03ce13f7SAndroid Build Coastguard Worker {
72*03ce13f7SAndroid Build Coastguard Worker 	union
73*03ce13f7SAndroid Build Coastguard Worker 	{
74*03ce13f7SAndroid Build Coastguard Worker 		sourceType s;
75*03ce13f7SAndroid Build Coastguard Worker 		destType d;
76*03ce13f7SAndroid Build Coastguard Worker 	} sd;
77*03ce13f7SAndroid Build Coastguard Worker 	sd.s = source;
78*03ce13f7SAndroid Build Coastguard Worker 	return sd.d;
79*03ce13f7SAndroid Build Coastguard Worker }
80*03ce13f7SAndroid Build Coastguard Worker 
iround(float x)81*03ce13f7SAndroid Build Coastguard Worker inline int iround(float x)
82*03ce13f7SAndroid Build Coastguard Worker {
83*03ce13f7SAndroid Build Coastguard Worker 	return (int)floor(x + 0.5f);
84*03ce13f7SAndroid Build Coastguard Worker 	//	return _mm_cvtss_si32(_mm_load_ss(&x));   // FIXME: Demands SSE support
85*03ce13f7SAndroid Build Coastguard Worker }
86*03ce13f7SAndroid Build Coastguard Worker 
ifloor(float x)87*03ce13f7SAndroid Build Coastguard Worker inline int ifloor(float x)
88*03ce13f7SAndroid Build Coastguard Worker {
89*03ce13f7SAndroid Build Coastguard Worker 	return (int)floor(x);
90*03ce13f7SAndroid Build Coastguard Worker }
91*03ce13f7SAndroid Build Coastguard Worker 
ceilFix4(int x)92*03ce13f7SAndroid Build Coastguard Worker inline int ceilFix4(int x)
93*03ce13f7SAndroid Build Coastguard Worker {
94*03ce13f7SAndroid Build Coastguard Worker 	return (x + 0xF) & 0xFFFFFFF0;
95*03ce13f7SAndroid Build Coastguard Worker }
96*03ce13f7SAndroid Build Coastguard Worker 
ceilInt4(int x)97*03ce13f7SAndroid Build Coastguard Worker inline int ceilInt4(int x)
98*03ce13f7SAndroid Build Coastguard Worker {
99*03ce13f7SAndroid Build Coastguard Worker 	return (x + 0xF) >> 4;
100*03ce13f7SAndroid Build Coastguard Worker }
101*03ce13f7SAndroid Build Coastguard Worker 
102*03ce13f7SAndroid Build Coastguard Worker #define BITS(x) (        \
103*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0x80000000) + \
104*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xC0000000) + \
105*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xE0000000) + \
106*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xF0000000) + \
107*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xF8000000) + \
108*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFC000000) + \
109*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFE000000) + \
110*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFF000000) + \
111*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFF800000) + \
112*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFC00000) + \
113*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFE00000) + \
114*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFF00000) + \
115*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFF80000) + \
116*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFC0000) + \
117*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFE0000) + \
118*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFF0000) + \
119*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFF8000) + \
120*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFC000) + \
121*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFE000) + \
122*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFF000) + \
123*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFF800) + \
124*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFC00) + \
125*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFE00) + \
126*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFF00) + \
127*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFF80) + \
128*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFC0) + \
129*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFE0) + \
130*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFF0) + \
131*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFF8) + \
132*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFFC) + \
133*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFFE) + \
134*03ce13f7SAndroid Build Coastguard Worker 	!!((x)&0xFFFFFFFF))
135*03ce13f7SAndroid Build Coastguard Worker 
log2i(int x)136*03ce13f7SAndroid Build Coastguard Worker inline unsigned long log2i(int x)
137*03ce13f7SAndroid Build Coastguard Worker {
138*03ce13f7SAndroid Build Coastguard Worker #if defined(_MSC_VER)
139*03ce13f7SAndroid Build Coastguard Worker 	unsigned long y;
140*03ce13f7SAndroid Build Coastguard Worker 	_BitScanReverse(&y, x);
141*03ce13f7SAndroid Build Coastguard Worker 	return y;
142*03ce13f7SAndroid Build Coastguard Worker #else
143*03ce13f7SAndroid Build Coastguard Worker 	return 31 - __builtin_clz(x);
144*03ce13f7SAndroid Build Coastguard Worker #endif
145*03ce13f7SAndroid Build Coastguard Worker }
146*03ce13f7SAndroid Build Coastguard Worker 
isPow2(int x)147*03ce13f7SAndroid Build Coastguard Worker inline bool isPow2(int x)
148*03ce13f7SAndroid Build Coastguard Worker {
149*03ce13f7SAndroid Build Coastguard Worker 	return (x & -x) == x;
150*03ce13f7SAndroid Build Coastguard Worker }
151*03ce13f7SAndroid Build Coastguard Worker 
152*03ce13f7SAndroid Build Coastguard Worker template<class T>
clamp(T x,T a,T b)153*03ce13f7SAndroid Build Coastguard Worker inline T clamp(T x, T a, T b)
154*03ce13f7SAndroid Build Coastguard Worker {
155*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(a <= b);
156*03ce13f7SAndroid Build Coastguard Worker 	if(x < a) x = a;
157*03ce13f7SAndroid Build Coastguard Worker 	if(x > b) x = b;
158*03ce13f7SAndroid Build Coastguard Worker 
159*03ce13f7SAndroid Build Coastguard Worker 	return x;
160*03ce13f7SAndroid Build Coastguard Worker }
161*03ce13f7SAndroid Build Coastguard Worker 
clamp01(float x)162*03ce13f7SAndroid Build Coastguard Worker inline float clamp01(float x)
163*03ce13f7SAndroid Build Coastguard Worker {
164*03ce13f7SAndroid Build Coastguard Worker 	return clamp(x, 0.0f, 1.0f);
165*03ce13f7SAndroid Build Coastguard Worker }
166*03ce13f7SAndroid Build Coastguard Worker 
167*03ce13f7SAndroid Build Coastguard Worker // Bit-cast of a floating-point value into a two's complement integer representation.
168*03ce13f7SAndroid Build Coastguard Worker // This makes floating-point values comparable as integers.
float_as_twos_complement(float f)169*03ce13f7SAndroid Build Coastguard Worker inline int32_t float_as_twos_complement(float f)
170*03ce13f7SAndroid Build Coastguard Worker {
171*03ce13f7SAndroid Build Coastguard Worker 	// IEEE-754 floating-point numbers are sorted by magnitude in the same way as integers,
172*03ce13f7SAndroid Build Coastguard Worker 	// except negative values are like one's complement integers. Convert them to two's complement.
173*03ce13f7SAndroid Build Coastguard Worker 	int32_t i = bit_cast<int32_t>(f);
174*03ce13f7SAndroid Build Coastguard Worker 	return (i < 0) ? (0x7FFFFFFFu - i) : i;
175*03ce13f7SAndroid Build Coastguard Worker }
176*03ce13f7SAndroid Build Coastguard Worker 
177*03ce13f7SAndroid Build Coastguard Worker // 'Safe' clamping operation which always returns a value between min and max (inclusive).
clamp_s(float x,float min,float max)178*03ce13f7SAndroid Build Coastguard Worker inline float clamp_s(float x, float min, float max)
179*03ce13f7SAndroid Build Coastguard Worker {
180*03ce13f7SAndroid Build Coastguard Worker 	// NaN values can't be compared directly
181*03ce13f7SAndroid Build Coastguard Worker 	if(float_as_twos_complement(x) < float_as_twos_complement(min)) x = min;
182*03ce13f7SAndroid Build Coastguard Worker 	if(float_as_twos_complement(x) > float_as_twos_complement(max)) x = max;
183*03ce13f7SAndroid Build Coastguard Worker 
184*03ce13f7SAndroid Build Coastguard Worker 	return x;
185*03ce13f7SAndroid Build Coastguard Worker }
186*03ce13f7SAndroid Build Coastguard Worker 
ceilPow2(int x)187*03ce13f7SAndroid Build Coastguard Worker inline int ceilPow2(int x)
188*03ce13f7SAndroid Build Coastguard Worker {
189*03ce13f7SAndroid Build Coastguard Worker 	int i = 1;
190*03ce13f7SAndroid Build Coastguard Worker 
191*03ce13f7SAndroid Build Coastguard Worker 	while(i < x)
192*03ce13f7SAndroid Build Coastguard Worker 	{
193*03ce13f7SAndroid Build Coastguard Worker 		i <<= 1;
194*03ce13f7SAndroid Build Coastguard Worker 	}
195*03ce13f7SAndroid Build Coastguard Worker 
196*03ce13f7SAndroid Build Coastguard Worker 	return i;
197*03ce13f7SAndroid Build Coastguard Worker }
198*03ce13f7SAndroid Build Coastguard Worker 
floorDiv(int a,int b)199*03ce13f7SAndroid Build Coastguard Worker inline int floorDiv(int a, int b)
200*03ce13f7SAndroid Build Coastguard Worker {
201*03ce13f7SAndroid Build Coastguard Worker 	return a / b + ((a % b) >> 31);
202*03ce13f7SAndroid Build Coastguard Worker }
203*03ce13f7SAndroid Build Coastguard Worker 
floorMod(int a,int b)204*03ce13f7SAndroid Build Coastguard Worker inline int floorMod(int a, int b)
205*03ce13f7SAndroid Build Coastguard Worker {
206*03ce13f7SAndroid Build Coastguard Worker 	int r = a % b;
207*03ce13f7SAndroid Build Coastguard Worker 	return r + ((r >> 31) & b);
208*03ce13f7SAndroid Build Coastguard Worker }
209*03ce13f7SAndroid Build Coastguard Worker 
ceilDiv(int a,int b)210*03ce13f7SAndroid Build Coastguard Worker inline int ceilDiv(int a, int b)
211*03ce13f7SAndroid Build Coastguard Worker {
212*03ce13f7SAndroid Build Coastguard Worker 	return a / b - (-(a % b) >> 31);
213*03ce13f7SAndroid Build Coastguard Worker }
214*03ce13f7SAndroid Build Coastguard Worker 
ceilMod(int a,int b)215*03ce13f7SAndroid Build Coastguard Worker inline int ceilMod(int a, int b)
216*03ce13f7SAndroid Build Coastguard Worker {
217*03ce13f7SAndroid Build Coastguard Worker 	int r = a % b;
218*03ce13f7SAndroid Build Coastguard Worker 	return r - ((-r >> 31) & b);
219*03ce13f7SAndroid Build Coastguard Worker }
220*03ce13f7SAndroid Build Coastguard Worker 
221*03ce13f7SAndroid Build Coastguard Worker template<const int n>
unorm(float x)222*03ce13f7SAndroid Build Coastguard Worker inline unsigned int unorm(float x)
223*03ce13f7SAndroid Build Coastguard Worker {
224*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int max = 0xFFFFFFFF >> (32 - n);
225*03ce13f7SAndroid Build Coastguard Worker 	static const float maxf = static_cast<float>(max);
226*03ce13f7SAndroid Build Coastguard Worker 
227*03ce13f7SAndroid Build Coastguard Worker 	if(x >= 1.0f)
228*03ce13f7SAndroid Build Coastguard Worker 	{
229*03ce13f7SAndroid Build Coastguard Worker 		return max;
230*03ce13f7SAndroid Build Coastguard Worker 	}
231*03ce13f7SAndroid Build Coastguard Worker 	else if(x <= 0.0f)
232*03ce13f7SAndroid Build Coastguard Worker 	{
233*03ce13f7SAndroid Build Coastguard Worker 		return 0;
234*03ce13f7SAndroid Build Coastguard Worker 	}
235*03ce13f7SAndroid Build Coastguard Worker 	else
236*03ce13f7SAndroid Build Coastguard Worker 	{
237*03ce13f7SAndroid Build Coastguard Worker 		return static_cast<unsigned int>(maxf * x + 0.5f);
238*03ce13f7SAndroid Build Coastguard Worker 	}
239*03ce13f7SAndroid Build Coastguard Worker }
240*03ce13f7SAndroid Build Coastguard Worker 
241*03ce13f7SAndroid Build Coastguard Worker template<const int n>
snorm(float x)242*03ce13f7SAndroid Build Coastguard Worker inline int snorm(float x)
243*03ce13f7SAndroid Build Coastguard Worker {
244*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int min = 0x80000000 >> (32 - n);
245*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
246*03ce13f7SAndroid Build Coastguard Worker 	static const float maxf = static_cast<float>(max);
247*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int range = 0xFFFFFFFF >> (32 - n);
248*03ce13f7SAndroid Build Coastguard Worker 
249*03ce13f7SAndroid Build Coastguard Worker 	if(x >= 0.0f)
250*03ce13f7SAndroid Build Coastguard Worker 	{
251*03ce13f7SAndroid Build Coastguard Worker 		if(x >= 1.0f)
252*03ce13f7SAndroid Build Coastguard Worker 		{
253*03ce13f7SAndroid Build Coastguard Worker 			return max;
254*03ce13f7SAndroid Build Coastguard Worker 		}
255*03ce13f7SAndroid Build Coastguard Worker 		else
256*03ce13f7SAndroid Build Coastguard Worker 		{
257*03ce13f7SAndroid Build Coastguard Worker 			return static_cast<int>(maxf * x + 0.5f);
258*03ce13f7SAndroid Build Coastguard Worker 		}
259*03ce13f7SAndroid Build Coastguard Worker 	}
260*03ce13f7SAndroid Build Coastguard Worker 	else
261*03ce13f7SAndroid Build Coastguard Worker 	{
262*03ce13f7SAndroid Build Coastguard Worker 		if(x <= -1.0f)
263*03ce13f7SAndroid Build Coastguard Worker 		{
264*03ce13f7SAndroid Build Coastguard Worker 			return min;
265*03ce13f7SAndroid Build Coastguard Worker 		}
266*03ce13f7SAndroid Build Coastguard Worker 		else
267*03ce13f7SAndroid Build Coastguard Worker 		{
268*03ce13f7SAndroid Build Coastguard Worker 			return static_cast<int>(maxf * x - 0.5f) & range;
269*03ce13f7SAndroid Build Coastguard Worker 		}
270*03ce13f7SAndroid Build Coastguard Worker 	}
271*03ce13f7SAndroid Build Coastguard Worker }
272*03ce13f7SAndroid Build Coastguard Worker 
273*03ce13f7SAndroid Build Coastguard Worker template<const int n>
ucast(float x)274*03ce13f7SAndroid Build Coastguard Worker inline unsigned int ucast(float x)
275*03ce13f7SAndroid Build Coastguard Worker {
276*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int max = 0xFFFFFFFF >> (32 - n);
277*03ce13f7SAndroid Build Coastguard Worker 	static const float maxf = static_cast<float>(max);
278*03ce13f7SAndroid Build Coastguard Worker 
279*03ce13f7SAndroid Build Coastguard Worker 	if(x >= maxf)
280*03ce13f7SAndroid Build Coastguard Worker 	{
281*03ce13f7SAndroid Build Coastguard Worker 		return max;
282*03ce13f7SAndroid Build Coastguard Worker 	}
283*03ce13f7SAndroid Build Coastguard Worker 	else if(x <= 0.0f)
284*03ce13f7SAndroid Build Coastguard Worker 	{
285*03ce13f7SAndroid Build Coastguard Worker 		return 0;
286*03ce13f7SAndroid Build Coastguard Worker 	}
287*03ce13f7SAndroid Build Coastguard Worker 	else
288*03ce13f7SAndroid Build Coastguard Worker 	{
289*03ce13f7SAndroid Build Coastguard Worker 		return static_cast<unsigned int>(x + 0.5f);
290*03ce13f7SAndroid Build Coastguard Worker 	}
291*03ce13f7SAndroid Build Coastguard Worker }
292*03ce13f7SAndroid Build Coastguard Worker 
293*03ce13f7SAndroid Build Coastguard Worker template<const int n>
scast(float x)294*03ce13f7SAndroid Build Coastguard Worker inline int scast(float x)
295*03ce13f7SAndroid Build Coastguard Worker {
296*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int min = 0x80000000 >> (32 - n);
297*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
298*03ce13f7SAndroid Build Coastguard Worker 	static const float maxf = static_cast<float>(max);
299*03ce13f7SAndroid Build Coastguard Worker 	static const float minf = static_cast<float>(min);
300*03ce13f7SAndroid Build Coastguard Worker 	static const unsigned int range = 0xFFFFFFFF >> (32 - n);
301*03ce13f7SAndroid Build Coastguard Worker 
302*03ce13f7SAndroid Build Coastguard Worker 	if(x > 0.0f)
303*03ce13f7SAndroid Build Coastguard Worker 	{
304*03ce13f7SAndroid Build Coastguard Worker 		if(x >= maxf)
305*03ce13f7SAndroid Build Coastguard Worker 		{
306*03ce13f7SAndroid Build Coastguard Worker 			return max;
307*03ce13f7SAndroid Build Coastguard Worker 		}
308*03ce13f7SAndroid Build Coastguard Worker 		else
309*03ce13f7SAndroid Build Coastguard Worker 		{
310*03ce13f7SAndroid Build Coastguard Worker 			return static_cast<int>(x + 0.5f);
311*03ce13f7SAndroid Build Coastguard Worker 		}
312*03ce13f7SAndroid Build Coastguard Worker 	}
313*03ce13f7SAndroid Build Coastguard Worker 	else
314*03ce13f7SAndroid Build Coastguard Worker 	{
315*03ce13f7SAndroid Build Coastguard Worker 		if(x <= -minf)
316*03ce13f7SAndroid Build Coastguard Worker 		{
317*03ce13f7SAndroid Build Coastguard Worker 			return min;
318*03ce13f7SAndroid Build Coastguard Worker 		}
319*03ce13f7SAndroid Build Coastguard Worker 		else
320*03ce13f7SAndroid Build Coastguard Worker 		{
321*03ce13f7SAndroid Build Coastguard Worker 			return static_cast<int>(x - 0.5f) & range;
322*03ce13f7SAndroid Build Coastguard Worker 		}
323*03ce13f7SAndroid Build Coastguard Worker 	}
324*03ce13f7SAndroid Build Coastguard Worker }
325*03ce13f7SAndroid Build Coastguard Worker 
sRGBtoLinear(float c)326*03ce13f7SAndroid Build Coastguard Worker inline float sRGBtoLinear(float c)
327*03ce13f7SAndroid Build Coastguard Worker {
328*03ce13f7SAndroid Build Coastguard Worker 	if(c <= 0.04045f)
329*03ce13f7SAndroid Build Coastguard Worker 	{
330*03ce13f7SAndroid Build Coastguard Worker 		return c / 12.92f;
331*03ce13f7SAndroid Build Coastguard Worker 	}
332*03ce13f7SAndroid Build Coastguard Worker 	else
333*03ce13f7SAndroid Build Coastguard Worker 	{
334*03ce13f7SAndroid Build Coastguard Worker 		return powf((c + 0.055f) / 1.055f, 2.4f);
335*03ce13f7SAndroid Build Coastguard Worker 	}
336*03ce13f7SAndroid Build Coastguard Worker }
337*03ce13f7SAndroid Build Coastguard Worker 
linearToSRGB(float c)338*03ce13f7SAndroid Build Coastguard Worker inline float linearToSRGB(float c)
339*03ce13f7SAndroid Build Coastguard Worker {
340*03ce13f7SAndroid Build Coastguard Worker 	if(c <= 0.0031308f)
341*03ce13f7SAndroid Build Coastguard Worker 	{
342*03ce13f7SAndroid Build Coastguard Worker 		return c * 12.92f;
343*03ce13f7SAndroid Build Coastguard Worker 	}
344*03ce13f7SAndroid Build Coastguard Worker 	else
345*03ce13f7SAndroid Build Coastguard Worker 	{
346*03ce13f7SAndroid Build Coastguard Worker 		return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
347*03ce13f7SAndroid Build Coastguard Worker 	}
348*03ce13f7SAndroid Build Coastguard Worker }
349*03ce13f7SAndroid Build Coastguard Worker 
350*03ce13f7SAndroid Build Coastguard Worker unsigned char sRGB8toLinear8(unsigned char value);
351*03ce13f7SAndroid Build Coastguard Worker 
352*03ce13f7SAndroid Build Coastguard Worker uint64_t FNV_1a(const unsigned char *data, int size);  // Fowler-Noll-Vo hash function
353*03ce13f7SAndroid Build Coastguard Worker 
354*03ce13f7SAndroid Build Coastguard Worker // Round up to the next multiple of alignment
355*03ce13f7SAndroid Build Coastguard Worker template<typename T>
align(T value,unsigned int alignment)356*03ce13f7SAndroid Build Coastguard Worker inline T align(T value, unsigned int alignment)
357*03ce13f7SAndroid Build Coastguard Worker {
358*03ce13f7SAndroid Build Coastguard Worker 	return ((value + alignment - 1) / alignment) * alignment;
359*03ce13f7SAndroid Build Coastguard Worker }
360*03ce13f7SAndroid Build Coastguard Worker 
361*03ce13f7SAndroid Build Coastguard Worker template<unsigned int alignment, typename T>
align(T value)362*03ce13f7SAndroid Build Coastguard Worker inline T align(T value)
363*03ce13f7SAndroid Build Coastguard Worker {
364*03ce13f7SAndroid Build Coastguard Worker 	return ((value + alignment - 1) / alignment) * alignment;
365*03ce13f7SAndroid Build Coastguard Worker }
366*03ce13f7SAndroid Build Coastguard Worker 
clampToSignedInt(unsigned int x)367*03ce13f7SAndroid Build Coastguard Worker inline int clampToSignedInt(unsigned int x)
368*03ce13f7SAndroid Build Coastguard Worker {
369*03ce13f7SAndroid Build Coastguard Worker 	return static_cast<int>(min(x, 0x7FFFFFFFu));
370*03ce13f7SAndroid Build Coastguard Worker }
371*03ce13f7SAndroid Build Coastguard Worker 
372*03ce13f7SAndroid Build Coastguard Worker // Convert floating value v to fixed point with p digits after the decimal point
toFixedPoint(float v,int p)373*03ce13f7SAndroid Build Coastguard Worker inline constexpr int toFixedPoint(float v, int p)
374*03ce13f7SAndroid Build Coastguard Worker {
375*03ce13f7SAndroid Build Coastguard Worker 	return static_cast<int>(v * (1 << p));
376*03ce13f7SAndroid Build Coastguard Worker }
377*03ce13f7SAndroid Build Coastguard Worker 
378*03ce13f7SAndroid Build Coastguard Worker // Returns the next floating-point number which is not treated identical to the input.
379*03ce13f7SAndroid Build Coastguard Worker // Note that std::nextafter() does not skip representations flushed to zero.
inc(float x)380*03ce13f7SAndroid Build Coastguard Worker [[nodiscard]] inline float inc(float x)
381*03ce13f7SAndroid Build Coastguard Worker {
382*03ce13f7SAndroid Build Coastguard Worker 	int x1 = bit_cast<int>(x);
383*03ce13f7SAndroid Build Coastguard Worker 
384*03ce13f7SAndroid Build Coastguard Worker 	while(bit_cast<float>(x1) == x)
385*03ce13f7SAndroid Build Coastguard Worker 	{
386*03ce13f7SAndroid Build Coastguard Worker 		// Since IEEE 754 uses ones' complement and integers are two's complement,
387*03ce13f7SAndroid Build Coastguard Worker 		// we need to explicitly hop from negative zero to positive zero.
388*03ce13f7SAndroid Build Coastguard Worker 		if(x1 == (int)0x80000000)  // -0.0f
389*03ce13f7SAndroid Build Coastguard Worker 		{
390*03ce13f7SAndroid Build Coastguard Worker 			// Note that while the comparison -0.0f == +0.0f returns true, this
391*03ce13f7SAndroid Build Coastguard Worker 			// function returns the next value which can be treated differently.
392*03ce13f7SAndroid Build Coastguard Worker 			return +0.0f;
393*03ce13f7SAndroid Build Coastguard Worker 		}
394*03ce13f7SAndroid Build Coastguard Worker 
395*03ce13f7SAndroid Build Coastguard Worker 		// Negative ones' complement value are made less negative by subtracting 1
396*03ce13f7SAndroid Build Coastguard Worker 		// in two's complement representation.
397*03ce13f7SAndroid Build Coastguard Worker 		x1 += (x1 >= 0) ? 1 : -1;
398*03ce13f7SAndroid Build Coastguard Worker 	}
399*03ce13f7SAndroid Build Coastguard Worker 
400*03ce13f7SAndroid Build Coastguard Worker 	float y = bit_cast<float>(x1);
401*03ce13f7SAndroid Build Coastguard Worker 
402*03ce13f7SAndroid Build Coastguard Worker 	// If we have a value which compares equal to 0.0, return 0.0. This ensures
403*03ce13f7SAndroid Build Coastguard Worker 	// subnormal values get flushed to zero when denormals-are-zero is enabled.
404*03ce13f7SAndroid Build Coastguard Worker 	return (y == 0.0f) ? +0.0f : y;
405*03ce13f7SAndroid Build Coastguard Worker }
406*03ce13f7SAndroid Build Coastguard Worker 
compactEvenBits(uint32_t x)407*03ce13f7SAndroid Build Coastguard Worker inline uint16_t compactEvenBits(uint32_t x)
408*03ce13f7SAndroid Build Coastguard Worker {
409*03ce13f7SAndroid Build Coastguard Worker 	x &= 0x55555555;                  // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
410*03ce13f7SAndroid Build Coastguard Worker 	x = (x ^ (x >> 1)) & 0x33333333;  // x = --fe --dc --ba --98 --76 --54 --32 --10
411*03ce13f7SAndroid Build Coastguard Worker 	x = (x ^ (x >> 2)) & 0x0F0F0F0F;  // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
412*03ce13f7SAndroid Build Coastguard Worker 	x = (x ^ (x >> 4)) & 0x00FF00FF;  // x = ---- ---- fedc ba98 ---- ---- 7654 3210
413*03ce13f7SAndroid Build Coastguard Worker 	x = (x ^ (x >> 8)) & 0x0000FFFF;  // x = ---- ---- ---- ---- fedc ba98 7654 3210
414*03ce13f7SAndroid Build Coastguard Worker 
415*03ce13f7SAndroid Build Coastguard Worker 	return static_cast<uint16_t>(x);
416*03ce13f7SAndroid Build Coastguard Worker }
417*03ce13f7SAndroid Build Coastguard Worker 
418*03ce13f7SAndroid Build Coastguard Worker }  // namespace sw
419*03ce13f7SAndroid Build Coastguard Worker 
420*03ce13f7SAndroid Build Coastguard Worker #endif  // sw_Math_hpp
421