1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker *
3*bbecb9d1SAndroid Build Coastguard Worker * Copyright 2008 VMware, Inc.
4*bbecb9d1SAndroid Build Coastguard Worker * All Rights Reserved.
5*bbecb9d1SAndroid Build Coastguard Worker *
6*bbecb9d1SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*bbecb9d1SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
8*bbecb9d1SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
9*bbecb9d1SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
10*bbecb9d1SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
11*bbecb9d1SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
12*bbecb9d1SAndroid Build Coastguard Worker * the following conditions:
13*bbecb9d1SAndroid Build Coastguard Worker *
14*bbecb9d1SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
15*bbecb9d1SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
16*bbecb9d1SAndroid Build Coastguard Worker * of the Software.
17*bbecb9d1SAndroid Build Coastguard Worker *
18*bbecb9d1SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19*bbecb9d1SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*bbecb9d1SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21*bbecb9d1SAndroid Build Coastguard Worker * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22*bbecb9d1SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23*bbecb9d1SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24*bbecb9d1SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*bbecb9d1SAndroid Build Coastguard Worker *
26*bbecb9d1SAndroid Build Coastguard Worker **************************************************************************/
27*bbecb9d1SAndroid Build Coastguard Worker
28*bbecb9d1SAndroid Build Coastguard Worker
29*bbecb9d1SAndroid Build Coastguard Worker /**
30*bbecb9d1SAndroid Build Coastguard Worker * Math utilities and approximations for common math functions.
31*bbecb9d1SAndroid Build Coastguard Worker * Reduced precision is usually acceptable in shaders...
32*bbecb9d1SAndroid Build Coastguard Worker *
33*bbecb9d1SAndroid Build Coastguard Worker * "fast" is used in the names of functions which are low-precision,
34*bbecb9d1SAndroid Build Coastguard Worker * or at least lower-precision than the normal C lib functions.
35*bbecb9d1SAndroid Build Coastguard Worker */
36*bbecb9d1SAndroid Build Coastguard Worker
37*bbecb9d1SAndroid Build Coastguard Worker
38*bbecb9d1SAndroid Build Coastguard Worker #ifndef U_MATH_H
39*bbecb9d1SAndroid Build Coastguard Worker #define U_MATH_H
40*bbecb9d1SAndroid Build Coastguard Worker
41*bbecb9d1SAndroid Build Coastguard Worker
42*bbecb9d1SAndroid Build Coastguard Worker #include "c99_math.h"
43*bbecb9d1SAndroid Build Coastguard Worker #include <assert.h>
44*bbecb9d1SAndroid Build Coastguard Worker #include <float.h>
45*bbecb9d1SAndroid Build Coastguard Worker #include <stdarg.h>
46*bbecb9d1SAndroid Build Coastguard Worker
47*bbecb9d1SAndroid Build Coastguard Worker #include "bitscan.h"
48*bbecb9d1SAndroid Build Coastguard Worker #include "u_endian.h" /* for UTIL_ARCH_BIG_ENDIAN */
49*bbecb9d1SAndroid Build Coastguard Worker
50*bbecb9d1SAndroid Build Coastguard Worker #ifdef __cplusplus
51*bbecb9d1SAndroid Build Coastguard Worker extern "C" {
52*bbecb9d1SAndroid Build Coastguard Worker #endif
53*bbecb9d1SAndroid Build Coastguard Worker
54*bbecb9d1SAndroid Build Coastguard Worker
55*bbecb9d1SAndroid Build Coastguard Worker #ifndef M_SQRT2
56*bbecb9d1SAndroid Build Coastguard Worker #define M_SQRT2 1.41421356237309504880
57*bbecb9d1SAndroid Build Coastguard Worker #endif
58*bbecb9d1SAndroid Build Coastguard Worker
59*bbecb9d1SAndroid Build Coastguard Worker
60*bbecb9d1SAndroid Build Coastguard Worker /**
61*bbecb9d1SAndroid Build Coastguard Worker * Initialize math module. This should be called before using any
62*bbecb9d1SAndroid Build Coastguard Worker * other functions in this module.
63*bbecb9d1SAndroid Build Coastguard Worker */
64*bbecb9d1SAndroid Build Coastguard Worker extern void
65*bbecb9d1SAndroid Build Coastguard Worker util_init_math(void);
66*bbecb9d1SAndroid Build Coastguard Worker
67*bbecb9d1SAndroid Build Coastguard Worker
68*bbecb9d1SAndroid Build Coastguard Worker union fi {
69*bbecb9d1SAndroid Build Coastguard Worker float f;
70*bbecb9d1SAndroid Build Coastguard Worker int32_t i;
71*bbecb9d1SAndroid Build Coastguard Worker uint32_t ui;
72*bbecb9d1SAndroid Build Coastguard Worker };
73*bbecb9d1SAndroid Build Coastguard Worker
74*bbecb9d1SAndroid Build Coastguard Worker
75*bbecb9d1SAndroid Build Coastguard Worker union di {
76*bbecb9d1SAndroid Build Coastguard Worker double d;
77*bbecb9d1SAndroid Build Coastguard Worker int64_t i;
78*bbecb9d1SAndroid Build Coastguard Worker uint64_t ui;
79*bbecb9d1SAndroid Build Coastguard Worker };
80*bbecb9d1SAndroid Build Coastguard Worker
81*bbecb9d1SAndroid Build Coastguard Worker
82*bbecb9d1SAndroid Build Coastguard Worker /**
83*bbecb9d1SAndroid Build Coastguard Worker * Extract the IEEE float32 exponent.
84*bbecb9d1SAndroid Build Coastguard Worker */
85*bbecb9d1SAndroid Build Coastguard Worker static inline signed
util_get_float32_exponent(float x)86*bbecb9d1SAndroid Build Coastguard Worker util_get_float32_exponent(float x)
87*bbecb9d1SAndroid Build Coastguard Worker {
88*bbecb9d1SAndroid Build Coastguard Worker union fi f;
89*bbecb9d1SAndroid Build Coastguard Worker
90*bbecb9d1SAndroid Build Coastguard Worker f.f = x;
91*bbecb9d1SAndroid Build Coastguard Worker
92*bbecb9d1SAndroid Build Coastguard Worker return ((f.ui >> 23) & 0xff) - 127;
93*bbecb9d1SAndroid Build Coastguard Worker }
94*bbecb9d1SAndroid Build Coastguard Worker
95*bbecb9d1SAndroid Build Coastguard Worker
96*bbecb9d1SAndroid Build Coastguard Worker #define LOG2_TABLE_SIZE_LOG2 8
97*bbecb9d1SAndroid Build Coastguard Worker #define LOG2_TABLE_SCALE (1 << LOG2_TABLE_SIZE_LOG2)
98*bbecb9d1SAndroid Build Coastguard Worker #define LOG2_TABLE_SIZE (LOG2_TABLE_SCALE + 1)
99*bbecb9d1SAndroid Build Coastguard Worker extern float log2_table[LOG2_TABLE_SIZE];
100*bbecb9d1SAndroid Build Coastguard Worker
101*bbecb9d1SAndroid Build Coastguard Worker
102*bbecb9d1SAndroid Build Coastguard Worker /**
103*bbecb9d1SAndroid Build Coastguard Worker * Fast approximation to log2(x).
104*bbecb9d1SAndroid Build Coastguard Worker */
105*bbecb9d1SAndroid Build Coastguard Worker static inline float
util_fast_log2(float x)106*bbecb9d1SAndroid Build Coastguard Worker util_fast_log2(float x)
107*bbecb9d1SAndroid Build Coastguard Worker {
108*bbecb9d1SAndroid Build Coastguard Worker union fi num;
109*bbecb9d1SAndroid Build Coastguard Worker float epart, mpart;
110*bbecb9d1SAndroid Build Coastguard Worker num.f = x;
111*bbecb9d1SAndroid Build Coastguard Worker epart = (float)(((num.i & 0x7f800000) >> 23) - 127);
112*bbecb9d1SAndroid Build Coastguard Worker /* mpart = log2_table[mantissa*LOG2_TABLE_SCALE + 0.5] */
113*bbecb9d1SAndroid Build Coastguard Worker mpart = log2_table[((num.i & 0x007fffff) + (1 << (22 - LOG2_TABLE_SIZE_LOG2))) >> (23 - LOG2_TABLE_SIZE_LOG2)];
114*bbecb9d1SAndroid Build Coastguard Worker return epart + mpart;
115*bbecb9d1SAndroid Build Coastguard Worker }
116*bbecb9d1SAndroid Build Coastguard Worker
117*bbecb9d1SAndroid Build Coastguard Worker
118*bbecb9d1SAndroid Build Coastguard Worker /**
119*bbecb9d1SAndroid Build Coastguard Worker * Floor(x), returned as int.
120*bbecb9d1SAndroid Build Coastguard Worker */
121*bbecb9d1SAndroid Build Coastguard Worker static inline int
util_ifloor(float f)122*bbecb9d1SAndroid Build Coastguard Worker util_ifloor(float f)
123*bbecb9d1SAndroid Build Coastguard Worker {
124*bbecb9d1SAndroid Build Coastguard Worker #if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
125*bbecb9d1SAndroid Build Coastguard Worker /*
126*bbecb9d1SAndroid Build Coastguard Worker * IEEE floor for computers that round to nearest or even.
127*bbecb9d1SAndroid Build Coastguard Worker * 'f' must be between -4194304 and 4194303.
128*bbecb9d1SAndroid Build Coastguard Worker * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
129*bbecb9d1SAndroid Build Coastguard Worker * but uses some IEEE specific tricks for better speed.
130*bbecb9d1SAndroid Build Coastguard Worker * Contributed by Josh Vanderhoof
131*bbecb9d1SAndroid Build Coastguard Worker */
132*bbecb9d1SAndroid Build Coastguard Worker int ai, bi;
133*bbecb9d1SAndroid Build Coastguard Worker double af, bf;
134*bbecb9d1SAndroid Build Coastguard Worker af = (3 << 22) + 0.5 + (double)f;
135*bbecb9d1SAndroid Build Coastguard Worker bf = (3 << 22) + 0.5 - (double)f;
136*bbecb9d1SAndroid Build Coastguard Worker /* GCC generates an extra fstp/fld without this. */
137*bbecb9d1SAndroid Build Coastguard Worker __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
138*bbecb9d1SAndroid Build Coastguard Worker __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
139*bbecb9d1SAndroid Build Coastguard Worker return (ai - bi) >> 1;
140*bbecb9d1SAndroid Build Coastguard Worker #else
141*bbecb9d1SAndroid Build Coastguard Worker int ai, bi;
142*bbecb9d1SAndroid Build Coastguard Worker double af, bf;
143*bbecb9d1SAndroid Build Coastguard Worker union fi u;
144*bbecb9d1SAndroid Build Coastguard Worker af = (3 << 22) + 0.5 + (double) f;
145*bbecb9d1SAndroid Build Coastguard Worker bf = (3 << 22) + 0.5 - (double) f;
146*bbecb9d1SAndroid Build Coastguard Worker u.f = (float) af; ai = u.i;
147*bbecb9d1SAndroid Build Coastguard Worker u.f = (float) bf; bi = u.i;
148*bbecb9d1SAndroid Build Coastguard Worker return (ai - bi) >> 1;
149*bbecb9d1SAndroid Build Coastguard Worker #endif
150*bbecb9d1SAndroid Build Coastguard Worker }
151*bbecb9d1SAndroid Build Coastguard Worker
152*bbecb9d1SAndroid Build Coastguard Worker
153*bbecb9d1SAndroid Build Coastguard Worker /**
154*bbecb9d1SAndroid Build Coastguard Worker * Round float to nearest int.
155*bbecb9d1SAndroid Build Coastguard Worker */
156*bbecb9d1SAndroid Build Coastguard Worker static inline int
util_iround(float f)157*bbecb9d1SAndroid Build Coastguard Worker util_iround(float f)
158*bbecb9d1SAndroid Build Coastguard Worker {
159*bbecb9d1SAndroid Build Coastguard Worker #if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
160*bbecb9d1SAndroid Build Coastguard Worker int r;
161*bbecb9d1SAndroid Build Coastguard Worker __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
162*bbecb9d1SAndroid Build Coastguard Worker return r;
163*bbecb9d1SAndroid Build Coastguard Worker #elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
164*bbecb9d1SAndroid Build Coastguard Worker int r;
165*bbecb9d1SAndroid Build Coastguard Worker _asm {
166*bbecb9d1SAndroid Build Coastguard Worker fld f
167*bbecb9d1SAndroid Build Coastguard Worker fistp r
168*bbecb9d1SAndroid Build Coastguard Worker }
169*bbecb9d1SAndroid Build Coastguard Worker return r;
170*bbecb9d1SAndroid Build Coastguard Worker #else
171*bbecb9d1SAndroid Build Coastguard Worker if (f >= 0.0f)
172*bbecb9d1SAndroid Build Coastguard Worker return (int) (f + 0.5f);
173*bbecb9d1SAndroid Build Coastguard Worker else
174*bbecb9d1SAndroid Build Coastguard Worker return (int) (f - 0.5f);
175*bbecb9d1SAndroid Build Coastguard Worker #endif
176*bbecb9d1SAndroid Build Coastguard Worker }
177*bbecb9d1SAndroid Build Coastguard Worker
178*bbecb9d1SAndroid Build Coastguard Worker
179*bbecb9d1SAndroid Build Coastguard Worker /**
180*bbecb9d1SAndroid Build Coastguard Worker * Approximate floating point comparison
181*bbecb9d1SAndroid Build Coastguard Worker */
182*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_approx(float a,float b,float tol)183*bbecb9d1SAndroid Build Coastguard Worker util_is_approx(float a, float b, float tol)
184*bbecb9d1SAndroid Build Coastguard Worker {
185*bbecb9d1SAndroid Build Coastguard Worker return fabsf(b - a) <= tol;
186*bbecb9d1SAndroid Build Coastguard Worker }
187*bbecb9d1SAndroid Build Coastguard Worker
188*bbecb9d1SAndroid Build Coastguard Worker
189*bbecb9d1SAndroid Build Coastguard Worker /**
190*bbecb9d1SAndroid Build Coastguard Worker * util_is_X_inf_or_nan = test if x is NaN or +/- Inf
191*bbecb9d1SAndroid Build Coastguard Worker * util_is_X_nan = test if x is NaN
192*bbecb9d1SAndroid Build Coastguard Worker * util_X_inf_sign = return +1 for +Inf, -1 for -Inf, or 0 for not Inf
193*bbecb9d1SAndroid Build Coastguard Worker *
194*bbecb9d1SAndroid Build Coastguard Worker * NaN can be checked with x != x, however this fails with the fast math flag
195*bbecb9d1SAndroid Build Coastguard Worker **/
196*bbecb9d1SAndroid Build Coastguard Worker
197*bbecb9d1SAndroid Build Coastguard Worker
198*bbecb9d1SAndroid Build Coastguard Worker /**
199*bbecb9d1SAndroid Build Coastguard Worker * Single-float
200*bbecb9d1SAndroid Build Coastguard Worker */
201*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_inf_or_nan(float x)202*bbecb9d1SAndroid Build Coastguard Worker util_is_inf_or_nan(float x)
203*bbecb9d1SAndroid Build Coastguard Worker {
204*bbecb9d1SAndroid Build Coastguard Worker union fi tmp;
205*bbecb9d1SAndroid Build Coastguard Worker tmp.f = x;
206*bbecb9d1SAndroid Build Coastguard Worker return (tmp.ui & 0x7f800000) == 0x7f800000;
207*bbecb9d1SAndroid Build Coastguard Worker }
208*bbecb9d1SAndroid Build Coastguard Worker
209*bbecb9d1SAndroid Build Coastguard Worker
210*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_nan(float x)211*bbecb9d1SAndroid Build Coastguard Worker util_is_nan(float x)
212*bbecb9d1SAndroid Build Coastguard Worker {
213*bbecb9d1SAndroid Build Coastguard Worker union fi tmp;
214*bbecb9d1SAndroid Build Coastguard Worker tmp.f = x;
215*bbecb9d1SAndroid Build Coastguard Worker return (tmp.ui & 0x7fffffff) > 0x7f800000;
216*bbecb9d1SAndroid Build Coastguard Worker }
217*bbecb9d1SAndroid Build Coastguard Worker
218*bbecb9d1SAndroid Build Coastguard Worker
219*bbecb9d1SAndroid Build Coastguard Worker static inline int
util_inf_sign(float x)220*bbecb9d1SAndroid Build Coastguard Worker util_inf_sign(float x)
221*bbecb9d1SAndroid Build Coastguard Worker {
222*bbecb9d1SAndroid Build Coastguard Worker union fi tmp;
223*bbecb9d1SAndroid Build Coastguard Worker tmp.f = x;
224*bbecb9d1SAndroid Build Coastguard Worker if ((tmp.ui & 0x7fffffff) != 0x7f800000) {
225*bbecb9d1SAndroid Build Coastguard Worker return 0;
226*bbecb9d1SAndroid Build Coastguard Worker }
227*bbecb9d1SAndroid Build Coastguard Worker
228*bbecb9d1SAndroid Build Coastguard Worker return (x < 0) ? -1 : 1;
229*bbecb9d1SAndroid Build Coastguard Worker }
230*bbecb9d1SAndroid Build Coastguard Worker
231*bbecb9d1SAndroid Build Coastguard Worker
232*bbecb9d1SAndroid Build Coastguard Worker /**
233*bbecb9d1SAndroid Build Coastguard Worker * Double-float
234*bbecb9d1SAndroid Build Coastguard Worker */
235*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_double_inf_or_nan(double x)236*bbecb9d1SAndroid Build Coastguard Worker util_is_double_inf_or_nan(double x)
237*bbecb9d1SAndroid Build Coastguard Worker {
238*bbecb9d1SAndroid Build Coastguard Worker union di tmp;
239*bbecb9d1SAndroid Build Coastguard Worker tmp.d = x;
240*bbecb9d1SAndroid Build Coastguard Worker return (tmp.ui & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL;
241*bbecb9d1SAndroid Build Coastguard Worker }
242*bbecb9d1SAndroid Build Coastguard Worker
243*bbecb9d1SAndroid Build Coastguard Worker
244*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_double_nan(double x)245*bbecb9d1SAndroid Build Coastguard Worker util_is_double_nan(double x)
246*bbecb9d1SAndroid Build Coastguard Worker {
247*bbecb9d1SAndroid Build Coastguard Worker union di tmp;
248*bbecb9d1SAndroid Build Coastguard Worker tmp.d = x;
249*bbecb9d1SAndroid Build Coastguard Worker return (tmp.ui & 0x7fffffffffffffffULL) > 0x7ff0000000000000ULL;
250*bbecb9d1SAndroid Build Coastguard Worker }
251*bbecb9d1SAndroid Build Coastguard Worker
252*bbecb9d1SAndroid Build Coastguard Worker
253*bbecb9d1SAndroid Build Coastguard Worker static inline int
util_double_inf_sign(double x)254*bbecb9d1SAndroid Build Coastguard Worker util_double_inf_sign(double x)
255*bbecb9d1SAndroid Build Coastguard Worker {
256*bbecb9d1SAndroid Build Coastguard Worker union di tmp;
257*bbecb9d1SAndroid Build Coastguard Worker tmp.d = x;
258*bbecb9d1SAndroid Build Coastguard Worker if ((tmp.ui & 0x7fffffffffffffffULL) != 0x7ff0000000000000ULL) {
259*bbecb9d1SAndroid Build Coastguard Worker return 0;
260*bbecb9d1SAndroid Build Coastguard Worker }
261*bbecb9d1SAndroid Build Coastguard Worker
262*bbecb9d1SAndroid Build Coastguard Worker return (x < 0) ? -1 : 1;
263*bbecb9d1SAndroid Build Coastguard Worker }
264*bbecb9d1SAndroid Build Coastguard Worker
265*bbecb9d1SAndroid Build Coastguard Worker
266*bbecb9d1SAndroid Build Coastguard Worker /**
267*bbecb9d1SAndroid Build Coastguard Worker * Half-float
268*bbecb9d1SAndroid Build Coastguard Worker */
269*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_half_inf_or_nan(int16_t x)270*bbecb9d1SAndroid Build Coastguard Worker util_is_half_inf_or_nan(int16_t x)
271*bbecb9d1SAndroid Build Coastguard Worker {
272*bbecb9d1SAndroid Build Coastguard Worker return (x & 0x7c00) == 0x7c00;
273*bbecb9d1SAndroid Build Coastguard Worker }
274*bbecb9d1SAndroid Build Coastguard Worker
275*bbecb9d1SAndroid Build Coastguard Worker
276*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_half_nan(int16_t x)277*bbecb9d1SAndroid Build Coastguard Worker util_is_half_nan(int16_t x)
278*bbecb9d1SAndroid Build Coastguard Worker {
279*bbecb9d1SAndroid Build Coastguard Worker return (x & 0x7fff) > 0x7c00;
280*bbecb9d1SAndroid Build Coastguard Worker }
281*bbecb9d1SAndroid Build Coastguard Worker
282*bbecb9d1SAndroid Build Coastguard Worker
283*bbecb9d1SAndroid Build Coastguard Worker static inline int
util_half_inf_sign(int16_t x)284*bbecb9d1SAndroid Build Coastguard Worker util_half_inf_sign(int16_t x)
285*bbecb9d1SAndroid Build Coastguard Worker {
286*bbecb9d1SAndroid Build Coastguard Worker if ((x & 0x7fff) != 0x7c00) {
287*bbecb9d1SAndroid Build Coastguard Worker return 0;
288*bbecb9d1SAndroid Build Coastguard Worker }
289*bbecb9d1SAndroid Build Coastguard Worker
290*bbecb9d1SAndroid Build Coastguard Worker return (x < 0) ? -1 : 1;
291*bbecb9d1SAndroid Build Coastguard Worker }
292*bbecb9d1SAndroid Build Coastguard Worker
293*bbecb9d1SAndroid Build Coastguard Worker
294*bbecb9d1SAndroid Build Coastguard Worker /**
295*bbecb9d1SAndroid Build Coastguard Worker * Return float bits.
296*bbecb9d1SAndroid Build Coastguard Worker */
297*bbecb9d1SAndroid Build Coastguard Worker static inline unsigned
fui(float f)298*bbecb9d1SAndroid Build Coastguard Worker fui( float f )
299*bbecb9d1SAndroid Build Coastguard Worker {
300*bbecb9d1SAndroid Build Coastguard Worker union fi fi;
301*bbecb9d1SAndroid Build Coastguard Worker fi.f = f;
302*bbecb9d1SAndroid Build Coastguard Worker return fi.ui;
303*bbecb9d1SAndroid Build Coastguard Worker }
304*bbecb9d1SAndroid Build Coastguard Worker
305*bbecb9d1SAndroid Build Coastguard Worker static inline float
uif(uint32_t ui)306*bbecb9d1SAndroid Build Coastguard Worker uif(uint32_t ui)
307*bbecb9d1SAndroid Build Coastguard Worker {
308*bbecb9d1SAndroid Build Coastguard Worker union fi fi;
309*bbecb9d1SAndroid Build Coastguard Worker fi.ui = ui;
310*bbecb9d1SAndroid Build Coastguard Worker return fi.f;
311*bbecb9d1SAndroid Build Coastguard Worker }
312*bbecb9d1SAndroid Build Coastguard Worker
313*bbecb9d1SAndroid Build Coastguard Worker
314*bbecb9d1SAndroid Build Coastguard Worker /**
315*bbecb9d1SAndroid Build Coastguard Worker * Convert uint8_t to float in [0, 1].
316*bbecb9d1SAndroid Build Coastguard Worker */
317*bbecb9d1SAndroid Build Coastguard Worker static inline float
ubyte_to_float(uint8_t ub)318*bbecb9d1SAndroid Build Coastguard Worker ubyte_to_float(uint8_t ub)
319*bbecb9d1SAndroid Build Coastguard Worker {
320*bbecb9d1SAndroid Build Coastguard Worker return (float) ub * (1.0f / 255.0f);
321*bbecb9d1SAndroid Build Coastguard Worker }
322*bbecb9d1SAndroid Build Coastguard Worker
323*bbecb9d1SAndroid Build Coastguard Worker
324*bbecb9d1SAndroid Build Coastguard Worker /**
325*bbecb9d1SAndroid Build Coastguard Worker * Convert float in [0,1] to uint8_t in [0,255] with clamping.
326*bbecb9d1SAndroid Build Coastguard Worker */
327*bbecb9d1SAndroid Build Coastguard Worker static inline uint8_t
float_to_ubyte(float f)328*bbecb9d1SAndroid Build Coastguard Worker float_to_ubyte(float f)
329*bbecb9d1SAndroid Build Coastguard Worker {
330*bbecb9d1SAndroid Build Coastguard Worker /* return 0 for NaN too */
331*bbecb9d1SAndroid Build Coastguard Worker if (!(f > 0.0f)) {
332*bbecb9d1SAndroid Build Coastguard Worker return (uint8_t) 0;
333*bbecb9d1SAndroid Build Coastguard Worker }
334*bbecb9d1SAndroid Build Coastguard Worker else if (f >= 1.0f) {
335*bbecb9d1SAndroid Build Coastguard Worker return (uint8_t) 255;
336*bbecb9d1SAndroid Build Coastguard Worker }
337*bbecb9d1SAndroid Build Coastguard Worker else {
338*bbecb9d1SAndroid Build Coastguard Worker union fi tmp;
339*bbecb9d1SAndroid Build Coastguard Worker tmp.f = f;
340*bbecb9d1SAndroid Build Coastguard Worker tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f;
341*bbecb9d1SAndroid Build Coastguard Worker return (uint8_t) tmp.i;
342*bbecb9d1SAndroid Build Coastguard Worker }
343*bbecb9d1SAndroid Build Coastguard Worker }
344*bbecb9d1SAndroid Build Coastguard Worker
345*bbecb9d1SAndroid Build Coastguard Worker /**
346*bbecb9d1SAndroid Build Coastguard Worker * Convert uint16_t to float in [0, 1].
347*bbecb9d1SAndroid Build Coastguard Worker */
348*bbecb9d1SAndroid Build Coastguard Worker static inline float
ushort_to_float(uint16_t us)349*bbecb9d1SAndroid Build Coastguard Worker ushort_to_float(uint16_t us)
350*bbecb9d1SAndroid Build Coastguard Worker {
351*bbecb9d1SAndroid Build Coastguard Worker return (float) us * (1.0f / 65535.0f);
352*bbecb9d1SAndroid Build Coastguard Worker }
353*bbecb9d1SAndroid Build Coastguard Worker
354*bbecb9d1SAndroid Build Coastguard Worker
355*bbecb9d1SAndroid Build Coastguard Worker /**
356*bbecb9d1SAndroid Build Coastguard Worker * Convert float in [0,1] to uint16_t in [0,65535] with clamping.
357*bbecb9d1SAndroid Build Coastguard Worker */
358*bbecb9d1SAndroid Build Coastguard Worker static inline uint16_t
float_to_ushort(float f)359*bbecb9d1SAndroid Build Coastguard Worker float_to_ushort(float f)
360*bbecb9d1SAndroid Build Coastguard Worker {
361*bbecb9d1SAndroid Build Coastguard Worker /* return 0 for NaN too */
362*bbecb9d1SAndroid Build Coastguard Worker if (!(f > 0.0f)) {
363*bbecb9d1SAndroid Build Coastguard Worker return (uint16_t) 0;
364*bbecb9d1SAndroid Build Coastguard Worker }
365*bbecb9d1SAndroid Build Coastguard Worker else if (f >= 1.0f) {
366*bbecb9d1SAndroid Build Coastguard Worker return (uint16_t) 65535;
367*bbecb9d1SAndroid Build Coastguard Worker }
368*bbecb9d1SAndroid Build Coastguard Worker else {
369*bbecb9d1SAndroid Build Coastguard Worker union fi tmp;
370*bbecb9d1SAndroid Build Coastguard Worker tmp.f = f;
371*bbecb9d1SAndroid Build Coastguard Worker tmp.f = tmp.f * (65535.0f/65536.0f) + 128.0f;
372*bbecb9d1SAndroid Build Coastguard Worker return (uint16_t) tmp.i;
373*bbecb9d1SAndroid Build Coastguard Worker }
374*bbecb9d1SAndroid Build Coastguard Worker }
375*bbecb9d1SAndroid Build Coastguard Worker
376*bbecb9d1SAndroid Build Coastguard Worker static inline float
byte_to_float_tex(int8_t b)377*bbecb9d1SAndroid Build Coastguard Worker byte_to_float_tex(int8_t b)
378*bbecb9d1SAndroid Build Coastguard Worker {
379*bbecb9d1SAndroid Build Coastguard Worker return (b == -128) ? -1.0F : b * 1.0F / 127.0F;
380*bbecb9d1SAndroid Build Coastguard Worker }
381*bbecb9d1SAndroid Build Coastguard Worker
382*bbecb9d1SAndroid Build Coastguard Worker static inline int8_t
float_to_byte_tex(float f)383*bbecb9d1SAndroid Build Coastguard Worker float_to_byte_tex(float f)
384*bbecb9d1SAndroid Build Coastguard Worker {
385*bbecb9d1SAndroid Build Coastguard Worker return (int8_t) (127.0F * f);
386*bbecb9d1SAndroid Build Coastguard Worker }
387*bbecb9d1SAndroid Build Coastguard Worker
388*bbecb9d1SAndroid Build Coastguard Worker /**
389*bbecb9d1SAndroid Build Coastguard Worker * Calc log base 2
390*bbecb9d1SAndroid Build Coastguard Worker */
391*bbecb9d1SAndroid Build Coastguard Worker static inline unsigned
util_logbase2(unsigned n)392*bbecb9d1SAndroid Build Coastguard Worker util_logbase2(unsigned n)
393*bbecb9d1SAndroid Build Coastguard Worker {
394*bbecb9d1SAndroid Build Coastguard Worker #if defined(HAVE___BUILTIN_CLZ)
395*bbecb9d1SAndroid Build Coastguard Worker return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1));
396*bbecb9d1SAndroid Build Coastguard Worker #else
397*bbecb9d1SAndroid Build Coastguard Worker unsigned pos = 0;
398*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1<<16) { n >>= 16; pos += 16; }
399*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1<< 8) { n >>= 8; pos += 8; }
400*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1<< 4) { n >>= 4; pos += 4; }
401*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1<< 2) { n >>= 2; pos += 2; }
402*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1<< 1) { pos += 1; }
403*bbecb9d1SAndroid Build Coastguard Worker return pos;
404*bbecb9d1SAndroid Build Coastguard Worker #endif
405*bbecb9d1SAndroid Build Coastguard Worker }
406*bbecb9d1SAndroid Build Coastguard Worker
407*bbecb9d1SAndroid Build Coastguard Worker static inline uint64_t
util_logbase2_64(uint64_t n)408*bbecb9d1SAndroid Build Coastguard Worker util_logbase2_64(uint64_t n)
409*bbecb9d1SAndroid Build Coastguard Worker {
410*bbecb9d1SAndroid Build Coastguard Worker #if defined(HAVE___BUILTIN_CLZLL)
411*bbecb9d1SAndroid Build Coastguard Worker return ((sizeof(uint64_t) * 8 - 1) - __builtin_clzll(n | 1));
412*bbecb9d1SAndroid Build Coastguard Worker #else
413*bbecb9d1SAndroid Build Coastguard Worker uint64_t pos = 0ull;
414*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1ull<<32) { n >>= 32; pos += 32; }
415*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1ull<<16) { n >>= 16; pos += 16; }
416*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1ull<< 8) { n >>= 8; pos += 8; }
417*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1ull<< 4) { n >>= 4; pos += 4; }
418*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1ull<< 2) { n >>= 2; pos += 2; }
419*bbecb9d1SAndroid Build Coastguard Worker if (n >= 1ull<< 1) { pos += 1; }
420*bbecb9d1SAndroid Build Coastguard Worker return pos;
421*bbecb9d1SAndroid Build Coastguard Worker #endif
422*bbecb9d1SAndroid Build Coastguard Worker }
423*bbecb9d1SAndroid Build Coastguard Worker
424*bbecb9d1SAndroid Build Coastguard Worker /**
425*bbecb9d1SAndroid Build Coastguard Worker * Returns the ceiling of log n base 2, and 0 when n == 0. Equivalently,
426*bbecb9d1SAndroid Build Coastguard Worker * returns the smallest x such that n <= 2**x.
427*bbecb9d1SAndroid Build Coastguard Worker */
428*bbecb9d1SAndroid Build Coastguard Worker static inline unsigned
util_logbase2_ceil(unsigned n)429*bbecb9d1SAndroid Build Coastguard Worker util_logbase2_ceil(unsigned n)
430*bbecb9d1SAndroid Build Coastguard Worker {
431*bbecb9d1SAndroid Build Coastguard Worker if (n <= 1)
432*bbecb9d1SAndroid Build Coastguard Worker return 0;
433*bbecb9d1SAndroid Build Coastguard Worker
434*bbecb9d1SAndroid Build Coastguard Worker return 1 + util_logbase2(n - 1);
435*bbecb9d1SAndroid Build Coastguard Worker }
436*bbecb9d1SAndroid Build Coastguard Worker
437*bbecb9d1SAndroid Build Coastguard Worker static inline uint64_t
util_logbase2_ceil64(uint64_t n)438*bbecb9d1SAndroid Build Coastguard Worker util_logbase2_ceil64(uint64_t n)
439*bbecb9d1SAndroid Build Coastguard Worker {
440*bbecb9d1SAndroid Build Coastguard Worker if (n <= 1)
441*bbecb9d1SAndroid Build Coastguard Worker return 0;
442*bbecb9d1SAndroid Build Coastguard Worker
443*bbecb9d1SAndroid Build Coastguard Worker return 1ull + util_logbase2_64(n - 1);
444*bbecb9d1SAndroid Build Coastguard Worker }
445*bbecb9d1SAndroid Build Coastguard Worker
446*bbecb9d1SAndroid Build Coastguard Worker /**
447*bbecb9d1SAndroid Build Coastguard Worker * Returns the smallest power of two >= x
448*bbecb9d1SAndroid Build Coastguard Worker */
449*bbecb9d1SAndroid Build Coastguard Worker static inline unsigned
util_next_power_of_two(unsigned x)450*bbecb9d1SAndroid Build Coastguard Worker util_next_power_of_two(unsigned x)
451*bbecb9d1SAndroid Build Coastguard Worker {
452*bbecb9d1SAndroid Build Coastguard Worker #if defined(HAVE___BUILTIN_CLZ)
453*bbecb9d1SAndroid Build Coastguard Worker if (x <= 1)
454*bbecb9d1SAndroid Build Coastguard Worker return 1;
455*bbecb9d1SAndroid Build Coastguard Worker
456*bbecb9d1SAndroid Build Coastguard Worker return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
457*bbecb9d1SAndroid Build Coastguard Worker #else
458*bbecb9d1SAndroid Build Coastguard Worker unsigned val = x;
459*bbecb9d1SAndroid Build Coastguard Worker
460*bbecb9d1SAndroid Build Coastguard Worker if (x <= 1)
461*bbecb9d1SAndroid Build Coastguard Worker return 1;
462*bbecb9d1SAndroid Build Coastguard Worker
463*bbecb9d1SAndroid Build Coastguard Worker if (util_is_power_of_two_or_zero(x))
464*bbecb9d1SAndroid Build Coastguard Worker return x;
465*bbecb9d1SAndroid Build Coastguard Worker
466*bbecb9d1SAndroid Build Coastguard Worker val--;
467*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 1) | val;
468*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 2) | val;
469*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 4) | val;
470*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 8) | val;
471*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 16) | val;
472*bbecb9d1SAndroid Build Coastguard Worker val++;
473*bbecb9d1SAndroid Build Coastguard Worker return val;
474*bbecb9d1SAndroid Build Coastguard Worker #endif
475*bbecb9d1SAndroid Build Coastguard Worker }
476*bbecb9d1SAndroid Build Coastguard Worker
477*bbecb9d1SAndroid Build Coastguard Worker static inline uint64_t
util_next_power_of_two64(uint64_t x)478*bbecb9d1SAndroid Build Coastguard Worker util_next_power_of_two64(uint64_t x)
479*bbecb9d1SAndroid Build Coastguard Worker {
480*bbecb9d1SAndroid Build Coastguard Worker #if defined(HAVE___BUILTIN_CLZLL)
481*bbecb9d1SAndroid Build Coastguard Worker if (x <= 1)
482*bbecb9d1SAndroid Build Coastguard Worker return 1;
483*bbecb9d1SAndroid Build Coastguard Worker
484*bbecb9d1SAndroid Build Coastguard Worker return (1ull << ((sizeof(uint64_t) * 8) - __builtin_clzll(x - 1)));
485*bbecb9d1SAndroid Build Coastguard Worker #else
486*bbecb9d1SAndroid Build Coastguard Worker uint64_t val = x;
487*bbecb9d1SAndroid Build Coastguard Worker
488*bbecb9d1SAndroid Build Coastguard Worker if (x <= 1)
489*bbecb9d1SAndroid Build Coastguard Worker return 1;
490*bbecb9d1SAndroid Build Coastguard Worker
491*bbecb9d1SAndroid Build Coastguard Worker if (util_is_power_of_two_or_zero64(x))
492*bbecb9d1SAndroid Build Coastguard Worker return x;
493*bbecb9d1SAndroid Build Coastguard Worker
494*bbecb9d1SAndroid Build Coastguard Worker val--;
495*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 1) | val;
496*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 2) | val;
497*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 4) | val;
498*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 8) | val;
499*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 16) | val;
500*bbecb9d1SAndroid Build Coastguard Worker val = (val >> 32) | val;
501*bbecb9d1SAndroid Build Coastguard Worker val++;
502*bbecb9d1SAndroid Build Coastguard Worker return val;
503*bbecb9d1SAndroid Build Coastguard Worker #endif
504*bbecb9d1SAndroid Build Coastguard Worker }
505*bbecb9d1SAndroid Build Coastguard Worker
506*bbecb9d1SAndroid Build Coastguard Worker /**
507*bbecb9d1SAndroid Build Coastguard Worker * Reverse bits in n
508*bbecb9d1SAndroid Build Coastguard Worker * Algorithm taken from:
509*bbecb9d1SAndroid Build Coastguard Worker * http://stackoverflow.com/questions/9144800/c-reverse-bits-in-unsigned-integer
510*bbecb9d1SAndroid Build Coastguard Worker */
511*bbecb9d1SAndroid Build Coastguard Worker static inline unsigned
util_bitreverse(unsigned n)512*bbecb9d1SAndroid Build Coastguard Worker util_bitreverse(unsigned n)
513*bbecb9d1SAndroid Build Coastguard Worker {
514*bbecb9d1SAndroid Build Coastguard Worker n = ((n >> 1) & 0x55555555u) | ((n & 0x55555555u) << 1);
515*bbecb9d1SAndroid Build Coastguard Worker n = ((n >> 2) & 0x33333333u) | ((n & 0x33333333u) << 2);
516*bbecb9d1SAndroid Build Coastguard Worker n = ((n >> 4) & 0x0f0f0f0fu) | ((n & 0x0f0f0f0fu) << 4);
517*bbecb9d1SAndroid Build Coastguard Worker n = ((n >> 8) & 0x00ff00ffu) | ((n & 0x00ff00ffu) << 8);
518*bbecb9d1SAndroid Build Coastguard Worker n = ((n >> 16) & 0xffffu) | ((n & 0xffffu) << 16);
519*bbecb9d1SAndroid Build Coastguard Worker return n;
520*bbecb9d1SAndroid Build Coastguard Worker }
521*bbecb9d1SAndroid Build Coastguard Worker
522*bbecb9d1SAndroid Build Coastguard Worker /**
523*bbecb9d1SAndroid Build Coastguard Worker * Convert from little endian to CPU byte order.
524*bbecb9d1SAndroid Build Coastguard Worker */
525*bbecb9d1SAndroid Build Coastguard Worker
526*bbecb9d1SAndroid Build Coastguard Worker #if UTIL_ARCH_BIG_ENDIAN
527*bbecb9d1SAndroid Build Coastguard Worker #define util_le64_to_cpu(x) util_bswap64(x)
528*bbecb9d1SAndroid Build Coastguard Worker #define util_le32_to_cpu(x) util_bswap32(x)
529*bbecb9d1SAndroid Build Coastguard Worker #define util_le16_to_cpu(x) util_bswap16(x)
530*bbecb9d1SAndroid Build Coastguard Worker #else
531*bbecb9d1SAndroid Build Coastguard Worker #define util_le64_to_cpu(x) (x)
532*bbecb9d1SAndroid Build Coastguard Worker #define util_le32_to_cpu(x) (x)
533*bbecb9d1SAndroid Build Coastguard Worker #define util_le16_to_cpu(x) (x)
534*bbecb9d1SAndroid Build Coastguard Worker #endif
535*bbecb9d1SAndroid Build Coastguard Worker
536*bbecb9d1SAndroid Build Coastguard Worker #define util_cpu_to_le64(x) util_le64_to_cpu(x)
537*bbecb9d1SAndroid Build Coastguard Worker #define util_cpu_to_le32(x) util_le32_to_cpu(x)
538*bbecb9d1SAndroid Build Coastguard Worker #define util_cpu_to_le16(x) util_le16_to_cpu(x)
539*bbecb9d1SAndroid Build Coastguard Worker
540*bbecb9d1SAndroid Build Coastguard Worker /**
541*bbecb9d1SAndroid Build Coastguard Worker * Reverse byte order of a 32 bit word.
542*bbecb9d1SAndroid Build Coastguard Worker */
543*bbecb9d1SAndroid Build Coastguard Worker static inline uint32_t
util_bswap32(uint32_t n)544*bbecb9d1SAndroid Build Coastguard Worker util_bswap32(uint32_t n)
545*bbecb9d1SAndroid Build Coastguard Worker {
546*bbecb9d1SAndroid Build Coastguard Worker #if defined(HAVE___BUILTIN_BSWAP32)
547*bbecb9d1SAndroid Build Coastguard Worker return __builtin_bswap32(n);
548*bbecb9d1SAndroid Build Coastguard Worker #else
549*bbecb9d1SAndroid Build Coastguard Worker return (n >> 24) |
550*bbecb9d1SAndroid Build Coastguard Worker ((n >> 8) & 0x0000ff00) |
551*bbecb9d1SAndroid Build Coastguard Worker ((n << 8) & 0x00ff0000) |
552*bbecb9d1SAndroid Build Coastguard Worker (n << 24);
553*bbecb9d1SAndroid Build Coastguard Worker #endif
554*bbecb9d1SAndroid Build Coastguard Worker }
555*bbecb9d1SAndroid Build Coastguard Worker
556*bbecb9d1SAndroid Build Coastguard Worker /**
557*bbecb9d1SAndroid Build Coastguard Worker * Reverse byte order of a 64bit word.
558*bbecb9d1SAndroid Build Coastguard Worker */
559*bbecb9d1SAndroid Build Coastguard Worker static inline uint64_t
util_bswap64(uint64_t n)560*bbecb9d1SAndroid Build Coastguard Worker util_bswap64(uint64_t n)
561*bbecb9d1SAndroid Build Coastguard Worker {
562*bbecb9d1SAndroid Build Coastguard Worker #if defined(HAVE___BUILTIN_BSWAP64)
563*bbecb9d1SAndroid Build Coastguard Worker return __builtin_bswap64(n);
564*bbecb9d1SAndroid Build Coastguard Worker #else
565*bbecb9d1SAndroid Build Coastguard Worker return ((uint64_t)util_bswap32((uint32_t)n) << 32) |
566*bbecb9d1SAndroid Build Coastguard Worker util_bswap32((n >> 32));
567*bbecb9d1SAndroid Build Coastguard Worker #endif
568*bbecb9d1SAndroid Build Coastguard Worker }
569*bbecb9d1SAndroid Build Coastguard Worker
570*bbecb9d1SAndroid Build Coastguard Worker
571*bbecb9d1SAndroid Build Coastguard Worker /**
572*bbecb9d1SAndroid Build Coastguard Worker * Reverse byte order of a 16 bit word.
573*bbecb9d1SAndroid Build Coastguard Worker */
574*bbecb9d1SAndroid Build Coastguard Worker static inline uint16_t
util_bswap16(uint16_t n)575*bbecb9d1SAndroid Build Coastguard Worker util_bswap16(uint16_t n)
576*bbecb9d1SAndroid Build Coastguard Worker {
577*bbecb9d1SAndroid Build Coastguard Worker return (n >> 8) |
578*bbecb9d1SAndroid Build Coastguard Worker (n << 8);
579*bbecb9d1SAndroid Build Coastguard Worker }
580*bbecb9d1SAndroid Build Coastguard Worker
581*bbecb9d1SAndroid Build Coastguard Worker /**
582*bbecb9d1SAndroid Build Coastguard Worker * Extend sign.
583*bbecb9d1SAndroid Build Coastguard Worker */
584*bbecb9d1SAndroid Build Coastguard Worker static inline int64_t
util_sign_extend(uint64_t val,unsigned width)585*bbecb9d1SAndroid Build Coastguard Worker util_sign_extend(uint64_t val, unsigned width)
586*bbecb9d1SAndroid Build Coastguard Worker {
587*bbecb9d1SAndroid Build Coastguard Worker assert(width > 0);
588*bbecb9d1SAndroid Build Coastguard Worker if (val & (UINT64_C(1) << (width - 1))) {
589*bbecb9d1SAndroid Build Coastguard Worker return -(int64_t)((UINT64_C(1) << width) - val);
590*bbecb9d1SAndroid Build Coastguard Worker } else {
591*bbecb9d1SAndroid Build Coastguard Worker return val;
592*bbecb9d1SAndroid Build Coastguard Worker }
593*bbecb9d1SAndroid Build Coastguard Worker }
594*bbecb9d1SAndroid Build Coastguard Worker
595*bbecb9d1SAndroid Build Coastguard Worker static inline void*
util_memcpy_cpu_to_le32(void * restrict dest,const void * restrict src,size_t n)596*bbecb9d1SAndroid Build Coastguard Worker util_memcpy_cpu_to_le32(void * restrict dest, const void * restrict src, size_t n)
597*bbecb9d1SAndroid Build Coastguard Worker {
598*bbecb9d1SAndroid Build Coastguard Worker #if UTIL_ARCH_BIG_ENDIAN
599*bbecb9d1SAndroid Build Coastguard Worker size_t i, e;
600*bbecb9d1SAndroid Build Coastguard Worker assert(n % 4 == 0);
601*bbecb9d1SAndroid Build Coastguard Worker
602*bbecb9d1SAndroid Build Coastguard Worker for (i = 0, e = n / 4; i < e; i++) {
603*bbecb9d1SAndroid Build Coastguard Worker uint32_t * restrict d = (uint32_t* restrict)dest;
604*bbecb9d1SAndroid Build Coastguard Worker const uint32_t * restrict s = (const uint32_t* restrict)src;
605*bbecb9d1SAndroid Build Coastguard Worker d[i] = util_bswap32(s[i]);
606*bbecb9d1SAndroid Build Coastguard Worker }
607*bbecb9d1SAndroid Build Coastguard Worker return dest;
608*bbecb9d1SAndroid Build Coastguard Worker #else
609*bbecb9d1SAndroid Build Coastguard Worker return memcpy(dest, src, n);
610*bbecb9d1SAndroid Build Coastguard Worker #endif
611*bbecb9d1SAndroid Build Coastguard Worker }
612*bbecb9d1SAndroid Build Coastguard Worker
613*bbecb9d1SAndroid Build Coastguard Worker /**
614*bbecb9d1SAndroid Build Coastguard Worker * Clamp X to [MIN, MAX].
615*bbecb9d1SAndroid Build Coastguard Worker * This is a macro to allow float, int, uint, etc. types.
616*bbecb9d1SAndroid Build Coastguard Worker * We arbitrarily turn NaN into MIN.
617*bbecb9d1SAndroid Build Coastguard Worker */
618*bbecb9d1SAndroid Build Coastguard Worker #define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) )
619*bbecb9d1SAndroid Build Coastguard Worker
620*bbecb9d1SAndroid Build Coastguard Worker /* Syntax sugar occuring frequently in graphics code */
621*bbecb9d1SAndroid Build Coastguard Worker #define SATURATE( X ) CLAMP(X, 0.0f, 1.0f)
622*bbecb9d1SAndroid Build Coastguard Worker
623*bbecb9d1SAndroid Build Coastguard Worker #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
624*bbecb9d1SAndroid Build Coastguard Worker #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
625*bbecb9d1SAndroid Build Coastguard Worker
626*bbecb9d1SAndroid Build Coastguard Worker #define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C))
627*bbecb9d1SAndroid Build Coastguard Worker #define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
628*bbecb9d1SAndroid Build Coastguard Worker
629*bbecb9d1SAndroid Build Coastguard Worker #define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D))
630*bbecb9d1SAndroid Build Coastguard Worker #define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D))
631*bbecb9d1SAndroid Build Coastguard Worker
632*bbecb9d1SAndroid Build Coastguard Worker
633*bbecb9d1SAndroid Build Coastguard Worker /**
634*bbecb9d1SAndroid Build Coastguard Worker * Align a value up to an alignment value
635*bbecb9d1SAndroid Build Coastguard Worker *
636*bbecb9d1SAndroid Build Coastguard Worker * If \c value is not already aligned to the requested alignment value, it
637*bbecb9d1SAndroid Build Coastguard Worker * will be rounded up.
638*bbecb9d1SAndroid Build Coastguard Worker *
639*bbecb9d1SAndroid Build Coastguard Worker * \param value Value to be rounded
640*bbecb9d1SAndroid Build Coastguard Worker * \param alignment Alignment value to be used. This must be a power of two.
641*bbecb9d1SAndroid Build Coastguard Worker *
642*bbecb9d1SAndroid Build Coastguard Worker * \sa ROUND_DOWN_TO()
643*bbecb9d1SAndroid Build Coastguard Worker */
644*bbecb9d1SAndroid Build Coastguard Worker
645*bbecb9d1SAndroid Build Coastguard Worker #if defined(ALIGN)
646*bbecb9d1SAndroid Build Coastguard Worker #undef ALIGN
647*bbecb9d1SAndroid Build Coastguard Worker #endif
648*bbecb9d1SAndroid Build Coastguard Worker static inline uintptr_t
ALIGN(uintptr_t value,int32_t alignment)649*bbecb9d1SAndroid Build Coastguard Worker ALIGN(uintptr_t value, int32_t alignment)
650*bbecb9d1SAndroid Build Coastguard Worker {
651*bbecb9d1SAndroid Build Coastguard Worker assert(util_is_power_of_two_nonzero(alignment));
652*bbecb9d1SAndroid Build Coastguard Worker return (((value) + (alignment) - 1) & ~((alignment) - 1));
653*bbecb9d1SAndroid Build Coastguard Worker }
654*bbecb9d1SAndroid Build Coastguard Worker
655*bbecb9d1SAndroid Build Coastguard Worker /**
656*bbecb9d1SAndroid Build Coastguard Worker * Like ALIGN(), but works with a non-power-of-two alignment.
657*bbecb9d1SAndroid Build Coastguard Worker */
658*bbecb9d1SAndroid Build Coastguard Worker static inline uintptr_t
ALIGN_NPOT(uintptr_t value,int32_t alignment)659*bbecb9d1SAndroid Build Coastguard Worker ALIGN_NPOT(uintptr_t value, int32_t alignment)
660*bbecb9d1SAndroid Build Coastguard Worker {
661*bbecb9d1SAndroid Build Coastguard Worker assert(alignment > 0);
662*bbecb9d1SAndroid Build Coastguard Worker return (value + alignment - 1) / alignment * alignment;
663*bbecb9d1SAndroid Build Coastguard Worker }
664*bbecb9d1SAndroid Build Coastguard Worker
665*bbecb9d1SAndroid Build Coastguard Worker /**
666*bbecb9d1SAndroid Build Coastguard Worker * Align a value down to an alignment value
667*bbecb9d1SAndroid Build Coastguard Worker *
668*bbecb9d1SAndroid Build Coastguard Worker * If \c value is not already aligned to the requested alignment value, it
669*bbecb9d1SAndroid Build Coastguard Worker * will be rounded down.
670*bbecb9d1SAndroid Build Coastguard Worker *
671*bbecb9d1SAndroid Build Coastguard Worker * \param value Value to be rounded
672*bbecb9d1SAndroid Build Coastguard Worker * \param alignment Alignment value to be used. This must be a power of two.
673*bbecb9d1SAndroid Build Coastguard Worker *
674*bbecb9d1SAndroid Build Coastguard Worker * \sa ALIGN()
675*bbecb9d1SAndroid Build Coastguard Worker */
676*bbecb9d1SAndroid Build Coastguard Worker static inline uint64_t
ROUND_DOWN_TO(uint64_t value,int32_t alignment)677*bbecb9d1SAndroid Build Coastguard Worker ROUND_DOWN_TO(uint64_t value, int32_t alignment)
678*bbecb9d1SAndroid Build Coastguard Worker {
679*bbecb9d1SAndroid Build Coastguard Worker assert(util_is_power_of_two_nonzero(alignment));
680*bbecb9d1SAndroid Build Coastguard Worker return ((value) & ~(alignment - 1));
681*bbecb9d1SAndroid Build Coastguard Worker }
682*bbecb9d1SAndroid Build Coastguard Worker
683*bbecb9d1SAndroid Build Coastguard Worker /**
684*bbecb9d1SAndroid Build Coastguard Worker * Align a value, only works pot alignemnts.
685*bbecb9d1SAndroid Build Coastguard Worker */
686*bbecb9d1SAndroid Build Coastguard Worker static inline int
align(int value,int alignment)687*bbecb9d1SAndroid Build Coastguard Worker align(int value, int alignment)
688*bbecb9d1SAndroid Build Coastguard Worker {
689*bbecb9d1SAndroid Build Coastguard Worker return (value + alignment - 1) & ~(alignment - 1);
690*bbecb9d1SAndroid Build Coastguard Worker }
691*bbecb9d1SAndroid Build Coastguard Worker
692*bbecb9d1SAndroid Build Coastguard Worker static inline uint64_t
align64(uint64_t value,unsigned alignment)693*bbecb9d1SAndroid Build Coastguard Worker align64(uint64_t value, unsigned alignment)
694*bbecb9d1SAndroid Build Coastguard Worker {
695*bbecb9d1SAndroid Build Coastguard Worker return (value + alignment - 1) & ~((uint64_t)alignment - 1);
696*bbecb9d1SAndroid Build Coastguard Worker }
697*bbecb9d1SAndroid Build Coastguard Worker
698*bbecb9d1SAndroid Build Coastguard Worker /**
699*bbecb9d1SAndroid Build Coastguard Worker * Works like align but on npot alignments.
700*bbecb9d1SAndroid Build Coastguard Worker */
701*bbecb9d1SAndroid Build Coastguard Worker static inline size_t
util_align_npot(size_t value,size_t alignment)702*bbecb9d1SAndroid Build Coastguard Worker util_align_npot(size_t value, size_t alignment)
703*bbecb9d1SAndroid Build Coastguard Worker {
704*bbecb9d1SAndroid Build Coastguard Worker if (value % alignment)
705*bbecb9d1SAndroid Build Coastguard Worker return value + (alignment - (value % alignment));
706*bbecb9d1SAndroid Build Coastguard Worker return value;
707*bbecb9d1SAndroid Build Coastguard Worker }
708*bbecb9d1SAndroid Build Coastguard Worker
709*bbecb9d1SAndroid Build Coastguard Worker static inline unsigned
u_minify(unsigned value,unsigned levels)710*bbecb9d1SAndroid Build Coastguard Worker u_minify(unsigned value, unsigned levels)
711*bbecb9d1SAndroid Build Coastguard Worker {
712*bbecb9d1SAndroid Build Coastguard Worker return MAX2(1, value >> levels);
713*bbecb9d1SAndroid Build Coastguard Worker }
714*bbecb9d1SAndroid Build Coastguard Worker
715*bbecb9d1SAndroid Build Coastguard Worker #ifndef COPY_4V
716*bbecb9d1SAndroid Build Coastguard Worker #define COPY_4V( DST, SRC ) \
717*bbecb9d1SAndroid Build Coastguard Worker do { \
718*bbecb9d1SAndroid Build Coastguard Worker (DST)[0] = (SRC)[0]; \
719*bbecb9d1SAndroid Build Coastguard Worker (DST)[1] = (SRC)[1]; \
720*bbecb9d1SAndroid Build Coastguard Worker (DST)[2] = (SRC)[2]; \
721*bbecb9d1SAndroid Build Coastguard Worker (DST)[3] = (SRC)[3]; \
722*bbecb9d1SAndroid Build Coastguard Worker } while (0)
723*bbecb9d1SAndroid Build Coastguard Worker #endif
724*bbecb9d1SAndroid Build Coastguard Worker
725*bbecb9d1SAndroid Build Coastguard Worker
726*bbecb9d1SAndroid Build Coastguard Worker #ifndef COPY_4FV
727*bbecb9d1SAndroid Build Coastguard Worker #define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC)
728*bbecb9d1SAndroid Build Coastguard Worker #endif
729*bbecb9d1SAndroid Build Coastguard Worker
730*bbecb9d1SAndroid Build Coastguard Worker
731*bbecb9d1SAndroid Build Coastguard Worker #ifndef ASSIGN_4V
732*bbecb9d1SAndroid Build Coastguard Worker #define ASSIGN_4V( DST, V0, V1, V2, V3 ) \
733*bbecb9d1SAndroid Build Coastguard Worker do { \
734*bbecb9d1SAndroid Build Coastguard Worker (DST)[0] = (V0); \
735*bbecb9d1SAndroid Build Coastguard Worker (DST)[1] = (V1); \
736*bbecb9d1SAndroid Build Coastguard Worker (DST)[2] = (V2); \
737*bbecb9d1SAndroid Build Coastguard Worker (DST)[3] = (V3); \
738*bbecb9d1SAndroid Build Coastguard Worker } while (0)
739*bbecb9d1SAndroid Build Coastguard Worker #endif
740*bbecb9d1SAndroid Build Coastguard Worker
741*bbecb9d1SAndroid Build Coastguard Worker
742*bbecb9d1SAndroid Build Coastguard Worker static inline uint32_t
util_unsigned_fixed(float value,unsigned frac_bits)743*bbecb9d1SAndroid Build Coastguard Worker util_unsigned_fixed(float value, unsigned frac_bits)
744*bbecb9d1SAndroid Build Coastguard Worker {
745*bbecb9d1SAndroid Build Coastguard Worker return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits));
746*bbecb9d1SAndroid Build Coastguard Worker }
747*bbecb9d1SAndroid Build Coastguard Worker
748*bbecb9d1SAndroid Build Coastguard Worker static inline int32_t
util_signed_fixed(float value,unsigned frac_bits)749*bbecb9d1SAndroid Build Coastguard Worker util_signed_fixed(float value, unsigned frac_bits)
750*bbecb9d1SAndroid Build Coastguard Worker {
751*bbecb9d1SAndroid Build Coastguard Worker return (int32_t)(value * (1<<frac_bits));
752*bbecb9d1SAndroid Build Coastguard Worker }
753*bbecb9d1SAndroid Build Coastguard Worker
754*bbecb9d1SAndroid Build Coastguard Worker unsigned
755*bbecb9d1SAndroid Build Coastguard Worker util_fpstate_get(void);
756*bbecb9d1SAndroid Build Coastguard Worker unsigned
757*bbecb9d1SAndroid Build Coastguard Worker util_fpstate_set_denorms_to_zero(unsigned current_fpstate);
758*bbecb9d1SAndroid Build Coastguard Worker void
759*bbecb9d1SAndroid Build Coastguard Worker util_fpstate_set(unsigned fpstate);
760*bbecb9d1SAndroid Build Coastguard Worker
761*bbecb9d1SAndroid Build Coastguard Worker /**
762*bbecb9d1SAndroid Build Coastguard Worker * For indexed draw calls, return true if the vertex count to be drawn is
763*bbecb9d1SAndroid Build Coastguard Worker * much lower than the vertex count that has to be uploaded, meaning
764*bbecb9d1SAndroid Build Coastguard Worker * that the driver should flatten indices instead of trying to upload
765*bbecb9d1SAndroid Build Coastguard Worker * a too big range.
766*bbecb9d1SAndroid Build Coastguard Worker *
767*bbecb9d1SAndroid Build Coastguard Worker * This is used by vertex upload code in u_vbuf and glthread.
768*bbecb9d1SAndroid Build Coastguard Worker */
769*bbecb9d1SAndroid Build Coastguard Worker static inline bool
util_is_vbo_upload_ratio_too_large(unsigned draw_vertex_count,unsigned upload_vertex_count)770*bbecb9d1SAndroid Build Coastguard Worker util_is_vbo_upload_ratio_too_large(unsigned draw_vertex_count,
771*bbecb9d1SAndroid Build Coastguard Worker unsigned upload_vertex_count)
772*bbecb9d1SAndroid Build Coastguard Worker {
773*bbecb9d1SAndroid Build Coastguard Worker if (draw_vertex_count > 1024)
774*bbecb9d1SAndroid Build Coastguard Worker return upload_vertex_count > draw_vertex_count * 4;
775*bbecb9d1SAndroid Build Coastguard Worker else if (draw_vertex_count > 32)
776*bbecb9d1SAndroid Build Coastguard Worker return upload_vertex_count > draw_vertex_count * 8;
777*bbecb9d1SAndroid Build Coastguard Worker else
778*bbecb9d1SAndroid Build Coastguard Worker return upload_vertex_count > draw_vertex_count * 16;
779*bbecb9d1SAndroid Build Coastguard Worker }
780*bbecb9d1SAndroid Build Coastguard Worker
781*bbecb9d1SAndroid Build Coastguard Worker bool util_invert_mat4x4(float *out, const float *m);
782*bbecb9d1SAndroid Build Coastguard Worker
783*bbecb9d1SAndroid Build Coastguard Worker /* Quantize the lod bias value to reduce the number of sampler state
784*bbecb9d1SAndroid Build Coastguard Worker * variants in gallium because apps use it for smooth mipmap transitions,
785*bbecb9d1SAndroid Build Coastguard Worker * thrashing cso_cache and degrading performance.
786*bbecb9d1SAndroid Build Coastguard Worker *
787*bbecb9d1SAndroid Build Coastguard Worker * This quantization matches the AMD hw specification, so having more
788*bbecb9d1SAndroid Build Coastguard Worker * precision would have no effect anyway.
789*bbecb9d1SAndroid Build Coastguard Worker */
790*bbecb9d1SAndroid Build Coastguard Worker static inline float
util_quantize_lod_bias(float lod)791*bbecb9d1SAndroid Build Coastguard Worker util_quantize_lod_bias(float lod)
792*bbecb9d1SAndroid Build Coastguard Worker {
793*bbecb9d1SAndroid Build Coastguard Worker lod = CLAMP(lod, -16, 16);
794*bbecb9d1SAndroid Build Coastguard Worker return roundf(lod * 256) / 256;
795*bbecb9d1SAndroid Build Coastguard Worker }
796*bbecb9d1SAndroid Build Coastguard Worker
797*bbecb9d1SAndroid Build Coastguard Worker #ifdef __cplusplus
798*bbecb9d1SAndroid Build Coastguard Worker }
799*bbecb9d1SAndroid Build Coastguard Worker #endif
800*bbecb9d1SAndroid Build Coastguard Worker
801*bbecb9d1SAndroid Build Coastguard Worker #endif /* U_MATH_H */
802