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_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
445 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
446 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
447 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
450 static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
454 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
455 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
459 static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
463 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
468 static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
472 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
473 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
474 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
477 static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
481 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
482 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
486 static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
490 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
496 static void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
500 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
504 /***********************************************************************
505 * Functions to perform the reverse operations to the above, for
506 * swrast translation and clip-interpolation.
508 * Currently always extracts a full 4 floats.
511 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
514 const GLfloat
*in
= (const GLfloat
*)v
;
515 const GLfloat
* const vp
= a
->vp
;
517 /* Although included for completeness, the position coordinate is
518 * usually handled differently during clipping.
520 out
[0] = (in
[0] - vp
[12]) / vp
[0];
521 out
[1] = (in
[1] - vp
[13]) / vp
[5];
522 out
[2] = (in
[2] - vp
[14]) / vp
[10];
526 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
529 const GLfloat
*in
= (const GLfloat
*)v
;
530 const GLfloat
* const vp
= a
->vp
;
532 out
[0] = (in
[0] - vp
[12]) / vp
[0];
533 out
[1] = (in
[1] - vp
[13]) / vp
[5];
534 out
[2] = (in
[2] - vp
[14]) / vp
[10];
539 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
542 const GLfloat
*in
= (const GLfloat
*)v
;
543 const GLfloat
* const vp
= a
->vp
;
545 out
[0] = (in
[0] - vp
[12]) / vp
[0];
546 out
[1] = (in
[1] - vp
[13]) / vp
[5];
552 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
554 const GLfloat
*in
= (const GLfloat
*)v
;
563 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
565 const GLfloat
*in
= (const GLfloat
*)v
;
575 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
577 const GLfloat
*in
= (const GLfloat
*)v
;
587 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
589 const GLfloat
*in
= (const GLfloat
*)v
;
598 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
600 const GLfloat
*in
= (const GLfloat
*)v
;
609 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
612 GLchan
*c
= (GLchan
*)v
;
615 out
[0] = CHAN_TO_FLOAT(c
[0]);
616 out
[1] = CHAN_TO_FLOAT(c
[1]);
617 out
[2] = CHAN_TO_FLOAT(c
[2]);
618 out
[3] = CHAN_TO_FLOAT(c
[3]);
621 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
625 out
[0] = UBYTE_TO_FLOAT(v
[0]);
626 out
[1] = UBYTE_TO_FLOAT(v
[1]);
627 out
[2] = UBYTE_TO_FLOAT(v
[2]);
628 out
[3] = UBYTE_TO_FLOAT(v
[3]);
631 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
635 out
[2] = UBYTE_TO_FLOAT(v
[0]);
636 out
[1] = UBYTE_TO_FLOAT(v
[1]);
637 out
[0] = UBYTE_TO_FLOAT(v
[2]);
638 out
[3] = UBYTE_TO_FLOAT(v
[3]);
641 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
645 out
[3] = UBYTE_TO_FLOAT(v
[0]);
646 out
[0] = UBYTE_TO_FLOAT(v
[1]);
647 out
[1] = UBYTE_TO_FLOAT(v
[2]);
648 out
[2] = UBYTE_TO_FLOAT(v
[3]);
651 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
655 out
[0] = UBYTE_TO_FLOAT(v
[0]);
656 out
[1] = UBYTE_TO_FLOAT(v
[1]);
657 out
[2] = UBYTE_TO_FLOAT(v
[2]);
661 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
665 out
[2] = UBYTE_TO_FLOAT(v
[0]);
666 out
[1] = UBYTE_TO_FLOAT(v
[1]);
667 out
[0] = UBYTE_TO_FLOAT(v
[2]);
671 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
674 out
[0] = UBYTE_TO_FLOAT(v
[0]);
683 tnl_extract_func extract
;
684 tnl_insert_func insert
[4];
685 const GLuint attrsize
;
686 } format_info
[EMIT_MAX
] = {
690 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
695 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
696 2 * sizeof(GLfloat
) },
700 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
701 3 * sizeof(GLfloat
) },
705 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
706 4 * sizeof(GLfloat
) },
710 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
711 insert_2f_viewport_2
},
712 2 * sizeof(GLfloat
) },
716 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
717 insert_3f_viewport_3
},
718 3 * sizeof(GLfloat
) },
722 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
723 insert_4f_viewport_4
},
724 4 * sizeof(GLfloat
) },
728 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
730 3 * sizeof(GLfloat
) },
734 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
739 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
740 insert_3ub_3f_rgb_3
},
741 3 * sizeof(GLubyte
) },
745 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
746 insert_3ub_3f_bgr_3
},
747 3 * sizeof(GLubyte
) },
751 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
752 insert_4ub_4f_rgba_4
},
753 4 * sizeof(GLubyte
) },
757 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
758 insert_4ub_4f_bgra_4
},
759 4 * sizeof(GLubyte
) },
763 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
764 insert_4ub_4f_argb_4
},
765 4 * sizeof(GLubyte
) },
768 extract_4chan_4f_rgba
,
769 { insert_4chan_4f_rgba_1
, insert_4chan_4f_rgba_2
, insert_4chan_4f_rgba_3
,
770 insert_4chan_4f_rgba_4
},
771 4 * sizeof(GLchan
) },
781 /***********************************************************************
782 * Generic (non-codegen) functions for whole vertices or groups of
786 static void generic_emit( GLcontext
*ctx
,
787 GLuint start
, GLuint end
,
790 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
791 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
792 struct tnl_clipspace_attr
*a
= vtx
->attr
;
793 GLubyte
*v
= (GLubyte
*)dest
;
795 const GLuint count
= vtx
->attr_count
;
798 for (j
= 0; j
< count
; j
++) {
799 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
800 a
[j
].inputstride
= vptr
->stride
;
801 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
802 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
806 stride
= vtx
->vertex_size
;
808 for (i
= 0 ; i
< end
; i
++, v
+= stride
) {
809 for (j
= 0; j
< count
; j
++) {
810 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
811 a
[j
].inputptr
+= a
[j
].inputstride
;
812 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
818 static void generic_interp( GLcontext
*ctx
,
820 GLuint edst
, GLuint eout
, GLuint ein
,
821 GLboolean force_boundary
)
823 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
824 struct vertex_buffer
*VB
= &tnl
->vb
;
825 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
826 const GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
827 const GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
828 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
829 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
830 const GLuint attr_count
= vtx
->attr_count
;
832 (void) force_boundary
;
834 if (tnl
->NeedNdcCoords
) {
835 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
836 if (dstclip
[3] != 0.0) {
837 const GLfloat w
= 1.0f
/ dstclip
[3];
840 pos
[0] = dstclip
[0] * w
;
841 pos
[1] = dstclip
[1] * w
;
842 pos
[2] = dstclip
[2] * w
;
845 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
849 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
853 for (j
= 1; j
< attr_count
; j
++) {
854 GLfloat fin
[4], fout
[4], fdst
[4];
856 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
857 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
859 INTERP_F( t
, fdst
[3], fout
[3], fin
[3] );
860 INTERP_F( t
, fdst
[2], fout
[2], fin
[2] );
861 INTERP_F( t
, fdst
[1], fout
[1], fin
[1] );
862 INTERP_F( t
, fdst
[0], fout
[0], fin
[0] );
864 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
869 /* Extract color attributes from one vertex and insert them into
870 * another. (Shortcircuit extract/insert with memcpy).
872 static void generic_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
874 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
875 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
876 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
877 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
878 const GLuint attr_count
= vtx
->attr_count
;
881 for (j
= 0; j
< attr_count
; j
++) {
882 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
883 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
885 _mesa_memcpy( vdst
+ a
[j
].vertoffset
,
886 vsrc
+ a
[j
].vertoffset
,
893 /* Helper functions for hardware which doesn't put back colors and/or
894 * edgeflags into vertices.
896 static void generic_interp_extras( GLcontext
*ctx
,
898 GLuint dst
, GLuint out
, GLuint in
,
899 GLboolean force_boundary
)
901 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
903 if (VB
->ColorPtr
[1]) {
904 assert(VB
->ColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
907 VB
->ColorPtr
[1]->data
[dst
],
908 VB
->ColorPtr
[1]->data
[out
],
909 VB
->ColorPtr
[1]->data
[in
] );
911 if (VB
->SecondaryColorPtr
[1]) {
913 VB
->SecondaryColorPtr
[1]->data
[dst
],
914 VB
->SecondaryColorPtr
[1]->data
[out
],
915 VB
->SecondaryColorPtr
[1]->data
[in
] );
918 else if (VB
->IndexPtr
[1]) {
919 VB
->IndexPtr
[1]->data
[dst
][0] = LINTERP( t
,
920 VB
->IndexPtr
[1]->data
[out
][0],
921 VB
->IndexPtr
[1]->data
[in
][0] );
925 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
928 generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
931 static void generic_copy_pv_extras( GLcontext
*ctx
,
932 GLuint dst
, GLuint src
)
934 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
936 if (VB
->ColorPtr
[1]) {
937 COPY_4FV( VB
->ColorPtr
[1]->data
[dst
],
938 VB
->ColorPtr
[1]->data
[src
] );
940 if (VB
->SecondaryColorPtr
[1]) {
941 COPY_4FV( VB
->SecondaryColorPtr
[1]->data
[dst
],
942 VB
->SecondaryColorPtr
[1]->data
[src
] );
945 else if (VB
->IndexPtr
[1]) {
946 VB
->IndexPtr
[1]->data
[dst
][0] = VB
->IndexPtr
[1]->data
[src
][0];
949 generic_copy_pv(ctx
, dst
, src
);
955 /***********************************************************************
956 * Build codegen functions or return generic ones:
960 static void do_emit( GLcontext
*ctx
, GLuint start
, GLuint end
,
963 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
964 struct vertex_buffer
*VB
= &tnl
->vb
;
965 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
966 struct tnl_clipspace_attr
*a
= vtx
->attr
;
967 const GLuint count
= vtx
->attr_count
;
970 for (j
= 0; j
< count
; j
++) {
971 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
972 a
[j
].inputstride
= vptr
->stride
;
973 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
974 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
980 vtx
->emit
= _tnl_codegen_emit(ctx
);
983 vtx
->emit
= generic_emit
;
985 vtx
->emit( ctx
, start
, end
, dest
);
990 static void choose_interp_func( GLcontext
*ctx
,
992 GLuint edst
, GLuint eout
, GLuint ein
,
993 GLboolean force_boundary
)
995 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
997 if (vtx
->need_extras
&&
998 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
999 vtx
->interp
= generic_interp_extras
;
1001 vtx
->interp
= generic_interp
;
1004 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
1008 static void choose_copy_pv_func( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1010 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1012 if (vtx
->need_extras
&&
1013 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
1014 vtx
->copy_pv
= generic_copy_pv_extras
;
1016 vtx
->copy_pv
= generic_copy_pv
;
1019 vtx
->copy_pv( ctx
, edst
, esrc
);
1023 /***********************************************************************
1024 * Public entrypoints, mostly dispatch to the above:
1028 /* Interpolate between two vertices to produce a third:
1030 void _tnl_interp( GLcontext
*ctx
,
1032 GLuint edst
, GLuint eout
, GLuint ein
,
1033 GLboolean force_boundary
)
1035 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1036 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
1039 /* Copy colors from one vertex to another:
1041 void _tnl_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
1043 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1044 vtx
->copy_pv( ctx
, edst
, esrc
);
1048 /* Extract a named attribute from a hardware vertex. Will have to
1049 * reverse any viewport transformation, swizzling or other conversions
1050 * which may have been applied:
1052 void _tnl_get_attr( GLcontext
*ctx
, const void *vin
,
1053 GLenum attr
, GLfloat
*dest
)
1055 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1056 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1057 const GLuint attr_count
= vtx
->attr_count
;
1060 for (j
= 0; j
< attr_count
; j
++) {
1061 if (a
[j
].attrib
== attr
) {
1062 a
[j
].extract( &a
[j
], dest
, (GLubyte
*)vin
+ a
[j
].vertoffset
);
1067 /* Else return the value from ctx->Current -- dangerous???
1069 _mesa_memcpy( dest
, ctx
->Current
.Attrib
[attr
], 4*sizeof(GLfloat
));
1073 /* Complementary operation to the above.
1075 void _tnl_set_attr( GLcontext
*ctx
, void *vout
,
1076 GLenum attr
, const GLfloat
*src
)
1078 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1079 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
1080 const GLuint attr_count
= vtx
->attr_count
;
1083 for (j
= 0; j
< attr_count
; j
++) {
1084 if (a
[j
].attrib
== attr
) {
1085 a
[j
].insert
[4-1]( &a
[j
], (GLubyte
*)vout
+ a
[j
].vertoffset
, src
);
1092 void *_tnl_get_vertex( GLcontext
*ctx
, GLuint nr
)
1094 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1096 return vtx
->vertex_buf
+ nr
* vtx
->vertex_size
;
1099 void _tnl_invalidate_vertex_state( GLcontext
*ctx
, GLuint new_state
)
1101 if (new_state
& (_DD_NEW_TRI_LIGHT_TWOSIDE
|_DD_NEW_TRI_UNFILLED
) ) {
1102 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1103 vtx
->new_inputs
= ~0;
1104 vtx
->interp
= choose_interp_func
;
1105 vtx
->copy_pv
= choose_copy_pv_func
;
1110 GLuint
_tnl_install_attrs( GLcontext
*ctx
, const struct tnl_attr_map
*map
,
1111 GLuint nr
, const GLfloat
*vp
,
1112 GLuint unpacked_size
)
1114 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1118 assert(nr
< _TNL_ATTRIB_MAX
);
1119 assert(nr
== 0 || map
[0].attrib
== VERT_ATTRIB_POS
);
1122 vtx
->interp
= choose_interp_func
;
1123 vtx
->copy_pv
= choose_copy_pv_func
;
1124 vtx
->new_inputs
= ~0;
1126 for (j
= 0, i
= 0; i
< nr
; i
++) {
1127 const GLuint format
= map
[i
].format
;
1128 if (format
== EMIT_PAD
) {
1130 fprintf(stderr, "%d: pad %d, offset %d\n", i,
1131 map[i].offset, offset);
1133 offset
+= map
[i
].offset
;
1137 vtx
->attr
[j
].attrib
= map
[i
].attrib
;
1138 vtx
->attr
[j
].format
= format
;
1139 vtx
->attr
[j
].vp
= vp
;
1140 vtx
->attr
[j
].insert
= format_info
[format
].insert
;
1141 vtx
->attr
[j
].extract
= format_info
[format
].extract
;
1142 vtx
->attr
[j
].vertattrsize
= format_info
[format
].attrsize
;
1145 vtx
->attr
[j
].vertoffset
= map
[i
].offset
;
1147 vtx
->attr
[j
].vertoffset
= offset
;
1150 fprintf(stderr, "%d: %s, vp %p, offset %d\n", i,
1151 format_info[format].name, (void *)vp,
1152 vtx->attr[j].vertoffset);
1154 offset
+= format_info
[format
].attrsize
;
1159 vtx
->attr_count
= j
;
1162 vtx
->vertex_size
= unpacked_size
;
1164 vtx
->vertex_size
= offset
;
1166 assert(vtx
->vertex_size
<= vtx
->max_vertex_size
);
1168 return vtx
->vertex_size
;
1173 void _tnl_invalidate_vertices( GLcontext
*ctx
, GLuint newinputs
)
1175 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1176 vtx
->new_inputs
|= newinputs
;
1180 void _tnl_build_vertices( GLcontext
*ctx
,
1185 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1186 const GLuint stride
= vtx
->vertex_size
;
1187 GLubyte
*vDest
= ((GLubyte
*)vtx
->vertex_buf
+ (start
*stride
));
1189 newinputs
|= vtx
->new_inputs
;
1190 vtx
->new_inputs
= 0;
1193 do_emit( ctx
, start
, end
, vDest
);
1197 void *_tnl_emit_vertices_to_buffer( GLcontext
*ctx
,
1202 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1203 do_emit( ctx
, start
, end
, dest
);
1204 return (void *)((GLubyte
*)dest
+ vtx
->vertex_size
* (end
- start
));
1208 void _tnl_init_vertices( GLcontext
*ctx
,
1210 GLuint max_vertex_size
)
1212 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1214 _tnl_install_attrs( ctx
, 0, 0, 0, 0 );
1216 vtx
->need_extras
= GL_TRUE
;
1217 if (max_vertex_size
> vtx
->max_vertex_size
) {
1218 _tnl_free_vertices( ctx
);
1219 vtx
->max_vertex_size
= max_vertex_size
;
1220 vtx
->vertex_buf
= (GLubyte
*)ALIGN_CALLOC(vb_size
* max_vertex_size
, 32 );
1223 _tnl_init_c_codegen( &vtx
->codegen
);
1227 void _tnl_free_vertices( GLcontext
*ctx
)
1229 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1230 if (vtx
->vertex_buf
) {
1231 ALIGN_FREE(vtx
->vertex_buf
);
1232 vtx
->vertex_buf
= 0;