2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 * Imports are services which the device driver or window system or
28 * operating system provides to the core renderer. The core renderer (Mesa)
29 * will call these functions in order to do memory allocation, simple I/O,
32 * Some drivers will want to override/replace this file with something
33 * specialized, but that'll be rare.
35 * Eventually, I want to move roll the glheader.h file into this.
37 * The OpenGL SI's __GLimports structure allows per-context specification of
38 * replacements for the standard C lib functions. In practice that's probably
39 * never needed; compile-time replacements are far more likely.
41 * The _mesa_foo() functions defined here don't in general take a context
42 * parameter. I guess we can change that someday, if need be.
43 * So for now, the __GLimports stuff really isn't used.
51 #define MAXSTRING 4000 /* for vsnprintf() */
54 #define vsnprintf _vsnprintf
55 #elif defined(__IBMC__) || defined(__IBMCPP__) || defined(VMS)
56 extern int vsnprintf(char *str
, size_t count
, const char *fmt
, va_list arg
);
60 /**********************************************************************/
61 /* Wrappers for standard C library functions */
62 /**********************************************************************/
65 * Functions still needed:
73 /**********************************************************************
78 _mesa_malloc(size_t bytes
)
80 #if defined(XFree86LOADER) && defined(IN_MODULE)
81 return xf86malloc(bytes
);
89 _mesa_calloc(size_t bytes
)
91 #if defined(XFree86LOADER) && defined(IN_MODULE)
92 return xf86calloc(1, bytes
);
94 return calloc(1, bytes
);
100 _mesa_free(void *ptr
)
102 #if defined(XFree86LOADER) && defined(IN_MODULE)
111 _mesa_align_malloc(size_t bytes
, unsigned long alignment
)
113 unsigned long ptr
, buf
;
115 ASSERT( alignment
> 0 );
117 /* Allocate extra memory to accomodate rounding up the address for
118 * alignment and to record the real malloc address.
120 ptr
= (unsigned long) _mesa_malloc(bytes
+ alignment
+ sizeof(void *));
124 buf
= (ptr
+ alignment
+ sizeof(void *)) & ~(unsigned long)(alignment
- 1);
125 *(unsigned long *)(buf
- sizeof(void *)) = ptr
;
128 /* mark the non-aligned area */
129 while ( ptr
< buf
- sizeof(void *) ) {
130 *(unsigned long *)ptr
= 0xcdcdcdcd;
131 ptr
+= sizeof(unsigned long);
140 _mesa_align_calloc(size_t bytes
, unsigned long alignment
)
142 unsigned long ptr
, buf
;
144 ASSERT( alignment
> 0 );
146 ptr
= (unsigned long) _mesa_calloc(bytes
+ alignment
+ sizeof(void *));
150 buf
= (ptr
+ alignment
+ sizeof(void *)) & ~(unsigned long)(alignment
- 1);
151 *(unsigned long *)(buf
- sizeof(void *)) = ptr
;
154 /* mark the non-aligned area */
155 while ( ptr
< buf
- sizeof(void *) ) {
156 *(unsigned long *)ptr
= 0xcdcdcdcd;
157 ptr
+= sizeof(unsigned long);
166 _mesa_align_free(void *ptr
)
169 _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr
- sizeof(void *))) );
171 /* The actuall address to free is stuffed in the word immediately
172 * before the address the client sees.
174 void **cubbyHole
= (void **) ((char *) ptr
- sizeof(void *));
175 void *realAddr
= *cubbyHole
;
176 _mesa_free(realAddr
);
182 _mesa_realloc(void *oldBuffer
, size_t oldSize
, size_t newSize
)
184 const size_t copySize
= (oldSize
< newSize
) ? oldSize
: newSize
;
185 void *newBuffer
= _mesa_malloc(newSize
);
186 if (newBuffer
&& copySize
> 0)
187 _mesa_memcpy(newBuffer
, oldBuffer
, copySize
);
189 _mesa_free(oldBuffer
);
195 _mesa_memcpy(void *dest
, const void *src
, size_t n
)
197 #if defined(XFree86LOADER) && defined(IN_MODULE)
198 return xf86memcpy(dest
, src
, n
);
199 #elif defined(SUNOS4)
200 return memcpy((char *) dest
, (char *) src
, (int) n
);
202 return memcpy(dest
, src
, n
);
208 _mesa_memset( void *dst
, int val
, size_t n
)
210 #if defined(XFree86LOADER) && defined(IN_MODULE)
211 xf86memset( dst
, val
, n
);
212 #elif defined(SUNOS4)
213 memset( (char *) dst
, (int) val
, (int) n
);
221 _mesa_memset16( unsigned short *dst
, unsigned short val
, size_t n
)
229 _mesa_bzero( void *dst
, size_t n
)
231 #if defined(XFree86LOADER) && defined(IN_MODULE)
232 xf86memset( dst
, 0, n
);
233 #elif defined(__FreeBSD__)
241 /**********************************************************************
248 #if defined(XFree86LOADER) && defined(IN_MODULE)
259 #if defined(XFree86LOADER) && defined(IN_MODULE)
268 _mesa_sqrtd(double x
)
270 #if defined(XFree86LOADER) && defined(IN_MODULE)
279 * A High Speed, Low Precision Square Root
280 * by Paul Lalonde and Robert Dawson
281 * from "Graphics Gems", Academic Press, 1990
283 * SPARC implementation of a fast square root by table
285 * SPARC floating point format is as follows:
288 * sign exponent mantissa
290 static short sqrttab
[0x100]; /* declare table of square roots */
292 static void init_sqrt_table(void)
294 #if defined(USE_IEEE) && !defined(DEBUG)
296 fi_type fi
; /* to access the bits of a float in C quickly */
297 /* we use a union defined in glheader.h */
299 for(i
=0; i
<= 0x7f; i
++) {
303 * Build a float with the bit pattern i as mantissa
304 * and an exponent of 0, stored as 127
307 fi
.i
= (i
<< 16) | (127 << 23);
308 fi
.f
= _mesa_sqrtd(fi
.f
);
311 * Take the square root then strip the first 7 bits of
312 * the mantissa into the table
315 sqrttab
[i
] = (fi
.i
& 0x7fffff) >> 16;
318 * Repeat the process, this time with an exponent of
323 fi
.i
= (i
<< 16) | (128 << 23);
325 sqrttab
[i
+0x80] = (fi
.i
& 0x7fffff) >> 16;
328 (void) sqrttab
; /* silence compiler warnings */
329 #endif /*HAVE_FAST_MATH*/
334 _mesa_sqrtf( float x
)
336 #if defined(USE_IEEE) && !defined(DEBUG)
338 /* to access the bits of a float in C
339 * we use a union from glheader.h */
341 short e
; /* the exponent */
342 if (x
== 0.0F
) return 0.0F
; /* check for square root of 0 */
344 e
= (num
.i
>> 23) - 127; /* get the exponent - on a SPARC the */
345 /* exponent is stored with 127 added */
346 num
.i
&= 0x7fffff; /* leave only the mantissa */
347 if (e
& 0x01) num
.i
|= 0x800000;
348 /* the exponent is odd so we have to */
349 /* look it up in the second half of */
350 /* the lookup table, so we set the */
352 e
>>= 1; /* divide the exponent by two */
353 /* note that in C the shift */
354 /* operators are sign preserving */
355 /* for signed operands */
356 /* Do the table lookup, based on the quaternary mantissa,
357 * then reconstruct the result back into a float
359 num
.i
= ((sqrttab
[num
.i
>> 16]) << 16) | ((e
+ 127) << 23);
363 return (float) _mesa_sqrtd((double) x
);
369 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
370 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
374 _mesa_inv_sqrtf(float n
)
376 #if defined(USE_IEEE) && !defined(DEBUG)
380 #if 0 /* not used, see below -BP */
383 union { float f
; unsigned int i
; } u
;
387 Exponent part of the magic number -
390 1. subtract the bias from the exponent,
392 3. divide by two (rounding towards -inf)
395 Which is the same as subtracting the exponent from 381 and dividing
398 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
404 Significand part of magic number -
406 With the current magic number, "(magic - u.i) >> 1" will give you:
408 for 1 <= u.f <= 2: 1.25 - u.f / 4
409 for 2 <= u.f <= 4: 1.00 - u.f / 8
411 This isn't a bad approximation of 1/sqrt. The maximum difference from
412 1/sqrt will be around .06. After three Newton-Raphson iterations, the
413 maximum difference is less than 4.5e-8. (Which is actually close
414 enough to make the following bias academic...)
416 To get a better approximation you can add a bias to the magic
417 number. For example, if you subtract 1/2 of the maximum difference in
418 the first approximation (.03), you will get the following function:
420 for 1 <= u.f <= 2: 1.22 - u.f / 4
421 for 2 <= u.f <= 3.76: 0.97 - u.f / 8
422 for 3.76 <= u.f <= 4: 0.72 - u.f / 16
423 (The 3.76 to 4 range is where the result is < .5.)
425 This is the closest possible initial approximation, but with a maximum
426 error of 8e-11 after three NR iterations, it is still not perfect. If
427 you subtract 0.0332281 instead of .03, the maximum error will be
428 2.5e-11 after three NR iterations, which should be about as close as
431 for 1 <= u.f <= 2: 1.2167719 - u.f / 4
432 for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
433 for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
437 magic
-= (int)(0.0332281 * (1 << 25));
440 u
.i
= (magic
- u
.i
) >> 1;
443 Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
444 allows more parallelism. From what I understand, the parallelism
445 comes at the cost of less precision, because it lets error
446 accumulate across iterations.
461 return x2
* r2
; /* we can stop here, and be conformant -BP */
469 #elif defined(XFree86LOADER) && defined(IN_MODULE)
470 return 1.0F
/ xf86sqrt(n
);
472 return 1.0F
/ sqrt(n
);
478 _mesa_pow(double x
, double y
)
480 #if defined(XFree86LOADER) && defined(IN_MODULE)
481 return xf86pow(x
, y
);
489 * Return number of bits set in given GLuint.
492 _mesa_bitcount(unsigned int n
)
495 for (bits
= 0; n
> 0; n
= n
>> 1) {
503 /**********************************************************************
508 _mesa_getenv( const char *var
)
510 #if defined(XFree86LOADER) && defined(IN_MODULE)
511 return xf86getenv(var
);
518 /**********************************************************************
523 _mesa_strstr( const char *haystack
, const char *needle
)
525 #if defined(XFree86LOADER) && defined(IN_MODULE)
526 return xf86strstr(haystack
, needle
);
528 return strstr(haystack
, needle
);
534 _mesa_strncat( char *dest
, const char *src
, size_t n
)
536 #if defined(XFree86LOADER) && defined(IN_MODULE)
537 return xf86strncat(dest
, src
, n
);
539 return strncat(dest
, src
, n
);
545 _mesa_strcpy( char *dest
, const char *src
)
547 #if defined(XFree86LOADER) && defined(IN_MODULE)
548 return xf86strcpy(dest
, src
);
550 return strcpy(dest
, src
);
556 _mesa_strncpy( char *dest
, const char *src
, size_t n
)
558 #if defined(XFree86LOADER) && defined(IN_MODULE)
559 return xf86strncpy(dest
, src
, n
);
561 return strncpy(dest
, src
, n
);
567 _mesa_strlen( const char *s
)
569 #if defined(XFree86LOADER) && defined(IN_MODULE)
570 return xf86strlen(s
);
578 _mesa_strcmp( const char *s1
, const char *s2
)
580 #if defined(XFree86LOADER) && defined(IN_MODULE)
581 return xf86strcmp(s1
, s2
);
583 return strcmp(s1
, s2
);
589 _mesa_strncmp( const char *s1
, const char *s2
, size_t n
)
591 #if defined(XFree86LOADER) && defined(IN_MODULE)
592 return xf86strncmp(s1
, s2
, n
);
594 return strncmp(s1
, s2
, n
);
600 _mesa_strdup( const char *s
)
602 int l
= _mesa_strlen(s
);
603 char *s2
= (char *) _mesa_malloc(l
+ 1);
611 _mesa_atoi(const char *s
)
613 #if defined(XFree86LOADER) && defined(IN_MODULE)
622 _mesa_strtod( const char *s
, char **end
)
624 #if defined(XFree86LOADER) && defined(IN_MODULE)
625 return xf86strtod(s
, end
);
627 return strtod(s
, end
);
632 /**********************************************************************
637 _mesa_sprintf( char *str
, const char *fmt
, ... )
641 va_start( args
, fmt
);
643 #if defined(XFree86LOADER) && defined(IN_MODULE)
644 r
= xf86vsprintf( str
, fmt
, args
);
646 r
= vsprintf( str
, fmt
, args
);
653 _mesa_printf( const char *fmtString
, ... )
657 va_start( args
, fmtString
);
658 vsnprintf(s
, MAXSTRING
, fmtString
, args
);
660 #if defined(XFree86LOADER) && defined(IN_MODULE)
668 /**********************************************************************
673 _mesa_warning( GLcontext
*ctx
, const char *fmtString
, ... )
679 va_start( args
, fmtString
);
680 (void) vsnprintf( str
, MAXSTRING
, fmtString
, args
);
683 debug
= GL_TRUE
; /* always print warning */
685 debug
= _mesa_getenv("MESA_DEBUG") ? GL_TRUE
: GL_FALSE
;
688 #if defined(XFree86LOADER) && defined(IN_MODULE)
689 xf86fprintf(stderr
, "Mesa warning: %s\n", str
);
691 fprintf(stderr
, "Mesa warning: %s\n", str
);
698 * This function is called when the Mesa user has stumbled into a code
699 * path which may not be implemented fully or correctly.
702 _mesa_problem( const GLcontext
*ctx
, const char *fmtString
, ... )
708 va_start( args
, fmtString
);
709 vsnprintf( str
, MAXSTRING
, fmtString
, args
);
712 #if defined(XFree86LOADER) && defined(IN_MODULE)
713 xf86fprintf(stderr
, "Mesa implementation error: %s\n", str
);
714 xf86fprintf(stderr
, "Please report to the DRI project at dri.sourceforge.net\n");
716 fprintf(stderr
, "Mesa implementation error: %s\n", str
);
717 fprintf(stderr
, "Please report to the Mesa bug database at www.mesa3d.org\n" );
723 * If in debug mode, print error message to stdout.
724 * Also, record the error code by calling _mesa_record_error().
725 * Input: ctx - the GL context
726 * error - the error value
727 * fmtString - printf-style format string, followed by optional args
730 _mesa_error( GLcontext
*ctx
, GLenum error
, const char *fmtString
, ... )
732 const char *debugEnv
;
735 debugEnv
= _mesa_getenv("MESA_DEBUG");
738 if (debugEnv
&& _mesa_strstr(debugEnv
, "silent"))
751 char where
[MAXSTRING
];
754 va_start( args
, fmtString
);
755 vsnprintf( where
, MAXSTRING
, fmtString
, args
);
760 errstr
= "GL_NO_ERROR";
762 case GL_INVALID_VALUE
:
763 errstr
= "GL_INVALID_VALUE";
765 case GL_INVALID_ENUM
:
766 errstr
= "GL_INVALID_ENUM";
768 case GL_INVALID_OPERATION
:
769 errstr
= "GL_INVALID_OPERATION";
771 case GL_STACK_OVERFLOW
:
772 errstr
= "GL_STACK_OVERFLOW";
774 case GL_STACK_UNDERFLOW
:
775 errstr
= "GL_STACK_UNDERFLOW";
777 case GL_OUT_OF_MEMORY
:
778 errstr
= "GL_OUT_OF_MEMORY";
780 case GL_TABLE_TOO_LARGE
:
781 errstr
= "GL_TABLE_TOO_LARGE";
787 _mesa_debug(ctx
, "Mesa user error: %s in %s\n", errstr
, where
);
790 _mesa_record_error(ctx
, error
);
795 * Call this to report debug information. Uses stderr.
798 _mesa_debug( const GLcontext
*ctx
, const char *fmtString
, ... )
802 va_start(args
, fmtString
);
803 vsnprintf(s
, MAXSTRING
, fmtString
, args
);
805 #if defined(XFree86LOADER) && defined(IN_MODULE)
806 xf86fprintf(stderr
, "Mesa: %s", s
);
808 fprintf(stderr
, "Mesa: %s", s
);
814 /**********************************************************************/
815 /* Default Imports Wrapper */
816 /**********************************************************************/
819 default_malloc(__GLcontext
*gc
, size_t size
)
822 return _mesa_malloc(size
);
826 default_calloc(__GLcontext
*gc
, size_t numElem
, size_t elemSize
)
829 return _mesa_calloc(numElem
* elemSize
);
833 default_realloc(__GLcontext
*gc
, void *oldAddr
, size_t newSize
)
836 #if defined(XFree86LOADER) && defined(IN_MODULE)
837 return xf86realloc(oldAddr
, newSize
);
839 return realloc(oldAddr
, newSize
);
844 default_free(__GLcontext
*gc
, void *addr
)
851 default_getenv( __GLcontext
*gc
, const char *var
)
854 return _mesa_getenv(var
);
858 default_warning(__GLcontext
*gc
, char *str
)
860 _mesa_warning(gc
, str
);
864 default_fatal(__GLcontext
*gc
, char *str
)
866 _mesa_problem(gc
, str
);
871 default_atoi(__GLcontext
*gc
, const char *str
)
878 default_sprintf(__GLcontext
*gc
, char *str
, const char *fmt
, ...)
882 va_start( args
, fmt
);
883 r
= vsprintf( str
, fmt
, args
);
889 default_fopen(__GLcontext
*gc
, const char *path
, const char *mode
)
891 return fopen(path
, mode
);
895 default_fclose(__GLcontext
*gc
, void *stream
)
897 return fclose((FILE *) stream
);
901 default_fprintf(__GLcontext
*gc
, void *stream
, const char *fmt
, ...)
905 va_start( args
, fmt
);
906 r
= vfprintf( (FILE *) stream
, fmt
, args
);
911 /* XXX this really is driver-specific and can't be here */
912 static __GLdrawablePrivate
*
913 default_GetDrawablePrivate(__GLcontext
*gc
)
922 * Initialize a __GLimports object to point to the functions in
923 * this file. This is to be called from device drivers.
924 * Also, do some one-time initializations.
925 * Input: imports - the object to init
926 * driverCtx - pointer to device driver-specific data
929 _mesa_init_default_imports(__GLimports
*imports
, void *driverCtx
)
931 /* XXX maybe move this one-time init stuff into context.c */
932 static GLboolean initialized
= GL_FALSE
;
936 #if defined(_FPU_GETCW) && defined(_FPU_SETCW)
938 const char *debug
= _mesa_getenv("MESA_DEBUG");
939 if (debug
&& _mesa_strcmp(debug
, "FP")==0) {
940 /* die on FP exceptions */
943 mask
&= ~(_FPU_MASK_IM
| _FPU_MASK_DM
| _FPU_MASK_ZM
944 | _FPU_MASK_OM
| _FPU_MASK_UM
);
949 initialized
= GL_TRUE
;
952 imports
->malloc
= default_malloc
;
953 imports
->calloc
= default_calloc
;
954 imports
->realloc
= default_realloc
;
955 imports
->free
= default_free
;
956 imports
->warning
= default_warning
;
957 imports
->fatal
= default_fatal
;
958 imports
->getenv
= default_getenv
; /* not used for now */
959 imports
->atoi
= default_atoi
;
960 imports
->sprintf
= default_sprintf
;
961 imports
->fopen
= default_fopen
;
962 imports
->fclose
= default_fclose
;
963 imports
->fprintf
= default_fprintf
;
964 imports
->getDrawablePrivate
= default_GetDrawablePrivate
;
965 imports
->other
= driverCtx
;