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