home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / mmath.cpp < prev    next >
C/C++ Source or Header  |  2002-10-25  |  5KB  |  179 lines

  1. /* $Id: mmath.c,v 1.13 2002/10/25 21:06:30 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.5
  6.  *
  7.  * Copyright (C) 1999-2001  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. #include "glheader.h"
  29. #include "mmath.h"
  30.  
  31.  
  32. static int in_fast_math;
  33.  
  34. /*
  35.  * A High Speed, Low Precision Square Root
  36.  * by Paul Lalonde and Robert Dawson
  37.  * from "Graphics Gems", Academic Press, 1990
  38.  */
  39.  
  40. /*
  41.  * SPARC implementation of a fast square root by table
  42.  * lookup.
  43.  * SPARC floating point format is as follows:
  44.  *
  45.  * BIT 31     30     23     22     0
  46.  *     sign    exponent    mantissa
  47.  */
  48. static short sqrttab[0x100];    /* declare table of square roots */
  49.  
  50. static void init_sqrt(void)
  51. {
  52. #ifdef FAST_MATH
  53.    unsigned short i;
  54.    fi_type fi;     /* to access the bits of a float in  C quickly  */
  55.                    /* we use a union defined in glheader.h         */
  56.  
  57.    for(i=0; i<= 0x7f; i++) {
  58.       fi.i = 0;
  59.  
  60.       /*
  61.        * Build a float with the bit pattern i as mantissa
  62.        * and an exponent of 0, stored as 127
  63.        */
  64.  
  65.       fi.i = (i << 16) | (127 << 23);
  66.       fi.f = _mesa_sqrt(fi.f);
  67.  
  68.       /*
  69.        * Take the square root then strip the first 7 bits of
  70.        * the mantissa into the table
  71.        */
  72.  
  73.       sqrttab[i] = (fi.i & 0x7fffff) >> 16;
  74.  
  75.       /*
  76.        * Repeat the process, this time with an exponent of
  77.        * 1, stored as 128
  78.        */
  79.  
  80.       fi.i = 0;
  81.       fi.i = (i << 16) | (128 << 23);
  82.       fi.f = sqrt(fi.f);
  83.       sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
  84.    }
  85. #else
  86.    (void) sqrttab;  /* silence compiler warnings */
  87. #endif /*FAST_MATH*/
  88. }
  89.  
  90.  
  91. float gl_sqrt( float x )
  92. {
  93. #ifdef FAST_MATH
  94.    fi_type num;
  95.                                 /* to access the bits of a float in C
  96.                                  * we use a union from glheader.h     */
  97.  
  98.    short e;                     /* the exponent */
  99.    if (x == 0.0F) return 0.0F;  /* check for square root of 0 */
  100.    num.f = x;
  101.    e = (num.i >> 23) - 127;     /* get the exponent - on a SPARC the */
  102.                                 /* exponent is stored with 127 added */
  103.    num.i &= 0x7fffff;           /* leave only the mantissa */
  104.    if (e & 0x01) num.i |= 0x800000;
  105.                                 /* the exponent is odd so we have to */
  106.                                 /* look it up in the second half of  */
  107.                                 /* the lookup table, so we set the   */
  108.                                 /* high bit                                */
  109.    e >>= 1;                     /* divide the exponent by two */
  110.                                 /* note that in C the shift */
  111.                                 /* operators are sign preserving */
  112.                                 /* for signed operands */
  113.    /* Do the table lookup, based on the quaternary mantissa,
  114.     * then reconstruct the result back into a float
  115.     */
  116.    num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
  117.    return num.f;
  118. #else
  119.    return (GLfloat) _mesa_sqrt(x);
  120. #endif
  121. }
  122.  
  123.  
  124. /* ubyte -> float conversion */
  125. float _mesa_ubyte_to_float_color_tab[256];
  126.  
  127.  
  128. /*
  129.  * Initialize tables, etc for fast math functions.
  130.  */
  131. void
  132. _mesa_init_math(void)
  133. {
  134.    static GLboolean initialized = GL_FALSE;
  135.  
  136.    if (!initialized) {
  137.       int i;
  138.       for (i = 0; i < 256; i++) {
  139.          _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
  140.       }
  141.  
  142.       init_sqrt();
  143.  
  144.       initialized = GL_TRUE;
  145.       in_fast_math = 0;
  146.  
  147. #if defined(_FPU_GETCW) && defined(_FPU_SETCW)
  148.       {
  149.          const char *debug = _mesa_getenv("MESA_DEBUG");
  150.          if (debug && _mesa_strcmp(debug, "FP")==0) {
  151.             /* die on FP exceptions */
  152.             fpu_control_t mask;
  153.             _FPU_GETCW(mask);
  154.             mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
  155.                       | _FPU_MASK_OM | _FPU_MASK_UM);
  156.             _FPU_SETCW(mask);
  157.          }
  158.       }
  159. #endif
  160.    }
  161. }
  162.  
  163.  
  164.  
  165. /*
  166.  * Return number of bits set in given GLuint.
  167.  */
  168. GLuint
  169. _mesa_bitcount(GLuint n)
  170. {
  171.    GLuint bits;
  172.    for (bits = 0; n > 0; n = n >> 1) {
  173.       if (n & 1) {
  174.          bits++;
  175.       }
  176.    }
  177.    return bits;
  178. }
  179.