1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file imports.c 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Standard C library function wrappers. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Imports are services which the device driver or window system or 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operating system provides to the core renderer. The core renderer (Mesa) 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will call these functions in order to do memory allocation, simple I/O, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * etc. 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Some drivers will want to override/replace this file with something 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * specialized, but that'll be rare. 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Eventually, I want to move roll the glheader.h file into this. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \todo Functions still needed: 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - scanf 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - qsort 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - rand and RAND_MAX 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 7.1 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "imports.h" 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "context.h" 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mtypes.h" 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "version.h" 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef _GNU_SOURCE 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <locale.h> 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __APPLE__ 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xlocale.h> 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef WIN32 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define vsnprintf _vsnprintf 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 ) 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __VMS 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vsnprintf.c" 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Memory */ 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate aligned memory. 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param bytes number of bytes to allocate. 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param alignment alignment (must be greater than zero). 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocates extra memory to accommodate rounding up the address for 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * alignment and to record the real malloc address. 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_align_free(). 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_malloc(size_t bytes, unsigned long alignment) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(HAVE_POSIX_MEMALIGN) 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int err = posix_memalign(& mem, alignment, bytes); 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (err) 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return mem; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_WIN32) && defined(_MSC_VER) 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return _aligned_malloc(bytes, alignment); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uintptr_t ptr, buf; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT( alignment > 0 ); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *)); 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ptr) 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(uintptr_t *)(buf - sizeof(void *)) = ptr; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* mark the non-aligned area */ 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while ( ptr < buf - sizeof(void *) ) { 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(unsigned long *)ptr = 0xcdcdcdcd; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr += sizeof(unsigned long); 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (void *) buf; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* defined(HAVE_POSIX_MEMALIGN) */ 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Same as _mesa_align_malloc(), but using calloc(1, ) instead of 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * malloc() 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_calloc(size_t bytes, unsigned long alignment) 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(HAVE_POSIX_MEMALIGN) 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mem = _mesa_align_malloc(bytes, alignment); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mem != NULL) { 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) memset(mem, 0, bytes); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return mem; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_WIN32) && defined(_MSC_VER) 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mem = _aligned_malloc(bytes, alignment); 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mem != NULL) { 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) memset(mem, 0, bytes); 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return mem; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uintptr_t ptr, buf; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT( alignment > 0 ); 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr = (uintptr_t) calloc(1, bytes + alignment + sizeof(void *)); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ptr) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(uintptr_t *)(buf - sizeof(void *)) = ptr; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* mark the non-aligned area */ 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while ( ptr < buf - sizeof(void *) ) { 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(unsigned long *)ptr = 0xcdcdcdcd; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr += sizeof(unsigned long); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (void *)buf; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* defined(HAVE_POSIX_MEMALIGN) */ 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free memory which was allocated with either _mesa_align_malloc() 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or _mesa_align_calloc(). 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ptr pointer to the memory to be freed. 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The actual address to free is stored in the word immediately before the 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * address the client sees. 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_free(void *ptr) 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(HAVE_POSIX_MEMALIGN) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(ptr); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_WIN32) && defined(_MSC_VER) 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _aligned_free(ptr); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *realAddr = *cubbyHole; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(realAddr); 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* defined(HAVE_POSIX_MEMALIGN) */ 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reallocate memory, with alignment. 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned long alignment) 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_WIN32) && defined(_MSC_VER) 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) oldSize; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return _aligned_realloc(oldBuffer, newSize, alignment); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const size_t copySize = (oldSize < newSize) ? oldSize : newSize; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *newBuf = _mesa_align_malloc(newSize, alignment); 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (newBuf && oldBuffer && copySize > 0) { 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(newBuf, oldBuffer, copySize); 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (oldBuffer) 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_align_free(oldBuffer); 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newBuf; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Reallocate memory */ 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize) 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const size_t copySize = (oldSize < newSize) ? oldSize : newSize; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *newBuffer = malloc(newSize); 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (newBuffer && oldBuffer && copySize > 0) 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(newBuffer, oldBuffer, copySize); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (oldBuffer) 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(oldBuffer); 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return newBuffer; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/ 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/ 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Math */ 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/ 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef __GNUC__ 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find the first bit set in a word. 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgffs(int i) 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org register int bit = 0; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i != 0) { 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((i & 0xffff) == 0) { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit += 16; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i >>= 16; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((i & 0xff) == 0) { 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit += 8; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i >>= 8; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((i & 0xf) == 0) { 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit += 4; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i >>= 4; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while ((i & 1) == 0) { 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit++; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i >>= 1; 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit++; 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bit; 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find position of first bit set in given value. 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX Warning: this function can only be used on 64-bit systems! 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return position of least-significant bit set, starting at 1, return zero 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if no bits set. 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgffsll(long long int val) 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int bit; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(sizeof(val) == 8); 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit = ffs((int) val); 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bit != 0) 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bit; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit = ffs((int) (val >> 32)); 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bit != 0) 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 32 + bit; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* __GNUC__ */ 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if !defined(__GNUC__) ||\ 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */ 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return number of bits set in given GLuint. 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_bitcount(unsigned int n) 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int bits; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (bits = 0; n > 0; n = n >> 1) { 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bits += (n & 1); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bits; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return number of bits set in given 64-bit uint. 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_bitcount_64(uint64_t n) 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int bits; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (bits = 0; n > 0; n = n >> 1) { 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bits += (n & 1); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bits; 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert a 4-byte float to a 2-byte half float. 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on code from: 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLhalfARB 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_float_to_half(float val) 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const fi_type fi = {val}; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int flt_m = fi.i & 0x7fffff; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int flt_e = (fi.i >> 23) & 0xff; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int flt_s = (fi.i >> 31) & 0x1; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int s, e, m = 0; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLhalfARB result; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* sign bit */ 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s = flt_s; 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* handle special cases */ 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((flt_e == 0) && (flt_m == 0)) { 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* zero */ 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* m = 0; - already set */ 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 0; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((flt_e == 0) && (flt_m != 0)) { 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* denorm -- denorm float maps to 0 half */ 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* m = 0; - already set */ 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 0; 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((flt_e == 0xff) && (flt_m == 0)) { 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* infinity */ 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* m = 0; - already set */ 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 31; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((flt_e == 0xff) && (flt_m != 0)) { 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* NaN */ 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org m = 1; 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 31; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* regular number */ 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int new_exp = flt_e - 127; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_exp < -24) { 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* this maps to 0 */ 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* m = 0; - already set */ 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 0; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (new_exp < -14) { 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* this maps to a denorm */ 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 0; 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (exp_val) { 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 0: 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_warning(NULL, 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "float_to_half: logical error in denorm creation!\n"); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* m = 0; - already set */ 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 1: m = 512 + (flt_m >> 14); break; 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 2: m = 256 + (flt_m >> 15); break; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 3: m = 128 + (flt_m >> 16); break; 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 4: m = 64 + (flt_m >> 17); break; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 5: m = 32 + (flt_m >> 18); break; 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 6: m = 16 + (flt_m >> 19); break; 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 7: m = 8 + (flt_m >> 20); break; 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 8: m = 4 + (flt_m >> 21); break; 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 9: m = 2 + (flt_m >> 22); break; 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 10: m = 1; break; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (new_exp > 15) { 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map this value to infinity */ 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* m = 0; - already set */ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = 31; 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* regular */ 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e = new_exp + 15; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org m = flt_m >> 13; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = (s << 15) | (e << 10) | m; 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert a 2-byte half float to a 4-byte float. 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on code from: 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_half_to_float(GLhalfARB val) 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX could also use a 64K-entry lookup table */ 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int m = val & 0x3ff; 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int e = (val >> 10) & 0x1f; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int s = (val >> 15) & 0x1; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int flt_m, flt_e, flt_s; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi_type fi; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float result; 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* sign bit */ 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_s = s; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* handle special cases */ 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((e == 0) && (m == 0)) { 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* zero */ 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_m = 0; 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_e = 0; 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((e == 0) && (m != 0)) { 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* denorm -- denorm half will fit in non-denorm single */ 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */ 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float mantissa = ((float) (m)) / 1024.0f; 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org float sign = s ? -1.0f : 1.0f; 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return sign * mantissa * half_denorm; 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((e == 31) && (m == 0)) { 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* infinity */ 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_e = 0xff; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_m = 0; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((e == 31) && (m != 0)) { 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* NaN */ 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_e = 0xff; 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_m = 1; 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* regular */ 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_e = e + 112; 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org flt_m = m << 13; 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fi.i = (flt_s << 31) | (flt_e << 23) | flt_m; 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = fi.f; 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/ 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/ 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Sort & Search */ 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/ 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Wrapper for bsearch(). 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size, 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int (*compar)(const void *, const void *) ) 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_WIN32_WCE) 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mid; 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int cmp; 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (nmemb) { 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nmemb >>= 1; 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mid = (char *)base + nmemb * size; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmp = (*compar)(key, mid); 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmp == 0) 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return mid; 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmp > 0) { 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base = (char *)mid + size; 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --nmemb; 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bsearch(key, base, nmemb, size, compar); 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/ 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/ 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Environment vars */ 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/ 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Wrapper for getenv(). 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar * 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_getenv( const char *var ) 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_XBOX) || defined(_WIN32_WCE) 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return getenv(var); 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/ 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/ 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name String */ 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/ 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Implemented using malloc() and strcpy. 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that NULL is handled accordingly. 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar * 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_strdup( const char *s ) 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s) { 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t l = strlen(s); 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char *s2 = (char *) malloc(l + 1); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s2) 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org strcpy(s2, s); 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return s2; 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Wrapper around strtof() */ 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_strtof( const char *s, char **end ) 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \ 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !defined(ANDROID) && !defined(__HAIKU__) && !defined(__UCLIBC__) 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static locale_t loc = NULL; 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!loc) { 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loc = newlocale(LC_CTYPE_MASK, "C", NULL); 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return strtof_l(s, end, loc); 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return strtof(s, end); 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (float)strtod(s, end); 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Compute simple checksum/hash for a string */ 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_str_checksum(const char *str) 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This could probably be much better */ 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int sum, i; 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *c; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sum = i = 1; 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (c = str; *c; c++, i++) 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sum += *c * (i % 100); 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return sum + i; 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/ 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Needed due to #ifdef's, above. */ 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list args) 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return vsnprintf( str, size, fmt, args); 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Wrapper around vsnprintf() */ 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int r; 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_list args; 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start( args, fmt ); 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = vsnprintf( str, size, fmt, args ); 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end( args ); 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return r; 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 595