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>
32 #include "pipe/p_compiler.h"
33 #include "pipe/p_util.h"
39 static INLINE
void insert_4f_4( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
41 float *out
= (float *)(v
);
50 static INLINE
void insert_4f_3( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
52 float *out
= (float *)(v
);
61 static INLINE
void insert_4f_2( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
63 float *out
= (float *)(v
);
72 static INLINE
void insert_4f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
74 float *out
= (float *)(v
);
83 static INLINE
void insert_3f_xyw_4( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
85 float *out
= (float *)(v
);
93 static INLINE
void insert_3f_xyw_err( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
95 (void) a
; (void) v
; (void) in
;
99 static INLINE
void insert_3f_3( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
101 float *out
= (float *)(v
);
109 static INLINE
void insert_3f_2( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
111 float *out
= (float *)(v
);
119 static INLINE
void insert_3f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
121 float *out
= (float *)(v
);
130 static INLINE
void insert_2f_2( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
132 float *out
= (float *)(v
);
139 static INLINE
void insert_2f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
141 float *out
= (float *)(v
);
148 static INLINE
void insert_1f_1( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
150 float *out
= (float *)(v
);
156 static INLINE
void insert_null( const struct draw_vf_attr
*a
, uint8_t *v
, const float *in
)
158 (void) a
; (void) v
; (void) in
;
161 static INLINE
void insert_4ub_4f_rgba_4( const struct draw_vf_attr
*a
, uint8_t *v
,
165 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
166 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
167 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
168 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
171 static INLINE
void insert_4ub_4f_rgba_3( const struct draw_vf_attr
*a
, uint8_t *v
,
175 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
176 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
177 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[2]);
181 static INLINE
void insert_4ub_4f_rgba_2( const struct draw_vf_attr
*a
, uint8_t *v
,
185 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
186 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
191 static INLINE
void insert_4ub_4f_rgba_1( const struct draw_vf_attr
*a
, uint8_t *v
,
195 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
201 static INLINE
void insert_4ub_4f_bgra_4( const struct draw_vf_attr
*a
, uint8_t *v
,
205 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
206 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
207 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
208 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[3]);
211 static INLINE
void insert_4ub_4f_bgra_3( const struct draw_vf_attr
*a
, uint8_t *v
,
215 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
216 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
217 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
221 static INLINE
void insert_4ub_4f_bgra_2( const struct draw_vf_attr
*a
, uint8_t *v
,
225 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
226 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
231 static INLINE
void insert_4ub_4f_bgra_1( const struct draw_vf_attr
*a
, uint8_t *v
,
235 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
241 static INLINE
void insert_4ub_4f_argb_4( const struct draw_vf_attr
*a
, uint8_t *v
,
245 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
246 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
247 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
248 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
251 static INLINE
void insert_4ub_4f_argb_3( const struct draw_vf_attr
*a
, uint8_t *v
,
255 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
256 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
257 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[2]);
261 static INLINE
void insert_4ub_4f_argb_2( const struct draw_vf_attr
*a
, uint8_t *v
,
265 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
266 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
271 static INLINE
void insert_4ub_4f_argb_1( const struct draw_vf_attr
*a
, uint8_t *v
,
275 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[0]);
281 static INLINE
void insert_4ub_4f_abgr_4( const struct draw_vf_attr
*a
, uint8_t *v
,
285 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
286 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
287 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
288 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[3]);
291 static INLINE
void insert_4ub_4f_abgr_3( const struct draw_vf_attr
*a
, uint8_t *v
,
295 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
296 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
297 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[2]);
301 static INLINE
void insert_4ub_4f_abgr_2( const struct draw_vf_attr
*a
, uint8_t *v
,
305 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
306 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[1]);
311 static INLINE
void insert_4ub_4f_abgr_1( const struct draw_vf_attr
*a
, uint8_t *v
,
315 UNCLAMPED_FLOAT_TO_UBYTE(v
[3], in
[0]);
321 static INLINE
void insert_3ub_3f_rgb_3( const struct draw_vf_attr
*a
, uint8_t *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]);
330 static INLINE
void insert_3ub_3f_rgb_2( const struct draw_vf_attr
*a
, uint8_t *v
,
334 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
339 static INLINE
void insert_3ub_3f_rgb_1( const struct draw_vf_attr
*a
, uint8_t *v
,
343 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
348 static INLINE
void insert_3ub_3f_bgr_3( const struct draw_vf_attr
*a
, uint8_t *v
,
352 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
353 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
354 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[2]);
357 static INLINE
void insert_3ub_3f_bgr_2( const struct draw_vf_attr
*a
, uint8_t *v
,
361 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
362 UNCLAMPED_FLOAT_TO_UBYTE(v
[1], in
[1]);
366 static INLINE
void insert_3ub_3f_bgr_1( const struct draw_vf_attr
*a
, uint8_t *v
,
370 UNCLAMPED_FLOAT_TO_UBYTE(v
[2], in
[0]);
376 static INLINE
void insert_1ub_1f_1( const struct draw_vf_attr
*a
, uint8_t *v
,
380 UNCLAMPED_FLOAT_TO_UBYTE(v
[0], in
[0]);
384 const struct draw_vf_format_info draw_vf_format_info
[DRAW_EMIT_MAX
] =
387 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
388 sizeof(float), FALSE
},
391 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
392 2 * sizeof(float), FALSE
},
395 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
396 3 * sizeof(float), FALSE
},
399 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
400 4 * sizeof(float), FALSE
},
403 { insert_3f_xyw_err
, insert_3f_xyw_err
, insert_3f_xyw_err
,
405 3 * sizeof(float), FALSE
},
408 { insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
, insert_1ub_1f_1
},
409 sizeof(uint8_t), FALSE
},
412 { insert_3ub_3f_rgb_1
, insert_3ub_3f_rgb_2
, insert_3ub_3f_rgb_3
,
413 insert_3ub_3f_rgb_3
},
414 3 * sizeof(uint8_t), FALSE
},
417 { insert_3ub_3f_bgr_1
, insert_3ub_3f_bgr_2
, insert_3ub_3f_bgr_3
,
418 insert_3ub_3f_bgr_3
},
419 3 * sizeof(uint8_t), FALSE
},
422 { insert_4ub_4f_rgba_1
, insert_4ub_4f_rgba_2
, insert_4ub_4f_rgba_3
,
423 insert_4ub_4f_rgba_4
},
424 4 * sizeof(uint8_t), FALSE
},
427 { insert_4ub_4f_bgra_1
, insert_4ub_4f_bgra_2
, insert_4ub_4f_bgra_3
,
428 insert_4ub_4f_bgra_4
},
429 4 * sizeof(uint8_t), FALSE
},
432 { insert_4ub_4f_argb_1
, insert_4ub_4f_argb_2
, insert_4ub_4f_argb_3
,
433 insert_4ub_4f_argb_4
},
434 4 * sizeof(uint8_t), FALSE
},
437 { insert_4ub_4f_abgr_1
, insert_4ub_4f_abgr_2
, insert_4ub_4f_abgr_3
,
438 insert_4ub_4f_abgr_4
},
439 4 * sizeof(uint8_t), FALSE
},
442 { insert_1f_1
, insert_1f_1
, insert_1f_1
, insert_1f_1
},
443 sizeof(float), TRUE
},
446 { insert_2f_1
, insert_2f_2
, insert_2f_2
, insert_2f_2
},
447 2 * sizeof(float), TRUE
},
450 { insert_3f_1
, insert_3f_2
, insert_3f_3
, insert_3f_3
},
451 3 * sizeof(float), TRUE
},
454 { insert_4f_1
, insert_4f_2
, insert_4f_3
, insert_4f_4
},
455 4 * sizeof(float), TRUE
},
458 { NULL
, NULL
, NULL
, NULL
},
466 /***********************************************************************
467 * Hardwired fastpaths for emitting whole vertices or groups of
470 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
471 static void NAME( struct draw_vertex_fetch *vf, \
475 struct draw_vf_attr *a = vf->attr; \
478 for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \
480 F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \
481 a[0].inputptr += a[0].inputstride; \
485 F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \
486 a[1].inputptr += a[1].inputstride; \
490 F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \
491 a[2].inputptr += a[2].inputstride; \
495 F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \
496 a[3].inputptr += a[3].inputstride; \
500 F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \
501 a[4].inputptr += a[4].inputstride; \
507 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
508 insert_null, insert_null, NAME)
510 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
513 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
517 EMIT2(insert_3f_3
, insert_4ub_4f_rgba_4
, emit_xyz3_rgba4
)
519 EMIT3(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, emit_xyzw4_rgba4_st2
)
521 EMIT4(insert_4f_4
, insert_4ub_4f_rgba_4
, insert_2f_2
, insert_2f_2
, emit_xyzw4_rgba4_st2_st2
)
524 /* Use the codegen paths to select one of a number of hardwired
527 void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch
*vf
)
529 draw_vf_emit_func func
= NULL
;
531 /* Does it fit a hardwired fastpath? Help! this is growing out of
534 switch (vf
->attr_count
) {
536 if (vf
->attr
[0].do_insert
== insert_3f_3
&&
537 vf
->attr
[1].do_insert
== insert_4ub_4f_rgba_4
) {
538 func
= emit_xyz3_rgba4
;
542 if (vf
->attr
[2].do_insert
== insert_2f_2
) {
543 if (vf
->attr
[1].do_insert
== insert_4ub_4f_rgba_4
) {
544 if (vf
->attr
[0].do_insert
== insert_4f_4
)
545 func
= emit_xyzw4_rgba4_st2
;
550 if (vf
->attr
[2].do_insert
== insert_2f_2
&&
551 vf
->attr
[3].do_insert
== insert_2f_2
) {
552 if (vf
->attr
[1].do_insert
== insert_4ub_4f_rgba_4
) {
553 if (vf
->attr
[0].do_insert
== insert_4f_4
)
554 func
= emit_xyzw4_rgba4_st2_st2
;
563 /***********************************************************************
564 * Generic (non-codegen) functions for whole vertices or groups of
568 void draw_vf_generic_emit( struct draw_vertex_fetch
*vf
,
572 struct draw_vf_attr
*a
= vf
->attr
;
573 const unsigned attr_count
= vf
->attr_count
;
574 const unsigned stride
= vf
->vertex_stride
;
577 for (i
= 0 ; i
< count
; i
++, v
+= stride
) {
578 for (j
= 0; j
< attr_count
; j
++) {
579 float *in
= (float *)a
[j
].inputptr
;
580 a
[j
].inputptr
+= a
[j
].inputstride
;
581 a
[j
].do_insert( &a
[j
], v
+ a
[j
].vertoffset
, in
);