Added support for the 3rd texture coordinate for cubemaps and 3D
[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 0x01 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 MTEX_to_nF( 1f, (GLenum target, GLfloat s), (target & 1), s, 0.0, 0.0 )
562 MTEX_to_nF( 2f, (GLenum target, GLfloat s, GLfloat t), (target & 1), s, t, 0.0 )
563 MTEX_to_nF( 3f, (GLenum target, GLfloat s, GLfloat t, GLfloat r), (target & 1), s, t, r )
564
565 MTEX_to_nF( 1fv, (GLenum target, const GLfloat *v), (target & 1), v[0], 0.0, 0.0 )
566 MTEX_to_nF( 2fv, (GLenum target, const GLfloat *v), (target & 1), v[0], v[1], 0.0 )
567 MTEX_to_nF( 3fv, (GLenum target, const GLfloat *v), (target & 1), v[0], v[1], v[2] )
568
569 static struct dynfn *lookup( struct dynfn *l, const int *key )
570 {
571 struct dynfn *f;
572
573 foreach( f, l ) {
574 if (f->key[0] == key[0] && f->key[1] == key[1])
575 return f;
576 }
577
578 return 0;
579 }
580
581 /* Can't use the loopback template for this:
582 */
583
584 #define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
585 static void choose_##FN ARGS1 \
586 { \
587 GET_CURRENT_CONTEXT(ctx); \
588 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
589 int key[2]; \
590 struct dynfn *dfn; \
591 \
592 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
593 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
594 \
595 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
596 if (dfn == 0) \
597 dfn = rmesa->vb.codegen.FN( ctx, key ); \
598 else if (R200_DEBUG & DEBUG_CODEGEN) \
599 fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
600 \
601 if (dfn) \
602 ctx->Exec->FN = (FNTYPE)(dfn->code); \
603 else { \
604 if (R200_DEBUG & DEBUG_CODEGEN) \
605 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
606 ctx->Exec->FN = r200_##FN; \
607 } \
608 \
609 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
610 ctx->Exec->FN ARGS2; \
611 }
612
613
614
615 /* For the _3f case, only allow one color function to be hooked in at
616 * a time. Eventually, use a similar mechanism to allow selecting the
617 * color component of the vertex format based on client behaviour.
618 *
619 * Note: Perform these actions even if there is a codegen or cached
620 * codegen version of the chosen function.
621 */
622 #define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \
623 static void choose_##FN ARGS1 \
624 { \
625 GET_CURRENT_CONTEXT(ctx); \
626 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
627 int key[2]; \
628 struct dynfn *dfn; \
629 \
630 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
631 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
632 \
633 if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \
634 ctx->Exec->FN = r200_##FN##_ub; \
635 } \
636 else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \
637 \
638 if (rmesa->vb.installed_color_3f_sz != NR) { \
639 rmesa->vb.installed_color_3f_sz = NR; \
640 if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \
641 if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \
642 r200_copy_to_current( ctx ); \
643 _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \
644 ctx->Exec->FN ARGS2; \
645 return; \
646 } \
647 } \
648 \
649 ctx->Exec->FN = r200_##FN##_3f; \
650 } \
651 else { \
652 ctx->Exec->FN = r200_##FN##_4f; \
653 } \
654 \
655 \
656 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
657 if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
658 \
659 if (dfn) { \
660 if (R200_DEBUG & DEBUG_CODEGEN) \
661 fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
662 ctx->Exec->FN = (FNTYPE)dfn->code; \
663 } \
664 else if (R200_DEBUG & DEBUG_CODEGEN) \
665 fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
666 \
667 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
668 ctx->Exec->FN ARGS2; \
669 }
670
671
672
673 /* Right now there are both _ub and _3f versions of the secondary color
674 * functions. Currently, we only set-up the hardware to use the _ub versions.
675 * The _3f versions are needed for the cases where secondary color isn't used
676 * in the vertex format, but it still needs to be stored in the context
677 * state vector.
678 */
679 #define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
680 static void choose_##FN ARGS1 \
681 { \
682 GET_CURRENT_CONTEXT(ctx); \
683 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
684 int key[2]; \
685 struct dynfn *dfn; \
686 \
687 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
688 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
689 \
690 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
691 if (dfn == 0) \
692 dfn = rmesa->vb.codegen.FN( ctx, key ); \
693 else if (R200_DEBUG & DEBUG_CODEGEN) \
694 fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
695 \
696 if (dfn) \
697 ctx->Exec->FN = (FNTYPE)(dfn->code); \
698 else { \
699 if (R200_DEBUG & DEBUG_CODEGEN) \
700 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
701 ctx->Exec->FN = (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \
702 ? r200_##FN##_ub : r200_##FN##_3f; \
703 } \
704 \
705 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
706 ctx->Exec->FN ARGS2; \
707 }
708
709
710
711
712
713
714
715 /* VTXFMT_0
716 */
717 #define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0)
718 #define MASK_NORM (MASK_XYZW|R200_VTX_N0)
719 #define MASK_COLOR (MASK_NORM |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT))
720 #define MASK_SPEC (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT))
721
722 /* VTXFMT_1
723 */
724 #define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT)
725
726
727
728 typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
729 typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
730 typedef void (*p2f)( GLfloat, GLfloat );
731 typedef void (*p1f)( GLfloat );
732 typedef void (*pe3f)( GLenum, GLfloat, GLfloat, GLfloat );
733 typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
734 typedef void (*pe1f)( GLenum, GLfloat );
735 typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
736 typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
737 typedef void (*pfv)( const GLfloat * );
738 typedef void (*pefv)( GLenum, const GLfloat * );
739 typedef void (*pubv)( const GLubyte * );
740
741
742 CHOOSE(Normal3f, p3f, MASK_NORM, 0,
743 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
744 CHOOSE(Normal3fv, pfv, MASK_NORM, 0,
745 (const GLfloat *v), (v))
746
747 #if 0
748 CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, 0,
749 (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
750 CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, 0,
751 (const GLubyte *v), (v))
752 CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, 0,
753 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
754 CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, 0,
755 (const GLubyte *v), (v))
756 CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, 0,
757 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
758 CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, 0,
759 (const GLubyte *v), (v))
760 #endif
761
762 CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, 0,
763 (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
764 CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, 0,
765 (const GLfloat *v), (v))
766 CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, 0,
767 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
768 CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, 0,
769 (const GLfloat *v), (v))
770
771
772 CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, 0,
773 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
774 CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, 0,
775 (const GLfloat *v), (v))
776
777 CHOOSE(TexCoord3f, p3f, ~0, MASK_ST0,
778 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
779 CHOOSE(TexCoord3fv, pfv, ~0, MASK_ST0,
780 (const GLfloat *v), (v))
781 CHOOSE(TexCoord2f, p2f, ~0, MASK_ST0,
782 (GLfloat a,GLfloat b), (a,b))
783 CHOOSE(TexCoord2fv, pfv, ~0, MASK_ST0,
784 (const GLfloat *v), (v))
785 CHOOSE(TexCoord1f, p1f, ~0, MASK_ST0,
786 (GLfloat a), (a))
787 CHOOSE(TexCoord1fv, pfv, ~0, MASK_ST0,
788 (const GLfloat *v), (v))
789
790 CHOOSE(MultiTexCoord3fARB, pe3f, ~0, ~0,
791 (GLenum u,GLfloat a,GLfloat b,GLfloat c), (u,a,b,c))
792 CHOOSE(MultiTexCoord3fvARB, pefv, ~0, ~0,
793 (GLenum u,const GLfloat *v), (u,v))
794 CHOOSE(MultiTexCoord2fARB, pe2f, ~0, ~0,
795 (GLenum u,GLfloat a,GLfloat b), (u,a,b))
796 CHOOSE(MultiTexCoord2fvARB, pefv, ~0, ~0,
797 (GLenum u,const GLfloat *v), (u,v))
798 CHOOSE(MultiTexCoord1fARB, pe1f, ~0, ~0,
799 (GLenum u,GLfloat a), (u,a))
800 CHOOSE(MultiTexCoord1fvARB, pefv, ~0, ~0,
801 (GLenum u,const GLfloat *v), (u,v))
802
803 CHOOSE(Vertex3f, p3f, ~0, ~0,
804 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
805 CHOOSE(Vertex3fv, pfv, ~0, ~0,
806 (const GLfloat *v), (v))
807 CHOOSE(Vertex2f, p2f, ~0, ~0,
808 (GLfloat a,GLfloat b), (a,b))
809 CHOOSE(Vertex2fv, pfv, ~0, ~0,
810 (const GLfloat *v), (v))
811
812
813
814
815
816 void r200VtxfmtInitChoosers( GLvertexformat *vfmt )
817 {
818 vfmt->Color3f = choose_Color3f;
819 vfmt->Color3fv = choose_Color3fv;
820 vfmt->Color4f = choose_Color4f;
821 vfmt->Color4fv = choose_Color4fv;
822 vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
823 vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
824 vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
825 vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
826 vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
827 vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
828 vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB;
829 vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB;
830 vfmt->Normal3f = choose_Normal3f;
831 vfmt->Normal3fv = choose_Normal3fv;
832 vfmt->TexCoord1f = choose_TexCoord1f;
833 vfmt->TexCoord1fv = choose_TexCoord1fv;
834 vfmt->TexCoord2f = choose_TexCoord2f;
835 vfmt->TexCoord2fv = choose_TexCoord2fv;
836 vfmt->TexCoord3f = choose_TexCoord3f;
837 vfmt->TexCoord3fv = choose_TexCoord3fv;
838 vfmt->Vertex2f = choose_Vertex2f;
839 vfmt->Vertex2fv = choose_Vertex2fv;
840 vfmt->Vertex3f = choose_Vertex3f;
841 vfmt->Vertex3fv = choose_Vertex3fv;
842
843 /* TODO: restore ubyte colors to vtxfmt.
844 */
845 #if 0
846 vfmt->Color3ub = choose_Color3ub;
847 vfmt->Color3ubv = choose_Color3ubv;
848 vfmt->Color4ub = choose_Color4ub;
849 vfmt->Color4ubv = choose_Color4ubv;
850 vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
851 vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
852 #endif
853 }
854
855
856 static struct dynfn *codegen_noop( GLcontext *ctx, const int *key )
857 {
858 (void) ctx; (void) key;
859 return 0;
860 }
861
862 void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen )
863 {
864 gen->Vertex3f = codegen_noop;
865 gen->Vertex3fv = codegen_noop;
866 gen->Color4ub = codegen_noop;
867 gen->Color4ubv = codegen_noop;
868 gen->Normal3f = codegen_noop;
869 gen->Normal3fv = codegen_noop;
870
871 gen->TexCoord3f = codegen_noop;
872 gen->TexCoord3fv = codegen_noop;
873 gen->TexCoord2f = codegen_noop;
874 gen->TexCoord2fv = codegen_noop;
875 gen->TexCoord1f = codegen_noop;
876 gen->TexCoord1fv = codegen_noop;
877
878 gen->MultiTexCoord3fARB = codegen_noop;
879 gen->MultiTexCoord3fvARB = codegen_noop;
880 gen->MultiTexCoord2fARB = codegen_noop;
881 gen->MultiTexCoord2fvARB = codegen_noop;
882 gen->MultiTexCoord1fARB = codegen_noop;
883 gen->MultiTexCoord1fvARB = codegen_noop;
884
885 gen->Vertex2f = codegen_noop;
886 gen->Vertex2fv = codegen_noop;
887 gen->Color3ub = codegen_noop;
888 gen->Color3ubv = codegen_noop;
889 gen->Color4f = codegen_noop;
890 gen->Color4fv = codegen_noop;
891 gen->Color3f = codegen_noop;
892 gen->Color3fv = codegen_noop;
893 gen->SecondaryColor3fEXT = codegen_noop;
894 gen->SecondaryColor3fvEXT = codegen_noop;
895 gen->SecondaryColor3ubEXT = codegen_noop;
896 gen->SecondaryColor3ubvEXT = codegen_noop;
897
898 if (useCodegen) {
899 #if defined(USE_X86_ASM)
900 r200InitX86Codegen( gen );
901 #endif
902
903 #if defined(USE_SSE_ASM)
904 r200InitSSECodegen( gen );
905 #endif
906 }
907 }