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 "swrast/s_chan.h"
33 #include "t_context.h"
38 #define DEBUG_INSERT printf("%s\n", __func__)
45 * These functions take the NDC coordinates pointed to by 'in', apply the
46 * NDC->Viewport mapping and store the results at 'v'.
49 static inline void insert_4f_viewport_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
52 GLfloat
*out
= (GLfloat
*)v
;
53 const GLfloat
* const vp
= a
->vp
;
55 out
[0] = vp
[0] * in
[0] + vp
[12];
56 out
[1] = vp
[5] * in
[1] + vp
[13];
57 out
[2] = vp
[10] * in
[2] + vp
[14];
61 static inline void insert_4f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
64 GLfloat
*out
= (GLfloat
*)v
;
65 const GLfloat
* const vp
= a
->vp
;
67 out
[0] = vp
[0] * in
[0] + vp
[12];
68 out
[1] = vp
[5] * in
[1] + vp
[13];
69 out
[2] = vp
[10] * in
[2] + vp
[14];
73 static inline void insert_4f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
76 GLfloat
*out
= (GLfloat
*)v
;
77 const GLfloat
* const vp
= a
->vp
;
79 out
[0] = vp
[0] * in
[0] + vp
[12];
80 out
[1] = vp
[5] * in
[1] + vp
[13];
85 static inline void insert_4f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
88 GLfloat
*out
= (GLfloat
*)v
;
89 const GLfloat
* const vp
= a
->vp
;
91 out
[0] = vp
[0] * in
[0] + vp
[12];
97 static inline void insert_3f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
100 GLfloat
*out
= (GLfloat
*)v
;
101 const GLfloat
* const vp
= a
->vp
;
103 out
[0] = vp
[0] * in
[0] + vp
[12];
104 out
[1] = vp
[5] * in
[1] + vp
[13];
105 out
[2] = vp
[10] * in
[2] + vp
[14];
108 static inline void insert_3f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
111 GLfloat
*out
= (GLfloat
*)v
;
112 const GLfloat
* const vp
= a
->vp
;
114 out
[0] = vp
[0] * in
[0] + vp
[12];
115 out
[1] = vp
[5] * in
[1] + vp
[13];
119 static inline void insert_3f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
122 GLfloat
*out
= (GLfloat
*)v
;
123 const GLfloat
* const vp
= a
->vp
;
125 out
[0] = vp
[0] * in
[0] + vp
[12];
130 static inline void insert_2f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
133 GLfloat
*out
= (GLfloat
*)v
;
134 const GLfloat
* const vp
= a
->vp
;
136 out
[0] = vp
[0] * in
[0] + vp
[12];
137 out
[1] = vp
[5] * in
[1] + vp
[13];
140 static inline void insert_2f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
143 GLfloat
*out
= (GLfloat
*)v
;
144 const GLfloat
* const vp
= a
->vp
;
146 out
[0] = vp
[0] * in
[0] + vp
[12];
152 * These functions do the same as above, except for the viewport mapping.
155 static inline void insert_4f_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
157 GLfloat
*out
= (GLfloat
*)(v
);
166 static inline void insert_4f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
168 GLfloat
*out
= (GLfloat
*)(v
);
177 static inline void insert_4f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
179 GLfloat
*out
= (GLfloat
*)(v
);
188 static inline void insert_4f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
190 GLfloat
*out
= (GLfloat
*)(v
);
199 static inline void insert_3f_xyw_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
201 GLfloat
*out
= (GLfloat
*)(v
);
209 static inline void insert_3f_xyw_err( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
211 (void) a
; (void) v
; (void) in
;
216 static inline void insert_3f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
218 GLfloat
*out
= (GLfloat
*)(v
);
226 static inline void insert_3f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
228 GLfloat
*out
= (GLfloat
*)(v
);
236 static inline void insert_3f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
238 GLfloat
*out
= (GLfloat
*)(v
);
247 static inline void insert_2f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
249 GLfloat
*out
= (GLfloat
*)(v
);
256 static inline void insert_2f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
258 GLfloat
*out
= (GLfloat
*)(v
);
265 static inline void insert_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
267 GLfloat
*out
= (GLfloat
*)(v
);
273 static inline void insert_null( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
276 (void) a
; (void) v
; (void) in
;
279 static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
282 GLchan
*c
= (GLchan
*)v
;
285 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
286 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
287 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
288 UNCLAMPED_FLOAT_TO_CHAN(c
[3], in
[3]);
291 static inline void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
294 GLchan
*c
= (GLchan
*)v
;
297 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
298 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
299 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
303 static inline void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
306 GLchan
*c
= (GLchan
*)v
;
309 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
310 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
315 static inline void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
318 GLchan
*c
= (GLchan
*)v
;
321 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
327 static inline void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
332 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
333 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
334 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
338 static inline void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
343 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
344 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
345 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
349 static inline void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
354 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
355 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
360 static inline void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
365 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
371 static inline void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
376 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
377 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
378 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
379 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
382 static inline void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
387 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
388 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
389 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
393 static inline void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
398 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
399 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
404 static inline void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
409 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
415 static inline void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
420 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
421 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
422 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
423 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
426 static inline void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
431 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
432 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
433 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
437 static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
442 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
443 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
448 static inline void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
453 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
459 static inline void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
464 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
465 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
466 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
467 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
470 static inline void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
475 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
476 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
477 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
481 static inline void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
486 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
487 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
492 static inline void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
497 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
503 static inline void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
508 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
509 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
510 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
513 static inline void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
518 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
519 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
523 static inline void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
528 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
533 static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
538 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
539 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
540 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
543 static inline void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
548 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
549 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
553 static inline void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
558 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
564 static inline void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
569 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
573 /***********************************************************************
574 * Functions to perform the reverse operations to the above, for
575 * swrast translation and clip-interpolation.
577 * Currently always extracts a full 4 floats.
580 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
583 const GLfloat
*in
= (const GLfloat
*)v
;
584 const GLfloat
* const vp
= a
->vp
;
586 /* Although included for completeness, the position coordinate is
587 * usually handled differently during clipping.
590 out
[0] = (in
[0] - vp
[12]) / vp
[0];
591 out
[1] = (in
[1] - vp
[13]) / vp
[5];
592 out
[2] = (in
[2] - vp
[14]) / vp
[10];
596 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
599 const GLfloat
*in
= (const GLfloat
*)v
;
600 const GLfloat
* const vp
= a
->vp
;
602 out
[0] = (in
[0] - vp
[12]) / vp
[0];
603 out
[1] = (in
[1] - vp
[13]) / vp
[5];
604 out
[2] = (in
[2] - vp
[14]) / vp
[10];
609 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
612 const GLfloat
*in
= (const GLfloat
*)v
;
613 const GLfloat
* const vp
= a
->vp
;
615 out
[0] = (in
[0] - vp
[12]) / vp
[0];
616 out
[1] = (in
[1] - vp
[13]) / vp
[5];
622 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
624 const GLfloat
*in
= (const GLfloat
*)v
;
633 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
635 const GLfloat
*in
= (const GLfloat
*)v
;
645 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
647 const GLfloat
*in
= (const GLfloat
*)v
;
657 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
659 const GLfloat
*in
= (const GLfloat
*)v
;
668 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
670 const GLfloat
*in
= (const GLfloat
*)v
;
679 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
682 GLchan
*c
= (GLchan
*)v
;
685 out
[0] = CHAN_TO_FLOAT(c
[0]);
686 out
[1] = CHAN_TO_FLOAT(c
[1]);
687 out
[2] = CHAN_TO_FLOAT(c
[2]);
688 out
[3] = CHAN_TO_FLOAT(c
[3]);
691 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
695 out
[0] = UBYTE_TO_FLOAT(v
[0]);
696 out
[1] = UBYTE_TO_FLOAT(v
[1]);
697 out
[2] = UBYTE_TO_FLOAT(v
[2]);
698 out
[3] = UBYTE_TO_FLOAT(v
[3]);
701 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
705 out
[2] = UBYTE_TO_FLOAT(v
[0]);
706 out
[1] = UBYTE_TO_FLOAT(v
[1]);
707 out
[0] = UBYTE_TO_FLOAT(v
[2]);
708 out
[3] = UBYTE_TO_FLOAT(v
[3]);
711 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
715 out
[3] = UBYTE_TO_FLOAT(v
[0]);
716 out
[0] = UBYTE_TO_FLOAT(v
[1]);
717 out
[1] = UBYTE_TO_FLOAT(v
[2]);
718 out
[2] = UBYTE_TO_FLOAT(v
[3]);
721 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
725 out
[3] = UBYTE_TO_FLOAT(v
[0]);
726 out
[2] = UBYTE_TO_FLOAT(v
[1]);
727 out
[1] = UBYTE_TO_FLOAT(v
[2]);
728 out
[0] = UBYTE_TO_FLOAT(v
[3]);
731 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
735 out
[0] = UBYTE_TO_FLOAT(v
[0]);
736 out
[1] = UBYTE_TO_FLOAT(v
[1]);
737 out
[2] = UBYTE_TO_FLOAT(v
[2]);
741 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
745 out
[2] = UBYTE_TO_FLOAT(v
[0]);
746 out
[1] = UBYTE_TO_FLOAT(v
[1]);
747 out
[0] = UBYTE_TO_FLOAT(v
[2]);
751 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
754 out
[0] = UBYTE_TO_FLOAT(v
[0]);
761 const struct tnl_format_info _tnl_format_info
[EMIT_MAX
] =
765 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
770 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
771 2 * sizeof(GLfloat
) },
775 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
776 3 * sizeof(GLfloat
) },
780 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
781 4 * sizeof(GLfloat
) },
785 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
786 insert_2f_viewport_2
},
787 2 * sizeof(GLfloat
) },
791 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
792 insert_3f_viewport_3
},
793 3 * sizeof(GLfloat
) },
797 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
798 insert_4f_viewport_4
},
799 4 * sizeof(GLfloat
) },
803 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
805 3 * sizeof(GLfloat
) },
809 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
814 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
815 insert_3ub_3f_rgb_3
},
816 3 * sizeof(GLubyte
) },
820 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
821 insert_3ub_3f_bgr_3
},
822 3 * sizeof(GLubyte
) },
826 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
827 insert_4ub_4f_rgba_4
},
828 4 * sizeof(GLubyte
) },
832 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
833 insert_4ub_4f_bgra_4
},
834 4 * sizeof(GLubyte
) },
838 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
839 insert_4ub_4f_argb_4
},
840 4 * sizeof(GLubyte
) },
844 { insert_4ub_4f_abgr_1
, insert_4ub_4f_abgr_2
, insert_4ub_4f_abgr_3
,
845 insert_4ub_4f_abgr_4
},
846 4 * sizeof(GLubyte
) },
849 extract_4chan_4f_rgba
,
850 { insert_4chan_4f_rgba_1
, insert_4chan_4f_rgba_2
, insert_4chan_4f_rgba_3
,
851 insert_4chan_4f_rgba_4
},
852 4 * sizeof(GLchan
) },
856 { NULL
, NULL
, NULL
, NULL
},
864 /***********************************************************************
865 * Hardwired fastpaths for emitting whole vertices or groups of
868 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
869 static void NAME( struct gl_context *ctx, \
873 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \
874 struct tnl_clipspace_attr *a = vtx->attr; \
877 for (i = 0 ; i < count ; i++, v += vtx->vertex_size) { \
879 F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr ); \
880 a[0].inputptr += a[0].inputstride; \
884 F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr ); \
885 a[1].inputptr += a[1].inputstride; \
889 F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr ); \
890 a[2].inputptr += a[2].inputstride; \
894 F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr ); \
895 a[3].inputptr += a[3].inputstride; \
899 F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr ); \
900 a[4].inputptr += a[4].inputstride; \
906 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
907 insert_null, insert_null, NAME)
909 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
912 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
916 EMIT2(insert_3f_viewport_3
, insert_4ub_4f_rgba_4
, emit_viewport3_rgba4
)
917 EMIT2(insert_3f_viewport_3
, insert_4ub_4f_bgra_4
, emit_viewport3_bgra4
)
918 EMIT2(insert_3f_3
, insert_4ub_4f_rgba_4
, emit_xyz3_rgba4
)
920 EMIT3(insert_4f_viewport_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_viewport4_rgba4_st2
)
921 EMIT3(insert_4f_viewport_4
, insert_4ub_4f_bgra_4
, insert_2f_2
, emit_viewport4_bgra4_st2
)
922 EMIT3(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_xyzw4_rgba4_st2
)
924 EMIT4(insert_4f_viewport_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_viewport4_rgba4_st2_st2
)
925 EMIT4(insert_4f_viewport_4
, insert_4ub_4f_bgra_4
, insert_2f_2
, insert_2f_2
, emit_viewport4_bgra4_st2_st2
)
926 EMIT4(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_xyzw4_rgba4_st2_st2
)
929 /* Use the codegen paths to select one of a number of hardwired
932 void _tnl_generate_hardwired_emit( struct gl_context
*ctx
)
934 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
935 tnl_emit_func func
= NULL
;
937 /* Does it fit a hardwired fastpath? Help! this is growing out of
940 switch (vtx
->attr_count
) {
942 if (vtx
->attr
[0].emit
== insert_3f_viewport_3
) {
943 if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
)
944 func
= emit_viewport3_bgra4
;
945 else if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
)
946 func
= emit_viewport3_rgba4
;
948 else if (vtx
->attr
[0].emit
== insert_3f_3
&&
949 vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
950 func
= emit_xyz3_rgba4
;
954 if (vtx
->attr
[2].emit
== insert_2f_2
) {
955 if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
956 if (vtx
->attr
[0].emit
== insert_4f_viewport_4
)
957 func
= emit_viewport4_rgba4_st2
;
958 else if (vtx
->attr
[0].emit
== insert_4f_4
)
959 func
= emit_xyzw4_rgba4_st2
;
961 else if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
&&
962 vtx
->attr
[0].emit
== insert_4f_viewport_4
)
963 func
= emit_viewport4_bgra4_st2
;
967 if (vtx
->attr
[2].emit
== insert_2f_2
&&
968 vtx
->attr
[3].emit
== insert_2f_2
) {
969 if (vtx
->attr
[1].emit
== insert_4ub_4f_rgba_4
) {
970 if (vtx
->attr
[0].emit
== insert_4f_viewport_4
)
971 func
= emit_viewport4_rgba4_st2_st2
;
972 else if (vtx
->attr
[0].emit
== insert_4f_4
)
973 func
= emit_xyzw4_rgba4_st2_st2
;
975 else if (vtx
->attr
[1].emit
== insert_4ub_4f_bgra_4
&&
976 vtx
->attr
[0].emit
== insert_4f_viewport_4
)
977 func
= emit_viewport4_bgra4_st2_st2
;
985 /***********************************************************************
986 * Generic (non-codegen) functions for whole vertices or groups of
990 void _tnl_generic_emit( struct gl_context
*ctx
,
994 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
995 struct tnl_clipspace_attr
*a
= vtx
->attr
;
996 const GLuint attr_count
= vtx
->attr_count
;
997 const GLuint stride
= vtx
->vertex_size
;
1000 for (i
= 0 ; i
< count
; i
++, v
+= stride
) {
1001 for (j
= 0; j
< attr_count
; j
++) {
1002 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
1003 a
[j
].inputptr
+= a
[j
].inputstride
;
1004 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
1010 void _tnl_generic_interp( struct gl_context
*ctx
,
1012 GLuint edst
, GLuint eout
, GLuint ein
,
1013 GLboolean force_boundary
)
1015 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1016 struct vertex_buffer
*VB
= &tnl
->vb
;
1017 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1018 const GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
1019 const GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
1020 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1021 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1022 const GLuint attr_count
= vtx
->attr_count
;
1024 (void) force_boundary
;
1026 if (tnl
->NeedNdcCoords
) {
1027 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
1028 if (dstclip
[3] != 0.0f
) {
1029 const GLfloat w
= 1.0f
/ dstclip
[3];
1032 pos
[0] = dstclip
[0] * w
;
1033 pos
[1] = dstclip
[1] * w
;
1034 pos
[2] = dstclip
[2] * w
;
1037 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
1041 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
1045 for (j
= 1; j
< attr_count
; j
++) {
1046 GLfloat fin
[4], fout
[4], fdst
[4];
1048 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
1049 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
1051 INTERP_4F(t
, fdst
, fout
, fin
);
1053 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
1058 /* Extract color attributes from one vertex and insert them into
1059 * another. (Shortcircuit extract/insert with memcpy).
1061 void _tnl_generic_copy_pv( struct gl_context
*ctx
, GLuint edst
, GLuint esrc
)
1063 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1064 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
1065 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1066 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1067 const GLuint attr_count
= vtx
->attr_count
;
1070 for (j
= 0; j
< attr_count
; j
++) {
1071 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
1072 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
1074 memcpy( vdst
+ a
[j
].vertoffset
,
1075 vsrc
+ a
[j
].vertoffset
,
1076 a
[j
].vertattrsize
);
1082 /* Helper functions for hardware which doesn't put back colors and/or
1083 * edgeflags into vertices.
1085 void _tnl_generic_interp_extras( struct gl_context
*ctx
,
1087 GLuint dst
, GLuint out
, GLuint in
,
1088 GLboolean force_boundary
)
1090 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1092 /* If stride is zero, BackfaceColorPtr is constant across the VB, so
1093 * there is no point interpolating between two values as they will
1094 * be identical. In all other cases, this value is generated by
1095 * t_vb_lighttmp.h and has a stride of 4 dwords.
1097 if (VB
->BackfaceColorPtr
&& VB
->BackfaceColorPtr
->stride
) {
1098 assert(VB
->BackfaceColorPtr
->stride
== 4 * sizeof(GLfloat
));
1101 VB
->BackfaceColorPtr
->data
[dst
],
1102 VB
->BackfaceColorPtr
->data
[out
],
1103 VB
->BackfaceColorPtr
->data
[in
] );
1106 if (VB
->BackfaceSecondaryColorPtr
) {
1107 assert(VB
->BackfaceSecondaryColorPtr
->stride
== 4 * sizeof(GLfloat
));
1110 VB
->BackfaceSecondaryColorPtr
->data
[dst
],
1111 VB
->BackfaceSecondaryColorPtr
->data
[out
],
1112 VB
->BackfaceSecondaryColorPtr
->data
[in
] );
1115 if (VB
->BackfaceIndexPtr
) {
1116 VB
->BackfaceIndexPtr
->data
[dst
][0] = LINTERP( t
,
1117 VB
->BackfaceIndexPtr
->data
[out
][0],
1118 VB
->BackfaceIndexPtr
->data
[in
][0] );
1122 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
1125 _tnl_generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
1128 void _tnl_generic_copy_pv_extras( struct gl_context
*ctx
,
1129 GLuint dst
, GLuint src
)
1131 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1133 /* See above comment:
1135 if (VB
->BackfaceColorPtr
&& VB
->BackfaceColorPtr
->stride
) {
1136 COPY_4FV( VB
->BackfaceColorPtr
->data
[dst
],
1137 VB
->BackfaceColorPtr
->data
[src
] );
1140 if (VB
->BackfaceSecondaryColorPtr
) {
1141 COPY_4FV( VB
->BackfaceSecondaryColorPtr
->data
[dst
],
1142 VB
->BackfaceSecondaryColorPtr
->data
[src
] );
1145 if (VB
->BackfaceIndexPtr
) {
1146 VB
->BackfaceIndexPtr
->data
[dst
][0] = VB
->BackfaceIndexPtr
->data
[src
][0];
1149 _tnl_generic_copy_pv(ctx
, dst
, src
);