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