1fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
2fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes/*
3fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * Mesa 3-D graphics library
427558a160a9fe91745728d7626995cd88f8fe339Brian Paul * Version:  5.1
5fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes *
627558a160a9fe91745728d7626995cd88f8fe339Brian Paul * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
7fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes *
8fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * Permission is hereby granted, free of charge, to any person obtaining a
9fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * copy of this software and associated documentation files (the "Software"),
10fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * to deal in the Software without restriction, including without limitation
11fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * and/or sell copies of the Software, and to permit persons to whom the
13fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * Software is furnished to do so, subject to the following conditions:
14fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes *
15fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * The above copyright notice and this permission notice shall be included
16fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * in all copies or substantial portions of the Software.
17fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes *
18fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes *
2522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * Authors:
2605a4b37707d2c598ea68c05d07a3d65bcbf5a076Brian Paul *    Gareth Hughes
27fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes */
28fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
33fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
34fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#include "m_matrix.h"
35fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#include "m_xform.h"
36fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
37fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#include "m_debug.h"
38fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#include "m_debug_util.h"
39fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
40fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
41462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane#ifdef __UNIXOS2__
42462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane/* The linker doesn't like empty files */
43462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihanestatic char dummy;
44462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane#endif
45462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane
4681a22ef53953d950052c7bd5a282e96107a25f24Brian Paul#ifdef DEBUG_MATH  /* This code only used for debugging */
47fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
48fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
49fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int m_norm_identity[16] = {
50fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   ONE, NIL, NIL, NIL,
51fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, ONE, NIL, NIL,
52fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, NIL, ONE, NIL,
53fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, NIL, NIL, NIL
54fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
55fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int m_norm_general[16] = {
56fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR, VAR, VAR, NIL,
57fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR, VAR, VAR, NIL,
58fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR, VAR, VAR, NIL,
59fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, NIL, NIL, NIL
60fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
61fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int m_norm_no_rot[16] = {
62fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR, NIL, NIL, NIL,
63fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, VAR, NIL, NIL,
64fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, NIL, VAR, NIL,
65fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL, NIL, NIL, NIL
66fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
67fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int *norm_templates[8] = {
68fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_no_rot,
69fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_no_rot,
70fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_no_rot,
71fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_general,
72fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_general,
73fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_general,
74fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_identity,
75fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   m_norm_identity
76fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
77fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int norm_types[8] = {
78fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_TRANSFORM_NO_ROT,
79fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_TRANSFORM_NO_ROT | NORM_RESCALE,
80fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE,
81fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_TRANSFORM,
82fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_TRANSFORM | NORM_RESCALE,
83fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_TRANSFORM | NORM_NORMALIZE,
84fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_RESCALE,
85fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NORM_NORMALIZE
86fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
87fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int norm_scale_types[8] = {               /*  rescale factor          */
88fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL,                                          /*  NIL disables rescaling  */
89fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR,
90fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL,
91fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL,
92fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR,
93fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL,
94fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   VAR,
95fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   NIL
96fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
97fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic int norm_normalize_types[8] = {           /*  normalizing ?? (no = 0) */
98fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   0,
99fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   0,
100fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   1,
101fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   0,
102fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   0,
103fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   1,
104fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   0,
105fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   1
106fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
107fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic char *norm_strings[8] = {
108fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_TRANSFORM_NO_ROT",
109fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_TRANSFORM_NO_ROT | NORM_RESCALE",
110fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE",
111fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_TRANSFORM",
112fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_TRANSFORM | NORM_RESCALE",
113fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_TRANSFORM | NORM_NORMALIZE",
114fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_RESCALE",
115fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   "NORM_NORMALIZE"
116fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes};
117fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
118fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
1195e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes/* =============================================================
120fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * Reference transformations
121fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes */
122fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
123fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic void ref_norm_transform_rescale( const GLmatrix *mat,
124fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes					GLfloat scale,
125bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul					const GLvector4f *in,
126fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes					const GLfloat *lengths,
127bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul					GLvector4f *dest )
128fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes{
12901915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul   GLuint i;
130fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   const GLfloat *s = in->start;
131fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   const GLfloat *m = mat->inv;
132bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   GLfloat (*out)[4] = (GLfloat (*)[4]) dest->start;
133fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
134fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   (void) lengths;
135fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
136fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   for ( i = 0 ; i < in->count ; i++ ) {
137fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      GLfloat t[3];
138fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
139fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      TRANSFORM_NORMAL( t, s, m );
140fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      SCALE_SCALAR_3V( out[i], scale, t );
141fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
142fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      s = (GLfloat *)((char *)s + in->stride);
143fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
144fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes}
145fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
146fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesstatic void ref_norm_transform_normalize( const GLmatrix *mat,
147fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes					  GLfloat scale,
148bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul					  const GLvector4f *in,
149fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes					  const GLfloat *lengths,
150bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul					  GLvector4f *dest )
151fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes{
15201915e90e6912f06d43d443a09157f7bbc96ddc5Brian Paul   GLuint i;
153fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   const GLfloat *s = in->start;
154fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   const GLfloat *m = mat->inv;
155bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   GLfloat (*out)[4] = (GLfloat (*)[4]) dest->start;
156fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
157fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   for ( i = 0 ; i < in->count ; i++ ) {
158fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      GLfloat t[3];
159fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
160fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      TRANSFORM_NORMAL( t, s, m );
161fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
162fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      if ( !lengths ) {
163fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         GLfloat len = LEN_SQUARED_3FV( t );
164fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         if ( len > 1e-20 ) {
165fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	    /* Hmmm, don't know how we could test the precalculated
166fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	     * length case...
167fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	     */
168ec79138138c3c88afb2052823b1e3f5271493085Matt Turner            scale = INV_SQRTF( len );
169fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	    SCALE_SCALAR_3V( out[i], scale, t );
170fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         } else {
171fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            out[i][0] = out[i][1] = out[i][2] = 0;
172fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         }
173fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      } else {
174fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         scale = lengths[i];;
175fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	 SCALE_SCALAR_3V( out[i], scale, t );
176fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      }
177fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
178fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      s = (GLfloat *)((char *)s + in->stride);
179fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
180fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes}
181fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
182fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
1835e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes/* =============================================================
184fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes * Normal transformation tests
185fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes */
186fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
1874e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paulstatic void init_matrix( GLfloat *m )
1884e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul{
1894e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0;
1904e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] =  7.0;
1914e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   m[2] = 44.0; m[6] =  9.0; m[10] =  7.0; m[14] =  3.0;
1924e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] =  9.0;
1934e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul}
1944e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul
1954e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul
1961b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesstatic int test_norm_function( normal_func func, int mtype, long *cycles )
197fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes{
198bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   GLvector4f source[1], dest[1], dest2[1], ref[1], ref2[1];
199fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   GLmatrix mat[1];
200bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   GLfloat s[TEST_COUNT][5], d[TEST_COUNT][4], r[TEST_COUNT][4];
201bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   GLfloat d2[TEST_COUNT][4], r2[TEST_COUNT][4], length[TEST_COUNT];
202fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   GLfloat scale;
203fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   GLfloat *m;
204fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   int i, j;
205fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#ifdef  RUN_DEBUG_BENCHMARK
206fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   int cycle_i;		/* the counter for the benchmarks we run */
207fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#endif
208fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
209fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   (void) cycles;
210fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
21199ae9e8d7d57ae37629754edd5b1e3716611827fKristian Høgsberg   mat->m = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 );
212fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   mat->inv = m = mat->m;
213fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
214fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   init_matrix( m );
215fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
216fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   scale = 1.0F + rnd () * norm_scale_types[mtype];
217fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
218fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   for ( i = 0 ; i < 4 ; i++ ) {
219fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      for ( j = 0 ; j < 4 ; j++ ) {
220fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         switch ( norm_templates[mtype][i * 4 + j] ) {
221fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         case NIL:
222fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            m[j * 4 + i] = 0.0;
223fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            break;
224fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         case ONE:
225fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            m[j * 4 + i] = 1.0;
226fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            break;
227fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         case NEG:
228fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            m[j * 4 + i] = -1.0;
229fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            break;
230fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         case VAR:
231fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            break;
232fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         default:
2331a80fe461e162d5b6e25bd270a54e6662f72e5b3Eric Anholt            exit(1);
234fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         }
235fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      }
236fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
237fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
238fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
239fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      ASSIGN_3V( d[i],  0.0, 0.0, 0.0 );
240fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      ASSIGN_3V( s[i],  0.0, 0.0, 0.0 );
241fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      ASSIGN_3V( d2[i], 0.0, 0.0, 0.0 );
242fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      for ( j = 0 ; j < 3 ; j++ )
243fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         s[i][j] = rnd();
244ec79138138c3c88afb2052823b1e3f5271493085Matt Turner      length[i] = INV_SQRTF( LEN_SQUARED_3FV( s[i] ) );
245fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
246fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
247bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   source->data = (GLfloat(*)[4]) s;
248bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   source->start = (GLfloat *) s;
249fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   source->count = TEST_COUNT;
250fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   source->stride = sizeof(s[0]);
251fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   source->flags = 0;
252fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
253bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   dest->data = d;
254bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   dest->start = (GLfloat *) d;
255fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   dest->count = TEST_COUNT;
256bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   dest->stride = sizeof(float[4]);
257fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   dest->flags = 0;
258fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
259bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   dest2->data = d2;
260bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   dest2->start = (GLfloat *) d2;
261fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   dest2->count = TEST_COUNT;
262bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   dest2->stride = sizeof(float[4]);
263fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   dest2->flags = 0;
264fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
265bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   ref->data = r;
266bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   ref->start = (GLfloat *) r;
267fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   ref->count = TEST_COUNT;
268bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   ref->stride = sizeof(float[4]);
269fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   ref->flags = 0;
270fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
271bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   ref2->data = r2;
272bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   ref2->start = (GLfloat *) r2;
273fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   ref2->count = TEST_COUNT;
274bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul   ref2->stride = sizeof(float[4]);
275fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   ref2->flags = 0;
276fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
277fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   if ( norm_normalize_types[mtype] == 0 ) {
2785e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      ref_norm_transform_rescale( mat, scale, source, NULL, ref );
279fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   } else {
2805e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      ref_norm_transform_normalize( mat, scale, source, NULL, ref );
2815e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      ref_norm_transform_normalize( mat, scale, source, length, ref2 );
282fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
283fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
284fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   if ( mesa_profile ) {
2851b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes      BEGIN_RACE( *cycles );
2865e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      func( mat, scale, source, NULL, dest );
2871b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes      END_RACE( *cycles );
2885e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      func( mat, scale, source, length, dest2 );
289fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   } else {
2905e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      func( mat, scale, source, NULL, dest );
2915e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      func( mat, scale, source, length, dest2 );
292fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
293fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
294fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
295fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      for ( j = 0 ; j < 3 ; j++ ) {
296fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) {
297298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf( "-----------------------------\n" );
298298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf( "(i = %i, j = %i)\n", i, j );
299298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
300fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		    d[i][0], r[i][0], r[i][0]/d[i][0],
301fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		    MAX_PRECISION - significand_match( d[i][0], r[i][0] ) );
302298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
303fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		    d[i][1], r[i][1], r[i][1]/d[i][1],
304fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		    MAX_PRECISION - significand_match( d[i][1], r[i][1] ) );
305298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
306fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		    d[i][2], r[i][2], r[i][2]/d[i][2],
307fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		    MAX_PRECISION - significand_match( d[i][2], r[i][2] ) );
308fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            return 0;
309fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         }
310fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
311fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         if ( norm_normalize_types[mtype] != 0 ) {
312fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) {
313298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf( "------------------- precalculated length case ------\n" );
314298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf( "(i = %i, j = %i)\n", i, j );
315298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
316fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		       d2[i][0], r2[i][0], r2[i][0]/d2[i][0],
317fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		       MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) );
318298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
319fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		       d2[i][1], r2[i][1], r2[i][1]/d2[i][1],
320fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		       MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) );
321298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf( "%f \t %f \t [ratio = %e - %i bit missed]\n",
322fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		       d2[i][2], r2[i][2], r2[i][2]/d2[i][2],
323fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes		       MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) );
324fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes               return 0;
325fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes            }
326fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes         }
327fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      }
328fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
329fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
33099ae9e8d7d57ae37629754edd5b1e3716611827fKristian Høgsberg   _mesa_align_free( mat->m );
331fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   return 1;
332fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes}
333fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
334fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughesvoid _math_test_all_normal_transform_functions( char *description )
335fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes{
336fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   int mtype;
3375e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes   long benchmark_tab[0xf];
338fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   static int first_time = 1;
339fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
340fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   if ( first_time ) {
341fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      first_time = 0;
342b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul      mesa_profile = _mesa_getenv( "MESA_PROFILE" );
343fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
344fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
345fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#ifdef RUN_DEBUG_BENCHMARK
346fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   if ( mesa_profile ) {
347fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      if ( !counter_overhead ) {
348fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	 INIT_COUNTER();
349298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf( "counter overhead: %ld cycles\n\n", counter_overhead );
350fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      }
351298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf( "normal transform results after hooking in %s functions:\n",
352fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes	      description );
353298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf( "\n-------------------------------------------------------\n" );
354fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
355fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#endif
356fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
3571b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes   for ( mtype = 0 ; mtype < 8 ; mtype++ ) {
3585e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      normal_func func = _mesa_normal_tab[norm_types[mtype]];
3595e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes      long *cycles = &benchmark_tab[mtype];
360fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
3611b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes      if ( test_norm_function( func, mtype, cycles ) == 0 ) {
3621b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes	 char buf[100];
363298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 sprintf( buf, "_mesa_normal_tab[0][%s] failed test (%s)",
3641b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes		  norm_strings[mtype], description );
3659c841abebc809be232032066c314d37231e595e2Vinson Lee	 _mesa_problem( NULL, "%s", buf );
366fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      }
367fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
368fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#ifdef RUN_DEBUG_BENCHMARK
3691b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes      if ( mesa_profile ) {
370298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf( " %li\t", benchmark_tab[mtype] );
371298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	 printf( " | [%s]\n", norm_strings[mtype] );
372fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes      }
373fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#endif
374fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes   }
375fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#ifdef RUN_DEBUG_BENCHMARK
3761b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes   if ( mesa_profile ) {
377298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf( "\n" );
3781b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes   }
379fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes#endif
380fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes}
381fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
382fe69cb4b9bff800b6078ea7da5ea18bab05678d8Gareth Hughes
38381a22ef53953d950052c7bd5a282e96107a25f24Brian Paul#endif /* DEBUG_MATH */
384