Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**
  2.  * \file imports.c
  3.  * Standard C library function wrappers.
  4.  *
  5.  * Imports are services which the device driver or window system or
  6.  * operating system provides to the core renderer.  The core renderer (Mesa)
  7.  * will call these functions in order to do memory allocation, simple I/O,
  8.  * etc.
  9.  *
  10.  * Some drivers will want to override/replace this file with something
  11.  * specialized, but that'll be rare.
  12.  *
  13.  * Eventually, I want to move roll the glheader.h file into this.
  14.  *
  15.  * \todo Functions still needed:
  16.  * - scanf
  17.  * - qsort
  18.  * - rand and RAND_MAX
  19.  */
  20.  
  21. /*
  22.  * Mesa 3-D graphics library
  23.  *
  24.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  25.  *
  26.  * Permission is hereby granted, free of charge, to any person obtaining a
  27.  * copy of this software and associated documentation files (the "Software"),
  28.  * to deal in the Software without restriction, including without limitation
  29.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  30.  * and/or sell copies of the Software, and to permit persons to whom the
  31.  * Software is furnished to do so, subject to the following conditions:
  32.  *
  33.  * The above copyright notice and this permission notice shall be included
  34.  * in all copies or substantial portions of the Software.
  35.  *
  36.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  37.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  38.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  39.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  40.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  41.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  42.  * OTHER DEALINGS IN THE SOFTWARE.
  43.  */
  44.  
  45. #include <stdio.h>
  46. #include <stdarg.h>
  47. #include "c99_math.h"
  48. #include "util/rounding.h" /* for _mesa_roundeven */
  49. #include "imports.h"
  50. #include "context.h"
  51. #include "mtypes.h"
  52. #include "version.h"
  53.  
  54. #ifdef _GNU_SOURCE
  55. #include <locale.h>
  56. #ifdef __APPLE__
  57. #include <xlocale.h>
  58. #endif
  59. #endif
  60.  
  61.  
  62. #ifdef _WIN32
  63. #define vsnprintf _vsnprintf
  64. #elif defined(__IBMC__) || defined(__IBMCPP__)
  65. extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
  66. #endif
  67.  
  68. /**********************************************************************/
  69. /** \name Memory */
  70. /*@{*/
  71.  
  72. /**
  73.  * Allocate aligned memory.
  74.  *
  75.  * \param bytes number of bytes to allocate.
  76.  * \param alignment alignment (must be greater than zero).
  77.  *
  78.  * Allocates extra memory to accommodate rounding up the address for
  79.  * alignment and to record the real malloc address.
  80.  *
  81.  * \sa _mesa_align_free().
  82.  */
  83. void *
  84. _mesa_align_malloc(size_t bytes, unsigned long alignment)
  85. {
  86. #if defined(HAVE_POSIX_MEMALIGN)
  87.    void *mem;
  88.    int err = posix_memalign(& mem, alignment, bytes);
  89.    if (err)
  90.       return NULL;
  91.    return mem;
  92. #elif defined(_WIN32) && defined(_MSC_VER)
  93.    return _aligned_malloc(bytes, alignment);
  94. #else
  95.    uintptr_t ptr, buf;
  96.  
  97.    assert( alignment > 0 );
  98.  
  99.    ptr = (uintptr_t)malloc(bytes + alignment + sizeof(void *));
  100.    if (!ptr)
  101.       return NULL;
  102.  
  103.    buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
  104.    *(uintptr_t *)(buf - sizeof(void *)) = ptr;
  105.  
  106. #ifdef DEBUG
  107.    /* mark the non-aligned area */
  108.    while ( ptr < buf - sizeof(void *) ) {
  109.       *(unsigned long *)ptr = 0xcdcdcdcd;
  110.       ptr += sizeof(unsigned long);
  111.    }
  112. #endif
  113.  
  114.    return (void *) buf;
  115. #endif /* defined(HAVE_POSIX_MEMALIGN) */
  116. }
  117.  
  118. /**
  119.  * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
  120.  * malloc()
  121.  */
  122. void *
  123. _mesa_align_calloc(size_t bytes, unsigned long alignment)
  124. {
  125. #if defined(HAVE_POSIX_MEMALIGN)
  126.    void *mem;
  127.    
  128.    mem = _mesa_align_malloc(bytes, alignment);
  129.    if (mem != NULL) {
  130.       (void) memset(mem, 0, bytes);
  131.    }
  132.  
  133.    return mem;
  134. #elif defined(_WIN32) && defined(_MSC_VER)
  135.    void *mem;
  136.  
  137.    mem = _aligned_malloc(bytes, alignment);
  138.    if (mem != NULL) {
  139.       (void) memset(mem, 0, bytes);
  140.    }
  141.  
  142.    return mem;
  143. #else
  144.    uintptr_t ptr, buf;
  145.  
  146.    assert( alignment > 0 );
  147.  
  148.    ptr = (uintptr_t)calloc(1, bytes + alignment + sizeof(void *));
  149.    if (!ptr)
  150.       return NULL;
  151.  
  152.    buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
  153.    *(uintptr_t *)(buf - sizeof(void *)) = ptr;
  154.  
  155. #ifdef DEBUG
  156.    /* mark the non-aligned area */
  157.    while ( ptr < buf - sizeof(void *) ) {
  158.       *(unsigned long *)ptr = 0xcdcdcdcd;
  159.       ptr += sizeof(unsigned long);
  160.    }
  161. #endif
  162.  
  163.    return (void *)buf;
  164. #endif /* defined(HAVE_POSIX_MEMALIGN) */
  165. }
  166.  
  167. /**
  168.  * Free memory which was allocated with either _mesa_align_malloc()
  169.  * or _mesa_align_calloc().
  170.  * \param ptr pointer to the memory to be freed.
  171.  * The actual address to free is stored in the word immediately before the
  172.  * address the client sees.
  173.  * Note that it is legal to pass NULL pointer to this function and will be
  174.  * handled accordingly.
  175.  */
  176. void
  177. _mesa_align_free(void *ptr)
  178. {
  179. #if defined(HAVE_POSIX_MEMALIGN)
  180.    free(ptr);
  181. #elif defined(_WIN32) && defined(_MSC_VER)
  182.    _aligned_free(ptr);
  183. #else
  184.    if (ptr) {
  185.       void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
  186.       void *realAddr = *cubbyHole;
  187.       free(realAddr);
  188.    }
  189. #endif /* defined(HAVE_POSIX_MEMALIGN) */
  190. }
  191.  
  192. /**
  193.  * Reallocate memory, with alignment.
  194.  */
  195. void *
  196. _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
  197.                     unsigned long alignment)
  198. {
  199. #if defined(_WIN32) && defined(_MSC_VER)
  200.    (void) oldSize;
  201.    return _aligned_realloc(oldBuffer, newSize, alignment);
  202. #else
  203.    const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
  204.    void *newBuf = _mesa_align_malloc(newSize, alignment);
  205.    if (newBuf && oldBuffer && copySize > 0) {
  206.       memcpy(newBuf, oldBuffer, copySize);
  207.    }
  208.  
  209.    _mesa_align_free(oldBuffer);
  210.    return newBuf;
  211. #endif
  212. }
  213.  
  214. /*@}*/
  215.  
  216.  
  217. /**********************************************************************/
  218. /** \name Math */
  219. /*@{*/
  220.  
  221.  
  222. #ifndef HAVE___BUILTIN_FFS
  223. /**
  224.  * Find the first bit set in a word.
  225.  */
  226. int
  227. ffs(int i)
  228. {
  229.    register int bit = 0;
  230.    if (i != 0) {
  231.       if ((i & 0xffff) == 0) {
  232.          bit += 16;
  233.          i >>= 16;
  234.       }
  235.       if ((i & 0xff) == 0) {
  236.          bit += 8;
  237.          i >>= 8;
  238.       }
  239.       if ((i & 0xf) == 0) {
  240.          bit += 4;
  241.          i >>= 4;
  242.       }
  243.       while ((i & 1) == 0) {
  244.          bit++;
  245.          i >>= 1;
  246.       }
  247.       bit++;
  248.    }
  249.    return bit;
  250. }
  251. #endif
  252.  
  253. #ifndef HAVE___BUILTIN_FFSLL
  254. /**
  255.  * Find position of first bit set in given value.
  256.  * XXX Warning: this function can only be used on 64-bit systems!
  257.  * \return  position of least-significant bit set, starting at 1, return zero
  258.  *          if no bits set.
  259.  */
  260. int
  261. ffsll(long long int val)
  262. {
  263.    int bit;
  264.  
  265.    assert(sizeof(val) == 8);
  266.  
  267.    bit = ffs((int) val);
  268.    if (bit != 0)
  269.       return bit;
  270.  
  271.    bit = ffs((int) (val >> 32));
  272.    if (bit != 0)
  273.       return 32 + bit;
  274.  
  275.    return 0;
  276. }
  277. #endif
  278.  
  279.  
  280. #ifndef HAVE___BUILTIN_POPCOUNT
  281. /**
  282.  * Return number of bits set in given GLuint.
  283.  */
  284. unsigned int
  285. _mesa_bitcount(unsigned int n)
  286. {
  287.    unsigned int bits;
  288.    for (bits = 0; n > 0; n = n >> 1) {
  289.       bits += (n & 1);
  290.    }
  291.    return bits;
  292. }
  293. #endif
  294.  
  295. #ifndef HAVE___BUILTIN_POPCOUNTLL
  296. /**
  297.  * Return number of bits set in given 64-bit uint.
  298.  */
  299. unsigned int
  300. _mesa_bitcount_64(uint64_t n)
  301. {
  302.    unsigned int bits;
  303.    for (bits = 0; n > 0; n = n >> 1) {
  304.       bits += (n & 1);
  305.    }
  306.    return bits;
  307. }
  308. #endif
  309.  
  310.  
  311. /**
  312.  * Convert a 4-byte float to a 2-byte half float.
  313.  *
  314.  * Not all float32 values can be represented exactly as a float16 value. We
  315.  * round such intermediate float32 values to the nearest float16. When the
  316.  * float32 lies exactly between to float16 values, we round to the one with
  317.  * an even mantissa.
  318.  *
  319.  * This rounding behavior has several benefits:
  320.  *   - It has no sign bias.
  321.  *
  322.  *   - It reproduces the behavior of real hardware: opcode F32TO16 in Intel's
  323.  *     GPU ISA.
  324.  *
  325.  *   - By reproducing the behavior of the GPU (at least on Intel hardware),
  326.  *     compile-time evaluation of constant packHalf2x16 GLSL expressions will
  327.  *     result in the same value as if the expression were executed on the GPU.
  328.  */
  329. GLhalfARB
  330. _mesa_float_to_half(float val)
  331. {
  332.    const fi_type fi = {val};
  333.    const int flt_m = fi.i & 0x7fffff;
  334.    const int flt_e = (fi.i >> 23) & 0xff;
  335.    const int flt_s = (fi.i >> 31) & 0x1;
  336.    int s, e, m = 0;
  337.    GLhalfARB result;
  338.    
  339.    /* sign bit */
  340.    s = flt_s;
  341.  
  342.    /* handle special cases */
  343.    if ((flt_e == 0) && (flt_m == 0)) {
  344.       /* zero */
  345.       /* m = 0; - already set */
  346.       e = 0;
  347.    }
  348.    else if ((flt_e == 0) && (flt_m != 0)) {
  349.       /* denorm -- denorm float maps to 0 half */
  350.       /* m = 0; - already set */
  351.       e = 0;
  352.    }
  353.    else if ((flt_e == 0xff) && (flt_m == 0)) {
  354.       /* infinity */
  355.       /* m = 0; - already set */
  356.       e = 31;
  357.    }
  358.    else if ((flt_e == 0xff) && (flt_m != 0)) {
  359.       /* NaN */
  360.       m = 1;
  361.       e = 31;
  362.    }
  363.    else {
  364.       /* regular number */
  365.       const int new_exp = flt_e - 127;
  366.       if (new_exp < -14) {
  367.          /* The float32 lies in the range (0.0, min_normal16) and is rounded
  368.           * to a nearby float16 value. The result will be either zero, subnormal,
  369.           * or normal.
  370.           */
  371.          e = 0;
  372.          m = (int) _mesa_roundevenf((1 << 24) * fabsf(fi.f));
  373.       }
  374.       else if (new_exp > 15) {
  375.          /* map this value to infinity */
  376.          /* m = 0; - already set */
  377.          e = 31;
  378.       }
  379.       else {
  380.          /* The float32 lies in the range
  381.           *   [min_normal16, max_normal16 + max_step16)
  382.           * and is rounded to a nearby float16 value. The result will be
  383.           * either normal or infinite.
  384.           */
  385.          e = new_exp + 15;
  386.          m = (int) _mesa_roundevenf(flt_m / (float) (1 << 13));
  387.       }
  388.    }
  389.  
  390.    assert(0 <= m && m <= 1024);
  391.    if (m == 1024) {
  392.       /* The float32 was rounded upwards into the range of the next exponent,
  393.        * so bump the exponent. This correctly handles the case where f32
  394.        * should be rounded up to float16 infinity.
  395.        */
  396.       ++e;
  397.       m = 0;
  398.    }
  399.  
  400.    result = (s << 15) | (e << 10) | m;
  401.    return result;
  402. }
  403.  
  404.  
  405. /**
  406.  * Convert a 2-byte half float to a 4-byte float.
  407.  * Based on code from:
  408.  * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
  409.  */
  410. float
  411. _mesa_half_to_float(GLhalfARB val)
  412. {
  413.    /* XXX could also use a 64K-entry lookup table */
  414.    const int m = val & 0x3ff;
  415.    const int e = (val >> 10) & 0x1f;
  416.    const int s = (val >> 15) & 0x1;
  417.    int flt_m, flt_e, flt_s;
  418.    fi_type fi;
  419.    float result;
  420.  
  421.    /* sign bit */
  422.    flt_s = s;
  423.  
  424.    /* handle special cases */
  425.    if ((e == 0) && (m == 0)) {
  426.       /* zero */
  427.       flt_m = 0;
  428.       flt_e = 0;
  429.    }
  430.    else if ((e == 0) && (m != 0)) {
  431.       /* denorm -- denorm half will fit in non-denorm single */
  432.       const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
  433.       float mantissa = ((float) (m)) / 1024.0f;
  434.       float sign = s ? -1.0f : 1.0f;
  435.       return sign * mantissa * half_denorm;
  436.    }
  437.    else if ((e == 31) && (m == 0)) {
  438.       /* infinity */
  439.       flt_e = 0xff;
  440.       flt_m = 0;
  441.    }
  442.    else if ((e == 31) && (m != 0)) {
  443.       /* NaN */
  444.       flt_e = 0xff;
  445.       flt_m = 1;
  446.    }
  447.    else {
  448.       /* regular */
  449.       flt_e = e + 112;
  450.       flt_m = m << 13;
  451.    }
  452.  
  453.    fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
  454.    result = fi.f;
  455.    return result;
  456. }
  457.  
  458. /*@}*/
  459.  
  460.  
  461. /**********************************************************************/
  462. /** \name String */
  463. /*@{*/
  464.  
  465.  
  466. /** Compute simple checksum/hash for a string */
  467. unsigned int
  468. _mesa_str_checksum(const char *str)
  469. {
  470.    /* This could probably be much better */
  471.    unsigned int sum, i;
  472.    const char *c;
  473.    sum = i = 1;
  474.    for (c = str; *c; c++, i++)
  475.       sum += *c * (i % 100);
  476.    return sum + i;
  477. }
  478.  
  479.  
  480. /*@}*/
  481.  
  482.  
  483. /** Needed due to #ifdef's, above. */
  484. int
  485. _mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list args)
  486. {
  487.    return vsnprintf( str, size, fmt, args);
  488. }
  489.  
  490. /** Wrapper around vsnprintf() */
  491. int
  492. _mesa_snprintf( char *str, size_t size, const char *fmt, ... )
  493. {
  494.    int r;
  495.    va_list args;
  496.    va_start( args, fmt );  
  497.    r = vsnprintf( str, size, fmt, args );
  498.    va_end( args );
  499.    return r;
  500. }
  501.  
  502.  
  503.