Silence gcc 3.4 warnings on ReactOS. Mostly unused var warnings. (patch 1015696)
[mesa.git] / src / mesa / main / imports.c
1 /**
2 * \file imports.c
3 * Standard C library function wrappers.
4 *
5 * Imports are services which the device driver or window system or
6 * operating system provides to the core renderer. The core renderer (Mesa)
7 * will call these functions in order to do memory allocation, simple I/O,
8 * etc.
9 *
10 * Some drivers will want to override/replace this file with something
11 * specialized, but that'll be rare.
12 *
13 * Eventually, I want to move roll the glheader.h file into this.
14 *
15 * The OpenGL SI's __GLimports structure allows per-context specification of
16 * replacements for the standard C lib functions. In practice that's probably
17 * never needed; compile-time replacements are far more likely.
18 *
19 * The _mesa_*() functions defined here don't in general take a context
20 * parameter. I guess we can change that someday, if need be.
21 * So for now, the __GLimports stuff really isn't used.
22 *
23 * \todo Functions still needed:
24 * - scanf
25 * - qsort
26 * - bsearch
27 * - rand and RAND_MAX
28 *
29 * \note When compiled into a XFree86 module these functions wrap around
30 * XFree86 own wrappers.
31 */
32
33 /*
34 * Mesa 3-D graphics library
35 * Version: 6.1
36 *
37 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
38 *
39 * Permission is hereby granted, free of charge, to any person obtaining a
40 * copy of this software and associated documentation files (the "Software"),
41 * to deal in the Software without restriction, including without limitation
42 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
43 * and/or sell copies of the Software, and to permit persons to whom the
44 * Software is furnished to do so, subject to the following conditions:
45 *
46 * The above copyright notice and this permission notice shall be included
47 * in all copies or substantial portions of the Software.
48 *
49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
50 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
52 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
53 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
54 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
55 */
56
57
58
59 #include "imports.h"
60 #include "context.h"
61
62
63 #define MAXSTRING 4000 /* for vsnprintf() */
64
65 #ifdef WIN32
66 #define vsnprintf _vsnprintf
67 #elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
68 extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
69 #ifdef __VMS
70 #include "vsnprintf.c"
71 #endif
72 #endif
73
74
75 /**********************************************************************/
76 /** \name Memory */
77 /*@{*/
78
79 /** Wrapper around either malloc() or xf86malloc() */
80 void *
81 _mesa_malloc(size_t bytes)
82 {
83 #if defined(XFree86LOADER) && defined(IN_MODULE)
84 return xf86malloc(bytes);
85 #else
86 return malloc(bytes);
87 #endif
88 }
89
90 /** Wrapper around either calloc() or xf86calloc() */
91 void *
92 _mesa_calloc(size_t bytes)
93 {
94 #if defined(XFree86LOADER) && defined(IN_MODULE)
95 return xf86calloc(1, bytes);
96 #else
97 return calloc(1, bytes);
98 #endif
99 }
100
101 /** Wrapper around either free() or xf86free() */
102 void
103 _mesa_free(void *ptr)
104 {
105 #if defined(XFree86LOADER) && defined(IN_MODULE)
106 xf86free(ptr);
107 #else
108 free(ptr);
109 #endif
110 }
111
112 /**
113 * Allocate aligned memory.
114 *
115 * \param bytes number of bytes to allocate.
116 * \param alignment alignment (must be greater than zero).
117 *
118 * Allocates extra memory to accommodate rounding up the address for
119 * alignment and to record the real malloc address.
120 *
121 * \sa _mesa_align_free().
122 */
123 void *
124 _mesa_align_malloc(size_t bytes, unsigned long alignment)
125 {
126 unsigned long ptr, buf;
127
128 ASSERT( alignment > 0 );
129
130 ptr = (unsigned long) _mesa_malloc(bytes + alignment + sizeof(void *));
131 if (!ptr)
132 return NULL;
133
134 buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment - 1);
135 *(unsigned long *)(buf - sizeof(void *)) = ptr;
136
137 #ifdef DEBUG
138 /* mark the non-aligned area */
139 while ( ptr < buf - sizeof(void *) ) {
140 *(unsigned long *)ptr = 0xcdcdcdcd;
141 ptr += sizeof(unsigned long);
142 }
143 #endif
144
145 return (void *) buf;
146 }
147
148 /** Same as _mesa_align_malloc(), but using _mesa_calloc() instead of
149 * _mesa_malloc() */
150 void *
151 _mesa_align_calloc(size_t bytes, unsigned long alignment)
152 {
153 unsigned long ptr, buf;
154
155 ASSERT( alignment > 0 );
156
157 ptr = (unsigned long) _mesa_calloc(bytes + alignment + sizeof(void *));
158 if (!ptr)
159 return NULL;
160
161 buf = (ptr + alignment + sizeof(void *)) & ~(unsigned long)(alignment - 1);
162 *(unsigned long *)(buf - sizeof(void *)) = ptr;
163
164 #ifdef DEBUG
165 /* mark the non-aligned area */
166 while ( ptr < buf - sizeof(void *) ) {
167 *(unsigned long *)ptr = 0xcdcdcdcd;
168 ptr += sizeof(unsigned long);
169 }
170 #endif
171
172 return (void *)buf;
173 }
174
175 /**
176 * Free memory allocated with _mesa_align_malloc() or _mesa_align_calloc().
177 *
178 * \param ptr pointer to the memory to be freed.
179 *
180 * The actual address to free is stored in the word immediately before the
181 * address the client sees.
182 */
183 void
184 _mesa_align_free(void *ptr)
185 {
186 #if 0
187 _mesa_free( (void *)(*(unsigned long *)((unsigned long)ptr - sizeof(void *))) );
188 #else
189 void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
190 void *realAddr = *cubbyHole;
191 _mesa_free(realAddr);
192 #endif
193 }
194
195 /** Wrapper around either memcpy() or xf86memcpy() */
196 void *
197 _mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
198 {
199 const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
200 void *newBuffer = _mesa_malloc(newSize);
201 if (newBuffer && copySize > 0)
202 _mesa_memcpy(newBuffer, oldBuffer, copySize);
203 if (oldBuffer)
204 _mesa_free(oldBuffer);
205 return newBuffer;
206 }
207
208
209 void *
210 _mesa_memcpy(void *dest, const void *src, size_t n)
211 {
212 #if defined(XFree86LOADER) && defined(IN_MODULE)
213 return xf86memcpy(dest, src, n);
214 #elif defined(SUNOS4)
215 return memcpy((char *) dest, (char *) src, (int) n);
216 #else
217 return memcpy(dest, src, n);
218 #endif
219 }
220
221 /** Wrapper around either memset() or xf86memset() */
222 void
223 _mesa_memset( void *dst, int val, size_t n )
224 {
225 #if defined(XFree86LOADER) && defined(IN_MODULE)
226 xf86memset( dst, val, n );
227 #elif defined(SUNOS4)
228 memset( (char *) dst, (int) val, (int) n );
229 #else
230 memset(dst, val, n);
231 #endif
232 }
233
234 /** Fill memory with a constant 16bit word.
235 *
236 * \param dst destination pointer.
237 * \param val value.
238 * \param n number of words.
239 */
240 void
241 _mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
242 {
243 while (n-- > 0)
244 *dst++ = val;
245 }
246
247 /** Wrapper around either memcpy() or xf86memcpy() or bzero() */
248 void
249 _mesa_bzero( void *dst, size_t n )
250 {
251 #if defined(XFree86LOADER) && defined(IN_MODULE)
252 xf86memset( dst, 0, n );
253 #elif defined(__FreeBSD__)
254 bzero( dst, n );
255 #else
256 memset( dst, 0, n );
257 #endif
258 }
259
260 /*@}*/
261
262
263 /**********************************************************************/
264 /** \name Math */
265 /*@{*/
266
267 /** Wrapper around either sin() or xf86sin() */
268 double
269 _mesa_sin(double a)
270 {
271 #if defined(XFree86LOADER) && defined(IN_MODULE)
272 return xf86sin(a);
273 #else
274 return sin(a);
275 #endif
276 }
277
278 /** Wrapper around either cos() or xf86cos() */
279 double
280 _mesa_cos(double a)
281 {
282 #if defined(XFree86LOADER) && defined(IN_MODULE)
283 return xf86cos(a);
284 #else
285 return cos(a);
286 #endif
287 }
288
289 /** Wrapper around either sqrt() or xf86sqrt() */
290 double
291 _mesa_sqrtd(double x)
292 {
293 #if defined(XFree86LOADER) && defined(IN_MODULE)
294 return xf86sqrt(x);
295 #else
296 return sqrt(x);
297 #endif
298 }
299
300
301 /*
302 * A High Speed, Low Precision Square Root
303 * by Paul Lalonde and Robert Dawson
304 * from "Graphics Gems", Academic Press, 1990
305 *
306 * SPARC implementation of a fast square root by table
307 * lookup.
308 * SPARC floating point format is as follows:
309 *
310 * BIT 31 30 23 22 0
311 * sign exponent mantissa
312 */
313 static short sqrttab[0x100]; /* declare table of square roots */
314
315 static void init_sqrt_table(void)
316 {
317 #if defined(USE_IEEE) && !defined(DEBUG)
318 unsigned short i;
319 fi_type fi; /* to access the bits of a float in C quickly */
320 /* we use a union defined in glheader.h */
321
322 for(i=0; i<= 0x7f; i++) {
323 fi.i = 0;
324
325 /*
326 * Build a float with the bit pattern i as mantissa
327 * and an exponent of 0, stored as 127
328 */
329
330 fi.i = (i << 16) | (127 << 23);
331 fi.f = _mesa_sqrtd(fi.f);
332
333 /*
334 * Take the square root then strip the first 7 bits of
335 * the mantissa into the table
336 */
337
338 sqrttab[i] = (fi.i & 0x7fffff) >> 16;
339
340 /*
341 * Repeat the process, this time with an exponent of
342 * 1, stored as 128
343 */
344
345 fi.i = 0;
346 fi.i = (i << 16) | (128 << 23);
347 fi.f = sqrt(fi.f);
348 sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
349 }
350 #else
351 (void) sqrttab; /* silence compiler warnings */
352 #endif /*HAVE_FAST_MATH*/
353 }
354
355
356 /**
357 * Single precision square root.
358 */
359 float
360 _mesa_sqrtf( float x )
361 {
362 #if defined(USE_IEEE) && !defined(DEBUG)
363 fi_type num;
364 /* to access the bits of a float in C
365 * we use a union from glheader.h */
366
367 short e; /* the exponent */
368 if (x == 0.0F) return 0.0F; /* check for square root of 0 */
369 num.f = x;
370 e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */
371 /* exponent is stored with 127 added */
372 num.i &= 0x7fffff; /* leave only the mantissa */
373 if (e & 0x01) num.i |= 0x800000;
374 /* the exponent is odd so we have to */
375 /* look it up in the second half of */
376 /* the lookup table, so we set the */
377 /* high bit */
378 e >>= 1; /* divide the exponent by two */
379 /* note that in C the shift */
380 /* operators are sign preserving */
381 /* for signed operands */
382 /* Do the table lookup, based on the quaternary mantissa,
383 * then reconstruct the result back into a float
384 */
385 num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
386
387 return num.f;
388 #else
389 return (float) _mesa_sqrtd((double) x);
390 #endif
391 }
392
393
394 /**
395 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
396 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
397 and Vesa Karvonen.
398 */
399 float
400 _mesa_inv_sqrtf(float n)
401 {
402 #if defined(USE_IEEE) && !defined(DEBUG)
403 float r0, x0, y0;
404 float r1, x1, y1;
405 float r2, x2, y2;
406 #if 0 /* not used, see below -BP */
407 float r3, x3, y3;
408 #endif
409 union { float f; unsigned int i; } u;
410 unsigned int magic;
411
412 /*
413 Exponent part of the magic number -
414
415 We want to:
416 1. subtract the bias from the exponent,
417 2. negate it
418 3. divide by two (rounding towards -inf)
419 4. add the bias back
420
421 Which is the same as subtracting the exponent from 381 and dividing
422 by 2.
423
424 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
425 */
426
427 magic = 381 << 23;
428
429 /*
430 Significand part of magic number -
431
432 With the current magic number, "(magic - u.i) >> 1" will give you:
433
434 for 1 <= u.f <= 2: 1.25 - u.f / 4
435 for 2 <= u.f <= 4: 1.00 - u.f / 8
436
437 This isn't a bad approximation of 1/sqrt. The maximum difference from
438 1/sqrt will be around .06. After three Newton-Raphson iterations, the
439 maximum difference is less than 4.5e-8. (Which is actually close
440 enough to make the following bias academic...)
441
442 To get a better approximation you can add a bias to the magic
443 number. For example, if you subtract 1/2 of the maximum difference in
444 the first approximation (.03), you will get the following function:
445
446 for 1 <= u.f <= 2: 1.22 - u.f / 4
447 for 2 <= u.f <= 3.76: 0.97 - u.f / 8
448 for 3.76 <= u.f <= 4: 0.72 - u.f / 16
449 (The 3.76 to 4 range is where the result is < .5.)
450
451 This is the closest possible initial approximation, but with a maximum
452 error of 8e-11 after three NR iterations, it is still not perfect. If
453 you subtract 0.0332281 instead of .03, the maximum error will be
454 2.5e-11 after three NR iterations, which should be about as close as
455 is possible.
456
457 for 1 <= u.f <= 2: 1.2167719 - u.f / 4
458 for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
459 for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
460
461 */
462
463 magic -= (int)(0.0332281 * (1 << 25));
464
465 u.f = n;
466 u.i = (magic - u.i) >> 1;
467
468 /*
469 Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
470 allows more parallelism. From what I understand, the parallelism
471 comes at the cost of less precision, because it lets error
472 accumulate across iterations.
473 */
474 x0 = 1.0f;
475 y0 = 0.5f * n;
476 r0 = u.f;
477
478 x1 = x0 * r0;
479 y1 = y0 * r0 * r0;
480 r1 = 1.5f - y1;
481
482 x2 = x1 * r1;
483 y2 = y1 * r1 * r1;
484 r2 = 1.5f - y2;
485
486 #if 1
487 return x2 * r2; /* we can stop here, and be conformant -BP */
488 #else
489 x3 = x2 * r2;
490 y3 = y2 * r2 * r2;
491 r3 = 1.5f - y3;
492
493 return x3 * r3;
494 #endif
495 #elif defined(XFree86LOADER) && defined(IN_MODULE)
496 return 1.0F / xf86sqrt(n);
497 #else
498 return (float) (1.0 / sqrt(n));
499 #endif
500 }
501
502
503 /**
504 * Wrapper around either pow() or xf86pow().
505 */
506 double
507 _mesa_pow(double x, double y)
508 {
509 #if defined(XFree86LOADER) && defined(IN_MODULE)
510 return xf86pow(x, y);
511 #else
512 return pow(x, y);
513 #endif
514 }
515
516
517 /**
518 * Return number of bits set in given GLuint.
519 */
520 unsigned int
521 _mesa_bitcount(unsigned int n)
522 {
523 unsigned int bits;
524 for (bits = 0; n > 0; n = n >> 1) {
525 bits += (n & 1);
526 }
527 return bits;
528 }
529
530
531 /**
532 * Convert a 4-byte float to a 2-byte half float.
533 * Based on code from:
534 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
535 */
536 GLhalfARB
537 _mesa_float_to_half(float val)
538 {
539 const int flt = *((int *) (void *) &val);
540 const int flt_m = flt & 0x7fffff;
541 const int flt_e = (flt >> 23) & 0xff;
542 const int flt_s = (flt >> 31) & 0x1;
543 int s, e, m = 0;
544 GLhalfARB result;
545
546 /* sign bit */
547 s = flt_s;
548
549 /* handle special cases */
550 if ((flt_e == 0) && (flt_m == 0)) {
551 /* zero */
552 /* m = 0; - already set */
553 e = 0;
554 }
555 else if ((flt_e == 0) && (flt_m != 0)) {
556 /* denorm -- denorm float maps to 0 half */
557 /* m = 0; - already set */
558 e = 0;
559 }
560 else if ((flt_e == 0xff) && (flt_m == 0)) {
561 /* infinity */
562 /* m = 0; - already set */
563 e = 31;
564 }
565 else if ((flt_e == 0xff) && (flt_m != 0)) {
566 /* NaN */
567 m = 1;
568 e = 31;
569 }
570 else {
571 /* regular number */
572 const int new_exp = flt_e - 127;
573 if (new_exp < -24) {
574 /* this maps to 0 */
575 /* m = 0; - already set */
576 e = 0;
577 }
578 else if (new_exp < -14) {
579 /* this maps to a denorm */
580 unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
581 e = 0;
582 switch (exp_val) {
583 case 0:
584 _mesa_warning(NULL,
585 "float_to_half: logical error in denorm creation!\n");
586 /* m = 0; - already set */
587 break;
588 case 1: m = 512 + (flt_m >> 14); break;
589 case 2: m = 256 + (flt_m >> 15); break;
590 case 3: m = 128 + (flt_m >> 16); break;
591 case 4: m = 64 + (flt_m >> 17); break;
592 case 5: m = 32 + (flt_m >> 18); break;
593 case 6: m = 16 + (flt_m >> 19); break;
594 case 7: m = 8 + (flt_m >> 20); break;
595 case 8: m = 4 + (flt_m >> 21); break;
596 case 9: m = 2 + (flt_m >> 22); break;
597 case 10: m = 1; break;
598 }
599 }
600 else if (new_exp > 15) {
601 /* map this value to infinity */
602 /* m = 0; - already set */
603 e = 31;
604 }
605 else {
606 /* regular */
607 e = new_exp + 15;
608 m = flt_m >> 13;
609 }
610 }
611
612 result = (s << 15) | (e << 10) | m;
613 return result;
614 }
615
616
617 /**
618 * Convert a 2-byte half float to a 4-byte float.
619 * Based on code from:
620 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
621 */
622 float
623 _mesa_half_to_float(GLhalfARB val)
624 {
625 /* XXX could also use a 64K-entry lookup table */
626 const int m = val & 0x3ff;
627 const int e = (val >> 10) & 0x1f;
628 const int s = (val >> 15) & 0x1;
629 int flt_m, flt_e, flt_s, flt;
630 float result;
631
632 /* sign bit */
633 flt_s = s;
634
635 /* handle special cases */
636 if ((e == 0) && (m == 0)) {
637 /* zero */
638 flt_m = 0;
639 flt_e = 0;
640 }
641 else if ((e == 0) && (m != 0)) {
642 /* denorm -- denorm half will fit in non-denorm single */
643 const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
644 float mantissa = ((float) (m)) / 1024.0f;
645 float sign = s ? -1.0f : 1.0f;
646 return sign * mantissa * half_denorm;
647 }
648 else if ((e == 31) && (m == 0)) {
649 /* infinity */
650 flt_e = 0xff;
651 flt_m = 0;
652 }
653 else if ((e == 31) && (m != 0)) {
654 /* NaN */
655 flt_e = 0xff;
656 flt_m = 1;
657 }
658 else {
659 /* regular */
660 flt_e = e + 112;
661 flt_m = m << 13;
662 }
663
664 flt = (flt_s << 31) | (flt_e << 23) | flt_m;
665 result = *((float *) (void *) &flt);
666 return result;
667 }
668
669 /*@}*/
670
671
672 /**********************************************************************/
673 /** \name Environment vars */
674 /*@{*/
675
676 /**
677 * Wrapper for getenv().
678 */
679 char *
680 _mesa_getenv( const char *var )
681 {
682 #if defined(XFree86LOADER) && defined(IN_MODULE)
683 return xf86getenv(var);
684 #else
685 return getenv(var);
686 #endif
687 }
688
689 /*@}*/
690
691
692 /**********************************************************************/
693 /** \name String */
694 /*@{*/
695
696 /** Wrapper around either strstr() or xf86strstr() */
697 char *
698 _mesa_strstr( const char *haystack, const char *needle )
699 {
700 #if defined(XFree86LOADER) && defined(IN_MODULE)
701 return xf86strstr(haystack, needle);
702 #else
703 return strstr(haystack, needle);
704 #endif
705 }
706
707 /** Wrapper around either strncat() or xf86strncat() */
708 char *
709 _mesa_strncat( char *dest, const char *src, size_t n )
710 {
711 #if defined(XFree86LOADER) && defined(IN_MODULE)
712 return xf86strncat(dest, src, n);
713 #else
714 return strncat(dest, src, n);
715 #endif
716 }
717
718 /** Wrapper around either strcpy() or xf86strcpy() */
719 char *
720 _mesa_strcpy( char *dest, const char *src )
721 {
722 #if defined(XFree86LOADER) && defined(IN_MODULE)
723 return xf86strcpy(dest, src);
724 #else
725 return strcpy(dest, src);
726 #endif
727 }
728
729 /** Wrapper around either strncpy() or xf86strncpy() */
730 char *
731 _mesa_strncpy( char *dest, const char *src, size_t n )
732 {
733 #if defined(XFree86LOADER) && defined(IN_MODULE)
734 return xf86strncpy(dest, src, n);
735 #else
736 return strncpy(dest, src, n);
737 #endif
738 }
739
740 /** Wrapper around either strlen() or xf86strlen() */
741 size_t
742 _mesa_strlen( const char *s )
743 {
744 #if defined(XFree86LOADER) && defined(IN_MODULE)
745 return xf86strlen(s);
746 #else
747 return strlen(s);
748 #endif
749 }
750
751 /** Wrapper around either strcmp() or xf86strcmp() */
752 int
753 _mesa_strcmp( const char *s1, const char *s2 )
754 {
755 #if defined(XFree86LOADER) && defined(IN_MODULE)
756 return xf86strcmp(s1, s2);
757 #else
758 return strcmp(s1, s2);
759 #endif
760 }
761
762 /** Wrapper around either strncmp() or xf86strncmp() */
763 int
764 _mesa_strncmp( const char *s1, const char *s2, size_t n )
765 {
766 #if defined(XFree86LOADER) && defined(IN_MODULE)
767 return xf86strncmp(s1, s2, n);
768 #else
769 return strncmp(s1, s2, n);
770 #endif
771 }
772
773 /** Implemented using _mesa_malloc() and _mesa_strcpy */
774 char *
775 _mesa_strdup( const char *s )
776 {
777 int l = _mesa_strlen(s);
778 char *s2 = (char *) _mesa_malloc(l + 1);
779 if (s2)
780 _mesa_strcpy(s2, s);
781 return s2;
782 }
783
784 /** Wrapper around either atoi() or xf86atoi() */
785 int
786 _mesa_atoi(const char *s)
787 {
788 #if defined(XFree86LOADER) && defined(IN_MODULE)
789 return xf86atoi(s);
790 #else
791 return atoi(s);
792 #endif
793 }
794
795 /** Wrapper around either strtod() or xf86strtod() */
796 double
797 _mesa_strtod( const char *s, char **end )
798 {
799 #if defined(XFree86LOADER) && defined(IN_MODULE)
800 return xf86strtod(s, end);
801 #else
802 return strtod(s, end);
803 #endif
804 }
805
806 /*@}*/
807
808
809 /**********************************************************************/
810 /** \name I/O */
811 /*@{*/
812
813 /** Wrapper around either vsprintf() or xf86vsprintf() */
814 int
815 _mesa_sprintf( char *str, const char *fmt, ... )
816 {
817 int r;
818 va_list args;
819 va_start( args, fmt );
820 va_end( args );
821 #if defined(XFree86LOADER) && defined(IN_MODULE)
822 r = xf86vsprintf( str, fmt, args );
823 #else
824 r = vsprintf( str, fmt, args );
825 #endif
826 return r;
827 }
828
829 /** Wrapper around either printf() or xf86printf(), using vsprintf() for
830 * the formatting. */
831 void
832 _mesa_printf( const char *fmtString, ... )
833 {
834 char s[MAXSTRING];
835 va_list args;
836 va_start( args, fmtString );
837 vsnprintf(s, MAXSTRING, fmtString, args);
838 va_end( args );
839 #if defined(XFree86LOADER) && defined(IN_MODULE)
840 xf86printf("%s", s);
841 #else
842 printf("%s", s);
843 #endif
844 }
845
846 /*@}*/
847
848
849 /**********************************************************************/
850 /** \name Diagnostics */
851 /*@{*/
852
853 /**
854 * Display a warning.
855 *
856 * \param ctx GL context.
857 * \param fmtString printf() alike format string.
858 *
859 * If debugging is enabled (either at compile-time via the DEBUG macro, or
860 * run-time via the MESA_DEBUG environment variable), prints the warning to
861 * stderr, either via fprintf() or xf86printf().
862 */
863 void
864 _mesa_warning( GLcontext *ctx, const char *fmtString, ... )
865 {
866 GLboolean debug;
867 char str[MAXSTRING];
868 va_list args;
869 (void) ctx;
870 va_start( args, fmtString );
871 (void) vsnprintf( str, MAXSTRING, fmtString, args );
872 va_end( args );
873 #ifdef DEBUG
874 debug = GL_TRUE; /* always print warning */
875 #else
876 debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
877 #endif
878 if (debug) {
879 #if defined(XFree86LOADER) && defined(IN_MODULE)
880 xf86fprintf(stderr, "Mesa warning: %s\n", str);
881 #else
882 fprintf(stderr, "Mesa warning: %s\n", str);
883 #endif
884 }
885 }
886
887 /**
888 * This function is called when the Mesa user has stumbled into a code
889 * path which may not be implemented fully or correctly.
890 *
891 * \param ctx GL context.
892 * \param s problem description string.
893 *
894 * Prints the message to stderr, either via fprintf() or xf86fprintf().
895 */
896 void
897 _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
898 {
899 va_list args;
900 char str[MAXSTRING];
901 (void) ctx;
902
903 va_start( args, fmtString );
904 vsnprintf( str, MAXSTRING, fmtString, args );
905 va_end( args );
906
907 #if defined(XFree86LOADER) && defined(IN_MODULE)
908 xf86fprintf(stderr, "Mesa implementation error: %s\n", str);
909 xf86fprintf(stderr, "Please report to the DRI project at dri.sourceforge.net\n");
910 #else
911 fprintf(stderr, "Mesa implementation error: %s\n", str);
912 fprintf(stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
913 #endif
914 }
915
916 /**
917 * Display an error message.
918 *
919 * If in debug mode, print error message.
920 * Also, record the error code by calling _mesa_record_error().
921 *
922 * \param ctx the GL context.
923 * \param error the error value.
924 * \param fmtString printf() style format string, followed by optional args
925 *
926 * If debugging is enabled (either at compile-time via the DEBUG macro, or
927 * run-time via the MESA_DEBUG environment variable), interperts the error code and
928 * prints the error message via _mesa_debug().
929 */
930 void
931 _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
932 {
933 const char *debugEnv;
934 GLboolean debug;
935
936 debugEnv = _mesa_getenv("MESA_DEBUG");
937
938 #ifdef DEBUG
939 if (debugEnv && _mesa_strstr(debugEnv, "silent"))
940 debug = GL_FALSE;
941 else
942 debug = GL_TRUE;
943 #else
944 if (debugEnv)
945 debug = GL_TRUE;
946 else
947 debug = GL_FALSE;
948 #endif
949
950 if (debug) {
951 va_list args;
952 char where[MAXSTRING];
953 const char *errstr;
954
955 va_start( args, fmtString );
956 vsnprintf( where, MAXSTRING, fmtString, args );
957 va_end( args );
958
959 switch (error) {
960 case GL_NO_ERROR:
961 errstr = "GL_NO_ERROR";
962 break;
963 case GL_INVALID_VALUE:
964 errstr = "GL_INVALID_VALUE";
965 break;
966 case GL_INVALID_ENUM:
967 errstr = "GL_INVALID_ENUM";
968 break;
969 case GL_INVALID_OPERATION:
970 errstr = "GL_INVALID_OPERATION";
971 break;
972 case GL_STACK_OVERFLOW:
973 errstr = "GL_STACK_OVERFLOW";
974 break;
975 case GL_STACK_UNDERFLOW:
976 errstr = "GL_STACK_UNDERFLOW";
977 break;
978 case GL_OUT_OF_MEMORY:
979 errstr = "GL_OUT_OF_MEMORY";
980 break;
981 case GL_TABLE_TOO_LARGE:
982 errstr = "GL_TABLE_TOO_LARGE";
983 break;
984 default:
985 errstr = "unknown";
986 break;
987 }
988 _mesa_debug(ctx, "User error: %s in %s\n", errstr, where);
989 }
990
991 _mesa_record_error(ctx, error);
992 }
993
994 /**
995 * Report debug information.
996 *
997 * \param ctx GL context.
998 * \param fmtString printf() alike format string.
999 *
1000 * Prints the message to stderr, either via fprintf() or xf86printf().
1001 */
1002 void
1003 _mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
1004 {
1005 char s[MAXSTRING];
1006 va_list args;
1007 (void) ctx;
1008 va_start(args, fmtString);
1009 vsnprintf(s, MAXSTRING, fmtString, args);
1010 va_end(args);
1011 #if defined(XFree86LOADER) && defined(IN_MODULE)
1012 xf86fprintf(stderr, "Mesa: %s", s);
1013 #else
1014 fprintf(stderr, "Mesa: %s", s);
1015 #endif
1016 }
1017
1018 /*@}*/
1019
1020
1021 /**********************************************************************/
1022 /** \name Default Imports Wrapper */
1023 /*@{*/
1024
1025 /** Wrapper around _mesa_malloc() */
1026 static void *
1027 default_malloc(__GLcontext *gc, size_t size)
1028 {
1029 (void) gc;
1030 return _mesa_malloc(size);
1031 }
1032
1033 /** Wrapper around _mesa_malloc() */
1034 static void *
1035 default_calloc(__GLcontext *gc, size_t numElem, size_t elemSize)
1036 {
1037 (void) gc;
1038 return _mesa_calloc(numElem * elemSize);
1039 }
1040
1041 /** Wrapper around either realloc() or xf86realloc() */
1042 static void *
1043 default_realloc(__GLcontext *gc, void *oldAddr, size_t newSize)
1044 {
1045 (void) gc;
1046 #if defined(XFree86LOADER) && defined(IN_MODULE)
1047 return xf86realloc(oldAddr, newSize);
1048 #else
1049 return realloc(oldAddr, newSize);
1050 #endif
1051 }
1052
1053 /** Wrapper around _mesa_free() */
1054 static void
1055 default_free(__GLcontext *gc, void *addr)
1056 {
1057 (void) gc;
1058 _mesa_free(addr);
1059 }
1060
1061 /** Wrapper around _mesa_getenv() */
1062 static char * CAPI
1063 default_getenv( __GLcontext *gc, const char *var )
1064 {
1065 (void) gc;
1066 return _mesa_getenv(var);
1067 }
1068
1069 /** Wrapper around _mesa_warning() */
1070 static void
1071 default_warning(__GLcontext *gc, char *str)
1072 {
1073 _mesa_warning(gc, str);
1074 }
1075
1076 /** Wrapper around _mesa_problem() */
1077 static void
1078 default_fatal(__GLcontext *gc, char *str)
1079 {
1080 _mesa_problem(gc, str);
1081 abort();
1082 }
1083
1084 /** Wrapper around atoi() */
1085 static int CAPI
1086 default_atoi(__GLcontext *gc, const char *str)
1087 {
1088 (void) gc;
1089 return atoi(str);
1090 }
1091
1092 /** Wrapper around vsprintf() */
1093 static int CAPI
1094 default_sprintf(__GLcontext *gc, char *str, const char *fmt, ...)
1095 {
1096 int r;
1097 va_list args;
1098 (void) gc;
1099 va_start( args, fmt );
1100 r = vsprintf( str, fmt, args );
1101 va_end( args );
1102 return r;
1103 }
1104
1105 /** Wrapper around fopen() */
1106 static void * CAPI
1107 default_fopen(__GLcontext *gc, const char *path, const char *mode)
1108 {
1109 (void) gc;
1110 return fopen(path, mode);
1111 }
1112
1113 /** Wrapper around fclose() */
1114 static int CAPI
1115 default_fclose(__GLcontext *gc, void *stream)
1116 {
1117 (void) gc;
1118 return fclose((FILE *) stream);
1119 }
1120
1121 /** Wrapper around vfprintf() */
1122 static int CAPI
1123 default_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
1124 {
1125 int r;
1126 va_list args;
1127 (void) gc;
1128 va_start( args, fmt );
1129 r = vfprintf( (FILE *) stream, fmt, args );
1130 va_end( args );
1131 return r;
1132 }
1133
1134 /**
1135 * \todo this really is driver-specific and can't be here
1136 */
1137 static __GLdrawablePrivate *
1138 default_GetDrawablePrivate(__GLcontext *gc)
1139 {
1140 (void) gc;
1141 return NULL;
1142 }
1143
1144 /*@}*/
1145
1146
1147 /**
1148 * Initialize a __GLimports object to point to the functions in this
1149 * file.
1150 *
1151 * This is to be called from device drivers.
1152 *
1153 * Also, do some one-time initializations.
1154 *
1155 * \param imports the object to initialize.
1156 * \param driverCtx pointer to device driver-specific data.
1157 */
1158 void
1159 _mesa_init_default_imports(__GLimports *imports, void *driverCtx)
1160 {
1161 /* XXX maybe move this one-time init stuff into context.c */
1162 static GLboolean initialized = GL_FALSE;
1163 if (!initialized) {
1164 init_sqrt_table();
1165
1166 #if defined(_FPU_GETCW) && defined(_FPU_SETCW)
1167 {
1168 const char *debug = _mesa_getenv("MESA_DEBUG");
1169 if (debug && _mesa_strcmp(debug, "FP")==0) {
1170 /* die on FP exceptions */
1171 fpu_control_t mask;
1172 _FPU_GETCW(mask);
1173 mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
1174 | _FPU_MASK_OM | _FPU_MASK_UM);
1175 _FPU_SETCW(mask);
1176 }
1177 }
1178 #endif
1179 initialized = GL_TRUE;
1180 }
1181
1182 imports->malloc = default_malloc;
1183 imports->calloc = default_calloc;
1184 imports->realloc = default_realloc;
1185 imports->free = default_free;
1186 imports->warning = default_warning;
1187 imports->fatal = default_fatal;
1188 imports->getenv = default_getenv; /* not used for now */
1189 imports->atoi = default_atoi;
1190 imports->sprintf = default_sprintf;
1191 imports->fopen = default_fopen;
1192 imports->fclose = default_fclose;
1193 imports->fprintf = default_fprintf;
1194 imports->getDrawablePrivate = default_GetDrawablePrivate;
1195 imports->other = driverCtx;
1196 }