1 
2 /*
3  * Mesa 3-D graphics library
4  *
5  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 /*
27  * New (3.1) transformation code written by Keith Whitwell.
28  */
29 
30 
31 /*----------------------------------------------------------------------
32  * Begin Keith's new code
33  *
34  *----------------------------------------------------------------------
35  */
36 
37 /* KW: Fixed stride, now measured in bytes as is the OpenGL array stride.
38  */
39 
40 /* KW: These are now parameterized to produce two versions, one
41  *     which transforms all incoming points, and a second which
42  *     takes notice of a cullmask array, and only transforms
43  *     unculled vertices.
44  */
45 
46 /* KW: 1-vectors can sneak into the texture pipeline via the array
47  *     interface.  These functions are here because I want consistant
48  *     treatment of the vertex sizes and a lazy strategy for
49  *     cleaning unused parts of the vector, and so as not to exclude
50  *     them from the vertex array interface.
51  *
52  *     Under our current analysis of matrices, there is no way that
53  *     the product of a matrix and a 1-vector can remain a 1-vector,
54  *     with the exception of the identity transform.
55  */
56 
57 /* KW: No longer zero-pad outgoing vectors.  Now that external
58  *     vectors can get into the pipeline we cannot ever assume
59  *     that there is more to a vector than indicated by its
60  *     size.
61  */
62 
63 /* KW: Now uses clipmask and a flag to allow us to skip both/either
64  *     cliped and/or culled vertices.
65  */
66 
67 /* GH: Not any more -- it's easier (and faster) to just process the
68  *     entire vector.  Clipping and culling are handled further down
69  *     the pipe, most often during or after the conversion to some
70  *     driver-specific vertex format.
71  */
72 
73 static void
TAG(transform_points1_general)74 TAG(transform_points1_general)( GLvector4f *to_vec,
75 				const GLfloat m[16],
76 				const GLvector4f *from_vec )
77 {
78    const GLuint stride = from_vec->stride;
79    GLfloat *from = from_vec->start;
80    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
81    GLuint count = from_vec->count;
82    const GLfloat m0 = m[0],  m12 = m[12];
83    const GLfloat m1 = m[1],  m13 = m[13];
84    const GLfloat m2 = m[2],  m14 = m[14];
85    const GLfloat m3 = m[3],  m15 = m[15];
86    GLuint i;
87    STRIDE_LOOP {
88       const GLfloat ox = from[0];
89       to[i][0] = m0 * ox + m12;
90       to[i][1] = m1 * ox + m13;
91       to[i][2] = m2 * ox + m14;
92       to[i][3] = m3 * ox + m15;
93    }
94    to_vec->size = 4;
95    to_vec->flags |= VEC_SIZE_4;
96    to_vec->count = from_vec->count;
97 }
98 
99 static void
TAG(transform_points1_identity)100 TAG(transform_points1_identity)( GLvector4f *to_vec,
101 				 const GLfloat m[16],
102 				 const GLvector4f *from_vec )
103 {
104    const GLuint stride = from_vec->stride;
105    GLfloat *from = from_vec->start;
106    GLuint count = from_vec->count;
107    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
108    GLuint i;
109    (void) m;
110    if (to_vec == from_vec) return;
111    STRIDE_LOOP {
112       to[i][0] = from[0];
113    }
114    to_vec->size = 1;
115    to_vec->flags |= VEC_SIZE_1;
116    to_vec->count = from_vec->count;
117 }
118 
119 static void
TAG(transform_points1_2d)120 TAG(transform_points1_2d)( GLvector4f *to_vec,
121 			   const GLfloat m[16],
122 			   const GLvector4f *from_vec )
123 {
124    const GLuint stride = from_vec->stride;
125    GLfloat *from = from_vec->start;
126    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
127    GLuint count = from_vec->count;
128    const GLfloat m0 = m[0], m1 = m[1];
129    const GLfloat m12 = m[12], m13 = m[13];
130    GLuint i;
131    STRIDE_LOOP {
132       const GLfloat ox = from[0];
133       to[i][0] = m0 * ox + m12;
134       to[i][1] = m1 * ox + m13;
135    }
136    to_vec->size = 2;
137    to_vec->flags |= VEC_SIZE_2;
138    to_vec->count = from_vec->count;
139 }
140 
141 static void
TAG(transform_points1_2d_no_rot)142 TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec,
143 				  const GLfloat m[16],
144 				  const GLvector4f *from_vec )
145 {
146    const GLuint stride = from_vec->stride;
147    GLfloat *from = from_vec->start;
148    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
149    GLuint count = from_vec->count;
150    const GLfloat m0 = m[0], m12 = m[12], m13 = m[13];
151    GLuint i;
152    STRIDE_LOOP {
153       const GLfloat ox = from[0];
154       to[i][0] = m0 * ox + m12;
155       to[i][1] =           m13;
156    }
157    to_vec->size = 2;
158    to_vec->flags |= VEC_SIZE_2;
159    to_vec->count = from_vec->count;
160 }
161 
162 static void
TAG(transform_points1_3d)163 TAG(transform_points1_3d)( GLvector4f *to_vec,
164 			   const GLfloat m[16],
165 			   const GLvector4f *from_vec )
166 {
167    const GLuint stride = from_vec->stride;
168    GLfloat *from = from_vec->start;
169    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
170    GLuint count = from_vec->count;
171    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2];
172    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
173    GLuint i;
174    STRIDE_LOOP {
175       const GLfloat ox = from[0];
176       to[i][0] = m0 * ox + m12;
177       to[i][1] = m1 * ox + m13;
178       to[i][2] = m2 * ox + m14;
179    }
180    to_vec->size = 3;
181    to_vec->flags |= VEC_SIZE_3;
182    to_vec->count = from_vec->count;
183 }
184 
185 
186 static void
TAG(transform_points1_3d_no_rot)187 TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec,
188 				  const GLfloat m[16],
189 				  const GLvector4f *from_vec )
190 {
191    const GLuint stride = from_vec->stride;
192    GLfloat *from = from_vec->start;
193    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
194    GLuint count = from_vec->count;
195    const GLfloat m0 = m[0];
196    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
197    GLuint i;
198    STRIDE_LOOP {
199       const GLfloat ox = from[0];
200       to[i][0] = m0 * ox           + m12;
201       to[i][1] =                     m13;
202       to[i][2] =                     m14;
203    }
204    to_vec->size = 3;
205    to_vec->flags |= VEC_SIZE_3;
206    to_vec->count = from_vec->count;
207 }
208 
209 static void
TAG(transform_points1_perspective)210 TAG(transform_points1_perspective)( GLvector4f *to_vec,
211 				    const GLfloat m[16],
212 				    const GLvector4f *from_vec )
213 {
214    const GLuint stride = from_vec->stride;
215    GLfloat *from = from_vec->start;
216    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
217    GLuint count = from_vec->count;
218    const GLfloat m0 = m[0], m14 = m[14];
219    GLuint i;
220    STRIDE_LOOP {
221       const GLfloat ox = from[0];
222       to[i][0] = m0 * ox                ;
223       to[i][1] =           0            ;
224       to[i][2] =                     m14;
225       to[i][3] = 0;
226    }
227    to_vec->size = 4;
228    to_vec->flags |= VEC_SIZE_4;
229    to_vec->count = from_vec->count;
230 }
231 
232 
233 
234 
235 /* 2-vectors, which are a lot more relevant than 1-vectors, are
236  * present early in the geometry pipeline and throughout the
237  * texture pipeline.
238  */
239 static void
TAG(transform_points2_general)240 TAG(transform_points2_general)( GLvector4f *to_vec,
241 				const GLfloat m[16],
242 				const GLvector4f *from_vec )
243 {
244    const GLuint stride = from_vec->stride;
245    GLfloat *from = from_vec->start;
246    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
247    GLuint count = from_vec->count;
248    const GLfloat m0 = m[0],  m4 = m[4],  m12 = m[12];
249    const GLfloat m1 = m[1],  m5 = m[5],  m13 = m[13];
250    const GLfloat m2 = m[2],  m6 = m[6],  m14 = m[14];
251    const GLfloat m3 = m[3],  m7 = m[7],  m15 = m[15];
252    GLuint i;
253    STRIDE_LOOP {
254       const GLfloat ox = from[0], oy = from[1];
255       to[i][0] = m0 * ox + m4 * oy + m12;
256       to[i][1] = m1 * ox + m5 * oy + m13;
257       to[i][2] = m2 * ox + m6 * oy + m14;
258       to[i][3] = m3 * ox + m7 * oy + m15;
259    }
260    to_vec->size = 4;
261    to_vec->flags |= VEC_SIZE_4;
262    to_vec->count = from_vec->count;
263 }
264 
265 static void
TAG(transform_points2_identity)266 TAG(transform_points2_identity)( GLvector4f *to_vec,
267 				 const GLfloat m[16],
268 				 const GLvector4f *from_vec )
269 {
270    const GLuint stride = from_vec->stride;
271    GLfloat *from = from_vec->start;
272    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
273    GLuint count = from_vec->count;
274    GLuint i;
275    (void) m;
276    if (to_vec == from_vec) return;
277    STRIDE_LOOP {
278       to[i][0] = from[0];
279       to[i][1] = from[1];
280    }
281    to_vec->size = 2;
282    to_vec->flags |= VEC_SIZE_2;
283    to_vec->count = from_vec->count;
284 }
285 
286 static void
TAG(transform_points2_2d)287 TAG(transform_points2_2d)( GLvector4f *to_vec,
288 			   const GLfloat m[16],
289 			   const GLvector4f *from_vec )
290 {
291    const GLuint stride = from_vec->stride;
292    GLfloat *from = from_vec->start;
293    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
294    GLuint count = from_vec->count;
295    const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
296    const GLfloat m12 = m[12], m13 = m[13];
297    GLuint i;
298    STRIDE_LOOP {
299       const GLfloat ox = from[0], oy = from[1];
300       to[i][0] = m0 * ox + m4 * oy + m12;
301       to[i][1] = m1 * ox + m5 * oy + m13;
302    }
303    to_vec->size = 2;
304    to_vec->flags |= VEC_SIZE_2;
305    to_vec->count = from_vec->count;
306 }
307 
308 static void
TAG(transform_points2_2d_no_rot)309 TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec,
310 				  const GLfloat m[16],
311 				  const GLvector4f *from_vec )
312 {
313    const GLuint stride = from_vec->stride;
314    GLfloat *from = from_vec->start;
315    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
316    GLuint count = from_vec->count;
317    const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
318    GLuint i;
319    STRIDE_LOOP {
320       const GLfloat ox = from[0], oy = from[1];
321       to[i][0] = m0 * ox           + m12;
322       to[i][1] =           m5 * oy + m13;
323    }
324    to_vec->size = 2;
325    to_vec->flags |= VEC_SIZE_2;
326    to_vec->count = from_vec->count;
327 }
328 
329 static void
TAG(transform_points2_3d)330 TAG(transform_points2_3d)( GLvector4f *to_vec,
331 			   const GLfloat m[16],
332 			   const GLvector4f *from_vec )
333 {
334    const GLuint stride = from_vec->stride;
335    GLfloat *from = from_vec->start;
336    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
337    GLuint count = from_vec->count;
338    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
339    const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14];
340    GLuint i;
341    STRIDE_LOOP {
342       const GLfloat ox = from[0], oy = from[1];
343       to[i][0] = m0 * ox + m4 * oy + m12;
344       to[i][1] = m1 * ox + m5 * oy + m13;
345       to[i][2] = m2 * ox + m6 * oy + m14;
346    }
347    to_vec->size = 3;
348    to_vec->flags |= VEC_SIZE_3;
349    to_vec->count = from_vec->count;
350 }
351 
352 
353 /* I would actually say this was a fairly important function, from
354  * a texture transformation point of view.
355  */
356 static void
TAG(transform_points2_3d_no_rot)357 TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec,
358 				  const GLfloat m[16],
359 				  const GLvector4f *from_vec )
360 {
361    const GLuint stride = from_vec->stride;
362    GLfloat *from = from_vec->start;
363    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
364    GLuint count = from_vec->count;
365    const GLfloat m0 = m[0], m5 = m[5];
366    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
367    GLuint i;
368    STRIDE_LOOP {
369       const GLfloat ox = from[0], oy = from[1];
370       to[i][0] = m0 * ox           + m12;
371       to[i][1] =           m5 * oy + m13;
372       to[i][2] =                     m14;
373    }
374    if (m14 == 0) {
375       to_vec->size = 2;
376       to_vec->flags |= VEC_SIZE_2;
377    } else {
378       to_vec->size = 3;
379       to_vec->flags |= VEC_SIZE_3;
380    }
381    to_vec->count = from_vec->count;
382 }
383 
384 
385 static void
TAG(transform_points2_perspective)386 TAG(transform_points2_perspective)( GLvector4f *to_vec,
387 				    const GLfloat m[16],
388 				    const GLvector4f *from_vec )
389 {
390    const GLuint stride = from_vec->stride;
391    GLfloat *from = from_vec->start;
392    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
393    GLuint count = from_vec->count;
394    const GLfloat m0 = m[0], m5 = m[5], m14 = m[14];
395    GLuint i;
396    STRIDE_LOOP {
397       const GLfloat ox = from[0], oy = from[1];
398       to[i][0] = m0 * ox                ;
399       to[i][1] =           m5 * oy      ;
400       to[i][2] =                     m14;
401       to[i][3] = 0;
402    }
403    to_vec->size = 4;
404    to_vec->flags |= VEC_SIZE_4;
405    to_vec->count = from_vec->count;
406 }
407 
408 
409 
410 static void
TAG(transform_points3_general)411 TAG(transform_points3_general)( GLvector4f *to_vec,
412 				const GLfloat m[16],
413 				const GLvector4f *from_vec )
414 {
415    const GLuint stride = from_vec->stride;
416    GLfloat *from = from_vec->start;
417    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
418    GLuint count = from_vec->count;
419    const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
420    const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
421    const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
422    const GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
423    GLuint i;
424    STRIDE_LOOP {
425       const GLfloat ox = from[0], oy = from[1], oz = from[2];
426       to[i][0] = m0 * ox + m4 * oy + m8  * oz + m12;
427       to[i][1] = m1 * ox + m5 * oy + m9  * oz + m13;
428       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14;
429       to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15;
430    }
431    to_vec->size = 4;
432    to_vec->flags |= VEC_SIZE_4;
433    to_vec->count = from_vec->count;
434 }
435 
436 static void
TAG(transform_points3_identity)437 TAG(transform_points3_identity)( GLvector4f *to_vec,
438 				 const GLfloat m[16],
439 				 const GLvector4f *from_vec )
440 {
441    const GLuint stride = from_vec->stride;
442    GLfloat *from = from_vec->start;
443    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
444    GLuint count = from_vec->count;
445    GLuint i;
446    (void) m;
447    if (to_vec == from_vec) return;
448    STRIDE_LOOP {
449       to[i][0] = from[0];
450       to[i][1] = from[1];
451       to[i][2] = from[2];
452    }
453    to_vec->size = 3;
454    to_vec->flags |= VEC_SIZE_3;
455    to_vec->count = from_vec->count;
456 }
457 
458 static void
TAG(transform_points3_2d)459 TAG(transform_points3_2d)( GLvector4f *to_vec,
460 			   const GLfloat m[16],
461 			   const GLvector4f *from_vec )
462 {
463    const GLuint stride = from_vec->stride;
464    GLfloat *from = from_vec->start;
465    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
466    GLuint count = from_vec->count;
467    const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
468    const GLfloat m12 = m[12], m13 = m[13];
469    GLuint i;
470    STRIDE_LOOP {
471       const GLfloat ox = from[0], oy = from[1], oz = from[2];
472       to[i][0] = m0 * ox + m4 * oy            + m12       ;
473       to[i][1] = m1 * ox + m5 * oy            + m13       ;
474       to[i][2] =                   +       oz             ;
475    }
476    to_vec->size = 3;
477    to_vec->flags |= VEC_SIZE_3;
478    to_vec->count = from_vec->count;
479 }
480 
481 static void
TAG(transform_points3_2d_no_rot)482 TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec,
483 				  const GLfloat m[16],
484 				  const GLvector4f *from_vec )
485 {
486    const GLuint stride = from_vec->stride;
487    GLfloat *from = from_vec->start;
488    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
489    GLuint count = from_vec->count;
490    const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
491    GLuint i;
492    STRIDE_LOOP {
493       const GLfloat ox = from[0], oy = from[1], oz = from[2];
494       to[i][0] = m0 * ox                      + m12       ;
495       to[i][1] =           m5 * oy            + m13       ;
496       to[i][2] =                   +       oz             ;
497    }
498    to_vec->size = 3;
499    to_vec->flags |= VEC_SIZE_3;
500    to_vec->count = from_vec->count;
501 }
502 
503 static void
TAG(transform_points3_3d)504 TAG(transform_points3_3d)( GLvector4f *to_vec,
505 			   const GLfloat m[16],
506 			   const GLvector4f *from_vec )
507 {
508    const GLuint stride = from_vec->stride;
509    GLfloat *from = from_vec->start;
510    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
511    GLuint count = from_vec->count;
512    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
513    const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
514    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
515    GLuint i;
516    STRIDE_LOOP {
517       const GLfloat ox = from[0], oy = from[1], oz = from[2];
518       to[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12       ;
519       to[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13       ;
520       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14       ;
521    }
522    to_vec->size = 3;
523    to_vec->flags |= VEC_SIZE_3;
524    to_vec->count = from_vec->count;
525 }
526 
527 /* previously known as ortho...
528  */
529 static void
TAG(transform_points3_3d_no_rot)530 TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec,
531 				  const GLfloat m[16],
532 				  const GLvector4f *from_vec )
533 {
534    const GLuint stride = from_vec->stride;
535    GLfloat *from = from_vec->start;
536    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
537    GLuint count = from_vec->count;
538    const GLfloat m0 = m[0], m5 = m[5];
539    const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14];
540    GLuint i;
541    STRIDE_LOOP {
542       const GLfloat ox = from[0], oy = from[1], oz = from[2];
543       to[i][0] = m0 * ox                      + m12       ;
544       to[i][1] =           m5 * oy            + m13       ;
545       to[i][2] =                     m10 * oz + m14       ;
546    }
547    to_vec->size = 3;
548    to_vec->flags |= VEC_SIZE_3;
549    to_vec->count = from_vec->count;
550 }
551 
552 static void
TAG(transform_points3_perspective)553 TAG(transform_points3_perspective)( GLvector4f *to_vec,
554 				    const GLfloat m[16],
555 				    const GLvector4f *from_vec )
556 {
557    const GLuint stride = from_vec->stride;
558    GLfloat *from = from_vec->start;
559    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
560    GLuint count = from_vec->count;
561    const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
562    const GLfloat m10 = m[10], m14 = m[14];
563    GLuint i;
564    STRIDE_LOOP {
565       const GLfloat ox = from[0], oy = from[1], oz = from[2];
566       to[i][0] = m0 * ox           + m8  * oz       ;
567       to[i][1] =           m5 * oy + m9  * oz       ;
568       to[i][2] =                     m10 * oz + m14 ;
569       to[i][3] =                          -oz       ;
570    }
571    to_vec->size = 4;
572    to_vec->flags |= VEC_SIZE_4;
573    to_vec->count = from_vec->count;
574 }
575 
576 
577 
578 static void
TAG(transform_points4_general)579 TAG(transform_points4_general)( GLvector4f *to_vec,
580 				const GLfloat m[16],
581 				const GLvector4f *from_vec )
582 {
583    const GLuint stride = from_vec->stride;
584    GLfloat *from = from_vec->start;
585    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
586    GLuint count = from_vec->count;
587    const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
588    const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
589    const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
590    const GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
591    GLuint i;
592    STRIDE_LOOP {
593       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
594       to[i][0] = m0 * ox + m4 * oy + m8  * oz + m12 * ow;
595       to[i][1] = m1 * ox + m5 * oy + m9  * oz + m13 * ow;
596       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
597       to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow;
598    }
599    to_vec->size = 4;
600    to_vec->flags |= VEC_SIZE_4;
601    to_vec->count = from_vec->count;
602 }
603 
604 static void
TAG(transform_points4_identity)605 TAG(transform_points4_identity)( GLvector4f *to_vec,
606 				 const GLfloat m[16],
607 				 const GLvector4f *from_vec )
608 {
609    const GLuint stride = from_vec->stride;
610    GLfloat *from = from_vec->start;
611    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
612    GLuint count = from_vec->count;
613    GLuint i;
614    (void) m;
615    if (to_vec == from_vec) return;
616    STRIDE_LOOP {
617       to[i][0] = from[0];
618       to[i][1] = from[1];
619       to[i][2] = from[2];
620       to[i][3] = from[3];
621    }
622    to_vec->size = 4;
623    to_vec->flags |= VEC_SIZE_4;
624    to_vec->count = from_vec->count;
625 }
626 
627 static void
TAG(transform_points4_2d)628 TAG(transform_points4_2d)( GLvector4f *to_vec,
629 			   const GLfloat m[16],
630 			   const GLvector4f *from_vec )
631 {
632    const GLuint stride = from_vec->stride;
633    GLfloat *from = from_vec->start;
634    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
635    GLuint count = from_vec->count;
636    const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
637    const GLfloat m12 = m[12], m13 = m[13];
638    GLuint i;
639    STRIDE_LOOP {
640       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
641       to[i][0] = m0 * ox + m4 * oy            + m12 * ow;
642       to[i][1] = m1 * ox + m5 * oy            + m13 * ow;
643       to[i][2] =                   +       oz           ;
644       to[i][3] =                                      ow;
645    }
646    to_vec->size = 4;
647    to_vec->flags |= VEC_SIZE_4;
648    to_vec->count = from_vec->count;
649 }
650 
651 static void
TAG(transform_points4_2d_no_rot)652 TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec,
653 				  const GLfloat m[16],
654 				  const GLvector4f *from_vec )
655 {
656    const GLuint stride = from_vec->stride;
657    GLfloat *from = from_vec->start;
658    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
659    GLuint count = from_vec->count;
660    const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
661    GLuint i;
662    STRIDE_LOOP {
663       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
664       to[i][0] = m0 * ox                      + m12 * ow;
665       to[i][1] =           m5 * oy            + m13 * ow;
666       to[i][2] =                   +       oz           ;
667       to[i][3] =                                      ow;
668    }
669    to_vec->size = 4;
670    to_vec->flags |= VEC_SIZE_4;
671    to_vec->count = from_vec->count;
672 }
673 
674 static void
TAG(transform_points4_3d)675 TAG(transform_points4_3d)( GLvector4f *to_vec,
676 			   const GLfloat m[16],
677 			   const GLvector4f *from_vec )
678 {
679    const GLuint stride = from_vec->stride;
680    GLfloat *from = from_vec->start;
681    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
682    GLuint count = from_vec->count;
683    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
684    const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
685    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
686    GLuint i;
687    STRIDE_LOOP {
688       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
689       to[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12 * ow;
690       to[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13 * ow;
691       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
692       to[i][3] =                                      ow;
693    }
694    to_vec->size = 4;
695    to_vec->flags |= VEC_SIZE_4;
696    to_vec->count = from_vec->count;
697 }
698 
699 static void
TAG(transform_points4_3d_no_rot)700 TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec,
701 				  const GLfloat m[16],
702 				  const GLvector4f *from_vec )
703 {
704    const GLuint stride = from_vec->stride;
705    GLfloat *from = from_vec->start;
706    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
707    GLuint count = from_vec->count;
708    const GLfloat m0 = m[0], m5 = m[5];
709    const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14];
710    GLuint i;
711    STRIDE_LOOP {
712       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
713       to[i][0] = m0 * ox                      + m12 * ow;
714       to[i][1] =           m5 * oy            + m13 * ow;
715       to[i][2] =                     m10 * oz + m14 * ow;
716       to[i][3] =                                      ow;
717    }
718    to_vec->size = 4;
719    to_vec->flags |= VEC_SIZE_4;
720    to_vec->count = from_vec->count;
721 }
722 
723 static void
TAG(transform_points4_perspective)724 TAG(transform_points4_perspective)( GLvector4f *to_vec,
725 				    const GLfloat m[16],
726 				    const GLvector4f *from_vec )
727 {
728    const GLuint stride = from_vec->stride;
729    GLfloat *from = from_vec->start;
730    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
731    GLuint count = from_vec->count;
732    const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
733    const GLfloat m10 = m[10], m14 = m[14];
734    GLuint i;
735    STRIDE_LOOP {
736       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
737       to[i][0] = m0 * ox           + m8  * oz            ;
738       to[i][1] =           m5 * oy + m9  * oz            ;
739       to[i][2] =                     m10 * oz + m14 * ow ;
740       to[i][3] =                          -oz            ;
741    }
742    to_vec->size = 4;
743    to_vec->flags |= VEC_SIZE_4;
744    to_vec->count = from_vec->count;
745 }
746 
747 static transform_func TAG(transform_tab_1)[7];
748 static transform_func TAG(transform_tab_2)[7];
749 static transform_func TAG(transform_tab_3)[7];
750 static transform_func TAG(transform_tab_4)[7];
751 
752 /* Similar functions could be called several times, with more highly
753  * optimized routines overwriting the arrays.  This only occurs during
754  * startup.
755  */
TAG(init_c_transformations)756 static void TAG(init_c_transformations)( void )
757 {
758 #define TAG_TAB   _mesa_transform_tab
759 #define TAG_TAB_1 TAG(transform_tab_1)
760 #define TAG_TAB_2 TAG(transform_tab_2)
761 #define TAG_TAB_3 TAG(transform_tab_3)
762 #define TAG_TAB_4 TAG(transform_tab_4)
763 
764    TAG_TAB[1] = TAG_TAB_1;
765    TAG_TAB[2] = TAG_TAB_2;
766    TAG_TAB[3] = TAG_TAB_3;
767    TAG_TAB[4] = TAG_TAB_4;
768 
769    /* 1-D points (ie texcoords) */
770    TAG_TAB_1[MATRIX_GENERAL]     = TAG(transform_points1_general);
771    TAG_TAB_1[MATRIX_IDENTITY]    = TAG(transform_points1_identity);
772    TAG_TAB_1[MATRIX_3D_NO_ROT]   = TAG(transform_points1_3d_no_rot);
773    TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective);
774    TAG_TAB_1[MATRIX_2D]          = TAG(transform_points1_2d);
775    TAG_TAB_1[MATRIX_2D_NO_ROT]   = TAG(transform_points1_2d_no_rot);
776    TAG_TAB_1[MATRIX_3D]          = TAG(transform_points1_3d);
777 
778    /* 2-D points */
779    TAG_TAB_2[MATRIX_GENERAL]     = TAG(transform_points2_general);
780    TAG_TAB_2[MATRIX_IDENTITY]    = TAG(transform_points2_identity);
781    TAG_TAB_2[MATRIX_3D_NO_ROT]   = TAG(transform_points2_3d_no_rot);
782    TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective);
783    TAG_TAB_2[MATRIX_2D]          = TAG(transform_points2_2d);
784    TAG_TAB_2[MATRIX_2D_NO_ROT]   = TAG(transform_points2_2d_no_rot);
785    TAG_TAB_2[MATRIX_3D]          = TAG(transform_points2_3d);
786 
787    /* 3-D points */
788    TAG_TAB_3[MATRIX_GENERAL]     = TAG(transform_points3_general);
789    TAG_TAB_3[MATRIX_IDENTITY]    = TAG(transform_points3_identity);
790    TAG_TAB_3[MATRIX_3D_NO_ROT]   = TAG(transform_points3_3d_no_rot);
791    TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective);
792    TAG_TAB_3[MATRIX_2D]          = TAG(transform_points3_2d);
793    TAG_TAB_3[MATRIX_2D_NO_ROT]   = TAG(transform_points3_2d_no_rot);
794    TAG_TAB_3[MATRIX_3D]          = TAG(transform_points3_3d);
795 
796    /* 4-D points */
797    TAG_TAB_4[MATRIX_GENERAL]     = TAG(transform_points4_general);
798    TAG_TAB_4[MATRIX_IDENTITY]    = TAG(transform_points4_identity);
799    TAG_TAB_4[MATRIX_3D_NO_ROT]   = TAG(transform_points4_3d_no_rot);
800    TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective);
801    TAG_TAB_4[MATRIX_2D]          = TAG(transform_points4_2d);
802    TAG_TAB_4[MATRIX_2D_NO_ROT]   = TAG(transform_points4_2d_no_rot);
803    TAG_TAB_4[MATRIX_3D]          = TAG(transform_points4_3d);
804 
805 #undef TAG_TAB
806 #undef TAG_TAB_1
807 #undef TAG_TAB_2
808 #undef TAG_TAB_3
809 #undef TAG_TAB_4
810 }
811