Subversion Repositories shark

Rev

Rev 55 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
55 pj 1
/* $Id: mmath.c,v 1.1 2003-02-28 11:42:03 pj 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
}