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