16dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
26dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \file imports.c
36dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Standard C library function wrappers.
46dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
56dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Imports are services which the device driver or window system or
66dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * operating system provides to the core renderer.  The core renderer (Mesa)
76dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * will call these functions in order to do memory allocation, simple I/O,
86dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * etc.
96dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
106dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Some drivers will want to override/replace this file with something
116dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * specialized, but that'll be rare.
126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Eventually, I want to move roll the glheader.h file into this.
146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \todo Functions still needed:
166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * - scanf
176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * - qsort
186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * - rand and RAND_MAX
196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
21b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul/*
22b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * Mesa 3-D graphics library
23ef82f004fab29f5aff809a31cbcb51e381df1a49Brian * Version:  7.1
24b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul *
25f1770c32103ed23d11422e7e33e8326d09d99370Brian * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
26b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul *
27b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a
28b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * copy of this software and associated documentation files (the "Software"),
29b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * to deal in the Software without restriction, including without limitation
30b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
31b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * and/or sell copies of the Software, and to permit persons to whom the
32b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * Software is furnished to do so, subject to the following conditions:
33b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul *
34b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * The above copyright notice and this permission notice shall be included
35b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * in all copies or substantial portions of the Software.
36b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul *
37b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
40b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
41b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul */
44b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul
45b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul
464753d60dd070bb08d0116076bcc08025c86ce857Brian Paul
47b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul#include "imports.h"
4827558a160a9fe91745728d7626995cd88f8fe339Brian Paul#include "context.h"
490117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h"
50d4aaa68979c96df01fbe7122a1dcd663ef83b441Brian Paul#include "version.h"
513c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
5289b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul#ifdef _GNU_SOURCE
5389b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul#include <locale.h>
54ca940a73a72c68c461344d27f9d1fac31cd73819Vinson Lee#ifdef __APPLE__
55ca940a73a72c68c461344d27f9d1fac31cd73819Vinson Lee#include <xlocale.h>
56ca940a73a72c68c461344d27f9d1fac31cd73819Vinson Lee#endif
5789b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul#endif
5889b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul
594753d60dd070bb08d0116076bcc08025c86ce857Brian Paul
602353e96c320d4bd26d10dc29b57df3e9f882e6d3Karl Schultz#ifdef WIN32
612353e96c320d4bd26d10dc29b57df3e9f882e6d3Karl Schultz#define vsnprintf _vsnprintf
621d61db5f314e7b7e2f1ab4a5cb4452f6a458ed34Jouk Jansen#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
63e7cf569475a2baed8f372d81657fc3516666d6acBrian Paulextern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
641d61db5f314e7b7e2f1ab4a5cb4452f6a458ed34Jouk Jansen#ifdef __VMS
651d61db5f314e7b7e2f1ab4a5cb4452f6a458ed34Jouk Jansen#include "vsnprintf.c"
661d61db5f314e7b7e2f1ab4a5cb4452f6a458ed34Jouk Jansen#endif
672353e96c320d4bd26d10dc29b57df3e9f882e6d3Karl Schultz#endif
68b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul
693c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul/**********************************************************************/
706dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name Memory */
716dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
7227558a160a9fe91745728d7626995cd88f8fe339Brian Paul
736dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Allocate aligned memory.
756dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
766dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param bytes number of bytes to allocate.
776dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param alignment alignment (must be greater than zero).
786dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
796dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Allocates extra memory to accommodate rounding up the address for
806dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * alignment and to record the real malloc address.
816dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
826dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa _mesa_align_free().
836dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
843c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paulvoid *
853c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul_mesa_align_malloc(size_t bytes, unsigned long alignment)
863c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul{
87b766643e5c3c9ed174c59b54e520f94e3420e39aGeorge Sapountzis#if defined(HAVE_POSIX_MEMALIGN)
88a7d02567451f69445ef31181a41b16e86487093dIan Romanick   void *mem;
8976aa0c0fd3d972000cb6707a3834128cea2f9738Brian Paul   int err = posix_memalign(& mem, alignment, bytes);
90b1097607db58ddaa91281e364dbb4aa53d904052pontus lidman   if (err)
91b1097607db58ddaa91281e364dbb4aa53d904052pontus lidman      return NULL;
92a7d02567451f69445ef31181a41b16e86487093dIan Romanick   return mem;
9331fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko#elif defined(_WIN32) && defined(_MSC_VER)
9431fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   return _aligned_malloc(bytes, alignment);
95a7d02567451f69445ef31181a41b16e86487093dIan Romanick#else
966258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   uintptr_t ptr, buf;
973c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
983c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   ASSERT( alignment > 0 );
993c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
10032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *));
101c5934054f3f3e2174a9897e901409da17c1a296eBrian Paul   if (!ptr)
102c5934054f3f3e2174a9897e901409da17c1a296eBrian Paul      return NULL;
1033c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1046258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
1056258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   *(uintptr_t *)(buf - sizeof(void *)) = ptr;
1063c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1073c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#ifdef DEBUG
1083c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   /* mark the non-aligned area */
1093c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   while ( ptr < buf - sizeof(void *) ) {
1103c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul      *(unsigned long *)ptr = 0xcdcdcdcd;
1113c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul      ptr += sizeof(unsigned long);
1123c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   }
1133c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#endif
1143c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
115c5934054f3f3e2174a9897e901409da17c1a296eBrian Paul   return (void *) buf;
116b766643e5c3c9ed174c59b54e520f94e3420e39aGeorge Sapountzis#endif /* defined(HAVE_POSIX_MEMALIGN) */
1173c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul}
1183c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
119f8582b6c1f2403869d21bf57093f644284139802Brian Paul/**
12032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
12132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg * malloc()
122f8582b6c1f2403869d21bf57093f644284139802Brian Paul */
1233c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paulvoid *
1243c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul_mesa_align_calloc(size_t bytes, unsigned long alignment)
125b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul{
126b766643e5c3c9ed174c59b54e520f94e3420e39aGeorge Sapountzis#if defined(HAVE_POSIX_MEMALIGN)
127a7d02567451f69445ef31181a41b16e86487093dIan Romanick   void *mem;
128a7d02567451f69445ef31181a41b16e86487093dIan Romanick
129a7d02567451f69445ef31181a41b16e86487093dIan Romanick   mem = _mesa_align_malloc(bytes, alignment);
130a7d02567451f69445ef31181a41b16e86487093dIan Romanick   if (mem != NULL) {
131a7d02567451f69445ef31181a41b16e86487093dIan Romanick      (void) memset(mem, 0, bytes);
132a7d02567451f69445ef31181a41b16e86487093dIan Romanick   }
133a7d02567451f69445ef31181a41b16e86487093dIan Romanick
134a7d02567451f69445ef31181a41b16e86487093dIan Romanick   return mem;
13531fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko#elif defined(_WIN32) && defined(_MSC_VER)
13631fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   void *mem;
13731fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko
13831fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   mem = _aligned_malloc(bytes, alignment);
13931fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   if (mem != NULL) {
14031fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko      (void) memset(mem, 0, bytes);
14131fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   }
14231fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko
14331fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   return mem;
144a7d02567451f69445ef31181a41b16e86487093dIan Romanick#else
1456258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   uintptr_t ptr, buf;
1463c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1473c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   ASSERT( alignment > 0 );
1483c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
14932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   ptr = (uintptr_t) calloc(1, bytes + alignment + sizeof(void *));
150c5934054f3f3e2174a9897e901409da17c1a296eBrian Paul   if (!ptr)
151c5934054f3f3e2174a9897e901409da17c1a296eBrian Paul      return NULL;
1523c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1536258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
1546258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz   *(uintptr_t *)(buf - sizeof(void *)) = ptr;
1553c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1563c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#ifdef DEBUG
1573c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   /* mark the non-aligned area */
1583c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   while ( ptr < buf - sizeof(void *) ) {
1593c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul      *(unsigned long *)ptr = 0xcdcdcdcd;
1603c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul      ptr += sizeof(unsigned long);
1613c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   }
1623c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#endif
1633c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1643c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   return (void *)buf;
165b766643e5c3c9ed174c59b54e520f94e3420e39aGeorge Sapountzis#endif /* defined(HAVE_POSIX_MEMALIGN) */
166b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul}
167b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul
1686dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
169f8582b6c1f2403869d21bf57093f644284139802Brian Paul * Free memory which was allocated with either _mesa_align_malloc()
170f8582b6c1f2403869d21bf57093f644284139802Brian Paul * or _mesa_align_calloc().
1716dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param ptr pointer to the memory to be freed.
1726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * The actual address to free is stored in the word immediately before the
1736dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * address the client sees.
1746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
1753c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paulvoid
1763c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul_mesa_align_free(void *ptr)
1773c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul{
178b766643e5c3c9ed174c59b54e520f94e3420e39aGeorge Sapountzis#if defined(HAVE_POSIX_MEMALIGN)
179a7d02567451f69445ef31181a41b16e86487093dIan Romanick   free(ptr);
18031fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko#elif defined(_WIN32) && defined(_MSC_VER)
18131fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   _aligned_free(ptr);
1823c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#else
1833c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
1843c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   void *realAddr = *cubbyHole;
18532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(realAddr);
186b766643e5c3c9ed174c59b54e520f94e3420e39aGeorge Sapountzis#endif /* defined(HAVE_POSIX_MEMALIGN) */
1873c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul}
1883c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul
1891798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul/**
1901798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul * Reallocate memory, with alignment.
1911798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul */
1921798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paulvoid *
1931798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
1941798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul                    unsigned long alignment)
1951798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul{
19631fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko#if defined(_WIN32) && defined(_MSC_VER)
19731fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   (void) oldSize;
19831fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko   return _aligned_realloc(oldBuffer, newSize, alignment);
19931fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko#else
2001798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul   const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
2011798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul   void *newBuf = _mesa_align_malloc(newSize, alignment);
2021798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul   if (newBuf && oldBuffer && copySize > 0) {
203c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke      memcpy(newBuf, oldBuffer, copySize);
2041798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul   }
2051798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul   if (oldBuffer)
2061798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul      _mesa_align_free(oldBuffer);
2071798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul   return newBuf;
20831fe7cf5e3ca38441acb25215420afa6944226f3Michal Wajdeczko#endif
2091798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul}
2101798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul
2111798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul
2121798d9a8a4a779746f5e665357b6bc10a2894d0bBrian Paul
213f8582b6c1f2403869d21bf57093f644284139802Brian Paul/** Reallocate memory */
2143c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paulvoid *
2150cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
2160cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul{
2170cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul   const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
21832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   void *newBuffer = malloc(newSize);
219f8582b6c1f2403869d21bf57093f644284139802Brian Paul   if (newBuffer && oldBuffer && copySize > 0)
220c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke      memcpy(newBuffer, oldBuffer, copySize);
2210cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul   if (oldBuffer)
22232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(oldBuffer);
2230cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul   return newBuffer;
2240cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul}
2250cebd5822a39ad3b3d7621f8e59efab329bfb5b9Brian Paul
2266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
2274e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul
22827558a160a9fe91745728d7626995cd88f8fe339Brian Paul
2296dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**********************************************************************/
2306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name Math */
2316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
2326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
23327558a160a9fe91745728d7626995cd88f8fe339Brian Paul
23441260a9bf63aa61f88f188053f1ed4dba3a852d2Chris Wilson#ifndef __GNUC__
235b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul/**
236cd81190d5c5f7064e0013eb313f2ad5da863fad7Brian Paul * Find the first bit set in a word.
237b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul */
238b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paulint
2399a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paulffs(int i)
240b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul{
2412cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul   register int bit = 0;
2422cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul   if (i != 0) {
2432cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      if ((i & 0xffff) == 0) {
2442cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         bit += 16;
2452cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         i >>= 16;
2462cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      }
2472cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      if ((i & 0xff) == 0) {
2482cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         bit += 8;
2492cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         i >>= 8;
2502cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      }
2512cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      if ((i & 0xf) == 0) {
2522cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         bit += 4;
2532cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         i >>= 4;
2542cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      }
2552cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      while ((i & 1) == 0) {
2562cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         bit++;
2572cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul         i >>= 1;
2582cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul      }
259e9809a36aaea3480cba5bd62360bf9d481ff9011Andrzej Trznadel      bit++;
2602cb1cf484ad2f78b9c4ec9aea025b5afc9b4b43aBrian Paul   }
2618716e7570d17c3e6bcf7e5c1d8aa3a0c5035a5acBrian Paul   return bit;
262b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul}
263b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
264b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
2657eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul/**
26699c9bc386f54964eea0ed93f6b036477076dae57Brian * Find position of first bit set in given value.
26799c9bc386f54964eea0ed93f6b036477076dae57Brian * XXX Warning: this function can only be used on 64-bit systems!
2681b62353dd868a37ee20c20d66b2123e2020cc59fBrian * \return  position of least-significant bit set, starting at 1, return zero
26999c9bc386f54964eea0ed93f6b036477076dae57Brian *          if no bits set.
27099c9bc386f54964eea0ed93f6b036477076dae57Brian */
271869b8ad499717eda4a1be04de4e516134123402cEric Anholtint
2729a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paulffsll(long long int val)
273869b8ad499717eda4a1be04de4e516134123402cEric Anholt{
27499c9bc386f54964eea0ed93f6b036477076dae57Brian   int bit;
275869b8ad499717eda4a1be04de4e516134123402cEric Anholt
27699c9bc386f54964eea0ed93f6b036477076dae57Brian   assert(sizeof(val) == 8);
277869b8ad499717eda4a1be04de4e516134123402cEric Anholt
2789a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul   bit = ffs((int) val);
27999c9bc386f54964eea0ed93f6b036477076dae57Brian   if (bit != 0)
28099c9bc386f54964eea0ed93f6b036477076dae57Brian      return bit;
281869b8ad499717eda4a1be04de4e516134123402cEric Anholt
2829a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul   bit = ffs((int) (val >> 32));
28399c9bc386f54964eea0ed93f6b036477076dae57Brian   if (bit != 0)
28499c9bc386f54964eea0ed93f6b036477076dae57Brian      return 32 + bit;
285869b8ad499717eda4a1be04de4e516134123402cEric Anholt
28699c9bc386f54964eea0ed93f6b036477076dae57Brian   return 0;
287869b8ad499717eda4a1be04de4e516134123402cEric Anholt}
2889a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul#endif /* __GNUC__ */
2899a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul
290b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
291da009212fe121206a67cb65ca8f88777a9f7e44fRoland Scheidegger#if !defined(__GNUC__) ||\
2928c509e1181fc8be85587f290b0a9337724fb7a7bAlan Coopersmith   ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
2937eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul/**
29427558a160a9fe91745728d7626995cd88f8fe339Brian Paul * Return number of bits set in given GLuint.
29527558a160a9fe91745728d7626995cd88f8fe339Brian Paul */
29627558a160a9fe91745728d7626995cd88f8fe339Brian Paulunsigned int
29727558a160a9fe91745728d7626995cd88f8fe339Brian Paul_mesa_bitcount(unsigned int n)
29827558a160a9fe91745728d7626995cd88f8fe339Brian Paul{
29927558a160a9fe91745728d7626995cd88f8fe339Brian Paul   unsigned int bits;
30027558a160a9fe91745728d7626995cd88f8fe339Brian Paul   for (bits = 0; n > 0; n = n >> 1) {
30127558a160a9fe91745728d7626995cd88f8fe339Brian Paul      bits += (n & 1);
30227558a160a9fe91745728d7626995cd88f8fe339Brian Paul   }
30327558a160a9fe91745728d7626995cd88f8fe339Brian Paul   return bits;
30427558a160a9fe91745728d7626995cd88f8fe339Brian Paul}
305c163072197b56e76b656cc472bbe6df650cf11baPaul Berry
306c163072197b56e76b656cc472bbe6df650cf11baPaul Berry/**
307c163072197b56e76b656cc472bbe6df650cf11baPaul Berry * Return number of bits set in given 64-bit uint.
308c163072197b56e76b656cc472bbe6df650cf11baPaul Berry */
309c163072197b56e76b656cc472bbe6df650cf11baPaul Berryunsigned int
310c163072197b56e76b656cc472bbe6df650cf11baPaul Berry_mesa_bitcount_64(uint64_t n)
311c163072197b56e76b656cc472bbe6df650cf11baPaul Berry{
312c163072197b56e76b656cc472bbe6df650cf11baPaul Berry   unsigned int bits;
313c163072197b56e76b656cc472bbe6df650cf11baPaul Berry   for (bits = 0; n > 0; n = n >> 1) {
314c163072197b56e76b656cc472bbe6df650cf11baPaul Berry      bits += (n & 1);
315c163072197b56e76b656cc472bbe6df650cf11baPaul Berry   }
316c163072197b56e76b656cc472bbe6df650cf11baPaul Berry   return bits;
317c163072197b56e76b656cc472bbe6df650cf11baPaul Berry}
31841260a9bf63aa61f88f188053f1ed4dba3a852d2Chris Wilson#endif
31927558a160a9fe91745728d7626995cd88f8fe339Brian Paul
3207eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
3217eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul/**
3227eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul * Convert a 4-byte float to a 2-byte half float.
323aa0d6dcd652ca3f6ece2e9314020283589d79a2aBrian Paul * Based on code from:
324aa0d6dcd652ca3f6ece2e9314020283589d79a2aBrian Paul * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
3257eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul */
326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLhalfARB
3277eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul_mesa_float_to_half(float val)
3287eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul{
329c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   const fi_type fi = {val};
330c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   const int flt_m = fi.i & 0x7fffff;
331c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   const int flt_e = (fi.i >> 23) & 0xff;
332c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   const int flt_s = (fi.i >> 31) & 0x1;
333a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane   int s, e, m = 0;
334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLhalfARB result;
3357eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
3367eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   /* sign bit */
3377eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   s = flt_s;
3387eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
3397eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   /* handle special cases */
3407eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   if ((flt_e == 0) && (flt_m == 0)) {
3417eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* zero */
342a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane      /* m = 0; - already set */
3437eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      e = 0;
3447eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
3457eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else if ((flt_e == 0) && (flt_m != 0)) {
3467eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* denorm -- denorm float maps to 0 half */
347a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane      /* m = 0; - already set */
3487eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      e = 0;
3497eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
3507eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else if ((flt_e == 0xff) && (flt_m == 0)) {
3517eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* infinity */
352a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane      /* m = 0; - already set */
3537eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      e = 31;
3547eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
3557eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else if ((flt_e == 0xff) && (flt_m != 0)) {
3567eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* NaN */
3577eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      m = 1;
3587eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      e = 31;
3597eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
3607eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else {
3617eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* regular number */
3627eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      const int new_exp = flt_e - 127;
3637eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      if (new_exp < -24) {
3647eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         /* this maps to 0 */
365a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane         /* m = 0; - already set */
3667eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         e = 0;
3677eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      }
3687eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      else if (new_exp < -14) {
3697eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         /* this maps to a denorm */
3707eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
3717eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         e = 0;
3727eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         switch (exp_val) {
3737eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 0:
3747eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul               _mesa_warning(NULL,
3757eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul                   "float_to_half: logical error in denorm creation!\n");
376a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane               /* m = 0; - already set */
3777eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul               break;
3787eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 1: m = 512 + (flt_m >> 14); break;
3797eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 2: m = 256 + (flt_m >> 15); break;
3807eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 3: m = 128 + (flt_m >> 16); break;
3817eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 4: m = 64 + (flt_m >> 17); break;
3827eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 5: m = 32 + (flt_m >> 18); break;
3837eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 6: m = 16 + (flt_m >> 19); break;
3847eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 7: m = 8 + (flt_m >> 20); break;
3857eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 8: m = 4 + (flt_m >> 21); break;
3867eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 9: m = 2 + (flt_m >> 22); break;
3877eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul            case 10: m = 1; break;
3887eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         }
3897eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      }
3907eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      else if (new_exp > 15) {
3917eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         /* map this value to infinity */
392a87bf1599c970a61a56f6271e2fb0b107c299893Alan Hourihane         /* m = 0; - already set */
3937eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         e = 31;
3947eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      }
3957eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      else {
3967eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         /* regular */
3977eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         e = new_exp + 15;
3987eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul         m = flt_m >> 13;
3997eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      }
4007eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
4017eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
4027eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   result = (s << 15) | (e << 10) | m;
4037eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   return result;
4047eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul}
4057eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
4067eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
4077eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul/**
4087eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul * Convert a 2-byte half float to a 4-byte float.
409aa0d6dcd652ca3f6ece2e9314020283589d79a2aBrian Paul * Based on code from:
410aa0d6dcd652ca3f6ece2e9314020283589d79a2aBrian Paul * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
4117eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul */
4127eb3e9b9648938500c6172a88fb2998e6264467fBrian Paulfloat
413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul_mesa_half_to_float(GLhalfARB val)
4147eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul{
4157eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   /* XXX could also use a 64K-entry lookup table */
4167eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   const int m = val & 0x3ff;
4177eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   const int e = (val >> 10) & 0x1f;
4187eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   const int s = (val >> 15) & 0x1;
419c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   int flt_m, flt_e, flt_s;
420c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   fi_type fi;
4217eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   float result;
4227eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
4237eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   /* sign bit */
4247eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   flt_s = s;
4257eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
4267eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   /* handle special cases */
4277eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   if ((e == 0) && (m == 0)) {
4287eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* zero */
4297eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_m = 0;
4307eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_e = 0;
4317eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
4327eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else if ((e == 0) && (m != 0)) {
4337eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* denorm -- denorm half will fit in non-denorm single */
4347eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
4357eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      float mantissa = ((float) (m)) / 1024.0f;
4367eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      float sign = s ? -1.0f : 1.0f;
4377eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      return sign * mantissa * half_denorm;
4387eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
4397eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else if ((e == 31) && (m == 0)) {
4407eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* infinity */
4417eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_e = 0xff;
4427eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_m = 0;
4437eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
4447eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else if ((e == 31) && (m != 0)) {
4457eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* NaN */
4467eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_e = 0xff;
4477eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_m = 1;
4487eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
4497eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   else {
4507eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      /* regular */
4517eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_e = e + 112;
4527eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul      flt_m = m << 13;
4537eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   }
4547eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
455c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
456c36d1aacf4c70d76165c91cd7048c0f9f43b8571Roland Scheidegger   result = fi.f;
4577eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul   return result;
4587eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul}
4597eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul
4606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
46127558a160a9fe91745728d7626995cd88f8fe339Brian Paul
46227558a160a9fe91745728d7626995cd88f8fe339Brian Paul
4636dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**********************************************************************/
464b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul/** \name Sort & Search */
465b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul/*@{*/
466b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
467b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul/**
468b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul * Wrapper for bsearch().
469b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul */
470b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paulvoid *
471b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
472b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul               int (*compar)(const void *, const void *) )
473b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul{
474baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca#if defined(_WIN32_WCE)
475baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca   void *mid;
476baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca   int cmp;
477baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca   while (nmemb) {
478baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca      nmemb >>= 1;
479baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca      mid = (char *)base + nmemb * size;
480baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca      cmp = (*compar)(key, mid);
481baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca      if (cmp == 0)
482baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca	 return mid;
483baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca      if (cmp > 0) {
484baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca	 base = (char *)mid + size;
485baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca	 --nmemb;
486baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca      }
487baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca   }
488baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca   return NULL;
489baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca#else
490b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul   return bsearch(key, base, nmemb, size, compar);
491baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca#endif
492b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul}
493b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
494b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul/*@}*/
495b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
496b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul
497b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul/**********************************************************************/
4986dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name Environment vars */
4996dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
50027558a160a9fe91745728d7626995cd88f8fe339Brian Paul
5017eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul/**
5027eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul * Wrapper for getenv().
5037eb3e9b9648938500c6172a88fb2998e6264467fBrian Paul */
5043c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paulchar *
5053c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul_mesa_getenv( const char *var )
506b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul{
507baa76e9aa255c4b4591111991b6ad6d80e69d9c1José Fonseca#if defined(_XBOX) || defined(_WIN32_WCE)
508369404299c6e23ee0cc4b572c95e5533314064d7Ben Crossman   return NULL;
5093c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#else
5103c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul   return getenv(var);
5113c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#endif
512b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul}
513b1394fa92aaaf859ce9efc8b5fc194397921320cBrian Paul
5146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
5154e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul
51627558a160a9fe91745728d7626995cd88f8fe339Brian Paul
5176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**********************************************************************/
5186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name String */
5196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
5206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
521200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian/**
52232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg * Implemented using malloc() and strcpy.
523200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian * Note that NULL is handled accordingly.
524200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian */
52544257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paulchar *
52644257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul_mesa_strdup( const char *s )
52744257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul{
528200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian   if (s) {
52921d0c70b4b1c18dc1c3ac7d0fbd8a903d60f8be7Kenneth Graunke      size_t l = strlen(s);
53032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      char *s2 = (char *) malloc(l + 1);
531200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian      if (s2)
5325fcaa78912bc78a5db410200c5987e2c57fad570Kenneth Graunke         strcpy(s2, s);
533200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian      return s2;
534200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian   }
535200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian   else {
536200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian      return NULL;
537200736ebd8c82b03b781a6c6481d05deb1f0c8bfBrian   }
53844257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul}
53944257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul
540346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński/** Wrapper around strtof() */
541346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyńskifloat
542346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński_mesa_strtof( const char *s, char **end )
54344257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul{
544bd064a49f119d126623c0e85702801e4cee62187Chad Versace#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
545f35e380dd240b418e17a179af73bbab74ceea784Anthony G. Basile   !defined(ANDROID) && !defined(__HAIKU__) && !defined(__UCLIBC__)
54689b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul   static locale_t loc = NULL;
54789b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul   if (!loc) {
54889b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul      loc = newlocale(LC_CTYPE_MASK, "C", NULL);
54989b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul   }
550346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński   return strtof_l(s, end, loc);
551346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński#elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
552346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński   return strtof(s, end);
55389b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul#else
554346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński   return (float)strtod(s, end);
55589b31c9619449d5c9b8ebe4e245c2a926e3583e6Brian Paul#endif
55644257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul}
55744257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul
5589f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul/** Compute simple checksum/hash for a string */
5599f8110adcc5a6f47b5db0915bb9265925d520856Brian Paulunsigned int
5609f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul_mesa_str_checksum(const char *str)
5619f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul{
5629f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul   /* This could probably be much better */
5639f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul   unsigned int sum, i;
5649f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul   const char *c;
5659f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul   sum = i = 1;
5660acb057ad16264b976b00aa7c6ecf285ca8c19e7Brian Paul   for (c = str; *c; c++, i++)
5679f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul      sum += *c * (i % 100);
5680acb057ad16264b976b00aa7c6ecf285ca8c19e7Brian Paul   return sum + i;
5699f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul}
5709f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul
5719f8110adcc5a6f47b5db0915bb9265925d520856Brian Paul
5726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
57344257dacc0d5e2032b2d5eb6a6b35127c0f77a76Brian Paul
57427558a160a9fe91745728d7626995cd88f8fe339Brian Paul
5755ab088c7e201ea7e55459a24a945abcaa90d12c6nobled/** Needed due to #ifdef's, above. */
5765ab088c7e201ea7e55459a24a945abcaa90d12c6nobledint
5775ab088c7e201ea7e55459a24a945abcaa90d12c6nobled_mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list args)
5785ab088c7e201ea7e55459a24a945abcaa90d12c6nobled{
5795ab088c7e201ea7e55459a24a945abcaa90d12c6nobled   return vsnprintf( str, size, fmt, args);
5805ab088c7e201ea7e55459a24a945abcaa90d12c6nobled}
5815ab088c7e201ea7e55459a24a945abcaa90d12c6nobled
58278a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul/** Wrapper around vsnprintf() */
58378a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paulint
58478a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul_mesa_snprintf( char *str, size_t size, const char *fmt, ... )
58578a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul{
58678a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul   int r;
58778a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul   va_list args;
58878a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul   va_start( args, fmt );
58978a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul   r = vsnprintf( str, size, fmt, args );
59078a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul   va_end( args );
59178a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul   return r;
59278a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul}
59378a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul
59478a0c353d0f87c85feaa6dcb3042fc25d424f21bBrian Paul
595