1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//
3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License.
5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at
6d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//
7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
8d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//
9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software
10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and
13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License.
14d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
15d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#ifndef sw_Math_hpp
16d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#define sw_Math_hpp
17d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
18d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#include "Types.hpp"
19d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
20d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#include <cmath>
21d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#if defined(_MSC_VER)
22d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	#include <intrin.h>
23d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#endif
24d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
25d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capensnamespace sw
26d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens{
27d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	using std::abs;
28d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
29d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	#undef min
30d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	#undef max
31d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
32d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
33d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T max(T a, T b)
34d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
35d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return a > b ? a : b;
36d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
37d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
38d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
39d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T min(T a, T b)
40d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
41d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return a < b ? a : b;
42d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
43d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
44d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
45d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T max(T a, T b, T c)
46d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
47d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return max(max(a, b), c);
48d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
49d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
50d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
51d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T min(T a, T b, T c)
52d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
53d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return min(min(a, b), c);
54d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
55d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
56d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
57d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T max(T a, T b, T c, T d)
58d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
59d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return max(max(a, b), max(c, d));
60d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
61d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
62d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
63d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T min(T a, T b, T c, T d)
64d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
65d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return min(min(a, b), min(c, d));
66d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
67d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
68d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
69d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline void swap(T &a, T &b)
70d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
71d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		T t = a;
72d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		a = b;
73d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		b = t;
74d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
75d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
76d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int iround(float x)
77d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
78d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return (int)floor(x + 0.5f);
79d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	//	return _mm_cvtss_si32(_mm_load_ss(&x));   // FIXME: Demands SSE support
80d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
81d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
82d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ifloor(float x)
83d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
84d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return (int)floor(x);
85d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
86d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
87d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ceilFix4(int x)
88d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
89d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return (x + 0xF) & 0xFFFFFFF0;
90d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
91d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
92d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ceilInt4(int x)
93d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
94d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return (x + 0xF) >> 4;
95d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
96d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
97d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	#define BITS(x)    ( \
98d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0x80000000) + \
99d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xC0000000) + \
100d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xE0000000) + \
101d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xF0000000) + \
102d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xF8000000) + \
103d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFC000000) + \
104d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFE000000) + \
105d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFF000000) + \
106d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFF800000) + \
107d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFC00000) + \
108d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFE00000) + \
109d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFF00000) + \
110d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFF80000) + \
111d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFC0000) + \
112d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFE0000) + \
113d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFF0000) + \
114d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFF8000) + \
115d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFC000) + \
116d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFE000) + \
117d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFF000) + \
118d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFF800) + \
119d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFC00) + \
120d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFE00) + \
121d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFF00) + \
122d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFF80) + \
123d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFC0) + \
124d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFE0) + \
125d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFF0) + \
126d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFF8) + \
127d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFFC) + \
128d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFFE) + \
129d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	!!((x) & 0xFFFFFFFF))
130d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
131d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	#define MAX(x, y) ((x) > (y) ? (x) : (y))
132d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	#define MIN(x, y) ((x) < (y) ? (x) : (y))
133d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
134d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline float exp2(float x)
135d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
136d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return exp2f(x);
137d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
138d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
139d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int exp2(int x)
140d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
141d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return 1 << x;
142d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
143d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
144d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline unsigned long log2(int x)
145d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
146d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		#if defined(_MSC_VER)
147d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned long y;
148d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			_BitScanReverse(&y, x);
149d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return y;
150d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		#else
151d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return 31 - __builtin_clz(x);
152d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		#endif
153d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
154d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
155d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ilog2(float x)
156d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
157d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int y = *(unsigned int*)&x;
158d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
159d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return ((y & 0x7F800000) >> 23) - 127;
160d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
161d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
162d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline float log2(float x)
163d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
164d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return logf(x) * 1.44269504f;   // 1.0 / log[e](2)
165d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
166d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
167d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline bool isPow2(int x)
168d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
169d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return (x & -x) == x;
170d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
171d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
172d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<class T>
173d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline T clamp(T x, T a, T b)
174d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
175d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(x < a) x = a;
176d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(x > b) x = b;
177d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
178d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return x;
179d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
180d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
181d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline float clamp01(float x)
182d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
183d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return clamp(x, 0.0f, 1.0f);
184d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
185d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
186d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ceilPow2(int x)
187d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
188d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		int i = 1;
189d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
190d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		while(i < x)
191d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
192d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			i <<= 1;
193d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
194d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
195d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return i;
196d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
197d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
198d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int floorDiv(int a, int b)
199d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
200d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return a / b + ((a % b) >> 31);
201d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
202d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
203d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int floorMod(int a, int b)
204d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
205d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		int r = a % b;
206d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return r + ((r >> 31) & b);
207d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
208d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
209d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ceilDiv(int a, int b)
210d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
211d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return a / b - (-(a % b) >> 31);
212d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
213d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
214d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int ceilMod(int a, int b)
215d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
216d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		int r = a % b;
217d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return r - ((-r >> 31) & b);
218d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
219d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
220d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<const int n>
221d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline unsigned int unorm(float x)
222d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
223d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int max = 0xFFFFFFFF >> (32 - n);
224d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const float maxf = static_cast<float>(max);
225d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
226d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(x >= 1.0f)
227d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
228d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return max;
229d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
230d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else if(x <= 0.0f)
231d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
232d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return 0;
233d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
234d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else
235d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
236d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return static_cast<unsigned int>(maxf * x + 0.5f);
237d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
238d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
239d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
240d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<const int n>
241d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int snorm(float x)
242d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
243d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int min = 0x80000000 >> (32 - n);
244d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
245d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const float maxf = static_cast<float>(max);
246d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int range = 0xFFFFFFFF >> (32 - n);
247d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
248d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(x >= 0.0f)
249d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
250d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			if(x >= 1.0f)
251d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
252d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return max;
253d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
254d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			else
255d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
256d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return static_cast<int>(maxf * x + 0.5f);
257d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
258d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
259d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else
260d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
261d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			if(x <= -1.0f)
262d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
263d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return min;
264d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
265d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			else
266d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
267d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return static_cast<int>(maxf * x - 0.5f) & range;
268d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
269d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
270d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
271d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
272d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<const int n>
273d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline unsigned int ucast(float x)
274d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
275d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int max = 0xFFFFFFFF >> (32 - n);
276d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const float maxf = static_cast<float>(max);
277d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
278d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(x >= maxf)
279d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
280d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return max;
281d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
282d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else if(x <= 0.0f)
283d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
284d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return 0;
285d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
286d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else
287d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
288d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return static_cast<unsigned int>(x + 0.5f);
289d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
290d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
291d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
292d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	template<const int n>
293d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int scast(float x)
294d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
295d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int min = 0x80000000 >> (32 - n);
296d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
297d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const float maxf = static_cast<float>(max);
298d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static const unsigned int range = 0xFFFFFFFF >> (32 - n);
299d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
300d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(x > 0.0f)
301d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
302d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			if(x >= maxf)
303d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
304d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return max;
305d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
306d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			else
307d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
308d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return static_cast<int>(maxf * x + 0.5f);
309d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
310d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
311d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else
312d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
313d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			if(x <= -1.0f)
314d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
315d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return min;
316d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
317d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			else
318d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
319d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				return static_cast<int>(maxf * x - 0.5f) & range;
320d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
321d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
322d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
323d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
324d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline float sRGBtoLinear(float c)
325d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
326d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(c <= 0.04045f)
327d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
328d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return c * 0.07739938f;   // 1.0f / 12.92f;
329d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
330d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else
331d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
332d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return powf((c + 0.055f) * 0.9478673f, 2.4f);   // 1.0f / 1.055f
333d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
334d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
335d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
336d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline float linearToSRGB(float c)
337d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
338d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		if(c <= 0.0031308f)
339d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
340d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return c * 12.92f;
341d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
342d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		else
343d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
344d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return 1.055f * powf(c, 0.4166667f) - 0.055f;   // 1.0f / 2.4f
345d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
346d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
347d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
348d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	unsigned char sRGB8toLinear8(unsigned char value);
349d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
350d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	uint64_t FNV_1a(const unsigned char *data, int size);   // Fowler-Noll-Vo hash function
351d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
352d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	// Round up to the next multiple of alignment
353d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline unsigned int align(unsigned int value, unsigned int alignment)
354d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
355d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return ((value + alignment - 1) / alignment) * alignment;
356d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
357d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
358d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	inline int clampToSignedInt(unsigned int x)
359d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
360d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		return static_cast<int>(min(x, 0x7FFFFFFFu));
361d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	}
362d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
363d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	class RGB9E5Data
364d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
365d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int R : 9;
366d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int G : 9;
367d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int B : 9;
368d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int E : 5;
369d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
370d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	public:
371d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		void toRGBFloats(float* rgb) const
372d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
373d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			static const float Offset = -24.0f; // Exponent Bias (15) + Number of mantissa bits per component (9) = 24
374d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
375d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			const float factor = powf(2.0f, static_cast<float>(E) + Offset);
376d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			rgb[0] = static_cast<float>(R) * factor;
377d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			rgb[1] = static_cast<float>(G) * factor;
378d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			rgb[2] = static_cast<float>(B) * factor;
379d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
380d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	};
381d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
382d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	class R11G11B10FData
383d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	{
384d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int R : 11;
385d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int G : 11;
386d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		unsigned int B : 10;
387d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
388d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static inline float float11ToFloat32(unsigned short fp11)
389d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
390d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned short exponent = (fp11 >> 6) & 0x1F;
391d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned short mantissa = fp11 & 0x3F;
392d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
393d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned int output;
394d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			if(exponent == 0x1F)
395d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
396d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				// INF or NAN
397d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				output = 0x7f800000 | (mantissa << 17);
398d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
399d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			else
400d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
401d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				if(exponent != 0)
402d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				{
403d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					// normalized
404d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				}
405d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				else if(mantissa != 0)
406d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				{
407d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					// The value is denormalized
408d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					exponent = 1;
409d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
410d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					do
411d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					{
412d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens						exponent--;
413d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens						mantissa <<= 1;
414d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					} while((mantissa & 0x40) == 0);
415d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
416d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					mantissa = mantissa & 0x3F;
417d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				}
418d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				else // The value is zero
419d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				{
420d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					exponent = static_cast<unsigned short>(-112);
421d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				}
422d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
423d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				output = ((exponent + 112) << 23) | (mantissa << 17);
424d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
425d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
426d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return *(float*)(&output);
427d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
428d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
429d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		static inline float float10ToFloat32(unsigned short fp10)
430d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
431d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned short exponent = (fp10 >> 5) & 0x1F;
432d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned short mantissa = fp10 & 0x1F;
433d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
434d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			unsigned int output;
435d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			if(exponent == 0x1F)
436d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
437d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				// INF or NAN
438d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				output = 0x7f800000 | (mantissa << 17);
439d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
440d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			else
441d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			{
442d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				if(exponent != 0)
443d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				{
444d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					// normalized
445d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				}
446d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				else if(mantissa != 0)
447d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				{
448d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					// The value is denormalized
449d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					exponent = 1;
450d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
451d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					do
452d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					{
453d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens						exponent--;
454d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens						mantissa <<= 1;
455d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					} while((mantissa & 0x20) == 0);
456d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
457d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					mantissa = mantissa & 0x1F;
458d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				}
459d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				else // The value is zero
460d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				{
461d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens					exponent = static_cast<unsigned short>(-112);
462d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				}
463d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
464d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens				output = ((exponent + 112) << 23) | (mantissa << 18);
465d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			}
466d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
467d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			return *(float*)(&output);
468d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
469d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
470d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	public:
471d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		void toRGBFloats(float* rgb) const
472d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		{
473d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			rgb[0] = float11ToFloat32(R);
474d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			rgb[1] = float11ToFloat32(G);
475d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			rgb[2] = float10ToFloat32(B);
476d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens		}
477d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens	};
478d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens}
479d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
480d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens#endif   // sw_Math_hpp
481