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