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_*.
44 static void choose_emit_func( GLcontext
*ctx
, GLuint count
, GLubyte
*dest
);
52 * These functions take the NDC coordinates pointed to by 'in', apply the
53 * NDC->Viewport mapping and store the results at 'v'.
56 static INLINE
void insert_4f_viewport_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
59 GLfloat
*out
= (GLfloat
*)v
;
60 const GLfloat
* const vp
= a
->vp
;
62 out
[0] = vp
[0] * in
[0] + vp
[12];
63 out
[1] = vp
[5] * in
[1] + vp
[13];
64 out
[2] = vp
[10] * in
[2] + vp
[14];
68 static INLINE
void insert_4f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
71 GLfloat
*out
= (GLfloat
*)v
;
72 const GLfloat
* const vp
= a
->vp
;
74 out
[0] = vp
[0] * in
[0] + vp
[12];
75 out
[1] = vp
[5] * in
[1] + vp
[13];
76 out
[2] = vp
[10] * in
[2] + vp
[14];
80 static INLINE
void insert_4f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
83 GLfloat
*out
= (GLfloat
*)v
;
84 const GLfloat
* const vp
= a
->vp
;
86 out
[0] = vp
[0] * in
[0] + vp
[12];
87 out
[1] = vp
[5] * in
[1] + vp
[13];
92 static INLINE
void insert_4f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
95 GLfloat
*out
= (GLfloat
*)v
;
96 const GLfloat
* const vp
= a
->vp
;
98 out
[0] = vp
[0] * in
[0] + vp
[12];
104 static INLINE
void insert_3f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
107 GLfloat
*out
= (GLfloat
*)v
;
108 const GLfloat
* const vp
= a
->vp
;
110 out
[0] = vp
[0] * in
[0] + vp
[12];
111 out
[1] = vp
[5] * in
[1] + vp
[13];
112 out
[2] = vp
[10] * in
[2] + vp
[14];
115 static INLINE
void insert_3f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
118 GLfloat
*out
= (GLfloat
*)v
;
119 const GLfloat
* const vp
= a
->vp
;
121 out
[0] = vp
[0] * in
[0] + vp
[12];
122 out
[1] = vp
[5] * in
[1] + vp
[13];
123 out
[2] = vp
[10] * in
[2] + vp
[14];
126 static INLINE
void insert_3f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
129 GLfloat
*out
= (GLfloat
*)v
;
130 const GLfloat
* const vp
= a
->vp
;
132 out
[0] = vp
[0] * in
[0] + vp
[12];
137 static INLINE
void insert_2f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
140 GLfloat
*out
= (GLfloat
*)v
;
141 const GLfloat
* const vp
= a
->vp
;
143 out
[0] = vp
[0] * in
[0] + vp
[12];
144 out
[1] = vp
[5] * in
[1] + vp
[13];
147 static INLINE
void insert_2f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
150 GLfloat
*out
= (GLfloat
*)v
;
151 const GLfloat
* const vp
= a
->vp
;
153 out
[0] = vp
[0] * in
[0] + vp
[12];
159 * These functions do the same as above, except for the viewport mapping.
162 static INLINE
void insert_4f_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
164 GLfloat
*out
= (GLfloat
*)(v
);
173 static INLINE
void insert_4f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
175 GLfloat
*out
= (GLfloat
*)(v
);
184 static INLINE
void insert_4f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
186 GLfloat
*out
= (GLfloat
*)(v
);
195 static INLINE
void insert_4f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
197 GLfloat
*out
= (GLfloat
*)(v
);
206 static INLINE
void insert_3f_xyw_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
208 GLfloat
*out
= (GLfloat
*)(v
);
216 static INLINE
void insert_3f_xyw_err( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
218 (void) a
; (void) v
; (void) in
;
222 static INLINE
void insert_3f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
224 GLfloat
*out
= (GLfloat
*)(v
);
232 static INLINE
void insert_3f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
234 GLfloat
*out
= (GLfloat
*)(v
);
242 static INLINE
void insert_3f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
244 GLfloat
*out
= (GLfloat
*)(v
);
253 static INLINE
void insert_2f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
255 GLfloat
*out
= (GLfloat
*)(v
);
262 static INLINE
void insert_2f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
264 GLfloat
*out
= (GLfloat
*)(v
);
271 static INLINE
void insert_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
273 GLfloat
*out
= (GLfloat
*)(v
);
279 static INLINE
void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
282 GLchan
*c
= (GLchan
*)v
;
284 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
285 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
286 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
287 UNCLAMPED_FLOAT_TO_CHAN(c
[3], in
[3]);
290 static INLINE
void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
293 GLchan
*c
= (GLchan
*)v
;
295 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
296 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
297 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
301 static INLINE
void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
304 GLchan
*c
= (GLchan
*)v
;
306 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
307 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
312 static INLINE
void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
315 GLchan
*c
= (GLchan
*)v
;
317 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
323 static INLINE
void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
327 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
328 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
329 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
330 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
333 static INLINE
void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
337 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
338 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
339 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
343 static INLINE
void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
347 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
348 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
353 static INLINE
void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
357 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
363 static INLINE
void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
367 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
368 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
369 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
370 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
373 static INLINE
void insert_4ub_4f_bgra_3( 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]);
383 static INLINE
void insert_4ub_4f_bgra_2( 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]);
393 static INLINE
void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
397 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
403 static INLINE
void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
407 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
408 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
409 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
410 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
413 static INLINE
void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
417 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
418 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
419 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
423 static INLINE
void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
427 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
428 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
433 static INLINE
void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
437 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
443 static INLINE
void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
447 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
448 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
449 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
450 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
453 static INLINE
void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
457 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
458 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
459 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
463 static INLINE
void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
467 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
468 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
473 static INLINE
void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
477 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
483 static INLINE
void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
487 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
488 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
489 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
492 static INLINE
void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
496 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
497 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
501 static INLINE
void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
505 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
510 static INLINE
void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
514 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
515 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
516 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
519 static INLINE
void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
523 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
524 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
528 static INLINE
void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
532 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
538 static INLINE
void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
542 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
546 /***********************************************************************
547 * Functions to perform the reverse operations to the above, for
548 * swrast translation and clip-interpolation.
550 * Currently always extracts a full 4 floats.
553 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
556 const GLfloat
*in
= (const GLfloat
*)v
;
557 const GLfloat
* const vp
= a
->vp
;
559 /* Although included for completeness, the position coordinate is
560 * usually handled differently during clipping.
562 out
[0] = (in
[0] - vp
[12]) / vp
[0];
563 out
[1] = (in
[1] - vp
[13]) / vp
[5];
564 out
[2] = (in
[2] - vp
[14]) / vp
[10];
568 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
571 const GLfloat
*in
= (const GLfloat
*)v
;
572 const GLfloat
* const vp
= a
->vp
;
574 out
[0] = (in
[0] - vp
[12]) / vp
[0];
575 out
[1] = (in
[1] - vp
[13]) / vp
[5];
576 out
[2] = (in
[2] - vp
[14]) / vp
[10];
581 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
584 const GLfloat
*in
= (const GLfloat
*)v
;
585 const GLfloat
* const vp
= a
->vp
;
587 out
[0] = (in
[0] - vp
[12]) / vp
[0];
588 out
[1] = (in
[1] - vp
[13]) / vp
[5];
594 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
596 const GLfloat
*in
= (const GLfloat
*)v
;
605 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
607 const GLfloat
*in
= (const GLfloat
*)v
;
617 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
619 const GLfloat
*in
= (const GLfloat
*)v
;
629 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
631 const GLfloat
*in
= (const GLfloat
*)v
;
640 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
642 const GLfloat
*in
= (const GLfloat
*)v
;
651 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
654 GLchan
*c
= (GLchan
*)v
;
657 out
[0] = CHAN_TO_FLOAT(c
[0]);
658 out
[1] = CHAN_TO_FLOAT(c
[1]);
659 out
[2] = CHAN_TO_FLOAT(c
[2]);
660 out
[3] = CHAN_TO_FLOAT(c
[3]);
663 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
667 out
[0] = UBYTE_TO_FLOAT(v
[0]);
668 out
[1] = UBYTE_TO_FLOAT(v
[1]);
669 out
[2] = UBYTE_TO_FLOAT(v
[2]);
670 out
[3] = UBYTE_TO_FLOAT(v
[3]);
673 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
677 out
[2] = UBYTE_TO_FLOAT(v
[0]);
678 out
[1] = UBYTE_TO_FLOAT(v
[1]);
679 out
[0] = UBYTE_TO_FLOAT(v
[2]);
680 out
[3] = UBYTE_TO_FLOAT(v
[3]);
683 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
687 out
[3] = UBYTE_TO_FLOAT(v
[0]);
688 out
[0] = UBYTE_TO_FLOAT(v
[1]);
689 out
[1] = UBYTE_TO_FLOAT(v
[2]);
690 out
[2] = UBYTE_TO_FLOAT(v
[3]);
693 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
697 out
[3] = UBYTE_TO_FLOAT(v
[0]);
698 out
[2] = UBYTE_TO_FLOAT(v
[1]);
699 out
[1] = UBYTE_TO_FLOAT(v
[2]);
700 out
[0] = UBYTE_TO_FLOAT(v
[3]);
703 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
707 out
[0] = UBYTE_TO_FLOAT(v
[0]);
708 out
[1] = UBYTE_TO_FLOAT(v
[1]);
709 out
[2] = UBYTE_TO_FLOAT(v
[2]);
713 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
717 out
[2] = UBYTE_TO_FLOAT(v
[0]);
718 out
[1] = UBYTE_TO_FLOAT(v
[1]);
719 out
[0] = UBYTE_TO_FLOAT(v
[2]);
723 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
726 out
[0] = UBYTE_TO_FLOAT(v
[0]);
735 tnl_extract_func extract
;
736 tnl_insert_func insert
[4];
737 const GLuint attrsize
;
738 } format_info
[EMIT_MAX
] = {
742 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
747 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
748 2 * sizeof(GLfloat
) },
752 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
753 3 * sizeof(GLfloat
) },
757 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
758 4 * sizeof(GLfloat
) },
762 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
763 insert_2f_viewport_2
},
764 2 * sizeof(GLfloat
) },
768 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
769 insert_3f_viewport_3
},
770 3 * sizeof(GLfloat
) },
774 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
775 insert_4f_viewport_4
},
776 4 * sizeof(GLfloat
) },
780 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
782 3 * sizeof(GLfloat
) },
786 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
791 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
792 insert_3ub_3f_rgb_3
},
793 3 * sizeof(GLubyte
) },
797 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
798 insert_3ub_3f_bgr_3
},
799 3 * sizeof(GLubyte
) },
803 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
804 insert_4ub_4f_rgba_4
},
805 4 * sizeof(GLubyte
) },
809 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
810 insert_4ub_4f_bgra_4
},
811 4 * sizeof(GLubyte
) },
815 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
816 insert_4ub_4f_argb_4
},
817 4 * sizeof(GLubyte
) },
821 { insert_4ub_4f_abgr_1
, insert_4ub_4f_abgr_2
, insert_4ub_4f_abgr_3
,
822 insert_4ub_4f_abgr_4
},
823 4 * sizeof(GLubyte
) },
826 extract_4chan_4f_rgba
,
827 { insert_4chan_4f_rgba_1
, insert_4chan_4f_rgba_2
, insert_4chan_4f_rgba_3
,
828 insert_4chan_4f_rgba_4
},
829 4 * sizeof(GLchan
) },
841 /***********************************************************************
842 * Hardwired fastpaths for emitting whole vertices or groups of
846 static void emit_viewport3_rgba4( GLcontext
*ctx
,
850 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
851 struct tnl_clipspace_attr
*a
= vtx
->attr
;
854 if (a
[0].emit
!= insert_3f_viewport_3
||
855 a
[1].emit
!= insert_4ub_4f_rgba_4
) {
856 choose_emit_func( ctx
, count
, v
);
860 for (i
= 0 ; i
< count
; i
++, v
+= vtx
->vertex_size
) {
861 insert_3f_viewport_3( &a
[0], v
+ a
[0].vertoffset
, (GLfloat
*)a
[0].inputptr
);
862 a
[0].inputptr
+= a
[0].inputstride
;
864 insert_4ub_4f_rgba_4( &a
[1], v
+ a
[1].vertoffset
, (GLfloat
*)a
[1].inputptr
);
865 a
[1].inputptr
+= a
[1].inputstride
;
870 static void emit_viewport3_bgra4( GLcontext
*ctx
,
874 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
875 struct tnl_clipspace_attr
*a
= vtx
->attr
;
878 if (a
[0].emit
!= insert_3f_viewport_3
||
879 a
[1].emit
!= insert_4ub_4f_bgra_4
) {
880 choose_emit_func( ctx
, count
, v
);
884 for (i
= 0 ; i
< count
; i
++, v
+= vtx
->vertex_size
) {
885 insert_3f_viewport_3( &a
[0], v
+ a
[0].vertoffset
, (GLfloat
*)a
[0].inputptr
);
886 a
[0].inputptr
+= a
[0].inputstride
;
888 insert_4ub_4f_bgra_4( &a
[1], v
+ a
[1].vertoffset
, (GLfloat
*)a
[1].inputptr
);
889 a
[1].inputptr
+= a
[1].inputstride
;
894 static void emit_viewport4_rgba4_st2( GLcontext
*ctx
,
898 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
899 struct tnl_clipspace_attr
*a
= vtx
->attr
;
902 if (a
[0].emit
!= insert_4f_viewport_4
||
903 a
[1].emit
!= insert_4ub_4f_rgba_4
||
904 a
[2].emit
!= insert_2f_2
) {
905 choose_emit_func( ctx
, count
, v
);
909 for (i
= 0 ; i
< count
; i
++, v
+= vtx
->vertex_size
) {
910 insert_4f_viewport_4( &a
[0], v
+ a
[0].vertoffset
, (GLfloat
*)a
[0].inputptr
);
911 a
[0].inputptr
+= a
[0].inputstride
;
913 insert_4ub_4f_rgba_4( &a
[1], v
+ a
[1].vertoffset
, (GLfloat
*)a
[1].inputptr
);
914 a
[1].inputptr
+= a
[1].inputstride
;
916 insert_2f_2( &a
[2], v
+ a
[2].vertoffset
, (GLfloat
*)a
[2].inputptr
);
917 a
[2].inputptr
+= a
[2].inputstride
;
922 static void emit_viewport4_bgra4_st2( GLcontext
*ctx
,
926 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
927 struct tnl_clipspace_attr
*a
= vtx
->attr
;
930 if (a
[0].emit
!= insert_4f_viewport_4
||
931 a
[1].emit
!= insert_4ub_4f_bgra_4
||
932 a
[2].emit
!= insert_2f_2
) {
933 choose_emit_func( ctx
, count
, v
);
937 for (i
= 0 ; i
< count
; i
++, v
+= vtx
->vertex_size
) {
938 insert_4f_viewport_4( &a
[0], v
+ a
[0].vertoffset
, (GLfloat
*)a
[0].inputptr
);
939 a
[0].inputptr
+= a
[0].inputstride
;
941 insert_4ub_4f_bgra_4( &a
[1], v
+ a
[1].vertoffset
, (GLfloat
*)a
[1].inputptr
);
942 a
[1].inputptr
+= a
[1].inputstride
;
944 insert_2f_2( &a
[2], v
+ a
[2].vertoffset
, (GLfloat
*)a
[2].inputptr
);
945 a
[2].inputptr
+= a
[2].inputstride
;
951 static void emit_viewport4_rgba4_st2_st2( GLcontext
*ctx
,
955 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
956 struct tnl_clipspace_attr
*a
= vtx
->attr
;
959 if (a
[0].emit
!= insert_4f_viewport_4
||
960 a
[1].emit
!= insert_4ub_4f_rgba_4
||
961 a
[2].emit
!= insert_2f_2
||
962 a
[3].emit
!= insert_2f_2
) {
963 choose_emit_func( ctx
, count
, v
);
967 for (i
= 0 ; i
< count
; i
++, v
+= vtx
->vertex_size
) {
968 insert_4f_viewport_4( &a
[0], v
+ a
[0].vertoffset
, (GLfloat
*)a
[0].inputptr
);
969 a
[0].inputptr
+= a
[0].inputstride
;
971 insert_4ub_4f_rgba_4( &a
[1], v
+ a
[1].vertoffset
, (GLfloat
*)a
[1].inputptr
);
972 a
[1].inputptr
+= a
[1].inputstride
;
974 insert_2f_2( &a
[2], v
+ a
[2].vertoffset
, (GLfloat
*)a
[2].inputptr
);
975 a
[2].inputptr
+= a
[2].inputstride
;
977 insert_2f_2( &a
[3], v
+ a
[3].vertoffset
, (GLfloat
*)a
[3].inputptr
);
978 a
[3].inputptr
+= a
[3].inputstride
;
984 static void emit_viewport4_bgra4_st2_st2( GLcontext
*ctx
,
988 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
989 struct tnl_clipspace_attr
*a
= vtx
->attr
;
992 if (a
[0].emit
!= insert_4f_viewport_4
||
993 a
[1].emit
!= insert_4ub_4f_bgra_4
||
994 a
[2].emit
!= insert_2f_2
||
995 a
[3].emit
!= insert_2f_2
) {
996 choose_emit_func( ctx
, count
, v
);
1000 for (i
= 0 ; i
< count
; i
++, v
+= vtx
->vertex_size
) {
1001 insert_4f_viewport_4( &a
[0], v
+ a
[0].vertoffset
, (GLfloat
*)a
[0].inputptr
);
1002 a
[0].inputptr
+= a
[0].inputstride
;
1004 insert_4ub_4f_bgra_4( &a
[1], v
+ a
[1].vertoffset
, (GLfloat
*)a
[1].inputptr
);
1005 a
[1].inputptr
+= a
[1].inputstride
;
1007 insert_2f_2( &a
[2], v
+ a
[2].vertoffset
, (GLfloat
*)a
[2].inputptr
);
1008 a
[2].inputptr
+= a
[2].inputstride
;
1010 insert_2f_2( &a
[3], v
+ a
[3].vertoffset
, (GLfloat
*)a
[3].inputptr
);
1011 a
[3].inputptr
+= a
[3].inputstride
;
1023 /***********************************************************************
1024 * Generic (non-codegen) functions for whole vertices or groups of
1028 static void generic_emit( GLcontext
*ctx
,
1032 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1033 struct tnl_clipspace_attr
*a
= vtx
->attr
;
1034 const GLuint attr_count
= vtx
->attr_count
;
1035 const GLuint stride
= vtx
->vertex_size
;
1038 for (i
= 0 ; i
< count
; i
++, v
+= stride
) {
1039 for (j
= 0; j
< attr_count
; j
++) {
1040 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
1041 a
[j
].inputptr
+= a
[j
].inputstride
;
1042 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
1048 static void generic_interp( GLcontext
*ctx
,
1050 GLuint edst
, GLuint eout
, GLuint ein
,
1051 GLboolean force_boundary
)
1053 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1054 struct vertex_buffer
*VB
= &tnl
->vb
;
1055 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1056 const GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
1057 const GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
1058 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1059 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1060 const GLuint attr_count
= vtx
->attr_count
;
1062 (void) force_boundary
;
1064 if (tnl
->NeedNdcCoords
) {
1065 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
1066 if (dstclip
[3] != 0.0) {
1067 const GLfloat w
= 1.0f
/ dstclip
[3];
1070 pos
[0] = dstclip
[0] * w
;
1071 pos
[1] = dstclip
[1] * w
;
1072 pos
[2] = dstclip
[2] * w
;
1075 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
1079 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
1083 for (j
= 1; j
< attr_count
; j
++) {
1084 GLfloat fin
[4], fout
[4], fdst
[4];
1086 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
1087 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
1089 INTERP_F( t
, fdst
[3], fout
[3], fin
[3] );
1090 INTERP_F( t
, fdst
[2], fout
[2], fin
[2] );
1091 INTERP_F( t
, fdst
[1], fout
[1], fin
[1] );
1092 INTERP_F( t
, fdst
[0], fout
[0], fin
[0] );
1094 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
1099 /* Extract color attributes from one vertex and insert them into
1100 * another. (Shortcircuit extract/insert with memcpy).
1102 static void generic_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1104 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1105 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
1106 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
1107 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1108 const GLuint attr_count
= vtx
->attr_count
;
1111 for (j
= 0; j
< attr_count
; j
++) {
1112 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
1113 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
1115 _mesa_memcpy( vdst
+ a
[j
].vertoffset
,
1116 vsrc
+ a
[j
].vertoffset
,
1117 a
[j
].vertattrsize
);
1123 /* Helper functions for hardware which doesn't put back colors and/or
1124 * edgeflags into vertices.
1126 static void generic_interp_extras( GLcontext
*ctx
,
1128 GLuint dst
, GLuint out
, GLuint in
,
1129 GLboolean force_boundary
)
1131 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1133 if (VB
->ColorPtr
[1]) {
1134 assert(VB
->ColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
1137 VB
->ColorPtr
[1]->data
[dst
],
1138 VB
->ColorPtr
[1]->data
[out
],
1139 VB
->ColorPtr
[1]->data
[in
] );
1141 if (VB
->SecondaryColorPtr
[1]) {
1143 VB
->SecondaryColorPtr
[1]->data
[dst
],
1144 VB
->SecondaryColorPtr
[1]->data
[out
],
1145 VB
->SecondaryColorPtr
[1]->data
[in
] );
1148 else if (VB
->IndexPtr
[1]) {
1149 VB
->IndexPtr
[1]->data
[dst
][0] = LINTERP( t
,
1150 VB
->IndexPtr
[1]->data
[out
][0],
1151 VB
->IndexPtr
[1]->data
[in
][0] );
1155 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
1158 generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
1161 static void generic_copy_pv_extras( GLcontext
*ctx
,
1162 GLuint dst
, GLuint src
)
1164 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1166 if (VB
->ColorPtr
[1]) {
1167 COPY_4FV( VB
->ColorPtr
[1]->data
[dst
],
1168 VB
->ColorPtr
[1]->data
[src
] );
1170 if (VB
->SecondaryColorPtr
[1]) {
1171 COPY_4FV( VB
->SecondaryColorPtr
[1]->data
[dst
],
1172 VB
->SecondaryColorPtr
[1]->data
[src
] );
1175 else if (VB
->IndexPtr
[1]) {
1176 VB
->IndexPtr
[1]->data
[dst
][0] = VB
->IndexPtr
[1]->data
[src
][0];
1179 generic_copy_pv(ctx
, dst
, src
);
1185 /***********************************************************************
1186 * Build codegen functions or return generic ones:
1190 static void choose_emit_func( GLcontext
*ctx
, GLuint count
, GLubyte
*dest
)
1192 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1193 struct tnl_clipspace_attr
*a
= vtx
->attr
;
1194 const GLuint attr_count
= vtx
->attr_count
;
1199 vtx
->emit
= _tnl_codegen_emit(ctx
);
1201 /* Does it fit a hardwired fastpath?
1203 switch (attr_count
) {
1205 if (a
[0].emit
== insert_3f_viewport_3
) {
1206 if (a
[1].emit
== insert_4ub_4f_bgra_4
)
1207 vtx
->emit
= emit_viewport3_bgra4
;
1208 else if (a
[1].emit
== insert_4ub_4f_rgba_4
)
1209 vtx
->emit
= emit_viewport3_rgba4
;
1213 if (a
[0].emit
== insert_4f_viewport_4
&&
1214 a
[2].emit
== insert_2f_2
) {
1215 if (a
[1].emit
== insert_4ub_4f_bgra_4
)
1216 vtx
->emit
= emit_viewport4_bgra4_st2
;
1217 else if (a
[1].emit
== insert_4ub_4f_rgba_4
)
1218 vtx
->emit
= emit_viewport4_rgba4_st2
;
1222 if (a
[0].emit
== insert_4f_viewport_4
&&
1223 a
[2].emit
== insert_2f_2
&&
1224 a
[3].emit
== insert_2f_2
) {
1225 if (a
[1].emit
== insert_4ub_4f_bgra_4
)
1226 vtx
->emit
= emit_viewport4_bgra4_st2_st2
;
1227 else if (a
[1].emit
== insert_4ub_4f_rgba_4
)
1228 vtx
->emit
= emit_viewport4_rgba4_st2_st2
;
1232 /* Otherwise use the generic version:
1235 vtx
->emit
= generic_emit
;
1237 vtx
->emit( ctx
, count
, dest
);
1242 static void choose_interp_func( GLcontext
*ctx
,
1244 GLuint edst
, GLuint eout
, GLuint ein
,
1245 GLboolean force_boundary
)
1247 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1249 if (vtx
->need_extras
&&
1250 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
1251 vtx
->interp
= generic_interp_extras
;
1253 vtx
->interp
= generic_interp
;
1256 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
1260 static void choose_copy_pv_func( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1262 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1264 if (vtx
->need_extras
&&
1265 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
1266 vtx
->copy_pv
= generic_copy_pv_extras
;
1268 vtx
->copy_pv
= generic_copy_pv
;
1271 vtx
->copy_pv( ctx
, edst
, esrc
);
1275 /***********************************************************************
1276 * Public entrypoints, mostly dispatch to the above:
1280 /* Interpolate between two vertices to produce a third:
1282 void _tnl_interp( GLcontext
*ctx
,
1284 GLuint edst
, GLuint eout
, GLuint ein
,
1285 GLboolean force_boundary
)
1287 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1288 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
1291 /* Copy colors from one vertex to another:
1293 void _tnl_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1295 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1296 vtx
->copy_pv( ctx
, edst
, esrc
);
1300 /* Extract a named attribute from a hardware vertex. Will have to
1301 * reverse any viewport transformation, swizzling or other conversions
1302 * which may have been applied:
1304 void _tnl_get_attr( GLcontext
*ctx
, const void *vin
,
1305 GLenum attr
, GLfloat
*dest
)
1307 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1308 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1309 const GLuint attr_count
= vtx
->attr_count
;
1312 for (j
= 0; j
< attr_count
; j
++) {
1313 if (a
[j
].attrib
== attr
) {
1314 a
[j
].extract( &a
[j
], dest
, (GLubyte
*)vin
+ a
[j
].vertoffset
);
1319 /* Else return the value from ctx->Current -- dangerous???
1321 _mesa_memcpy( dest
, ctx
->Current
.Attrib
[attr
], 4*sizeof(GLfloat
));
1325 /* Complementary operation to the above.
1327 void _tnl_set_attr( GLcontext
*ctx
, void *vout
,
1328 GLenum attr
, const GLfloat
*src
)
1330 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1331 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1332 const GLuint attr_count
= vtx
->attr_count
;
1335 for (j
= 0; j
< attr_count
; j
++) {
1336 if (a
[j
].attrib
== attr
) {
1337 a
[j
].insert
[4-1]( &a
[j
], (GLubyte
*)vout
+ a
[j
].vertoffset
, src
);
1344 void *_tnl_get_vertex( GLcontext
*ctx
, GLuint nr
)
1346 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1348 return vtx
->vertex_buf
+ nr
* vtx
->vertex_size
;
1351 void _tnl_invalidate_vertex_state( GLcontext
*ctx
, GLuint new_state
)
1353 if (new_state
& (_DD_NEW_TRI_LIGHT_TWOSIDE
|_DD_NEW_TRI_UNFILLED
) ) {
1354 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1355 vtx
->new_inputs
= ~0;
1356 vtx
->interp
= choose_interp_func
;
1357 vtx
->copy_pv
= choose_copy_pv_func
;
1362 GLuint
_tnl_install_attrs( GLcontext
*ctx
, const struct tnl_attr_map
*map
,
1363 GLuint nr
, const GLfloat
*vp
,
1364 GLuint unpacked_size
)
1366 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1370 assert(nr
< _TNL_ATTRIB_MAX
);
1371 assert(nr
== 0 || map
[0].attrib
== VERT_ATTRIB_POS
);
1373 vtx
->emit
= choose_emit_func
;
1374 vtx
->interp
= choose_interp_func
;
1375 vtx
->copy_pv
= choose_copy_pv_func
;
1376 vtx
->new_inputs
= ~0;
1378 for (j
= 0, i
= 0; i
< nr
; i
++) {
1379 const GLuint format
= map
[i
].format
;
1380 if (format
== EMIT_PAD
) {
1382 fprintf(stderr, "%d: pad %d, offset %d\n", i,
1383 map[i].offset, offset);
1385 offset
+= map
[i
].offset
;
1389 vtx
->attr
[j
].attrib
= map
[i
].attrib
;
1390 vtx
->attr
[j
].format
= format
;
1391 vtx
->attr
[j
].vp
= vp
;
1392 vtx
->attr
[j
].insert
= format_info
[format
].insert
;
1393 vtx
->attr
[j
].extract
= format_info
[format
].extract
;
1394 vtx
->attr
[j
].vertattrsize
= format_info
[format
].attrsize
;
1397 vtx
->attr
[j
].vertoffset
= map
[i
].offset
;
1399 vtx
->attr
[j
].vertoffset
= offset
;
1402 fprintf(stderr, "%d: %s, vp %p, offset %d\n", i,
1403 format_info[format].name, (void *)vp,
1404 vtx->attr[j].vertoffset);
1406 offset
+= format_info
[format
].attrsize
;
1411 vtx
->attr_count
= j
;
1414 vtx
->vertex_size
= unpacked_size
;
1416 vtx
->vertex_size
= offset
;
1418 assert(vtx
->vertex_size
<= vtx
->max_vertex_size
);
1420 return vtx
->vertex_size
;
1425 void _tnl_invalidate_vertices( GLcontext
*ctx
, GLuint newinputs
)
1427 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1428 vtx
->new_inputs
|= newinputs
;
1432 void _tnl_build_vertices( GLcontext
*ctx
,
1437 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1439 newinputs
|= vtx
->new_inputs
;
1440 vtx
->new_inputs
= 0;
1443 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1444 struct tnl_clipspace_attr
*a
= vtx
->attr
;
1445 const GLuint stride
= vtx
->vertex_size
;
1446 const GLuint count
= vtx
->attr_count
;
1449 for (j
= 0; j
< count
; j
++) {
1450 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
1451 a
[j
].inputstride
= vptr
->stride
;
1452 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
1453 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
1456 vtx
->emit( ctx
, end
- start
,
1457 (GLubyte
*)vtx
->vertex_buf
+ start
* stride
);
1462 void *_tnl_emit_vertices_to_buffer( GLcontext
*ctx
,
1467 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1468 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
1469 struct tnl_clipspace_attr
*a
= vtx
->attr
;
1470 const GLuint count
= vtx
->attr_count
;
1473 for (j
= 0; j
< count
; j
++) {
1474 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
1475 a
[j
].inputstride
= vptr
->stride
;
1476 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
1477 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
1480 /* Note: dest should not be adjusted for non-zero 'start' values:
1482 vtx
->emit( ctx
, end
- start
, dest
);
1484 return (void *)((GLubyte
*)dest
+ vtx
->vertex_size
* (end
- start
));
1488 void _tnl_init_vertices( GLcontext
*ctx
,
1490 GLuint max_vertex_size
)
1492 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1494 _tnl_install_attrs( ctx
, 0, 0, 0, 0 );
1496 vtx
->need_extras
= GL_TRUE
;
1497 if (max_vertex_size
> vtx
->max_vertex_size
) {
1498 _tnl_free_vertices( ctx
);
1499 vtx
->max_vertex_size
= max_vertex_size
;
1500 vtx
->vertex_buf
= (GLubyte
*)ALIGN_CALLOC(vb_size
* max_vertex_size
, 32 );
1503 _tnl_init_c_codegen( &vtx
->codegen
);
1507 void _tnl_free_vertices( GLcontext
*ctx
)
1509 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1510 if (vtx
->vertex_buf
) {
1511 ALIGN_FREE(vtx
->vertex_buf
);
1512 vtx
->vertex_buf
= 0;