aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/imports.c2061
-rw-r--r--mesalib/src/mesa/main/imports.h1217
2 files changed, 1643 insertions, 1635 deletions
diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c
index f98098230..bf89815f2 100644
--- a/mesalib/src/mesa/main/imports.c
+++ b/mesalib/src/mesa/main/imports.c
@@ -1,1033 +1,1028 @@
-/**
- * \file imports.c
- * Standard C library function wrappers.
- *
- * Imports are services which the device driver or window system or
- * operating system provides to the core renderer. The core renderer (Mesa)
- * will call these functions in order to do memory allocation, simple I/O,
- * etc.
- *
- * Some drivers will want to override/replace this file with something
- * specialized, but that'll be rare.
- *
- * Eventually, I want to move roll the glheader.h file into this.
- *
- * \todo Functions still needed:
- * - scanf
- * - qsort
- * - rand and RAND_MAX
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-
-#include "imports.h"
-#include "context.h"
-#include "mtypes.h"
-#include "version.h"
-
-#ifdef _GNU_SOURCE
-#include <locale.h>
-#ifdef __APPLE__
-#include <xlocale.h>
-#endif
-#endif
-
-
-#define MAXSTRING 4000 /* for vsnprintf() */
-
-#ifdef WIN32
-#define vsnprintf _vsnprintf
-#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
-extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
-#ifdef __VMS
-#include "vsnprintf.c"
-#endif
-#endif
-
-/**********************************************************************/
-/** \name Memory */
-/*@{*/
-
-/**
- * Allocate aligned memory.
- *
- * \param bytes number of bytes to allocate.
- * \param alignment alignment (must be greater than zero).
- *
- * Allocates extra memory to accommodate rounding up the address for
- * alignment and to record the real malloc address.
- *
- * \sa _mesa_align_free().
- */
-void *
-_mesa_align_malloc(size_t bytes, unsigned long alignment)
-{
-#if defined(HAVE_POSIX_MEMALIGN)
- void *mem;
- int err = posix_memalign(& mem, alignment, bytes);
- if (err)
- return NULL;
- return mem;
-#elif defined(_WIN32) && defined(_MSC_VER)
- return _aligned_malloc(bytes, alignment);
-#else
- uintptr_t ptr, buf;
-
- ASSERT( alignment > 0 );
-
- ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *));
- if (!ptr)
- return NULL;
-
- buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
- *(uintptr_t *)(buf - sizeof(void *)) = ptr;
-
-#ifdef DEBUG
- /* mark the non-aligned area */
- while ( ptr < buf - sizeof(void *) ) {
- *(unsigned long *)ptr = 0xcdcdcdcd;
- ptr += sizeof(unsigned long);
- }
-#endif
-
- return (void *) buf;
-#endif /* defined(HAVE_POSIX_MEMALIGN) */
-}
-
-/**
- * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
- * malloc()
- */
-void *
-_mesa_align_calloc(size_t bytes, unsigned long alignment)
-{
-#if defined(HAVE_POSIX_MEMALIGN)
- void *mem;
-
- mem = _mesa_align_malloc(bytes, alignment);
- if (mem != NULL) {
- (void) memset(mem, 0, bytes);
- }
-
- return mem;
-#elif defined(_WIN32) && defined(_MSC_VER)
- void *mem;
-
- mem = _aligned_malloc(bytes, alignment);
- if (mem != NULL) {
- (void) memset(mem, 0, bytes);
- }
-
- return mem;
-#else
- uintptr_t ptr, buf;
-
- ASSERT( alignment > 0 );
-
- ptr = (uintptr_t) calloc(1, bytes + alignment + sizeof(void *));
- if (!ptr)
- return NULL;
-
- buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
- *(uintptr_t *)(buf - sizeof(void *)) = ptr;
-
-#ifdef DEBUG
- /* mark the non-aligned area */
- while ( ptr < buf - sizeof(void *) ) {
- *(unsigned long *)ptr = 0xcdcdcdcd;
- ptr += sizeof(unsigned long);
- }
-#endif
-
- return (void *)buf;
-#endif /* defined(HAVE_POSIX_MEMALIGN) */
-}
-
-/**
- * Free memory which was allocated with either _mesa_align_malloc()
- * or _mesa_align_calloc().
- * \param ptr pointer to the memory to be freed.
- * The actual address to free is stored in the word immediately before the
- * address the client sees.
- */
-void
-_mesa_align_free(void *ptr)
-{
-#if defined(HAVE_POSIX_MEMALIGN)
- free(ptr);
-#elif defined(_WIN32) && defined(_MSC_VER)
- _aligned_free(ptr);
-#else
- void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
- void *realAddr = *cubbyHole;
- free(realAddr);
-#endif /* defined(HAVE_POSIX_MEMALIGN) */
-}
-
-/**
- * Reallocate memory, with alignment.
- */
-void *
-_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
- unsigned long alignment)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
- (void) oldSize;
- return _aligned_realloc(oldBuffer, newSize, alignment);
-#else
- const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
- void *newBuf = _mesa_align_malloc(newSize, alignment);
- if (newBuf && oldBuffer && copySize > 0) {
- memcpy(newBuf, oldBuffer, copySize);
- }
- if (oldBuffer)
- _mesa_align_free(oldBuffer);
- return newBuf;
-#endif
-}
-
-
-
-/** Reallocate memory */
-void *
-_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
-{
- const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
- void *newBuffer = malloc(newSize);
- if (newBuffer && oldBuffer && copySize > 0)
- memcpy(newBuffer, oldBuffer, copySize);
- if (oldBuffer)
- free(oldBuffer);
- return newBuffer;
-}
-
-/**
- * Fill memory with a constant 16bit word.
- * \param dst destination pointer.
- * \param val value.
- * \param n number of words.
- */
-void
-_mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
-{
- while (n-- > 0)
- *dst++ = val;
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Math */
-/*@{*/
-
-/** Wrapper around sqrt() */
-double
-_mesa_sqrtd(double x)
-{
- return sqrt(x);
-}
-
-
-/*
- * A High Speed, Low Precision Square Root
- * by Paul Lalonde and Robert Dawson
- * from "Graphics Gems", Academic Press, 1990
- *
- * SPARC implementation of a fast square root by table
- * lookup.
- * SPARC floating point format is as follows:
- *
- * BIT 31 30 23 22 0
- * sign exponent mantissa
- */
-static short sqrttab[0x100]; /* declare table of square roots */
-
-void
-_mesa_init_sqrt_table(void)
-{
-#if defined(USE_IEEE) && !defined(DEBUG)
- unsigned short i;
- fi_type fi; /* to access the bits of a float in C quickly */
- /* we use a union defined in glheader.h */
-
- for(i=0; i<= 0x7f; i++) {
- fi.i = 0;
-
- /*
- * Build a float with the bit pattern i as mantissa
- * and an exponent of 0, stored as 127
- */
-
- fi.i = (i << 16) | (127 << 23);
- fi.f = _mesa_sqrtd(fi.f);
-
- /*
- * Take the square root then strip the first 7 bits of
- * the mantissa into the table
- */
-
- sqrttab[i] = (fi.i & 0x7fffff) >> 16;
-
- /*
- * Repeat the process, this time with an exponent of
- * 1, stored as 128
- */
-
- fi.i = 0;
- fi.i = (i << 16) | (128 << 23);
- fi.f = sqrt(fi.f);
- sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
- }
-#else
- (void) sqrttab; /* silence compiler warnings */
-#endif /*HAVE_FAST_MATH*/
-}
-
-
-/**
- * Single precision square root.
- */
-float
-_mesa_sqrtf( float x )
-{
-#if defined(USE_IEEE) && !defined(DEBUG)
- fi_type num;
- /* to access the bits of a float in C
- * we use a union from glheader.h */
-
- short e; /* the exponent */
- if (x == 0.0F) return 0.0F; /* check for square root of 0 */
- num.f = x;
- e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */
- /* exponent is stored with 127 added */
- num.i &= 0x7fffff; /* leave only the mantissa */
- if (e & 0x01) num.i |= 0x800000;
- /* the exponent is odd so we have to */
- /* look it up in the second half of */
- /* the lookup table, so we set the */
- /* high bit */
- e >>= 1; /* divide the exponent by two */
- /* note that in C the shift */
- /* operators are sign preserving */
- /* for signed operands */
- /* Do the table lookup, based on the quaternary mantissa,
- * then reconstruct the result back into a float
- */
- num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
-
- return num.f;
-#else
- return (float) _mesa_sqrtd((double) x);
-#endif
-}
-
-
-/**
- inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
- written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
- and Vesa Karvonen.
-*/
-float
-_mesa_inv_sqrtf(float n)
-{
-#if defined(USE_IEEE) && !defined(DEBUG)
- float r0, x0, y0;
- float r1, x1, y1;
- float r2, x2, y2;
-#if 0 /* not used, see below -BP */
- float r3, x3, y3;
-#endif
- fi_type u;
- unsigned int magic;
-
- /*
- Exponent part of the magic number -
-
- We want to:
- 1. subtract the bias from the exponent,
- 2. negate it
- 3. divide by two (rounding towards -inf)
- 4. add the bias back
-
- Which is the same as subtracting the exponent from 381 and dividing
- by 2.
-
- floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
- */
-
- magic = 381 << 23;
-
- /*
- Significand part of magic number -
-
- With the current magic number, "(magic - u.i) >> 1" will give you:
-
- for 1 <= u.f <= 2: 1.25 - u.f / 4
- for 2 <= u.f <= 4: 1.00 - u.f / 8
-
- This isn't a bad approximation of 1/sqrt. The maximum difference from
- 1/sqrt will be around .06. After three Newton-Raphson iterations, the
- maximum difference is less than 4.5e-8. (Which is actually close
- enough to make the following bias academic...)
-
- To get a better approximation you can add a bias to the magic
- number. For example, if you subtract 1/2 of the maximum difference in
- the first approximation (.03), you will get the following function:
-
- for 1 <= u.f <= 2: 1.22 - u.f / 4
- for 2 <= u.f <= 3.76: 0.97 - u.f / 8
- for 3.76 <= u.f <= 4: 0.72 - u.f / 16
- (The 3.76 to 4 range is where the result is < .5.)
-
- This is the closest possible initial approximation, but with a maximum
- error of 8e-11 after three NR iterations, it is still not perfect. If
- you subtract 0.0332281 instead of .03, the maximum error will be
- 2.5e-11 after three NR iterations, which should be about as close as
- is possible.
-
- for 1 <= u.f <= 2: 1.2167719 - u.f / 4
- for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
- for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
-
- */
-
- magic -= (int)(0.0332281 * (1 << 25));
-
- u.f = n;
- u.i = (magic - u.i) >> 1;
-
- /*
- Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
- allows more parallelism. From what I understand, the parallelism
- comes at the cost of less precision, because it lets error
- accumulate across iterations.
- */
- x0 = 1.0f;
- y0 = 0.5f * n;
- r0 = u.f;
-
- x1 = x0 * r0;
- y1 = y0 * r0 * r0;
- r1 = 1.5f - y1;
-
- x2 = x1 * r1;
- y2 = y1 * r1 * r1;
- r2 = 1.5f - y2;
-
-#if 1
- return x2 * r2; /* we can stop here, and be conformant -BP */
-#else
- x3 = x2 * r2;
- y3 = y2 * r2 * r2;
- r3 = 1.5f - y3;
-
- return x3 * r3;
-#endif
-#else
- return (float) (1.0 / sqrt(n));
-#endif
-}
-
-/**
- * Find the first bit set in a word.
- */
-int
-_mesa_ffs(int32_t i)
-{
-#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__)
- register int bit = 0;
- if (i != 0) {
- if ((i & 0xffff) == 0) {
- bit += 16;
- i >>= 16;
- }
- if ((i & 0xff) == 0) {
- bit += 8;
- i >>= 8;
- }
- if ((i & 0xf) == 0) {
- bit += 4;
- i >>= 4;
- }
- while ((i & 1) == 0) {
- bit++;
- i >>= 1;
- }
- bit++;
- }
- return bit;
-#else
- return ffs(i);
-#endif
-}
-
-
-/**
- * Find position of first bit set in given value.
- * XXX Warning: this function can only be used on 64-bit systems!
- * \return position of least-significant bit set, starting at 1, return zero
- * if no bits set.
- */
-int
-_mesa_ffsll(int64_t val)
-{
-#ifdef ffsll
- return ffsll(val);
-#else
- int bit;
-
- assert(sizeof(val) == 8);
-
- bit = _mesa_ffs((int32_t)val);
- if (bit != 0)
- return bit;
-
- bit = _mesa_ffs((int32_t)(val >> 32));
- if (bit != 0)
- return 32 + bit;
-
- return 0;
-#endif
-}
-
-
-/**
- * Return number of bits set in given GLuint.
- */
-unsigned int
-_mesa_bitcount(unsigned int n)
-{
-#if defined(__GNUC__) && \
- ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
- return __builtin_popcount(n);
-#else
- unsigned int bits;
- for (bits = 0; n > 0; n = n >> 1) {
- bits += (n & 1);
- }
- return bits;
-#endif
-}
-
-
-/**
- * Convert a 4-byte float to a 2-byte half float.
- * Based on code from:
- * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
- */
-GLhalfARB
-_mesa_float_to_half(float val)
-{
- const fi_type fi = {val};
- const int flt_m = fi.i & 0x7fffff;
- const int flt_e = (fi.i >> 23) & 0xff;
- const int flt_s = (fi.i >> 31) & 0x1;
- int s, e, m = 0;
- GLhalfARB result;
-
- /* sign bit */
- s = flt_s;
-
- /* handle special cases */
- if ((flt_e == 0) && (flt_m == 0)) {
- /* zero */
- /* m = 0; - already set */
- e = 0;
- }
- else if ((flt_e == 0) && (flt_m != 0)) {
- /* denorm -- denorm float maps to 0 half */
- /* m = 0; - already set */
- e = 0;
- }
- else if ((flt_e == 0xff) && (flt_m == 0)) {
- /* infinity */
- /* m = 0; - already set */
- e = 31;
- }
- else if ((flt_e == 0xff) && (flt_m != 0)) {
- /* NaN */
- m = 1;
- e = 31;
- }
- else {
- /* regular number */
- const int new_exp = flt_e - 127;
- if (new_exp < -24) {
- /* this maps to 0 */
- /* m = 0; - already set */
- e = 0;
- }
- else if (new_exp < -14) {
- /* this maps to a denorm */
- unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
- e = 0;
- switch (exp_val) {
- case 0:
- _mesa_warning(NULL,
- "float_to_half: logical error in denorm creation!\n");
- /* m = 0; - already set */
- break;
- case 1: m = 512 + (flt_m >> 14); break;
- case 2: m = 256 + (flt_m >> 15); break;
- case 3: m = 128 + (flt_m >> 16); break;
- case 4: m = 64 + (flt_m >> 17); break;
- case 5: m = 32 + (flt_m >> 18); break;
- case 6: m = 16 + (flt_m >> 19); break;
- case 7: m = 8 + (flt_m >> 20); break;
- case 8: m = 4 + (flt_m >> 21); break;
- case 9: m = 2 + (flt_m >> 22); break;
- case 10: m = 1; break;
- }
- }
- else if (new_exp > 15) {
- /* map this value to infinity */
- /* m = 0; - already set */
- e = 31;
- }
- else {
- /* regular */
- e = new_exp + 15;
- m = flt_m >> 13;
- }
- }
-
- result = (s << 15) | (e << 10) | m;
- return result;
-}
-
-
-/**
- * Convert a 2-byte half float to a 4-byte float.
- * Based on code from:
- * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
- */
-float
-_mesa_half_to_float(GLhalfARB val)
-{
- /* XXX could also use a 64K-entry lookup table */
- const int m = val & 0x3ff;
- const int e = (val >> 10) & 0x1f;
- const int s = (val >> 15) & 0x1;
- int flt_m, flt_e, flt_s;
- fi_type fi;
- float result;
-
- /* sign bit */
- flt_s = s;
-
- /* handle special cases */
- if ((e == 0) && (m == 0)) {
- /* zero */
- flt_m = 0;
- flt_e = 0;
- }
- else if ((e == 0) && (m != 0)) {
- /* denorm -- denorm half will fit in non-denorm single */
- const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
- float mantissa = ((float) (m)) / 1024.0f;
- float sign = s ? -1.0f : 1.0f;
- return sign * mantissa * half_denorm;
- }
- else if ((e == 31) && (m == 0)) {
- /* infinity */
- flt_e = 0xff;
- flt_m = 0;
- }
- else if ((e == 31) && (m != 0)) {
- /* NaN */
- flt_e = 0xff;
- flt_m = 1;
- }
- else {
- /* regular */
- flt_e = e + 112;
- flt_m = m << 13;
- }
-
- fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
- result = fi.f;
- return result;
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Sort & Search */
-/*@{*/
-
-/**
- * Wrapper for bsearch().
- */
-void *
-_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
- int (*compar)(const void *, const void *) )
-{
-#if defined(_WIN32_WCE)
- void *mid;
- int cmp;
- while (nmemb) {
- nmemb >>= 1;
- mid = (char *)base + nmemb * size;
- cmp = (*compar)(key, mid);
- if (cmp == 0)
- return mid;
- if (cmp > 0) {
- base = (char *)mid + size;
- --nmemb;
- }
- }
- return NULL;
-#else
- return bsearch(key, base, nmemb, size, compar);
-#endif
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Environment vars */
-/*@{*/
-
-/**
- * Wrapper for getenv().
- */
-char *
-_mesa_getenv( const char *var )
-{
-#if defined(_XBOX) || defined(_WIN32_WCE)
- return NULL;
-#else
- return getenv(var);
-#endif
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name String */
-/*@{*/
-
-/**
- * Implemented using malloc() and strcpy.
- * Note that NULL is handled accordingly.
- */
-char *
-_mesa_strdup( const char *s )
-{
- if (s) {
- size_t l = strlen(s);
- char *s2 = (char *) malloc(l + 1);
- if (s2)
- strcpy(s2, s);
- return s2;
- }
- else {
- return NULL;
- }
-}
-
-/** Wrapper around strtof() */
-float
-_mesa_strtof( const char *s, char **end )
-{
-#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__)
- static locale_t loc = NULL;
- if (!loc) {
- loc = newlocale(LC_CTYPE_MASK, "C", NULL);
- }
- return strtof_l(s, end, loc);
-#elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
- return strtof(s, end);
-#else
- return (float)strtod(s, end);
-#endif
-}
-
-/** Compute simple checksum/hash for a string */
-unsigned int
-_mesa_str_checksum(const char *str)
-{
- /* This could probably be much better */
- unsigned int sum, i;
- const char *c;
- sum = i = 1;
- for (c = str; *c; c++, i++)
- sum += *c * (i % 100);
- return sum + i;
-}
-
-
-/*@}*/
-
-
-/** Wrapper around vsnprintf() */
-int
-_mesa_snprintf( char *str, size_t size, const char *fmt, ... )
-{
- int r;
- va_list args;
- va_start( args, fmt );
- r = vsnprintf( str, size, fmt, args );
- va_end( args );
- return r;
-}
-
-
-/**********************************************************************/
-/** \name Diagnostics */
-/*@{*/
-
-static void
-output_if_debug(const char *prefixString, const char *outputString,
- GLboolean newline)
-{
- static int debug = -1;
-
- /* Check the MESA_DEBUG environment variable if it hasn't
- * been checked yet. We only have to check it once...
- */
- if (debug == -1) {
- char *env = _mesa_getenv("MESA_DEBUG");
-
- /* In a debug build, we print warning messages *unless*
- * MESA_DEBUG is 0. In a non-debug build, we don't
- * print warning messages *unless* MESA_DEBUG is
- * set *to any value*.
- */
-#ifdef DEBUG
- debug = (env != NULL && atoi(env) == 0) ? 0 : 1;
-#else
- debug = (env != NULL) ? 1 : 0;
-#endif
- }
-
- /* Now only print the string if we're required to do so. */
- if (debug) {
- fprintf(stderr, "%s: %s", prefixString, outputString);
- if (newline)
- fprintf(stderr, "\n");
-
-#if defined(_WIN32) && !defined(_WIN32_WCE)
- /* stderr from windows applications without console is not usually
- * visible, so communicate with the debugger instead */
- {
- char buf[4096];
- _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
- OutputDebugStringA(buf);
- }
-#endif
- }
-}
-
-
-/**
- * Return string version of GL error code.
- */
-static const char *
-error_string( GLenum error )
-{
- switch (error) {
- case GL_NO_ERROR:
- return "GL_NO_ERROR";
- case GL_INVALID_VALUE:
- return "GL_INVALID_VALUE";
- case GL_INVALID_ENUM:
- return "GL_INVALID_ENUM";
- case GL_INVALID_OPERATION:
- return "GL_INVALID_OPERATION";
- case GL_STACK_OVERFLOW:
- return "GL_STACK_OVERFLOW";
- case GL_STACK_UNDERFLOW:
- return "GL_STACK_UNDERFLOW";
- case GL_OUT_OF_MEMORY:
- return "GL_OUT_OF_MEMORY";
- case GL_TABLE_TOO_LARGE:
- return "GL_TABLE_TOO_LARGE";
- case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
- return "GL_INVALID_FRAMEBUFFER_OPERATION";
- default:
- return "unknown";
- }
-}
-
-
-/**
- * When a new type of error is recorded, print a message describing
- * previous errors which were accumulated.
- */
-static void
-flush_delayed_errors( struct gl_context *ctx )
-{
- char s[MAXSTRING];
-
- if (ctx->ErrorDebugCount) {
- _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
- ctx->ErrorDebugCount,
- error_string(ctx->ErrorValue));
-
- output_if_debug("Mesa", s, GL_TRUE);
-
- ctx->ErrorDebugCount = 0;
- }
-}
-
-
-/**
- * Report a warning (a recoverable error condition) to stderr if
- * either DEBUG is defined or the MESA_DEBUG env var is set.
- *
- * \param ctx GL context.
- * \param fmtString printf()-like format string.
- */
-void
-_mesa_warning( struct gl_context *ctx, const char *fmtString, ... )
-{
- char str[MAXSTRING];
- va_list args;
- va_start( args, fmtString );
- (void) vsnprintf( str, MAXSTRING, fmtString, args );
- va_end( args );
-
- if (ctx)
- flush_delayed_errors( ctx );
-
- output_if_debug("Mesa warning", str, GL_TRUE);
-}
-
-
-/**
- * Report an internal implementation problem.
- * Prints the message to stderr via fprintf().
- *
- * \param ctx GL context.
- * \param fmtString problem description string.
- */
-void
-_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
-{
- va_list args;
- char str[MAXSTRING];
- (void) ctx;
-
- va_start( args, fmtString );
- vsnprintf( str, MAXSTRING, fmtString, args );
- va_end( args );
-
- fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
- fprintf(stderr, "Please report at bugs.freedesktop.org\n");
-}
-
-
-/**
- * Record an OpenGL state error. These usually occur when the user
- * passes invalid parameters to a GL function.
- *
- * If debugging is enabled (either at compile-time via the DEBUG macro, or
- * run-time via the MESA_DEBUG environment variable), report the error with
- * _mesa_debug().
- *
- * \param ctx the GL context.
- * \param error the error value.
- * \param fmtString printf() style format string, followed by optional args
- */
-void
-_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
-{
- static GLint debug = -1;
-
- /* Check debug environment variable only once:
- */
- if (debug == -1) {
- const char *debugEnv = _mesa_getenv("MESA_DEBUG");
-
-#ifdef DEBUG
- if (debugEnv && strstr(debugEnv, "silent"))
- debug = GL_FALSE;
- else
- debug = GL_TRUE;
-#else
- if (debugEnv)
- debug = GL_TRUE;
- else
- debug = GL_FALSE;
-#endif
- }
-
- if (debug) {
- if (ctx->ErrorValue == error &&
- ctx->ErrorDebugFmtString == fmtString) {
- ctx->ErrorDebugCount++;
- }
- else {
- char s[MAXSTRING], s2[MAXSTRING];
- va_list args;
-
- flush_delayed_errors( ctx );
-
- va_start(args, fmtString);
- vsnprintf(s, MAXSTRING, fmtString, args);
- va_end(args);
-
- _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s);
- output_if_debug("Mesa: User error", s2, GL_TRUE);
-
- ctx->ErrorDebugFmtString = fmtString;
- ctx->ErrorDebugCount = 0;
- }
- }
-
- _mesa_record_error(ctx, error);
-}
-
-
-/**
- * Report debug information. Print error message to stderr via fprintf().
- * No-op if DEBUG mode not enabled.
- *
- * \param ctx GL context.
- * \param fmtString printf()-style format string, followed by optional args.
- */
-void
-_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
-{
-#ifdef DEBUG
- char s[MAXSTRING];
- va_list args;
- va_start(args, fmtString);
- vsnprintf(s, MAXSTRING, fmtString, args);
- va_end(args);
- output_if_debug("Mesa", s, GL_FALSE);
-#endif /* DEBUG */
- (void) ctx;
- (void) fmtString;
-}
-
-/*@}*/
+/**
+ * \file imports.c
+ * Standard C library function wrappers.
+ *
+ * Imports are services which the device driver or window system or
+ * operating system provides to the core renderer. The core renderer (Mesa)
+ * will call these functions in order to do memory allocation, simple I/O,
+ * etc.
+ *
+ * Some drivers will want to override/replace this file with something
+ * specialized, but that'll be rare.
+ *
+ * Eventually, I want to move roll the glheader.h file into this.
+ *
+ * \todo Functions still needed:
+ * - scanf
+ * - qsort
+ * - rand and RAND_MAX
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "imports.h"
+#include "context.h"
+#include "mtypes.h"
+#include "version.h"
+
+#ifdef _GNU_SOURCE
+#include <locale.h>
+#ifdef __APPLE__
+#include <xlocale.h>
+#endif
+#endif
+
+
+#define MAXSTRING 4000 /* for vsnprintf() */
+
+#ifdef WIN32
+#define vsnprintf _vsnprintf
+#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
+extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
+#ifdef __VMS
+#include "vsnprintf.c"
+#endif
+#endif
+
+/**********************************************************************/
+/** \name Memory */
+/*@{*/
+
+/**
+ * Allocate aligned memory.
+ *
+ * \param bytes number of bytes to allocate.
+ * \param alignment alignment (must be greater than zero).
+ *
+ * Allocates extra memory to accommodate rounding up the address for
+ * alignment and to record the real malloc address.
+ *
+ * \sa _mesa_align_free().
+ */
+void *
+_mesa_align_malloc(size_t bytes, unsigned long alignment)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ void *mem;
+ int err = posix_memalign(& mem, alignment, bytes);
+ if (err)
+ return NULL;
+ return mem;
+#elif defined(_WIN32) && defined(_MSC_VER)
+ return _aligned_malloc(bytes, alignment);
+#else
+ uintptr_t ptr, buf;
+
+ ASSERT( alignment > 0 );
+
+ ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *));
+ if (!ptr)
+ return NULL;
+
+ buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
+ *(uintptr_t *)(buf - sizeof(void *)) = ptr;
+
+#ifdef DEBUG
+ /* mark the non-aligned area */
+ while ( ptr < buf - sizeof(void *) ) {
+ *(unsigned long *)ptr = 0xcdcdcdcd;
+ ptr += sizeof(unsigned long);
+ }
+#endif
+
+ return (void *) buf;
+#endif /* defined(HAVE_POSIX_MEMALIGN) */
+}
+
+/**
+ * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
+ * malloc()
+ */
+void *
+_mesa_align_calloc(size_t bytes, unsigned long alignment)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ void *mem;
+
+ mem = _mesa_align_malloc(bytes, alignment);
+ if (mem != NULL) {
+ (void) memset(mem, 0, bytes);
+ }
+
+ return mem;
+#elif defined(_WIN32) && defined(_MSC_VER)
+ void *mem;
+
+ mem = _aligned_malloc(bytes, alignment);
+ if (mem != NULL) {
+ (void) memset(mem, 0, bytes);
+ }
+
+ return mem;
+#else
+ uintptr_t ptr, buf;
+
+ ASSERT( alignment > 0 );
+
+ ptr = (uintptr_t) calloc(1, bytes + alignment + sizeof(void *));
+ if (!ptr)
+ return NULL;
+
+ buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
+ *(uintptr_t *)(buf - sizeof(void *)) = ptr;
+
+#ifdef DEBUG
+ /* mark the non-aligned area */
+ while ( ptr < buf - sizeof(void *) ) {
+ *(unsigned long *)ptr = 0xcdcdcdcd;
+ ptr += sizeof(unsigned long);
+ }
+#endif
+
+ return (void *)buf;
+#endif /* defined(HAVE_POSIX_MEMALIGN) */
+}
+
+/**
+ * Free memory which was allocated with either _mesa_align_malloc()
+ * or _mesa_align_calloc().
+ * \param ptr pointer to the memory to be freed.
+ * The actual address to free is stored in the word immediately before the
+ * address the client sees.
+ */
+void
+_mesa_align_free(void *ptr)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ free(ptr);
+#elif defined(_WIN32) && defined(_MSC_VER)
+ _aligned_free(ptr);
+#else
+ void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
+ void *realAddr = *cubbyHole;
+ free(realAddr);
+#endif /* defined(HAVE_POSIX_MEMALIGN) */
+}
+
+/**
+ * Reallocate memory, with alignment.
+ */
+void *
+_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
+ unsigned long alignment)
+{
+#if defined(_WIN32) && defined(_MSC_VER)
+ (void) oldSize;
+ return _aligned_realloc(oldBuffer, newSize, alignment);
+#else
+ const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
+ void *newBuf = _mesa_align_malloc(newSize, alignment);
+ if (newBuf && oldBuffer && copySize > 0) {
+ memcpy(newBuf, oldBuffer, copySize);
+ }
+ if (oldBuffer)
+ _mesa_align_free(oldBuffer);
+ return newBuf;
+#endif
+}
+
+
+
+/** Reallocate memory */
+void *
+_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
+{
+ const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
+ void *newBuffer = malloc(newSize);
+ if (newBuffer && oldBuffer && copySize > 0)
+ memcpy(newBuffer, oldBuffer, copySize);
+ if (oldBuffer)
+ free(oldBuffer);
+ return newBuffer;
+}
+
+/**
+ * Fill memory with a constant 16bit word.
+ * \param dst destination pointer.
+ * \param val value.
+ * \param n number of words.
+ */
+void
+_mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
+{
+ while (n-- > 0)
+ *dst++ = val;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Math */
+/*@{*/
+
+/** Wrapper around sqrt() */
+double
+_mesa_sqrtd(double x)
+{
+ return sqrt(x);
+}
+
+
+/*
+ * A High Speed, Low Precision Square Root
+ * by Paul Lalonde and Robert Dawson
+ * from "Graphics Gems", Academic Press, 1990
+ *
+ * SPARC implementation of a fast square root by table
+ * lookup.
+ * SPARC floating point format is as follows:
+ *
+ * BIT 31 30 23 22 0
+ * sign exponent mantissa
+ */
+static short sqrttab[0x100]; /* declare table of square roots */
+
+void
+_mesa_init_sqrt_table(void)
+{
+#if defined(USE_IEEE) && !defined(DEBUG)
+ unsigned short i;
+ fi_type fi; /* to access the bits of a float in C quickly */
+ /* we use a union defined in glheader.h */
+
+ for(i=0; i<= 0x7f; i++) {
+ fi.i = 0;
+
+ /*
+ * Build a float with the bit pattern i as mantissa
+ * and an exponent of 0, stored as 127
+ */
+
+ fi.i = (i << 16) | (127 << 23);
+ fi.f = _mesa_sqrtd(fi.f);
+
+ /*
+ * Take the square root then strip the first 7 bits of
+ * the mantissa into the table
+ */
+
+ sqrttab[i] = (fi.i & 0x7fffff) >> 16;
+
+ /*
+ * Repeat the process, this time with an exponent of
+ * 1, stored as 128
+ */
+
+ fi.i = 0;
+ fi.i = (i << 16) | (128 << 23);
+ fi.f = sqrt(fi.f);
+ sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
+ }
+#else
+ (void) sqrttab; /* silence compiler warnings */
+#endif /*HAVE_FAST_MATH*/
+}
+
+
+/**
+ * Single precision square root.
+ */
+float
+_mesa_sqrtf( float x )
+{
+#if defined(USE_IEEE) && !defined(DEBUG)
+ fi_type num;
+ /* to access the bits of a float in C
+ * we use a union from glheader.h */
+
+ short e; /* the exponent */
+ if (x == 0.0F) return 0.0F; /* check for square root of 0 */
+ num.f = x;
+ e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */
+ /* exponent is stored with 127 added */
+ num.i &= 0x7fffff; /* leave only the mantissa */
+ if (e & 0x01) num.i |= 0x800000;
+ /* the exponent is odd so we have to */
+ /* look it up in the second half of */
+ /* the lookup table, so we set the */
+ /* high bit */
+ e >>= 1; /* divide the exponent by two */
+ /* note that in C the shift */
+ /* operators are sign preserving */
+ /* for signed operands */
+ /* Do the table lookup, based on the quaternary mantissa,
+ * then reconstruct the result back into a float
+ */
+ num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
+
+ return num.f;
+#else
+ return (float) _mesa_sqrtd((double) x);
+#endif
+}
+
+
+/**
+ inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
+ written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
+ and Vesa Karvonen.
+*/
+float
+_mesa_inv_sqrtf(float n)
+{
+#if defined(USE_IEEE) && !defined(DEBUG)
+ float r0, x0, y0;
+ float r1, x1, y1;
+ float r2, x2, y2;
+#if 0 /* not used, see below -BP */
+ float r3, x3, y3;
+#endif
+ fi_type u;
+ unsigned int magic;
+
+ /*
+ Exponent part of the magic number -
+
+ We want to:
+ 1. subtract the bias from the exponent,
+ 2. negate it
+ 3. divide by two (rounding towards -inf)
+ 4. add the bias back
+
+ Which is the same as subtracting the exponent from 381 and dividing
+ by 2.
+
+ floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
+ */
+
+ magic = 381 << 23;
+
+ /*
+ Significand part of magic number -
+
+ With the current magic number, "(magic - u.i) >> 1" will give you:
+
+ for 1 <= u.f <= 2: 1.25 - u.f / 4
+ for 2 <= u.f <= 4: 1.00 - u.f / 8
+
+ This isn't a bad approximation of 1/sqrt. The maximum difference from
+ 1/sqrt will be around .06. After three Newton-Raphson iterations, the
+ maximum difference is less than 4.5e-8. (Which is actually close
+ enough to make the following bias academic...)
+
+ To get a better approximation you can add a bias to the magic
+ number. For example, if you subtract 1/2 of the maximum difference in
+ the first approximation (.03), you will get the following function:
+
+ for 1 <= u.f <= 2: 1.22 - u.f / 4
+ for 2 <= u.f <= 3.76: 0.97 - u.f / 8
+ for 3.76 <= u.f <= 4: 0.72 - u.f / 16
+ (The 3.76 to 4 range is where the result is < .5.)
+
+ This is the closest possible initial approximation, but with a maximum
+ error of 8e-11 after three NR iterations, it is still not perfect. If
+ you subtract 0.0332281 instead of .03, the maximum error will be
+ 2.5e-11 after three NR iterations, which should be about as close as
+ is possible.
+
+ for 1 <= u.f <= 2: 1.2167719 - u.f / 4
+ for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
+ for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
+
+ */
+
+ magic -= (int)(0.0332281 * (1 << 25));
+
+ u.f = n;
+ u.i = (magic - u.i) >> 1;
+
+ /*
+ Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
+ allows more parallelism. From what I understand, the parallelism
+ comes at the cost of less precision, because it lets error
+ accumulate across iterations.
+ */
+ x0 = 1.0f;
+ y0 = 0.5f * n;
+ r0 = u.f;
+
+ x1 = x0 * r0;
+ y1 = y0 * r0 * r0;
+ r1 = 1.5f - y1;
+
+ x2 = x1 * r1;
+ y2 = y1 * r1 * r1;
+ r2 = 1.5f - y2;
+
+#if 1
+ return x2 * r2; /* we can stop here, and be conformant -BP */
+#else
+ x3 = x2 * r2;
+ y3 = y2 * r2 * r2;
+ r3 = 1.5f - y3;
+
+ return x3 * r3;
+#endif
+#else
+ return (float) (1.0 / sqrt(n));
+#endif
+}
+
+#ifndef __GNUC__
+/**
+ * Find the first bit set in a word.
+ */
+int
+_mesa_ffs(int32_t i)
+{
+#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__)
+ register int bit = 0;
+ if (i != 0) {
+ if ((i & 0xffff) == 0) {
+ bit += 16;
+ i >>= 16;
+ }
+ if ((i & 0xff) == 0) {
+ bit += 8;
+ i >>= 8;
+ }
+ if ((i & 0xf) == 0) {
+ bit += 4;
+ i >>= 4;
+ }
+ while ((i & 1) == 0) {
+ bit++;
+ i >>= 1;
+ }
+ bit++;
+ }
+ return bit;
+#else
+ return ffs(i);
+#endif
+}
+
+
+/**
+ * Find position of first bit set in given value.
+ * XXX Warning: this function can only be used on 64-bit systems!
+ * \return position of least-significant bit set, starting at 1, return zero
+ * if no bits set.
+ */
+int
+_mesa_ffsll(int64_t val)
+{
+ int bit;
+
+ assert(sizeof(val) == 8);
+
+ bit = _mesa_ffs((int32_t)val);
+ if (bit != 0)
+ return bit;
+
+ bit = _mesa_ffs((int32_t)(val >> 32));
+ if (bit != 0)
+ return 32 + bit;
+
+ return 0;
+}
+
+
+#if ((_GNUC__ == 3 && __GNUC_MINOR__ < 4) || __GNUC__ < 4)
+/**
+ * Return number of bits set in given GLuint.
+ */
+unsigned int
+_mesa_bitcount(unsigned int n)
+{
+ unsigned int bits;
+ for (bits = 0; n > 0; n = n >> 1) {
+ bits += (n & 1);
+ }
+ return bits;
+}
+#endif
+#endif
+
+
+/**
+ * Convert a 4-byte float to a 2-byte half float.
+ * Based on code from:
+ * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
+ */
+GLhalfARB
+_mesa_float_to_half(float val)
+{
+ const fi_type fi = {val};
+ const int flt_m = fi.i & 0x7fffff;
+ const int flt_e = (fi.i >> 23) & 0xff;
+ const int flt_s = (fi.i >> 31) & 0x1;
+ int s, e, m = 0;
+ GLhalfARB result;
+
+ /* sign bit */
+ s = flt_s;
+
+ /* handle special cases */
+ if ((flt_e == 0) && (flt_m == 0)) {
+ /* zero */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if ((flt_e == 0) && (flt_m != 0)) {
+ /* denorm -- denorm float maps to 0 half */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if ((flt_e == 0xff) && (flt_m == 0)) {
+ /* infinity */
+ /* m = 0; - already set */
+ e = 31;
+ }
+ else if ((flt_e == 0xff) && (flt_m != 0)) {
+ /* NaN */
+ m = 1;
+ e = 31;
+ }
+ else {
+ /* regular number */
+ const int new_exp = flt_e - 127;
+ if (new_exp < -24) {
+ /* this maps to 0 */
+ /* m = 0; - already set */
+ e = 0;
+ }
+ else if (new_exp < -14) {
+ /* this maps to a denorm */
+ unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
+ e = 0;
+ switch (exp_val) {
+ case 0:
+ _mesa_warning(NULL,
+ "float_to_half: logical error in denorm creation!\n");
+ /* m = 0; - already set */
+ break;
+ case 1: m = 512 + (flt_m >> 14); break;
+ case 2: m = 256 + (flt_m >> 15); break;
+ case 3: m = 128 + (flt_m >> 16); break;
+ case 4: m = 64 + (flt_m >> 17); break;
+ case 5: m = 32 + (flt_m >> 18); break;
+ case 6: m = 16 + (flt_m >> 19); break;
+ case 7: m = 8 + (flt_m >> 20); break;
+ case 8: m = 4 + (flt_m >> 21); break;
+ case 9: m = 2 + (flt_m >> 22); break;
+ case 10: m = 1; break;
+ }
+ }
+ else if (new_exp > 15) {
+ /* map this value to infinity */
+ /* m = 0; - already set */
+ e = 31;
+ }
+ else {
+ /* regular */
+ e = new_exp + 15;
+ m = flt_m >> 13;
+ }
+ }
+
+ result = (s << 15) | (e << 10) | m;
+ return result;
+}
+
+
+/**
+ * Convert a 2-byte half float to a 4-byte float.
+ * Based on code from:
+ * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
+ */
+float
+_mesa_half_to_float(GLhalfARB val)
+{
+ /* XXX could also use a 64K-entry lookup table */
+ const int m = val & 0x3ff;
+ const int e = (val >> 10) & 0x1f;
+ const int s = (val >> 15) & 0x1;
+ int flt_m, flt_e, flt_s;
+ fi_type fi;
+ float result;
+
+ /* sign bit */
+ flt_s = s;
+
+ /* handle special cases */
+ if ((e == 0) && (m == 0)) {
+ /* zero */
+ flt_m = 0;
+ flt_e = 0;
+ }
+ else if ((e == 0) && (m != 0)) {
+ /* denorm -- denorm half will fit in non-denorm single */
+ const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
+ float mantissa = ((float) (m)) / 1024.0f;
+ float sign = s ? -1.0f : 1.0f;
+ return sign * mantissa * half_denorm;
+ }
+ else if ((e == 31) && (m == 0)) {
+ /* infinity */
+ flt_e = 0xff;
+ flt_m = 0;
+ }
+ else if ((e == 31) && (m != 0)) {
+ /* NaN */
+ flt_e = 0xff;
+ flt_m = 1;
+ }
+ else {
+ /* regular */
+ flt_e = e + 112;
+ flt_m = m << 13;
+ }
+
+ fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
+ result = fi.f;
+ return result;
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Sort & Search */
+/*@{*/
+
+/**
+ * Wrapper for bsearch().
+ */
+void *
+_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *) )
+{
+#if defined(_WIN32_WCE)
+ void *mid;
+ int cmp;
+ while (nmemb) {
+ nmemb >>= 1;
+ mid = (char *)base + nmemb * size;
+ cmp = (*compar)(key, mid);
+ if (cmp == 0)
+ return mid;
+ if (cmp > 0) {
+ base = (char *)mid + size;
+ --nmemb;
+ }
+ }
+ return NULL;
+#else
+ return bsearch(key, base, nmemb, size, compar);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Environment vars */
+/*@{*/
+
+/**
+ * Wrapper for getenv().
+ */
+char *
+_mesa_getenv( const char *var )
+{
+#if defined(_XBOX) || defined(_WIN32_WCE)
+ return NULL;
+#else
+ return getenv(var);
+#endif
+}
+
+/*@}*/
+
+
+/**********************************************************************/
+/** \name String */
+/*@{*/
+
+/**
+ * Implemented using malloc() and strcpy.
+ * Note that NULL is handled accordingly.
+ */
+char *
+_mesa_strdup( const char *s )
+{
+ if (s) {
+ size_t l = strlen(s);
+ char *s2 = (char *) malloc(l + 1);
+ if (s2)
+ strcpy(s2, s);
+ return s2;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/** Wrapper around strtof() */
+float
+_mesa_strtof( const char *s, char **end )
+{
+#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__)
+ static locale_t loc = NULL;
+ if (!loc) {
+ loc = newlocale(LC_CTYPE_MASK, "C", NULL);
+ }
+ return strtof_l(s, end, loc);
+#elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
+ return strtof(s, end);
+#else
+ return (float)strtod(s, end);
+#endif
+}
+
+/** Compute simple checksum/hash for a string */
+unsigned int
+_mesa_str_checksum(const char *str)
+{
+ /* This could probably be much better */
+ unsigned int sum, i;
+ const char *c;
+ sum = i = 1;
+ for (c = str; *c; c++, i++)
+ sum += *c * (i % 100);
+ return sum + i;
+}
+
+
+/*@}*/
+
+
+/** Wrapper around vsnprintf() */
+int
+_mesa_snprintf( char *str, size_t size, const char *fmt, ... )
+{
+ int r;
+ va_list args;
+ va_start( args, fmt );
+ r = vsnprintf( str, size, fmt, args );
+ va_end( args );
+ return r;
+}
+
+
+/**********************************************************************/
+/** \name Diagnostics */
+/*@{*/
+
+static void
+output_if_debug(const char *prefixString, const char *outputString,
+ GLboolean newline)
+{
+ static int debug = -1;
+
+ /* Check the MESA_DEBUG environment variable if it hasn't
+ * been checked yet. We only have to check it once...
+ */
+ if (debug == -1) {
+ char *env = _mesa_getenv("MESA_DEBUG");
+
+ /* In a debug build, we print warning messages *unless*
+ * MESA_DEBUG is 0. In a non-debug build, we don't
+ * print warning messages *unless* MESA_DEBUG is
+ * set *to any value*.
+ */
+#ifdef DEBUG
+ debug = (env != NULL && atoi(env) == 0) ? 0 : 1;
+#else
+ debug = (env != NULL) ? 1 : 0;
+#endif
+ }
+
+ /* Now only print the string if we're required to do so. */
+ if (debug) {
+ fprintf(stderr, "%s: %s", prefixString, outputString);
+ if (newline)
+ fprintf(stderr, "\n");
+
+#if defined(_WIN32) && !defined(_WIN32_WCE)
+ /* stderr from windows applications without console is not usually
+ * visible, so communicate with the debugger instead */
+ {
+ char buf[4096];
+ _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
+ OutputDebugStringA(buf);
+ }
+#endif
+ }
+}
+
+
+/**
+ * Return string version of GL error code.
+ */
+static const char *
+error_string( GLenum error )
+{
+ switch (error) {
+ case GL_NO_ERROR:
+ return "GL_NO_ERROR";
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ case GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+ case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+ default:
+ return "unknown";
+ }
+}
+
+
+/**
+ * When a new type of error is recorded, print a message describing
+ * previous errors which were accumulated.
+ */
+static void
+flush_delayed_errors( struct gl_context *ctx )
+{
+ char s[MAXSTRING];
+
+ if (ctx->ErrorDebugCount) {
+ _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
+ ctx->ErrorDebugCount,
+ error_string(ctx->ErrorValue));
+
+ output_if_debug("Mesa", s, GL_TRUE);
+
+ ctx->ErrorDebugCount = 0;
+ }
+}
+
+
+/**
+ * Report a warning (a recoverable error condition) to stderr if
+ * either DEBUG is defined or the MESA_DEBUG env var is set.
+ *
+ * \param ctx GL context.
+ * \param fmtString printf()-like format string.
+ */
+void
+_mesa_warning( struct gl_context *ctx, const char *fmtString, ... )
+{
+ char str[MAXSTRING];
+ va_list args;
+ va_start( args, fmtString );
+ (void) vsnprintf( str, MAXSTRING, fmtString, args );
+ va_end( args );
+
+ if (ctx)
+ flush_delayed_errors( ctx );
+
+ output_if_debug("Mesa warning", str, GL_TRUE);
+}
+
+
+/**
+ * Report an internal implementation problem.
+ * Prints the message to stderr via fprintf().
+ *
+ * \param ctx GL context.
+ * \param fmtString problem description string.
+ */
+void
+_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
+{
+ va_list args;
+ char str[MAXSTRING];
+ (void) ctx;
+
+ va_start( args, fmtString );
+ vsnprintf( str, MAXSTRING, fmtString, args );
+ va_end( args );
+
+ fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
+ fprintf(stderr, "Please report at bugs.freedesktop.org\n");
+}
+
+
+/**
+ * Record an OpenGL state error. These usually occur when the user
+ * passes invalid parameters to a GL function.
+ *
+ * If debugging is enabled (either at compile-time via the DEBUG macro, or
+ * run-time via the MESA_DEBUG environment variable), report the error with
+ * _mesa_debug().
+ *
+ * \param ctx the GL context.
+ * \param error the error value.
+ * \param fmtString printf() style format string, followed by optional args
+ */
+void
+_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
+{
+ static GLint debug = -1;
+
+ /* Check debug environment variable only once:
+ */
+ if (debug == -1) {
+ const char *debugEnv = _mesa_getenv("MESA_DEBUG");
+
+#ifdef DEBUG
+ if (debugEnv && strstr(debugEnv, "silent"))
+ debug = GL_FALSE;
+ else
+ debug = GL_TRUE;
+#else
+ if (debugEnv)
+ debug = GL_TRUE;
+ else
+ debug = GL_FALSE;
+#endif
+ }
+
+ if (debug) {
+ if (ctx->ErrorValue == error &&
+ ctx->ErrorDebugFmtString == fmtString) {
+ ctx->ErrorDebugCount++;
+ }
+ else {
+ char s[MAXSTRING], s2[MAXSTRING];
+ va_list args;
+
+ flush_delayed_errors( ctx );
+
+ va_start(args, fmtString);
+ vsnprintf(s, MAXSTRING, fmtString, args);
+ va_end(args);
+
+ _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s);
+ output_if_debug("Mesa: User error", s2, GL_TRUE);
+
+ ctx->ErrorDebugFmtString = fmtString;
+ ctx->ErrorDebugCount = 0;
+ }
+ }
+
+ _mesa_record_error(ctx, error);
+}
+
+
+/**
+ * Report debug information. Print error message to stderr via fprintf().
+ * No-op if DEBUG mode not enabled.
+ *
+ * \param ctx GL context.
+ * \param fmtString printf()-style format string, followed by optional args.
+ */
+void
+_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
+{
+#ifdef DEBUG
+ char s[MAXSTRING];
+ va_list args;
+ va_start(args, fmtString);
+ vsnprintf(s, MAXSTRING, fmtString, args);
+ va_end(args);
+ output_if_debug("Mesa", s, GL_FALSE);
+#endif /* DEBUG */
+ (void) ctx;
+ (void) fmtString;
+}
+
+/*@}*/
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index af7a8cc00..a994dbcae 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -1,602 +1,615 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.5
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * \file imports.h
- * Standard C library function wrappers.
- *
- * This file provides wrappers for all the standard C library functions
- * like malloc(), free(), printf(), getenv(), etc.
- */
-
-
-#ifndef IMPORTS_H
-#define IMPORTS_H
-
-
-#include "compiler.h"
-#include "glheader.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/**********************************************************************/
-/** Memory macros */
-/*@{*/
-
-/** Allocate \p BYTES bytes */
-#define MALLOC(BYTES) malloc(BYTES)
-/** Allocate and zero \p BYTES bytes */
-#define CALLOC(BYTES) calloc(1, BYTES)
-/** Allocate a structure of type \p T */
-#define MALLOC_STRUCT(T) (struct T *) malloc(sizeof(struct T))
-/** Allocate and zero a structure of type \p T */
-#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
-/** Free memory */
-#define FREE(PTR) free(PTR)
-
-/*@}*/
-
-
-/*
- * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers
- * as offsets into buffer stores. Since the vertex array pointer and
- * buffer store pointer are both pointers and we need to add them, we use
- * this macro.
- * Both pointers/offsets are expressed in bytes.
- */
-#define ADD_POINTERS(A, B) ( (GLubyte *) (A) + (uintptr_t) (B) )
-
-
-/**
- * Sometimes we treat GLfloats as GLints. On x86 systems, moving a float
- * as a int (thereby using integer registers instead of FP registers) is
- * a performance win. Typically, this can be done with ordinary casts.
- * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0)
- * these casts generate warnings.
- * The following union typedef is used to solve that.
- */
-typedef union { GLfloat f; GLint i; } fi_type;
-
-
-
-/**********************************************************************
- * Math macros
- */
-
-#define MAX_GLUSHORT 0xffff
-#define MAX_GLUINT 0xffffffff
-
-/* Degrees to radians conversion: */
-#define DEG2RAD (M_PI/180.0)
-
-
-/***
- *** SQRTF: single-precision square root
- ***/
-#if 0 /* _mesa_sqrtf() not accurate enough - temporarily disabled */
-# define SQRTF(X) _mesa_sqrtf(X)
-#else
-# define SQRTF(X) (float) sqrt((float) (X))
-#endif
-
-
-/***
- *** INV_SQRTF: single-precision inverse square root
- ***/
-#if 0
-#define INV_SQRTF(X) _mesa_inv_sqrt(X)
-#else
-#define INV_SQRTF(X) (1.0F / SQRTF(X)) /* this is faster on a P4 */
-#endif
-
-
-/**
- * \name Work-arounds for platforms that lack C99 math functions
- */
-/*@{*/
-#if (!defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 600)) && !defined(_ISOC99_SOURCE) \
- && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)) \
- && (!defined(_MSC_VER) || (_MSC_VER < 1400))
-#define acosf(f) ((float) acos(f))
-#define asinf(f) ((float) asin(f))
-#define atan2f(x,y) ((float) atan2(x,y))
-#define atanf(f) ((float) atan(f))
-#define cielf(f) ((float) ciel(f))
-#define cosf(f) ((float) cos(f))
-#define coshf(f) ((float) cosh(f))
-#define expf(f) ((float) exp(f))
-#define exp2f(f) ((float) exp2(f))
-#define floorf(f) ((float) floor(f))
-#define logf(f) ((float) log(f))
-#define log2f(f) ((float) log2(f))
-#define powf(x,y) ((float) pow(x,y))
-#define sinf(f) ((float) sin(f))
-#define sinhf(f) ((float) sinh(f))
-#define sqrtf(f) ((float) sqrt(f))
-#define tanf(f) ((float) tan(f))
-#define tanhf(f) ((float) tanh(f))
-#define acoshf(f) ((float) acosh(f))
-#define asinhf(f) ((float) asinh(f))
-#define atanhf(f) ((float) atanh(f))
-#endif
-
-#if defined(_MSC_VER)
-static INLINE float truncf(float x) { return x < 0.0f ? ceilf(x) : floorf(x); }
-static INLINE float exp2f(float x) { return powf(2.0f, x); }
-static INLINE float log2f(float x) { return logf(x) * 1.442695041f; }
-static INLINE float asinhf(float x) { return logf(x + sqrtf(x * x + 1.0f)); }
-static INLINE float acoshf(float x) { return logf(x + sqrtf(x * x - 1.0f)); }
-static INLINE float atanhf(float x) { return (logf(1.0f + x) - logf(1.0f - x)) / 2.0f; }
-static INLINE int isblank(int ch) { return ch == ' ' || ch == '\t'; }
-#define strtoll(p, e, b) _strtoi64(p, e, b)
-#endif
-/*@}*/
-
-/***
- *** LOG2: Log base 2 of float
- ***/
-#ifdef USE_IEEE
-#if 0
-/* This is pretty fast, but not accurate enough (only 2 fractional bits).
- * Based on code from http://www.stereopsis.com/log2.html
- */
-static INLINE GLfloat LOG2(GLfloat x)
-{
- const GLfloat y = x * x * x * x;
- const GLuint ix = *((GLuint *) &y);
- const GLuint exp = (ix >> 23) & 0xFF;
- const GLint log2 = ((GLint) exp) - 127;
- return (GLfloat) log2 * (1.0 / 4.0); /* 4, because of x^4 above */
-}
-#endif
-/* Pretty fast, and accurate.
- * Based on code from http://www.flipcode.com/totd/
- */
-static INLINE GLfloat LOG2(GLfloat val)
-{
- fi_type num;
- GLint log_2;
- num.f = val;
- log_2 = ((num.i >> 23) & 255) - 128;
- num.i &= ~(255 << 23);
- num.i += 127 << 23;
- num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3;
- return num.f + log_2;
-}
-#else
-/*
- * NOTE: log_base_2(x) = log(x) / log(2)
- * NOTE: 1.442695 = 1/log(2).
- */
-#define LOG2(x) ((GLfloat) (log(x) * 1.442695F))
-#endif
-
-
-/***
- *** IS_INF_OR_NAN: test if float is infinite or NaN
- ***/
-#ifdef USE_IEEE
-static INLINE int IS_INF_OR_NAN( float x )
-{
- fi_type tmp;
- tmp.f = x;
- return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31);
-}
-#elif defined(isfinite)
-#define IS_INF_OR_NAN(x) (!isfinite(x))
-#elif defined(finite)
-#define IS_INF_OR_NAN(x) (!finite(x))
-#elif defined(__VMS)
-#define IS_INF_OR_NAN(x) (!finite(x))
-#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#define IS_INF_OR_NAN(x) (!isfinite(x))
-#else
-#define IS_INF_OR_NAN(x) (!finite(x))
-#endif
-
-
-/***
- *** IS_NEGATIVE: test if float is negative
- ***/
-#if defined(USE_IEEE)
-static INLINE int GET_FLOAT_BITS( float x )
-{
- fi_type fi;
- fi.f = x;
- return fi.i;
-}
-#define IS_NEGATIVE(x) (GET_FLOAT_BITS(x) < 0)
-#else
-#define IS_NEGATIVE(x) (x < 0.0F)
-#endif
-
-
-/***
- *** DIFFERENT_SIGNS: test if two floats have opposite signs
- ***/
-#if defined(USE_IEEE)
-#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31))
-#else
-/* Could just use (x*y<0) except for the flatshading requirements.
- * Maybe there's a better way?
- */
-#define DIFFERENT_SIGNS(x,y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
-#endif
-
-
-/***
- *** CEILF: ceiling of float
- *** FLOORF: floor of float
- *** FABSF: absolute value of float
- *** LOGF: the natural logarithm (base e) of the value
- *** EXPF: raise e to the value
- *** LDEXPF: multiply value by an integral power of two
- *** FREXPF: extract mantissa and exponent from value
- ***/
-#if defined(__gnu_linux__)
-/* C99 functions */
-#define CEILF(x) ceilf(x)
-#define FLOORF(x) floorf(x)
-#define FABSF(x) fabsf(x)
-#define LOGF(x) logf(x)
-#define EXPF(x) expf(x)
-#define LDEXPF(x,y) ldexpf(x,y)
-#define FREXPF(x,y) frexpf(x,y)
-#else
-#define CEILF(x) ((GLfloat) ceil(x))
-#define FLOORF(x) ((GLfloat) floor(x))
-#define FABSF(x) ((GLfloat) fabs(x))
-#define LOGF(x) ((GLfloat) log(x))
-#define EXPF(x) ((GLfloat) exp(x))
-#define LDEXPF(x,y) ((GLfloat) ldexp(x,y))
-#define FREXPF(x,y) ((GLfloat) frexp(x,y))
-#endif
-
-
-/***
- *** IROUND: return (as an integer) float rounded to nearest integer
- ***/
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
-static INLINE int iround(float f)
-{
- int r;
- __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
- return r;
-}
-#define IROUND(x) iround(x)
-#elif defined(USE_X86_ASM) && defined(_MSC_VER)
-static INLINE int iround(float f)
-{
- int r;
- _asm {
- fld f
- fistp r
- }
- return r;
-}
-#define IROUND(x) iround(x)
-#elif defined(__WATCOMC__) && defined(__386__)
-long iround(float f);
-#pragma aux iround = \
- "push eax" \
- "fistp dword ptr [esp]" \
- "pop eax" \
- parm [8087] \
- value [eax] \
- modify exact [eax];
-#define IROUND(x) iround(x)
-#else
-#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
-#endif
-
-#define IROUND64(f) ((GLint64) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
-
-/***
- *** IROUND_POS: return (as an integer) positive float rounded to nearest int
- ***/
-#ifdef DEBUG
-#define IROUND_POS(f) (assert((f) >= 0.0F), IROUND(f))
-#else
-#define IROUND_POS(f) (IROUND(f))
-#endif
-
-
-/***
- *** IFLOOR: return (as an integer) floor of float
- ***/
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
-/*
- * IEEE floor for computers that round to nearest or even.
- * 'f' must be between -4194304 and 4194303.
- * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
- * but uses some IEEE specific tricks for better speed.
- * Contributed by Josh Vanderhoof
- */
-static INLINE int ifloor(float f)
-{
- int ai, bi;
- double af, bf;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
- /* GCC generates an extra fstp/fld without this. */
- __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
- __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
- return (ai - bi) >> 1;
-}
-#define IFLOOR(x) ifloor(x)
-#elif defined(USE_IEEE)
-static INLINE int ifloor(float f)
-{
- int ai, bi;
- double af, bf;
- fi_type u;
-
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
- u.f = (float) af; ai = u.i;
- u.f = (float) bf; bi = u.i;
- return (ai - bi) >> 1;
-}
-#define IFLOOR(x) ifloor(x)
-#else
-static INLINE int ifloor(float f)
-{
- int i = IROUND(f);
- return (i > f) ? i - 1 : i;
-}
-#define IFLOOR(x) ifloor(x)
-#endif
-
-
-/***
- *** ICEIL: return (as an integer) ceiling of float
- ***/
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
-/*
- * IEEE ceil for computers that round to nearest or even.
- * 'f' must be between -4194304 and 4194303.
- * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
- * but uses some IEEE specific tricks for better speed.
- * Contributed by Josh Vanderhoof
- */
-static INLINE int iceil(float f)
-{
- int ai, bi;
- double af, bf;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
- /* GCC generates an extra fstp/fld without this. */
- __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
- __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
- return (ai - bi + 1) >> 1;
-}
-#define ICEIL(x) iceil(x)
-#elif defined(USE_IEEE)
-static INLINE int iceil(float f)
-{
- int ai, bi;
- double af, bf;
- fi_type u;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
- u.f = (float) af; ai = u.i;
- u.f = (float) bf; bi = u.i;
- return (ai - bi + 1) >> 1;
-}
-#define ICEIL(x) iceil(x)
-#else
-static INLINE int iceil(float f)
-{
- int i = IROUND(f);
- return (i < f) ? i + 1 : i;
-}
-#define ICEIL(x) iceil(x)
-#endif
-
-
-/**
- * Is x a power of two?
- */
-static INLINE int
-_mesa_is_pow_two(int x)
-{
- return !(x & (x - 1));
-}
-
-/**
- * Round given integer to next higer power of two
- * If X is zero result is undefined.
- *
- * Source for the fallback implementation is
- * Sean Eron Anderson's webpage "Bit Twiddling Hacks"
- * http://graphics.stanford.edu/~seander/bithacks.html
- *
- * When using builtin function have to do some work
- * for case when passed values 1 to prevent hiting
- * undefined result from __builtin_clz. Undefined
- * results would be different depending on optimization
- * level used for build.
- */
-static INLINE int32_t
-_mesa_next_pow_two_32(uint32_t x)
-{
-#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
- uint32_t y = (x != 1);
- return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
-#else
- x--;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- x++;
- return x;
-#endif
-}
-
-static INLINE int64_t
-_mesa_next_pow_two_64(uint64_t x)
-{
-#if defined(__GNUC__) && \
- ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
- uint64_t y = (x != 1);
- if (sizeof(x) == sizeof(long))
- return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
- else
- return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
-#else
- x--;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- x |= x >> 32;
- x++;
- return x;
-#endif
-}
-
-
-/**
- * Return 1 if this is a little endian machine, 0 if big endian.
- */
-static INLINE GLboolean
-_mesa_little_endian(void)
-{
- const GLuint ui = 1; /* intentionally not static */
- return *((const GLubyte *) &ui);
-}
-
-
-
-/**********************************************************************
- * Functions
- */
-
-extern void *
-_mesa_align_malloc( size_t bytes, unsigned long alignment );
-
-extern void *
-_mesa_align_calloc( size_t bytes, unsigned long alignment );
-
-extern void
-_mesa_align_free( void *ptr );
-
-extern void *
-_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
- unsigned long alignment);
-
-extern void *
-_mesa_exec_malloc( GLuint size );
-
-extern void
-_mesa_exec_free( void *addr );
-
-extern void *
-_mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize );
-
-extern void
-_mesa_memset16( unsigned short *dst, unsigned short val, size_t n );
-
-extern double
-_mesa_sqrtd(double x);
-
-extern float
-_mesa_sqrtf(float x);
-
-extern float
-_mesa_inv_sqrtf(float x);
-
-extern void
-_mesa_init_sqrt_table(void);
-
-extern int
-_mesa_ffs(int32_t i);
-
-extern int
-_mesa_ffsll(int64_t i);
-
-extern unsigned int
-_mesa_bitcount(unsigned int n);
-
-extern GLhalfARB
-_mesa_float_to_half(float f);
-
-extern float
-_mesa_half_to_float(GLhalfARB h);
-
-
-extern void *
-_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
- int (*compar)(const void *, const void *) );
-
-extern char *
-_mesa_getenv( const char *var );
-
-extern char *
-_mesa_strdup( const char *s );
-
-extern float
-_mesa_strtof( const char *s, char **end );
-
-extern unsigned int
-_mesa_str_checksum(const char *str);
-
-extern int
-_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) PRINTFLIKE(3, 4);
-
-struct gl_context;
-
-extern void
-_mesa_warning( struct gl_context *gc, const char *fmtString, ... ) PRINTFLIKE(2, 3);
-
-extern void
-_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
-
-extern void
-_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) PRINTFLIKE(3, 4);
-
-extern void
-_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
-
-
-#if defined(_MSC_VER) && !defined(snprintf)
-#define snprintf _snprintf
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* IMPORTS_H */
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.5
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file imports.h
+ * Standard C library function wrappers.
+ *
+ * This file provides wrappers for all the standard C library functions
+ * like malloc(), free(), printf(), getenv(), etc.
+ */
+
+
+#ifndef IMPORTS_H
+#define IMPORTS_H
+
+
+#include "compiler.h"
+#include "glheader.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**********************************************************************/
+/** Memory macros */
+/*@{*/
+
+/** Allocate \p BYTES bytes */
+#define MALLOC(BYTES) malloc(BYTES)
+/** Allocate and zero \p BYTES bytes */
+#define CALLOC(BYTES) calloc(1, BYTES)
+/** Allocate a structure of type \p T */
+#define MALLOC_STRUCT(T) (struct T *) malloc(sizeof(struct T))
+/** Allocate and zero a structure of type \p T */
+#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
+/** Free memory */
+#define FREE(PTR) free(PTR)
+
+/*@}*/
+
+
+/*
+ * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers
+ * as offsets into buffer stores. Since the vertex array pointer and
+ * buffer store pointer are both pointers and we need to add them, we use
+ * this macro.
+ * Both pointers/offsets are expressed in bytes.
+ */
+#define ADD_POINTERS(A, B) ( (GLubyte *) (A) + (uintptr_t) (B) )
+
+
+/**
+ * Sometimes we treat GLfloats as GLints. On x86 systems, moving a float
+ * as a int (thereby using integer registers instead of FP registers) is
+ * a performance win. Typically, this can be done with ordinary casts.
+ * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0)
+ * these casts generate warnings.
+ * The following union typedef is used to solve that.
+ */
+typedef union { GLfloat f; GLint i; } fi_type;
+
+
+
+/**********************************************************************
+ * Math macros
+ */
+
+#define MAX_GLUSHORT 0xffff
+#define MAX_GLUINT 0xffffffff
+
+/* Degrees to radians conversion: */
+#define DEG2RAD (M_PI/180.0)
+
+
+/***
+ *** SQRTF: single-precision square root
+ ***/
+#if 0 /* _mesa_sqrtf() not accurate enough - temporarily disabled */
+# define SQRTF(X) _mesa_sqrtf(X)
+#else
+# define SQRTF(X) (float) sqrt((float) (X))
+#endif
+
+
+/***
+ *** INV_SQRTF: single-precision inverse square root
+ ***/
+#if 0
+#define INV_SQRTF(X) _mesa_inv_sqrt(X)
+#else
+#define INV_SQRTF(X) (1.0F / SQRTF(X)) /* this is faster on a P4 */
+#endif
+
+
+/**
+ * \name Work-arounds for platforms that lack C99 math functions
+ */
+/*@{*/
+#if (!defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 600)) && !defined(_ISOC99_SOURCE) \
+ && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)) \
+ && (!defined(_MSC_VER) || (_MSC_VER < 1400))
+#define acosf(f) ((float) acos(f))
+#define asinf(f) ((float) asin(f))
+#define atan2f(x,y) ((float) atan2(x,y))
+#define atanf(f) ((float) atan(f))
+#define cielf(f) ((float) ciel(f))
+#define cosf(f) ((float) cos(f))
+#define coshf(f) ((float) cosh(f))
+#define expf(f) ((float) exp(f))
+#define exp2f(f) ((float) exp2(f))
+#define floorf(f) ((float) floor(f))
+#define logf(f) ((float) log(f))
+#define log2f(f) ((float) log2(f))
+#define powf(x,y) ((float) pow(x,y))
+#define sinf(f) ((float) sin(f))
+#define sinhf(f) ((float) sinh(f))
+#define sqrtf(f) ((float) sqrt(f))
+#define tanf(f) ((float) tan(f))
+#define tanhf(f) ((float) tanh(f))
+#define acoshf(f) ((float) acosh(f))
+#define asinhf(f) ((float) asinh(f))
+#define atanhf(f) ((float) atanh(f))
+#endif
+
+#if defined(_MSC_VER)
+static INLINE float truncf(float x) { return x < 0.0f ? ceilf(x) : floorf(x); }
+static INLINE float exp2f(float x) { return powf(2.0f, x); }
+static INLINE float log2f(float x) { return logf(x) * 1.442695041f; }
+static INLINE float asinhf(float x) { return logf(x + sqrtf(x * x + 1.0f)); }
+static INLINE float acoshf(float x) { return logf(x + sqrtf(x * x - 1.0f)); }
+static INLINE float atanhf(float x) { return (logf(1.0f + x) - logf(1.0f - x)) / 2.0f; }
+static INLINE int isblank(int ch) { return ch == ' ' || ch == '\t'; }
+#define strtoll(p, e, b) _strtoi64(p, e, b)
+#endif
+/*@}*/
+
+/***
+ *** LOG2: Log base 2 of float
+ ***/
+#ifdef USE_IEEE
+#if 0
+/* This is pretty fast, but not accurate enough (only 2 fractional bits).
+ * Based on code from http://www.stereopsis.com/log2.html
+ */
+static INLINE GLfloat LOG2(GLfloat x)
+{
+ const GLfloat y = x * x * x * x;
+ const GLuint ix = *((GLuint *) &y);
+ const GLuint exp = (ix >> 23) & 0xFF;
+ const GLint log2 = ((GLint) exp) - 127;
+ return (GLfloat) log2 * (1.0 / 4.0); /* 4, because of x^4 above */
+}
+#endif
+/* Pretty fast, and accurate.
+ * Based on code from http://www.flipcode.com/totd/
+ */
+static INLINE GLfloat LOG2(GLfloat val)
+{
+ fi_type num;
+ GLint log_2;
+ num.f = val;
+ log_2 = ((num.i >> 23) & 255) - 128;
+ num.i &= ~(255 << 23);
+ num.i += 127 << 23;
+ num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3;
+ return num.f + log_2;
+}
+#else
+/*
+ * NOTE: log_base_2(x) = log(x) / log(2)
+ * NOTE: 1.442695 = 1/log(2).
+ */
+#define LOG2(x) ((GLfloat) (log(x) * 1.442695F))
+#endif
+
+
+/***
+ *** IS_INF_OR_NAN: test if float is infinite or NaN
+ ***/
+#ifdef USE_IEEE
+static INLINE int IS_INF_OR_NAN( float x )
+{
+ fi_type tmp;
+ tmp.f = x;
+ return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31);
+}
+#elif defined(isfinite)
+#define IS_INF_OR_NAN(x) (!isfinite(x))
+#elif defined(finite)
+#define IS_INF_OR_NAN(x) (!finite(x))
+#elif defined(__VMS)
+#define IS_INF_OR_NAN(x) (!finite(x))
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define IS_INF_OR_NAN(x) (!isfinite(x))
+#else
+#define IS_INF_OR_NAN(x) (!finite(x))
+#endif
+
+
+/***
+ *** IS_NEGATIVE: test if float is negative
+ ***/
+#if defined(USE_IEEE)
+static INLINE int GET_FLOAT_BITS( float x )
+{
+ fi_type fi;
+ fi.f = x;
+ return fi.i;
+}
+#define IS_NEGATIVE(x) (GET_FLOAT_BITS(x) < 0)
+#else
+#define IS_NEGATIVE(x) (x < 0.0F)
+#endif
+
+
+/***
+ *** DIFFERENT_SIGNS: test if two floats have opposite signs
+ ***/
+#if defined(USE_IEEE)
+#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31))
+#else
+/* Could just use (x*y<0) except for the flatshading requirements.
+ * Maybe there's a better way?
+ */
+#define DIFFERENT_SIGNS(x,y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
+#endif
+
+
+/***
+ *** CEILF: ceiling of float
+ *** FLOORF: floor of float
+ *** FABSF: absolute value of float
+ *** LOGF: the natural logarithm (base e) of the value
+ *** EXPF: raise e to the value
+ *** LDEXPF: multiply value by an integral power of two
+ *** FREXPF: extract mantissa and exponent from value
+ ***/
+#if defined(__gnu_linux__)
+/* C99 functions */
+#define CEILF(x) ceilf(x)
+#define FLOORF(x) floorf(x)
+#define FABSF(x) fabsf(x)
+#define LOGF(x) logf(x)
+#define EXPF(x) expf(x)
+#define LDEXPF(x,y) ldexpf(x,y)
+#define FREXPF(x,y) frexpf(x,y)
+#else
+#define CEILF(x) ((GLfloat) ceil(x))
+#define FLOORF(x) ((GLfloat) floor(x))
+#define FABSF(x) ((GLfloat) fabs(x))
+#define LOGF(x) ((GLfloat) log(x))
+#define EXPF(x) ((GLfloat) exp(x))
+#define LDEXPF(x,y) ((GLfloat) ldexp(x,y))
+#define FREXPF(x,y) ((GLfloat) frexp(x,y))
+#endif
+
+
+/***
+ *** IROUND: return (as an integer) float rounded to nearest integer
+ ***/
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+static INLINE int iround(float f)
+{
+ int r;
+ __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
+ return r;
+}
+#define IROUND(x) iround(x)
+#elif defined(USE_X86_ASM) && defined(_MSC_VER)
+static INLINE int iround(float f)
+{
+ int r;
+ _asm {
+ fld f
+ fistp r
+ }
+ return r;
+}
+#define IROUND(x) iround(x)
+#elif defined(__WATCOMC__) && defined(__386__)
+long iround(float f);
+#pragma aux iround = \
+ "push eax" \
+ "fistp dword ptr [esp]" \
+ "pop eax" \
+ parm [8087] \
+ value [eax] \
+ modify exact [eax];
+#define IROUND(x) iround(x)
+#else
+#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
+#endif
+
+#define IROUND64(f) ((GLint64) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
+
+/***
+ *** IROUND_POS: return (as an integer) positive float rounded to nearest int
+ ***/
+#ifdef DEBUG
+#define IROUND_POS(f) (assert((f) >= 0.0F), IROUND(f))
+#else
+#define IROUND_POS(f) (IROUND(f))
+#endif
+
+
+/***
+ *** IFLOOR: return (as an integer) floor of float
+ ***/
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+/*
+ * IEEE floor for computers that round to nearest or even.
+ * 'f' must be between -4194304 and 4194303.
+ * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
+ * but uses some IEEE specific tricks for better speed.
+ * Contributed by Josh Vanderhoof
+ */
+static INLINE int ifloor(float f)
+{
+ int ai, bi;
+ double af, bf;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ /* GCC generates an extra fstp/fld without this. */
+ __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+ return (ai - bi) >> 1;
+}
+#define IFLOOR(x) ifloor(x)
+#elif defined(USE_IEEE)
+static INLINE int ifloor(float f)
+{
+ int ai, bi;
+ double af, bf;
+ fi_type u;
+
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ u.f = (float) af; ai = u.i;
+ u.f = (float) bf; bi = u.i;
+ return (ai - bi) >> 1;
+}
+#define IFLOOR(x) ifloor(x)
+#else
+static INLINE int ifloor(float f)
+{
+ int i = IROUND(f);
+ return (i > f) ? i - 1 : i;
+}
+#define IFLOOR(x) ifloor(x)
+#endif
+
+
+/***
+ *** ICEIL: return (as an integer) ceiling of float
+ ***/
+#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
+/*
+ * IEEE ceil for computers that round to nearest or even.
+ * 'f' must be between -4194304 and 4194303.
+ * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
+ * but uses some IEEE specific tricks for better speed.
+ * Contributed by Josh Vanderhoof
+ */
+static INLINE int iceil(float f)
+{
+ int ai, bi;
+ double af, bf;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ /* GCC generates an extra fstp/fld without this. */
+ __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+ return (ai - bi + 1) >> 1;
+}
+#define ICEIL(x) iceil(x)
+#elif defined(USE_IEEE)
+static INLINE int iceil(float f)
+{
+ int ai, bi;
+ double af, bf;
+ fi_type u;
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+ u.f = (float) af; ai = u.i;
+ u.f = (float) bf; bi = u.i;
+ return (ai - bi + 1) >> 1;
+}
+#define ICEIL(x) iceil(x)
+#else
+static INLINE int iceil(float f)
+{
+ int i = IROUND(f);
+ return (i < f) ? i + 1 : i;
+}
+#define ICEIL(x) iceil(x)
+#endif
+
+
+/**
+ * Is x a power of two?
+ */
+static INLINE int
+_mesa_is_pow_two(int x)
+{
+ return !(x & (x - 1));
+}
+
+/**
+ * Round given integer to next higer power of two
+ * If X is zero result is undefined.
+ *
+ * Source for the fallback implementation is
+ * Sean Eron Anderson's webpage "Bit Twiddling Hacks"
+ * http://graphics.stanford.edu/~seander/bithacks.html
+ *
+ * When using builtin function have to do some work
+ * for case when passed values 1 to prevent hiting
+ * undefined result from __builtin_clz. Undefined
+ * results would be different depending on optimization
+ * level used for build.
+ */
+static INLINE int32_t
+_mesa_next_pow_two_32(uint32_t x)
+{
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ uint32_t y = (x != 1);
+ return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
+#else
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x++;
+ return x;
+#endif
+}
+
+static INLINE int64_t
+_mesa_next_pow_two_64(uint64_t x)
+{
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+ uint64_t y = (x != 1);
+ if (sizeof(x) == sizeof(long))
+ return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
+ else
+ return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
+#else
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x |= x >> 32;
+ x++;
+ return x;
+#endif
+}
+
+
+/**
+ * Return 1 if this is a little endian machine, 0 if big endian.
+ */
+static INLINE GLboolean
+_mesa_little_endian(void)
+{
+ const GLuint ui = 1; /* intentionally not static */
+ return *((const GLubyte *) &ui);
+}
+
+
+
+/**********************************************************************
+ * Functions
+ */
+
+extern void *
+_mesa_align_malloc( size_t bytes, unsigned long alignment );
+
+extern void *
+_mesa_align_calloc( size_t bytes, unsigned long alignment );
+
+extern void
+_mesa_align_free( void *ptr );
+
+extern void *
+_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
+ unsigned long alignment);
+
+extern void *
+_mesa_exec_malloc( GLuint size );
+
+extern void
+_mesa_exec_free( void *addr );
+
+extern void *
+_mesa_realloc( void *oldBuffer, size_t oldSize, size_t newSize );
+
+extern void
+_mesa_memset16( unsigned short *dst, unsigned short val, size_t n );
+
+extern double
+_mesa_sqrtd(double x);
+
+extern float
+_mesa_sqrtf(float x);
+
+extern float
+_mesa_inv_sqrtf(float x);
+
+extern void
+_mesa_init_sqrt_table(void);
+
+#ifdef __GNUC__
+#define _mesa_ffs(i) ffs(i)
+#define _mesa_ffsll(i) ffsll(i)
+
+#if ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
+#define _mesa_bitcount(i) __builtin_popcount(i)
+#else
+extern unsigned int
+_mesa_bitcount(unsigned int n);
+#endif
+
+#else
+extern int
+_mesa_ffs(int32_t i);
+
+extern int
+_mesa_ffsll(int64_t i);
+
+extern unsigned int
+_mesa_bitcount(unsigned int n);
+#endif
+
+extern GLhalfARB
+_mesa_float_to_half(float f);
+
+extern float
+_mesa_half_to_float(GLhalfARB h);
+
+
+extern void *
+_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *) );
+
+extern char *
+_mesa_getenv( const char *var );
+
+extern char *
+_mesa_strdup( const char *s );
+
+extern float
+_mesa_strtof( const char *s, char **end );
+
+extern unsigned int
+_mesa_str_checksum(const char *str);
+
+extern int
+_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) PRINTFLIKE(3, 4);
+
+struct gl_context;
+
+extern void
+_mesa_warning( struct gl_context *gc, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+extern void
+_mesa_problem( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+extern void
+_mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) PRINTFLIKE(3, 4);
+
+extern void
+_mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#define snprintf _snprintf
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* IMPORTS_H */