gallium: Fix build on WinXP.
[mesa.git] / src / mesa / pipe / draw / draw_vf_generic.c
1
2 /*
3 * Copyright 2003 Tungsten Graphics, inc.
4 * All Rights Reserved.
5 *
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:
12 *
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
15 * Software.
16 *
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.
24 *
25 * Authors:
26 * Keith Whitwell <keithw@tungstengraphics.com>
27 */
28
29
30 #include <assert.h>
31
32 #include "pipe/p_compiler.h"
33 #include "pipe/p_util.h"
34
35 #include "draw_vf.h"
36
37
38
39 static INLINE void insert_4f_4( const struct draw_vf_attr *a, uint8_t *v, const float *in )
40 {
41 float *out = (float *)(v);
42 (void) a;
43
44 out[0] = in[0];
45 out[1] = in[1];
46 out[2] = in[2];
47 out[3] = in[3];
48 }
49
50 static INLINE void insert_4f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in )
51 {
52 float *out = (float *)(v);
53 (void) a;
54
55 out[0] = in[0];
56 out[1] = in[1];
57 out[2] = in[2];
58 out[3] = 1;
59 }
60
61 static INLINE void insert_4f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in )
62 {
63 float *out = (float *)(v);
64 (void) a;
65
66 out[0] = in[0];
67 out[1] = in[1];
68 out[2] = 0;
69 out[3] = 1;
70 }
71
72 static INLINE void insert_4f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in )
73 {
74 float *out = (float *)(v);
75 (void) a;
76
77 out[0] = in[0];
78 out[1] = 0;
79 out[2] = 0;
80 out[3] = 1;
81 }
82
83 static INLINE void insert_3f_xyw_4( const struct draw_vf_attr *a, uint8_t *v, const float *in )
84 {
85 float *out = (float *)(v);
86 (void) a;
87
88 out[0] = in[0];
89 out[1] = in[1];
90 out[2] = in[3];
91 }
92
93 static INLINE void insert_3f_xyw_err( const struct draw_vf_attr *a, uint8_t *v, const float *in )
94 {
95 (void) a; (void) v; (void) in;
96 assert(0);
97 }
98
99 static INLINE void insert_3f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in )
100 {
101 float *out = (float *)(v);
102 (void) a;
103
104 out[0] = in[0];
105 out[1] = in[1];
106 out[2] = in[2];
107 }
108
109 static INLINE void insert_3f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in )
110 {
111 float *out = (float *)(v);
112 (void) a;
113
114 out[0] = in[0];
115 out[1] = in[1];
116 out[2] = 0;
117 }
118
119 static INLINE void insert_3f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in )
120 {
121 float *out = (float *)(v);
122 (void) a;
123
124 out[0] = in[0];
125 out[1] = 0;
126 out[2] = 0;
127 }
128
129
130 static INLINE void insert_2f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in )
131 {
132 float *out = (float *)(v);
133 (void) a;
134
135 out[0] = in[0];
136 out[1] = in[1];
137 }
138
139 static INLINE void insert_2f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in )
140 {
141 float *out = (float *)(v);
142 (void) a;
143
144 out[0] = in[0];
145 out[1] = 0;
146 }
147
148 static INLINE void insert_1f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in )
149 {
150 float *out = (float *)(v);
151 (void) a;
152
153 out[0] = in[0];
154 }
155
156 static INLINE void insert_null( const struct draw_vf_attr *a, uint8_t *v, const float *in )
157 {
158 (void) a; (void) v; (void) in;
159 }
160
161 static INLINE void insert_4ub_4f_rgba_4( const struct draw_vf_attr *a, uint8_t *v,
162 const float *in )
163 {
164 (void) a;
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]);
169 }
170
171 static INLINE void insert_4ub_4f_rgba_3( const struct draw_vf_attr *a, uint8_t *v,
172 const float *in )
173 {
174 (void) a;
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]);
178 v[3] = 0xff;
179 }
180
181 static INLINE void insert_4ub_4f_rgba_2( const struct draw_vf_attr *a, uint8_t *v,
182 const float *in )
183 {
184 (void) a;
185 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
186 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
187 v[2] = 0;
188 v[3] = 0xff;
189 }
190
191 static INLINE void insert_4ub_4f_rgba_1( const struct draw_vf_attr *a, uint8_t *v,
192 const float *in )
193 {
194 (void) a;
195 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
196 v[1] = 0;
197 v[2] = 0;
198 v[3] = 0xff;
199 }
200
201 static INLINE void insert_4ub_4f_bgra_4( const struct draw_vf_attr *a, uint8_t *v,
202 const float *in )
203 {
204 (void) a;
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]);
209 }
210
211 static INLINE void insert_4ub_4f_bgra_3( const struct draw_vf_attr *a, uint8_t *v,
212 const float *in )
213 {
214 (void) a;
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]);
218 v[3] = 0xff;
219 }
220
221 static INLINE void insert_4ub_4f_bgra_2( const struct draw_vf_attr *a, uint8_t *v,
222 const float *in )
223 {
224 (void) a;
225 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
226 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
227 v[0] = 0;
228 v[3] = 0xff;
229 }
230
231 static INLINE void insert_4ub_4f_bgra_1( const struct draw_vf_attr *a, uint8_t *v,
232 const float *in )
233 {
234 (void) a;
235 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
236 v[1] = 0;
237 v[0] = 0;
238 v[3] = 0xff;
239 }
240
241 static INLINE void insert_4ub_4f_argb_4( const struct draw_vf_attr *a, uint8_t *v,
242 const float *in )
243 {
244 (void) a;
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]);
249 }
250
251 static INLINE void insert_4ub_4f_argb_3( const struct draw_vf_attr *a, uint8_t *v,
252 const float *in )
253 {
254 (void) a;
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]);
258 v[0] = 0xff;
259 }
260
261 static INLINE void insert_4ub_4f_argb_2( const struct draw_vf_attr *a, uint8_t *v,
262 const float *in )
263 {
264 (void) a;
265 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
266 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
267 v[3] = 0x00;
268 v[0] = 0xff;
269 }
270
271 static INLINE void insert_4ub_4f_argb_1( const struct draw_vf_attr *a, uint8_t *v,
272 const float *in )
273 {
274 (void) a;
275 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
276 v[2] = 0x00;
277 v[3] = 0x00;
278 v[0] = 0xff;
279 }
280
281 static INLINE void insert_4ub_4f_abgr_4( const struct draw_vf_attr *a, uint8_t *v,
282 const float *in )
283 {
284 (void) a;
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]);
289 }
290
291 static INLINE void insert_4ub_4f_abgr_3( const struct draw_vf_attr *a, uint8_t *v,
292 const float *in )
293 {
294 (void) a;
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]);
298 v[0] = 0xff;
299 }
300
301 static INLINE void insert_4ub_4f_abgr_2( const struct draw_vf_attr *a, uint8_t *v,
302 const float *in )
303 {
304 (void) a;
305 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
306 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
307 v[1] = 0x00;
308 v[0] = 0xff;
309 }
310
311 static INLINE void insert_4ub_4f_abgr_1( const struct draw_vf_attr *a, uint8_t *v,
312 const float *in )
313 {
314 (void) a;
315 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
316 v[2] = 0x00;
317 v[1] = 0x00;
318 v[0] = 0xff;
319 }
320
321 static INLINE void insert_3ub_3f_rgb_3( const struct draw_vf_attr *a, uint8_t *v,
322 const float *in )
323 {
324 (void) a;
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 }
329
330 static INLINE void insert_3ub_3f_rgb_2( const struct draw_vf_attr *a, uint8_t *v,
331 const float *in )
332 {
333 (void) a;
334 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
336 v[2] = 0;
337 }
338
339 static INLINE void insert_3ub_3f_rgb_1( const struct draw_vf_attr *a, uint8_t *v,
340 const float *in )
341 {
342 (void) a;
343 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
344 v[1] = 0;
345 v[2] = 0;
346 }
347
348 static INLINE void insert_3ub_3f_bgr_3( const struct draw_vf_attr *a, uint8_t *v,
349 const float *in )
350 {
351 (void) a;
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]);
355 }
356
357 static INLINE void insert_3ub_3f_bgr_2( const struct draw_vf_attr *a, uint8_t *v,
358 const float *in )
359 {
360 (void) a;
361 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
362 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
363 v[0] = 0;
364 }
365
366 static INLINE void insert_3ub_3f_bgr_1( const struct draw_vf_attr *a, uint8_t *v,
367 const float *in )
368 {
369 (void) a;
370 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
371 v[1] = 0;
372 v[0] = 0;
373 }
374
375
376 static INLINE void insert_1ub_1f_1( const struct draw_vf_attr *a, uint8_t *v,
377 const float *in )
378 {
379 (void) a;
380 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
381 }
382
383
384 const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] =
385 {
386 { "1f",
387 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
388 sizeof(float), FALSE },
389
390 { "2f",
391 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
392 2 * sizeof(float), FALSE },
393
394 { "3f",
395 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
396 3 * sizeof(float), FALSE },
397
398 { "4f",
399 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
400 4 * sizeof(float), FALSE },
401
402 { "3f_xyw",
403 { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
404 insert_3f_xyw_4 },
405 3 * sizeof(float), FALSE },
406
407 { "1ub_1f",
408 { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
409 sizeof(uint8_t), FALSE },
410
411 { "3ub_3f_rgb",
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 },
415
416 { "3ub_3f_bgr",
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 },
420
421 { "4ub_4f_rgba",
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 },
425
426 { "4ub_4f_bgra",
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 },
430
431 { "4ub_4f_argb",
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 },
435
436 { "4ub_4f_abgr",
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 },
440
441 { "1f_const",
442 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
443 sizeof(float), TRUE },
444
445 { "2f_const",
446 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
447 2 * sizeof(float), TRUE },
448
449 { "3f_const",
450 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
451 3 * sizeof(float), TRUE },
452
453 { "4f_const",
454 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
455 4 * sizeof(float), TRUE },
456
457 { "pad",
458 { NULL, NULL, NULL, NULL },
459 0, FALSE },
460
461 };
462
463
464
465
466 /***********************************************************************
467 * Hardwired fastpaths for emitting whole vertices or groups of
468 * vertices
469 */
470 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
471 static void NAME( struct draw_vertex_fetch *vf, \
472 unsigned count, \
473 uint8_t *v ) \
474 { \
475 struct draw_vf_attr *a = vf->attr; \
476 unsigned i; \
477 \
478 for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \
479 if (NR > 0) { \
480 F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \
481 a[0].inputptr += a[0].inputstride; \
482 } \
483 \
484 if (NR > 1) { \
485 F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \
486 a[1].inputptr += a[1].inputstride; \
487 } \
488 \
489 if (NR > 2) { \
490 F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \
491 a[2].inputptr += a[2].inputstride; \
492 } \
493 \
494 if (NR > 3) { \
495 F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \
496 a[3].inputptr += a[3].inputstride; \
497 } \
498 \
499 if (NR > 4) { \
500 F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \
501 a[4].inputptr += a[4].inputstride; \
502 } \
503 } \
504 }
505
506
507 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
508 insert_null, insert_null, NAME)
509
510 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
511 insert_null, NAME)
512
513 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
514 insert_null, NAME)
515
516
517 EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
518
519 EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
520
521 EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
522
523
524 /* Use the codegen paths to select one of a number of hardwired
525 * fastpaths.
526 */
527 void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf )
528 {
529 draw_vf_emit_func func = NULL;
530
531 /* Does it fit a hardwired fastpath? Help! this is growing out of
532 * control!
533 */
534 switch (vf->attr_count) {
535 case 2:
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;
539 }
540 break;
541 case 3:
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;
546 }
547 }
548 break;
549 case 4:
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;
555 }
556 }
557 break;
558 }
559
560 vf->emit = func;
561 }
562
563 /***********************************************************************
564 * Generic (non-codegen) functions for whole vertices or groups of
565 * vertices
566 */
567
568 void draw_vf_generic_emit( struct draw_vertex_fetch *vf,
569 unsigned count,
570 uint8_t *v )
571 {
572 struct draw_vf_attr *a = vf->attr;
573 const unsigned attr_count = vf->attr_count;
574 const unsigned stride = vf->vertex_stride;
575 unsigned i, j;
576
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 );
582 }
583 }
584 }
585
586