3 * Copyright 2003 Tungsten Graphics, inc.
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:
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
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.
26 * Keith Whitwell <keithw@tungstengraphics.com>
32 #include "t_context.h"
34 #include "simple_list.h"
39 * These functions take the NDC coordinates pointed to by 'in', apply the
40 * NDC->Viewport mapping and store the results at 'v'.
43 static INLINE
void insert_4f_viewport_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
46 GLfloat
*out
= (GLfloat
*)v
;
47 const GLfloat
* const vp
= a
->vp
;
49 out
[0] = vp
[0] * in
[0] + vp
[12];
50 out
[1] = vp
[5] * in
[1] + vp
[13];
51 out
[2] = vp
[10] * in
[2] + vp
[14];
55 static INLINE
void insert_4f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
58 GLfloat
*out
= (GLfloat
*)v
;
59 const GLfloat
* const vp
= a
->vp
;
61 out
[0] = vp
[0] * in
[0] + vp
[12];
62 out
[1] = vp
[5] * in
[1] + vp
[13];
63 out
[2] = vp
[10] * in
[2] + vp
[14];
67 static INLINE
void insert_4f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
70 GLfloat
*out
= (GLfloat
*)v
;
71 const GLfloat
* const vp
= a
->vp
;
73 out
[0] = vp
[0] * in
[0] + vp
[12];
74 out
[1] = vp
[5] * in
[1] + vp
[13];
79 static INLINE
void insert_4f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
82 GLfloat
*out
= (GLfloat
*)v
;
83 const GLfloat
* const vp
= a
->vp
;
85 out
[0] = vp
[0] * in
[0] + vp
[12];
91 static INLINE
void insert_3f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
94 GLfloat
*out
= (GLfloat
*)v
;
95 const GLfloat
* const vp
= a
->vp
;
97 out
[0] = vp
[0] * in
[0] + vp
[12];
98 out
[1] = vp
[5] * in
[1] + vp
[13];
99 out
[2] = vp
[10] * in
[2] + vp
[14];
102 static INLINE
void insert_3f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
105 GLfloat
*out
= (GLfloat
*)v
;
106 const GLfloat
* const vp
= a
->vp
;
108 out
[0] = vp
[0] * in
[0] + vp
[12];
109 out
[1] = vp
[5] * in
[1] + vp
[13];
110 out
[2] = vp
[10] * in
[2] + vp
[14];
113 static INLINE
void insert_3f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
116 GLfloat
*out
= (GLfloat
*)v
;
117 const GLfloat
* const vp
= a
->vp
;
119 out
[0] = vp
[0] * in
[0] + vp
[12];
124 static INLINE
void insert_2f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
127 GLfloat
*out
= (GLfloat
*)v
;
128 const GLfloat
* const vp
= a
->vp
;
130 out
[0] = vp
[0] * in
[0] + vp
[12];
131 out
[1] = vp
[5] * in
[1] + vp
[13];
134 static INLINE
void insert_2f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
137 GLfloat
*out
= (GLfloat
*)v
;
138 const GLfloat
* const vp
= a
->vp
;
140 out
[0] = vp
[0] * in
[0] + vp
[12];
146 * These functions do the same as above, except for the viewport mapping.
149 static INLINE
void insert_4f_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
151 GLfloat
*out
= (GLfloat
*)(v
);
160 static INLINE
void insert_4f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
162 GLfloat
*out
= (GLfloat
*)(v
);
171 static INLINE
void insert_4f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
173 GLfloat
*out
= (GLfloat
*)(v
);
182 static INLINE
void insert_4f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
184 GLfloat
*out
= (GLfloat
*)(v
);
193 static INLINE
void insert_3f_xyw_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
195 GLfloat
*out
= (GLfloat
*)(v
);
203 static INLINE
void insert_3f_xyw_err( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
205 (void) a
; (void) v
; (void) in
;
209 static INLINE
void insert_3f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
211 GLfloat
*out
= (GLfloat
*)(v
);
219 static INLINE
void insert_3f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
221 GLfloat
*out
= (GLfloat
*)(v
);
229 static INLINE
void insert_3f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
231 GLfloat
*out
= (GLfloat
*)(v
);
240 static INLINE
void insert_2f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
242 GLfloat
*out
= (GLfloat
*)(v
);
249 static INLINE
void insert_2f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
251 GLfloat
*out
= (GLfloat
*)(v
);
258 static INLINE
void insert_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
260 GLfloat
*out
= (GLfloat
*)(v
);
266 static INLINE
void insert_null( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
268 (void) a
; (void) v
; (void) in
;
271 static INLINE
void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
274 GLchan
*c
= (GLchan
*)v
;
276 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
277 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
278 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
279 UNCLAMPED_FLOAT_TO_CHAN(c
[3], in
[3]);
282 static INLINE
void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
285 GLchan
*c
= (GLchan
*)v
;
287 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
288 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
289 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
293 static INLINE
void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
296 GLchan
*c
= (GLchan
*)v
;
298 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
299 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
304 static INLINE
void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
307 GLchan
*c
= (GLchan
*)v
;
309 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
315 static INLINE
void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
319 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
320 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
321 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
322 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
325 static INLINE
void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
329 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
330 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
331 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
335 static INLINE
void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
339 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
340 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
345 static INLINE
void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
349 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
355 static INLINE
void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
359 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
360 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
361 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
362 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
365 static INLINE
void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
369 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
370 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
371 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
375 static INLINE
void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
379 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
380 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
385 static INLINE
void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
389 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
395 static INLINE
void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
399 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
400 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
401 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
402 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
405 static INLINE
void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
409 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
410 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
411 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
415 static INLINE
void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
419 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
420 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
425 static INLINE
void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
429 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
435 static INLINE
void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
439 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
440 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
441 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
442 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
445 static INLINE
void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
449 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
450 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
451 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
455 static INLINE
void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
459 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
460 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
465 static INLINE
void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
469 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
475 static INLINE
void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
479 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
480 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
481 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
484 static INLINE
void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
488 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
489 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
493 static INLINE
void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
497 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
502 static INLINE
void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
506 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
507 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
508 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
511 static INLINE
void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
515 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
516 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
520 static INLINE
void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
524 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
530 static INLINE
void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
534 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
538 /***********************************************************************
539 * Functions to perform the reverse operations to the above, for
540 * swrast translation and clip-interpolation.
542 * Currently always extracts a full 4 floats.
545 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
548 const GLfloat
*in
= (const GLfloat
*)v
;
549 const GLfloat
* const vp
= a
->vp
;
551 /* Although included for completeness, the position coordinate is
552 * usually handled differently during clipping.
554 out
[0] = (in
[0] - vp
[12]) / vp
[0];
555 out
[1] = (in
[1] - vp
[13]) / vp
[5];
556 out
[2] = (in
[2] - vp
[14]) / vp
[10];
560 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
563 const GLfloat
*in
= (const GLfloat
*)v
;
564 const GLfloat
* const vp
= a
->vp
;
566 out
[0] = (in
[0] - vp
[12]) / vp
[0];
567 out
[1] = (in
[1] - vp
[13]) / vp
[5];
568 out
[2] = (in
[2] - vp
[14]) / vp
[10];
573 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
576 const GLfloat
*in
= (const GLfloat
*)v
;
577 const GLfloat
* const vp
= a
->vp
;
579 out
[0] = (in
[0] - vp
[12]) / vp
[0];
580 out
[1] = (in
[1] - vp
[13]) / vp
[5];
586 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
588 const GLfloat
*in
= (const GLfloat
*)v
;
597 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
599 const GLfloat
*in
= (const GLfloat
*)v
;
609 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
611 const GLfloat
*in
= (const GLfloat
*)v
;
621 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
623 const GLfloat
*in
= (const GLfloat
*)v
;
632 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
634 const GLfloat
*in
= (const GLfloat
*)v
;
643 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
646 GLchan
*c
= (GLchan
*)v
;
649 out
[0] = CHAN_TO_FLOAT(c
[0]);
650 out
[1] = CHAN_TO_FLOAT(c
[1]);
651 out
[2] = CHAN_TO_FLOAT(c
[2]);
652 out
[3] = CHAN_TO_FLOAT(c
[3]);
655 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
659 out
[0] = UBYTE_TO_FLOAT(v
[0]);
660 out
[1] = UBYTE_TO_FLOAT(v
[1]);
661 out
[2] = UBYTE_TO_FLOAT(v
[2]);
662 out
[3] = UBYTE_TO_FLOAT(v
[3]);
665 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
669 out
[2] = UBYTE_TO_FLOAT(v
[0]);
670 out
[1] = UBYTE_TO_FLOAT(v
[1]);
671 out
[0] = UBYTE_TO_FLOAT(v
[2]);
672 out
[3] = UBYTE_TO_FLOAT(v
[3]);
675 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
679 out
[3] = UBYTE_TO_FLOAT(v
[0]);
680 out
[0] = UBYTE_TO_FLOAT(v
[1]);
681 out
[1] = UBYTE_TO_FLOAT(v
[2]);
682 out
[2] = UBYTE_TO_FLOAT(v
[3]);
685 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
689 out
[3] = UBYTE_TO_FLOAT(v
[0]);
690 out
[2] = UBYTE_TO_FLOAT(v
[1]);
691 out
[1] = UBYTE_TO_FLOAT(v
[2]);
692 out
[0] = UBYTE_TO_FLOAT(v
[3]);
695 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
699 out
[0] = UBYTE_TO_FLOAT(v
[0]);
700 out
[1] = UBYTE_TO_FLOAT(v
[1]);
701 out
[2] = UBYTE_TO_FLOAT(v
[2]);
705 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
709 out
[2] = UBYTE_TO_FLOAT(v
[0]);
710 out
[1] = UBYTE_TO_FLOAT(v
[1]);
711 out
[0] = UBYTE_TO_FLOAT(v
[2]);
715 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
718 out
[0] = UBYTE_TO_FLOAT(v
[0]);
725 const struct tnl_format_info _tnl_format_info
[EMIT_MAX
] =
729 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
734 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
735 2 * sizeof(GLfloat
) },
739 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
740 3 * sizeof(GLfloat
) },
744 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
745 4 * sizeof(GLfloat
) },
749 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
750 insert_2f_viewport_2
},
751 2 * sizeof(GLfloat
) },
755 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
756 insert_3f_viewport_3
},
757 3 * sizeof(GLfloat
) },
761 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
762 insert_4f_viewport_4
},
763 4 * sizeof(GLfloat
) },
767 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
769 3 * sizeof(GLfloat
) },
773 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
778 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
779 insert_3ub_3f_rgb_3
},
780 3 * sizeof(GLubyte
) },
784 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
785 insert_3ub_3f_bgr_3
},
786 3 * sizeof(GLubyte
) },
790 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
791 insert_4ub_4f_rgba_4
},
792 4 * sizeof(GLubyte
) },
796 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
797 insert_4ub_4f_bgra_4
},
798 4 * sizeof(GLubyte
) },
802 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
803 insert_4ub_4f_argb_4
},
804 4 * sizeof(GLubyte
) },
808 { insert_4ub_4f_abgr_1
, insert_4ub_4f_abgr_2
, insert_4ub_4f_abgr_3
,
809 insert_4ub_4f_abgr_4
},
810 4 * sizeof(GLubyte
) },
813 extract_4chan_4f_rgba
,
814 { insert_4chan_4f_rgba_1
, insert_4chan_4f_rgba_2
, insert_4chan_4f_rgba_3
,
815 insert_4chan_4f_rgba_4
},
816 4 * sizeof(GLchan
) },
820 { NULL
, NULL
, NULL
, NULL
},
828 /***********************************************************************
829 * Hardwired fastpaths for emitting whole vertices or groups of
832 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
833 static void NAME( GLcontext *ctx, \
837 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \
838 struct tnl_clipspace_attr *a = vtx->attr; \
841 for (i = 0 ; i < count ; i++, v += vtx->vertex_size) { \
843 F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr ); \
844 a[0].inputptr += a[0].inputstride; \
848 F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr ); \
849 a[1].inputptr += a[1].inputstride; \
853 F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr ); \
854 a[2].inputptr += a[2].inputstride; \
858 F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr ); \
859 a[3].inputptr += a[3].inputstride; \
863 F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr ); \
864 a[4].inputptr += a[4].inputstride; \
870 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
871 insert_null, insert_null, NAME)
873 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
876 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
880 EMIT2(insert_3f_viewport_3
, insert_4ub_4f_rgba_4
, emit_viewport3_rgba4
)
881 EMIT2(insert_3f_viewport_3
, insert_4ub_4f_bgra_4
, emit_viewport3_bgra4
)
882 EMIT2(insert_3f_3
, insert_4ub_4f_rgba_4
, emit_xyz3_rgba4
)
884 EMIT3(insert_4f_viewport_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_viewport4_rgba4_st2
)
885 EMIT3(insert_4f_viewport_4
, insert_4ub_4f_bgra_4
, insert_2f_2
, emit_viewport4_bgra4_st2
)
886 EMIT3(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_xyzw4_rgba4_st2
)
888 EMIT4(insert_4f_viewport_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_viewport4_rgba4_st2_st2
)
889 EMIT4(insert_4f_viewport_4
, insert_4ub_4f_bgra_4
, insert_2f_2
, insert_2f_2
, emit_viewport4_bgra4_st2_st2
)
890 EMIT4(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_xyzw4_rgba4_st2_st2
)
893 /* Use the codegen paths to select one of a number of hardwired
896 void _tnl_generate_hardwired_emit( GLcontext
*ctx
)
898 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
899 tnl_emit_func func
= NULL
;
901 /* Does it fit a hardwired fastpath? Help! this is growing out of
904 switch (vtx
->attr_count
) {
906 if (vtx
->attr
[0].emit
== insert_3f_viewport_3
) {
907 if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
)
908 func
= emit_viewport3_bgra4
;
909 else if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
)
910 func
= emit_viewport3_rgba4
;
912 else if (vtx
->attr
[0].emit
== insert_3f_3
&&
913 vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
914 func
= emit_xyz3_rgba4
;
918 if (vtx
->attr
[2].emit
== insert_2f_2
) {
919 if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
920 if (vtx
->attr
[0].emit
== insert_4f_viewport_4
)
921 func
= emit_viewport4_rgba4_st2
;
922 else if (vtx
->attr
[0].emit
== insert_4f_4
)
923 func
= emit_xyzw4_rgba4_st2
;
925 else if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
&&
926 vtx
->attr
[0].emit
== insert_4f_viewport_4
)
927 func
= emit_viewport4_bgra4_st2
;
931 if (vtx
->attr
[2].emit
== insert_2f_2
&&
932 vtx
->attr
[3].emit
== insert_2f_2
) {
933 if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
934 if (vtx
->attr
[0].emit
== insert_4f_viewport_4
)
935 func
= emit_viewport4_rgba4_st2_st2
;
936 else if (vtx
->attr
[0].emit
== insert_4f_4
)
937 func
= emit_xyzw4_rgba4_st2_st2
;
939 else if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
&&
940 vtx
->attr
[0].emit
== insert_4f_viewport_4
)
941 func
= emit_viewport4_bgra4_st2_st2
;
949 /***********************************************************************
950 * Generic (non-codegen) functions for whole vertices or groups of
954 void _tnl_generic_emit( GLcontext
*ctx
,
958 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
959 struct tnl_clipspace_attr
*a
= vtx
->attr
;
960 const GLuint attr_count
= vtx
->attr_count
;
961 const GLuint stride
= vtx
->vertex_size
;
964 for (i
= 0 ; i
< count
; i
++, v
+= stride
) {
965 for (j
= 0; j
< attr_count
; j
++) {
966 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
967 a
[j
].inputptr
+= a
[j
].inputstride
;
968 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
974 void _tnl_generic_interp( GLcontext
*ctx
,
976 GLuint edst
, GLuint eout
, GLuint ein
,
977 GLboolean force_boundary
)
979 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
980 struct vertex_buffer
*VB
= &tnl
->vb
;
981 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
982 const GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
983 const GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
984 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
985 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
986 const GLuint attr_count
= vtx
->attr_count
;
988 (void) force_boundary
;
990 if (tnl
->NeedNdcCoords
) {
991 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
992 if (dstclip
[3] != 0.0) {
993 const GLfloat w
= 1.0f
/ dstclip
[3];
996 pos
[0] = dstclip
[0] * w
;
997 pos
[1] = dstclip
[1] * w
;
998 pos
[2] = dstclip
[2] * w
;
1001 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
1005 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
1009 for (j
= 1; j
< attr_count
; j
++) {
1010 GLfloat fin
[4], fout
[4], fdst
[4];
1012 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
1013 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
1015 INTERP_F( t
, fdst
[3], fout
[3], fin
[3] );
1016 INTERP_F( t
, fdst
[2], fout
[2], fin
[2] );
1017 INTERP_F( t
, fdst
[1], fout
[1], fin
[1] );
1018 INTERP_F( t
, fdst
[0], fout
[0], fin
[0] );
1020 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
1025 /* Extract color attributes from one vertex and insert them into
1026 * another. (Shortcircuit extract/insert with memcpy).
1028 void _tnl_generic_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1030 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1031 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
1032 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1033 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1034 const GLuint attr_count
= vtx
->attr_count
;
1037 for (j
= 0; j
< attr_count
; j
++) {
1038 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
1039 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
1041 _mesa_memcpy( vdst
+ a
[j
].vertoffset
,
1042 vsrc
+ a
[j
].vertoffset
,
1043 a
[j
].vertattrsize
);
1049 /* Helper functions for hardware which doesn't put back colors and/or
1050 * edgeflags into vertices.
1052 void _tnl_generic_interp_extras( GLcontext
*ctx
,
1054 GLuint dst
, GLuint out
, GLuint in
,
1055 GLboolean force_boundary
)
1057 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1059 /* If stride is zero, ColorPtr[1] is constant across the VB, so
1060 * there is no point interpolating between two values as they will
1061 * be identical. In all other cases, this value is generated by
1062 * t_vb_lighttmp.h and has a stride of 4 dwords.
1064 if (VB
->ColorPtr
[1] && VB
->ColorPtr
[1]->stride
) {
1065 assert(VB
->ColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
1068 VB
->ColorPtr
[1]->data
[dst
],
1069 VB
->ColorPtr
[1]->data
[out
],
1070 VB
->ColorPtr
[1]->data
[in
] );
1073 if (VB
->SecondaryColorPtr
[1]) {
1074 assert(VB
->SecondaryColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
1077 VB
->SecondaryColorPtr
[1]->data
[dst
],
1078 VB
->SecondaryColorPtr
[1]->data
[out
],
1079 VB
->SecondaryColorPtr
[1]->data
[in
] );
1082 if (VB
->IndexPtr
[1]) {
1083 VB
->IndexPtr
[1]->data
[dst
][0] = LINTERP( t
,
1084 VB
->IndexPtr
[1]->data
[out
][0],
1085 VB
->IndexPtr
[1]->data
[in
][0] );
1089 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
1092 _tnl_generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
1095 void _tnl_generic_copy_pv_extras( GLcontext
*ctx
,
1096 GLuint dst
, GLuint src
)
1098 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1100 /* See above comment:
1102 if (VB
->ColorPtr
[1] && VB
->ColorPtr
[1]->stride
) {
1103 COPY_4FV( VB
->ColorPtr
[1]->data
[dst
],
1104 VB
->ColorPtr
[1]->data
[src
] );
1107 if (VB
->SecondaryColorPtr
[1]) {
1108 COPY_4FV( VB
->SecondaryColorPtr
[1]->data
[dst
],
1109 VB
->SecondaryColorPtr
[1]->data
[src
] );
1112 if (VB
->IndexPtr
[1]) {
1113 VB
->IndexPtr
[1]->data
[dst
][0] = VB
->IndexPtr
[1]->data
[src
][0];
1116 _tnl_generic_copy_pv(ctx
, dst
, src
);