3 * Copyright 2003 Tungsten Graphics, inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Keith Whitwell <keithw@tungstengraphics.com>
30 #include "pipe/p_compiler.h"
31 #include "pipe/p_debug.h"
32 #include "pipe/p_util.h"
38 static INLINE
void insert_4f_4( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
40 float *out
= (float *)(v
);
49 static INLINE
void insert_4f_3( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
51 float *out
= (float *)(v
);
60 static INLINE
void insert_4f_2( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
62 float *out
= (float *)(v
);
71 static INLINE
void insert_4f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
73 float *out
= (float *)(v
);
82 static INLINE
void insert_3f_xyw_4( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
84 float *out
= (float *)(v
);
92 static INLINE
void insert_3f_xyw_err( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
94 (void) a
; (void) v
; (void) in
;
98 static INLINE
void insert_3f_3( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
100 float *out
= (float *)(v
);
108 static INLINE
void insert_3f_2( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
110 float *out
= (float *)(v
);
118 static INLINE
void insert_3f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
120 float *out
= (float *)(v
);
129 static INLINE
void insert_2f_2( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
131 float *out
= (float *)(v
);
138 static INLINE
void insert_2f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
140 float *out
= (float *)(v
);
147 static INLINE
void insert_1f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
149 float *out
= (float *)(v
);
155 static INLINE
void insert_null( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
157 (void) a
; (void) v
; (void) in
;
160 static INLINE
void insert_4ub_4f_rgba_4( const struct draw_vf_attr
*a
, uint8_t *v
,
164 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
165 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
166 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
167 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
170 static INLINE
void insert_4ub_4f_rgba_3( const struct draw_vf_attr
*a
, uint8_t *v
,
174 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
175 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
176 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
180 static INLINE
void insert_4ub_4f_rgba_2( const struct draw_vf_attr
*a
, uint8_t *v
,
184 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
185 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
190 static INLINE
void insert_4ub_4f_rgba_1( const struct draw_vf_attr
*a
, uint8_t *v
,
194 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
200 static INLINE
void insert_4ub_4f_bgra_4( const struct draw_vf_attr
*a
, uint8_t *v
,
204 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
205 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
206 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
207 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
210 static INLINE
void insert_4ub_4f_bgra_3( const struct draw_vf_attr
*a
, uint8_t *v
,
214 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
215 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
216 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
220 static INLINE
void insert_4ub_4f_bgra_2( const struct draw_vf_attr
*a
, uint8_t *v
,
224 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
225 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
230 static INLINE
void insert_4ub_4f_bgra_1( const struct draw_vf_attr
*a
, uint8_t *v
,
234 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
240 static INLINE
void insert_4ub_4f_argb_4( const struct draw_vf_attr
*a
, uint8_t *v
,
244 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
245 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
246 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
247 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
250 static INLINE
void insert_4ub_4f_argb_3( const struct draw_vf_attr
*a
, uint8_t *v
,
254 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
255 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
256 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
260 static INLINE
void insert_4ub_4f_argb_2( const struct draw_vf_attr
*a
, uint8_t *v
,
264 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
265 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
270 static INLINE
void insert_4ub_4f_argb_1( const struct draw_vf_attr
*a
, uint8_t *v
,
274 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
280 static INLINE
void insert_4ub_4f_abgr_4( const struct draw_vf_attr
*a
, uint8_t *v
,
284 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
285 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
286 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
287 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
290 static INLINE
void insert_4ub_4f_abgr_3( const struct draw_vf_attr
*a
, uint8_t *v
,
294 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
295 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
296 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
300 static INLINE
void insert_4ub_4f_abgr_2( const struct draw_vf_attr
*a
, uint8_t *v
,
304 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
305 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
310 static INLINE
void insert_4ub_4f_abgr_1( const struct draw_vf_attr
*a
, uint8_t *v
,
314 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
320 static INLINE
void insert_3ub_3f_rgb_3( const struct draw_vf_attr
*a
, uint8_t *v
,
324 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
325 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
326 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
329 static INLINE
void insert_3ub_3f_rgb_2( const struct draw_vf_attr
*a
, uint8_t *v
,
333 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
334 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
338 static INLINE
void insert_3ub_3f_rgb_1( const struct draw_vf_attr
*a
, uint8_t *v
,
342 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
347 static INLINE
void insert_3ub_3f_bgr_3( const struct draw_vf_attr
*a
, uint8_t *v
,
351 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
352 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
353 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
356 static INLINE
void insert_3ub_3f_bgr_2( const struct draw_vf_attr
*a
, uint8_t *v
,
360 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
361 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
365 static INLINE
void insert_3ub_3f_bgr_1( const struct draw_vf_attr
*a
, uint8_t *v
,
369 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
375 static INLINE
void insert_1ub_1f_1( const struct draw_vf_attr
*a
, uint8_t *v
,
379 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
383 const struct draw_vf_format_info draw_vf_format_info
[DRAW_EMIT_MAX
] =
386 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
387 sizeof(float), FALSE
},
390 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
391 2 * sizeof(float), FALSE
},
394 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
395 3 * sizeof(float), FALSE
},
398 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
399 4 * sizeof(float), FALSE
},
402 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
404 3 * sizeof(float), FALSE
},
407 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
408 sizeof(uint8_t), FALSE
},
411 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
412 insert_3ub_3f_rgb_3
},
413 3 * sizeof(uint8_t), FALSE
},
416 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
417 insert_3ub_3f_bgr_3
},
418 3 * sizeof(uint8_t), FALSE
},
421 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
422 insert_4ub_4f_rgba_4
},
423 4 * sizeof(uint8_t), FALSE
},
426 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
427 insert_4ub_4f_bgra_4
},
428 4 * sizeof(uint8_t), FALSE
},
431 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
432 insert_4ub_4f_argb_4
},
433 4 * sizeof(uint8_t), FALSE
},
436 { insert_4ub_4f_abgr_1
, insert_4ub_4f_abgr_2
, insert_4ub_4f_abgr_3
,
437 insert_4ub_4f_abgr_4
},
438 4 * sizeof(uint8_t), FALSE
},
441 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
442 sizeof(float), TRUE
},
445 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
446 2 * sizeof(float), TRUE
},
449 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
450 3 * sizeof(float), TRUE
},
453 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
454 4 * sizeof(float), TRUE
},
457 { NULL
, NULL
, NULL
, NULL
},
465 /***********************************************************************
466 * Hardwired fastpaths for emitting whole vertices or groups of
469 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
470 static void NAME( struct draw_vertex_fetch *vf, \
474 struct draw_vf_attr *a = vf->attr; \
477 for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \
479 F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \
480 a[0].inputptr += a[0].inputstride; \
484 F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \
485 a[1].inputptr += a[1].inputstride; \
489 F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \
490 a[2].inputptr += a[2].inputstride; \
494 F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \
495 a[3].inputptr += a[3].inputstride; \
499 F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \
500 a[4].inputptr += a[4].inputstride; \
506 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
507 insert_null, insert_null, NAME)
509 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
512 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
516 EMIT2(insert_3f_3
, insert_4ub_4f_rgba_4
, emit_xyz3_rgba4
)
518 EMIT3(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_xyzw4_rgba4_st2
)
520 EMIT4(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_xyzw4_rgba4_st2_st2
)
523 /* Use the codegen paths to select one of a number of hardwired
526 void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch
*vf
)
528 draw_vf_emit_func func
= NULL
;
530 /* Does it fit a hardwired fastpath? Help! this is growing out of
533 switch (vf
->attr_count
) {
535 if (vf
->attr
[0].do_insert
== insert_3f_3
&&
536 vf
->attr
[1].do_insert
== insert_4ub_4f_rgba_4
) {
537 func
= emit_xyz3_rgba4
;
541 if (vf
->attr
[2].do_insert
== insert_2f_2
) {
542 if (vf
->attr
[1].do_insert
== insert_4ub_4f_rgba_4
) {
543 if (vf
->attr
[0].do_insert
== insert_4f_4
)
544 func
= emit_xyzw4_rgba4_st2
;
549 if (vf
->attr
[2].do_insert
== insert_2f_2
&&
550 vf
->attr
[3].do_insert
== insert_2f_2
) {
551 if (vf
->attr
[1].do_insert
== insert_4ub_4f_rgba_4
) {
552 if (vf
->attr
[0].do_insert
== insert_4f_4
)
553 func
= emit_xyzw4_rgba4_st2_st2
;
562 /***********************************************************************
563 * Generic (non-codegen) functions for whole vertices or groups of
567 void draw_vf_generic_emit( struct draw_vertex_fetch
*vf
,
571 struct draw_vf_attr
*a
= vf
->attr
;
572 const unsigned attr_count
= vf
->attr_count
;
573 const unsigned stride
= vf
->vertex_stride
;
576 for (i
= 0 ; i
< count
; i
++, v
+= stride
) {
577 for (j
= 0; j
< attr_count
; j
++) {
578 float *in
= (float *)a
[j
].inputptr
;
579 a
[j
].inputptr
+= a
[j
].inputstride
;
580 a
[j
].do_insert( &a
[j
], v
+ a
[j
].vertoffset
, in
);