Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / tnl / t_vertex_generic.c
1
2 /*
3  * Copyright 2003 Tungsten Graphics, inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * on the rights to use, copy, modify, merge, publish, distribute, sub
10  * license, and/or sell copies of the Software, and to permit persons to whom
11  * the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20  * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23  * USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Keith Whitwell <keithw@tungstengraphics.com>
27  */
28
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/colormac.h"
32 #include "main/simple_list.h"
33 #include "t_context.h"
34 #include "t_vertex.h"
35
36
37 #if 0
38 #define DEBUG_INSERT printf("%s\n", __FUNCTION__)
39 #else
40 #define DEBUG_INSERT
41 #endif
42
43
44 /*
45  * These functions take the NDC coordinates pointed to by 'in', apply the
46  * NDC->Viewport mapping and store the results at 'v'.
47  */
48
49 static INLINE void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
50                       const GLfloat *in )
51 {
52    GLfloat *out = (GLfloat *)v;
53    const GLfloat * const vp = a->vp;
54    DEBUG_INSERT;
55    out[0] = vp[0] * in[0] + vp[12];
56    out[1] = vp[5] * in[1] + vp[13];
57    out[2] = vp[10] * in[2] + vp[14];
58    out[3] = in[3];
59 }
60
61 static INLINE void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
62                                 const GLfloat *in )
63 {
64    GLfloat *out = (GLfloat *)v;
65    const GLfloat * const vp = a->vp;
66    DEBUG_INSERT;
67    out[0] = vp[0] * in[0] + vp[12];
68    out[1] = vp[5] * in[1] + vp[13];
69    out[2] = vp[10] * in[2] + vp[14];
70    out[3] = 1;
71 }
72
73 static INLINE void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
74                                 const GLfloat *in )
75 {
76    GLfloat *out = (GLfloat *)v;
77    const GLfloat * const vp = a->vp;
78    DEBUG_INSERT;
79    out[0] = vp[0] * in[0] + vp[12];
80    out[1] = vp[5] * in[1] + vp[13];
81    out[2] = vp[14];
82    out[3] = 1;
83 }
84
85 static INLINE void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
86                                 const GLfloat *in )
87 {
88    GLfloat *out = (GLfloat *)v;
89    const GLfloat * const vp = a->vp;
90    DEBUG_INSERT;
91    out[0] = vp[0] * in[0] + vp[12];
92    out[1] = vp[13];
93    out[2] = vp[14];
94    out[3] = 1;
95 }
96
97 static INLINE void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
98                                 const GLfloat *in )
99 {
100    GLfloat *out = (GLfloat *)v;
101    const GLfloat * const vp = a->vp;
102    DEBUG_INSERT;
103    out[0] = vp[0] * in[0] + vp[12];
104    out[1] = vp[5] * in[1] + vp[13];
105    out[2] = vp[10] * in[2] + vp[14];
106 }
107
108 static INLINE void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
109                                 const GLfloat *in )
110 {
111    GLfloat *out = (GLfloat *)v;
112    const GLfloat * const vp = a->vp;
113    DEBUG_INSERT;
114    out[0] = vp[0] * in[0] + vp[12];
115    out[1] = vp[5] * in[1] + vp[13];
116    out[2] = vp[14];
117 }
118
119 static INLINE void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
120                                 const GLfloat *in )
121 {
122    GLfloat *out = (GLfloat *)v;
123    const GLfloat * const vp = a->vp;
124    DEBUG_INSERT;
125    out[0] = vp[0] * in[0] + vp[12];
126    out[1] = vp[13];
127    out[2] = vp[14];
128 }
129
130 static INLINE void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
131                                 const GLfloat *in )
132 {
133    GLfloat *out = (GLfloat *)v;
134    const GLfloat * const vp = a->vp;
135    DEBUG_INSERT;
136    out[0] = vp[0] * in[0] + vp[12];
137    out[1] = vp[5] * in[1] + vp[13];
138 }
139
140 static INLINE void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
141                                 const GLfloat *in )
142 {
143    GLfloat *out = (GLfloat *)v;
144    const GLfloat * const vp = a->vp;
145    DEBUG_INSERT;
146    out[0] = vp[0] * in[0] + vp[12];
147    out[1] = vp[13];
148 }
149
150
151 /*
152  * These functions do the same as above, except for the viewport mapping.
153  */
154
155 static INLINE void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
156 {
157    GLfloat *out = (GLfloat *)(v);
158    (void) a;
159    DEBUG_INSERT;
160    out[0] = in[0];
161    out[1] = in[1];
162    out[2] = in[2];
163    out[3] = in[3];
164 }
165
166 static INLINE void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
167 {
168    GLfloat *out = (GLfloat *)(v);
169    (void) a;
170    DEBUG_INSERT;
171    out[0] = in[0];
172    out[1] = in[1];
173    out[2] = in[2];
174    out[3] = 1;
175 }
176
177 static INLINE void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
178 {
179    GLfloat *out = (GLfloat *)(v);
180    (void) a;
181    DEBUG_INSERT;
182    out[0] = in[0];
183    out[1] = in[1];
184    out[2] = 0;
185    out[3] = 1;
186 }
187
188 static INLINE void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
189 {
190    GLfloat *out = (GLfloat *)(v);
191    (void) a;
192    DEBUG_INSERT;
193    out[0] = in[0];
194    out[1] = 0;
195    out[2] = 0;
196    out[3] = 1;
197 }
198
199 static INLINE void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
200 {
201    GLfloat *out = (GLfloat *)(v);
202    (void) a;
203    DEBUG_INSERT;
204    out[0] = in[0];
205    out[1] = in[1];
206    out[2] = in[3];
207 }
208
209 static INLINE void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
210 {
211    (void) a; (void) v; (void) in;
212    DEBUG_INSERT;
213    exit(1);
214 }
215
216 static INLINE void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
217 {
218    GLfloat *out = (GLfloat *)(v);
219    (void) a;
220    DEBUG_INSERT;
221    out[0] = in[0];
222    out[1] = in[1];
223    out[2] = in[2];
224 }
225
226 static INLINE void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
227 {
228    GLfloat *out = (GLfloat *)(v);
229    (void) a;
230    DEBUG_INSERT;
231    out[0] = in[0];
232    out[1] = in[1];
233    out[2] = 0;
234 }
235
236 static INLINE void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
237 {
238    GLfloat *out = (GLfloat *)(v);
239    (void) a;
240    DEBUG_INSERT;
241    out[0] = in[0];
242    out[1] = 0;
243    out[2] = 0;
244 }
245
246
247 static INLINE void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
248 {
249    GLfloat *out = (GLfloat *)(v);
250    (void) a;
251    DEBUG_INSERT;
252    out[0] = in[0];
253    out[1] = in[1];
254 }
255
256 static INLINE void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
257 {
258    GLfloat *out = (GLfloat *)(v);
259    (void) a;
260    DEBUG_INSERT;
261    out[0] = in[0];
262    out[1] = 0;
263 }
264
265 static INLINE void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
266 {
267    GLfloat *out = (GLfloat *)(v);
268    (void) a;
269    DEBUG_INSERT;
270    out[0] = in[0];
271 }
272
273 static INLINE void insert_null( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
274 {
275    DEBUG_INSERT;
276    (void) a; (void) v; (void) in;
277 }
278
279 static INLINE void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
280                                   const GLfloat *in )
281 {
282    GLchan *c = (GLchan *)v;
283    DEBUG_INSERT;
284    (void) a;
285    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
286    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
287    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
288    UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
289 }
290
291 static INLINE void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
292                                   const GLfloat *in )
293 {
294    GLchan *c = (GLchan *)v;
295    DEBUG_INSERT;
296    (void) a;
297    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
298    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
299    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
300    c[3] = CHAN_MAX;
301 }
302
303 static INLINE void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
304                                   const GLfloat *in )
305 {
306    GLchan *c = (GLchan *)v;
307    DEBUG_INSERT;
308    (void) a;
309    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
310    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
311    c[2] = 0;
312    c[3] = CHAN_MAX;
313 }
314
315 static INLINE void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
316                                   const GLfloat *in )
317 {
318    GLchan *c = (GLchan *)v;
319    DEBUG_INSERT;
320    (void) a;
321    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
322    c[1] = 0;
323    c[2] = 0;
324    c[3] = CHAN_MAX;
325 }
326
327 static INLINE void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
328                                 const GLfloat *in )
329 {
330    DEBUG_INSERT;
331    (void) a;
332    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
333    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
334    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
335    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
336 }
337
338 static INLINE void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
339                                 const GLfloat *in )
340 {
341    DEBUG_INSERT;
342    (void) a;
343    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
344    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
345    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
346    v[3] = 0xff;
347 }
348
349 static INLINE void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
350                                 const GLfloat *in )
351 {
352    DEBUG_INSERT;
353    (void) a;
354    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
355    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
356    v[2] = 0;
357    v[3] = 0xff;
358 }
359
360 static INLINE void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
361                                 const GLfloat *in )
362 {
363    DEBUG_INSERT;
364    (void) a;
365    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
366    v[1] = 0;
367    v[2] = 0;
368    v[3] = 0xff;
369 }
370
371 static INLINE void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
372                                 const GLfloat *in )
373 {
374    DEBUG_INSERT;
375    (void) a;
376    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
377    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
378    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
379    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
380 }
381
382 static INLINE void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
383                                 const GLfloat *in )
384 {
385    DEBUG_INSERT;
386    (void) a;
387    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
388    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
389    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
390    v[3] = 0xff;
391 }
392
393 static INLINE void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
394                                 const GLfloat *in )
395 {
396    DEBUG_INSERT;
397    (void) a;
398    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
399    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
400    v[0] = 0;
401    v[3] = 0xff;
402 }
403
404 static INLINE void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
405                                 const GLfloat *in )
406 {
407    DEBUG_INSERT;
408    (void) a;
409    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
410    v[1] = 0;
411    v[0] = 0;
412    v[3] = 0xff;
413 }
414
415 static INLINE void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
416                                 const GLfloat *in )
417 {
418    DEBUG_INSERT;
419    (void) a;
420    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
421    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
422    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
423    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
424 }
425
426 static INLINE void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
427                                 const GLfloat *in )
428 {
429    DEBUG_INSERT;
430    (void) a;
431    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
432    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
433    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
434    v[0] = 0xff;
435 }
436
437 static INLINE void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
438                                 const GLfloat *in )
439 {
440    DEBUG_INSERT;
441    (void) a;
442    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
443    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
444    v[3] = 0x00;
445    v[0] = 0xff;
446 }
447
448 static INLINE void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
449                                 const GLfloat *in )
450 {
451    DEBUG_INSERT;
452    (void) a;
453    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
454    v[2] = 0x00;
455    v[3] = 0x00;
456    v[0] = 0xff;
457 }
458
459 static INLINE void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
460                                 const GLfloat *in )
461 {
462    DEBUG_INSERT;
463    (void) a;
464    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
465    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
466    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
467    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
468 }
469
470 static INLINE void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
471                                 const GLfloat *in )
472 {
473    DEBUG_INSERT;
474    (void) a;
475    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
476    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
477    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
478    v[0] = 0xff;
479 }
480
481 static INLINE void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
482                                 const GLfloat *in )
483 {
484    DEBUG_INSERT;
485    (void) a;
486    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
487    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
488    v[1] = 0x00;
489    v[0] = 0xff;
490 }
491
492 static INLINE void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
493                                 const GLfloat *in )
494 {
495    DEBUG_INSERT;
496    (void) a;
497    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
498    v[2] = 0x00;
499    v[1] = 0x00;
500    v[0] = 0xff;
501 }
502
503 static INLINE void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
504                                const GLfloat *in )
505 {
506    DEBUG_INSERT;
507    (void) a;
508    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
509    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
510    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
511 }
512
513 static INLINE void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
514                                const GLfloat *in )
515 {
516    DEBUG_INSERT;
517    (void) a;
518    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
519    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
520    v[2] = 0;
521 }
522
523 static INLINE void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
524                                const GLfloat *in )
525 {
526    DEBUG_INSERT;
527    (void) a;
528    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
529    v[1] = 0;
530    v[2] = 0;
531 }
532
533 static INLINE void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
534                                  const GLfloat *in )
535 {
536    DEBUG_INSERT;
537    (void) a;
538    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
539    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
540    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
541 }
542
543 static INLINE void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
544                                  const GLfloat *in )
545 {
546    DEBUG_INSERT;
547    (void) a;
548    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
549    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
550    v[0] = 0;
551 }
552
553 static INLINE void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
554                                  const GLfloat *in )
555 {
556    DEBUG_INSERT;
557    (void) a;
558    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
559    v[1] = 0;
560    v[0] = 0;
561 }
562
563
564 static INLINE void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
565                            const GLfloat *in )
566 {
567    DEBUG_INSERT;
568    (void) a;
569    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
570 }
571
572
573 /***********************************************************************
574  * Functions to perform the reverse operations to the above, for
575  * swrast translation and clip-interpolation.
576  * 
577  * Currently always extracts a full 4 floats.
578  */
579
580 static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
581                                  const GLubyte *v )
582 {
583    const GLfloat *in = (const GLfloat *)v;
584    const GLfloat * const vp = a->vp;
585    
586    /* Although included for completeness, the position coordinate is
587     * usually handled differently during clipping.
588     */
589    DEBUG_INSERT;
590    out[0] = (in[0] - vp[12]) / vp[0];
591    out[1] = (in[1] - vp[13]) / vp[5];
592    out[2] = (in[2] - vp[14]) / vp[10];
593    out[3] = in[3];
594 }
595
596 static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
597                                  const GLubyte *v )
598 {
599    const GLfloat *in = (const GLfloat *)v;
600    const GLfloat * const vp = a->vp;
601    DEBUG_INSERT;
602    out[0] = (in[0] - vp[12]) / vp[0];
603    out[1] = (in[1] - vp[13]) / vp[5];
604    out[2] = (in[2] - vp[14]) / vp[10];
605    out[3] = 1;
606 }
607
608
609 static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
610                                  const GLubyte *v )
611 {
612    const GLfloat *in = (const GLfloat *)v;
613    const GLfloat * const vp = a->vp;
614    DEBUG_INSERT;
615    out[0] = (in[0] - vp[12]) / vp[0];
616    out[1] = (in[1] - vp[13]) / vp[5];
617    out[2] = 0;
618    out[3] = 1;
619 }
620
621
622 static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v  )
623 {
624    const GLfloat *in = (const GLfloat *)v;
625    (void) a;
626    
627    out[0] = in[0];
628    out[1] = in[1];
629    out[2] = in[2];
630    out[3] = in[3];
631 }
632
633 static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
634 {
635    const GLfloat *in = (const GLfloat *)v;
636    (void) a;
637    
638    out[0] = in[0];
639    out[1] = in[1];
640    out[2] = 0;
641    out[3] = in[2];
642 }
643
644
645 static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
646 {
647    const GLfloat *in = (const GLfloat *)v;
648    (void) a;
649    
650    out[0] = in[0];
651    out[1] = in[1];
652    out[2] = in[2];
653    out[3] = 1;
654 }
655
656
657 static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
658 {
659    const GLfloat *in = (const GLfloat *)v;
660    (void) a;
661    
662    out[0] = in[0];
663    out[1] = in[1];
664    out[2] = 0;
665    out[3] = 1;
666 }
667
668 static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
669 {
670    const GLfloat *in = (const GLfloat *)v;
671    (void) a;
672    
673    out[0] = in[0];
674    out[1] = 0;
675    out[2] = 0;
676    out[3] = 1;
677 }
678
679 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
680                                  const GLubyte *v )
681 {
682    GLchan *c = (GLchan *)v;
683    (void) a;
684
685    out[0] = CHAN_TO_FLOAT(c[0]);
686    out[1] = CHAN_TO_FLOAT(c[1]);
687    out[2] = CHAN_TO_FLOAT(c[2]);
688    out[3] = CHAN_TO_FLOAT(c[3]);
689 }
690
691 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
692                                  const GLubyte *v )
693 {
694    (void) a;
695    out[0] = UBYTE_TO_FLOAT(v[0]);
696    out[1] = UBYTE_TO_FLOAT(v[1]);
697    out[2] = UBYTE_TO_FLOAT(v[2]);
698    out[3] = UBYTE_TO_FLOAT(v[3]);
699 }
700
701 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out, 
702                                  const GLubyte *v )
703 {
704    (void) a;
705    out[2] = UBYTE_TO_FLOAT(v[0]);
706    out[1] = UBYTE_TO_FLOAT(v[1]);
707    out[0] = UBYTE_TO_FLOAT(v[2]);
708    out[3] = UBYTE_TO_FLOAT(v[3]);
709 }
710
711 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr *a, GLfloat *out, 
712                                  const GLubyte *v )
713 {
714    (void) a;
715    out[3] = UBYTE_TO_FLOAT(v[0]);
716    out[0] = UBYTE_TO_FLOAT(v[1]);
717    out[1] = UBYTE_TO_FLOAT(v[2]);
718    out[2] = UBYTE_TO_FLOAT(v[3]);
719 }
720
721 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr *a, GLfloat *out, 
722                                  const GLubyte *v )
723 {
724    (void) a;
725    out[3] = UBYTE_TO_FLOAT(v[0]);
726    out[2] = UBYTE_TO_FLOAT(v[1]);
727    out[1] = UBYTE_TO_FLOAT(v[2]);
728    out[0] = UBYTE_TO_FLOAT(v[3]);
729 }
730
731 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out, 
732                                 const GLubyte *v )
733 {
734    (void) a;
735    out[0] = UBYTE_TO_FLOAT(v[0]);
736    out[1] = UBYTE_TO_FLOAT(v[1]);
737    out[2] = UBYTE_TO_FLOAT(v[2]);
738    out[3] = 1;
739 }
740
741 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out, 
742                                 const GLubyte *v )
743 {
744    (void) a;
745    out[2] = UBYTE_TO_FLOAT(v[0]);
746    out[1] = UBYTE_TO_FLOAT(v[1]);
747    out[0] = UBYTE_TO_FLOAT(v[2]);
748    out[3] = 1;
749 }
750
751 static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
752 {
753    (void) a;
754    out[0] = UBYTE_TO_FLOAT(v[0]);
755    out[1] = 0;
756    out[2] = 0;
757    out[3] = 1;
758 }
759
760
761 const struct tnl_format_info _tnl_format_info[EMIT_MAX] = 
762 {
763    { "1f",
764      extract_1f,
765      { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
766      sizeof(GLfloat) },
767
768    { "2f",
769      extract_2f,
770      { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
771      2 * sizeof(GLfloat) },
772
773    { "3f",
774      extract_3f,
775      { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
776      3 * sizeof(GLfloat) },
777
778    { "4f",
779      extract_4f,
780      { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
781      4 * sizeof(GLfloat) },
782
783    { "2f_viewport",
784      extract_2f_viewport,
785      { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
786        insert_2f_viewport_2 },
787      2 * sizeof(GLfloat) },
788
789    { "3f_viewport",
790      extract_3f_viewport,
791      { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
792        insert_3f_viewport_3 },
793      3 * sizeof(GLfloat) },
794
795    { "4f_viewport",
796      extract_4f_viewport,
797      { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
798        insert_4f_viewport_4 }, 
799      4 * sizeof(GLfloat) },
800
801    { "3f_xyw",
802      extract_3f_xyw,
803      { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, 
804        insert_3f_xyw_4 },
805      3 * sizeof(GLfloat) },
806
807    { "1ub_1f",
808      extract_1ub_1f,
809      { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
810      sizeof(GLubyte) },
811
812    { "3ub_3f_rgb",
813      extract_3ub_3f_rgb,
814      { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
815        insert_3ub_3f_rgb_3 },
816      3 * sizeof(GLubyte) },
817
818    { "3ub_3f_bgr",
819      extract_3ub_3f_bgr,
820      { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
821        insert_3ub_3f_bgr_3 },
822      3 * sizeof(GLubyte) },
823
824    { "4ub_4f_rgba",
825      extract_4ub_4f_rgba,
826      { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, 
827        insert_4ub_4f_rgba_4 },
828      4 * sizeof(GLubyte) },
829
830    { "4ub_4f_bgra",
831      extract_4ub_4f_bgra,
832      { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
833        insert_4ub_4f_bgra_4 },
834      4 * sizeof(GLubyte) },
835
836    { "4ub_4f_argb",
837      extract_4ub_4f_argb,
838      { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3,
839        insert_4ub_4f_argb_4 },
840      4 * sizeof(GLubyte) },
841
842    { "4ub_4f_abgr",
843      extract_4ub_4f_abgr,
844      { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3,
845        insert_4ub_4f_abgr_4 },
846      4 * sizeof(GLubyte) },
847
848    { "4chan_4f_rgba",
849      extract_4chan_4f_rgba,
850      { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
851        insert_4chan_4f_rgba_4 },
852      4 * sizeof(GLchan) },
853
854    { "pad",
855      NULL,
856      { NULL, NULL, NULL, NULL },
857      0 }
858
859 };
860
861
862
863     
864 /***********************************************************************
865  * Hardwired fastpaths for emitting whole vertices or groups of
866  * vertices
867  */
868 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME)                             \
869 static void NAME( struct gl_context *ctx,                                       \
870                   GLuint count,                                         \
871                   GLubyte *v )                                          \
872 {                                                                       \
873    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);                   \
874    struct tnl_clipspace_attr *a = vtx->attr;                            \
875    GLuint i;                                                            \
876                                                                         \
877    for (i = 0 ; i < count ; i++, v += vtx->vertex_size) {               \
878       if (NR > 0) {                                                     \
879          F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr );    \
880          a[0].inputptr += a[0].inputstride;                             \
881       }                                                                 \
882                                                                         \
883       if (NR > 1) {                                                     \
884          F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr );    \
885          a[1].inputptr += a[1].inputstride;                             \
886       }                                                                 \
887                                                                         \
888       if (NR > 2) {                                                     \
889          F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr );    \
890          a[2].inputptr += a[2].inputstride;                             \
891       }                                                                 \
892                                                                         \
893       if (NR > 3) {                                                     \
894          F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr );    \
895          a[3].inputptr += a[3].inputstride;                             \
896       }                                                                 \
897                                                                         \
898       if (NR > 4) {                                                     \
899          F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr );    \
900          a[4].inputptr += a[4].inputstride;                             \
901       }                                                                 \
902    }                                                                    \
903 }
904
905    
906 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
907                                   insert_null, insert_null, NAME)
908
909 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
910                                       insert_null, NAME)
911    
912 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
913                                           insert_null, NAME)
914    
915
916 EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4)
917 EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4)
918 EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
919
920 EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2)
921 EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2,  emit_viewport4_bgra4_st2)
922 EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
923
924 EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2)
925 EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2,  emit_viewport4_bgra4_st2_st2)
926 EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
927
928
929 /* Use the codegen paths to select one of a number of hardwired
930  * fastpaths.
931  */
932 void _tnl_generate_hardwired_emit( struct gl_context *ctx )
933 {
934    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
935    tnl_emit_func func = NULL;
936
937    /* Does it fit a hardwired fastpath?  Help! this is growing out of
938     * control!
939     */
940    switch (vtx->attr_count) {
941    case 2:
942       if (vtx->attr[0].emit == insert_3f_viewport_3) {
943          if (vtx->attr[1].emit == insert_4ub_4f_bgra_4) 
944             func = emit_viewport3_bgra4;
945          else if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) 
946             func = emit_viewport3_rgba4;
947       }
948       else if (vtx->attr[0].emit == insert_3f_3 &&
949                vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
950          func = emit_xyz3_rgba4; 
951       }
952       break;
953    case 3:
954       if (vtx->attr[2].emit == insert_2f_2) {
955          if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
956             if (vtx->attr[0].emit == insert_4f_viewport_4)
957                func = emit_viewport4_rgba4_st2;
958             else if (vtx->attr[0].emit == insert_4f_4) 
959                func = emit_xyzw4_rgba4_st2;
960          }
961          else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
962                   vtx->attr[0].emit == insert_4f_viewport_4)
963             func = emit_viewport4_bgra4_st2;
964       }
965       break;
966    case 4:
967       if (vtx->attr[2].emit == insert_2f_2 &&
968           vtx->attr[3].emit == insert_2f_2) {
969          if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
970             if (vtx->attr[0].emit == insert_4f_viewport_4)
971                func = emit_viewport4_rgba4_st2_st2;
972             else if (vtx->attr[0].emit == insert_4f_4) 
973                func = emit_xyzw4_rgba4_st2_st2;
974          }
975          else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
976                   vtx->attr[0].emit == insert_4f_viewport_4)
977             func = emit_viewport4_bgra4_st2_st2;
978       }
979       break;
980    }
981
982    vtx->emit = func;
983 }
984
985 /***********************************************************************
986  * Generic (non-codegen) functions for whole vertices or groups of
987  * vertices
988  */
989
990 void _tnl_generic_emit( struct gl_context *ctx,
991                         GLuint count,
992                         GLubyte *v )
993 {
994    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
995    struct tnl_clipspace_attr *a = vtx->attr;
996    const GLuint attr_count = vtx->attr_count;
997    const GLuint stride = vtx->vertex_size;
998    GLuint i, j;
999
1000    for (i = 0 ; i < count ; i++, v += stride) {
1001       for (j = 0; j < attr_count; j++) {
1002          GLfloat *in = (GLfloat *)a[j].inputptr;
1003          a[j].inputptr += a[j].inputstride;
1004          a[j].emit( &a[j], v + a[j].vertoffset, in );
1005       }
1006    }
1007 }
1008
1009
1010 void _tnl_generic_interp( struct gl_context *ctx,
1011                             GLfloat t,
1012                             GLuint edst, GLuint eout, GLuint ein,
1013                             GLboolean force_boundary )
1014 {
1015    TNLcontext *tnl = TNL_CONTEXT(ctx);
1016    struct vertex_buffer *VB = &tnl->vb;
1017    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1018    const GLubyte *vin  = vtx->vertex_buf + ein  * vtx->vertex_size;
1019    const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
1020    GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
1021    const struct tnl_clipspace_attr *a = vtx->attr;
1022    const GLuint attr_count = vtx->attr_count;
1023    GLuint j;
1024    (void) force_boundary;
1025
1026    if (tnl->NeedNdcCoords) {
1027       const GLfloat *dstclip = VB->ClipPtr->data[edst];
1028       if (dstclip[3] != 0.0) {
1029          const GLfloat w = 1.0f / dstclip[3];
1030          GLfloat pos[4];
1031
1032          pos[0] = dstclip[0] * w;
1033          pos[1] = dstclip[1] * w;
1034          pos[2] = dstclip[2] * w;
1035          pos[3] = w;
1036
1037          a[0].insert[4-1]( &a[0], vdst, pos );
1038       }
1039    }
1040    else {
1041       a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
1042    }
1043
1044
1045    for (j = 1; j < attr_count; j++) {
1046       GLfloat fin[4], fout[4], fdst[4];
1047          
1048       a[j].extract( &a[j], fin, vin + a[j].vertoffset );
1049       a[j].extract( &a[j], fout, vout + a[j].vertoffset );
1050
1051       INTERP_F( t, fdst[3], fout[3], fin[3] );
1052       INTERP_F( t, fdst[2], fout[2], fin[2] );
1053       INTERP_F( t, fdst[1], fout[1], fin[1] );
1054       INTERP_F( t, fdst[0], fout[0], fin[0] );
1055
1056       a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
1057    }
1058 }
1059
1060
1061 /* Extract color attributes from one vertex and insert them into
1062  * another.  (Shortcircuit extract/insert with memcpy).
1063  */
1064 void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc )
1065 {
1066    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1067    GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
1068    GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
1069    const struct tnl_clipspace_attr *a = vtx->attr;
1070    const GLuint attr_count = vtx->attr_count;
1071    GLuint j;
1072
1073    for (j = 0; j < attr_count; j++) {
1074       if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
1075           a[j].attrib == VERT_ATTRIB_COLOR1) {
1076
1077          memcpy( vdst + a[j].vertoffset,
1078                  vsrc + a[j].vertoffset,
1079                  a[j].vertattrsize );
1080       }
1081    }
1082 }
1083
1084
1085 /* Helper functions for hardware which doesn't put back colors and/or
1086  * edgeflags into vertices.
1087  */
1088 void _tnl_generic_interp_extras( struct gl_context *ctx,
1089                                    GLfloat t,
1090                                    GLuint dst, GLuint out, GLuint in,
1091                                    GLboolean force_boundary )
1092 {
1093    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
1094
1095    /* If stride is zero, BackfaceColorPtr is constant across the VB, so
1096     * there is no point interpolating between two values as they will
1097     * be identical.  In all other cases, this value is generated by
1098     * t_vb_lighttmp.h and has a stride of 4 dwords.
1099     */
1100    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
1101       assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
1102
1103       INTERP_4F( t,
1104                  VB->BackfaceColorPtr->data[dst],
1105                  VB->BackfaceColorPtr->data[out],
1106                  VB->BackfaceColorPtr->data[in] );
1107    }
1108
1109    if (VB->BackfaceSecondaryColorPtr) {
1110       assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat));
1111       
1112       INTERP_3F( t,
1113                  VB->BackfaceSecondaryColorPtr->data[dst],
1114                  VB->BackfaceSecondaryColorPtr->data[out],
1115                  VB->BackfaceSecondaryColorPtr->data[in] );
1116    }
1117    
1118    if (VB->BackfaceIndexPtr) {
1119       VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t,
1120                                                VB->BackfaceIndexPtr->data[out][0],
1121                                                VB->BackfaceIndexPtr->data[in][0] );
1122    }
1123
1124    if (VB->EdgeFlag) {
1125       VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
1126    }
1127
1128    _tnl_generic_interp(ctx, t, dst, out, in, force_boundary);
1129 }
1130
1131 void _tnl_generic_copy_pv_extras( struct gl_context *ctx, 
1132                                   GLuint dst, GLuint src )
1133 {
1134    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
1135
1136    /* See above comment:
1137     */
1138    if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
1139       COPY_4FV( VB->BackfaceColorPtr->data[dst],
1140                 VB->BackfaceColorPtr->data[src] );
1141    }
1142
1143    if (VB->BackfaceSecondaryColorPtr) {
1144       COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst],
1145                 VB->BackfaceSecondaryColorPtr->data[src] );
1146    }
1147
1148    if (VB->BackfaceIndexPtr) {
1149       VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0];
1150    }
1151
1152    _tnl_generic_copy_pv(ctx, dst, src);
1153 }
1154
1155