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