lots of gl_*() to _mesa_*() namespace clean-up
[mesa.git] / src / mesa / math / m_debug_norm.c
1 /* $Id: m_debug_norm.c,v 1.2 2001/03/03 20:33:30 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
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 * Author:
27 * Gareth Hughes <gareth@valinux.com>
28 */
29
30 #include "glheader.h"
31 #include "context.h"
32 #include "macros.h"
33 #include "mem.h"
34 #include "mmath.h"
35
36 #include "m_matrix.h"
37 #include "m_xform.h"
38
39 #include "m_debug.h"
40 #include "m_debug_util.h"
41
42
43 #ifdef DEBUG /* This code only used for debugging */
44
45
46 static int m_norm_identity[16] = {
47 ONE, NIL, NIL, NIL,
48 NIL, ONE, NIL, NIL,
49 NIL, NIL, ONE, NIL,
50 NIL, NIL, NIL, NIL
51 };
52 static int m_norm_general[16] = {
53 VAR, VAR, VAR, NIL,
54 VAR, VAR, VAR, NIL,
55 VAR, VAR, VAR, NIL,
56 NIL, NIL, NIL, NIL
57 };
58 static int m_norm_no_rot[16] = {
59 VAR, NIL, NIL, NIL,
60 NIL, VAR, NIL, NIL,
61 NIL, NIL, VAR, NIL,
62 NIL, NIL, NIL, NIL
63 };
64 static int *norm_templates[8] = {
65 m_norm_no_rot,
66 m_norm_no_rot,
67 m_norm_no_rot,
68 m_norm_general,
69 m_norm_general,
70 m_norm_general,
71 m_norm_identity,
72 m_norm_identity
73 };
74 static int norm_types[8] = {
75 NORM_TRANSFORM_NO_ROT,
76 NORM_TRANSFORM_NO_ROT | NORM_RESCALE,
77 NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE,
78 NORM_TRANSFORM,
79 NORM_TRANSFORM | NORM_RESCALE,
80 NORM_TRANSFORM | NORM_NORMALIZE,
81 NORM_RESCALE,
82 NORM_NORMALIZE
83 };
84 static int norm_scale_types[8] = { /* rescale factor */
85 NIL, /* NIL disables rescaling */
86 VAR,
87 NIL,
88 NIL,
89 VAR,
90 NIL,
91 VAR,
92 NIL
93 };
94 static int norm_normalize_types[8] = { /* normalizing ?? (no = 0) */
95 0,
96 0,
97 1,
98 0,
99 0,
100 1,
101 0,
102 1
103 };
104 static char *norm_strings[8] = {
105 "NORM_TRANSFORM_NO_ROT",
106 "NORM_TRANSFORM_NO_ROT | NORM_RESCALE",
107 "NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE",
108 "NORM_TRANSFORM",
109 "NORM_TRANSFORM | NORM_RESCALE",
110 "NORM_TRANSFORM | NORM_NORMALIZE",
111 "NORM_RESCALE",
112 "NORM_NORMALIZE"
113 };
114
115
116 /* ================================================================
117 * Reference transformations
118 */
119
120 static void ref_norm_transform_rescale( const GLmatrix *mat,
121 GLfloat scale,
122 const GLvector3f *in,
123 const GLfloat *lengths,
124 const GLubyte mask[],
125 GLvector3f *dest )
126 {
127 int i;
128 const GLfloat *s = in->start;
129 const GLfloat *m = mat->inv;
130 GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
131
132 (void) mask;
133 (void) lengths;
134
135 for ( i = 0 ; i < in->count ; i++ ) {
136 GLfloat t[3];
137
138 TRANSFORM_NORMAL( t, s, m );
139 SCALE_SCALAR_3V( out[i], scale, t );
140
141 s = (GLfloat *)((char *)s + in->stride);
142 }
143 }
144
145 static void ref_norm_transform_normalize( const GLmatrix *mat,
146 GLfloat scale,
147 const GLvector3f *in,
148 const GLfloat *lengths,
149 const GLubyte mask[],
150 GLvector3f *dest )
151 {
152 int i;
153 const GLfloat *s = in->start;
154 const GLfloat *m = mat->inv;
155 GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
156
157 (void) mask;
158
159 for ( i = 0 ; i < in->count ; i++ ) {
160 GLfloat t[3];
161
162 TRANSFORM_NORMAL( t, s, m );
163
164 if ( !lengths ) {
165 GLfloat len = LEN_SQUARED_3FV( t );
166 if ( len > 1e-20 ) {
167 /* Hmmm, don't know how we could test the precalculated
168 * length case...
169 */
170 scale = 1.0 / sqrt( len );
171 SCALE_SCALAR_3V( out[i], scale, t );
172 } else {
173 out[i][0] = out[i][1] = out[i][2] = 0;
174 }
175 } else {
176 scale = lengths[i];;
177 SCALE_SCALAR_3V( out[i], scale, t );
178 }
179
180 s = (GLfloat *)((char *)s + in->stride);
181 }
182 }
183
184
185 /* ================================================================
186 * Normal transformation tests
187 */
188
189 static int test_norm_function( normal_func func, int mtype,
190 int masked, long *cycles )
191 {
192 GLvector3f source[1], dest[1], dest2[1], ref[1], ref2[1];
193 GLmatrix mat[1];
194 GLfloat s[TEST_COUNT][5], d[TEST_COUNT][3], r[TEST_COUNT][3];
195 GLfloat d2[TEST_COUNT][3], r2[TEST_COUNT][3], length[TEST_COUNT];
196 GLfloat scale;
197 GLfloat *m;
198 GLubyte mask[TEST_COUNT];
199 int i, j;
200 #ifdef RUN_DEBUG_BENCHMARK
201 int cycle_i; /* the counter for the benchmarks we run */
202 #endif
203
204 (void) cycles;
205
206 mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
207 mat->inv = m = mat->m;
208
209 init_matrix( m );
210
211 scale = 1.0F + rnd () * norm_scale_types[mtype];
212
213 for ( i = 0 ; i < 4 ; i++ ) {
214 for ( j = 0 ; j < 4 ; j++ ) {
215 switch ( norm_templates[mtype][i * 4 + j] ) {
216 case NIL:
217 m[j * 4 + i] = 0.0;
218 break;
219 case ONE:
220 m[j * 4 + i] = 1.0;
221 break;
222 case NEG:
223 m[j * 4 + i] = -1.0;
224 break;
225 case VAR:
226 break;
227 default:
228 abort();
229 }
230 }
231 }
232
233 for ( i = 0 ; i < TEST_COUNT ; i++ ) {
234 mask[i] = i % 2; /* mask every 2nd element */
235 ASSIGN_3V( d[i], 0.0, 0.0, 0.0 );
236 ASSIGN_3V( s[i], 0.0, 0.0, 0.0 );
237 ASSIGN_3V( d2[i], 0.0, 0.0, 0.0 );
238 for ( j = 0 ; j < 3 ; j++ )
239 s[i][j] = rnd();
240 length[i] = 1 / sqrt( LEN_SQUARED_3FV( s[i] ) );
241 }
242
243 source->data = (GLfloat(*)[3])s;
244 source->start = (GLfloat *)s;
245 source->count = TEST_COUNT;
246 source->stride = sizeof(s[0]);
247 source->flags = 0;
248
249 dest->data = (GLfloat(*)[3])d;
250 dest->start = (GLfloat *)d;
251 dest->count = TEST_COUNT;
252 dest->stride = sizeof(float[3]);
253 dest->flags = 0;
254
255 dest2->data = (GLfloat(*)[3])d2;
256 dest2->start = (GLfloat *)d2;
257 dest2->count = TEST_COUNT;
258 dest2->stride = sizeof(float[3]);
259 dest2->flags = 0;
260
261 ref->data = (GLfloat(*)[3])r;
262 ref->start = (GLfloat *)r;
263 ref->count = TEST_COUNT;
264 ref->stride = sizeof(float[3]);
265 ref->flags = 0;
266
267 ref2->data = (GLfloat(*)[3])r2;
268 ref2->start = (GLfloat *)r2;
269 ref2->count = TEST_COUNT;
270 ref2->stride = sizeof(float[3]);
271 ref2->flags = 0;
272
273 if ( norm_normalize_types[mtype] == 0 ) {
274 ref_norm_transform_rescale( mat, scale, source, NULL, NULL, ref );
275 } else {
276 ref_norm_transform_normalize( mat, scale, source, NULL, NULL, ref );
277 ref_norm_transform_normalize( mat, scale, source, length, NULL, ref2 );
278 }
279
280 if ( mesa_profile ) {
281 if ( masked ) {
282 BEGIN_RACE( *cycles );
283 func( mat, scale, source, NULL, mask, dest );
284 END_RACE( *cycles );
285 func( mat, scale, source, length, mask, dest2 );
286 } else {
287 BEGIN_RACE( *cycles );
288 func( mat, scale, source, NULL, NULL, dest );
289 END_RACE( *cycles );
290 func( mat, scale, source, length, NULL, dest2 );
291 }
292 } else {
293 if ( masked ) {
294 func( mat, scale, source, NULL, mask, dest );
295 func( mat, scale, source, length, mask, dest2 );
296 } else {
297 func( mat, scale, source, NULL, NULL, dest );
298 func( mat, scale, source, length, NULL, dest2 );
299 }
300 }
301
302 for ( i = 0 ; i < TEST_COUNT ; i++ ) {
303 if ( masked && !(mask[i] & 1) )
304 continue;
305
306 for ( j = 0 ; j < 3 ; j++ ) {
307 if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) {
308 printf( "-----------------------------\n" );
309 printf( "(i = %i, j = %i)\n", i, j );
310 printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
311 d[i][0], r[i][0], r[i][0]/d[i][0],
312 MAX_PRECISION - significand_match( d[i][0], r[i][0] ) );
313 printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
314 d[i][1], r[i][1], r[i][1]/d[i][1],
315 MAX_PRECISION - significand_match( d[i][1], r[i][1] ) );
316 printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
317 d[i][2], r[i][2], r[i][2]/d[i][2],
318 MAX_PRECISION - significand_match( d[i][2], r[i][2] ) );
319 return 0;
320 }
321
322 if ( norm_normalize_types[mtype] != 0 ) {
323 if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) {
324 printf( "------------------- precalculated length case ------\n" );
325 printf( "(i = %i, j = %i)\n", i, j );
326 printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
327 d2[i][0], r2[i][0], r2[i][0]/d2[i][0],
328 MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) );
329 printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
330 d2[i][1], r2[i][1], r2[i][1]/d2[i][1],
331 MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) );
332 printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
333 d2[i][2], r2[i][2], r2[i][2]/d2[i][2],
334 MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) );
335 return 0;
336 }
337 }
338 }
339 }
340
341 ALIGN_FREE( mat->m );
342 return 1;
343 }
344
345 void _math_test_all_normal_transform_functions( char *description )
346 {
347 int masked;
348 int mtype;
349 long benchmark_tab[0xf][0x4];
350 static int first_time = 1;
351
352 if ( first_time ) {
353 first_time = 0;
354 mesa_profile = getenv( "MESA_PROFILE" );
355 }
356
357 #ifdef RUN_DEBUG_BENCHMARK
358 if ( mesa_profile ) {
359 if ( !counter_overhead ) {
360 INIT_COUNTER();
361 printf( "counter overhead: %ld cycles\n\n", counter_overhead );
362 }
363 printf( "normal transform results after hooking in %s functions:\n",
364 description );
365 }
366 #endif
367
368 for ( masked = 0 ; masked <= 1 ; masked++ ) {
369 int cma = masked ? 1 : 0;
370 char *cmastring = masked ? "CULL_MASK_ACTIVE" : "0";
371
372 #ifdef RUN_DEBUG_BENCHMARK
373 if ( mesa_profile ) {
374 printf( "\n culling: %s \n", masked ? "CULL_MASK_ACTIVE" : "0" );
375 printf( "\n-------------------------------------------------------\n" );
376 }
377 #endif
378
379 for ( mtype = 0 ; mtype < 8 ; mtype++ ) {
380 normal_func func = gl_normal_tab[norm_types[mtype]][cma];
381 long *cycles = &(benchmark_tab[mtype][cma]);
382
383 if ( test_norm_function( func, mtype, masked, cycles ) == 0 ) {
384 char buf[100];
385 sprintf( buf, "gl_normal_tab[%s][%s] failed test (%s)",
386 cmastring, norm_strings[mtype], description );
387 _mesa_problem( NULL, buf );
388 }
389
390 #ifdef RUN_DEBUG_BENCHMARK
391 if ( mesa_profile ) {
392 printf( " %li\t", benchmark_tab[mtype][cma] );
393 printf( " | [%s]\n", norm_strings[mtype] );
394 }
395 }
396 if ( mesa_profile )
397 printf( "\n" );
398 #else
399 }
400 #endif
401 }
402 #ifdef RUN_DEBUG_BENCHMARK
403 if ( mesa_profile )
404 fflush( stdout );
405 #endif
406 }
407
408
409 #endif /* DEBUG */