imports.h revision 2efa86ea3040c37965987160733b22e2a0541a3e
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * \file imports.h 28 * Standard C library function wrappers. 29 * 30 * This file provides wrappers for all the standard C library functions 31 * like malloc(), free(), printf(), getenv(), etc. 32 */ 33 34 35#ifndef IMPORTS_H 36#define IMPORTS_H 37 38 39#include "compiler.h" 40#include "glheader.h" 41 42 43#ifdef __cplusplus 44extern "C" { 45#endif 46 47 48/**********************************************************************/ 49/** Memory macros */ 50/*@{*/ 51 52/** Allocate \p BYTES bytes */ 53#define MALLOC(BYTES) _mesa_malloc(BYTES) 54/** Allocate and zero \p BYTES bytes */ 55#define CALLOC(BYTES) _mesa_calloc(BYTES) 56/** Allocate a structure of type \p T */ 57#define MALLOC_STRUCT(T) (struct T *) _mesa_malloc(sizeof(struct T)) 58/** Allocate and zero a structure of type \p T */ 59#define CALLOC_STRUCT(T) (struct T *) _mesa_calloc(sizeof(struct T)) 60/** Free memory */ 61#define FREE(PTR) _mesa_free(PTR) 62 63/** Allocate \p BYTES aligned at \p N bytes */ 64#define ALIGN_MALLOC(BYTES, N) _mesa_align_malloc(BYTES, N) 65/** Allocate and zero \p BYTES bytes aligned at \p N bytes */ 66#define ALIGN_CALLOC(BYTES, N) _mesa_align_calloc(BYTES, N) 67/** Allocate a structure of type \p T aligned at \p N bytes */ 68#define ALIGN_MALLOC_STRUCT(T, N) (struct T *) _mesa_align_malloc(sizeof(struct T), N) 69/** Allocate and zero a structure of type \p T aligned at \p N bytes */ 70#define ALIGN_CALLOC_STRUCT(T, N) (struct T *) _mesa_align_calloc(sizeof(struct T), N) 71/** Free aligned memory */ 72#define ALIGN_FREE(PTR) _mesa_align_free(PTR) 73 74/** Copy \p BYTES bytes from \p SRC into \p DST */ 75#define MEMCPY( DST, SRC, BYTES) memcpy(DST, SRC, BYTES) 76/** Set \p N bytes in \p DST to \p VAL */ 77#define MEMSET( DST, VAL, N ) memset(DST, VAL, N) 78 79/*@}*/ 80 81 82/* 83 * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers 84 * as offsets into buffer stores. Since the vertex array pointer and 85 * buffer store pointer are both pointers and we need to add them, we use 86 * this macro. 87 * Both pointers/offsets are expressed in bytes. 88 */ 89#define ADD_POINTERS(A, B) ( (GLubyte *) (A) + (uintptr_t) (B) ) 90 91 92/** 93 * Sometimes we treat GLfloats as GLints. On x86 systems, moving a float 94 * as a int (thereby using integer registers instead of FP registers) is 95 * a performance win. Typically, this can be done with ordinary casts. 96 * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0) 97 * these casts generate warnings. 98 * The following union typedef is used to solve that. 99 */ 100typedef union { GLfloat f; GLint i; } fi_type; 101 102 103 104/********************************************************************** 105 * Math macros 106 */ 107 108#define MAX_GLUSHORT 0xffff 109#define MAX_GLUINT 0xffffffff 110 111/* Degrees to radians conversion: */ 112#define DEG2RAD (M_PI/180.0) 113 114 115/*** 116 *** SQRTF: single-precision square root 117 ***/ 118#if 0 /* _mesa_sqrtf() not accurate enough - temporarily disabled */ 119# define SQRTF(X) _mesa_sqrtf(X) 120#else 121# define SQRTF(X) (float) sqrt((float) (X)) 122#endif 123 124 125/*** 126 *** INV_SQRTF: single-precision inverse square root 127 ***/ 128#if 0 129#define INV_SQRTF(X) _mesa_inv_sqrt(X) 130#else 131#define INV_SQRTF(X) (1.0F / SQRTF(X)) /* this is faster on a P4 */ 132#endif 133 134 135/*** 136 *** LOG2: Log base 2 of float 137 ***/ 138#ifdef USE_IEEE 139#if 0 140/* This is pretty fast, but not accurate enough (only 2 fractional bits). 141 * Based on code from http://www.stereopsis.com/log2.html 142 */ 143static INLINE GLfloat LOG2(GLfloat x) 144{ 145 const GLfloat y = x * x * x * x; 146 const GLuint ix = *((GLuint *) &y); 147 const GLuint exp = (ix >> 23) & 0xFF; 148 const GLint log2 = ((GLint) exp) - 127; 149 return (GLfloat) log2 * (1.0 / 4.0); /* 4, because of x^4 above */ 150} 151#endif 152/* Pretty fast, and accurate. 153 * Based on code from http://www.flipcode.com/totd/ 154 */ 155static INLINE GLfloat LOG2(GLfloat val) 156{ 157 fi_type num; 158 GLint log_2; 159 num.f = val; 160 log_2 = ((num.i >> 23) & 255) - 128; 161 num.i &= ~(255 << 23); 162 num.i += 127 << 23; 163 num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3; 164 return num.f + log_2; 165} 166#else 167/* 168 * NOTE: log_base_2(x) = log(x) / log(2) 169 * NOTE: 1.442695 = 1/log(2). 170 */ 171#define LOG2(x) ((GLfloat) (log(x) * 1.442695F)) 172#endif 173 174 175/*** 176 *** IS_INF_OR_NAN: test if float is infinite or NaN 177 ***/ 178#ifdef USE_IEEE 179static INLINE int IS_INF_OR_NAN( float x ) 180{ 181 fi_type tmp; 182 tmp.f = x; 183 return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31); 184} 185#elif defined(isfinite) 186#define IS_INF_OR_NAN(x) (!isfinite(x)) 187#elif defined(finite) 188#define IS_INF_OR_NAN(x) (!finite(x)) 189#elif defined(__VMS) 190#define IS_INF_OR_NAN(x) (!finite(x)) 191#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 192#define IS_INF_OR_NAN(x) (!isfinite(x)) 193#else 194#define IS_INF_OR_NAN(x) (!finite(x)) 195#endif 196 197 198/*** 199 *** IS_NEGATIVE: test if float is negative 200 ***/ 201#if defined(USE_IEEE) 202static INLINE int GET_FLOAT_BITS( float x ) 203{ 204 fi_type fi; 205 fi.f = x; 206 return fi.i; 207} 208#define IS_NEGATIVE(x) (GET_FLOAT_BITS(x) < 0) 209#else 210#define IS_NEGATIVE(x) (x < 0.0F) 211#endif 212 213 214/*** 215 *** DIFFERENT_SIGNS: test if two floats have opposite signs 216 ***/ 217#if defined(USE_IEEE) 218#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31)) 219#else 220/* Could just use (x*y<0) except for the flatshading requirements. 221 * Maybe there's a better way? 222 */ 223#define DIFFERENT_SIGNS(x,y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) 224#endif 225 226 227/*** 228 *** CEILF: ceiling of float 229 *** FLOORF: floor of float 230 *** FABSF: absolute value of float 231 *** LOGF: the natural logarithm (base e) of the value 232 *** EXPF: raise e to the value 233 *** LDEXPF: multiply value by an integral power of two 234 *** FREXPF: extract mantissa and exponent from value 235 ***/ 236#if defined(__gnu_linux__) 237/* C99 functions */ 238#define CEILF(x) ceilf(x) 239#define FLOORF(x) floorf(x) 240#define FABSF(x) fabsf(x) 241#define LOGF(x) logf(x) 242#define EXPF(x) expf(x) 243#define LDEXPF(x,y) ldexpf(x,y) 244#define FREXPF(x,y) frexpf(x,y) 245#else 246#define CEILF(x) ((GLfloat) ceil(x)) 247#define FLOORF(x) ((GLfloat) floor(x)) 248#define FABSF(x) ((GLfloat) fabs(x)) 249#define LOGF(x) ((GLfloat) log(x)) 250#define EXPF(x) ((GLfloat) exp(x)) 251#define LDEXPF(x,y) ((GLfloat) ldexp(x,y)) 252#define FREXPF(x,y) ((GLfloat) frexp(x,y)) 253#endif 254 255 256/*** 257 *** IROUND: return (as an integer) float rounded to nearest integer 258 ***/ 259#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) && \ 260 (!(defined(__BEOS__) || defined(__HAIKU__)) || \ 261 (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))) 262static INLINE int iround(float f) 263{ 264 int r; 265 __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); 266 return r; 267} 268#define IROUND(x) iround(x) 269#elif defined(USE_X86_ASM) && defined(_MSC_VER) 270static INLINE int iround(float f) 271{ 272 int r; 273 _asm { 274 fld f 275 fistp r 276 } 277 return r; 278} 279#define IROUND(x) iround(x) 280#elif defined(__WATCOMC__) && defined(__386__) 281long iround(float f); 282#pragma aux iround = \ 283 "push eax" \ 284 "fistp dword ptr [esp]" \ 285 "pop eax" \ 286 parm [8087] \ 287 value [eax] \ 288 modify exact [eax]; 289#define IROUND(x) iround(x) 290#else 291#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) 292#endif 293 294#define IROUND64(f) ((GLint64) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) 295 296/*** 297 *** IROUND_POS: return (as an integer) positive float rounded to nearest int 298 ***/ 299#ifdef DEBUG 300#define IROUND_POS(f) (assert((f) >= 0.0F), IROUND(f)) 301#else 302#define IROUND_POS(f) (IROUND(f)) 303#endif 304 305 306/*** 307 *** IFLOOR: return (as an integer) floor of float 308 ***/ 309#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) 310/* 311 * IEEE floor for computers that round to nearest or even. 312 * 'f' must be between -4194304 and 4194303. 313 * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1", 314 * but uses some IEEE specific tricks for better speed. 315 * Contributed by Josh Vanderhoof 316 */ 317static INLINE int ifloor(float f) 318{ 319 int ai, bi; 320 double af, bf; 321 af = (3 << 22) + 0.5 + (double)f; 322 bf = (3 << 22) + 0.5 - (double)f; 323 /* GCC generates an extra fstp/fld without this. */ 324 __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st"); 325 __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st"); 326 return (ai - bi) >> 1; 327} 328#define IFLOOR(x) ifloor(x) 329#elif defined(USE_IEEE) 330static INLINE int ifloor(float f) 331{ 332 int ai, bi; 333 double af, bf; 334 fi_type u; 335 336 af = (3 << 22) + 0.5 + (double)f; 337 bf = (3 << 22) + 0.5 - (double)f; 338 u.f = (float) af; ai = u.i; 339 u.f = (float) bf; bi = u.i; 340 return (ai - bi) >> 1; 341} 342#define IFLOOR(x) ifloor(x) 343#else 344static INLINE int ifloor(float f) 345{ 346 int i = IROUND(f); 347 return (i > f) ? i - 1 : i; 348} 349#define IFLOOR(x) ifloor(x) 350#endif 351 352 353/*** 354 *** ICEIL: return (as an integer) ceiling of float 355 ***/ 356#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) 357/* 358 * IEEE ceil for computers that round to nearest or even. 359 * 'f' must be between -4194304 and 4194303. 360 * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1", 361 * but uses some IEEE specific tricks for better speed. 362 * Contributed by Josh Vanderhoof 363 */ 364static INLINE int iceil(float f) 365{ 366 int ai, bi; 367 double af, bf; 368 af = (3 << 22) + 0.5 + (double)f; 369 bf = (3 << 22) + 0.5 - (double)f; 370 /* GCC generates an extra fstp/fld without this. */ 371 __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st"); 372 __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st"); 373 return (ai - bi + 1) >> 1; 374} 375#define ICEIL(x) iceil(x) 376#elif defined(USE_IEEE) 377static INLINE int iceil(float f) 378{ 379 int ai, bi; 380 double af, bf; 381 fi_type u; 382 af = (3 << 22) + 0.5 + (double)f; 383 bf = (3 << 22) + 0.5 - (double)f; 384 u.f = (float) af; ai = u.i; 385 u.f = (float) bf; bi = u.i; 386 return (ai - bi + 1) >> 1; 387} 388#define ICEIL(x) iceil(x) 389#else 390static INLINE int iceil(float f) 391{ 392 int i = IROUND(f); 393 return (i < f) ? i + 1 : i; 394} 395#define ICEIL(x) iceil(x) 396#endif 397 398 399/** 400 * Is x a power of two? 401 */ 402static INLINE int 403_mesa_is_pow_two(int x) 404{ 405 return !(x & (x - 1)); 406} 407 408/** 409 * Round given integer to next higer power of two 410 * If X is zero result is undefined. 411 * 412 * Source for the fallback implementation is 413 * Sean Eron Anderson's webpage "Bit Twiddling Hacks" 414 * http://graphics.stanford.edu/~seander/bithacks.html 415 * 416 * When using builtin function have to do some work 417 * for case when passed values 1 to prevent hiting 418 * undefined result from __builtin_clz. Undefined 419 * results would be different depending on optimization 420 * level used for build. 421 */ 422static INLINE int32_t 423_mesa_next_pow_two_32(uint32_t x) 424{ 425#ifdef __GNUC__ 426 uint32_t y = (x != 1); 427 return (1 + y) << ((__builtin_clz(x - y) ^ 31) ); 428#else 429 x--; 430 x |= x >> 1; 431 x |= x >> 2; 432 x |= x >> 4; 433 x |= x >> 8; 434 x |= x >> 16; 435 x++; 436 return x; 437#endif 438} 439 440static INLINE int64_t 441_mesa_next_pow_two_64(uint64_t x) 442{ 443#ifdef __GNUC__ 444 uint64_t y = (x != 1); 445 if (sizeof(x) == sizeof(long)) 446 return (1 + y) << ((__builtin_clzl(x - y) ^ 63)); 447 else 448 return (1 + y) << ((__builtin_clzll(x - y) ^ 63)); 449#else 450 x--; 451 x |= x >> 1; 452 x |= x >> 2; 453 x |= x >> 4; 454 x |= x >> 8; 455 x |= x >> 16; 456 x |= x >> 32; 457 x++; 458 return x; 459#endif 460} 461 462 463/*** 464 *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] 465 *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255] 466 ***/ 467#if defined(USE_IEEE) && !defined(DEBUG) 468#define IEEE_0996 0x3f7f0000 /* 0.996 or so */ 469/* This function/macro is sensitive to precision. Test very carefully 470 * if you change it! 471 */ 472#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F) \ 473 do { \ 474 fi_type __tmp; \ 475 __tmp.f = (F); \ 476 if (__tmp.i < 0) \ 477 UB = (GLubyte) 0; \ 478 else if (__tmp.i >= IEEE_0996) \ 479 UB = (GLubyte) 255; \ 480 else { \ 481 __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F; \ 482 UB = (GLubyte) __tmp.i; \ 483 } \ 484 } while (0) 485#define CLAMPED_FLOAT_TO_UBYTE(UB, F) \ 486 do { \ 487 fi_type __tmp; \ 488 __tmp.f = (F) * (255.0F/256.0F) + 32768.0F; \ 489 UB = (GLubyte) __tmp.i; \ 490 } while (0) 491#else 492#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \ 493 ub = ((GLubyte) IROUND(CLAMP((f), 0.0F, 1.0F) * 255.0F)) 494#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \ 495 ub = ((GLubyte) IROUND((f) * 255.0F)) 496#endif 497 498 499/** 500 * Return 1 if this is a little endian machine, 0 if big endian. 501 */ 502static INLINE GLboolean 503_mesa_little_endian(void) 504{ 505 const GLuint ui = 1; /* intentionally not static */ 506 return *((const GLubyte *) &ui); 507} 508 509 510 511/********************************************************************** 512 * Functions 513 */ 514 515extern void * 516_mesa_malloc( size_t bytes ); 517 518extern void * 519_mesa_calloc( size_t bytes ); 520 521extern void 522_mesa_free( void *ptr ); 523 524extern void * 525_mesa_align_malloc( size_t bytes, unsigned long alignment ); 526 527extern void * 528_mesa_align_calloc( size_t bytes, unsigned long alignment ); 529 530extern void 531_mesa_align_free( void *ptr ); 532 533extern void * 534_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, 535 unsigned long alignment); 536 537extern void * 538_mesa_exec_malloc( GLuint size ); 539 540extern void 541_mesa_exec_free( void *addr ); 542 543extern void * 544_mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize ); 545 546extern void 547_mesa_memset16( unsigned short *dst, unsigned short val, size_t n ); 548 549extern void 550_mesa_bzero( void *dst, size_t n ); 551 552extern double 553_mesa_sin(double a); 554 555extern float 556_mesa_sinf(float a); 557 558extern double 559_mesa_cos(double a); 560 561extern float 562_mesa_asinf(float x); 563 564extern float 565_mesa_atanf(float x); 566 567extern double 568_mesa_sqrtd(double x); 569 570extern float 571_mesa_sqrtf(float x); 572 573extern float 574_mesa_inv_sqrtf(float x); 575 576extern void 577_mesa_init_sqrt_table(void); 578 579extern double 580_mesa_pow(double x, double y); 581 582extern int 583_mesa_ffs(int32_t i); 584 585extern int 586_mesa_ffsll(int64_t i); 587 588extern unsigned int 589_mesa_bitcount(unsigned int n); 590 591extern GLhalfARB 592_mesa_float_to_half(float f); 593 594extern float 595_mesa_half_to_float(GLhalfARB h); 596 597 598extern void * 599_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size, 600 int (*compar)(const void *, const void *) ); 601 602extern char * 603_mesa_getenv( const char *var ); 604 605extern char * 606_mesa_strdup( const char *s ); 607 608extern double 609_mesa_strtod( const char *s, char **end ); 610 611extern unsigned int 612_mesa_str_checksum(const char *str); 613 614extern int 615_mesa_sprintf( char *str, const char *fmt, ... ); 616 617extern int 618_mesa_snprintf( char *str, size_t size, const char *fmt, ... ); 619 620extern void 621_mesa_printf( const char *fmtString, ... ); 622 623extern void 624_mesa_fprintf( FILE *f, const char *fmtString, ... ); 625 626extern int 627_mesa_vsprintf( char *str, const char *fmt, va_list args ); 628 629 630extern void 631_mesa_warning( __GLcontext *gc, const char *fmtString, ... ); 632 633extern void 634_mesa_problem( const __GLcontext *ctx, const char *fmtString, ... ); 635 636extern void 637_mesa_error( __GLcontext *ctx, GLenum error, const char *fmtString, ... ); 638 639extern void 640_mesa_debug( const __GLcontext *ctx, const char *fmtString, ... ); 641 642#ifdef __cplusplus 643} 644#endif 645 646 647#endif /* IMPORTS_H */ 648