r200 driver, brought over by Jon Smirl
[mesa.git] / src / mesa / drivers / dri / r200 / r200_vtxfmt_c.c
1 /* $XFree86$ */
2 /**************************************************************************
3
4 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
9
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 /*
33 * Authors:
34 * Keith Whitwell <keith@tungstengraphics.com>
35 */
36
37 #include "glheader.h"
38 #include "imports.h"
39 #include "mtypes.h"
40 #include "colormac.h"
41 #include "simple_list.h"
42 #include "api_noop.h"
43 #include "vtxfmt.h"
44
45 #include "r200_vtxfmt.h"
46
47 /* Fallback versions of all the entrypoints for situations where
48 * codegen isn't available. This is still a lot faster than the
49 * vb/pipeline implementation in Mesa.
50 */
51 static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
52 {
53 GET_CURRENT_CONTEXT(ctx);
54 r200ContextPtr rmesa = R200_CONTEXT(ctx);
55 int i;
56
57 *rmesa->vb.dmaptr++ = *(int *)&x;
58 *rmesa->vb.dmaptr++ = *(int *)&y;
59 *rmesa->vb.dmaptr++ = *(int *)&z;
60
61 for (i = 3; i < rmesa->vb.vertex_size; i++)
62 *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
63
64 if (--rmesa->vb.counter == 0)
65 rmesa->vb.notify();
66 }
67
68
69 static void r200_Vertex3fv( const GLfloat *v )
70 {
71 GET_CURRENT_CONTEXT(ctx);
72 r200ContextPtr rmesa = R200_CONTEXT(ctx);
73 int i;
74
75 *rmesa->vb.dmaptr++ = *(int *)&v[0];
76 *rmesa->vb.dmaptr++ = *(int *)&v[1];
77 *rmesa->vb.dmaptr++ = *(int *)&v[2];
78
79 for (i = 3; i < rmesa->vb.vertex_size; i++)
80 *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
81
82 if (--rmesa->vb.counter == 0)
83 rmesa->vb.notify();
84 }
85
86
87 static void r200_Vertex2f( GLfloat x, GLfloat y )
88 {
89 GET_CURRENT_CONTEXT(ctx);
90 r200ContextPtr rmesa = R200_CONTEXT(ctx);
91 int i;
92
93 *rmesa->vb.dmaptr++ = *(int *)&x;
94 *rmesa->vb.dmaptr++ = *(int *)&y;
95 *rmesa->vb.dmaptr++ = 0;
96
97 for (i = 3; i < rmesa->vb.vertex_size; i++)
98 *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
99
100 if (--rmesa->vb.counter == 0)
101 rmesa->vb.notify();
102 }
103
104
105 static void r200_Vertex2fv( const GLfloat *v )
106 {
107 GET_CURRENT_CONTEXT(ctx);
108 r200ContextPtr rmesa = R200_CONTEXT(ctx);
109 int i;
110
111 *rmesa->vb.dmaptr++ = *(int *)&v[0];
112 *rmesa->vb.dmaptr++ = *(int *)&v[1];
113 *rmesa->vb.dmaptr++ = 0;
114
115 for (i = 3; i < rmesa->vb.vertex_size; i++)
116 *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i;
117
118 if (--rmesa->vb.counter == 0)
119 rmesa->vb.notify();
120 }
121
122
123
124 /* Color for ubyte (packed) color formats:
125 */
126 static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b )
127 {
128 GET_CURRENT_CONTEXT(ctx);
129 r200ContextPtr rmesa = R200_CONTEXT(ctx);
130 r200_color_t *dest = rmesa->vb.colorptr;
131 dest->red = r;
132 dest->green = g;
133 dest->blue = b;
134 dest->alpha = 0xff;
135 }
136
137 static void r200_Color3ubv_ub( const GLubyte *v )
138 {
139 GET_CURRENT_CONTEXT(ctx);
140 r200ContextPtr rmesa = R200_CONTEXT(ctx);
141 r200_color_t *dest = rmesa->vb.colorptr;
142 dest->red = v[0];
143 dest->green = v[1];
144 dest->blue = v[2];
145 dest->alpha = 0xff;
146 }
147
148 static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
149 {
150 GET_CURRENT_CONTEXT(ctx);
151 r200ContextPtr rmesa = R200_CONTEXT(ctx);
152 r200_color_t *dest = rmesa->vb.colorptr;
153 dest->red = r;
154 dest->green = g;
155 dest->blue = b;
156 dest->alpha = a;
157 }
158
159 static void r200_Color4ubv_ub( const GLubyte *v )
160 {
161 GET_CURRENT_CONTEXT(ctx);
162 r200ContextPtr rmesa = R200_CONTEXT(ctx);
163 *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v);
164 }
165
166
167 static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b )
168 {
169 GET_CURRENT_CONTEXT(ctx);
170 r200ContextPtr rmesa = R200_CONTEXT(ctx);
171 r200_color_t *dest = rmesa->vb.colorptr;
172 UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
173 UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
174 UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
175 dest->alpha = 255;
176 }
177
178 static void r200_Color3fv_ub( const GLfloat *v )
179 {
180 GET_CURRENT_CONTEXT(ctx);
181 r200ContextPtr rmesa = R200_CONTEXT(ctx);
182 r200_color_t *dest = rmesa->vb.colorptr;
183 UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
184 UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
185 UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
186 dest->alpha = 255;
187 }
188
189 static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
190 {
191 GET_CURRENT_CONTEXT(ctx);
192 r200ContextPtr rmesa = R200_CONTEXT(ctx);
193 r200_color_t *dest = rmesa->vb.colorptr;
194 UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
195 UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
196 UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
197 UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a );
198 }
199
200 static void r200_Color4fv_ub( const GLfloat *v )
201 {
202 GET_CURRENT_CONTEXT(ctx);
203 r200ContextPtr rmesa = R200_CONTEXT(ctx);
204 r200_color_t *dest = rmesa->vb.colorptr;
205 UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
206 UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
207 UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
208 UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] );
209 }
210
211
212 /* Color for float color+alpha formats:
213 */
214 static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b )
215 {
216 GET_CURRENT_CONTEXT(ctx);
217 r200ContextPtr rmesa = R200_CONTEXT(ctx);
218 GLfloat *dest = rmesa->vb.floatcolorptr;
219 dest[0] = UBYTE_TO_FLOAT(r);
220 dest[1] = UBYTE_TO_FLOAT(g);
221 dest[2] = UBYTE_TO_FLOAT(b);
222 dest[3] = 1.0;
223 }
224
225 static void r200_Color3ubv_4f( const GLubyte *v )
226 {
227 GET_CURRENT_CONTEXT(ctx);
228 r200ContextPtr rmesa = R200_CONTEXT(ctx);
229 GLfloat *dest = rmesa->vb.floatcolorptr;
230 dest[0] = UBYTE_TO_FLOAT(v[0]);
231 dest[1] = UBYTE_TO_FLOAT(v[1]);
232 dest[2] = UBYTE_TO_FLOAT(v[2]);
233 dest[3] = 1.0;
234 }
235
236 static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
237 {
238 GET_CURRENT_CONTEXT(ctx);
239 r200ContextPtr rmesa = R200_CONTEXT(ctx);
240 GLfloat *dest = rmesa->vb.floatcolorptr;
241 dest[0] = UBYTE_TO_FLOAT(r);
242 dest[1] = UBYTE_TO_FLOAT(g);
243 dest[2] = UBYTE_TO_FLOAT(b);
244 dest[3] = UBYTE_TO_FLOAT(a);
245 }
246
247 static void r200_Color4ubv_4f( const GLubyte *v )
248 {
249 GET_CURRENT_CONTEXT(ctx);
250 r200ContextPtr rmesa = R200_CONTEXT(ctx);
251 GLfloat *dest = rmesa->vb.floatcolorptr;
252 dest[0] = UBYTE_TO_FLOAT(v[0]);
253 dest[1] = UBYTE_TO_FLOAT(v[1]);
254 dest[2] = UBYTE_TO_FLOAT(v[2]);
255 dest[3] = UBYTE_TO_FLOAT(v[3]);
256 }
257
258
259 static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b )
260 {
261 GET_CURRENT_CONTEXT(ctx);
262 r200ContextPtr rmesa = R200_CONTEXT(ctx);
263 GLfloat *dest = rmesa->vb.floatcolorptr;
264 dest[0] = r;
265 dest[1] = g;
266 dest[2] = b;
267 dest[3] = 1.0;
268 }
269
270 static void r200_Color3fv_4f( const GLfloat *v )
271 {
272 GET_CURRENT_CONTEXT(ctx);
273 r200ContextPtr rmesa = R200_CONTEXT(ctx);
274 GLfloat *dest = rmesa->vb.floatcolorptr;
275 dest[0] = v[0];
276 dest[1] = v[1];
277 dest[2] = v[2];
278 dest[3] = 1.0;
279 }
280
281 static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
282 {
283 GET_CURRENT_CONTEXT(ctx);
284 r200ContextPtr rmesa = R200_CONTEXT(ctx);
285 GLfloat *dest = rmesa->vb.floatcolorptr;
286 dest[0] = r;
287 dest[1] = g;
288 dest[2] = b;
289 dest[3] = a;
290 }
291
292 static void r200_Color4fv_4f( const GLfloat *v )
293 {
294 GET_CURRENT_CONTEXT(ctx);
295 r200ContextPtr rmesa = R200_CONTEXT(ctx);
296 GLfloat *dest = rmesa->vb.floatcolorptr;
297 dest[0] = v[0];
298 dest[1] = v[1];
299 dest[2] = v[2];
300 dest[3] = v[3];
301 }
302
303
304 /* Color for float color formats:
305 */
306 static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b )
307 {
308 GET_CURRENT_CONTEXT(ctx);
309 r200ContextPtr rmesa = R200_CONTEXT(ctx);
310 GLfloat *dest = rmesa->vb.floatcolorptr;
311 dest[0] = UBYTE_TO_FLOAT(r);
312 dest[1] = UBYTE_TO_FLOAT(g);
313 dest[2] = UBYTE_TO_FLOAT(b);
314 }
315
316 static void r200_Color3ubv_3f( const GLubyte *v )
317 {
318 GET_CURRENT_CONTEXT(ctx);
319 r200ContextPtr rmesa = R200_CONTEXT(ctx);
320 GLfloat *dest = rmesa->vb.floatcolorptr;
321 dest[0] = UBYTE_TO_FLOAT(v[0]);
322 dest[1] = UBYTE_TO_FLOAT(v[1]);
323 dest[2] = UBYTE_TO_FLOAT(v[2]);
324 }
325
326 static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
327 {
328 GET_CURRENT_CONTEXT(ctx);
329 r200ContextPtr rmesa = R200_CONTEXT(ctx);
330 GLfloat *dest = rmesa->vb.floatcolorptr;
331 dest[0] = UBYTE_TO_FLOAT(r);
332 dest[1] = UBYTE_TO_FLOAT(g);
333 dest[2] = UBYTE_TO_FLOAT(b);
334 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a);
335 }
336
337 static void r200_Color4ubv_3f( const GLubyte *v )
338 {
339 GET_CURRENT_CONTEXT(ctx);
340 r200ContextPtr rmesa = R200_CONTEXT(ctx);
341 GLfloat *dest = rmesa->vb.floatcolorptr;
342 dest[0] = UBYTE_TO_FLOAT(v[0]);
343 dest[1] = UBYTE_TO_FLOAT(v[1]);
344 dest[2] = UBYTE_TO_FLOAT(v[2]);
345 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]);
346 }
347
348
349 static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b )
350 {
351 GET_CURRENT_CONTEXT(ctx);
352 r200ContextPtr rmesa = R200_CONTEXT(ctx);
353 GLfloat *dest = rmesa->vb.floatcolorptr;
354 dest[0] = r;
355 dest[1] = g;
356 dest[2] = b;
357 }
358
359 static void r200_Color3fv_3f( const GLfloat *v )
360 {
361 GET_CURRENT_CONTEXT(ctx);
362 r200ContextPtr rmesa = R200_CONTEXT(ctx);
363 GLfloat *dest = rmesa->vb.floatcolorptr;
364 dest[0] = v[0];
365 dest[1] = v[1];
366 dest[2] = v[2];
367 }
368
369 static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
370 {
371 GET_CURRENT_CONTEXT(ctx);
372 r200ContextPtr rmesa = R200_CONTEXT(ctx);
373 GLfloat *dest = rmesa->vb.floatcolorptr;
374 dest[0] = r;
375 dest[1] = g;
376 dest[2] = b;
377 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a;
378 }
379
380 static void r200_Color4fv_3f( const GLfloat *v )
381 {
382 GET_CURRENT_CONTEXT(ctx);
383 r200ContextPtr rmesa = R200_CONTEXT(ctx);
384 GLfloat *dest = rmesa->vb.floatcolorptr;
385 dest[0] = v[0];
386 dest[1] = v[1];
387 dest[2] = v[2];
388 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3];
389 }
390
391
392 /* Secondary Color:
393 */
394 static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b )
395 {
396 GET_CURRENT_CONTEXT(ctx);
397 r200ContextPtr rmesa = R200_CONTEXT(ctx);
398 r200_color_t *dest = rmesa->vb.specptr;
399 dest->red = r;
400 dest->green = g;
401 dest->blue = b;
402 dest->alpha = 0xff;
403 }
404
405 static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v )
406 {
407 GET_CURRENT_CONTEXT(ctx);
408 r200ContextPtr rmesa = R200_CONTEXT(ctx);
409 r200_color_t *dest = rmesa->vb.specptr;
410 dest->red = v[0];
411 dest->green = v[1];
412 dest->blue = v[2];
413 dest->alpha = 0xff;
414 }
415
416 static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b )
417 {
418 GET_CURRENT_CONTEXT(ctx);
419 r200ContextPtr rmesa = R200_CONTEXT(ctx);
420 r200_color_t *dest = rmesa->vb.specptr;
421 UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r );
422 UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g );
423 UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b );
424 dest->alpha = 255;
425 }
426
427 static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v )
428 {
429 GET_CURRENT_CONTEXT(ctx);
430 r200ContextPtr rmesa = R200_CONTEXT(ctx);
431 r200_color_t *dest = rmesa->vb.specptr;
432 UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] );
433 UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] );
434 UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] );
435 dest->alpha = 255;
436 }
437
438 static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b )
439 {
440 GET_CURRENT_CONTEXT(ctx);
441 r200ContextPtr rmesa = R200_CONTEXT(ctx);
442 GLfloat *dest = rmesa->vb.floatspecptr;
443 dest[0] = UBYTE_TO_FLOAT(r);
444 dest[1] = UBYTE_TO_FLOAT(g);
445 dest[2] = UBYTE_TO_FLOAT(b);
446 dest[3] = 1.0;
447 }
448
449 static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v )
450 {
451 GET_CURRENT_CONTEXT(ctx);
452 r200ContextPtr rmesa = R200_CONTEXT(ctx);
453 GLfloat *dest = rmesa->vb.floatspecptr;
454 dest[0] = UBYTE_TO_FLOAT(v[0]);
455 dest[1] = UBYTE_TO_FLOAT(v[1]);
456 dest[2] = UBYTE_TO_FLOAT(v[2]);
457 dest[3] = 1.0;
458 }
459
460 static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b )
461 {
462 GET_CURRENT_CONTEXT(ctx);
463 r200ContextPtr rmesa = R200_CONTEXT(ctx);
464 GLfloat *dest = rmesa->vb.floatspecptr;
465 dest[0] = r;
466 dest[1] = g;
467 dest[2] = b;
468 dest[3] = 1.0;
469 }
470
471 static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v )
472 {
473 GET_CURRENT_CONTEXT(ctx);
474 r200ContextPtr rmesa = R200_CONTEXT(ctx);
475 GLfloat *dest = rmesa->vb.floatspecptr;
476 dest[0] = v[0];
477 dest[1] = v[1];
478 dest[2] = v[2];
479 dest[3] = 1.0;
480 }
481
482
483
484 /* Normal
485 */
486 static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
487 {
488 GET_CURRENT_CONTEXT(ctx);
489 r200ContextPtr rmesa = R200_CONTEXT(ctx);
490 GLfloat *dest = rmesa->vb.normalptr;
491 dest[0] = n0;
492 dest[1] = n1;
493 dest[2] = n2;
494 }
495
496 static void r200_Normal3fv( const GLfloat *v )
497 {
498 GET_CURRENT_CONTEXT(ctx);
499 r200ContextPtr rmesa = R200_CONTEXT(ctx);
500 GLfloat *dest = rmesa->vb.normalptr;
501 dest[0] = v[0];
502 dest[1] = v[1];
503 dest[2] = v[2];
504 }
505
506
507 /* TexCoord
508 */
509 static void r200_TexCoord1f( GLfloat s )
510 {
511 GET_CURRENT_CONTEXT(ctx);
512 r200ContextPtr rmesa = R200_CONTEXT(ctx);
513 GLfloat *dest = rmesa->vb.texcoordptr[0];
514 dest[0] = s;
515 dest[1] = 0;
516 }
517
518 static void r200_TexCoord1fv( const GLfloat *v )
519 {
520 GET_CURRENT_CONTEXT(ctx);
521 r200ContextPtr rmesa = R200_CONTEXT(ctx);
522 GLfloat *dest = rmesa->vb.texcoordptr[0];
523 dest[0] = v[0];
524 dest[1] = 0;
525 }
526
527 static void r200_TexCoord2f( GLfloat s, GLfloat t )
528 {
529 GET_CURRENT_CONTEXT(ctx);
530 r200ContextPtr rmesa = R200_CONTEXT(ctx);
531 GLfloat *dest = rmesa->vb.texcoordptr[0];
532 dest[0] = s;
533 dest[1] = t;
534 }
535
536 static void r200_TexCoord2fv( const GLfloat *v )
537 {
538 GET_CURRENT_CONTEXT(ctx);
539 r200ContextPtr rmesa = R200_CONTEXT(ctx);
540 GLfloat *dest = rmesa->vb.texcoordptr[0];
541 dest[0] = v[0];
542 dest[1] = v[1];
543 }
544
545
546 /* MultiTexcoord
547 *
548 * Technically speaking, these functions should subtract GL_TEXTURE0 from
549 * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0,
550 * which has the low-order 5 bits 0. For all possible valid values of
551 * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target
552 * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so
553 * the subtraction has been omitted.
554 */
555
556 static void r200_MultiTexCoord1fARB( GLenum target, GLfloat s )
557 {
558 GET_CURRENT_CONTEXT(ctx);
559 r200ContextPtr rmesa = R200_CONTEXT(ctx);
560 GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
561 dest[0] = s;
562 dest[1] = 0;
563 }
564
565 static void r200_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
566 {
567 GET_CURRENT_CONTEXT(ctx);
568 r200ContextPtr rmesa = R200_CONTEXT(ctx);
569 GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
570 dest[0] = v[0];
571 dest[1] = 0;
572 }
573
574 static void r200_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
575 {
576 GET_CURRENT_CONTEXT(ctx);
577 r200ContextPtr rmesa = R200_CONTEXT(ctx);
578 GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
579 dest[0] = s;
580 dest[1] = t;
581 }
582
583 static void r200_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
584 {
585 GET_CURRENT_CONTEXT(ctx);
586 r200ContextPtr rmesa = R200_CONTEXT(ctx);
587 GLfloat *dest = rmesa->vb.texcoordptr[target & 1];
588 dest[0] = v[0];
589 dest[1] = v[1];
590 }
591
592 static struct dynfn *lookup( struct dynfn *l, const int *key )
593 {
594 struct dynfn *f;
595
596 foreach( f, l ) {
597 if (f->key[0] == key[0] && f->key[1] == key[1])
598 return f;
599 }
600
601 return 0;
602 }
603
604 /* Can't use the loopback template for this:
605 */
606
607 #define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
608 static void choose_##FN ARGS1 \
609 { \
610 GET_CURRENT_CONTEXT(ctx); \
611 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
612 int key[2]; \
613 struct dynfn *dfn; \
614 \
615 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
616 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
617 \
618 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
619 if (dfn == 0) \
620 dfn = rmesa->vb.codegen.FN( ctx, key ); \
621 else if (R200_DEBUG & DEBUG_CODEGEN) \
622 fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
623 \
624 if (dfn) \
625 ctx->Exec->FN = (FNTYPE)(dfn->code); \
626 else { \
627 if (R200_DEBUG & DEBUG_CODEGEN) \
628 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
629 ctx->Exec->FN = r200_##FN; \
630 } \
631 \
632 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
633 ctx->Exec->FN ARGS2; \
634 }
635
636
637
638 /* For the _3f case, only allow one color function to be hooked in at
639 * a time. Eventually, use a similar mechanism to allow selecting the
640 * color component of the vertex format based on client behaviour.
641 *
642 * Note: Perform these actions even if there is a codegen or cached
643 * codegen version of the chosen function.
644 */
645 #define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \
646 static void choose_##FN ARGS1 \
647 { \
648 GET_CURRENT_CONTEXT(ctx); \
649 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
650 int key[2]; \
651 struct dynfn *dfn; \
652 \
653 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
654 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
655 \
656 if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \
657 ctx->Exec->FN = r200_##FN##_ub; \
658 } \
659 else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \
660 \
661 if (rmesa->vb.installed_color_3f_sz != NR) { \
662 rmesa->vb.installed_color_3f_sz = NR; \
663 if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \
664 if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \
665 r200_copy_to_current( ctx ); \
666 _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \
667 ctx->Exec->FN ARGS2; \
668 return; \
669 } \
670 } \
671 \
672 ctx->Exec->FN = r200_##FN##_3f; \
673 } \
674 else { \
675 ctx->Exec->FN = r200_##FN##_4f; \
676 } \
677 \
678 \
679 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
680 if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
681 \
682 if (dfn) { \
683 if (R200_DEBUG & DEBUG_CODEGEN) \
684 fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
685 ctx->Exec->FN = (FNTYPE)dfn->code; \
686 } \
687 else if (R200_DEBUG & DEBUG_CODEGEN) \
688 fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
689 \
690 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
691 ctx->Exec->FN ARGS2; \
692 }
693
694
695
696 /* Right now there are both _ub and _3f versions of the secondary color
697 * functions. Currently, we only set-up the hardware to use the _ub versions.
698 * The _3f versions are needed for the cases where secondary color isn't used
699 * in the vertex format, but it still needs to be stored in the context
700 * state vector.
701 */
702 #define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
703 static void choose_##FN ARGS1 \
704 { \
705 GET_CURRENT_CONTEXT(ctx); \
706 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
707 int key[2]; \
708 struct dynfn *dfn; \
709 \
710 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
711 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
712 \
713 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
714 if (dfn == 0) \
715 dfn = rmesa->vb.codegen.FN( ctx, key ); \
716 else if (R200_DEBUG & DEBUG_CODEGEN) \
717 fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
718 \
719 if (dfn) \
720 ctx->Exec->FN = (FNTYPE)(dfn->code); \
721 else { \
722 if (R200_DEBUG & DEBUG_CODEGEN) \
723 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
724 ctx->Exec->FN = (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \
725 ? r200_##FN##_ub : r200_##FN##_3f; \
726 } \
727 \
728 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
729 ctx->Exec->FN ARGS2; \
730 }
731
732
733
734
735
736 /* VTXFMT_0
737 */
738 #define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0)
739 #define MASK_NORM (MASK_XYZW|R200_VTX_N0)
740 #define MASK_COLOR (MASK_NORM |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT))
741 #define MASK_SPEC (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT))
742
743 /* VTXFMT_1
744 */
745 #define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT)
746
747
748
749 typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
750 typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
751 typedef void (*p2f)( GLfloat, GLfloat );
752 typedef void (*p1f)( GLfloat );
753 typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
754 typedef void (*pe1f)( GLenum, GLfloat );
755 typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
756 typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
757 typedef void (*pfv)( const GLfloat * );
758 typedef void (*pefv)( GLenum, const GLfloat * );
759 typedef void (*pubv)( const GLubyte * );
760
761
762 CHOOSE(Normal3f, p3f, MASK_NORM, 0,
763 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
764 CHOOSE(Normal3fv, pfv, MASK_NORM, 0,
765 (const GLfloat *v), (v))
766
767 CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0,
768 (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
769 CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0,
770 (const GLubyte *v), (v))
771 CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0,
772 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
773 CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0,
774 (const GLubyte *v), (v))
775
776 CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0,
777 (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
778 CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0,
779 (const GLfloat *v), (v))
780 CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0,
781 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
782 CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0,
783 (const GLfloat *v), (v))
784
785
786 CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0,
787 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
788 CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0,
789 (const GLubyte *v), (v))
790 CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0,
791 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
792 CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0,
793 (const GLfloat *v), (v))
794
795 CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0,
796 (GLfloat a,GLfloat b), (a,b))
797 CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0,
798 (const GLfloat *v), (v))
799 CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0,
800 (GLfloat a), (a))
801 CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0,
802 (const GLfloat *v), (v))
803
804 CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0,
805 (GLenum u,GLfloat a,GLfloat b), (u,a,b))
806 CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0,
807 (GLenum u,const GLfloat *v), (u,v))
808 CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0,
809 (GLenum u,GLfloat a), (u,a))
810 CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0,
811 (GLenum u,const GLfloat *v), (u,v))
812
813 CHOOSE(Vertex3f, p3f, ~0, ~0,
814 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
815 CHOOSE(Vertex3fv, pfv, ~0, ~0,
816 (const GLfloat *v), (v))
817 CHOOSE(Vertex2f, p2f, ~0, ~0,
818 (GLfloat a,GLfloat b), (a,b))
819 CHOOSE(Vertex2fv, pfv, ~0, ~0,
820 (const GLfloat *v), (v))
821
822
823
824
825
826 void r200VtxfmtInitChoosers( GLvertexformat *vfmt )
827 {
828 vfmt->Color3f = choose_Color3f;
829 vfmt->Color3fv = choose_Color3fv;
830 vfmt->Color3ub = choose_Color3ub;
831 vfmt->Color3ubv = choose_Color3ubv;
832 vfmt->Color4f = choose_Color4f;
833 vfmt->Color4fv = choose_Color4fv;
834 vfmt->Color4ub = choose_Color4ub;
835 vfmt->Color4ubv = choose_Color4ubv;
836 vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
837 vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
838 vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
839 vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
840 vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
841 vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
842 vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
843 vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
844 vfmt->Normal3f = choose_Normal3f;
845 vfmt->Normal3fv = choose_Normal3fv;
846 vfmt->TexCoord1f = choose_TexCoord1f;
847 vfmt->TexCoord1fv = choose_TexCoord1fv;
848 vfmt->TexCoord2f = choose_TexCoord2f;
849 vfmt->TexCoord2fv = choose_TexCoord2fv;
850 vfmt->Vertex2f = choose_Vertex2f;
851 vfmt->Vertex2fv = choose_Vertex2fv;
852 vfmt->Vertex3f = choose_Vertex3f;
853 vfmt->Vertex3fv = choose_Vertex3fv;
854 }
855
856
857 static struct dynfn *codegen_noop( GLcontext *ctx, const int *key )
858 {
859 (void) ctx; (void) key;
860 return 0;
861 }
862
863 void r200InitCodegen( struct dfn_generators *gen )
864 {
865 gen->Vertex3f = codegen_noop;
866 gen->Vertex3fv = codegen_noop;
867 gen->Color4ub = codegen_noop;
868 gen->Color4ubv = codegen_noop;
869 gen->Normal3f = codegen_noop;
870 gen->Normal3fv = codegen_noop;
871 gen->TexCoord2f = codegen_noop;
872 gen->TexCoord2fv = codegen_noop;
873 gen->MultiTexCoord2fARB = codegen_noop;
874 gen->MultiTexCoord2fvARB = codegen_noop;
875 gen->Vertex2f = codegen_noop;
876 gen->Vertex2fv = codegen_noop;
877 gen->Color3ub = codegen_noop;
878 gen->Color3ubv = codegen_noop;
879 gen->Color4f = codegen_noop;
880 gen->Color4fv = codegen_noop;
881 gen->Color3f = codegen_noop;
882 gen->Color3fv = codegen_noop;
883 gen->SecondaryColor3fEXT = codegen_noop;
884 gen->SecondaryColor3fvEXT = codegen_noop;
885 gen->SecondaryColor3ubEXT = codegen_noop;
886 gen->SecondaryColor3ubvEXT = codegen_noop;
887 gen->TexCoord1f = codegen_noop;
888 gen->TexCoord1fv = codegen_noop;
889 gen->MultiTexCoord1fARB = codegen_noop;
890 gen->MultiTexCoord1fvARB = codegen_noop;
891
892 if (!getenv("R200_NO_CODEGEN")) {
893 #if defined(USE_X86_ASM)
894 r200InitX86Codegen( gen );
895 #endif
896
897 #if defined(USE_SSE_ASM)
898 r200InitSSECodegen( gen );
899 #endif
900 }
901 }