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