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