Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /**
  27.  * \file imports.h
  28.  * Standard C library function wrappers.
  29.  *
  30.  * This file provides wrappers for all the standard C library functions
  31.  * like malloc(), free(), printf(), getenv(), etc.
  32.  */
  33.  
  34.  
  35. #ifndef IMPORTS_H
  36. #define IMPORTS_H
  37.  
  38.  
  39. #include <stdlib.h>
  40. #include <stdarg.h>
  41. #include <string.h>
  42. #include "compiler.h"
  43. #include "glheader.h"
  44. #include "errors.h"
  45.  
  46. #ifdef __cplusplus
  47. extern "C" {
  48. #endif
  49.  
  50.  
  51. /**********************************************************************/
  52. /** Memory macros */
  53. /*@{*/
  54.  
  55. /** Allocate a structure of type \p T */
  56. #define MALLOC_STRUCT(T)   (struct T *) malloc(sizeof(struct T))
  57. /** Allocate and zero a structure of type \p T */
  58. #define CALLOC_STRUCT(T)   (struct T *) calloc(1, sizeof(struct T))
  59.  
  60. /*@}*/
  61.  
  62.  
  63. /*
  64.  * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers
  65.  * as offsets into buffer stores.  Since the vertex array pointer and
  66.  * buffer store pointer are both pointers and we need to add them, we use
  67.  * this macro.
  68.  * Both pointers/offsets are expressed in bytes.
  69.  */
  70. #define ADD_POINTERS(A, B)  ( (GLubyte *) (A) + (uintptr_t) (B) )
  71.  
  72.  
  73. /**
  74.  * Sometimes we treat GLfloats as GLints.  On x86 systems, moving a float
  75.  * as a int (thereby using integer registers instead of FP registers) is
  76.  * a performance win.  Typically, this can be done with ordinary casts.
  77.  * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0)
  78.  * these casts generate warnings.
  79.  * The following union typedef is used to solve that.
  80.  */
  81. typedef union { GLfloat f; GLint i; GLuint u; } fi_type;
  82.  
  83.  
  84.  
  85. #if defined(_MSC_VER)
  86. #if _MSC_VER < 1800  /* Not req'd on VS2013 and above */
  87. #define strtoll(p, e, b) _strtoi64(p, e, b)
  88. #endif /* _MSC_VER < 1800 */
  89. #define strcasecmp(s1, s2) _stricmp(s1, s2)
  90. #endif
  91. /*@}*/
  92.  
  93.  
  94. /***
  95.  *** LOG2: Log base 2 of float
  96.  ***/
  97. static inline GLfloat LOG2(GLfloat x)
  98. {
  99. #if 0
  100.    /* This is pretty fast, but not accurate enough (only 2 fractional bits).
  101.     * Based on code from http://www.stereopsis.com/log2.html
  102.     */
  103.    const GLfloat y = x * x * x * x;
  104.    const GLuint ix = *((GLuint *) &y);
  105.    const GLuint exp = (ix >> 23) & 0xFF;
  106.    const GLint log2 = ((GLint) exp) - 127;
  107.    return (GLfloat) log2 * (1.0 / 4.0);  /* 4, because of x^4 above */
  108. #endif
  109.    /* Pretty fast, and accurate.
  110.     * Based on code from http://www.flipcode.com/totd/
  111.     */
  112.    fi_type num;
  113.    GLint log_2;
  114.    num.f = x;
  115.    log_2 = ((num.i >> 23) & 255) - 128;
  116.    num.i &= ~(255 << 23);
  117.    num.i += 127 << 23;
  118.    num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3;
  119.    return num.f + log_2;
  120. }
  121.  
  122.  
  123.  
  124. /**
  125.  * finite macro.
  126.  */
  127. #if defined(_MSC_VER)
  128. #  define finite _finite
  129. #endif
  130.  
  131.  
  132. /***
  133.  *** IS_INF_OR_NAN: test if float is infinite or NaN
  134.  ***/
  135. #if defined(isfinite)
  136. #define IS_INF_OR_NAN(x)        (!isfinite(x))
  137. #elif defined(finite)
  138. #define IS_INF_OR_NAN(x)        (!finite(x))
  139. #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
  140. #define IS_INF_OR_NAN(x)        (!isfinite(x))
  141. #else
  142. #define IS_INF_OR_NAN(x)        (!finite(x))
  143. #endif
  144.  
  145.  
  146. /**
  147.  * Convert float to int by rounding to nearest integer, away from zero.
  148.  */
  149. static inline int IROUND(float f)
  150. {
  151.    return (int) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F));
  152. }
  153.  
  154.  
  155. /**
  156.  * Convert float to int64 by rounding to nearest integer.
  157.  */
  158. static inline GLint64 IROUND64(float f)
  159. {
  160.    return (GLint64) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F));
  161. }
  162.  
  163.  
  164. /**
  165.  * Convert positive float to int by rounding to nearest integer.
  166.  */
  167. static inline int IROUND_POS(float f)
  168. {
  169.    assert(f >= 0.0F);
  170.    return (int) (f + 0.5F);
  171. }
  172.  
  173. #ifdef __x86_64__
  174. #  include <xmmintrin.h>
  175. #endif
  176.  
  177. /**
  178.  * Convert float to int using a fast method.  The rounding mode may vary.
  179.  */
  180. static inline int F_TO_I(float f)
  181. {
  182. #if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
  183.    int r;
  184.    __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
  185.    return r;
  186. #elif defined(USE_X86_ASM) && defined(_MSC_VER)
  187.    int r;
  188.    _asm {
  189.          fld f
  190.          fistp r
  191.         }
  192.    return r;
  193. #elif defined(__x86_64__)
  194.    return _mm_cvt_ss2si(_mm_load_ss(&f));
  195. #else
  196.    return IROUND(f);
  197. #endif
  198. }
  199.  
  200.  
  201. /** Return (as an integer) floor of float */
  202. static inline int IFLOOR(float f)
  203. {
  204. #if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
  205.    /*
  206.     * IEEE floor for computers that round to nearest or even.
  207.     * 'f' must be between -4194304 and 4194303.
  208.     * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
  209.     * but uses some IEEE specific tricks for better speed.
  210.     * Contributed by Josh Vanderhoof
  211.     */
  212.    int ai, bi;
  213.    double af, bf;
  214.    af = (3 << 22) + 0.5 + (double)f;
  215.    bf = (3 << 22) + 0.5 - (double)f;
  216.    /* GCC generates an extra fstp/fld without this. */
  217.    __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
  218.    __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
  219.    return (ai - bi) >> 1;
  220. #else
  221.    int ai, bi;
  222.    double af, bf;
  223.    fi_type u;
  224.    af = (3 << 22) + 0.5 + (double)f;
  225.    bf = (3 << 22) + 0.5 - (double)f;
  226.    u.f = (float) af;  ai = u.i;
  227.    u.f = (float) bf;  bi = u.i;
  228.    return (ai - bi) >> 1;
  229. #endif
  230. }
  231.  
  232.  
  233. /** Return (as an integer) ceiling of float */
  234. static inline int ICEIL(float f)
  235. {
  236. #if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
  237.    /*
  238.     * IEEE ceil for computers that round to nearest or even.
  239.     * 'f' must be between -4194304 and 4194303.
  240.     * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
  241.     * but uses some IEEE specific tricks for better speed.
  242.     * Contributed by Josh Vanderhoof
  243.     */
  244.    int ai, bi;
  245.    double af, bf;
  246.    af = (3 << 22) + 0.5 + (double)f;
  247.    bf = (3 << 22) + 0.5 - (double)f;
  248.    /* GCC generates an extra fstp/fld without this. */
  249.    __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
  250.    __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
  251.    return (ai - bi + 1) >> 1;
  252. #else
  253.    int ai, bi;
  254.    double af, bf;
  255.    fi_type u;
  256.    af = (3 << 22) + 0.5 + (double)f;
  257.    bf = (3 << 22) + 0.5 - (double)f;
  258.    u.f = (float) af; ai = u.i;
  259.    u.f = (float) bf; bi = u.i;
  260.    return (ai - bi + 1) >> 1;
  261. #endif
  262. }
  263.  
  264.  
  265. /**
  266.  * Is x a power of two?
  267.  */
  268. static inline int
  269. _mesa_is_pow_two(int x)
  270. {
  271.    return !(x & (x - 1));
  272. }
  273.  
  274. /**
  275.  * Round given integer to next higer power of two
  276.  * If X is zero result is undefined.
  277.  *
  278.  * Source for the fallback implementation is
  279.  * Sean Eron Anderson's webpage "Bit Twiddling Hacks"
  280.  * http://graphics.stanford.edu/~seander/bithacks.html
  281.  *
  282.  * When using builtin function have to do some work
  283.  * for case when passed values 1 to prevent hiting
  284.  * undefined result from __builtin_clz. Undefined
  285.  * results would be different depending on optimization
  286.  * level used for build.
  287.  */
  288. static inline int32_t
  289. _mesa_next_pow_two_32(uint32_t x)
  290. {
  291. #ifdef HAVE___BUILTIN_CLZ
  292.         uint32_t y = (x != 1);
  293.         return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
  294. #else
  295.         x--;
  296.         x |= x >> 1;
  297.         x |= x >> 2;
  298.         x |= x >> 4;
  299.         x |= x >> 8;
  300.         x |= x >> 16;
  301.         x++;
  302.         return x;
  303. #endif
  304. }
  305.  
  306. static inline int64_t
  307. _mesa_next_pow_two_64(uint64_t x)
  308. {
  309. #ifdef HAVE___BUILTIN_CLZLL
  310.         uint64_t y = (x != 1);
  311.         STATIC_ASSERT(sizeof(x) == sizeof(long long));
  312.         return (1 + y) << ((__builtin_clzll(x - y) ^ 63));
  313. #else
  314.         x--;
  315.         x |= x >> 1;
  316.         x |= x >> 2;
  317.         x |= x >> 4;
  318.         x |= x >> 8;
  319.         x |= x >> 16;
  320.         x |= x >> 32;
  321.         x++;
  322.         return x;
  323. #endif
  324. }
  325.  
  326.  
  327. /*
  328.  * Returns the floor form of binary logarithm for a 32-bit integer.
  329.  */
  330. static inline GLuint
  331. _mesa_logbase2(GLuint n)
  332. {
  333. #ifdef HAVE___BUILTIN_CLZ
  334.    return (31 - __builtin_clz(n | 1));
  335. #else
  336.    GLuint pos = 0;
  337.    if (n >= 1<<16) { n >>= 16; pos += 16; }
  338.    if (n >= 1<< 8) { n >>=  8; pos +=  8; }
  339.    if (n >= 1<< 4) { n >>=  4; pos +=  4; }
  340.    if (n >= 1<< 2) { n >>=  2; pos +=  2; }
  341.    if (n >= 1<< 1) {           pos +=  1; }
  342.    return pos;
  343. #endif
  344. }
  345.  
  346.  
  347. /**
  348.  * Return 1 if this is a little endian machine, 0 if big endian.
  349.  */
  350. static inline GLboolean
  351. _mesa_little_endian(void)
  352. {
  353.    const GLuint ui = 1; /* intentionally not static */
  354.    return *((const GLubyte *) &ui);
  355. }
  356.  
  357.  
  358.  
  359. /**********************************************************************
  360.  * Functions
  361.  */
  362.  
  363. extern void *
  364. _mesa_align_malloc( size_t bytes, unsigned long alignment );
  365.  
  366. extern void *
  367. _mesa_align_calloc( size_t bytes, unsigned long alignment );
  368.  
  369. extern void
  370. _mesa_align_free( void *ptr );
  371.  
  372. extern void *
  373. _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
  374.                     unsigned long alignment);
  375.  
  376. extern void *
  377. _mesa_exec_malloc( GLuint size );
  378.  
  379. extern void
  380. _mesa_exec_free( void *addr );
  381.  
  382.  
  383. #ifndef FFS_DEFINED
  384. #define FFS_DEFINED 1
  385. #ifdef HAVE___BUILTIN_FFS
  386. #define ffs __builtin_ffs
  387. #else
  388. extern int ffs(int i);
  389. #endif
  390.  
  391. #ifdef HAVE___BUILTIN_FFSLL
  392. #define ffsll __builtin_ffsll
  393. #else
  394. extern int ffsll(long long int i);
  395. #endif
  396. #endif /* FFS_DEFINED */
  397.  
  398.  
  399. #ifdef HAVE___BUILTIN_POPCOUNT
  400. #define _mesa_bitcount(i) __builtin_popcount(i)
  401. #else
  402. extern unsigned int
  403. _mesa_bitcount(unsigned int n);
  404. #endif
  405.  
  406. #ifdef HAVE___BUILTIN_POPCOUNTLL
  407. #define _mesa_bitcount_64(i) __builtin_popcountll(i)
  408. #else
  409. extern unsigned int
  410. _mesa_bitcount_64(uint64_t n);
  411. #endif
  412.  
  413. /**
  414.  * Find the last (most significant) bit set in a word.
  415.  *
  416.  * Essentially ffs() in the reverse direction.
  417.  */
  418. static inline unsigned int
  419. _mesa_fls(unsigned int n)
  420. {
  421. #ifdef HAVE___BUILTIN_CLZ
  422.    return n == 0 ? 0 : 32 - __builtin_clz(n);
  423. #else
  424.    unsigned int v = 1;
  425.  
  426.    if (n == 0)
  427.       return 0;
  428.  
  429.    while (n >>= 1)
  430.        v++;
  431.  
  432.    return v;
  433. #endif
  434. }
  435.  
  436. /**
  437.  * Find the last (most significant) bit set in a uint64_t value.
  438.  *
  439.  * Essentially ffsll() in the reverse direction.
  440.  */
  441. static inline unsigned int
  442. _mesa_flsll(uint64_t n)
  443. {
  444. #ifdef HAVE___BUILTIN_CLZLL
  445.    return n == 0 ? 0 : 64 - __builtin_clzll(n);
  446. #else
  447.    unsigned int v = 1;
  448.  
  449.    if (n == 0)
  450.       return 0;
  451.  
  452.    while (n >>= 1)
  453.        v++;
  454.  
  455.    return v;
  456. #endif
  457. }
  458.  
  459.  
  460. extern GLhalfARB
  461. _mesa_float_to_half(float f);
  462.  
  463. extern float
  464. _mesa_half_to_float(GLhalfARB h);
  465.  
  466. static inline bool
  467. _mesa_half_is_negative(GLhalfARB h)
  468. {
  469.    return h & 0x8000;
  470. }
  471.  
  472. extern unsigned int
  473. _mesa_str_checksum(const char *str);
  474.  
  475. extern int
  476. _mesa_snprintf( char *str, size_t size, const char *fmt, ... ) PRINTFLIKE(3, 4);
  477.  
  478. extern int
  479. _mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list arg);
  480.  
  481.  
  482. #if defined(_MSC_VER) && !defined(snprintf)
  483. #define snprintf _snprintf
  484. #endif
  485.  
  486.  
  487. #ifdef __cplusplus
  488. }
  489. #endif
  490.  
  491.  
  492. #endif /* IMPORTS_H */
  493.