glBindProgramARB dispatches to glBindProgramNV (remove _mesa_BindProgramARB).
[mesa.git] / src / mesa / main / imports.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 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 * 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,
30 * etc.
31 *
32 * Some drivers will want to override/replace this file with something
33 * specialized, but that'll be rare.
34 *
35 * Eventually, I want to move roll the glheader.h file into this.
36 *
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.
40 *
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.
44 */
45
46
47 #include "imports.h"
48 #include "context.h"
49
50
51 #define MAXSTRING 4000 /* for vsnprintf() */
52
53 #ifdef WIN32
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);
57 #endif
58
59
60 /**********************************************************************/
61 /* Wrappers for standard C library functions */
62 /**********************************************************************/
63
64 /*
65 * Functions still needed:
66 * scanf
67 * qsort
68 * bsearch
69 * rand and RAND_MAX
70 */
71
72
73 /**********************************************************************
74 * Memory
75 */
76
77 void *
78 _mesa_malloc(size_t bytes)
79 {
80 #if defined(XFree86LOADER) && defined(IN_MODULE)
81 return xf86malloc(bytes);
82 #else
83 return malloc(bytes);
84 #endif
85 }
86
87
88 void *
89 _mesa_calloc(size_t bytes)
90 {
91 #if defined(XFree86LOADER) && defined(IN_MODULE)
92 return xf86calloc(1, bytes);
93 #else
94 return calloc(1, bytes);
95 #endif
96 }
97
98
99 void
100 _mesa_free(void *ptr)
101 {
102 #if defined(XFree86LOADER) && defined(IN_MODULE)
103 xf86free(ptr);
104 #else
105 free(ptr);
106 #endif
107 }
108
109
110 void *
111 _mesa_align_malloc(size_t bytes, unsigned long alignment)
112 {
113 unsigned long ptr, buf;
114
115 ASSERT( alignment > 0 );
116
117 /* Allocate extra memory to accomodate rounding up the address for
118 * alignment and to record the real malloc address.
119 */
120 ptr = (unsigned long) _mesa_malloc(bytes + alignment + sizeof(void *));
121 if (!ptr)
122 return NULL;
123
124 buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment - 1);
125 *(unsigned long *)(buf - sizeof(void *)) = ptr;
126
127 #ifdef DEBUG
128 /* mark the non-aligned area */
129 while ( ptr < buf - sizeof(void *) ) {
130 *(unsigned long *)ptr = 0xcdcdcdcd;
131 ptr += sizeof(unsigned long);
132 }
133 #endif
134
135 return (void *) buf;
136 }
137
138
139 void *
140 _mesa_align_calloc(size_t bytes, unsigned long alignment)
141 {
142 unsigned long ptr, buf;
143
144 ASSERT( alignment > 0 );
145
146 ptr = (unsigned long) _mesa_calloc(bytes + alignment + sizeof(void *));
147 if (!ptr)
148 return NULL;
149
150 buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment - 1);
151 *(unsigned long *)(buf - sizeof(void *)) = ptr;
152
153 #ifdef DEBUG
154 /* mark the non-aligned area */
155 while ( ptr < buf - sizeof(void *) ) {
156 *(unsigned long *)ptr = 0xcdcdcdcd;
157 ptr += sizeof(unsigned long);
158 }
159 #endif
160
161 return (void *)buf;
162 }
163
164
165 void
166 _mesa_align_free(void *ptr)
167 {
168 #if 0
169 _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr - sizeof(void *))) );
170 #else
171 /* The actuall address to free is stuffed in the word immediately
172 * before the address the client sees.
173 */
174 void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
175 void *realAddr = *cubbyHole;
176 _mesa_free(realAddr);
177 #endif
178 }
179
180
181 void *
182 _mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
183 {
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);
188 if (oldBuffer)
189 _mesa_free(oldBuffer);
190 return newBuffer;
191 }
192
193
194 void *
195 _mesa_memcpy(void *dest, const void *src, size_t n)
196 {
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);
201 #else
202 return memcpy(dest, src, n);
203 #endif
204 }
205
206
207 void
208 _mesa_memset( void *dst, int val, size_t n )
209 {
210 #if defined(XFree86LOADER) && defined(IN_MODULE)
211 xf86memset( dst, val, n );
212 #elif defined(SUNOS4)
213 memset( (char *) dst, (int) val, (int) n );
214 #else
215 memset(dst, val, n);
216 #endif
217 }
218
219
220 void
221 _mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
222 {
223 while (n-- > 0)
224 *dst++ = val;
225 }
226
227
228 void
229 _mesa_bzero( void *dst, size_t n )
230 {
231 #if defined(XFree86LOADER) && defined(IN_MODULE)
232 xf86memset( dst, 0, n );
233 #elif defined(__FreeBSD__)
234 bzero( dst, n );
235 #else
236 memset( dst, 0, n );
237 #endif
238 }
239
240
241 /**********************************************************************
242 * Math
243 */
244
245 double
246 _mesa_sin(double a)
247 {
248 #if defined(XFree86LOADER) && defined(IN_MODULE)
249 return xf86sin(a);
250 #else
251 return sin(a);
252 #endif
253 }
254
255
256 double
257 _mesa_cos(double a)
258 {
259 #if defined(XFree86LOADER) && defined(IN_MODULE)
260 return xf86cos(a);
261 #else
262 return cos(a);
263 #endif
264 }
265
266
267 double
268 _mesa_sqrtd(double x)
269 {
270 #if defined(XFree86LOADER) && defined(IN_MODULE)
271 return xf86sqrt(x);
272 #else
273 return sqrt(x);
274 #endif
275 }
276
277
278 /*
279 * A High Speed, Low Precision Square Root
280 * by Paul Lalonde and Robert Dawson
281 * from "Graphics Gems", Academic Press, 1990
282 *
283 * SPARC implementation of a fast square root by table
284 * lookup.
285 * SPARC floating point format is as follows:
286 *
287 * BIT 31 30 23 22 0
288 * sign exponent mantissa
289 */
290 static short sqrttab[0x100]; /* declare table of square roots */
291
292 static void init_sqrt_table(void)
293 {
294 #if defined(USE_IEEE) && !defined(DEBUG)
295 unsigned short i;
296 fi_type fi; /* to access the bits of a float in C quickly */
297 /* we use a union defined in glheader.h */
298
299 for(i=0; i<= 0x7f; i++) {
300 fi.i = 0;
301
302 /*
303 * Build a float with the bit pattern i as mantissa
304 * and an exponent of 0, stored as 127
305 */
306
307 fi.i = (i << 16) | (127 << 23);
308 fi.f = _mesa_sqrtd(fi.f);
309
310 /*
311 * Take the square root then strip the first 7 bits of
312 * the mantissa into the table
313 */
314
315 sqrttab[i] = (fi.i & 0x7fffff) >> 16;
316
317 /*
318 * Repeat the process, this time with an exponent of
319 * 1, stored as 128
320 */
321
322 fi.i = 0;
323 fi.i = (i << 16) | (128 << 23);
324 fi.f = sqrt(fi.f);
325 sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
326 }
327 #else
328 (void) sqrttab; /* silence compiler warnings */
329 #endif /*HAVE_FAST_MATH*/
330 }
331
332
333 float
334 _mesa_sqrtf( float x )
335 {
336 #if defined(USE_IEEE) && !defined(DEBUG)
337 fi_type num;
338 /* to access the bits of a float in C
339 * we use a union from glheader.h */
340
341 short e; /* the exponent */
342 if (x == 0.0F) return 0.0F; /* check for square root of 0 */
343 num.f = x;
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 */
351 /* high bit */
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
358 */
359 num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
360
361 return num.f;
362 #else
363 return (float) _mesa_sqrtd((double) x);
364 #endif
365 }
366
367
368 /**
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
371 and Vesa Karvonen.
372 */
373 float
374 _mesa_inv_sqrtf(float n)
375 {
376 #if defined(USE_IEEE) && !defined(DEBUG)
377 float r0, x0, y0;
378 float r1, x1, y1;
379 float r2, x2, y2;
380 #if 0 /* not used, see below -BP */
381 float r3, x3, y3;
382 #endif
383 union { float f; unsigned int i; } u;
384 unsigned int magic;
385
386 /*
387 Exponent part of the magic number -
388
389 We want to:
390 1. subtract the bias from the exponent,
391 2. negate it
392 3. divide by two (rounding towards -inf)
393 4. add the bias back
394
395 Which is the same as subtracting the exponent from 381 and dividing
396 by 2.
397
398 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
399 */
400
401 magic = 381 << 23;
402
403 /*
404 Significand part of magic number -
405
406 With the current magic number, "(magic - u.i) >> 1" will give you:
407
408 for 1 <= u.f <= 2: 1.25 - u.f / 4
409 for 2 <= u.f <= 4: 1.00 - u.f / 8
410
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...)
415
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:
419
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.)
424
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
429 is possible.
430
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
434
435 */
436
437 magic -= (int)(0.0332281 * (1 << 25));
438
439 u.f = n;
440 u.i = (magic - u.i) >> 1;
441
442 /*
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.
447 */
448 x0 = 1.0f;
449 y0 = 0.5f * n;
450 r0 = u.f;
451
452 x1 = x0 * r0;
453 y1 = y0 * r0 * r0;
454 r1 = 1.5f - y1;
455
456 x2 = x1 * r1;
457 y2 = y1 * r1 * r1;
458 r2 = 1.5f - y2;
459
460 #if 1
461 return x2 * r2; /* we can stop here, and be conformant -BP */
462 #else
463 x3 = x2 * r2;
464 y3 = y2 * r2 * r2;
465 r3 = 1.5f - y3;
466
467 return x3 * r3;
468 #endif
469 #elif defined(XFree86LOADER) && defined(IN_MODULE)
470 return 1.0F / xf86sqrt(n);
471 #else
472 return 1.0F / sqrt(n);
473 #endif
474 }
475
476
477 double
478 _mesa_pow(double x, double y)
479 {
480 #if defined(XFree86LOADER) && defined(IN_MODULE)
481 return xf86pow(x, y);
482 #else
483 return pow(x, y);
484 #endif
485 }
486
487
488 /*
489 * Return number of bits set in given GLuint.
490 */
491 unsigned int
492 _mesa_bitcount(unsigned int n)
493 {
494 unsigned int bits;
495 for (bits = 0; n > 0; n = n >> 1) {
496 bits += (n & 1);
497 }
498 return bits;
499 }
500
501
502
503 /**********************************************************************
504 * Environment vars
505 */
506
507 char *
508 _mesa_getenv( const char *var )
509 {
510 #if defined(XFree86LOADER) && defined(IN_MODULE)
511 return xf86getenv(var);
512 #else
513 return getenv(var);
514 #endif
515 }
516
517
518 /**********************************************************************
519 * String
520 */
521
522 char *
523 _mesa_strstr( const char *haystack, const char *needle )
524 {
525 #if defined(XFree86LOADER) && defined(IN_MODULE)
526 return xf86strstr(haystack, needle);
527 #else
528 return strstr(haystack, needle);
529 #endif
530 }
531
532
533 char *
534 _mesa_strncat( char *dest, const char *src, size_t n )
535 {
536 #if defined(XFree86LOADER) && defined(IN_MODULE)
537 return xf86strncat(dest, src, n);
538 #else
539 return strncat(dest, src, n);
540 #endif
541 }
542
543
544 char *
545 _mesa_strcpy( char *dest, const char *src )
546 {
547 #if defined(XFree86LOADER) && defined(IN_MODULE)
548 return xf86strcpy(dest, src);
549 #else
550 return strcpy(dest, src);
551 #endif
552 }
553
554
555 char *
556 _mesa_strncpy( char *dest, const char *src, size_t n )
557 {
558 #if defined(XFree86LOADER) && defined(IN_MODULE)
559 return xf86strncpy(dest, src, n);
560 #else
561 return strncpy(dest, src, n);
562 #endif
563 }
564
565
566 size_t
567 _mesa_strlen( const char *s )
568 {
569 #if defined(XFree86LOADER) && defined(IN_MODULE)
570 return xf86strlen(s);
571 #else
572 return strlen(s);
573 #endif
574 }
575
576
577 int
578 _mesa_strcmp( const char *s1, const char *s2 )
579 {
580 #if defined(XFree86LOADER) && defined(IN_MODULE)
581 return xf86strcmp(s1, s2);
582 #else
583 return strcmp(s1, s2);
584 #endif
585 }
586
587
588 int
589 _mesa_strncmp( const char *s1, const char *s2, size_t n )
590 {
591 #if defined(XFree86LOADER) && defined(IN_MODULE)
592 return xf86strncmp(s1, s2, n);
593 #else
594 return strncmp(s1, s2, n);
595 #endif
596 }
597
598
599 char *
600 _mesa_strdup( const char *s )
601 {
602 int l = _mesa_strlen(s);
603 char *s2 = (char *) _mesa_malloc(l + 1);
604 if (s2)
605 _mesa_strcpy(s2, s);
606 return s2;
607 }
608
609
610 int
611 _mesa_atoi(const char *s)
612 {
613 #if defined(XFree86LOADER) && defined(IN_MODULE)
614 return xf86atoi(s);
615 #else
616 return atoi(s);
617 #endif
618 }
619
620
621 double
622 _mesa_strtod( const char *s, char **end )
623 {
624 #if defined(XFree86LOADER) && defined(IN_MODULE)
625 return xf86strtod(s, end);
626 #else
627 return strtod(s, end);
628 #endif
629 }
630
631
632 /**********************************************************************
633 * I/O
634 */
635
636 int
637 _mesa_sprintf( char *str, const char *fmt, ... )
638 {
639 int r;
640 va_list args;
641 va_start( args, fmt );
642 va_end( args );
643 #if defined(XFree86LOADER) && defined(IN_MODULE)
644 r = xf86vsprintf( str, fmt, args );
645 #else
646 r = vsprintf( str, fmt, args );
647 #endif
648 return r;
649 }
650
651
652 void
653 _mesa_printf( const char *fmtString, ... )
654 {
655 char s[MAXSTRING];
656 va_list args;
657 va_start( args, fmtString );
658 vsnprintf(s, MAXSTRING, fmtString, args);
659 va_end( args );
660 #if defined(XFree86LOADER) && defined(IN_MODULE)
661 xf86printf("%s", s);
662 #else
663 printf("%s", s);
664 #endif
665 }
666
667
668 /**********************************************************************
669 * Diagnostics
670 */
671
672 void
673 _mesa_warning( GLcontext *ctx, const char *fmtString, ... )
674 {
675 GLboolean debug;
676 char str[MAXSTRING];
677 va_list args;
678 (void) ctx;
679 va_start( args, fmtString );
680 (void) vsnprintf( str, MAXSTRING, fmtString, args );
681 va_end( args );
682 #ifdef DEBUG
683 debug = GL_TRUE; /* always print warning */
684 #else
685 debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
686 #endif
687 if (debug) {
688 #if defined(XFree86LOADER) && defined(IN_MODULE)
689 xf86fprintf(stderr, "Mesa warning: %s\n", str);
690 #else
691 fprintf(stderr, "Mesa warning: %s\n", str);
692 #endif
693 }
694 }
695
696
697 /*
698 * This function is called when the Mesa user has stumbled into a code
699 * path which may not be implemented fully or correctly.
700 */
701 void
702 _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
703 {
704 va_list args;
705 char str[MAXSTRING];
706 (void) ctx;
707
708 va_start( args, fmtString );
709 vsnprintf( str, MAXSTRING, fmtString, args );
710 va_end( args );
711
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");
715 #else
716 fprintf(stderr, "Mesa implementation error: %s\n", str);
717 fprintf(stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
718 #endif
719 }
720
721
722 /*
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
728 */
729 void
730 _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
731 {
732 const char *debugEnv;
733 GLboolean debug;
734
735 debugEnv = _mesa_getenv("MESA_DEBUG");
736
737 #ifdef DEBUG
738 if (debugEnv && _mesa_strstr(debugEnv, "silent"))
739 debug = GL_FALSE;
740 else
741 debug = GL_TRUE;
742 #else
743 if (debugEnv)
744 debug = GL_TRUE;
745 else
746 debug = GL_FALSE;
747 #endif
748
749 if (debug) {
750 va_list args;
751 char where[MAXSTRING];
752 const char *errstr;
753
754 va_start( args, fmtString );
755 vsnprintf( where, MAXSTRING, fmtString, args );
756 va_end( args );
757
758 switch (error) {
759 case GL_NO_ERROR:
760 errstr = "GL_NO_ERROR";
761 break;
762 case GL_INVALID_VALUE:
763 errstr = "GL_INVALID_VALUE";
764 break;
765 case GL_INVALID_ENUM:
766 errstr = "GL_INVALID_ENUM";
767 break;
768 case GL_INVALID_OPERATION:
769 errstr = "GL_INVALID_OPERATION";
770 break;
771 case GL_STACK_OVERFLOW:
772 errstr = "GL_STACK_OVERFLOW";
773 break;
774 case GL_STACK_UNDERFLOW:
775 errstr = "GL_STACK_UNDERFLOW";
776 break;
777 case GL_OUT_OF_MEMORY:
778 errstr = "GL_OUT_OF_MEMORY";
779 break;
780 case GL_TABLE_TOO_LARGE:
781 errstr = "GL_TABLE_TOO_LARGE";
782 break;
783 default:
784 errstr = "unknown";
785 break;
786 }
787 _mesa_debug(ctx, "Mesa user error: %s in %s\n", errstr, where);
788 }
789
790 _mesa_record_error(ctx, error);
791 }
792
793
794 /*
795 * Call this to report debug information. Uses stderr.
796 */
797 void
798 _mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
799 {
800 char s[MAXSTRING];
801 va_list args;
802 va_start(args, fmtString);
803 vsnprintf(s, MAXSTRING, fmtString, args);
804 va_end(args);
805 #if defined(XFree86LOADER) && defined(IN_MODULE)
806 xf86fprintf(stderr, "Mesa: %s", s);
807 #else
808 fprintf(stderr, "Mesa: %s", s);
809 #endif
810 }
811
812
813
814 /**********************************************************************/
815 /* Default Imports Wrapper */
816 /**********************************************************************/
817
818 static void *
819 default_malloc(__GLcontext *gc, size_t size)
820 {
821 (void) gc;
822 return _mesa_malloc(size);
823 }
824
825 static void *
826 default_calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
827 {
828 (void) gc;
829 return _mesa_calloc(numElem * elemSize);
830 }
831
832 static void *
833 default_realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
834 {
835 (void) gc;
836 #if defined(XFree86LOADER) && defined(IN_MODULE)
837 return xf86realloc(oldAddr, newSize);
838 #else
839 return realloc(oldAddr, newSize);
840 #endif
841 }
842
843 static void
844 default_free(__GLcontext *gc, void *addr)
845 {
846 (void) gc;
847 _mesa_free(addr);
848 }
849
850 static char * CAPI
851 default_getenv( __GLcontext *gc, const char *var )
852 {
853 (void) gc;
854 return _mesa_getenv(var);
855 }
856
857 static void
858 default_warning(__GLcontext *gc, char *str)
859 {
860 _mesa_warning(gc, str);
861 }
862
863 static void
864 default_fatal(__GLcontext *gc, char *str)
865 {
866 _mesa_problem(gc, str);
867 abort();
868 }
869
870 static int CAPI
871 default_atoi(__GLcontext *gc, const char *str)
872 {
873 (void) gc;
874 return atoi(str);
875 }
876
877 static int CAPI
878 default_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
879 {
880 int r;
881 va_list args;
882 va_start( args, fmt );
883 r = vsprintf( str, fmt, args );
884 va_end( args );
885 return r;
886 }
887
888 static void * CAPI
889 default_fopen(__GLcontext *gc, const char *path, const char *mode)
890 {
891 return fopen(path, mode);
892 }
893
894 static int CAPI
895 default_fclose(__GLcontext *gc, void *stream)
896 {
897 return fclose((FILE *) stream);
898 }
899
900 static int CAPI
901 default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
902 {
903 int r;
904 va_list args;
905 va_start( args, fmt );
906 r = vfprintf( (FILE *) stream, fmt, args );
907 va_end( args );
908 return r;
909 }
910
911 /* XXX this really is driver-specific and can't be here */
912 static __GLdrawablePrivate *
913 default_GetDrawablePrivate(__GLcontext *gc)
914 {
915 return NULL;
916 }
917
918
919
920
921 /*
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
927 */
928 void
929 _mesa_init_default_imports(__GLimports *imports, void *driverCtx)
930 {
931 /* XXX maybe move this one-time init stuff into context.c */
932 static GLboolean initialized = GL_FALSE;
933 if (!initialized) {
934 init_sqrt_table();
935
936 #if defined(_FPU_GETCW) && defined(_FPU_SETCW)
937 {
938 const char *debug = _mesa_getenv("MESA_DEBUG");
939 if (debug && _mesa_strcmp(debug, "FP")==0) {
940 /* die on FP exceptions */
941 fpu_control_t mask;
942 _FPU_GETCW(mask);
943 mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
944 | _FPU_MASK_OM | _FPU_MASK_UM);
945 _FPU_SETCW(mask);
946 }
947 }
948 #endif
949 initialized = GL_TRUE;
950 }
951
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;
966 }