Silence gcc 3.4 warnings on ReactOS. Mostly unused var warnings. (patch 1015696)
[mesa.git] / src / mesa / tnl / t_vertex.c
1 /*
2 * Copyright 2003 Tungsten Graphics, inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keithw@tungstengraphics.com>
26 */
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "colormac.h"
31
32 #include "t_context.h"
33 #include "t_vertex.h"
34
35
36 /* Build and manage clipspace/ndc/window vertices.
37 *
38 * Another new mechanism designed and crying out for codegen. Before
39 * that, it would be very interesting to investigate the merger of
40 * these vertices and those built in t_vtx_*.
41 */
42
43
44
45
46
47
48 /*
49 * These functions take the NDC coordinates pointed to by 'in', apply the
50 * NDC->Viewport mapping and store the results at 'v'.
51 */
52
53 static void
54 insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
55 const GLfloat *in )
56 {
57 GLfloat *out = (GLfloat *)v;
58 const GLfloat * const vp = a->vp;
59
60 out[0] = vp[0] * in[0] + vp[12];
61 out[1] = vp[5] * in[1] + vp[13];
62 out[2] = vp[10] * in[2] + vp[14];
63 out[3] = in[3];
64 }
65
66 static void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
67 const GLfloat *in )
68 {
69 GLfloat *out = (GLfloat *)v;
70 const GLfloat * const vp = a->vp;
71
72 out[0] = vp[0] * in[0] + vp[12];
73 out[1] = vp[5] * in[1] + vp[13];
74 out[2] = vp[10] * in[2] + vp[14];
75 out[3] = 1;
76 }
77
78 static void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
79 const GLfloat *in )
80 {
81 GLfloat *out = (GLfloat *)v;
82 const GLfloat * const vp = a->vp;
83
84 out[0] = vp[0] * in[0] + vp[12];
85 out[1] = vp[5] * in[1] + vp[13];
86 out[2] = vp[14];
87 out[3] = 1;
88 }
89
90 static void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
91 const GLfloat *in )
92 {
93 GLfloat *out = (GLfloat *)v;
94 const GLfloat * const vp = a->vp;
95
96 out[0] = vp[0] * in[0] + vp[12];
97 out[1] = vp[13];
98 out[2] = vp[14];
99 out[3] = 1;
100 }
101
102 static void insert_3f_viewport_3( 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 void insert_3f_viewport_2( 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[5] * in[1] + vp[13];
121 out[2] = vp[10] * in[2] + vp[14];
122 }
123
124 static void insert_3f_viewport_1( 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[13];
132 out[2] = vp[14];
133 }
134
135 static void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
136 const GLfloat *in )
137 {
138 GLfloat *out = (GLfloat *)v;
139 const GLfloat * const vp = a->vp;
140
141 out[0] = vp[0] * in[0] + vp[12];
142 out[1] = vp[5] * in[1] + vp[13];
143 }
144
145 static void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
146 const GLfloat *in )
147 {
148 GLfloat *out = (GLfloat *)v;
149 const GLfloat * const vp = a->vp;
150
151 out[0] = vp[0] * in[0] + vp[12];
152 out[1] = vp[13];
153 }
154
155
156 /*
157 * These functions do the same as above, except for the viewport mapping.
158 */
159
160 static void insert_4f_4( 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] = in[3];
169 }
170
171 static void insert_4f_3( 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] = in[2];
179 out[3] = 1;
180 }
181
182 static void insert_4f_2( 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] = in[1];
189 out[2] = 0;
190 out[3] = 1;
191 }
192
193 static void insert_4f_1( 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] = 0;
200 out[2] = 0;
201 out[3] = 1;
202 }
203
204 static void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
205 {
206 GLfloat *out = (GLfloat *)(v);
207 (void) a;
208
209 out[0] = in[0];
210 out[1] = in[1];
211 out[2] = in[3];
212 }
213
214 static void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
215 {
216 (void) a; (void) v; (void) in;
217 abort();
218 }
219
220 static void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
221 {
222 GLfloat *out = (GLfloat *)(v);
223 (void) a;
224
225 out[0] = in[0];
226 out[1] = in[1];
227 out[2] = in[2];
228 }
229
230 static void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
231 {
232 GLfloat *out = (GLfloat *)(v);
233 (void) a;
234
235 out[0] = in[0];
236 out[1] = in[1];
237 out[2] = 0;
238 }
239
240 static void insert_3f_1( 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] = 0;
247 out[2] = 0;
248 }
249
250
251 static void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
252 {
253 GLfloat *out = (GLfloat *)(v);
254 (void) a;
255
256 out[0] = in[0];
257 out[1] = in[1];
258 }
259
260 static void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
261 {
262 GLfloat *out = (GLfloat *)(v);
263 (void) a;
264
265 out[0] = in[0];
266 out[1] = 0;
267 }
268
269 static void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
270 {
271 GLfloat *out = (GLfloat *)(v);
272 (void) a;
273
274 out[0] = in[0];
275 }
276
277 static void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
278 const GLfloat *in )
279 {
280 GLchan *c = (GLchan *)v;
281 (void) a;
282 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
283 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
284 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
285 UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
286 }
287
288 static void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
289 const GLfloat *in )
290 {
291 GLchan *c = (GLchan *)v;
292 (void) a;
293 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
294 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
295 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
296 c[3] = CHAN_MAX;
297 }
298
299 static void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
300 const GLfloat *in )
301 {
302 GLchan *c = (GLchan *)v;
303 (void) a;
304 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
305 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
306 c[2] = 0;
307 c[3] = CHAN_MAX;
308 }
309
310 static void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
311 const GLfloat *in )
312 {
313 GLchan *c = (GLchan *)v;
314 (void) a;
315 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
316 c[1] = 0;
317 c[2] = 0;
318 c[3] = CHAN_MAX;
319 }
320
321 static void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
322 const GLfloat *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 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
329 }
330
331 static void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
332 const GLfloat *in )
333 {
334 (void) a;
335 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
336 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
337 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
338 v[3] = 0xff;
339 }
340
341 static void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
342 const GLfloat *in )
343 {
344 (void) a;
345 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
346 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
347 v[2] = 0;
348 v[3] = 0xff;
349 }
350
351 static void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
352 const GLfloat *in )
353 {
354 (void) a;
355 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
356 v[1] = 0;
357 v[2] = 0;
358 v[3] = 0xff;
359 }
360
361 static void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v,
362 const GLfloat *in )
363 {
364 (void) a;
365 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
366 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
367 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
368 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
369 }
370
371 static void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v,
372 const GLfloat *in )
373 {
374 (void) a;
375 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
376 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
377 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
378 v[3] = 0xff;
379 }
380
381 static void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v,
382 const GLfloat *in )
383 {
384 (void) a;
385 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
386 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
387 v[0] = 0;
388 v[3] = 0xff;
389 }
390
391 static void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v,
392 const GLfloat *in )
393 {
394 (void) a;
395 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
396 v[1] = 0;
397 v[0] = 0;
398 v[3] = 0xff;
399 }
400
401 static void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
402 const GLfloat *in )
403 {
404 (void) a;
405 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
406 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
407 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
408 }
409
410 static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
411 const GLfloat *in )
412 {
413 (void) a;
414 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
415 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
416 v[2] = 0;
417 }
418
419 static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
420 const GLfloat *in )
421 {
422 (void) a;
423 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
424 v[1] = 0;
425 v[2] = 0;
426 }
427
428 static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
429 const GLfloat *in )
430 {
431 (void) a;
432 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
433 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
434 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
435 }
436
437 static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
438 const GLfloat *in )
439 {
440 (void) a;
441 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
442 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
443 v[0] = 0;
444 }
445
446 static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
447 const GLfloat *in )
448 {
449 (void) a;
450 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
451 v[1] = 0;
452 v[0] = 0;
453 }
454
455
456 static void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v,
457 const GLfloat *in )
458 {
459 (void) a;
460 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
461 }
462
463
464 /***********************************************************************
465 * Functions to perform the reverse operations to the above, for
466 * swrast translation and clip-interpolation.
467 *
468 * Currently always extracts a full 4 floats.
469 */
470
471 static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
472 const GLubyte *v )
473 {
474 const GLfloat *in = (const GLfloat *)v;
475 const GLfloat * const vp = a->vp;
476
477 /* Although included for completeness, the position coordinate is
478 * usually handled differently during clipping.
479 */
480 out[0] = (in[0] - vp[12]) / vp[0];
481 out[1] = (in[1] - vp[13]) / vp[5];
482 out[2] = (in[2] - vp[14]) / vp[10];
483 out[3] = in[3];
484 }
485
486 static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
487 const GLubyte *v )
488 {
489 const GLfloat *in = (const GLfloat *)v;
490 const GLfloat * const vp = a->vp;
491
492 out[0] = (in[0] - vp[12]) / vp[0];
493 out[1] = (in[1] - vp[13]) / vp[5];
494 out[2] = (in[2] - vp[14]) / vp[10];
495 out[3] = 1;
496 }
497
498
499 static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
500 const GLubyte *v )
501 {
502 const GLfloat *in = (const GLfloat *)v;
503 const GLfloat * const vp = a->vp;
504
505 out[0] = (in[0] - vp[12]) / vp[0];
506 out[1] = (in[1] - vp[13]) / vp[5];
507 out[2] = 0;
508 out[3] = 1;
509 }
510
511
512 static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
513 {
514 const GLfloat *in = (const GLfloat *)v;
515 (void) a;
516
517 out[0] = in[0];
518 out[1] = in[1];
519 out[2] = in[2];
520 out[3] = in[3];
521 }
522
523 static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
524 {
525 const GLfloat *in = (const GLfloat *)v;
526 (void) a;
527
528 out[0] = in[0];
529 out[1] = in[1];
530 out[2] = 0;
531 out[3] = in[2];
532 }
533
534
535 static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
536 {
537 const GLfloat *in = (const GLfloat *)v;
538 (void) a;
539
540 out[0] = in[0];
541 out[1] = in[1];
542 out[2] = in[2];
543 out[3] = 1;
544 }
545
546
547 static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
548 {
549 const GLfloat *in = (const GLfloat *)v;
550 (void) a;
551
552 out[0] = in[0];
553 out[1] = in[1];
554 out[2] = 0;
555 out[3] = 1;
556 }
557
558 static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
559 {
560 const GLfloat *in = (const GLfloat *)v;
561 (void) a;
562
563 out[0] = in[0];
564 out[1] = 0;
565 out[2] = 0;
566 out[3] = 1;
567 }
568
569 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
570 const GLubyte *v )
571 {
572 GLchan *c = (GLchan *)v;
573 (void) a;
574
575 out[0] = CHAN_TO_FLOAT(c[0]);
576 out[1] = CHAN_TO_FLOAT(c[1]);
577 out[2] = CHAN_TO_FLOAT(c[2]);
578 out[3] = CHAN_TO_FLOAT(c[3]);
579 }
580
581 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
582 const GLubyte *v )
583 {
584 (void) a;
585 out[0] = UBYTE_TO_FLOAT(v[0]);
586 out[1] = UBYTE_TO_FLOAT(v[1]);
587 out[2] = UBYTE_TO_FLOAT(v[2]);
588 out[3] = UBYTE_TO_FLOAT(v[3]);
589 }
590
591 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out,
592 const GLubyte *v )
593 {
594 (void) a;
595 out[2] = UBYTE_TO_FLOAT(v[0]);
596 out[1] = UBYTE_TO_FLOAT(v[1]);
597 out[0] = UBYTE_TO_FLOAT(v[2]);
598 out[3] = UBYTE_TO_FLOAT(v[3]);
599 }
600
601 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out,
602 const GLubyte *v )
603 {
604 (void) a;
605 out[0] = UBYTE_TO_FLOAT(v[0]);
606 out[1] = UBYTE_TO_FLOAT(v[1]);
607 out[2] = UBYTE_TO_FLOAT(v[2]);
608 out[3] = 1;
609 }
610
611 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out,
612 const GLubyte *v )
613 {
614 (void) a;
615 out[2] = UBYTE_TO_FLOAT(v[0]);
616 out[1] = UBYTE_TO_FLOAT(v[1]);
617 out[0] = UBYTE_TO_FLOAT(v[2]);
618 out[3] = 1;
619 }
620
621 static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
622 {
623 (void) a;
624 out[0] = UBYTE_TO_FLOAT(v[0]);
625 out[1] = 0;
626 out[2] = 0;
627 out[3] = 1;
628 }
629
630
631 static struct {
632 const char *name;
633 tnl_extract_func extract;
634 tnl_insert_func insert[4];
635 const GLuint attrsize;
636 } format_info[EMIT_MAX] = {
637
638 { "1f",
639 extract_1f,
640 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
641 sizeof(GLfloat) },
642
643 { "2f",
644 extract_2f,
645 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
646 2 * sizeof(GLfloat) },
647
648 { "3f",
649 extract_3f,
650 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
651 3 * sizeof(GLfloat) },
652
653 { "4f",
654 extract_4f,
655 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
656 4 * sizeof(GLfloat) },
657
658 { "2f_viewport",
659 extract_2f_viewport,
660 { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
661 insert_2f_viewport_2 },
662 2 * sizeof(GLfloat) },
663
664 { "3f_viewport",
665 extract_3f_viewport,
666 { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
667 insert_3f_viewport_3 },
668 3 * sizeof(GLfloat) },
669
670 { "4f_viewport",
671 extract_4f_viewport,
672 { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
673 insert_4f_viewport_4 },
674 4 * sizeof(GLfloat) },
675
676 { "3f_xyw",
677 extract_3f_xyw,
678 { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
679 insert_3f_xyw_4 },
680 3 * sizeof(GLfloat) },
681
682 { "1ub_1f",
683 extract_1ub_1f,
684 { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
685 sizeof(GLubyte) },
686
687 { "3ub_3f_rgb",
688 extract_3ub_3f_rgb,
689 { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
690 insert_3ub_3f_rgb_3 },
691 3 * sizeof(GLubyte) },
692
693 { "3ub_3f_bgr",
694 extract_3ub_3f_bgr,
695 { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
696 insert_3ub_3f_bgr_3 },
697 3 * sizeof(GLubyte) },
698
699 { "4ub_4f_rgba",
700 extract_4ub_4f_rgba,
701 { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3,
702 insert_4ub_4f_rgba_4 },
703 4 * sizeof(GLubyte) },
704
705 { "4ub_4f_bgra",
706 extract_4ub_4f_bgra,
707 { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
708 insert_4ub_4f_bgra_4 },
709 4 * sizeof(GLubyte) },
710
711 { "4chan_4f_rgba",
712 extract_4chan_4f_rgba,
713 { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
714 insert_4chan_4f_rgba_4 },
715 4 * sizeof(GLchan) },
716
717 { "pad",
718 0,
719 { 0, 0, 0, 0 },
720 0 }
721
722 };
723
724
725 /***********************************************************************
726 * Generic (non-codegen) functions for whole vertices or groups of
727 * vertices
728 */
729
730 static void generic_emit( GLcontext *ctx,
731 GLuint start, GLuint end,
732 void *dest )
733 {
734 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
735 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
736 struct tnl_clipspace_attr *a = vtx->attr;
737 GLubyte *v = (GLubyte *)dest;
738 GLuint i, j;
739 const GLuint count = vtx->attr_count;
740 GLuint stride;
741
742 for (j = 0; j < count; j++) {
743 GLvector4f *vptr = VB->AttribPtr[a[j].attrib];
744 a[j].inputstride = vptr->stride;
745 a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
746 a[j].emit = a[j].insert[vptr->size - 1];
747 }
748
749 end -= start;
750 stride = vtx->vertex_size;
751
752 for (i = 0 ; i < end ; i++, v += stride) {
753 for (j = 0; j < count; j++) {
754 GLfloat *in = (GLfloat *)a[j].inputptr;
755 a[j].inputptr += a[j].inputstride;
756 a[j].emit( &a[j], v + a[j].vertoffset, in );
757 }
758 }
759 }
760
761
762 static void generic_interp( GLcontext *ctx,
763 GLfloat t,
764 GLuint edst, GLuint eout, GLuint ein,
765 GLboolean force_boundary )
766 {
767 TNLcontext *tnl = TNL_CONTEXT(ctx);
768 struct vertex_buffer *VB = &tnl->vb;
769 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
770 const GLubyte *vin = vtx->vertex_buf + ein * vtx->vertex_size;
771 const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
772 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
773 const struct tnl_clipspace_attr *a = vtx->attr;
774 const GLuint attr_count = vtx->attr_count;
775 GLuint j;
776 (void) force_boundary;
777
778 if (tnl->NeedNdcCoords) {
779 const GLfloat *dstclip = VB->ClipPtr->data[edst];
780 if (dstclip[3] != 0.0) {
781 const GLfloat w = 1.0f / dstclip[3];
782 GLfloat pos[4];
783
784 pos[0] = dstclip[0] * w;
785 pos[1] = dstclip[1] * w;
786 pos[2] = dstclip[2] * w;
787 pos[3] = w;
788
789 a[0].insert[4-1]( &a[0], vdst, pos );
790 }
791 }
792 else {
793 a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
794 }
795
796
797 for (j = 1; j < attr_count; j++) {
798 GLfloat fin[4], fout[4], fdst[4];
799
800 a[j].extract( &a[j], fin, vin + a[j].vertoffset );
801 a[j].extract( &a[j], fout, vout + a[j].vertoffset );
802
803 INTERP_F( t, fdst[3], fout[3], fin[3] );
804 INTERP_F( t, fdst[2], fout[2], fin[2] );
805 INTERP_F( t, fdst[1], fout[1], fin[1] );
806 INTERP_F( t, fdst[0], fout[0], fin[0] );
807
808 a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
809 }
810 }
811
812
813 /* Extract color attributes from one vertex and insert them into
814 * another. (Shortcircuit extract/insert with memcpy).
815 */
816 static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
817 {
818 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
819 GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
820 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
821 const struct tnl_clipspace_attr *a = vtx->attr;
822 const GLuint attr_count = vtx->attr_count;
823 GLuint j;
824
825 for (j = 0; j < attr_count; j++) {
826 if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
827 a[j].attrib == VERT_ATTRIB_COLOR1) {
828
829 _mesa_memcpy( vdst + a[j].vertoffset,
830 vsrc + a[j].vertoffset,
831 a[j].vertattrsize );
832 }
833 }
834 }
835
836
837 /* Helper functions for hardware which doesn't put back colors and/or
838 * edgeflags into vertices.
839 */
840 static void generic_interp_extras( GLcontext *ctx,
841 GLfloat t,
842 GLuint dst, GLuint out, GLuint in,
843 GLboolean force_boundary )
844 {
845 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
846
847 if (VB->ColorPtr[1]) {
848 assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
849
850 INTERP_4F( t,
851 VB->ColorPtr[1]->data[dst],
852 VB->ColorPtr[1]->data[out],
853 VB->ColorPtr[1]->data[in] );
854
855 if (VB->SecondaryColorPtr[1]) {
856 INTERP_3F( t,
857 VB->SecondaryColorPtr[1]->data[dst],
858 VB->SecondaryColorPtr[1]->data[out],
859 VB->SecondaryColorPtr[1]->data[in] );
860 }
861 }
862 else if (VB->IndexPtr[1]) {
863 VB->IndexPtr[1]->data[dst][0] = LINTERP( t,
864 VB->IndexPtr[1]->data[out][0],
865 VB->IndexPtr[1]->data[in][0] );
866 }
867
868 if (VB->EdgeFlag) {
869 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
870 }
871
872 generic_interp(ctx, t, dst, out, in, force_boundary);
873 }
874
875 static void generic_copy_pv_extras( GLcontext *ctx,
876 GLuint dst, GLuint src )
877 {
878 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
879
880 if (VB->ColorPtr[1]) {
881 COPY_4FV( VB->ColorPtr[1]->data[dst],
882 VB->ColorPtr[1]->data[src] );
883
884 if (VB->SecondaryColorPtr[1]) {
885 COPY_4FV( VB->SecondaryColorPtr[1]->data[dst],
886 VB->SecondaryColorPtr[1]->data[src] );
887 }
888 }
889 else if (VB->IndexPtr[1]) {
890 VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
891 }
892
893 generic_copy_pv(ctx, dst, src);
894 }
895
896
897
898
899 /***********************************************************************
900 * Build codegen functions or return generic ones:
901 */
902
903
904 static void do_emit( GLcontext *ctx, GLuint start, GLuint end,
905 void *dest)
906 {
907 TNLcontext *tnl = TNL_CONTEXT(ctx);
908 struct vertex_buffer *VB = &tnl->vb;
909 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
910 struct tnl_clipspace_attr *a = vtx->attr;
911 const GLuint count = vtx->attr_count;
912 GLuint j;
913
914 for (j = 0; j < count; j++) {
915 GLvector4f *vptr = VB->AttribPtr[a[j].attrib];
916 a[j].inputstride = vptr->stride;
917 a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
918 a[j].emit = a[j].insert[vptr->size - 1];
919 }
920
921 vtx->emit = 0;
922
923 if (0)
924 vtx->emit = _tnl_codegen_emit(ctx);
925
926 if (!vtx->emit)
927 vtx->emit = generic_emit;
928
929 vtx->emit( ctx, start, end, dest );
930 }
931
932
933
934 static void choose_interp_func( GLcontext *ctx,
935 GLfloat t,
936 GLuint edst, GLuint eout, GLuint ein,
937 GLboolean force_boundary )
938 {
939 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
940
941 if (vtx->need_extras &&
942 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
943 vtx->interp = generic_interp_extras;
944 } else {
945 vtx->interp = generic_interp;
946 }
947
948 vtx->interp( ctx, t, edst, eout, ein, force_boundary );
949 }
950
951
952 static void choose_copy_pv_func( GLcontext *ctx, GLuint edst, GLuint esrc )
953 {
954 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
955
956 if (vtx->need_extras &&
957 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
958 vtx->copy_pv = generic_copy_pv_extras;
959 } else {
960 vtx->copy_pv = generic_copy_pv;
961 }
962
963 vtx->copy_pv( ctx, edst, esrc );
964 }
965
966
967 /***********************************************************************
968 * Public entrypoints, mostly dispatch to the above:
969 */
970
971
972 /* Interpolate between two vertices to produce a third:
973 */
974 void _tnl_interp( GLcontext *ctx,
975 GLfloat t,
976 GLuint edst, GLuint eout, GLuint ein,
977 GLboolean force_boundary )
978 {
979 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
980 vtx->interp( ctx, t, edst, eout, ein, force_boundary );
981 }
982
983 /* Copy colors from one vertex to another:
984 */
985 void _tnl_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
986 {
987 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
988 vtx->copy_pv( ctx, edst, esrc );
989 }
990
991
992 /* Extract a named attribute from a hardware vertex. Will have to
993 * reverse any viewport transformation, swizzling or other conversions
994 * which may have been applied:
995 */
996 void _tnl_get_attr( GLcontext *ctx, const void *vin,
997 GLenum attr, GLfloat *dest )
998 {
999 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1000 const struct tnl_clipspace_attr *a = vtx->attr;
1001 const GLuint attr_count = vtx->attr_count;
1002 GLuint j;
1003
1004 for (j = 0; j < attr_count; j++) {
1005 if (a[j].attrib == attr) {
1006 a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset );
1007 return;
1008 }
1009 }
1010
1011 /* Else return the value from ctx->Current -- dangerous???
1012 */
1013 _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
1014 }
1015
1016
1017 /* Complementary operation to the above.
1018 */
1019 void _tnl_set_attr( GLcontext *ctx, void *vout,
1020 GLenum attr, const GLfloat *src )
1021 {
1022 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1023 const struct tnl_clipspace_attr *a = vtx->attr;
1024 const GLuint attr_count = vtx->attr_count;
1025 GLuint j;
1026
1027 for (j = 0; j < attr_count; j++) {
1028 if (a[j].attrib == attr) {
1029 a[j].insert[4-1]( &a[j], (GLubyte *)vout + a[j].vertoffset, src );
1030 return;
1031 }
1032 }
1033 }
1034
1035
1036 void *_tnl_get_vertex( GLcontext *ctx, GLuint nr )
1037 {
1038 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1039
1040 return vtx->vertex_buf + nr * vtx->vertex_size;
1041 }
1042
1043 void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state )
1044 {
1045 if (new_state & (_DD_NEW_TRI_LIGHT_TWOSIDE|_DD_NEW_TRI_UNFILLED) ) {
1046 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1047 vtx->new_inputs = ~0;
1048 vtx->interp = choose_interp_func;
1049 vtx->copy_pv = choose_copy_pv_func;
1050 }
1051 }
1052
1053
1054 GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map,
1055 GLuint nr, const GLfloat *vp,
1056 GLuint unpacked_size )
1057 {
1058 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1059 GLuint offset = 0;
1060 GLuint i, j;
1061
1062 assert(nr < _TNL_ATTRIB_MAX);
1063 assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);
1064
1065 vtx->emit = 0;
1066 vtx->interp = choose_interp_func;
1067 vtx->copy_pv = choose_copy_pv_func;
1068 vtx->new_inputs = ~0;
1069
1070 for (j = 0, i = 0; i < nr; i++) {
1071 const GLuint format = map[i].format;
1072 if (format == EMIT_PAD) {
1073 /*
1074 fprintf(stderr, "%d: pad %d, offset %d\n", i,
1075 map[i].offset, offset);
1076 */
1077 offset += map[i].offset;
1078
1079 }
1080 else {
1081 vtx->attr[j].attrib = map[i].attrib;
1082 vtx->attr[j].format = format;
1083 vtx->attr[j].vp = vp;
1084 vtx->attr[j].insert = format_info[format].insert;
1085 vtx->attr[j].extract = format_info[format].extract;
1086 vtx->attr[j].vertattrsize = format_info[format].attrsize;
1087
1088 if (unpacked_size)
1089 vtx->attr[j].vertoffset = map[i].offset;
1090 else
1091 vtx->attr[j].vertoffset = offset;
1092
1093 /*
1094 fprintf(stderr, "%d: %s, vp %p, offset %d\n", i,
1095 format_info[format].name, (void *)vp,
1096 vtx->attr[j].vertoffset);
1097 */
1098 offset += format_info[format].attrsize;
1099 j++;
1100 }
1101 }
1102
1103 vtx->attr_count = j;
1104
1105 if (unpacked_size)
1106 vtx->vertex_size = unpacked_size;
1107 else
1108 vtx->vertex_size = offset;
1109
1110 assert(vtx->vertex_size <= vtx->max_vertex_size);
1111
1112 return vtx->vertex_size;
1113 }
1114
1115
1116
1117 void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs )
1118 {
1119 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1120 vtx->new_inputs |= newinputs;
1121 }
1122
1123
1124 void _tnl_build_vertices( GLcontext *ctx,
1125 GLuint start,
1126 GLuint end,
1127 GLuint newinputs )
1128 {
1129 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1130 const GLuint stride = vtx->vertex_size;
1131 GLubyte *vDest = ((GLubyte *)vtx->vertex_buf + (start*stride));
1132
1133 newinputs |= vtx->new_inputs;
1134 vtx->new_inputs = 0;
1135
1136 if (newinputs)
1137 do_emit( ctx, start, end, vDest );
1138 }
1139
1140
1141 void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
1142 GLuint start,
1143 GLuint end,
1144 void *dest )
1145 {
1146 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1147 do_emit( ctx, start, end, dest );
1148 return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start));
1149 }
1150
1151
1152 void _tnl_init_vertices( GLcontext *ctx,
1153 GLuint vb_size,
1154 GLuint max_vertex_size )
1155 {
1156 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1157
1158 _tnl_install_attrs( ctx, 0, 0, 0, 0 );
1159
1160 vtx->need_extras = GL_TRUE;
1161 if (max_vertex_size > vtx->max_vertex_size) {
1162 _tnl_free_vertices( ctx );
1163 vtx->max_vertex_size = max_vertex_size;
1164 vtx->vertex_buf = (GLubyte *)ALIGN_CALLOC(vb_size * max_vertex_size, 32 );
1165 }
1166
1167 _tnl_init_c_codegen( &vtx->codegen );
1168 }
1169
1170
1171 void _tnl_free_vertices( GLcontext *ctx )
1172 {
1173 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1174 if (vtx->vertex_buf) {
1175 ALIGN_FREE(vtx->vertex_buf);
1176 vtx->vertex_buf = 0;
1177 }
1178 }