1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
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.
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:
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.
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.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "simple_list.h"
44 #include "r200_vtxfmt.h"
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.
50 static void r200_Vertex3f( GLfloat x
, GLfloat y
, GLfloat z
)
52 GET_CURRENT_CONTEXT(ctx
);
53 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
56 *rmesa
->vb
.dmaptr
++ = *(int *)&x
;
57 *rmesa
->vb
.dmaptr
++ = *(int *)&y
;
58 *rmesa
->vb
.dmaptr
++ = *(int *)&z
;
60 for (i
= 3; i
< rmesa
->vb
.vertex_size
; i
++)
61 *rmesa
->vb
.dmaptr
++ = rmesa
->vb
.vertex
[i
].i
;
63 if (--rmesa
->vb
.counter
== 0)
68 static void r200_Vertex3fv( const GLfloat
*v
)
70 GET_CURRENT_CONTEXT(ctx
);
71 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
74 *rmesa
->vb
.dmaptr
++ = *(int *)&v
[0];
75 *rmesa
->vb
.dmaptr
++ = *(int *)&v
[1];
76 *rmesa
->vb
.dmaptr
++ = *(int *)&v
[2];
78 for (i
= 3; i
< rmesa
->vb
.vertex_size
; i
++)
79 *rmesa
->vb
.dmaptr
++ = rmesa
->vb
.vertex
[i
].i
;
81 if (--rmesa
->vb
.counter
== 0)
86 static void r200_Vertex2f( GLfloat x
, GLfloat y
)
88 GET_CURRENT_CONTEXT(ctx
);
89 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
92 *rmesa
->vb
.dmaptr
++ = *(int *)&x
;
93 *rmesa
->vb
.dmaptr
++ = *(int *)&y
;
94 *rmesa
->vb
.dmaptr
++ = 0;
96 for (i
= 3; i
< rmesa
->vb
.vertex_size
; i
++)
97 *rmesa
->vb
.dmaptr
++ = rmesa
->vb
.vertex
[i
].i
;
99 if (--rmesa
->vb
.counter
== 0)
104 static void r200_Vertex2fv( const GLfloat
*v
)
106 GET_CURRENT_CONTEXT(ctx
);
107 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
110 *rmesa
->vb
.dmaptr
++ = *(int *)&v
[0];
111 *rmesa
->vb
.dmaptr
++ = *(int *)&v
[1];
112 *rmesa
->vb
.dmaptr
++ = 0;
114 for (i
= 3; i
< rmesa
->vb
.vertex_size
; i
++)
115 *rmesa
->vb
.dmaptr
++ = rmesa
->vb
.vertex
[i
].i
;
117 if (--rmesa
->vb
.counter
== 0)
123 /* Color for ubyte (packed) color formats:
125 static void r200_Color3ub_ub( GLubyte r
, GLubyte g
, GLubyte b
)
127 GET_CURRENT_CONTEXT(ctx
);
128 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
129 r200_color_t
*dest
= rmesa
->vb
.colorptr
;
136 static void r200_Color3ubv_ub( const GLubyte
*v
)
138 GET_CURRENT_CONTEXT(ctx
);
139 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
140 r200_color_t
*dest
= rmesa
->vb
.colorptr
;
147 static void r200_Color4ub_ub( GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
149 GET_CURRENT_CONTEXT(ctx
);
150 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
151 r200_color_t
*dest
= rmesa
->vb
.colorptr
;
158 static void r200_Color4ubv_ub( const GLubyte
*v
)
160 GET_CURRENT_CONTEXT(ctx
);
161 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
162 *(GLuint
*)rmesa
->vb
.colorptr
= LE32_TO_CPU(*(GLuint
*)v
);
166 static void r200_Color3f_ub( GLfloat r
, GLfloat g
, GLfloat b
)
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
);
177 static void r200_Color3fv_ub( const GLfloat
*v
)
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] );
188 static void r200_Color4f_ub( GLfloat r
, GLfloat g
, GLfloat b
, GLfloat a
)
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
);
199 static void r200_Color4fv_ub( const GLfloat
*v
)
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] );
211 /* Color for float color+alpha formats:
213 static void r200_Color3ub_4f( GLubyte r
, GLubyte g
, GLubyte b
)
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
);
224 static void r200_Color3ubv_4f( const GLubyte
*v
)
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]);
235 static void r200_Color4ub_4f( GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
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
);
246 static void r200_Color4ubv_4f( const GLubyte
*v
)
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]);
258 static void r200_Color3f_4f( GLfloat r
, GLfloat g
, GLfloat b
)
260 GET_CURRENT_CONTEXT(ctx
);
261 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
262 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
269 static void r200_Color3fv_4f( const GLfloat
*v
)
271 GET_CURRENT_CONTEXT(ctx
);
272 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
273 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
280 static void r200_Color4f_4f( GLfloat r
, GLfloat g
, GLfloat b
, GLfloat a
)
282 GET_CURRENT_CONTEXT(ctx
);
283 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
284 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
291 static void r200_Color4fv_4f( const GLfloat
*v
)
293 GET_CURRENT_CONTEXT(ctx
);
294 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
295 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
303 /* Color for float color formats:
305 static void r200_Color3ub_3f( GLubyte r
, GLubyte g
, GLubyte b
)
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
);
315 static void r200_Color3ubv_3f( const GLubyte
*v
)
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]);
325 static void r200_Color4ub_3f( GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
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
);
336 static void r200_Color4ubv_3f( const GLubyte
*v
)
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]);
348 static void r200_Color3f_3f( GLfloat r
, GLfloat g
, GLfloat b
)
350 GET_CURRENT_CONTEXT(ctx
);
351 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
352 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
358 static void r200_Color3fv_3f( const GLfloat
*v
)
360 GET_CURRENT_CONTEXT(ctx
);
361 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
362 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
368 static void r200_Color4f_3f( GLfloat r
, GLfloat g
, GLfloat b
, GLfloat a
)
370 GET_CURRENT_CONTEXT(ctx
);
371 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
372 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
376 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = a
;
379 static void r200_Color4fv_3f( const GLfloat
*v
)
381 GET_CURRENT_CONTEXT(ctx
);
382 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
383 GLfloat
*dest
= rmesa
->vb
.floatcolorptr
;
387 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = v
[3];
393 static void r200_SecondaryColor3ubEXT_ub( GLubyte r
, GLubyte g
, GLubyte b
)
395 GET_CURRENT_CONTEXT(ctx
);
396 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
397 r200_color_t
*dest
= rmesa
->vb
.specptr
;
404 static void r200_SecondaryColor3ubvEXT_ub( const GLubyte
*v
)
406 GET_CURRENT_CONTEXT(ctx
);
407 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
408 r200_color_t
*dest
= rmesa
->vb
.specptr
;
415 static void r200_SecondaryColor3fEXT_ub( GLfloat r
, GLfloat g
, GLfloat b
)
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
);
426 static void r200_SecondaryColor3fvEXT_ub( const GLfloat
*v
)
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] );
437 static void r200_SecondaryColor3ubEXT_3f( GLubyte r
, GLubyte g
, GLubyte b
)
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
);
448 static void r200_SecondaryColor3ubvEXT_3f( const GLubyte
*v
)
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]);
459 static void r200_SecondaryColor3fEXT_3f( GLfloat r
, GLfloat g
, GLfloat b
)
461 GET_CURRENT_CONTEXT(ctx
);
462 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
463 GLfloat
*dest
= rmesa
->vb
.floatspecptr
;
470 static void r200_SecondaryColor3fvEXT_3f( const GLfloat
*v
)
472 GET_CURRENT_CONTEXT(ctx
);
473 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
474 GLfloat
*dest
= rmesa
->vb
.floatspecptr
;
485 static void r200_Normal3f( GLfloat n0
, GLfloat n1
, GLfloat n2
)
487 GET_CURRENT_CONTEXT(ctx
);
488 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
489 GLfloat
*dest
= rmesa
->vb
.normalptr
;
495 static void r200_Normal3fv( const GLfloat
*v
)
497 GET_CURRENT_CONTEXT(ctx
);
498 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
499 GLfloat
*dest
= rmesa
->vb
.normalptr
;
509 #define TEX_to_nF(N, P, S, T, R) \
510 static void r200_TexCoord ## N P \
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: \
518 case TEXTURE_2D_BIT: \
519 case TEXTURE_RECT_BIT: \
521 case TEXTURE_1D_BIT: \
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] )
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.
544 #define MTEX_to_nF(N, P, U, S, T, R) \
545 static void r200_MultiTexCoord ## N ## ARB P \
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: \
553 case TEXTURE_2D_BIT: \
554 case TEXTURE_RECT_BIT: \
556 case TEXTURE_1D_BIT: \
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
)
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] )
569 static struct dynfn
*lookup( struct dynfn
*l
, const int *key
)
574 if (f
->key
[0] == key
[0] && f
->key
[1] == key
[1])
581 /* Can't use the loopback template for this:
584 #define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
585 static void choose_##FN ARGS1 \
587 GET_CURRENT_CONTEXT(ctx); \
588 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
592 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
593 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
595 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
597 dfn = rmesa->vb.codegen.FN( ctx, key ); \
598 else if (R200_DEBUG & DEBUG_CODEGEN) \
599 fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
602 ctx->Exec->FN = (FNTYPE)(dfn->code); \
604 if (R200_DEBUG & DEBUG_CODEGEN) \
605 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
606 ctx->Exec->FN = r200_##FN; \
609 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
610 ctx->Exec->FN ARGS2; \
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.
619 * Note: Perform these actions even if there is a codegen or cached
620 * codegen version of the chosen function.
622 #define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \
623 static void choose_##FN ARGS1 \
625 GET_CURRENT_CONTEXT(ctx); \
626 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
630 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
631 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
633 if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \
634 ctx->Exec->FN = r200_##FN##_ub; \
636 else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \
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; \
649 ctx->Exec->FN = r200_##FN##_3f; \
652 ctx->Exec->FN = r200_##FN##_4f; \
656 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
657 if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \
660 if (R200_DEBUG & DEBUG_CODEGEN) \
661 fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \
662 ctx->Exec->FN = (FNTYPE)dfn->code; \
664 else if (R200_DEBUG & DEBUG_CODEGEN) \
665 fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \
667 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
668 ctx->Exec->FN ARGS2; \
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
679 #define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \
680 static void choose_##FN ARGS1 \
682 GET_CURRENT_CONTEXT(ctx); \
683 r200ContextPtr rmesa = R200_CONTEXT(ctx); \
687 key[0] = rmesa->vb.vtxfmt_0 & MASK0; \
688 key[1] = rmesa->vb.vtxfmt_1 & MASK1; \
690 dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \
692 dfn = rmesa->vb.codegen.FN( ctx, key ); \
693 else if (R200_DEBUG & DEBUG_CODEGEN) \
694 fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \
697 ctx->Exec->FN = (FNTYPE)(dfn->code); \
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; \
705 ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
706 ctx->Exec->FN ARGS2; \
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))
724 #define MASK_ST0 (0x7 << R200_VTX_TEX0_COMP_CNT_SHIFT)
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
* );
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
))
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
))
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
))
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
))
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
,
787 CHOOSE(TexCoord1fv
, pfv
, ~0, MASK_ST0
,
788 (const GLfloat
*v
), (v
))
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
))
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
))
816 void r200VtxfmtInitChoosers( GLvertexformat
*vfmt
)
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
;
843 /* TODO: restore ubyte colors to vtxfmt.
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
;
856 static struct dynfn
*codegen_noop( GLcontext
*ctx
, const int *key
)
858 (void) ctx
; (void) key
;
862 void r200InitCodegen( struct dfn_generators
*gen
, GLboolean useCodegen
)
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
;
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
;
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
;
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
;
899 #if defined(USE_X86_ASM)
900 r200InitX86Codegen( gen
);
903 #if defined(USE_SSE_ASM)
904 r200InitSSECodegen( gen
);