2 * Copyright 2003 Tungsten Graphics, inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keithw@tungstengraphics.com>
32 #include "t_context.h"
36 /* Build and manage clipspace/ndc/window vertices.
38 * Another new mechanism designed and crying out for codegen. Before
39 * that, it would be very interesting to investigate the merger of
40 * these vertices and those built in t_vtx_*.
49 * These functions take the NDC coordinates pointed to by 'in', apply the
50 * NDC->Viewport mapping and store the results at 'v'.
54 insert_4f_viewport_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
57 GLfloat
*out
= (GLfloat
*)v
;
58 const GLfloat
* const vp
= a
->vp
;
60 out
[0] = vp
[0] * in
[0] + vp
[12];
61 out
[1] = vp
[5] * in
[1] + vp
[13];
62 out
[2] = vp
[10] * in
[2] + vp
[14];
66 static void insert_4f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
69 GLfloat
*out
= (GLfloat
*)v
;
70 const GLfloat
* const vp
= a
->vp
;
72 out
[0] = vp
[0] * in
[0] + vp
[12];
73 out
[1] = vp
[5] * in
[1] + vp
[13];
74 out
[2] = vp
[10] * in
[2] + vp
[14];
78 static void insert_4f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
81 GLfloat
*out
= (GLfloat
*)v
;
82 const GLfloat
* const vp
= a
->vp
;
84 out
[0] = vp
[0] * in
[0] + vp
[12];
85 out
[1] = vp
[5] * in
[1] + vp
[13];
90 static void insert_4f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
93 GLfloat
*out
= (GLfloat
*)v
;
94 const GLfloat
* const vp
= a
->vp
;
96 out
[0] = vp
[0] * in
[0] + vp
[12];
102 static void insert_3f_viewport_3( 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 void insert_3f_viewport_2( 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];
120 out
[1] = vp
[5] * in
[1] + vp
[13];
121 out
[2] = vp
[10] * in
[2] + vp
[14];
124 static void insert_3f_viewport_1( 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];
135 static void insert_2f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
138 GLfloat
*out
= (GLfloat
*)v
;
139 const GLfloat
* const vp
= a
->vp
;
141 out
[0] = vp
[0] * in
[0] + vp
[12];
142 out
[1] = vp
[5] * in
[1] + vp
[13];
145 static void insert_2f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
148 GLfloat
*out
= (GLfloat
*)v
;
149 const GLfloat
* const vp
= a
->vp
;
151 out
[0] = vp
[0] * in
[0] + vp
[12];
157 * These functions do the same as above, except for the viewport mapping.
160 static void insert_4f_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
162 GLfloat
*out
= (GLfloat
*)(v
);
171 static void insert_4f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
173 GLfloat
*out
= (GLfloat
*)(v
);
182 static void insert_4f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
184 GLfloat
*out
= (GLfloat
*)(v
);
193 static void insert_4f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
195 GLfloat
*out
= (GLfloat
*)(v
);
204 static void insert_3f_xyw_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
206 GLfloat
*out
= (GLfloat
*)(v
);
214 static void insert_3f_xyw_err( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
216 (void) a
; (void) v
; (void) in
;
220 static void insert_3f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
222 GLfloat
*out
= (GLfloat
*)(v
);
230 static void insert_3f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
232 GLfloat
*out
= (GLfloat
*)(v
);
240 static void insert_3f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
242 GLfloat
*out
= (GLfloat
*)(v
);
251 static void insert_2f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
253 GLfloat
*out
= (GLfloat
*)(v
);
260 static void insert_2f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
262 GLfloat
*out
= (GLfloat
*)(v
);
269 static void insert_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
271 GLfloat
*out
= (GLfloat
*)(v
);
277 static void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
280 GLchan
*c
= (GLchan
*)v
;
282 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
283 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
284 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
285 UNCLAMPED_FLOAT_TO_CHAN(c
[3], in
[3]);
288 static void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
291 GLchan
*c
= (GLchan
*)v
;
293 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
294 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
295 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
299 static void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
302 GLchan
*c
= (GLchan
*)v
;
304 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
305 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
310 static void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
313 GLchan
*c
= (GLchan
*)v
;
315 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
321 static void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
325 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
326 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
327 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
328 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
331 static void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
335 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
336 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
337 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
341 static void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
345 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
346 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
351 static void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
355 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
361 static void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
365 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
366 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
367 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
368 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
371 static void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
375 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
376 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
377 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
381 static void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
385 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
386 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
391 static void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
395 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
401 static void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
405 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
406 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
407 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
408 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
411 static void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
415 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
416 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
417 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
421 static void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
425 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
426 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
431 static void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
435 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
441 static void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
445 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
446 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
447 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
448 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
451 static void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
455 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
456 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
457 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
461 static void insert_4ub_4f_abgr_2( 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]);
471 static void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
475 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
481 static void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
485 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
486 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
487 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
490 static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
494 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
495 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
499 static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
503 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
508 static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
512 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
513 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
514 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
517 static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
521 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
522 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
526 static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
530 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
536 static void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
540 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
544 /***********************************************************************
545 * Functions to perform the reverse operations to the above, for
546 * swrast translation and clip-interpolation.
548 * Currently always extracts a full 4 floats.
551 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
554 const GLfloat
*in
= (const GLfloat
*)v
;
555 const GLfloat
* const vp
= a
->vp
;
557 /* Although included for completeness, the position coordinate is
558 * usually handled differently during clipping.
560 out
[0] = (in
[0] - vp
[12]) / vp
[0];
561 out
[1] = (in
[1] - vp
[13]) / vp
[5];
562 out
[2] = (in
[2] - vp
[14]) / vp
[10];
566 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
569 const GLfloat
*in
= (const GLfloat
*)v
;
570 const GLfloat
* const vp
= a
->vp
;
572 out
[0] = (in
[0] - vp
[12]) / vp
[0];
573 out
[1] = (in
[1] - vp
[13]) / vp
[5];
574 out
[2] = (in
[2] - vp
[14]) / vp
[10];
579 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
582 const GLfloat
*in
= (const GLfloat
*)v
;
583 const GLfloat
* const vp
= a
->vp
;
585 out
[0] = (in
[0] - vp
[12]) / vp
[0];
586 out
[1] = (in
[1] - vp
[13]) / vp
[5];
592 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
594 const GLfloat
*in
= (const GLfloat
*)v
;
603 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
605 const GLfloat
*in
= (const GLfloat
*)v
;
615 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
617 const GLfloat
*in
= (const GLfloat
*)v
;
627 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
629 const GLfloat
*in
= (const GLfloat
*)v
;
638 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
640 const GLfloat
*in
= (const GLfloat
*)v
;
649 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
652 GLchan
*c
= (GLchan
*)v
;
655 out
[0] = CHAN_TO_FLOAT(c
[0]);
656 out
[1] = CHAN_TO_FLOAT(c
[1]);
657 out
[2] = CHAN_TO_FLOAT(c
[2]);
658 out
[3] = CHAN_TO_FLOAT(c
[3]);
661 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
665 out
[0] = UBYTE_TO_FLOAT(v
[0]);
666 out
[1] = UBYTE_TO_FLOAT(v
[1]);
667 out
[2] = UBYTE_TO_FLOAT(v
[2]);
668 out
[3] = UBYTE_TO_FLOAT(v
[3]);
671 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
675 out
[2] = UBYTE_TO_FLOAT(v
[0]);
676 out
[1] = UBYTE_TO_FLOAT(v
[1]);
677 out
[0] = UBYTE_TO_FLOAT(v
[2]);
678 out
[3] = UBYTE_TO_FLOAT(v
[3]);
681 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
685 out
[3] = UBYTE_TO_FLOAT(v
[0]);
686 out
[0] = UBYTE_TO_FLOAT(v
[1]);
687 out
[1] = UBYTE_TO_FLOAT(v
[2]);
688 out
[2] = UBYTE_TO_FLOAT(v
[3]);
691 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
695 out
[3] = UBYTE_TO_FLOAT(v
[0]);
696 out
[2] = UBYTE_TO_FLOAT(v
[1]);
697 out
[1] = UBYTE_TO_FLOAT(v
[2]);
698 out
[0] = UBYTE_TO_FLOAT(v
[3]);
701 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
705 out
[0] = UBYTE_TO_FLOAT(v
[0]);
706 out
[1] = UBYTE_TO_FLOAT(v
[1]);
707 out
[2] = UBYTE_TO_FLOAT(v
[2]);
711 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
715 out
[2] = UBYTE_TO_FLOAT(v
[0]);
716 out
[1] = UBYTE_TO_FLOAT(v
[1]);
717 out
[0] = UBYTE_TO_FLOAT(v
[2]);
721 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
724 out
[0] = UBYTE_TO_FLOAT(v
[0]);
733 tnl_extract_func extract
;
734 tnl_insert_func insert
[4];
735 const GLuint attrsize
;
736 } format_info
[EMIT_MAX
] = {
740 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
745 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
746 2 * sizeof(GLfloat
) },
750 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
751 3 * sizeof(GLfloat
) },
755 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
756 4 * sizeof(GLfloat
) },
760 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
761 insert_2f_viewport_2
},
762 2 * sizeof(GLfloat
) },
766 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
767 insert_3f_viewport_3
},
768 3 * sizeof(GLfloat
) },
772 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
773 insert_4f_viewport_4
},
774 4 * sizeof(GLfloat
) },
778 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
780 3 * sizeof(GLfloat
) },
784 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
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
) },
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
) },
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
) },
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
) },
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
) },
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
) },
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
) },
837 /***********************************************************************
838 * Generic (non-codegen) functions for whole vertices or groups of
842 static void generic_emit( GLcontext
*ctx
,
843 GLuint start
, GLuint end
,
846 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
847 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
848 struct tnl_clipspace_attr
*a
= vtx
->attr
;
849 GLubyte
*v
= (GLubyte
*)dest
;
851 const GLuint count
= vtx
->attr_count
;
854 for (j
= 0; j
< count
; j
++) {
855 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
856 a
[j
].inputstride
= vptr
->stride
;
857 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
858 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
862 stride
= vtx
->vertex_size
;
864 for (i
= 0 ; i
< end
; i
++, v
+= stride
) {
865 for (j
= 0; j
< count
; j
++) {
866 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
867 a
[j
].inputptr
+= a
[j
].inputstride
;
868 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
874 static void generic_interp( GLcontext
*ctx
,
876 GLuint edst
, GLuint eout
, GLuint ein
,
877 GLboolean force_boundary
)
879 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
880 struct vertex_buffer
*VB
= &tnl
->vb
;
881 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
882 const GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
883 const GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
884 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
885 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
886 const GLuint attr_count
= vtx
->attr_count
;
888 (void) force_boundary
;
890 if (tnl
->NeedNdcCoords
) {
891 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
892 if (dstclip
[3] != 0.0) {
893 const GLfloat w
= 1.0f
/ dstclip
[3];
896 pos
[0] = dstclip
[0] * w
;
897 pos
[1] = dstclip
[1] * w
;
898 pos
[2] = dstclip
[2] * w
;
901 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
905 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
909 for (j
= 1; j
< attr_count
; j
++) {
910 GLfloat fin
[4], fout
[4], fdst
[4];
912 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
913 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
915 INTERP_F( t
, fdst
[3], fout
[3], fin
[3] );
916 INTERP_F( t
, fdst
[2], fout
[2], fin
[2] );
917 INTERP_F( t
, fdst
[1], fout
[1], fin
[1] );
918 INTERP_F( t
, fdst
[0], fout
[0], fin
[0] );
920 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
925 /* Extract color attributes from one vertex and insert them into
926 * another. (Shortcircuit extract/insert with memcpy).
928 static void generic_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
930 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
931 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
932 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
933 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
934 const GLuint attr_count
= vtx
->attr_count
;
937 for (j
= 0; j
< attr_count
; j
++) {
938 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
939 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
941 _mesa_memcpy( vdst
+ a
[j
].vertoffset
,
942 vsrc
+ a
[j
].vertoffset
,
949 /* Helper functions for hardware which doesn't put back colors and/or
950 * edgeflags into vertices.
952 static void generic_interp_extras( GLcontext
*ctx
,
954 GLuint dst
, GLuint out
, GLuint in
,
955 GLboolean force_boundary
)
957 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
959 if (VB
->ColorPtr
[1]) {
960 assert(VB
->ColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
963 VB
->ColorPtr
[1]->data
[dst
],
964 VB
->ColorPtr
[1]->data
[out
],
965 VB
->ColorPtr
[1]->data
[in
] );
967 if (VB
->SecondaryColorPtr
[1]) {
969 VB
->SecondaryColorPtr
[1]->data
[dst
],
970 VB
->SecondaryColorPtr
[1]->data
[out
],
971 VB
->SecondaryColorPtr
[1]->data
[in
] );
974 else if (VB
->IndexPtr
[1]) {
975 VB
->IndexPtr
[1]->data
[dst
][0] = LINTERP( t
,
976 VB
->IndexPtr
[1]->data
[out
][0],
977 VB
->IndexPtr
[1]->data
[in
][0] );
981 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
984 generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
987 static void generic_copy_pv_extras( GLcontext
*ctx
,
988 GLuint dst
, GLuint src
)
990 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
992 if (VB
->ColorPtr
[1]) {
993 COPY_4FV( VB
->ColorPtr
[1]->data
[dst
],
994 VB
->ColorPtr
[1]->data
[src
] );
996 if (VB
->SecondaryColorPtr
[1]) {
997 COPY_4FV( VB
->SecondaryColorPtr
[1]->data
[dst
],
998 VB
->SecondaryColorPtr
[1]->data
[src
] );
1001 else if (VB
->IndexPtr
[1]) {
1002 VB
->IndexPtr
[1]->data
[dst
][0] = VB
->IndexPtr
[1]->data
[src
][0];
1005 generic_copy_pv(ctx
, dst
, src
);
1011 /***********************************************************************
1012 * Build codegen functions or return generic ones:
1016 static void do_emit( GLcontext
*ctx
, GLuint start
, GLuint end
,
1019 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1020 struct vertex_buffer
*VB
= &tnl
->vb
;
1021 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1022 struct tnl_clipspace_attr
*a
= vtx
->attr
;
1023 const GLuint count
= vtx
->attr_count
;
1026 for (j
= 0; j
< count
; j
++) {
1027 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
1028 a
[j
].inputstride
= vptr
->stride
;
1029 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
1030 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
1036 vtx
->emit
= _tnl_codegen_emit(ctx
);
1039 vtx
->emit
= generic_emit
;
1041 vtx
->emit( ctx
, start
, end
, dest
);
1046 static void choose_interp_func( GLcontext
*ctx
,
1048 GLuint edst
, GLuint eout
, GLuint ein
,
1049 GLboolean force_boundary
)
1051 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1053 if (vtx
->need_extras
&&
1054 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
1055 vtx
->interp
= generic_interp_extras
;
1057 vtx
->interp
= generic_interp
;
1060 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
1064 static void choose_copy_pv_func( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1066 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1068 if (vtx
->need_extras
&&
1069 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
1070 vtx
->copy_pv
= generic_copy_pv_extras
;
1072 vtx
->copy_pv
= generic_copy_pv
;
1075 vtx
->copy_pv( ctx
, edst
, esrc
);
1079 /***********************************************************************
1080 * Public entrypoints, mostly dispatch to the above:
1084 /* Interpolate between two vertices to produce a third:
1086 void _tnl_interp( GLcontext
*ctx
,
1088 GLuint edst
, GLuint eout
, GLuint ein
,
1089 GLboolean force_boundary
)
1091 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1092 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
1095 /* Copy colors from one vertex to another:
1097 void _tnl_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1099 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1100 vtx
->copy_pv( ctx
, edst
, esrc
);
1104 /* Extract a named attribute from a hardware vertex. Will have to
1105 * reverse any viewport transformation, swizzling or other conversions
1106 * which may have been applied:
1108 void _tnl_get_attr( GLcontext
*ctx
, const void *vin
,
1109 GLenum attr
, GLfloat
*dest
)
1111 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1112 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1113 const GLuint attr_count
= vtx
->attr_count
;
1116 for (j
= 0; j
< attr_count
; j
++) {
1117 if (a
[j
].attrib
== attr
) {
1118 a
[j
].extract( &a
[j
], dest
, (GLubyte
*)vin
+ a
[j
].vertoffset
);
1123 /* Else return the value from ctx->Current -- dangerous???
1125 _mesa_memcpy( dest
, ctx
->Current
.Attrib
[attr
], 4*sizeof(GLfloat
));
1129 /* Complementary operation to the above.
1131 void _tnl_set_attr( GLcontext
*ctx
, void *vout
,
1132 GLenum attr
, const GLfloat
*src
)
1134 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1135 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1136 const GLuint attr_count
= vtx
->attr_count
;
1139 for (j
= 0; j
< attr_count
; j
++) {
1140 if (a
[j
].attrib
== attr
) {
1141 a
[j
].insert
[4-1]( &a
[j
], (GLubyte
*)vout
+ a
[j
].vertoffset
, src
);
1148 void *_tnl_get_vertex( GLcontext
*ctx
, GLuint nr
)
1150 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1152 return vtx
->vertex_buf
+ nr
* vtx
->vertex_size
;
1155 void _tnl_invalidate_vertex_state( GLcontext
*ctx
, GLuint new_state
)
1157 if (new_state
& (_DD_NEW_TRI_LIGHT_TWOSIDE
|_DD_NEW_TRI_UNFILLED
) ) {
1158 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1159 vtx
->new_inputs
= ~0;
1160 vtx
->interp
= choose_interp_func
;
1161 vtx
->copy_pv
= choose_copy_pv_func
;
1166 GLuint
_tnl_install_attrs( GLcontext
*ctx
, const struct tnl_attr_map
*map
,
1167 GLuint nr
, const GLfloat
*vp
,
1168 GLuint unpacked_size
)
1170 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1174 assert(nr
< _TNL_ATTRIB_MAX
);
1175 assert(nr
== 0 || map
[0].attrib
== VERT_ATTRIB_POS
);
1178 vtx
->interp
= choose_interp_func
;
1179 vtx
->copy_pv
= choose_copy_pv_func
;
1180 vtx
->new_inputs
= ~0;
1182 for (j
= 0, i
= 0; i
< nr
; i
++) {
1183 const GLuint format
= map
[i
].format
;
1184 if (format
== EMIT_PAD
) {
1186 fprintf(stderr, "%d: pad %d, offset %d\n", i,
1187 map[i].offset, offset);
1189 offset
+= map
[i
].offset
;
1193 vtx
->attr
[j
].attrib
= map
[i
].attrib
;
1194 vtx
->attr
[j
].format
= format
;
1195 vtx
->attr
[j
].vp
= vp
;
1196 vtx
->attr
[j
].insert
= format_info
[format
].insert
;
1197 vtx
->attr
[j
].extract
= format_info
[format
].extract
;
1198 vtx
->attr
[j
].vertattrsize
= format_info
[format
].attrsize
;
1201 vtx
->attr
[j
].vertoffset
= map
[i
].offset
;
1203 vtx
->attr
[j
].vertoffset
= offset
;
1206 fprintf(stderr, "%d: %s, vp %p, offset %d\n", i,
1207 format_info[format].name, (void *)vp,
1208 vtx->attr[j].vertoffset);
1210 offset
+= format_info
[format
].attrsize
;
1215 vtx
->attr_count
= j
;
1218 vtx
->vertex_size
= unpacked_size
;
1220 vtx
->vertex_size
= offset
;
1222 assert(vtx
->vertex_size
<= vtx
->max_vertex_size
);
1224 return vtx
->vertex_size
;
1229 void _tnl_invalidate_vertices( GLcontext
*ctx
, GLuint newinputs
)
1231 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1232 vtx
->new_inputs
|= newinputs
;
1236 void _tnl_build_vertices( GLcontext
*ctx
,
1241 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1242 const GLuint stride
= vtx
->vertex_size
;
1243 GLubyte
*vDest
= ((GLubyte
*)vtx
->vertex_buf
+ (start
*stride
));
1245 newinputs
|= vtx
->new_inputs
;
1246 vtx
->new_inputs
= 0;
1249 do_emit( ctx
, start
, end
, vDest
);
1253 void *_tnl_emit_vertices_to_buffer( GLcontext
*ctx
,
1258 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1259 do_emit( ctx
, start
, end
, dest
);
1260 return (void *)((GLubyte
*)dest
+ vtx
->vertex_size
* (end
- start
));
1264 void _tnl_init_vertices( GLcontext
*ctx
,
1266 GLuint max_vertex_size
)
1268 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1270 _tnl_install_attrs( ctx
, 0, 0, 0, 0 );
1272 vtx
->need_extras
= GL_TRUE
;
1273 if (max_vertex_size
> vtx
->max_vertex_size
) {
1274 _tnl_free_vertices( ctx
);
1275 vtx
->max_vertex_size
= max_vertex_size
;
1276 vtx
->vertex_buf
= (GLubyte
*)ALIGN_CALLOC(vb_size
* max_vertex_size
, 32 );
1279 _tnl_init_c_codegen( &vtx
->codegen
);
1283 void _tnl_free_vertices( GLcontext
*ctx
)
1285 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1286 if (vtx
->vertex_buf
) {
1287 ALIGN_FREE(vtx
->vertex_buf
);
1288 vtx
->vertex_buf
= 0;