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