00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00038 #ifndef U_MATH_H
00039 #define U_MATH_H
00040
00041
00042 #include "pipe/p_compiler.h"
00043 #include "pipe/p_debug.h"
00044
00045
00046 #ifdef __cplusplus
00047 extern "C" {
00048 #endif
00049
00050
00051 #if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
00052 __inline double ceil(double val)
00053 {
00054 double ceil_val;
00055
00056 if((val - (long) val) == 0) {
00057 ceil_val = val;
00058 }
00059 else {
00060 if(val > 0) {
00061 ceil_val = (long) val + 1;
00062 }
00063 else {
00064 ceil_val = (long) val;
00065 }
00066 }
00067
00068 return ceil_val;
00069 }
00070
00071 #ifndef PIPE_SUBSYSTEM_WINDOWS_CE
00072 __inline double floor(double val)
00073 {
00074 double floor_val;
00075
00076 if((val - (long) val) == 0) {
00077 floor_val = val;
00078 }
00079 else {
00080 if(val > 0) {
00081 floor_val = (long) val;
00082 }
00083 else {
00084 floor_val = (long) val - 1;
00085 }
00086 }
00087
00088 return floor_val;
00089 }
00090 #endif
00091
00092 #pragma function(pow)
00093 __inline double __cdecl pow(double val, double exponent)
00094 {
00095
00096 assert(0);
00097 return 0;
00098 }
00099
00100 #pragma function(log)
00101 __inline double __cdecl log(double val)
00102 {
00103
00104 assert(0);
00105 return 0;
00106 }
00107
00108 #pragma function(atan2)
00109 __inline double __cdecl atan2(double val)
00110 {
00111
00112 assert(0);
00113 return 0;
00114 }
00115 #else
00116 #include <math.h>
00117 #include <stdarg.h>
00118 #endif
00119
00120
00121 #if defined(_MSC_VER)
00122
00123 #if _MSC_VER < 1400 && !defined(__cplusplus) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
00124
00125 static INLINE float cosf( float f )
00126 {
00127 return (float) cos( (double) f );
00128 }
00129
00130 static INLINE float sinf( float f )
00131 {
00132 return (float) sin( (double) f );
00133 }
00134
00135 static INLINE float ceilf( float f )
00136 {
00137 return (float) ceil( (double) f );
00138 }
00139
00140 static INLINE float floorf( float f )
00141 {
00142 return (float) floor( (double) f );
00143 }
00144
00145 static INLINE float powf( float f, float g )
00146 {
00147 return (float) pow( (double) f, (double) g );
00148 }
00149
00150 static INLINE float sqrtf( float f )
00151 {
00152 return (float) sqrt( (double) f );
00153 }
00154
00155 static INLINE float fabsf( float f )
00156 {
00157 return (float) fabs( (double) f );
00158 }
00159
00160 static INLINE float logf( float f )
00161 {
00162 return (float) log( (double) f );
00163 }
00164
00165 #else
00166
00167 #ifdef logf
00168 #undef logf
00169 #define logf(x) ((float)log((double)(x)))
00170 #endif
00171 #endif
00172
00173 static INLINE double log2( double x )
00174 {
00175 const double invln2 = 1.442695041;
00176 return log( x ) * invln2;
00177 }
00178
00179 #endif
00180
00181
00182
00183
00184
00185 #define POW2_TABLE_SIZE_LOG2 9
00186 #define POW2_TABLE_SIZE (1 << POW2_TABLE_SIZE_LOG2)
00187 #define POW2_TABLE_OFFSET (POW2_TABLE_SIZE/2)
00188 #define POW2_TABLE_SCALE ((float)(POW2_TABLE_SIZE/2))
00189 extern float pow2_table[POW2_TABLE_SIZE];
00190
00191
00192
00193 extern void
00194 util_init_math(void);
00195
00196
00197 union fi {
00198 float f;
00199 int32_t i;
00200 uint32_t ui;
00201 };
00202
00203
00213 static INLINE float
00214 util_fast_exp2(float x)
00215 {
00216 int32_t ipart;
00217 float fpart, mpart;
00218 union fi epart;
00219
00220 if(x > 129.00000f)
00221 return 3.402823466e+38f;
00222
00223 if(x < -126.99999f)
00224 return 0.0f;
00225
00226 ipart = (int32_t) x;
00227 fpart = x - (float) ipart;
00228
00229
00230
00231
00232 epart.i = (ipart + 127 ) << 23;
00233
00234 mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)];
00235
00236 return epart.f * mpart;
00237 }
00238
00239
00243 static INLINE float
00244 util_fast_exp(float x)
00245 {
00246 const float k = 1.44269f;
00247 return util_fast_exp2(k * x);
00248 }
00249
00250
00251 #define LOG2_TABLE_SIZE_LOG2 16
00252 #define LOG2_TABLE_SCALE (1 << LOG2_TABLE_SIZE_LOG2)
00253 #define LOG2_TABLE_SIZE (LOG2_TABLE_SCALE + 1)
00254 extern float log2_table[LOG2_TABLE_SIZE];
00255
00256
00257 static INLINE float
00258 util_fast_log2(float x)
00259 {
00260 union fi num;
00261 float epart, mpart;
00262 num.f = x;
00263 epart = (float)(((num.i & 0x7f800000) >> 23) - 127);
00264
00265 mpart = log2_table[((num.i & 0x007fffff) + (1 << (22 - LOG2_TABLE_SIZE_LOG2))) >> (23 - LOG2_TABLE_SIZE_LOG2)];
00266 return epart + mpart;
00267 }
00268
00269
00270 static INLINE float
00271 util_fast_pow(float x, float y)
00272 {
00273 return util_fast_exp2(util_fast_log2(x) * y);
00274 }
00275
00276
00277
00281 static INLINE int
00282 util_ifloor(float f)
00283 {
00284 int ai, bi;
00285 double af, bf;
00286 union fi u;
00287 af = (3 << 22) + 0.5 + (double)f;
00288 bf = (3 << 22) + 0.5 - (double)f;
00289 u.f = (float) af; ai = u.i;
00290 u.f = (float) bf; bi = u.i;
00291 return (ai - bi) >> 1;
00292 }
00293
00294
00298 static INLINE int
00299 util_iround(float f)
00300 {
00301 #if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)
00302 int r;
00303 __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
00304 return r;
00305 #elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
00306 int r;
00307 _asm {
00308 fld f
00309 fistp r
00310 }
00311 return r;
00312 #else
00313 if (f >= 0.0f)
00314 return (int) (f + 0.5f);
00315 else
00316 return (int) (f - 0.5f);
00317 #endif
00318 }
00319
00320
00321
00322 #if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
00323
00327 static INLINE
00328 unsigned ffs( unsigned u )
00329 {
00330 unsigned i;
00331
00332 if( u == 0 ) {
00333 return 0;
00334 }
00335
00336 __asm bsf eax, [u]
00337 __asm inc eax
00338 __asm mov [i], eax
00339
00340 return i;
00341 }
00342 #endif
00343
00344 #ifdef __MINGW32__
00345 #define ffs __builtin_ffs
00346 #endif
00347
00348
00352 static INLINE unsigned
00353 fui( float f )
00354 {
00355 union fi fi;
00356 fi.f = f;
00357 return fi.ui;
00358 }
00359
00360
00361
00362 static INLINE float
00363 ubyte_to_float(ubyte ub)
00364 {
00365 return (float) ub * (1.0f / 255.0f);
00366 }
00367
00368
00372 static INLINE ubyte
00373 float_to_ubyte(float f)
00374 {
00375 const int ieee_0996 = 0x3f7f0000;
00376 union fi tmp;
00377
00378 tmp.f = f;
00379 if (tmp.i < 0) {
00380 return (ubyte) 0;
00381 }
00382 else if (tmp.i >= ieee_0996) {
00383 return (ubyte) 255;
00384 }
00385 else {
00386 tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f;
00387 return (ubyte) tmp.i;
00388 }
00389 }
00390
00391
00392
00393 #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
00394
00395 #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
00396 #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
00397
00398
00399 static INLINE int
00400 align(int value, int alignment)
00401 {
00402 return (value + alignment - 1) & ~(alignment - 1);
00403 }
00404
00405
00406 #ifndef COPY_4V
00407 #define COPY_4V( DST, SRC ) \
00408 do { \
00409 (DST)[0] = (SRC)[0]; \
00410 (DST)[1] = (SRC)[1]; \
00411 (DST)[2] = (SRC)[2]; \
00412 (DST)[3] = (SRC)[3]; \
00413 } while (0)
00414 #endif
00415
00416
00417 #ifndef COPY_4FV
00418 #define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC)
00419 #endif
00420
00421
00422 #ifndef ASSIGN_4V
00423 #define ASSIGN_4V( DST, V0, V1, V2, V3 ) \
00424 do { \
00425 (DST)[0] = (V0); \
00426 (DST)[1] = (V1); \
00427 (DST)[2] = (V2); \
00428 (DST)[3] = (V3); \
00429 } while (0)
00430 #endif
00431
00432
00433 #ifdef __cplusplus
00434 }
00435 #endif
00436
00437 #endif