i965: Fix readpixels from ReadBuffer != DrawBuffer.
[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 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