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_*.
46 #define GET_VERTEX_STATE(ctx) &(TNL_CONTEXT(ctx)->clipspace)
48 static void insert_4f_viewport_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
51 GLfloat
*out
= (GLfloat
*)v
;
52 const GLfloat
* const vp
= a
->vp
;
54 out
[0] = vp
[0] * in
[0] + vp
[12];
55 out
[1] = vp
[5] * in
[1] + vp
[13];
56 out
[2] = vp
[10] * in
[2] + vp
[14];
60 static void insert_4f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
63 GLfloat
*out
= (GLfloat
*)v
;
64 const GLfloat
* const vp
= a
->vp
;
66 out
[0] = vp
[0] * in
[0] + vp
[12];
67 out
[1] = vp
[5] * in
[1] + vp
[13];
68 out
[2] = vp
[10] * in
[2] + vp
[14];
72 static void insert_4f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
75 GLfloat
*out
= (GLfloat
*)v
;
76 const GLfloat
* const vp
= a
->vp
;
78 out
[0] = vp
[0] * in
[0] + vp
[12];
79 out
[1] = vp
[5] * in
[1] + vp
[13];
84 static void insert_4f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
87 GLfloat
*out
= (GLfloat
*)v
;
88 const GLfloat
* const vp
= a
->vp
;
90 out
[0] = vp
[0] * in
[0] + vp
[12];
96 static void insert_3f_viewport_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
99 GLfloat
*out
= (GLfloat
*)v
;
100 const GLfloat
* const vp
= a
->vp
;
102 out
[0] = vp
[0] * in
[0] + vp
[12];
103 out
[1] = vp
[5] * in
[1] + vp
[13];
104 out
[2] = vp
[10] * in
[2] + vp
[14];
107 static void insert_3f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
110 GLfloat
*out
= (GLfloat
*)v
;
111 const GLfloat
* const vp
= a
->vp
;
113 out
[0] = vp
[0] * in
[0] + vp
[12];
114 out
[1] = vp
[5] * in
[1] + vp
[13];
115 out
[2] = vp
[10] * in
[2] + vp
[14];
118 static void insert_3f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
121 GLfloat
*out
= (GLfloat
*)v
;
122 const GLfloat
* const vp
= a
->vp
;
124 out
[0] = vp
[0] * in
[0] + vp
[12];
129 static void insert_2f_viewport_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
132 GLfloat
*out
= (GLfloat
*)v
;
133 const GLfloat
* const vp
= a
->vp
;
135 out
[0] = vp
[0] * in
[0] + vp
[12];
136 out
[1] = vp
[5] * in
[1] + vp
[13];
139 static void insert_2f_viewport_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
142 GLfloat
*out
= (GLfloat
*)v
;
143 const GLfloat
* const vp
= a
->vp
;
145 out
[0] = vp
[0] * in
[0] + vp
[12];
150 static void insert_4f_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
152 GLfloat
*out
= (GLfloat
*)(v
);
160 static void insert_4f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
162 GLfloat
*out
= (GLfloat
*)(v
);
170 static void insert_4f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
172 GLfloat
*out
= (GLfloat
*)(v
);
180 static void insert_4f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
182 GLfloat
*out
= (GLfloat
*)(v
);
190 static void insert_3f_xyw_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
192 GLfloat
*out
= (GLfloat
*)(v
);
199 static void insert_3f_xyw_err( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
204 static void insert_3f_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
206 GLfloat
*out
= (GLfloat
*)(v
);
213 static void insert_3f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
215 GLfloat
*out
= (GLfloat
*)(v
);
222 static void insert_3f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
224 GLfloat
*out
= (GLfloat
*)(v
);
232 static void insert_2f_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
234 GLfloat
*out
= (GLfloat
*)(v
);
240 static void insert_2f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
242 GLfloat
*out
= (GLfloat
*)(v
);
248 static void insert_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
, const GLfloat
*in
)
250 GLfloat
*out
= (GLfloat
*)(v
);
255 static void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
258 GLchan
*c
= (GLchan
*)v
;
259 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
260 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
261 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
262 UNCLAMPED_FLOAT_TO_CHAN(c
[3], in
[3]);
265 static void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
268 GLchan
*c
= (GLchan
*)v
;
269 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
270 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
271 UNCLAMPED_FLOAT_TO_CHAN(c
[2], in
[2]);
275 static void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
278 GLchan
*c
= (GLchan
*)v
;
279 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
280 UNCLAMPED_FLOAT_TO_CHAN(c
[1], in
[1]);
285 static void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
288 GLchan
*c
= (GLchan
*)v
;
289 UNCLAMPED_FLOAT_TO_CHAN(c
[0], in
[0]);
295 static void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
298 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
299 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
300 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
301 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
304 static void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
307 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
308 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
309 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
313 static void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
316 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
317 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
322 static void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
325 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
331 static void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
334 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
336 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
337 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
340 static void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
343 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
344 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
345 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
349 static void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
352 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
353 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
358 static void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
361 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
367 static void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
370 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
371 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
372 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
375 static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
378 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
379 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
383 static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
386 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
391 static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
394 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
395 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
396 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
399 static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
402 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
403 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
407 static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
410 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
416 static void insert_1ub_1f_1( const struct tnl_clipspace_attr
*a
, GLubyte
*v
,
419 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
423 /***********************************************************************
424 * Functions to perform the reverse operations to the above, for
425 * swrast translation and clip-interpolation.
427 * Currently always extracts a full 4 floats.
430 static void extract_4f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
433 const GLfloat
*in
= (const GLfloat
*)v
;
434 const GLfloat
* const vp
= a
->vp
;
436 /* Although included for completeness, the position coordinate is
437 * usually handled differently during clipping.
439 out
[0] = (in
[0] - vp
[12]) / vp
[0];
440 out
[1] = (in
[1] - vp
[13]) / vp
[5];
441 out
[2] = (in
[2] - vp
[14]) / vp
[10];
445 static void extract_3f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
448 const GLfloat
*in
= (const GLfloat
*)v
;
449 const GLfloat
* const vp
= a
->vp
;
451 out
[0] = (in
[0] - vp
[12]) / vp
[0];
452 out
[1] = (in
[1] - vp
[13]) / vp
[5];
453 out
[2] = (in
[2] - vp
[14]) / vp
[10];
458 static void extract_2f_viewport( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
461 const GLfloat
*in
= (const GLfloat
*)v
;
462 const GLfloat
* const vp
= a
->vp
;
464 out
[0] = (in
[0] - vp
[12]) / vp
[0];
465 out
[1] = (in
[1] - vp
[13]) / vp
[5];
471 static void extract_4f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
473 const GLfloat
*in
= (const GLfloat
*)v
;
481 static void extract_3f_xyw( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
483 const GLfloat
*in
= (const GLfloat
*)v
;
492 static void extract_3f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
494 const GLfloat
*in
= (const GLfloat
*)v
;
503 static void extract_2f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
505 const GLfloat
*in
= (const GLfloat
*)v
;
513 static void extract_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
515 const GLfloat
*in
= (const GLfloat
*)v
;
523 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
526 GLchan
*c
= (GLchan
*)v
;
528 out
[0] = CHAN_TO_FLOAT(c
[0]);
529 out
[1] = CHAN_TO_FLOAT(c
[1]);
530 out
[2] = CHAN_TO_FLOAT(c
[2]);
531 out
[3] = CHAN_TO_FLOAT(c
[3]);
534 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
537 out
[0] = UBYTE_TO_FLOAT(v
[0]);
538 out
[1] = UBYTE_TO_FLOAT(v
[1]);
539 out
[2] = UBYTE_TO_FLOAT(v
[2]);
540 out
[3] = UBYTE_TO_FLOAT(v
[3]);
543 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
546 out
[2] = UBYTE_TO_FLOAT(v
[0]);
547 out
[1] = UBYTE_TO_FLOAT(v
[1]);
548 out
[0] = UBYTE_TO_FLOAT(v
[2]);
549 out
[3] = UBYTE_TO_FLOAT(v
[3]);
552 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
555 out
[0] = UBYTE_TO_FLOAT(v
[0]);
556 out
[1] = UBYTE_TO_FLOAT(v
[1]);
557 out
[2] = UBYTE_TO_FLOAT(v
[2]);
561 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr
*a
, GLfloat
*out
,
564 out
[2] = UBYTE_TO_FLOAT(v
[0]);
565 out
[1] = UBYTE_TO_FLOAT(v
[1]);
566 out
[0] = UBYTE_TO_FLOAT(v
[2]);
570 static void extract_1ub_1f( const struct tnl_clipspace_attr
*a
, GLfloat
*out
, const GLubyte
*v
)
572 out
[0] = UBYTE_TO_FLOAT(v
[0]);
581 extract_func extract
;
582 insert_func insert
[4];
584 } format_info
[EMIT_MAX
] = {
588 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
593 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
594 2 * sizeof(GLfloat
) },
598 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
599 3 * sizeof(GLfloat
) },
603 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
604 4 * sizeof(GLfloat
) },
608 { insert_2f_viewport_1
, insert_2f_viewport_2
, insert_2f_viewport_2
,
609 insert_2f_viewport_2
},
610 2 * sizeof(GLfloat
) },
614 { insert_3f_viewport_1
, insert_3f_viewport_2
, insert_3f_viewport_3
,
615 insert_3f_viewport_3
},
616 3 * sizeof(GLfloat
) },
620 { insert_4f_viewport_1
, insert_4f_viewport_2
, insert_4f_viewport_3
,
621 insert_4f_viewport_4
},
622 4 * sizeof(GLfloat
) },
626 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
628 3 * sizeof(GLfloat
) },
632 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
637 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
638 insert_3ub_3f_rgb_3
},
639 3 * sizeof(GLubyte
) },
643 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
644 insert_3ub_3f_bgr_3
},
645 3 * sizeof(GLubyte
) },
649 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
650 insert_4ub_4f_rgba_4
},
651 4 * sizeof(GLubyte
) },
655 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
656 insert_4ub_4f_bgra_4
},
657 4 * sizeof(GLubyte
) },
660 extract_4chan_4f_rgba
,
661 { insert_4chan_4f_rgba_1
, insert_4chan_4f_rgba_2
, insert_4chan_4f_rgba_3
,
662 insert_4chan_4f_rgba_4
},
663 4 * sizeof(GLchan
) },
673 /***********************************************************************
674 * Generic (non-codegen) functions for whole vertices or groups of
678 static void generic_emit( GLcontext
*ctx
,
679 GLuint start
, GLuint end
,
682 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
683 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
684 struct tnl_clipspace_attr
*a
= vtx
->attr
;
685 GLubyte
*v
= (GLubyte
*)dest
;
687 GLuint count
= vtx
->attr_count
;
690 for (j
= 0; j
< count
; j
++) {
691 GLvector4f
*vptr
= VB
->AttribPtr
[a
[j
].attrib
];
692 a
[j
].inputstride
= vptr
->stride
;
693 a
[j
].inputptr
= ((GLubyte
*)vptr
->data
) + start
* vptr
->stride
;
694 a
[j
].emit
= a
[j
].insert
[vptr
->size
- 1];
698 stride
= vtx
->vertex_size
;
700 for (i
= 0 ; i
< end
; i
++, v
+= stride
) {
701 for (j
= 0; j
< count
; j
++) {
702 GLfloat
*in
= (GLfloat
*)a
[j
].inputptr
;
703 a
[j
].inputptr
+= a
[j
].inputstride
;
704 a
[j
].emit( &a
[j
], v
+ a
[j
].vertoffset
, in
);
710 static void generic_interp( GLcontext
*ctx
,
712 GLuint edst
, GLuint eout
, GLuint ein
,
713 GLboolean force_boundary
)
715 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
716 struct vertex_buffer
*VB
= &tnl
->vb
;
717 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
718 GLubyte
*vin
= vtx
->vertex_buf
+ ein
* vtx
->vertex_size
;
719 GLubyte
*vout
= vtx
->vertex_buf
+ eout
* vtx
->vertex_size
;
720 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
721 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
722 int attr_count
= vtx
->attr_count
;
725 if (tnl
->NeedNdcCoords
) {
726 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
727 if (dstclip
[3] != 0.0) {
728 const GLfloat w
= 1.0f
/ dstclip
[3];
731 pos
[0] = dstclip
[0] * w
;
732 pos
[1] = dstclip
[1] * w
;
733 pos
[2] = dstclip
[2] * w
;
736 a
[0].insert
[4-1]( &a
[0], vdst
, pos
);
740 a
[0].insert
[4-1]( &a
[0], vdst
, VB
->ClipPtr
->data
[edst
] );
744 for (j
= 1; j
< attr_count
; j
++) {
745 GLfloat fin
[4], fout
[4], fdst
[4];
747 a
[j
].extract( &a
[j
], fin
, vin
+ a
[j
].vertoffset
);
748 a
[j
].extract( &a
[j
], fout
, vout
+ a
[j
].vertoffset
);
750 INTERP_F( t
, fdst
[3], fout
[3], fin
[3] );
751 INTERP_F( t
, fdst
[2], fout
[2], fin
[2] );
752 INTERP_F( t
, fdst
[1], fout
[1], fin
[1] );
753 INTERP_F( t
, fdst
[0], fout
[0], fin
[0] );
755 a
[j
].insert
[4-1]( &a
[j
], vdst
+ a
[j
].vertoffset
, fdst
);
760 /* Extract color attributes from one vertex and insert them into
761 * another. (Shortcircuit extract/insert with memcpy).
763 static void generic_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
765 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
766 GLubyte
*vsrc
= vtx
->vertex_buf
+ esrc
* vtx
->vertex_size
;
767 GLubyte
*vdst
= vtx
->vertex_buf
+ edst
* vtx
->vertex_size
;
768 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
769 int attr_count
= vtx
->attr_count
;
772 for (j
= 0; j
< attr_count
; j
++) {
773 if (a
[j
].attrib
== VERT_ATTRIB_COLOR0
||
774 a
[j
].attrib
== VERT_ATTRIB_COLOR1
) {
776 _mesa_memcpy( vdst
+ a
[j
].vertoffset
,
777 vsrc
+ a
[j
].vertoffset
,
784 /* Helper functions for hardware which doesn't put back colors and/or
785 * edgeflags into vertices.
787 static void generic_interp_extras( GLcontext
*ctx
,
789 GLuint dst
, GLuint out
, GLuint in
,
790 GLboolean force_boundary
)
792 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
794 if (VB
->ColorPtr
[1]) {
795 assert(VB
->ColorPtr
[1]->stride
== 4 * sizeof(GLfloat
));
798 VB
->ColorPtr
[1]->data
[dst
],
799 VB
->ColorPtr
[1]->data
[out
],
800 VB
->ColorPtr
[1]->data
[in
] );
802 if (VB
->SecondaryColorPtr
[1]) {
804 VB
->SecondaryColorPtr
[1]->data
[dst
],
805 VB
->SecondaryColorPtr
[1]->data
[out
],
806 VB
->SecondaryColorPtr
[1]->data
[in
] );
809 else if (VB
->IndexPtr
[1]) {
810 VB
->IndexPtr
[1]->data
[dst
][0] = LINTERP( t
,
811 VB
->IndexPtr
[1]->data
[out
][0],
812 VB
->IndexPtr
[1]->data
[in
][0] );
816 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
819 generic_interp(ctx
, t
, dst
, out
, in
, force_boundary
);
822 static void generic_copy_pv_extras( GLcontext
*ctx
,
823 GLuint dst
, GLuint src
)
825 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
827 if (VB
->ColorPtr
[1]) {
828 COPY_4FV( VB
->ColorPtr
[1]->data
[dst
],
829 VB
->ColorPtr
[1]->data
[src
] );
831 if (VB
->SecondaryColorPtr
[1]) {
832 COPY_4FV( VB
->SecondaryColorPtr
[1]->data
[dst
],
833 VB
->SecondaryColorPtr
[1]->data
[src
] );
836 else if (VB
->IndexPtr
[1]) {
837 VB
->IndexPtr
[1]->data
[dst
][0] = VB
->IndexPtr
[1]->data
[src
][0];
840 generic_copy_pv(ctx
, dst
, src
);
848 /***********************************************************************
849 * Build codegen functions or return generic ones:
853 static void choose_emit_func( GLcontext
*ctx
,
854 GLuint start
, GLuint end
,
857 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
858 vtx
->emit
= generic_emit
;
859 vtx
->emit( ctx
, start
, end
, dest
);
863 static void choose_interp_func( GLcontext
*ctx
,
865 GLuint edst
, GLuint eout
, GLuint ein
,
866 GLboolean force_boundary
)
868 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
870 if (vtx
->need_extras
&&
871 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
872 vtx
->interp
= generic_interp_extras
;
874 vtx
->interp
= generic_interp
;
877 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
881 static void choose_copy_pv_func( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
883 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
885 if (vtx
->need_extras
&&
886 (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
887 vtx
->copy_pv
= generic_copy_pv_extras
;
889 vtx
->copy_pv
= generic_copy_pv
;
892 vtx
->copy_pv( ctx
, edst
, esrc
);
896 /***********************************************************************
897 * Public entrypoints, mostly dispatch to the above:
901 /* Interpolate between two vertices to produce a third:
903 void _tnl_interp( GLcontext
*ctx
,
905 GLuint edst
, GLuint eout
, GLuint ein
,
906 GLboolean force_boundary
)
908 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
909 vtx
->interp( ctx
, t
, edst
, eout
, ein
, force_boundary
);
912 /* Copy colors from one vertex to another:
914 void _tnl_copy_pv( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
916 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
917 vtx
->copy_pv( ctx
, edst
, esrc
);
921 /* Extract a named attribute from a hardware vertex. Will have to
922 * reverse any viewport transformation, swizzling or other conversions
923 * which may have been applied:
925 void _tnl_get_attr( GLcontext
*ctx
, const void *vin
,
926 GLenum attr
, GLfloat
*dest
)
928 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
929 const struct tnl_clipspace_attr
*a
= vtx
->attr
;
930 int attr_count
= vtx
->attr_count
;
933 for (j
= 0; j
< attr_count
; j
++) {
934 if (a
[j
].attrib
== (int)attr
) {
935 a
[j
].extract( &a
[j
], dest
, (GLubyte
*)vin
+ a
[j
].vertoffset
);
940 /* Else return the value from ctx->Current
942 _mesa_memcpy( dest
, ctx
->Current
.Attrib
[attr
], 4*sizeof(GLfloat
));
945 void *_tnl_get_vertex( GLcontext
*ctx
, GLuint nr
)
947 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
949 return vtx
->vertex_buf
+ nr
* vtx
->vertex_size
;
952 void _tnl_invalidate_vertex_state( GLcontext
*ctx
, GLuint new_state
)
954 if (new_state
& (_DD_NEW_TRI_LIGHT_TWOSIDE
|_DD_NEW_TRI_UNFILLED
) ) {
955 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
956 vtx
->new_inputs
= ~0;
957 vtx
->interp
= choose_interp_func
;
958 vtx
->copy_pv
= choose_copy_pv_func
;
963 GLuint
_tnl_install_attrs( GLcontext
*ctx
, const struct tnl_attr_map
*map
,
964 GLuint nr
, const GLfloat
*vp
,
965 GLuint unpacked_size
)
967 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
971 assert(nr
< _TNL_ATTRIB_MAX
);
972 assert(nr
== 0 || map
[0].attrib
== VERT_ATTRIB_POS
);
974 vtx
->emit
= choose_emit_func
;
975 vtx
->interp
= choose_interp_func
;
976 vtx
->copy_pv
= choose_copy_pv_func
;
977 vtx
->new_inputs
= ~0;
979 for (j
= 0, i
= 0; i
< nr
; i
++) {
980 GLuint format
= map
[i
].format
;
981 if (format
== EMIT_PAD
) {
982 offset
+= map
[i
].offset
;
984 /* fprintf(stderr, "%d: pad %d, offset now %d\n", i, */
985 /* map[i].offset, offset); */
989 vtx
->attr
[j
].attrib
= map
[i
].attrib
;
990 vtx
->attr
[j
].vp
= vp
;
991 vtx
->attr
[j
].insert
= format_info
[format
].insert
;
992 vtx
->attr
[j
].extract
= format_info
[format
].extract
;
993 vtx
->attr
[j
].vertattrsize
= format_info
[format
].attrsize
;
996 vtx
->attr
[j
].vertoffset
= map
[i
].offset
;
998 vtx
->attr
[j
].vertoffset
= offset
;
1000 /* fprintf(stderr, "%d: %s offset %d\n", i, */
1001 /* format_info[format].name, vtx->attr[j].vertoffset); */
1003 offset
+= format_info
[format
].attrsize
;
1008 vtx
->attr_count
= j
;
1011 vtx
->vertex_size
= unpacked_size
;
1013 vtx
->vertex_size
= offset
;
1015 assert(vtx
->vertex_size
<= vtx
->max_vertex_size
);
1017 return vtx
->vertex_size
;
1022 void _tnl_invalidate_vertices( GLcontext
*ctx
, GLuint newinputs
)
1024 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1025 vtx
->new_inputs
|= newinputs
;
1030 void _tnl_build_vertices( GLcontext
*ctx
,
1035 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1036 GLuint stride
= vtx
->vertex_size
;
1037 GLubyte
*v
= ((GLubyte
*)vtx
->vertex_buf
+ (start
*stride
));
1039 newinputs
|= vtx
->new_inputs
;
1040 vtx
->new_inputs
= 0;
1043 vtx
->emit( ctx
, start
, end
, v
);
1047 void *_tnl_emit_vertices_to_buffer( GLcontext
*ctx
,
1052 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1053 vtx
->emit( ctx
, start
, end
, dest
);
1054 return (void *)((GLubyte
*)dest
+ vtx
->vertex_size
* (end
- start
));
1058 void _tnl_init_vertices( GLcontext
*ctx
,
1060 GLuint max_vertex_size
)
1062 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1064 _tnl_install_attrs( ctx
, 0, 0, 0, 0 );
1066 vtx
->need_extras
= GL_TRUE
;
1067 if (max_vertex_size
> vtx
->max_vertex_size
) {
1068 _tnl_free_vertices( ctx
);
1069 vtx
->max_vertex_size
= max_vertex_size
;
1070 vtx
->vertex_buf
= (GLubyte
*)ALIGN_CALLOC(vb_size
* max_vertex_size
, 32 );
1075 void _tnl_free_vertices( GLcontext
*ctx
)
1077 struct tnl_clipspace
*vtx
= GET_VERTEX_STATE(ctx
);
1078 if (vtx
->vertex_buf
) {
1079 ALIGN_FREE(vtx
->vertex_buf
);
1080 vtx
->vertex_buf
= 0;