mesa: Move simple_list.h to src/util.
[mesa.git] / src / mesa / tnl / t_vertex_generic.c
1
2 /*
3 * Copyright 2003 VMware, 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 * VMWARE 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@vmware.com>
27 */
28
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/colormac.h"
32 #include "util/simple_list.h"
33 #include "swrast/s_chan.h"
34 #include "t_context.h"
35 #include "t_vertex.h"
36
37
38 #if 0
39 #define DEBUG_INSERT printf("%s\n", __FUNCTION__)
40 #else
41 #define DEBUG_INSERT
42 #endif
43
44
45 /*
46 * These functions take the NDC coordinates pointed to by 'in', apply the
47 * NDC->Viewport mapping and store the results at 'v'.
48 */
49
50 static inline void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
51 const GLfloat *in )
52 {
53 GLfloat *out = (GLfloat *)v;
54 const GLfloat * const vp = a->vp;
55 DEBUG_INSERT;
56 out[0] = vp[0] * in[0] + vp[12];
57 out[1] = vp[5] * in[1] + vp[13];
58 out[2] = vp[10] * in[2] + vp[14];
59 out[3] = in[3];
60 }
61
62 static inline void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
63 const GLfloat *in )
64 {
65 GLfloat *out = (GLfloat *)v;
66 const GLfloat * const vp = a->vp;
67 DEBUG_INSERT;
68 out[0] = vp[0] * in[0] + vp[12];
69 out[1] = vp[5] * in[1] + vp[13];
70 out[2] = vp[10] * in[2] + vp[14];
71 out[3] = 1;
72 }
73
74 static inline void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
75 const GLfloat *in )
76 {
77 GLfloat *out = (GLfloat *)v;
78 const GLfloat * const vp = a->vp;
79 DEBUG_INSERT;
80 out[0] = vp[0] * in[0] + vp[12];
81 out[1] = vp[5] * in[1] + vp[13];
82 out[2] = vp[14];
83 out[3] = 1;
84 }
85
86 static inline void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
87 const GLfloat *in )
88 {
89 GLfloat *out = (GLfloat *)v;
90 const GLfloat * const vp = a->vp;
91 DEBUG_INSERT;
92 out[0] = vp[0] * in[0] + vp[12];
93 out[1] = vp[13];
94 out[2] = vp[14];
95 out[3] = 1;
96 }
97
98 static inline void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
99 const GLfloat *in )
100 {
101 GLfloat *out = (GLfloat *)v;
102 const GLfloat * const vp = a->vp;
103 DEBUG_INSERT;
104 out[0] = vp[0] * in[0] + vp[12];
105 out[1] = vp[5] * in[1] + vp[13];
106 out[2] = vp[10] * in[2] + vp[14];
107 }
108
109 static inline void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
110 const GLfloat *in )
111 {
112 GLfloat *out = (GLfloat *)v;
113 const GLfloat * const vp = a->vp;
114 DEBUG_INSERT;
115 out[0] = vp[0] * in[0] + vp[12];
116 out[1] = vp[5] * in[1] + vp[13];
117 out[2] = vp[14];
118 }
119
120 static inline void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
121 const GLfloat *in )
122 {
123 GLfloat *out = (GLfloat *)v;
124 const GLfloat * const vp = a->vp;
125 DEBUG_INSERT;
126 out[0] = vp[0] * in[0] + vp[12];
127 out[1] = vp[13];
128 out[2] = vp[14];
129 }
130
131 static inline void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
132 const GLfloat *in )
133 {
134 GLfloat *out = (GLfloat *)v;
135 const GLfloat * const vp = a->vp;
136 DEBUG_INSERT;
137 out[0] = vp[0] * in[0] + vp[12];
138 out[1] = vp[5] * in[1] + vp[13];
139 }
140
141 static inline void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
142 const GLfloat *in )
143 {
144 GLfloat *out = (GLfloat *)v;
145 const GLfloat * const vp = a->vp;
146 DEBUG_INSERT;
147 out[0] = vp[0] * in[0] + vp[12];
148 out[1] = vp[13];
149 }
150
151
152 /*
153 * These functions do the same as above, except for the viewport mapping.
154 */
155
156 static inline void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
157 {
158 GLfloat *out = (GLfloat *)(v);
159 (void) a;
160 DEBUG_INSERT;
161 out[0] = in[0];
162 out[1] = in[1];
163 out[2] = in[2];
164 out[3] = in[3];
165 }
166
167 static inline void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
168 {
169 GLfloat *out = (GLfloat *)(v);
170 (void) a;
171 DEBUG_INSERT;
172 out[0] = in[0];
173 out[1] = in[1];
174 out[2] = in[2];
175 out[3] = 1;
176 }
177
178 static inline void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
179 {
180 GLfloat *out = (GLfloat *)(v);
181 (void) a;
182 DEBUG_INSERT;
183 out[0] = in[0];
184 out[1] = in[1];
185 out[2] = 0;
186 out[3] = 1;
187 }
188
189 static inline void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
190 {
191 GLfloat *out = (GLfloat *)(v);
192 (void) a;
193 DEBUG_INSERT;
194 out[0] = in[0];
195 out[1] = 0;
196 out[2] = 0;
197 out[3] = 1;
198 }
199
200 static inline void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
201 {
202 GLfloat *out = (GLfloat *)(v);
203 (void) a;
204 DEBUG_INSERT;
205 out[0] = in[0];
206 out[1] = in[1];
207 out[2] = in[3];
208 }
209
210 static inline void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
211 {
212 (void) a; (void) v; (void) in;
213 DEBUG_INSERT;
214 exit(1);
215 }
216
217 static inline void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
218 {
219 GLfloat *out = (GLfloat *)(v);
220 (void) a;
221 DEBUG_INSERT;
222 out[0] = in[0];
223 out[1] = in[1];
224 out[2] = in[2];
225 }
226
227 static inline void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
228 {
229 GLfloat *out = (GLfloat *)(v);
230 (void) a;
231 DEBUG_INSERT;
232 out[0] = in[0];
233 out[1] = in[1];
234 out[2] = 0;
235 }
236
237 static inline void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
238 {
239 GLfloat *out = (GLfloat *)(v);
240 (void) a;
241 DEBUG_INSERT;
242 out[0] = in[0];
243 out[1] = 0;
244 out[2] = 0;
245 }
246
247
248 static inline void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
249 {
250 GLfloat *out = (GLfloat *)(v);
251 (void) a;
252 DEBUG_INSERT;
253 out[0] = in[0];
254 out[1] = in[1];
255 }
256
257 static inline void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
258 {
259 GLfloat *out = (GLfloat *)(v);
260 (void) a;
261 DEBUG_INSERT;
262 out[0] = in[0];
263 out[1] = 0;
264 }
265
266 static inline void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
267 {
268 GLfloat *out = (GLfloat *)(v);
269 (void) a;
270 DEBUG_INSERT;
271 out[0] = in[0];
272 }
273
274 static inline void insert_null( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
275 {
276 DEBUG_INSERT;
277 (void) a; (void) v; (void) in;
278 }
279
280 static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
281 const GLfloat *in )
282 {
283 GLchan *c = (GLchan *)v;
284 DEBUG_INSERT;
285 (void) a;
286 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
287 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
288 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
289 UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
290 }
291
292 static inline void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
293 const GLfloat *in )
294 {
295 GLchan *c = (GLchan *)v;
296 DEBUG_INSERT;
297 (void) a;
298 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
299 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
300 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
301 c[3] = CHAN_MAX;
302 }
303
304 static inline void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
305 const GLfloat *in )
306 {
307 GLchan *c = (GLchan *)v;
308 DEBUG_INSERT;
309 (void) a;
310 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
311 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
312 c[2] = 0;
313 c[3] = CHAN_MAX;
314 }
315
316 static inline void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
317 const GLfloat *in )
318 {
319 GLchan *c = (GLchan *)v;
320 DEBUG_INSERT;
321 (void) a;
322 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
323 c[1] = 0;
324 c[2] = 0;
325 c[3] = CHAN_MAX;
326 }
327
328 static inline void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
329 const GLfloat *in )
330 {
331 DEBUG_INSERT;
332 (void) a;
333 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
334 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
336 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
337 }
338
339 static inline void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
340 const GLfloat *in )
341 {
342 DEBUG_INSERT;
343 (void) a;
344 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
345 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
346 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
347 v[3] = 0xff;
348 }
349
350 static inline void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
351 const GLfloat *in )
352 {
353 DEBUG_INSERT;
354 (void) a;
355 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
356 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
357 v[2] = 0;
358 v[3] = 0xff;
359 }
360
361 static inline void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
362 const GLfloat *in )
363 {
364 DEBUG_INSERT;
365 (void) a;
366 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
367 v[1] = 0;
368 v[2] = 0;
369 v[3] = 0xff;
370 }
371
372 static inline void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v,
373 const GLfloat *in )
374 {
375 DEBUG_INSERT;
376 (void) a;
377 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
378 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
379 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
380 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
381 }
382
383 static inline void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v,
384 const GLfloat *in )
385 {
386 DEBUG_INSERT;
387 (void) a;
388 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
389 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
390 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
391 v[3] = 0xff;
392 }
393
394 static inline void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v,
395 const GLfloat *in )
396 {
397 DEBUG_INSERT;
398 (void) a;
399 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
400 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
401 v[0] = 0;
402 v[3] = 0xff;
403 }
404
405 static inline void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v,
406 const GLfloat *in )
407 {
408 DEBUG_INSERT;
409 (void) a;
410 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
411 v[1] = 0;
412 v[0] = 0;
413 v[3] = 0xff;
414 }
415
416 static inline void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v,
417 const GLfloat *in )
418 {
419 DEBUG_INSERT;
420 (void) a;
421 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
422 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
423 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
424 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
425 }
426
427 static inline void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
428 const GLfloat *in )
429 {
430 DEBUG_INSERT;
431 (void) a;
432 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
433 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
434 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]);
435 v[0] = 0xff;
436 }
437
438 static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
439 const GLfloat *in )
440 {
441 DEBUG_INSERT;
442 (void) a;
443 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
444 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
445 v[3] = 0x00;
446 v[0] = 0xff;
447 }
448
449 static inline void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
450 const GLfloat *in )
451 {
452 DEBUG_INSERT;
453 (void) a;
454 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]);
455 v[2] = 0x00;
456 v[3] = 0x00;
457 v[0] = 0xff;
458 }
459
460 static inline void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr *a, GLubyte *v,
461 const GLfloat *in )
462 {
463 DEBUG_INSERT;
464 (void) a;
465 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
466 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
467 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
468 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]);
469 }
470
471 static inline void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
472 const GLfloat *in )
473 {
474 DEBUG_INSERT;
475 (void) a;
476 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
477 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
478 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]);
479 v[0] = 0xff;
480 }
481
482 static inline void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
483 const GLfloat *in )
484 {
485 DEBUG_INSERT;
486 (void) a;
487 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
488 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]);
489 v[1] = 0x00;
490 v[0] = 0xff;
491 }
492
493 static inline void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
494 const GLfloat *in )
495 {
496 DEBUG_INSERT;
497 (void) a;
498 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]);
499 v[2] = 0x00;
500 v[1] = 0x00;
501 v[0] = 0xff;
502 }
503
504 static inline void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
505 const GLfloat *in )
506 {
507 DEBUG_INSERT;
508 (void) a;
509 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
510 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
511 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
512 }
513
514 static inline void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
515 const GLfloat *in )
516 {
517 DEBUG_INSERT;
518 (void) a;
519 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
520 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
521 v[2] = 0;
522 }
523
524 static inline void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
525 const GLfloat *in )
526 {
527 DEBUG_INSERT;
528 (void) a;
529 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
530 v[1] = 0;
531 v[2] = 0;
532 }
533
534 static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
535 const GLfloat *in )
536 {
537 DEBUG_INSERT;
538 (void) a;
539 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
540 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
541 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
542 }
543
544 static inline void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
545 const GLfloat *in )
546 {
547 DEBUG_INSERT;
548 (void) a;
549 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
550 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
551 v[0] = 0;
552 }
553
554 static inline void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
555 const GLfloat *in )
556 {
557 DEBUG_INSERT;
558 (void) a;
559 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
560 v[1] = 0;
561 v[0] = 0;
562 }
563
564
565 static inline void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v,
566 const GLfloat *in )
567 {
568 DEBUG_INSERT;
569 (void) a;
570 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
571 }
572
573
574 /***********************************************************************
575 * Functions to perform the reverse operations to the above, for
576 * swrast translation and clip-interpolation.
577 *
578 * Currently always extracts a full 4 floats.
579 */
580
581 static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
582 const GLubyte *v )
583 {
584 const GLfloat *in = (const GLfloat *)v;
585 const GLfloat * const vp = a->vp;
586
587 /* Although included for completeness, the position coordinate is
588 * usually handled differently during clipping.
589 */
590 DEBUG_INSERT;
591 out[0] = (in[0] - vp[12]) / vp[0];
592 out[1] = (in[1] - vp[13]) / vp[5];
593 out[2] = (in[2] - vp[14]) / vp[10];
594 out[3] = in[3];
595 }
596
597 static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
598 const GLubyte *v )
599 {
600 const GLfloat *in = (const GLfloat *)v;
601 const GLfloat * const vp = a->vp;
602 DEBUG_INSERT;
603 out[0] = (in[0] - vp[12]) / vp[0];
604 out[1] = (in[1] - vp[13]) / vp[5];
605 out[2] = (in[2] - vp[14]) / vp[10];
606 out[3] = 1;
607 }
608
609
610 static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
611 const GLubyte *v )
612 {
613 const GLfloat *in = (const GLfloat *)v;
614 const GLfloat * const vp = a->vp;
615 DEBUG_INSERT;
616 out[0] = (in[0] - vp[12]) / vp[0];
617 out[1] = (in[1] - vp[13]) / vp[5];
618 out[2] = 0;
619 out[3] = 1;
620 }
621
622
623 static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
624 {
625 const GLfloat *in = (const GLfloat *)v;
626 (void) a;
627
628 out[0] = in[0];
629 out[1] = in[1];
630 out[2] = in[2];
631 out[3] = in[3];
632 }
633
634 static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
635 {
636 const GLfloat *in = (const GLfloat *)v;
637 (void) a;
638
639 out[0] = in[0];
640 out[1] = in[1];
641 out[2] = 0;
642 out[3] = in[2];
643 }
644
645
646 static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
647 {
648 const GLfloat *in = (const GLfloat *)v;
649 (void) a;
650
651 out[0] = in[0];
652 out[1] = in[1];
653 out[2] = in[2];
654 out[3] = 1;
655 }
656
657
658 static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
659 {
660 const GLfloat *in = (const GLfloat *)v;
661 (void) a;
662
663 out[0] = in[0];
664 out[1] = in[1];
665 out[2] = 0;
666 out[3] = 1;
667 }
668
669 static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
670 {
671 const GLfloat *in = (const GLfloat *)v;
672 (void) a;
673
674 out[0] = in[0];
675 out[1] = 0;
676 out[2] = 0;
677 out[3] = 1;
678 }
679
680 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
681 const GLubyte *v )
682 {
683 GLchan *c = (GLchan *)v;
684 (void) a;
685
686 out[0] = CHAN_TO_FLOAT(c[0]);
687 out[1] = CHAN_TO_FLOAT(c[1]);
688 out[2] = CHAN_TO_FLOAT(c[2]);
689 out[3] = CHAN_TO_FLOAT(c[3]);
690 }
691
692 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
693 const GLubyte *v )
694 {
695 (void) a;
696 out[0] = UBYTE_TO_FLOAT(v[0]);
697 out[1] = UBYTE_TO_FLOAT(v[1]);
698 out[2] = UBYTE_TO_FLOAT(v[2]);
699 out[3] = UBYTE_TO_FLOAT(v[3]);
700 }
701
702 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out,
703 const GLubyte *v )
704 {
705 (void) a;
706 out[2] = UBYTE_TO_FLOAT(v[0]);
707 out[1] = UBYTE_TO_FLOAT(v[1]);
708 out[0] = UBYTE_TO_FLOAT(v[2]);
709 out[3] = UBYTE_TO_FLOAT(v[3]);
710 }
711
712 static void extract_4ub_4f_argb( const struct tnl_clipspace_attr *a, GLfloat *out,
713 const GLubyte *v )
714 {
715 (void) a;
716 out[3] = UBYTE_TO_FLOAT(v[0]);
717 out[0] = UBYTE_TO_FLOAT(v[1]);
718 out[1] = UBYTE_TO_FLOAT(v[2]);
719 out[2] = UBYTE_TO_FLOAT(v[3]);
720 }
721
722 static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr *a, GLfloat *out,
723 const GLubyte *v )
724 {
725 (void) a;
726 out[3] = UBYTE_TO_FLOAT(v[0]);
727 out[2] = UBYTE_TO_FLOAT(v[1]);
728 out[1] = UBYTE_TO_FLOAT(v[2]);
729 out[0] = UBYTE_TO_FLOAT(v[3]);
730 }
731
732 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out,
733 const GLubyte *v )
734 {
735 (void) a;
736 out[0] = UBYTE_TO_FLOAT(v[0]);
737 out[1] = UBYTE_TO_FLOAT(v[1]);
738 out[2] = UBYTE_TO_FLOAT(v[2]);
739 out[3] = 1;
740 }
741
742 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out,
743 const GLubyte *v )
744 {
745 (void) a;
746 out[2] = UBYTE_TO_FLOAT(v[0]);
747 out[1] = UBYTE_TO_FLOAT(v[1]);
748 out[0] = UBYTE_TO_FLOAT(v[2]);
749 out[3] = 1;
750 }
751
752 static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
753 {
754 (void) a;
755 out[0] = UBYTE_TO_FLOAT(v[0]);
756 out[1] = 0;
757 out[2] = 0;
758 out[3] = 1;
759 }
760
761
762 const struct tnl_format_info _tnl_format_info[EMIT_MAX] =
763 {
764 { "1f",
765 extract_1f,
766 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
767 sizeof(GLfloat) },
768
769 { "2f",
770 extract_2f,
771 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
772 2 * sizeof(GLfloat) },
773
774 { "3f",
775 extract_3f,
776 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
777 3 * sizeof(GLfloat) },
778
779 { "4f",
780 extract_4f,
781 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
782 4 * sizeof(GLfloat) },
783
784 { "2f_viewport",
785 extract_2f_viewport,
786 { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
787 insert_2f_viewport_2 },
788 2 * sizeof(GLfloat) },
789
790 { "3f_viewport",
791 extract_3f_viewport,
792 { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
793 insert_3f_viewport_3 },
794 3 * sizeof(GLfloat) },
795
796 { "4f_viewport",
797 extract_4f_viewport,
798 { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
799 insert_4f_viewport_4 },
800 4 * sizeof(GLfloat) },
801
802 { "3f_xyw",
803 extract_3f_xyw,
804 { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
805 insert_3f_xyw_4 },
806 3 * sizeof(GLfloat) },
807
808 { "1ub_1f",
809 extract_1ub_1f,
810 { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
811 sizeof(GLubyte) },
812
813 { "3ub_3f_rgb",
814 extract_3ub_3f_rgb,
815 { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
816 insert_3ub_3f_rgb_3 },
817 3 * sizeof(GLubyte) },
818
819 { "3ub_3f_bgr",
820 extract_3ub_3f_bgr,
821 { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
822 insert_3ub_3f_bgr_3 },
823 3 * sizeof(GLubyte) },
824
825 { "4ub_4f_rgba",
826 extract_4ub_4f_rgba,
827 { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3,
828 insert_4ub_4f_rgba_4 },
829 4 * sizeof(GLubyte) },
830
831 { "4ub_4f_bgra",
832 extract_4ub_4f_bgra,
833 { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
834 insert_4ub_4f_bgra_4 },
835 4 * sizeof(GLubyte) },
836
837 { "4ub_4f_argb",
838 extract_4ub_4f_argb,
839 { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3,
840 insert_4ub_4f_argb_4 },
841 4 * sizeof(GLubyte) },
842
843 { "4ub_4f_abgr",
844 extract_4ub_4f_abgr,
845 { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3,
846 insert_4ub_4f_abgr_4 },
847 4 * sizeof(GLubyte) },
848
849 { "4chan_4f_rgba",
850 extract_4chan_4f_rgba,
851 { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
852 insert_4chan_4f_rgba_4 },
853 4 * sizeof(GLchan) },
854
855 { "pad",
856 NULL,
857 { NULL, NULL, NULL, NULL },
858 0 }
859
860 };
861
862
863
864
865 /***********************************************************************
866 * Hardwired fastpaths for emitting whole vertices or groups of
867 * vertices
868 */
869 #define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \
870 static void NAME( struct gl_context *ctx, \
871 GLuint count, \
872 GLubyte *v ) \
873 { \
874 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \
875 struct tnl_clipspace_attr *a = vtx->attr; \
876 GLuint i; \
877 \
878 for (i = 0 ; i < count ; i++, v += vtx->vertex_size) { \
879 if (NR > 0) { \
880 F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr ); \
881 a[0].inputptr += a[0].inputstride; \
882 } \
883 \
884 if (NR > 1) { \
885 F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr ); \
886 a[1].inputptr += a[1].inputstride; \
887 } \
888 \
889 if (NR > 2) { \
890 F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr ); \
891 a[2].inputptr += a[2].inputstride; \
892 } \
893 \
894 if (NR > 3) { \
895 F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr ); \
896 a[3].inputptr += a[3].inputstride; \
897 } \
898 \
899 if (NR > 4) { \
900 F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr ); \
901 a[4].inputptr += a[4].inputstride; \
902 } \
903 } \
904 }
905
906
907 #define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \
908 insert_null, insert_null, NAME)
909
910 #define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \
911 insert_null, NAME)
912
913 #define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \
914 insert_null, NAME)
915
916
917 EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4)
918 EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4)
919 EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4)
920
921 EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2)
922 EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, emit_viewport4_bgra4_st2)
923 EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2)
924
925 EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2)
926 EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2, emit_viewport4_bgra4_st2_st2)
927 EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2)
928
929
930 /* Use the codegen paths to select one of a number of hardwired
931 * fastpaths.
932 */
933 void _tnl_generate_hardwired_emit( struct gl_context *ctx )
934 {
935 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
936 tnl_emit_func func = NULL;
937
938 /* Does it fit a hardwired fastpath? Help! this is growing out of
939 * control!
940 */
941 switch (vtx->attr_count) {
942 case 2:
943 if (vtx->attr[0].emit == insert_3f_viewport_3) {
944 if (vtx->attr[1].emit == insert_4ub_4f_bgra_4)
945 func = emit_viewport3_bgra4;
946 else if (vtx->attr[1].emit == insert_4ub_4f_rgba_4)
947 func = emit_viewport3_rgba4;
948 }
949 else if (vtx->attr[0].emit == insert_3f_3 &&
950 vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
951 func = emit_xyz3_rgba4;
952 }
953 break;
954 case 3:
955 if (vtx->attr[2].emit == insert_2f_2) {
956 if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
957 if (vtx->attr[0].emit == insert_4f_viewport_4)
958 func = emit_viewport4_rgba4_st2;
959 else if (vtx->attr[0].emit == insert_4f_4)
960 func = emit_xyzw4_rgba4_st2;
961 }
962 else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
963 vtx->attr[0].emit == insert_4f_viewport_4)
964 func = emit_viewport4_bgra4_st2;
965 }
966 break;
967 case 4:
968 if (vtx->attr[2].emit == insert_2f_2 &&
969 vtx->attr[3].emit == insert_2f_2) {
970 if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) {
971 if (vtx->attr[0].emit == insert_4f_viewport_4)
972 func = emit_viewport4_rgba4_st2_st2;
973 else if (vtx->attr[0].emit == insert_4f_4)
974 func = emit_xyzw4_rgba4_st2_st2;
975 }
976 else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 &&
977 vtx->attr[0].emit == insert_4f_viewport_4)
978 func = emit_viewport4_bgra4_st2_st2;
979 }
980 break;
981 }
982
983 vtx->emit = func;
984 }
985
986 /***********************************************************************
987 * Generic (non-codegen) functions for whole vertices or groups of
988 * vertices
989 */
990
991 void _tnl_generic_emit( struct gl_context *ctx,
992 GLuint count,
993 GLubyte *v )
994 {
995 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
996 struct tnl_clipspace_attr *a = vtx->attr;
997 const GLuint attr_count = vtx->attr_count;
998 const GLuint stride = vtx->vertex_size;
999 GLuint i, j;
1000
1001 for (i = 0 ; i < count ; i++, v += stride) {
1002 for (j = 0; j < attr_count; j++) {
1003 GLfloat *in = (GLfloat *)a[j].inputptr;
1004 a[j].inputptr += a[j].inputstride;
1005 a[j].emit( &a[j], v + a[j].vertoffset, in );
1006 }
1007 }
1008 }
1009
1010
1011 void _tnl_generic_interp( struct gl_context *ctx,
1012 GLfloat t,
1013 GLuint edst, GLuint eout, GLuint ein,
1014 GLboolean force_boundary )
1015 {
1016 TNLcontext *tnl = TNL_CONTEXT(ctx);
1017 struct vertex_buffer *VB = &tnl->vb;
1018 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1019 const GLubyte *vin = vtx->vertex_buf + ein * vtx->vertex_size;
1020 const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
1021 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
1022 const struct tnl_clipspace_attr *a = vtx->attr;
1023 const GLuint attr_count = vtx->attr_count;
1024 GLuint j;
1025 (void) force_boundary;
1026
1027 if (tnl->NeedNdcCoords) {
1028 const GLfloat *dstclip = VB->ClipPtr->data[edst];
1029 if (dstclip[3] != 0.0) {
1030 const GLfloat w = 1.0f / dstclip[3];
1031 GLfloat pos[4];
1032
1033 pos[0] = dstclip[0] * w;
1034 pos[1] = dstclip[1] * w;
1035 pos[2] = dstclip[2] * w;
1036 pos[3] = w;
1037
1038 a[0].insert[4-1]( &a[0], vdst, pos );
1039 }
1040 }
1041 else {
1042 a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
1043 }
1044
1045
1046 for (j = 1; j < attr_count; j++) {
1047 GLfloat fin[4], fout[4], fdst[4];
1048
1049 a[j].extract( &a[j], fin, vin + a[j].vertoffset );
1050 a[j].extract( &a[j], fout, vout + a[j].vertoffset );
1051
1052 INTERP_4F(t, fdst, fout, fin);
1053
1054 a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
1055 }
1056 }
1057
1058
1059 /* Extract color attributes from one vertex and insert them into
1060 * another. (Shortcircuit extract/insert with memcpy).
1061 */
1062 void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc )
1063 {
1064 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1065 GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
1066 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
1067 const struct tnl_clipspace_attr *a = vtx->attr;
1068 const GLuint attr_count = vtx->attr_count;
1069 GLuint j;
1070
1071 for (j = 0; j < attr_count; j++) {
1072 if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
1073 a[j].attrib == VERT_ATTRIB_COLOR1) {
1074
1075 memcpy( vdst + a[j].vertoffset,
1076 vsrc + a[j].vertoffset,
1077 a[j].vertattrsize );
1078 }
1079 }
1080 }
1081
1082
1083 /* Helper functions for hardware which doesn't put back colors and/or
1084 * edgeflags into vertices.
1085 */
1086 void _tnl_generic_interp_extras( struct gl_context *ctx,
1087 GLfloat t,
1088 GLuint dst, GLuint out, GLuint in,
1089 GLboolean force_boundary )
1090 {
1091 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
1092
1093 /* If stride is zero, BackfaceColorPtr is constant across the VB, so
1094 * there is no point interpolating between two values as they will
1095 * be identical. In all other cases, this value is generated by
1096 * t_vb_lighttmp.h and has a stride of 4 dwords.
1097 */
1098 if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
1099 assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
1100
1101 INTERP_4F( t,
1102 VB->BackfaceColorPtr->data[dst],
1103 VB->BackfaceColorPtr->data[out],
1104 VB->BackfaceColorPtr->data[in] );
1105 }
1106
1107 if (VB->BackfaceSecondaryColorPtr) {
1108 assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat));
1109
1110 INTERP_3F( t,
1111 VB->BackfaceSecondaryColorPtr->data[dst],
1112 VB->BackfaceSecondaryColorPtr->data[out],
1113 VB->BackfaceSecondaryColorPtr->data[in] );
1114 }
1115
1116 if (VB->BackfaceIndexPtr) {
1117 VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t,
1118 VB->BackfaceIndexPtr->data[out][0],
1119 VB->BackfaceIndexPtr->data[in][0] );
1120 }
1121
1122 if (VB->EdgeFlag) {
1123 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
1124 }
1125
1126 _tnl_generic_interp(ctx, t, dst, out, in, force_boundary);
1127 }
1128
1129 void _tnl_generic_copy_pv_extras( struct gl_context *ctx,
1130 GLuint dst, GLuint src )
1131 {
1132 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
1133
1134 /* See above comment:
1135 */
1136 if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
1137 COPY_4FV( VB->BackfaceColorPtr->data[dst],
1138 VB->BackfaceColorPtr->data[src] );
1139 }
1140
1141 if (VB->BackfaceSecondaryColorPtr) {
1142 COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst],
1143 VB->BackfaceSecondaryColorPtr->data[src] );
1144 }
1145
1146 if (VB->BackfaceIndexPtr) {
1147 VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0];
1148 }
1149
1150 _tnl_generic_copy_pv(ctx, dst, src);
1151 }
1152
1153