home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / mmath.h < prev    next >
C/C++ Source or Header  |  2002-12-15  |  20KB  |  683 lines

  1. /* $Id: mmath.h,v 1.65 2002/12/01 14:01:22 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.0.1
  6.  *
  7.  * Copyright (C) 1999-2002 Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Faster arithmetic functions.  If the FAST_MATH preprocessor symbol is
  30.  * defined on the command line (-DFAST_MATH) then we'll use some (hopefully)
  31.  * faster functions for sqrt(), etc.
  32.  */
  33.  
  34.  
  35. #ifndef MMATH_H
  36. #define MMATH_H
  37.  
  38.  
  39. #include "glheader.h"
  40. #include "imports.h"
  41. /* Do not reference mtypes.h from this file.
  42.  */
  43.  
  44. /*
  45.  * Set the x86 FPU control word to guarentee only 32 bits of presision
  46.  * are stored in registers.  Allowing the FPU to store more introduces
  47.  * differences between situations where numbers are pulled out of memory
  48.  * vs. situations where the compiler is able to optimize register usage.
  49.  *
  50.  * In the worst case, we force the compiler to use a memory access to
  51.  * truncate the float, by specifying the 'volatile' keyword.
  52.  */
  53. #if defined(__GNUC__) && defined(__i386__)
  54.  
  55. /* Hardware default: All exceptions masked, extended double precision,
  56.  * round to nearest.  IEEE compliant.
  57.  */
  58. #define DEFAULT_X86_FPU        0x037f
  59.  
  60. /* All exceptions masked, single precision, round to nearest.
  61.  */
  62. #define FAST_X86_FPU        0x003f
  63.  
  64. /* Set it up how we want it.  The fldcw instruction will cause any
  65.  * pending FP exceptions to be raised prior to entering the block, and
  66.  * we clear any pending exceptions before exiting the block.  Hence, asm
  67.  * code has free reign over the FPU while in the fast math block.
  68.  */
  69. #if defined(NO_FAST_MATH)
  70. #define START_FAST_MATH(x)                        \
  71. do {                                    \
  72.    static GLuint mask = DEFAULT_X86_FPU;                \
  73.    __asm__ ( "fnstcw %0" : "=m" (*&(x)) );                \
  74.    __asm__ ( "fldcw %0" : : "m" (mask) );                \
  75. } while (0)
  76. #else
  77. #define START_FAST_MATH(x)                        \
  78. do {                                    \
  79.    static GLuint mask = FAST_X86_FPU;                    \
  80.    __asm__ ( "fnstcw %0" : "=m" (*&(x)) );                \
  81.    __asm__ ( "fldcw %0" : : "m" (mask) );                \
  82. } while (0)
  83. #endif
  84.  
  85. /* Put it back how the application had it, and clear any exceptions that
  86.  * may have occurred in the FAST_MATH block.
  87.  */
  88. #define END_FAST_MATH(x)                        \
  89. do {                                    \
  90.    __asm__ ( "fnclex ; fldcw %0" : : "m" (*&(x)) );            \
  91. } while (0)
  92.  
  93. #define HAVE_FAST_MATH
  94.  
  95. #elif defined(__WATCOMC__) && !defined(NO_FAST_MATH)
  96.  
  97. /* This is the watcom specific inline assembly version of setcw and getcw */
  98.  
  99. void START_FAST_MATH2(unsigned short *x);
  100. #pragma aux START_FAST_MATH2 =          \
  101.     "fstcw   word ptr [esi]"            \
  102.     "or      word ptr [esi], 0x3f"      \
  103.     "fldcw   word ptr [esi]"            \
  104.     parm [esi]                          \
  105.     modify exact [];
  106.  
  107. void END_FAST_MATH2(unsigned short *x);
  108. #pragma aux END_FAST_MATH2 =            \
  109.     "fldcw   word ptr [esi]"            \
  110.     parm [esi]                          \
  111.     modify exact [];
  112.  
  113. #define START_FAST_MATH(x)  START_FAST_MATH2(& x)
  114. #define END_FAST_MATH(x)  END_FAST_MATH2(& x)
  115.  
  116. /*
  117. __inline START_FAST_MATH(unsigned short x)
  118.     {
  119.     _asm {
  120.         fstcw   ax
  121.         mov     x , ax
  122.         or      ax, 0x3f
  123.         fldcw   ax
  124.         }
  125.     }
  126.  
  127. __inline END_FAST_MATH(unsigned short x)
  128.     {
  129.     _asm {
  130.         fldcw   x
  131.         }
  132.     }
  133. */
  134. #define HAVE_FAST_MATH
  135.  
  136. #else
  137. #define START_FAST_MATH(x) x = 0
  138. #define END_FAST_MATH(x)   (void)(x)
  139.  
  140. /* The mac float really is a float, with the same precision as a
  141.  * single precision 387 float.
  142.  */
  143. #if defined(macintosh) || defined(__powerpc__)
  144. #define HAVE_FAST_MATH
  145. #endif
  146.  
  147. #endif
  148.  
  149.  
  150.  
  151. /*
  152.  * Square root
  153.  */
  154.  
  155. extern float gl_sqrt(float x);
  156.  
  157. #ifdef FAST_MATH
  158. #if defined(__WATCOMC__) && defined(USE_X86_ASM)
  159. #  define GL_SQRT(X)  asm_sqrt(X)
  160. #else
  161. #  define GL_SQRT(X)  gl_sqrt(X)
  162. #endif
  163. #else
  164. #  define GL_SQRT(X)  sqrt(X)
  165. #endif
  166.  
  167.  
  168. /*
  169.  * Normalize a 3-element vector to unit length.
  170.  */
  171. #define NORMALIZE_3FV( V )            \
  172. {                        \
  173.    GLfloat len = (GLfloat) LEN_SQUARED_3FV(V);    \
  174.    if (len) {                    \
  175.       len = (GLfloat) (1.0 / GL_SQRT(len));    \
  176.       (V)[0] = (GLfloat) ((V)[0] * len);    \
  177.       (V)[1] = (GLfloat) ((V)[1] * len);    \
  178.       (V)[2] = (GLfloat) ((V)[2] * len);    \
  179.    }                        \
  180. }
  181.  
  182. #define LEN_3FV( V ) (GL_SQRT((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2]))
  183. #define LEN_2FV( V ) (GL_SQRT((V)[0]*(V)[0]+(V)[1]*(V)[1]))
  184.  
  185. #define LEN_SQUARED_3FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2])
  186. #define LEN_SQUARED_2FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1])
  187.  
  188.  
  189. /*
  190.  * Single precision ceiling, floor, and absolute value functions
  191.  */
  192. #if defined(__sparc__) /* XXX this probably isn't the ideal test */
  193. #define CEILF(x)   ceil(x)
  194. #define FLOORF(x)  floor(x)
  195. #define FABSF(x)   fabs(x)
  196. #elif defined(__WIN32__) || defined(__IBMC__) || defined(__IBMCPP__)
  197. #define CEILF(x)   ((GLfloat)ceil(x))
  198. #define FLOORF(x)  ((GLfloat)floor(x))
  199. #define FABSF(x)   ((GLfloat)fabs(x))
  200. #elif defined(XFree86LOADER) && defined(IN_MODULE)
  201. #define CEILF(x)   ((GLfloat) xf86ceil(x))
  202. #define FLOORF(x)  ((GLfloat) xf86floor(x))
  203. #define FABSF(x)   ((GLfloat) xf86fabs(x))
  204. #else
  205. #define CEILF(x)   ceilf(x)
  206. #define FLOORF(x)  floorf(x)
  207. #define FABSF(x)   fabsf(x)
  208. #endif
  209.  
  210.  
  211. #if defined(__i386__) || defined(__sparc__) || defined(__s390x__) || \
  212.     defined(__powerpc__) || \
  213.     ( defined(__alpha__) && ( defined(__IEEE_FLOAT) || !defined(VMS) ) )
  214. #define USE_IEEE
  215. #endif
  216.  
  217.  
  218.  
  219. #define GET_FLOAT_BITS(x) ((fi_type *) &(x))->i
  220.  
  221. /*
  222.  * Float -> Int conversions (rounding, floor, ceiling)
  223.  */
  224.  
  225. #if defined(USE_SPARC_ASM) && defined(__GNUC__) && defined(__sparc__)
  226.  
  227. static INLINE int iround(float f)
  228. {
  229.        int r;
  230.        __asm__ ("fstoi %1, %0" : "=f" (r) : "f" (f));
  231.        return r;
  232. }
  233.  
  234. #define IROUND(x)  iround(x)
  235.  
  236. #elif defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
  237.  
  238.  
  239. static INLINE int iround(float f)
  240. {
  241.    int r;
  242.    __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
  243.    return r;
  244. }
  245.  
  246. #define IROUND(x)  iround(x)
  247.  
  248. /*
  249.  * IEEE floor for computers that round to nearest or even.
  250.  * 'f' must be between -4194304 and 4194303.
  251.  * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
  252.  * but uses some IEEE specific tricks for better speed.
  253.  * Contributed by Josh Vanderhoof
  254.  */
  255. static INLINE int ifloor(float f)
  256. {
  257.    int ai, bi;
  258.    double af, bf;
  259.    af = (3 << 22) + 0.5 + (double)f;
  260.    bf = (3 << 22) + 0.5 - (double)f;
  261.    /* GCC generates an extra fstp/fld without this. */
  262.    __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
  263.    __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
  264.    return (ai - bi) >> 1;
  265. }
  266.  
  267. #define IFLOOR(x)  ifloor(x)
  268.  
  269. /*
  270.  * IEEE ceil for computers that round to nearest or even.
  271.  * 'f' must be between -4194304 and 4194303.
  272.  * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
  273.  * but uses some IEEE specific tricks for better speed.
  274.  * Contributed by Josh Vanderhoof
  275.  */
  276. static INLINE int iceil(float f)
  277. {
  278.    int ai, bi;
  279.    double af, bf;
  280.    af = (3 << 22) + 0.5 + (double)f;
  281.    bf = (3 << 22) + 0.5 - (double)f;
  282.    /* GCC generates an extra fstp/fld without this. */
  283.    __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
  284.    __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
  285.    return (ai - bi + 1) >> 1;
  286. }
  287.  
  288. #define ICEIL(x)  iceil(x)
  289.  
  290.  
  291. #elif defined(USE_X86_ASM) && defined(__MSC__) && defined(__WIN32__)
  292.  
  293.  
  294. static INLINE int iround(float f)
  295. {
  296.    int r;
  297.    _asm {
  298.      fld f
  299.      fistp r
  300.     }
  301.    return r;
  302. }
  303.  
  304. #define IROUND(x)  iround(x)
  305.  
  306.  
  307. #elif defined(USE_X86_ASM) && defined(__WATCOMC__)
  308.  
  309.  
  310. long iround(float f);
  311. #pragma aux iround =                        \
  312.     "push   eax"                        \
  313.     "fistp  dword ptr [esp]"            \
  314.     "pop    eax"                        \
  315.     parm [8087]                         \
  316.     value [eax]                         \
  317.     modify exact [eax];
  318.  
  319. #define IROUND(x)  iround(x)
  320.  
  321. float asm_sqrt (float x);
  322. #pragma aux asm_sqrt =                      \
  323.     "fsqrt"                             \
  324.     parm [8087]                         \
  325.     value [8087]                        \
  326.     modify exact [];
  327.  
  328.  
  329. #endif /* assembly/optimized IROUND, IROUND_POS, IFLOOR, ICEIL macros */
  330.  
  331.  
  332. /* default IROUND macro */
  333. #ifndef IROUND
  334. #define IROUND(f)  ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
  335. #endif
  336.  
  337.  
  338. /* default IROUND_POS macro */
  339. #ifndef IROUND_POS
  340. #ifdef DEBUG
  341. #define IROUND_POS(f) (ASSERT((f) >= 0.0F), IROUND(f))
  342. #else
  343. #define IROUND_POS(f) (IROUND(f))
  344. #endif
  345. #endif /* IROUND_POS */
  346.  
  347.  
  348. /* default IFLOOR macro */
  349. #ifndef IFLOOR
  350. static INLINE int ifloor(float f)
  351. {
  352. #ifdef USE_IEEE
  353.    int ai, bi;
  354.    double af, bf;
  355.    union { int i; float f; } u;
  356.  
  357.    af = (3 << 22) + 0.5 + (double)f;
  358.    bf = (3 << 22) + 0.5 - (double)f;
  359.    u.f = af; ai = u.i;
  360.    u.f = bf; bi = u.i;
  361.    return (ai - bi) >> 1;
  362. #else
  363.    int i = IROUND(f);
  364.    return (i > f) ? i - 1 : i;
  365. #endif
  366. }
  367. #define IFLOOR(x)  ifloor(x)
  368. #endif /* IFLOOR */
  369.  
  370.  
  371. /* default ICEIL macro */
  372. #ifndef ICEIL
  373. static INLINE int iceil(float f)
  374. {
  375. #ifdef USE_IEEE
  376.    int ai, bi;
  377.    double af, bf;
  378.    union { int i; float f; } u;
  379.    af = (3 << 22) + 0.5 + (double)f;
  380.    bf = (3 << 22) + 0.5 - (double)f;
  381.    u.f = af; ai = u.i;
  382.    u.f = bf; bi = u.i;
  383.    return (ai - bi + 1) >> 1;
  384. #else
  385.    int i = IROUND(f);
  386.    return (i < f) ? i + 1 : i;
  387. #endif
  388. }
  389. #define ICEIL(x)  iceil(x)
  390. #endif /* ICEIL */
  391.  
  392.  
  393.  
  394. /*
  395.  * Convert unclamped or clamped ([0,1]) floats to ubytes for color
  396.  * conversion only.  These functions round to the nearest int.
  397.  */
  398. #define IEEE_ONE 0x3f800000
  399. #define IEEE_0996 0x3f7f0000    /* 0.996 or something??? used in macro
  400.                                    below only */
  401.  
  402. #if defined(USE_IEEE) && !defined(DEBUG)
  403.  
  404. /*
  405.  * This function/macro is sensitive to precision.  Test carefully
  406.  * if you change it.
  407.  */
  408. #define UNCLAMPED_FLOAT_TO_UBYTE(ub, f)                    \
  409.         {                                \
  410.            union { GLfloat r; GLuint i; } __tmp;            \
  411.            __tmp.r = (f);                        \
  412.            ub = ((__tmp.i >= IEEE_0996)                    \
  413.                ? ((GLint)__tmp.i < 0) ? (GLubyte)0 : (GLubyte)255    \
  414.                : (__tmp.r = __tmp.r*(255.0F/256.0F) + 32768.0F,        \
  415.                   (GLubyte)__tmp.i));                    \
  416.         }
  417.  
  418. #define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
  419.         UNCLAMPED_FLOAT_TO_UBYTE(ub, f)
  420.  
  421. #define COPY_FLOAT( dst, src )                    \
  422.     ((fi_type *) &(dst))->i = ((fi_type *) &(src))->i
  423.  
  424. #else /* USE_IEEE */
  425.  
  426. #define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
  427.     ub = ((GLubyte) IROUND(CLAMP((f), 0.0F, 1.0F) * 255.0F))
  428.  
  429. #define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
  430.     ub = ((GLubyte) IROUND((f) * 255.0F))
  431.  
  432. #define COPY_FLOAT( dst, src )        (dst) = (src)
  433.  
  434. #endif /* USE_IEEE */
  435.  
  436.  
  437.  
  438. /*
  439.  * Integer / float conversion for colors, normals, etc.
  440.  */
  441.  
  442. /* Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
  443. extern float _mesa_ubyte_to_float_color_tab[256];
  444. #define UBYTE_TO_FLOAT(u) _mesa_ubyte_to_float_color_tab[(unsigned int)(u)]
  445.  
  446. /* Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */
  447. #define FLOAT_TO_UBYTE(X)    ((GLubyte) (GLint) ((X) * 255.0F))
  448.  
  449.  
  450. /* Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
  451. #define BYTE_TO_FLOAT(B)    ((2.0F * (B) + 1.0F) * (1.0F/255.0F))
  452.  
  453. /* Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */
  454. #define FLOAT_TO_BYTE(X)    ( (((GLint) (255.0F * (X))) - 1) / 2 )
  455.  
  456.  
  457. /* Convert GLushort in [0,65536] to GLfloat in [0.0,1.0] */
  458. #define USHORT_TO_FLOAT(S)    ((GLfloat) (S) * (1.0F / 65535.0F))
  459.  
  460. /* Convert GLfloat in [0.0,1.0] to GLushort in [0,65536] */
  461. #define FLOAT_TO_USHORT(X)    ((GLushort) (GLint) ((X) * 65535.0F))
  462.  
  463.  
  464. /* Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
  465. #define SHORT_TO_FLOAT(S)    ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
  466.  
  467. /* Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */
  468. #define FLOAT_TO_SHORT(X)    ( (((GLint) (65535.0F * (X))) - 1) / 2 )
  469.  
  470.  
  471. /* Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
  472. #define UINT_TO_FLOAT(U)    ((GLfloat) (U) * (1.0F / 4294967295.0F))
  473.  
  474. /* Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
  475. #define FLOAT_TO_UINT(X)    ((GLuint) ((X) * 4294967295.0))
  476.  
  477.  
  478. /* Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
  479. #define INT_TO_FLOAT(I)        ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F))
  480.  
  481. /* Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
  482. /* causes overflow:
  483. #define FLOAT_TO_INT(X)        ( (((GLint) (4294967294.0F * (X))) - 1) / 2 )
  484. */
  485. /* a close approximation: */
  486. #define FLOAT_TO_INT(X)        ( (GLint) (2147483647.0 * (X)) )
  487.  
  488.  
  489. #define BYTE_TO_UBYTE(b)   ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
  490. #define SHORT_TO_UBYTE(s)  ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
  491. #define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
  492. #define INT_TO_UBYTE(i)    ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23)))
  493. #define UINT_TO_UBYTE(i)   ((GLubyte) ((i) >> 24))
  494.  
  495.  
  496. #define BYTE_TO_USHORT(b)  ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255)))
  497. #define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b))
  498. #define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767))))
  499. #define INT_TO_USHORT(i)   ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
  500. #define UINT_TO_USHORT(i)  ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
  501. #define UNCLAMPED_FLOAT_TO_USHORT(us, f)  \
  502.         us = ( (GLushort) IROUND( CLAMP((f), 0.0, 1.0) * 65535.0F) )
  503. #define CLAMPED_FLOAT_TO_USHORT(us, f)  \
  504.         us = ( (GLushort) IROUND( (f) * 65535.0F) )
  505.  
  506.  
  507.  
  508. /*
  509.  * Linear interpolation
  510.  * NOTE:  OUT argument is evaluated twice!
  511.  * NOTE:  Be wary of using *coord++ as an argument to any of these macros!
  512.  */
  513. #define LINTERP(T, OUT, IN)    ((OUT) + (T) * ((IN) - (OUT)))
  514.  
  515. /* Can do better with integer math:
  516.  */
  517. #define INTERP_UB( t, dstub, outub, inub )    \
  518. {                        \
  519.    GLfloat inf = UBYTE_TO_FLOAT( inub );    \
  520.    GLfloat outf = UBYTE_TO_FLOAT( outub );    \
  521.    GLfloat dstf = LINTERP( t, outf, inf );    \
  522.    UNCLAMPED_FLOAT_TO_UBYTE( dstub, dstf );    \
  523. }
  524.  
  525. #define INTERP_CHAN( t, dstc, outc, inc )    \
  526. {                        \
  527.    GLfloat inf = CHAN_TO_FLOAT( inc );        \
  528.    GLfloat outf = CHAN_TO_FLOAT( outc );    \
  529.    GLfloat dstf = LINTERP( t, outf, inf );    \
  530.    UNCLAMPED_FLOAT_TO_CHAN( dstc, dstf );    \
  531. }
  532.  
  533. #define INTERP_UI( t, dstui, outui, inui )    \
  534.    dstui = (GLuint) (GLint) LINTERP( (t), (GLfloat) (outui), (GLfloat) (inui) )
  535.  
  536. #define INTERP_F( t, dstf, outf, inf )        \
  537.    dstf = LINTERP( t, outf, inf )
  538.  
  539. #define INTERP_4F( t, dst, out, in )        \
  540. {                        \
  541.    dst[0] = LINTERP( (t), (out)[0], (in)[0] );    \
  542.    dst[1] = LINTERP( (t), (out)[1], (in)[1] );    \
  543.    dst[2] = LINTERP( (t), (out)[2], (in)[2] );    \
  544.    dst[3] = LINTERP( (t), (out)[3], (in)[3] );    \
  545. }
  546.  
  547. #define INTERP_3F( t, dst, out, in )        \
  548. {                        \
  549.    dst[0] = LINTERP( (t), (out)[0], (in)[0] );    \
  550.    dst[1] = LINTERP( (t), (out)[1], (in)[1] );    \
  551.    dst[2] = LINTERP( (t), (out)[2], (in)[2] );    \
  552. }
  553.  
  554. #define INTERP_4CHAN( t, dst, out, in )            \
  555. {                            \
  556.    INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] );    \
  557.    INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] );    \
  558.    INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] );    \
  559.    INTERP_CHAN( (t), (dst)[3], (out)[3], (in)[3] );    \
  560. }
  561.  
  562. #define INTERP_3CHAN( t, dst, out, in )            \
  563. {                            \
  564.    INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] );    \
  565.    INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] );    \
  566.    INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] );    \
  567. }
  568.  
  569. #define INTERP_SZ( t, vec, to, out, in, sz )                \
  570. {                                    \
  571.    switch (sz) {                            \
  572.    case 4: vec[to][3] = LINTERP( (t), (vec)[out][3], (vec)[in][3] );    \
  573.    case 3: vec[to][2] = LINTERP( (t), (vec)[out][2], (vec)[in][2] );    \
  574.    case 2: vec[to][1] = LINTERP( (t), (vec)[out][1], (vec)[in][1] );    \
  575.    case 1: vec[to][0] = LINTERP( (t), (vec)[out][0], (vec)[in][0] );    \
  576.    }                                    \
  577. }
  578.  
  579.  
  580. /*
  581.  * Fixed point arithmetic macros
  582.  */
  583. #ifdef FIXED_14
  584. #define FIXED_ONE       0x00004000
  585. #define FIXED_HALF      0x00002000
  586. #define FIXED_FRAC_MASK 0x00003FFF
  587. #define FIXED_SCALE     16384.0f
  588. #define FIXED_SHIFT     14
  589. #else
  590. #define FIXED_ONE       0x00000800
  591. #define FIXED_HALF      0x00000400
  592. #define FIXED_FRAC_MASK 0x000007FF
  593. #define FIXED_SCALE     2048.0f
  594. #define FIXED_SHIFT     11
  595. #endif
  596. #define FIXED_INT_MASK  (~FIXED_FRAC_MASK)
  597. #define FIXED_EPSILON   1
  598. #define FloatToFixed(X) (IROUND((X) * FIXED_SCALE))
  599. #define IntToFixed(I)   ((I) << FIXED_SHIFT)
  600. #define FixedToInt(X)   ((X) >> FIXED_SHIFT)
  601. #define FixedToUns(X)   (((unsigned int)(X)) >> FIXED_SHIFT)
  602. #define FixedCeil(X)    (((X) + FIXED_ONE - FIXED_EPSILON) & FIXED_INT_MASK)
  603. #define FixedFloor(X)   ((X) & FIXED_INT_MASK)
  604. #define FixedToFloat(X) ((X) * (1.0F / FIXED_SCALE))
  605. #define PosFloatToFixed(X)      FloatToFixed(X)
  606. #define SignedFloatToFixed(X)   FloatToFixed(X)
  607.  
  608. /* Returns TRUE for x == Inf or x == NaN. */
  609. #ifdef USE_IEEE
  610. static INLINE int IS_INF_OR_NAN( float x )
  611. {
  612.    union {float f; int i;} tmp;
  613.    tmp.f = x;
  614.    return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31);
  615. }
  616. #elif defined(isfinite)
  617. #define IS_INF_OR_NAN(x)        (!isfinite(x))
  618. #elif defined(finite)
  619. #define IS_INF_OR_NAN(x)        (!finite(x))
  620. #elif __VMS
  621. #define IS_INF_OR_NAN(x)        (!finite(x))
  622. #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
  623. #define IS_INF_OR_NAN(x)        (!isfinite(x))
  624. #else
  625. #define IS_INF_OR_NAN(x)        (!finite(x))
  626. #endif 
  627.  
  628.  
  629. /*
  630.  * Return log_base_2(x).
  631.  */
  632. #ifdef USE_IEEE
  633.  
  634. #if 0
  635. /* This is pretty fast, but not accurate enough (only 2 fractional bits).
  636.  * Based on code from http://www.stereopsis.com/log2.html
  637.  */
  638. static INLINE GLfloat LOG2(GLfloat x)
  639. {
  640.    const GLfloat y = x * x * x * x;
  641.    const GLuint ix = *((GLuint *) &y);
  642.    const GLuint exp = (ix >> 23) & 0xFF;
  643.    const GLint log2 = ((GLint) exp) - 127;
  644.    return (GLfloat) log2 * (1.0 / 4.0);  /* 4, because of x^4 above */
  645. }
  646. #endif
  647.  
  648. /* Pretty fast, and accurate.
  649.  * Based on code from http://www.flipcode.com/totd/
  650.  */
  651. static INLINE GLfloat LOG2(GLfloat val)
  652. {
  653.    GLint *exp_ptr = (GLint *) &val;
  654.    GLint x = *exp_ptr;
  655.    const GLint log_2 = ((x >> 23) & 255) - 128;
  656.    x &= ~(255 << 23);
  657.    x += 127 << 23;
  658.    *exp_ptr = x;
  659.    val = ((-1.0f/3) * val + 2) * val - 2.0f/3;
  660.    return val + log_2;
  661. }
  662.  
  663. #else /* USE_IEEE */
  664.  
  665. /* Slow, portable solution.
  666.  * NOTE: log_base_2(x) = log(x) / log(2)
  667.  * NOTE: 1.442695 = 1/log(2).
  668.  */
  669. #define LOG2(x)  ((GLfloat) (log(x) * 1.442695F))
  670.  
  671. #endif /* USE_IEEE */
  672.  
  673.  
  674. extern void
  675. _mesa_init_math(void);
  676.  
  677.  
  678. extern GLuint
  679. _mesa_bitcount(GLuint n);
  680.  
  681.  
  682. #endif
  683.