Merge commit 'origin/master' into gallium-0.2
[profile/ivi/mesa.git] / src / mesa / vf / vf_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
34 #include "vf/vf.h"
35
36
37 /*
38  * These functions take the NDC coordinates pointed to by 'in', apply the
39  * NDC->Viewport mapping and store the results at 'v'.
40  */
41
42 static INLINE void insert_4f_viewport_4( const struct vf_attr *a, GLubyte *v,
43                                          const GLfloat *in )
44 {
45    GLfloat *out = (GLfloat *)v;
46    const GLfloat *scale = a->vf->vp;
47    const GLfloat *trans = a->vf->vp + 4;
48    
49    out[0] = scale[0] * in[0] + trans[0];
50    out[1] = scale[1] * in[1] + trans[1];
51    out[2] = scale[2] * in[2] + trans[2];
52    out[3] = in[3];
53 }
54
55 static INLINE void insert_4f_viewport_3( const struct vf_attr *a, GLubyte *v,
56                                          const GLfloat *in )
57 {
58    GLfloat *out = (GLfloat *)v;
59    const GLfloat *scale = a->vf->vp;
60    const GLfloat *trans = a->vf->vp + 4;
61    
62    out[0] = scale[0] * in[0] + trans[0];
63    out[1] = scale[1] * in[1] + trans[1];
64    out[2] = scale[2] * in[2] + trans[2];
65    out[3] = 1;
66 }
67
68 static INLINE void insert_4f_viewport_2( const struct vf_attr *a, GLubyte *v,
69                                          const GLfloat *in )
70 {
71    GLfloat *out = (GLfloat *)v;
72    const GLfloat *scale = a->vf->vp;
73    const GLfloat *trans = a->vf->vp + 4;
74    
75    out[0] = scale[0] * in[0] + trans[0];
76    out[1] = scale[1] * in[1] + trans[1];
77    out[2] =                    trans[2];
78    out[3] = 1;
79 }
80
81 static INLINE void insert_4f_viewport_1( const struct vf_attr *a, GLubyte *v,
82                                          const GLfloat *in )
83 {
84    GLfloat *out = (GLfloat *)v;
85    const GLfloat *scale = a->vf->vp;
86    const GLfloat *trans = a->vf->vp + 4;
87    
88    out[0] = scale[0] * in[0] + trans[0];
89    out[1] =                    trans[1];
90    out[2] =                    trans[2];
91    out[3] = 1;
92 }
93
94 static INLINE void insert_3f_viewport_3( const struct vf_attr *a, GLubyte *v,
95                                          const GLfloat *in )
96 {
97    GLfloat *out = (GLfloat *)v;
98    const GLfloat *scale = a->vf->vp;
99    const GLfloat *trans = a->vf->vp + 4;
100    
101    out[0] = scale[0] * in[0] + trans[0];
102    out[1] = scale[1] * in[1] + trans[1];
103    out[2] = scale[2] * in[2] + trans[2];
104 }
105
106 static INLINE void insert_3f_viewport_2( const struct vf_attr *a, GLubyte *v,
107                                          const GLfloat *in )
108 {
109    GLfloat *out = (GLfloat *)v;
110    const GLfloat *scale = a->vf->vp;
111    const GLfloat *trans = a->vf->vp + 4;
112    
113    out[0] = scale[0] * in[0] + trans[0];
114    out[1] = scale[1] * in[1] + trans[1];
115    out[2] = scale[2] * in[2] + trans[2];
116 }
117
118 static INLINE void insert_3f_viewport_1( const struct vf_attr *a, GLubyte *v,
119                                          const GLfloat *in )
120 {
121    GLfloat *out = (GLfloat *)v;
122    const GLfloat *scale = a->vf->vp;
123    const GLfloat *trans = a->vf->vp + 4;
124    
125    out[0] = scale[0] * in[0] + trans[0];
126    out[1] =                    trans[1];
127    out[2] =                    trans[2];
128 }
129
130 static INLINE void insert_2f_viewport_2( const struct vf_attr *a, GLubyte *v,
131                                          const GLfloat *in )
132 {
133    GLfloat *out = (GLfloat *)v;
134    const GLfloat *scale = a->vf->vp;
135    const GLfloat *trans = a->vf->vp + 4;
136    
137    out[0] = scale[0] * in[0] + trans[0];
138    out[1] = scale[1] * in[1] + trans[1];
139 }
140
141 static INLINE void insert_2f_viewport_1( const struct vf_attr *a, GLubyte *v,
142                                          const GLfloat *in )
143 {
144    GLfloat *out = (GLfloat *)v;
145    const GLfloat *scale = a->vf->vp;
146    const GLfloat *trans = a->vf->vp + 4;
147    
148    out[0] = scale[0] * in[0] + trans[0];
149    out[1] = trans[1];
150 }
151
152
153 /*
154  * These functions do the same as above, except for the viewport mapping.
155  */
156
157 static INLINE void insert_4f_4( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
158 {
159    GLfloat *out = (GLfloat *)(v);
160    (void) a;
161    
162    out[0] = in[0];
163    out[1] = in[1];
164    out[2] = in[2];
165    out[3] = in[3];
166 }
167
168 static INLINE void insert_4f_3( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
169 {
170    GLfloat *out = (GLfloat *)(v);
171    (void) a;
172    
173    out[0] = in[0];
174    out[1] = in[1];
175    out[2] = in[2];
176    out[3] = 1;
177 }
178
179 static INLINE void insert_4f_2( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
180 {
181    GLfloat *out = (GLfloat *)(v);
182    (void) a;
183    
184    out[0] = in[0];
185    out[1] = in[1];
186    out[2] = 0;
187    out[3] = 1;
188 }
189
190 static INLINE void insert_4f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
191 {
192    GLfloat *out = (GLfloat *)(v);
193    (void) a;
194    
195    out[0] = in[0];
196    out[1] = 0;
197    out[2] = 0;
198    out[3] = 1;
199 }
200
201 static INLINE void insert_3f_xyw_4( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
202 {
203    GLfloat *out = (GLfloat *)(v);
204    (void) a;
205    
206    out[0] = in[0];
207    out[1] = in[1];
208    out[2] = in[3];
209 }
210
211 static INLINE void insert_3f_xyw_err( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
212 {
213    (void) a; (void) v; (void) in;
214    _mesa_exit(1);
215 }
216
217 static INLINE void insert_3f_3( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
218 {
219    GLfloat *out = (GLfloat *)(v);
220    (void) a;
221    
222    out[0] = in[0];
223    out[1] = in[1];
224    out[2] = in[2];
225 }
226
227 static INLINE void insert_3f_2( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
228 {
229    GLfloat *out = (GLfloat *)(v);
230    (void) a;
231    
232    out[0] = in[0];
233    out[1] = in[1];
234    out[2] = 0;
235 }
236
237 static INLINE void insert_3f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
238 {
239    GLfloat *out = (GLfloat *)(v);
240    (void) a;
241    
242    out[0] = in[0];
243    out[1] = 0;
244    out[2] = 0;
245 }
246
247
248 static INLINE void insert_2f_2( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
249 {
250    GLfloat *out = (GLfloat *)(v);
251    (void) a;
252    
253    out[0] = in[0];
254    out[1] = in[1];
255 }
256
257 static INLINE void insert_2f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
258 {
259    GLfloat *out = (GLfloat *)(v);
260    (void) a;
261    
262    out[0] = in[0];
263    out[1] = 0;
264 }
265
266 static INLINE void insert_1f_1( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
267 {
268    GLfloat *out = (GLfloat *)(v);
269    (void) a;
270
271    out[0] = in[0];
272 }
273
274 static INLINE void insert_null( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
275 {
276    (void) a; (void) v; (void) in;
277 }
278
279 static INLINE void insert_4chan_4f_rgba_4( const struct vf_attr *a, GLubyte *v, 
280                                            const GLfloat *in )
281 {
282    GLchan *c = (GLchan *)v;
283    (void) a;
284    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
285    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
286    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
287    UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
288 }
289
290 static INLINE void insert_4chan_4f_rgba_3( const struct vf_attr *a, GLubyte *v, 
291                                            const GLfloat *in )
292 {
293    GLchan *c = (GLchan *)v;
294    (void) a;
295    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
296    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
297    UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
298    c[3] = CHAN_MAX;
299 }
300
301 static INLINE void insert_4chan_4f_rgba_2( const struct vf_attr *a, GLubyte *v, 
302                                            const GLfloat *in )
303 {
304    GLchan *c = (GLchan *)v;
305    (void) a;
306    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
307    UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
308    c[2] = 0;
309    c[3] = CHAN_MAX;
310 }
311
312 static INLINE void insert_4chan_4f_rgba_1( const struct vf_attr *a, GLubyte *v, 
313                                            const GLfloat *in )
314 {
315    GLchan *c = (GLchan *)v;
316    (void) a;
317    UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
318    c[1] = 0;
319    c[2] = 0;
320    c[3] = CHAN_MAX;
321 }
322
323 static INLINE void insert_4ub_4f_rgba_4( const struct vf_attr *a, GLubyte *v, 
324                                          const GLfloat *in )
325 {
326    (void) a;
327    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
328    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
329    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
330    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
331 }
332
333 static INLINE void insert_4ub_4f_rgba_3( const struct vf_attr *a, GLubyte *v, 
334                                          const GLfloat *in )
335 {
336    (void) a;
337    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
338    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
339    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
340    v[3] = 0xff;
341 }
342
343 static INLINE void insert_4ub_4f_rgba_2( const struct vf_attr *a, GLubyte *v, 
344                                          const GLfloat *in )
345 {
346    (void) a;
347    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
348    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
349    v[2] = 0;
350    v[3] = 0xff;
351 }
352
353 static INLINE void insert_4ub_4f_rgba_1( const struct vf_attr *a, GLubyte *v, 
354                                          const GLfloat *in )
355 {
356    (void) a;
357    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
358    v[1] = 0;
359    v[2] = 0;
360    v[3] = 0xff;
361 }
362
363 static INLINE void insert_4ub_4f_bgra_4( const struct vf_attr *a, GLubyte *v, 
364                                          const GLfloat *in )
365 {
366    (void) a;
367    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
368    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
369    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
370    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
371 }
372
373 static INLINE void insert_4ub_4f_bgra_3( const struct vf_attr *a, GLubyte *v, 
374                                          const GLfloat *in )
375 {
376    (void) a;
377    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
378    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
379    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
380    v[3] = 0xff;
381 }
382
383 static INLINE void insert_4ub_4f_bgra_2( const struct vf_attr *a, GLubyte *v, 
384                                          const GLfloat *in )
385 {
386    (void) a;
387    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
388    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
389    v[0] = 0;
390    v[3] = 0xff;
391 }
392
393 static INLINE void insert_4ub_4f_bgra_1( const struct vf_attr *a, GLubyte *v, 
394                                          const GLfloat *in )
395 {
396    (void) a;
397    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
398    v[1] = 0;
399    v[0] = 0;
400    v[3] = 0xff;
401 }
402
403 static INLINE void insert_4ub_4f_argb_4( const struct vf_attr *a, GLubyte *v, 
404                                          const GLfloat *in )
405 {
406    (void) a;
407    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
408    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
409    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
410    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
411 }
412
413 static INLINE void insert_4ub_4f_argb_3( const struct vf_attr *a, GLubyte *v, 
414                                          const GLfloat *in )
415 {
416    (void) a;
417    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
418    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
419    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
420    v[0] = 0xff;
421 }
422
423 static INLINE void insert_4ub_4f_argb_2( const struct vf_attr *a, GLubyte *v, 
424                                          const GLfloat *in )
425 {
426    (void) a;
427    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
428    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
429    v[3] = 0x00;
430    v[0] = 0xff;
431 }
432
433 static INLINE void insert_4ub_4f_argb_1( const struct vf_attr *a, GLubyte *v, 
434                                          const GLfloat *in )
435 {
436    (void) a;
437    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
438    v[2] = 0x00;
439    v[3] = 0x00;
440    v[0] = 0xff;
441 }
442
443 static INLINE void insert_4ub_4f_abgr_4( const struct vf_attr *a, GLubyte *v, 
444                                          const GLfloat *in )
445 {
446    (void) a;
447    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
448    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
449    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
450    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
451 }
452
453 static INLINE void insert_4ub_4f_abgr_3( const struct vf_attr *a, GLubyte *v, 
454                                          const GLfloat *in )
455 {
456    (void) a;
457    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
458    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
459    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
460    v[0] = 0xff;
461 }
462
463 static INLINE void insert_4ub_4f_abgr_2( const struct vf_attr *a, GLubyte *v, 
464                                          const GLfloat *in )
465 {
466    (void) a;
467    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
468    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
469    v[1] = 0x00;
470    v[0] = 0xff;
471 }
472
473 static INLINE void insert_4ub_4f_abgr_1( const struct vf_attr *a, GLubyte *v, 
474                                          const GLfloat *in )
475 {
476    (void) a;
477    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
478    v[2] = 0x00;
479    v[1] = 0x00;
480    v[0] = 0xff;
481 }
482
483 static INLINE void insert_3ub_3f_rgb_3( const struct vf_attr *a, GLubyte *v, 
484                                         const GLfloat *in )
485 {
486    (void) a;
487    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
488    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
489    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
490 }
491
492 static INLINE void insert_3ub_3f_rgb_2( const struct vf_attr *a, GLubyte *v, 
493                                         const GLfloat *in )
494 {
495    (void) a;
496    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
497    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
498    v[2] = 0;
499 }
500
501 static INLINE void insert_3ub_3f_rgb_1( const struct vf_attr *a, GLubyte *v, 
502                                         const GLfloat *in )
503 {
504    (void) a;
505    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
506    v[1] = 0;
507    v[2] = 0;
508 }
509
510 static INLINE void insert_3ub_3f_bgr_3( const struct vf_attr *a, GLubyte *v, 
511                                         const GLfloat *in )
512 {
513    (void) a;
514    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
515    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
516    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
517 }
518
519 static INLINE void insert_3ub_3f_bgr_2( const struct vf_attr *a, GLubyte *v, 
520                                         const GLfloat *in )
521 {
522    (void) a;
523    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
524    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
525    v[0] = 0;
526 }
527
528 static INLINE void insert_3ub_3f_bgr_1( const struct vf_attr *a, GLubyte *v, 
529                                         const GLfloat *in )
530 {
531    (void) a;
532    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
533    v[1] = 0;
534    v[0] = 0;
535 }
536
537
538 static INLINE void insert_1ub_1f_1( const struct vf_attr *a, GLubyte *v, 
539                                     const GLfloat *in )
540 {
541    (void) a;
542    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
543 }
544
545
546 /***********************************************************************
547  * Functions to perform the reverse operations to the above, for
548  * swrast translation and clip-interpolation.
549  * 
550  * Currently always extracts a full 4 floats.
551  */
552
553 static void extract_4f_viewport( const struct vf_attr *a, GLfloat *out, 
554                                  const GLubyte *v )
555 {
556    const GLfloat *in = (const GLfloat *)v;
557    const GLfloat *scale = a->vf->vp;
558    const GLfloat *trans = a->vf->vp + 4;
559    
560    /* Although included for completeness, the position coordinate is
561     * usually handled differently during clipping.
562     */
563    out[0] = (in[0] - trans[0]) / scale[0];
564    out[1] = (in[1] - trans[1]) / scale[1];
565    out[2] = (in[2] - trans[2]) / scale[2];
566    out[3] = in[3];
567 }
568
569 static void extract_3f_viewport( const struct vf_attr *a, GLfloat *out, 
570                                  const GLubyte *v )
571 {
572    const GLfloat *in = (const GLfloat *)v;
573    const GLfloat *scale = a->vf->vp;
574    const GLfloat *trans = a->vf->vp + 4;
575    
576    out[0] = (in[0] - trans[0]) / scale[0];
577    out[1] = (in[1] - trans[1]) / scale[1];
578    out[2] = (in[2] - trans[2]) / scale[2];
579    out[3] = 1;
580 }
581
582
583 static void extract_2f_viewport( const struct vf_attr *a, GLfloat *out, 
584                                  const GLubyte *v )
585 {
586    const GLfloat *in = (const GLfloat *)v;
587    const GLfloat *scale = a->vf->vp;
588    const GLfloat *trans = a->vf->vp + 4;
589    
590    out[0] = (in[0] - trans[0]) / scale[0];
591    out[1] = (in[1] - trans[1]) / scale[1];
592    out[2] = 0;
593    out[3] = 1;
594 }
595
596
597 static void extract_4f( const struct vf_attr *a, GLfloat *out, const GLubyte *v  )
598 {
599    const GLfloat *in = (const GLfloat *)v;
600    (void) a;
601    
602    out[0] = in[0];
603    out[1] = in[1];
604    out[2] = in[2];
605    out[3] = in[3];
606 }
607
608 static void extract_3f_xyw( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
609 {
610    const GLfloat *in = (const GLfloat *)v;
611    (void) a;
612    
613    out[0] = in[0];
614    out[1] = in[1];
615    out[2] = 0;
616    out[3] = in[2];
617 }
618
619
620 static void extract_3f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
621 {
622    const GLfloat *in = (const GLfloat *)v;
623    (void) a;
624    
625    out[0] = in[0];
626    out[1] = in[1];
627    out[2] = in[2];
628    out[3] = 1;
629 }
630
631
632 static void extract_2f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
633 {
634    const GLfloat *in = (const GLfloat *)v;
635    (void) a;
636    
637    out[0] = in[0];
638    out[1] = in[1];
639    out[2] = 0;
640    out[3] = 1;
641 }
642
643 static void extract_1f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
644 {
645    const GLfloat *in = (const GLfloat *)v;
646    (void) a;
647    
648    out[0] = in[0];
649    out[1] = 0;
650    out[2] = 0;
651    out[3] = 1;
652 }
653
654 static void extract_4chan_4f_rgba( const struct vf_attr *a, GLfloat *out, 
655                                    const GLubyte *v )
656 {
657    GLchan *c = (GLchan *)v;
658    (void) a;
659
660    out[0] = CHAN_TO_FLOAT(c[0]);
661    out[1] = CHAN_TO_FLOAT(c[1]);
662    out[2] = CHAN_TO_FLOAT(c[2]);
663    out[3] = CHAN_TO_FLOAT(c[3]);
664 }
665
666 static void extract_4ub_4f_rgba( const struct vf_attr *a, GLfloat *out, 
667                                  const GLubyte *v )
668 {
669    (void) a;
670    out[0] = UBYTE_TO_FLOAT(v[0]);
671    out[1] = UBYTE_TO_FLOAT(v[1]);
672    out[2] = UBYTE_TO_FLOAT(v[2]);
673    out[3] = UBYTE_TO_FLOAT(v[3]);
674 }
675
676 static void extract_4ub_4f_bgra( const struct vf_attr *a, GLfloat *out, 
677                                  const GLubyte *v )
678 {
679    (void) a;
680    out[2] = UBYTE_TO_FLOAT(v[0]);
681    out[1] = UBYTE_TO_FLOAT(v[1]);
682    out[0] = UBYTE_TO_FLOAT(v[2]);
683    out[3] = UBYTE_TO_FLOAT(v[3]);
684 }
685
686 static void extract_4ub_4f_argb( const struct vf_attr *a, GLfloat *out, 
687                                  const GLubyte *v )
688 {
689    (void) a;
690    out[3] = UBYTE_TO_FLOAT(v[0]);
691    out[0] = UBYTE_TO_FLOAT(v[1]);
692    out[1] = UBYTE_TO_FLOAT(v[2]);
693    out[2] = UBYTE_TO_FLOAT(v[3]);
694 }
695
696 static void extract_4ub_4f_abgr( const struct vf_attr *a, GLfloat *out, 
697                                  const GLubyte *v )
698 {
699    (void) a;
700    out[3] = UBYTE_TO_FLOAT(v[0]);
701    out[2] = UBYTE_TO_FLOAT(v[1]);
702    out[1] = UBYTE_TO_FLOAT(v[2]);
703    out[0] = UBYTE_TO_FLOAT(v[3]);
704 }
705
706 static void extract_3ub_3f_rgb( const struct vf_attr *a, GLfloat *out, 
707                                 const GLubyte *v )
708 {
709    (void) a;
710    out[0] = UBYTE_TO_FLOAT(v[0]);
711    out[1] = UBYTE_TO_FLOAT(v[1]);
712    out[2] = UBYTE_TO_FLOAT(v[2]);
713    out[3] = 1;
714 }
715
716 static void extract_3ub_3f_bgr( const struct vf_attr *a, GLfloat *out, 
717                                 const GLubyte *v )
718 {
719    (void) a;
720    out[2] = UBYTE_TO_FLOAT(v[0]);
721    out[1] = UBYTE_TO_FLOAT(v[1]);
722    out[0] = UBYTE_TO_FLOAT(v[2]);
723    out[3] = 1;
724 }
725
726 static void extract_1ub_1f( const struct vf_attr *a, GLfloat *out, const GLubyte *v )
727 {
728    (void) a;
729    out[0] = UBYTE_TO_FLOAT(v[0]);
730    out[1] = 0;
731    out[2] = 0;
732    out[3] = 1;
733 }
734
735
736 const struct vf_format_info vf_format_info[EMIT_MAX] = 
737 {
738    { "1f",
739      extract_1f,
740      { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
741      sizeof(GLfloat) },
742
743    { "2f",
744      extract_2f,
745      { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
746      2 * sizeof(GLfloat) },
747
748    { "3f",
749      extract_3f,
750      { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
751      3 * sizeof(GLfloat) },
752
753    { "4f",
754      extract_4f,
755      { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
756      4 * sizeof(GLfloat) },
757
758    { "2f_viewport",
759      extract_2f_viewport,
760      { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
761        insert_2f_viewport_2 },
762      2 * sizeof(GLfloat) },
763
764    { "3f_viewport",
765      extract_3f_viewport,
766      { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
767        insert_3f_viewport_3 },
768      3 * sizeof(GLfloat) },
769
770    { "4f_viewport",
771      extract_4f_viewport,
772      { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
773        insert_4f_viewport_4 }, 
774      4 * sizeof(GLfloat) },
775
776    { "3f_xyw",
777      extract_3f_xyw,
778      { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, 
779        insert_3f_xyw_4 },
780      3 * sizeof(GLfloat) },
781
782    { "1ub_1f",
783      extract_1ub_1f,
784      { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
785      sizeof(GLubyte) },
786
787    { "3ub_3f_rgb",
788      extract_3ub_3f_rgb,
789      { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
790        insert_3ub_3f_rgb_3 },
791      3 * sizeof(GLubyte) },
792
793    { "3ub_3f_bgr",
794      extract_3ub_3f_bgr,
795      { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
796        insert_3ub_3f_bgr_3 },
797      3 * sizeof(GLubyte) },
798
799    { "4ub_4f_rgba",
800      extract_4ub_4f_rgba,
801      { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, 
802        insert_4ub_4f_rgba_4 },
803      4 * sizeof(GLubyte) },
804
805    { "4ub_4f_bgra",
806      extract_4ub_4f_bgra,
807      { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
808        insert_4ub_4f_bgra_4 },
809      4 * sizeof(GLubyte) },
810
811    { "4ub_4f_argb",
812      extract_4ub_4f_argb,
813      { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3,
814        insert_4ub_4f_argb_4 },
815      4 * sizeof(GLubyte) },
816
817    { "4ub_4f_abgr",
818      extract_4ub_4f_abgr,
819      { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3,
820        insert_4ub_4f_abgr_4 },
821      4 * sizeof(GLubyte) },
822
823    { "4chan_4f_rgba",
824      extract_4chan_4f_rgba,
825      { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
826        insert_4chan_4f_rgba_4 },
827      4 * sizeof(GLchan) },
828
829    { "pad",
830      NULL,
831      { NULL, NULL, NULL, NULL },
832      0 }
833
834 };
835
836
837
838     
839 /***********************************************************************
840  * Hardwired fastpaths for emitting whole vertices or groups of
841  * vertices
842  */
843 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME)                             \
844 static void NAME( struct vertex_fetch *vf,                              \
845                   GLuint count,                                         \
846                   GLubyte *v )                                          \
847 {                                                                       \
848    struct vf_attr *a = vf->attr;                                \
849    GLuint i;                                                            \
850                                                                         \
851    for (i = 0 ; i < count ; i++, v += vf->vertex_stride) {              \
852       if (NR > 0) {                                                     \
853          F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr );    \
854          a[0].inputptr += a[0].inputstride;                             \
855       }                                                                 \
856                                                                         \
857       if (NR > 1) {                                                     \
858          F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr );    \
859          a[1].inputptr += a[1].inputstride;                             \
860       }                                                                 \
861                                                                         \
862       if (NR > 2) {                                                     \
863          F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr );    \
864          a[2].inputptr += a[2].inputstride;                             \
865       }                                                                 \
866                                                                         \
867       if (NR > 3) {                                                     \
868          F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr );    \
869          a[3].inputptr += a[3].inputstride;                             \
870       }                                                                 \
871                                                                         \
872       if (NR > 4) {                                                     \
873          F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr );    \
874          a[4].inputptr += a[4].inputstride;                             \
875       }                                                                 \
876    }                                                                    \
877 }
878
879    
880 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
881                                   insert_null, insert_null, NAME)
882
883 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
884                                       insert_null, NAME)
885    
886 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
887                                           insert_null, NAME)
888    
889
890 EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4)
891 EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4)
892 EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
893
894 EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2)
895 EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2,  emit_viewport4_bgra4_st2)
896 EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
897
898 EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2)
899 EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2,  emit_viewport4_bgra4_st2_st2)
900 EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
901
902
903 /* Use the codegen paths to select one of a number of hardwired
904  * fastpaths.
905  */
906 void vf_generate_hardwired_emit( struct vertex_fetch *vf )
907 {
908    vf_emit_func func = NULL;
909
910    /* Does it fit a hardwired fastpath?  Help! this is growing out of
911     * control!
912     */
913    switch (vf->attr_count) {
914    case 2:
915       if (vf->attr[0].do_insert == insert_3f_viewport_3) {
916          if (vf->attr[1].do_insert == insert_4ub_4f_bgra_4) 
917             func = emit_viewport3_bgra4;
918          else if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) 
919             func = emit_viewport3_rgba4;
920       }
921       else if (vf->attr[0].do_insert == insert_3f_3 &&
922                vf->attr[1].do_insert == insert_4ub_4f_rgba_4) {
923          func = emit_xyz3_rgba4; 
924       }
925       break;
926    case 3:
927       if (vf->attr[2].do_insert == insert_2f_2) {
928          if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) {
929             if (vf->attr[0].do_insert == insert_4f_viewport_4)
930                func = emit_viewport4_rgba4_st2;
931             else if (vf->attr[0].do_insert == insert_4f_4) 
932                func = emit_xyzw4_rgba4_st2;
933          }
934          else if (vf->attr[1].do_insert == insert_4ub_4f_bgra_4 &&
935                   vf->attr[0].do_insert == insert_4f_viewport_4)
936             func = emit_viewport4_bgra4_st2;
937       }
938       break;
939    case 4:
940       if (vf->attr[2].do_insert == insert_2f_2 &&
941           vf->attr[3].do_insert == insert_2f_2) {
942          if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) {
943             if (vf->attr[0].do_insert == insert_4f_viewport_4)
944                func = emit_viewport4_rgba4_st2_st2;
945             else if (vf->attr[0].do_insert == insert_4f_4) 
946                func = emit_xyzw4_rgba4_st2_st2;
947          }
948          else if (vf->attr[1].do_insert == insert_4ub_4f_bgra_4 &&
949                   vf->attr[0].do_insert == insert_4f_viewport_4)
950             func = emit_viewport4_bgra4_st2_st2;
951       }
952       break;
953    }
954
955    vf->emit = func;
956 }
957
958 /***********************************************************************
959  * Generic (non-codegen) functions for whole vertices or groups of
960  * vertices
961  */
962
963 void vf_generic_emit( struct vertex_fetch *vf,
964                       GLuint count,
965                       GLubyte *v )
966 {
967    struct vf_attr *a = vf->attr;
968    const GLuint attr_count = vf->attr_count;
969    const GLuint stride = vf->vertex_stride;
970    GLuint i, j;
971
972    for (i = 0 ; i < count ; i++, v += stride) {
973       for (j = 0; j < attr_count; j++) {
974          GLfloat *in = (GLfloat *)a[j].inputptr;
975          a[j].inputptr += a[j].inputstride;
976          a[j].do_insert( &a[j], v + a[j].vertoffset, in );
977       }
978    }
979 }
980
981