source: trunk/src/opengl/mesa/mmath.h@ 2938

Last change on this file since 2938 was 2938, checked in by sandervl, 25 years ago

created

File size: 7.8 KB
Line 
1/* $Id: mmath.h,v 1.1 2000-02-29 00:48:34 sandervl Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 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/* $XFree86: xc/lib/GL/mesa/src/mmath.h,v 1.2 1999/04/04 00:20:28 dawes Exp $ */
27
28
29
30
31
32/*
33 * Faster arithmetic functions. If the FAST_MATH preprocessor symbol is
34 * defined on the command line (-DFAST_MATH) then we'll use some (hopefully)
35 * faster functions for sqrt(), etc.
36 */
37
38
39#ifndef MMATH_H
40#define MMATH_H
41
42#ifdef HAVE_CONFIG_H
43#include "conf.h"
44#endif
45
46#ifndef XFree86Server
47#include <math.h>
48#else
49#include "GL/xf86glx.h"
50#endif
51
52/*
53 * Set the x86 FPU control word to guarentee only 32 bits of presision
54 * are stored in registers. Allowing the FPU to store more introduces
55 * differences between situations where numbers are pulled out of memory
56 * vs. situations where the compiler is able to optimize register usage.
57 *
58 * In the worst case, we force the compiler to use a memory access to
59 * truncate the float, by specifying the 'volatile' keyword.
60 */
61#if defined(__linux__) && defined(__i386__)
62#include <fpu_control.h>
63
64#if !defined(_FPU_SETCW)
65#define _FPU_SETCW __setfpucw
66typedef unsigned short fpu_control_t;
67#endif
68
69#if !defined(_FPU_GETCW)
70#define _FPU_GETCW(a) (a) = __fpu_control;
71#endif
72
73/* Set it up how we want it.
74 */
75#if !defined(NO_FAST_MATH)
76#define START_FAST_MATH(x) \
77 { \
78 static fpu_control_t mask = _FPU_SINGLE | _FPU_MASK_IM \
79 | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM \
80 | _FPU_MASK_UM | _FPU_MASK_PM; \
81 _FPU_GETCW( x ); \
82 _FPU_SETCW( mask ); \
83 }
84#else
85#define START_FAST_MATH(x) \
86 { \
87 static fpu_control_t mask = _FPU_DEFAULT; \
88 _FPU_GETCW( x ); \
89 _FPU_SETCW( mask ); \
90 }
91#endif
92
93/* Put it back how the application had it.
94 */
95#define END_FAST_MATH(x) \
96 { \
97 _FPU_SETCW( x ); \
98 }
99
100#define HAVE_FAST_MATH
101
102#else
103#define START_FAST_MATH(x) (void)(x)
104#define END_FAST_MATH(x) (void)(x)
105
106/* The mac float really is a float, with the same precision as a
107 * single precision 387 float.
108 */
109#if defined(macintosh)
110#define HAVE_FAST_MATH
111#endif
112
113#endif
114
115
116
117/*
118 * Float -> Int conversion
119 */
120
121#if defined(USE_X86_ASM)
122#if defined(__GNUC__) && defined(__i386__)
123static __inline__ int FloatToInt(float f)
124{
125 int r;
126 __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
127 return r;
128}
129#elif defined(__MSC__) && defined(__WIN32__)
130static __inline int FloatToInt(float f)
131{
132 int r;
133 _asm {
134 fld f
135 fistp r
136 }
137 return r;
138}
139#elif defined(__WIN32OS2__)
140#define FloatToInt(F) ((int) (F))
141#endif
142#else
143#define FloatToInt(F) ((int) (F))
144#endif
145
146
147
148
149
150/*
151 * Square root
152 */
153
154extern float gl_sqrt(float x);
155
156#ifdef FAST_MATH
157# define GL_SQRT(X) gl_sqrt(X)
158#else
159# define GL_SQRT(X) sqrt(X)
160#endif
161
162
163
164/*
165 * Normalize a 3-element vector to unit length.
166 */
167#define NORMALIZE_3FV( V ) \
168do { \
169 GLdouble len = LEN_SQUARED_3FV(V); \
170 if (len > 1e-50) { \
171 len = 1.0 / GL_SQRT(len); \
172 V[0] = (GLfloat) (V[0] * len); \
173 V[1] = (GLfloat) (V[1] * len); \
174 V[2] = (GLfloat) (V[2] * len); \
175 } \
176} while(0)
177
178#define LEN_3FV( V ) (GL_SQRT(V[0]*V[0]+V[1]*V[1]+V[2]*V[2]))
179
180#define LEN_SQUARED_3FV( V ) (V[0]*V[0]+V[1]*V[1]+V[2]*V[2])
181
182/*
183 * Optimization for:
184 * GLfloat f;
185 * GLubyte b = FloatToInt(CLAMP(f, 0, 1) * 255)
186 */
187
188#if defined(__i386__) || defined(__sparc__)
189#define USE_IEEE
190#endif
191
192#if defined(USE_IEEE) && !defined(DEBUG)
193
194#define IEEE_ONE 0x3f7f0000
195
196#define CLAMP_FLOAT_COLOR(f) \
197 do { \
198 if (*(GLuint *)&f >= IEEE_ONE) \
199 f = (*(GLint *)&f < 0) ? 0 : 1; \
200 } while(0)
201
202#define CLAMP_FLOAT_COLOR_VALUE(f) \
203 ( (*(GLuint *)&f >= IEEE_ONE) \
204 ? ((*(GLint *)&f < 0) ? 0 : 1) \
205 : f )
206
207/*
208 * This function/macro is sensitive to precision. Test carefully
209 * if you change it.
210 */
211#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \
212 do { \
213 union { GLfloat r; GLuint i; } tmp; \
214 tmp.r = f; \
215 b = ((tmp.i >= IEEE_ONE) \
216 ? ((GLint)tmp.i < 0) ? (GLubyte)0 : (GLubyte)255 \
217 : (tmp.r = tmp.r*(255.0F/256.0F) + 32768.0F, \
218 (GLubyte)tmp.i)); \
219 } while (0)
220
221
222#define CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b,f) \
223 FLOAT_COLOR_TO_UBYTE_COLOR(b, f)
224
225#else
226
227#define CLAMP_FLOAT_COLOR(f) \
228 (void) CLAMP_SELF(f,0,1)
229
230#define CLAMP_FLOAT_COLOR_VALUE(f) \
231 CLAMP(f,0,1)
232
233#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \
234 b = ((GLubyte) FloatToInt(CLAMP(f, 0.0F, 1.0F) * 255.0F))
235
236#define CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b,f) \
237 b = ((GLubyte) FloatToInt(f * 255.0F))
238
239#endif
240
241
242extern float gl_ubyte_to_float_color_tab[256];
243extern float gl_ubyte_to_float_255_color_tab[256];
244#define UBYTE_COLOR_TO_FLOAT_COLOR(c) gl_ubyte_to_float_color_tab[c]
245
246#define UBYTE_COLOR_TO_FLOAT_255_COLOR(c) gl_ubyte_to_float_255_color_tab[c]
247
248#define UBYTE_COLOR_TO_FLOAT_255_COLOR2(f,c) \
249 (*(int *)&(f)) = ((int *)gl_ubyte_to_float_255_color_tab)[c]
250
251
252#define UBYTE_RGBA_TO_FLOAT_RGBA(f,b) \
253do { \
254 f[0] = UBYTE_COLOR_TO_FLOAT_COLOR(b[0]); \
255 f[1] = UBYTE_COLOR_TO_FLOAT_COLOR(b[1]); \
256 f[2] = UBYTE_COLOR_TO_FLOAT_COLOR(b[2]); \
257 f[3] = UBYTE_COLOR_TO_FLOAT_COLOR(b[3]); \
258} while(0)
259
260
261#define UBYTE_RGBA_TO_FLOAT_255_RGBA(f,b) \
262do { \
263 f[0] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[0]); \
264 f[1] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[1]); \
265 f[2] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[2]); \
266 f[3] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[3]); \
267} while(0)
268
269#define FLOAT_RGBA_TO_UBYTE_RGBA(b,f) \
270do { \
271 FLOAT_COLOR_TO_UBYTE_COLOR((b[0]),(f[0])); \
272 FLOAT_COLOR_TO_UBYTE_COLOR((b[1]),(f[1])); \
273 FLOAT_COLOR_TO_UBYTE_COLOR((b[2]),(f[2])); \
274 FLOAT_COLOR_TO_UBYTE_COLOR((b[3]),(f[3])); \
275} while(0)
276
277#define FLOAT_RGB_TO_UBYTE_RGB(b,f) \
278do { \
279 FLOAT_COLOR_TO_UBYTE_COLOR(b[0],f[0]); \
280 FLOAT_COLOR_TO_UBYTE_COLOR(b[1],f[1]); \
281 FLOAT_COLOR_TO_UBYTE_COLOR(b[2],f[2]); \
282} while(0)
283
284
285extern void gl_init_math(void);
286
287
288#endif
Note: See TracBrowser for help on using the repository browser.