3 * Copyright 2003 VMware, 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 * VMWARE 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@vmware.com>
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/macros.h"
32 #include "util/simple_list.h"
33 #include "swrast/s_chan.h"
34 #include "t_context.h"
39 #define DEBUG_INSERT printf("%s\n", __func__)
46 * These functions take the NDC coordinates pointed to by 'in', apply the
47 * NDC->Viewport mapping and store the results at 'v'.
50 static inline void insert_4f_viewport_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
53 GLfloat
*out
= (GLfloat
*)v
;
54 const GLfloat
* const vp
= a
->vp
;
56 out
[0] = vp
[0] * in
[0] + vp
[12];
57 out
[1] = vp
[5] * in
[1] + vp
[13];
58 out
[2] = vp
[10] * in
[2] + vp
[14];
62 static inline void insert_4f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
65 GLfloat
*out
= (GLfloat
*)v
;
66 const GLfloat
* const vp
= a
->vp
;
68 out
[0] = vp
[0] * in
[0] + vp
[12];
69 out
[1] = vp
[5] * in
[1] + vp
[13];
70 out
[2] = vp
[10] * in
[2] + vp
[14];
74 static inline void insert_4f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
77 GLfloat
*out
= (GLfloat
*)v
;
78 const GLfloat
* const vp
= a
->vp
;
80 out
[0] = vp
[0] * in
[0] + vp
[12];
81 out
[1] = vp
[5] * in
[1] + vp
[13];
86 static inline void insert_4f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
89 GLfloat
*out
= (GLfloat
*)v
;
90 const GLfloat
* const vp
= a
->vp
;
92 out
[0] = vp
[0] * in
[0] + vp
[12];
98 static inline void insert_3f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
101 GLfloat
*out
= (GLfloat
*)v
;
102 const GLfloat
* const vp
= a
->vp
;
104 out
[0] = vp
[0] * in
[0] + vp
[12];
105 out
[1] = vp
[5] * in
[1] + vp
[13];
106 out
[2] = vp
[10] * in
[2] + vp
[14];
109 static inline void insert_3f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
112 GLfloat
*out
= (GLfloat
*)v
;
113 const GLfloat
* const vp
= a
->vp
;
115 out
[0] = vp
[0] * in
[0] + vp
[12];
116 out
[1] = vp
[5] * in
[1] + vp
[13];
120 static inline void insert_3f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
123 GLfloat
*out
= (GLfloat
*)v
;
124 const GLfloat
* const vp
= a
->vp
;
126 out
[0] = vp
[0] * in
[0] + vp
[12];
131 static inline void insert_2f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
134 GLfloat
*out
= (GLfloat
*)v
;
135 const GLfloat
* const vp
= a
->vp
;
137 out
[0] = vp
[0] * in
[0] + vp
[12];
138 out
[1] = vp
[5] * in
[1] + vp
[13];
141 static inline void insert_2f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
144 GLfloat
*out
= (GLfloat
*)v
;
145 const GLfloat
* const vp
= a
->vp
;
147 out
[0] = vp
[0] * in
[0] + vp
[12];
153 * These functions do the same as above, except for the viewport mapping.
156 static inline void insert_4f_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
158 GLfloat
*out
= (GLfloat
*)(v
);
167 static inline void insert_4f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
169 GLfloat
*out
= (GLfloat
*)(v
);
178 static inline void insert_4f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
180 GLfloat
*out
= (GLfloat
*)(v
);
189 static inline void insert_4f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
191 GLfloat
*out
= (GLfloat
*)(v
);
200 static inline void insert_3f_xyw_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
202 GLfloat
*out
= (GLfloat
*)(v
);
210 static inline void insert_3f_xyw_err( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
212 (void) a
; (void) v
; (void) in
;
217 static inline void insert_3f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
219 GLfloat
*out
= (GLfloat
*)(v
);
227 static inline void insert_3f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
229 GLfloat
*out
= (GLfloat
*)(v
);
237 static inline void insert_3f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
239 GLfloat
*out
= (GLfloat
*)(v
);
248 static inline void insert_2f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
250 GLfloat
*out
= (GLfloat
*)(v
);
257 static inline void insert_2f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
259 GLfloat
*out
= (GLfloat
*)(v
);
266 static inline void insert_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
268 GLfloat
*out
= (GLfloat
*)(v
);
274 static inline void insert_null( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
277 (void) a
; (void) v
; (void) in
;
280 static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
283 GLchan
*c
= (GLchan
*)v
;
286 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
287 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
288 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
289 UNCLAMPED_FLOAT_TO_CHAN(c
[3], in
[3]);
292 static inline void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
295 GLchan
*c
= (GLchan
*)v
;
298 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
299 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
300 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
304 static inline void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
307 GLchan
*c
= (GLchan
*)v
;
310 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
311 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
316 static inline void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
319 GLchan
*c
= (GLchan
*)v
;
322 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
328 static inline void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
333 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
334 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
336 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
339 static inline void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
344 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
345 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
346 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
350 static inline void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
355 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
356 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
361 static inline void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
366 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
372 static inline void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
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 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
383 static inline void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
388 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
389 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
390 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
394 static inline void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
399 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
400 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
405 static inline void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
410 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
416 static inline void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
421 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
422 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
423 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
424 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
427 static inline void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
432 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
433 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
434 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
438 static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
443 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
444 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
449 static inline void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
454 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
460 static inline void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
465 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
466 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
467 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
468 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
471 static inline void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
476 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
477 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
478 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
482 static inline void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
487 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
488 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
493 static inline void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
498 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
504 static inline void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
509 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
510 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
511 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
514 static inline void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
519 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
520 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
524 static inline void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
529 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
534 static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
539 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
540 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
541 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
544 static inline void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
549 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
550 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
554 static inline void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
559 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
565 static inline void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
570 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
574 /***********************************************************************
575 * Functions to perform the reverse operations to the above, for
576 * swrast translation and clip-interpolation.
578 * Currently always extracts a full 4 floats.
581 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
584 const GLfloat
*in
= (const GLfloat
*)v
;
585 const GLfloat
* const vp
= a
->vp
;
587 /* Although included for completeness, the position coordinate is
588 * usually handled differently during clipping.
591 out
[0] = (in
[0] - vp
[12]) / vp
[0];
592 out
[1] = (in
[1] - vp
[13]) / vp
[5];
593 out
[2] = (in
[2] - vp
[14]) / vp
[10];
597 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
600 const GLfloat
*in
= (const GLfloat
*)v
;
601 const GLfloat
* const vp
= a
->vp
;
603 out
[0] = (in
[0] - vp
[12]) / vp
[0];
604 out
[1] = (in
[1] - vp
[13]) / vp
[5];
605 out
[2] = (in
[2] - vp
[14]) / vp
[10];
610 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
613 const GLfloat
*in
= (const GLfloat
*)v
;
614 const GLfloat
* const vp
= a
->vp
;
616 out
[0] = (in
[0] - vp
[12]) / vp
[0];
617 out
[1] = (in
[1] - vp
[13]) / vp
[5];
623 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
625 const GLfloat
*in
= (const GLfloat
*)v
;
634 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
636 const GLfloat
*in
= (const GLfloat
*)v
;
646 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
648 const GLfloat
*in
= (const GLfloat
*)v
;
658 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
660 const GLfloat
*in
= (const GLfloat
*)v
;
669 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
671 const GLfloat
*in
= (const GLfloat
*)v
;
680 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
683 GLchan
*c
= (GLchan
*)v
;
686 out
[0] = CHAN_TO_FLOAT(c
[0]);
687 out
[1] = CHAN_TO_FLOAT(c
[1]);
688 out
[2] = CHAN_TO_FLOAT(c
[2]);
689 out
[3] = CHAN_TO_FLOAT(c
[3]);
692 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
696 out
[0] = UBYTE_TO_FLOAT(v
[0]);
697 out
[1] = UBYTE_TO_FLOAT(v
[1]);
698 out
[2] = UBYTE_TO_FLOAT(v
[2]);
699 out
[3] = UBYTE_TO_FLOAT(v
[3]);
702 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
706 out
[2] = UBYTE_TO_FLOAT(v
[0]);
707 out
[1] = UBYTE_TO_FLOAT(v
[1]);
708 out
[0] = UBYTE_TO_FLOAT(v
[2]);
709 out
[3] = UBYTE_TO_FLOAT(v
[3]);
712 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
716 out
[3] = UBYTE_TO_FLOAT(v
[0]);
717 out
[0] = UBYTE_TO_FLOAT(v
[1]);
718 out
[1] = UBYTE_TO_FLOAT(v
[2]);
719 out
[2] = UBYTE_TO_FLOAT(v
[3]);
722 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
726 out
[3] = UBYTE_TO_FLOAT(v
[0]);
727 out
[2] = UBYTE_TO_FLOAT(v
[1]);
728 out
[1] = UBYTE_TO_FLOAT(v
[2]);
729 out
[0] = UBYTE_TO_FLOAT(v
[3]);
732 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
736 out
[0] = UBYTE_TO_FLOAT(v
[0]);
737 out
[1] = UBYTE_TO_FLOAT(v
[1]);
738 out
[2] = UBYTE_TO_FLOAT(v
[2]);
742 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
746 out
[2] = UBYTE_TO_FLOAT(v
[0]);
747 out
[1] = UBYTE_TO_FLOAT(v
[1]);
748 out
[0] = UBYTE_TO_FLOAT(v
[2]);
752 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
755 out
[0] = UBYTE_TO_FLOAT(v
[0]);
762 const struct tnl_format_info _tnl_format_info
[EMIT_MAX
] =
766 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
771 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
772 2 * sizeof(GLfloat
) },
776 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
777 3 * sizeof(GLfloat
) },
781 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
782 4 * sizeof(GLfloat
) },
786 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
787 insert_2f_viewport_2
},
788 2 * sizeof(GLfloat
) },
792 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
793 insert_3f_viewport_3
},
794 3 * sizeof(GLfloat
) },
798 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
799 insert_4f_viewport_4
},
800 4 * sizeof(GLfloat
) },
804 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
806 3 * sizeof(GLfloat
) },
810 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
815 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
816 insert_3ub_3f_rgb_3
},
817 3 * sizeof(GLubyte
) },
821 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
822 insert_3ub_3f_bgr_3
},
823 3 * sizeof(GLubyte
) },
827 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
828 insert_4ub_4f_rgba_4
},
829 4 * sizeof(GLubyte
) },
833 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
834 insert_4ub_4f_bgra_4
},
835 4 * sizeof(GLubyte
) },
839 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
840 insert_4ub_4f_argb_4
},
841 4 * sizeof(GLubyte
) },
845 { insert_4ub_4f_abgr_1
, insert_4ub_4f_abgr_2
, insert_4ub_4f_abgr_3
,
846 insert_4ub_4f_abgr_4
},
847 4 * sizeof(GLubyte
) },
850 extract_4chan_4f_rgba
,
851 { insert_4chan_4f_rgba_1
, insert_4chan_4f_rgba_2
, insert_4chan_4f_rgba_3
,
852 insert_4chan_4f_rgba_4
},
853 4 * sizeof(GLchan
) },
857 { NULL
, NULL
, NULL
, NULL
},
865 /***********************************************************************
866 * Hardwired fastpaths for emitting whole vertices or groups of
869 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
870 static void NAME( struct gl_context *ctx, \
874 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \
875 struct tnl_clipspace_attr *a = vtx->attr; \
878 for (i = 0 ; i < count ; i++, v += vtx->vertex_size) { \
880 F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr ); \
881 a[0].inputptr += a[0].inputstride; \
885 F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr ); \
886 a[1].inputptr += a[1].inputstride; \
890 F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr ); \
891 a[2].inputptr += a[2].inputstride; \
895 F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr ); \
896 a[3].inputptr += a[3].inputstride; \
900 F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr ); \
901 a[4].inputptr += a[4].inputstride; \
907 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
908 insert_null, insert_null, NAME)
910 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
913 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
917 EMIT2(insert_3f_viewport_3
, insert_4ub_4f_rgba_4
, emit_viewport3_rgba4
)
918 EMIT2(insert_3f_viewport_3
, insert_4ub_4f_bgra_4
, emit_viewport3_bgra4
)
919 EMIT2(insert_3f_3
, insert_4ub_4f_rgba_4
, emit_xyz3_rgba4
)
921 EMIT3(insert_4f_viewport_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_viewport4_rgba4_st2
)
922 EMIT3(insert_4f_viewport_4
, insert_4ub_4f_bgra_4
, insert_2f_2
, emit_viewport4_bgra4_st2
)
923 EMIT3(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_xyzw4_rgba4_st2
)
925 EMIT4(insert_4f_viewport_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_viewport4_rgba4_st2_st2
)
926 EMIT4(insert_4f_viewport_4
, insert_4ub_4f_bgra_4
, insert_2f_2
, insert_2f_2
, emit_viewport4_bgra4_st2_st2
)
927 EMIT4(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_xyzw4_rgba4_st2_st2
)
930 /* Use the codegen paths to select one of a number of hardwired
933 void _tnl_generate_hardwired_emit( struct gl_context
*ctx
)
935 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
936 tnl_emit_func func
= NULL
;
938 /* Does it fit a hardwired fastpath? Help! this is growing out of
941 switch (vtx
->attr_count
) {
943 if (vtx
->attr
[0].emit
== insert_3f_viewport_3
) {
944 if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
)
945 func
= emit_viewport3_bgra4
;
946 else if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
)
947 func
= emit_viewport3_rgba4
;
949 else if (vtx
->attr
[0].emit
== insert_3f_3
&&
950 vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
951 func
= emit_xyz3_rgba4
;
955 if (vtx
->attr
[2].emit
== insert_2f_2
) {
956 if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
957 if (vtx
->attr
[0].emit
== insert_4f_viewport_4
)
958 func
= emit_viewport4_rgba4_st2
;
959 else if (vtx
->attr
[0].emit
== insert_4f_4
)
960 func
= emit_xyzw4_rgba4_st2
;
962 else if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
&&
963 vtx
->attr
[0].emit
== insert_4f_viewport_4
)
964 func
= emit_viewport4_bgra4_st2
;
968 if (vtx
->attr
[2].emit
== insert_2f_2
&&
969 vtx
->attr
[3].emit
== insert_2f_2
) {
970 if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
971 if (vtx
->attr
[0].emit
== insert_4f_viewport_4
)
972 func
= emit_viewport4_rgba4_st2_st2
;
973 else if (vtx
->attr
[0].emit
== insert_4f_4
)
974 func
= emit_xyzw4_rgba4_st2_st2
;
976 else if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
&&
977 vtx
->attr
[0].emit
== insert_4f_viewport_4
)
978 func
= emit_viewport4_bgra4_st2_st2
;
986 /***********************************************************************
987 * Generic (non-codegen) functions for whole vertices or groups of
991 void _tnl_generic_emit( struct gl_context
*ctx
,
995 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
996 struct tnl_clipspace_attr
*a
= vtx
->attr
;
997 const GLuint attr_count
= vtx
->attr_count
;
998 const GLuint stride
= vtx
->vertex_size
;
1001 for (i
= 0 ; i
< count
; i
++, v
+= stride
) {
1002 for (j
= 0; j
< attr_count
; j
++) {
1003 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
1004 a
[j
].inputptr
+= a
[j
].inputstride
;
1005 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
1011 void _tnl_generic_interp( struct gl_context
*ctx
,
1013 GLuint edst
, GLuint eout
, GLuint ein
,
1014 GLboolean force_boundary
)
1016 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1017 struct vertex_buffer
*VB
= &tnl
->vb
;
1018 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1019 const GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
1020 const GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
1021 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1022 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1023 const GLuint attr_count
= vtx
->attr_count
;
1025 (void) force_boundary
;
1027 if (tnl
->NeedNdcCoords
) {
1028 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
1029 if (dstclip
[3] != 0.0f
) {
1030 const GLfloat w
= 1.0f
/ dstclip
[3];
1033 pos
[0] = dstclip
[0] * w
;
1034 pos
[1] = dstclip
[1] * w
;
1035 pos
[2] = dstclip
[2] * w
;
1038 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
1042 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
1046 for (j
= 1; j
< attr_count
; j
++) {
1047 GLfloat fin
[4], fout
[4], fdst
[4];
1049 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
1050 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
1052 INTERP_4F(t
, fdst
, fout
, fin
);
1054 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
1059 /* Extract color attributes from one vertex and insert them into
1060 * another. (Shortcircuit extract/insert with memcpy).
1062 void _tnl_generic_copy_pv( struct gl_context
*ctx
, GLuint edst
, GLuint esrc
)
1064 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1065 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
1066 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1067 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1068 const GLuint attr_count
= vtx
->attr_count
;
1071 for (j
= 0; j
< attr_count
; j
++) {
1072 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
1073 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
1075 memcpy( vdst
+ a
[j
].vertoffset
,
1076 vsrc
+ a
[j
].vertoffset
,
1077 a
[j
].vertattrsize
);
1083 /* Helper functions for hardware which doesn't put back colors and/or
1084 * edgeflags into vertices.
1086 void _tnl_generic_interp_extras( struct gl_context
*ctx
,
1088 GLuint dst
, GLuint out
, GLuint in
,
1089 GLboolean force_boundary
)
1091 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1093 /* If stride is zero, BackfaceColorPtr is constant across the VB, so
1094 * there is no point interpolating between two values as they will
1095 * be identical. In all other cases, this value is generated by
1096 * t_vb_lighttmp.h and has a stride of 4 dwords.
1098 if (VB
->BackfaceColorPtr
&& VB
->BackfaceColorPtr
->stride
) {
1099 assert(VB
->BackfaceColorPtr
->stride
== 4 * sizeof(GLfloat
));
1102 VB
->BackfaceColorPtr
->data
[dst
],
1103 VB
->BackfaceColorPtr
->data
[out
],
1104 VB
->BackfaceColorPtr
->data
[in
] );
1107 if (VB
->BackfaceSecondaryColorPtr
) {
1108 assert(VB
->BackfaceSecondaryColorPtr
->stride
== 4 * sizeof(GLfloat
));
1111 VB
->BackfaceSecondaryColorPtr
->data
[dst
],
1112 VB
->BackfaceSecondaryColorPtr
->data
[out
],
1113 VB
->BackfaceSecondaryColorPtr
->data
[in
] );
1116 if (VB
->BackfaceIndexPtr
) {
1117 VB
->BackfaceIndexPtr
->data
[dst
][0] = LINTERP( t
,
1118 VB
->BackfaceIndexPtr
->data
[out
][0],
1119 VB
->BackfaceIndexPtr
->data
[in
][0] );
1123 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
1126 _tnl_generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
1129 void _tnl_generic_copy_pv_extras( struct gl_context
*ctx
,
1130 GLuint dst
, GLuint src
)
1132 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1134 /* See above comment:
1136 if (VB
->BackfaceColorPtr
&& VB
->BackfaceColorPtr
->stride
) {
1137 COPY_4FV( VB
->BackfaceColorPtr
->data
[dst
],
1138 VB
->BackfaceColorPtr
->data
[src
] );
1141 if (VB
->BackfaceSecondaryColorPtr
) {
1142 COPY_4FV( VB
->BackfaceSecondaryColorPtr
->data
[dst
],
1143 VB
->BackfaceSecondaryColorPtr
->data
[src
] );
1146 if (VB
->BackfaceIndexPtr
) {
1147 VB
->BackfaceIndexPtr
->data
[dst
][0] = VB
->BackfaceIndexPtr
->data
[src
][0];
1150 _tnl_generic_copy_pv(ctx
, dst
, src
);