1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.6 2003/05/06 23:52:08 daenzer Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 Tungsten Graphics Inc., Cedar Park, Texas.
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>
38 #include "api_arrayelt.h"
49 #include "tnl/t_context.h"
50 #include "tnl/t_array_api.h"
52 #include "radeon_context.h"
53 #include "radeon_state.h"
54 #include "radeon_ioctl.h"
55 #include "radeon_tex.h"
56 #include "radeon_tcl.h"
57 #include "radeon_swtcl.h"
58 #include "radeon_vtxfmt.h"
62 static void radeonVtxfmtFlushVertices( GLcontext
*, GLuint
);
64 static void count_func( const char *name
, struct dynfn
*l
)
69 if (i
) fprintf(stderr
, "%s: %d\n", name
, i
);
72 static void count_funcs( radeonContextPtr rmesa
)
74 count_func( "Vertex2f", &rmesa
->vb
.dfn_cache
.Vertex2f
);
75 count_func( "Vertex2fv", &rmesa
->vb
.dfn_cache
.Vertex2fv
);
76 count_func( "Vertex3f", &rmesa
->vb
.dfn_cache
.Vertex3f
);
77 count_func( "Vertex3fv", &rmesa
->vb
.dfn_cache
.Vertex3fv
);
78 count_func( "Color4ub", &rmesa
->vb
.dfn_cache
.Color4ub
);
79 count_func( "Color4ubv", &rmesa
->vb
.dfn_cache
.Color4ubv
);
80 count_func( "Color3ub", &rmesa
->vb
.dfn_cache
.Color3ub
);
81 count_func( "Color3ubv", &rmesa
->vb
.dfn_cache
.Color3ubv
);
82 count_func( "Color4f", &rmesa
->vb
.dfn_cache
.Color4f
);
83 count_func( "Color4fv", &rmesa
->vb
.dfn_cache
.Color4fv
);
84 count_func( "Color3f", &rmesa
->vb
.dfn_cache
.Color3f
);
85 count_func( "Color3fv", &rmesa
->vb
.dfn_cache
.Color3fv
);
86 count_func( "SecondaryColor3f", &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
87 count_func( "SecondaryColor3fv", &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
88 count_func( "SecondaryColor3ub", &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
89 count_func( "SecondaryColor3ubv", &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
90 count_func( "Normal3f", &rmesa
->vb
.dfn_cache
.Normal3f
);
91 count_func( "Normal3fv", &rmesa
->vb
.dfn_cache
.Normal3fv
);
92 count_func( "TexCoord2f", &rmesa
->vb
.dfn_cache
.TexCoord2f
);
93 count_func( "TexCoord2fv", &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
94 count_func( "TexCoord1f", &rmesa
->vb
.dfn_cache
.TexCoord1f
);
95 count_func( "TexCoord1fv", &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
96 count_func( "MultiTexCoord2fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
97 count_func( "MultiTexCoord2fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
98 count_func( "MultiTexCoord1fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
99 count_func( "MultiTexCoord1fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
103 void radeon_copy_to_current( GLcontext
*ctx
)
105 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
107 assert(ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
);
109 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_N0
) {
110 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0] = rmesa
->vb
.normalptr
[0];
111 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1] = rmesa
->vb
.normalptr
[1];
112 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2] = rmesa
->vb
.normalptr
[2];
115 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_PKCOLOR
) {
116 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->red
);
117 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->green
);
118 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->blue
);
119 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->alpha
);
122 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_FPCOLOR
) {
123 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = rmesa
->vb
.floatcolorptr
[0];
124 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = rmesa
->vb
.floatcolorptr
[1];
125 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = rmesa
->vb
.floatcolorptr
[2];
128 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_FPALPHA
)
129 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = rmesa
->vb
.floatcolorptr
[3];
131 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_PKSPEC
) {
132 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->red
);
133 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->green
);
134 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->blue
);
137 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_ST0
) {
138 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][0] = rmesa
->vb
.texcoordptr
[0][0];
139 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][1] = rmesa
->vb
.texcoordptr
[0][1];
140 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][2] = 0.0F
;
141 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][3] = 1.0F
;
144 if (rmesa
->vb
.vertex_format
& RADEON_CP_VC_FRMT_ST1
) {
145 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][0] = rmesa
->vb
.texcoordptr
[1][0];
146 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][1] = rmesa
->vb
.texcoordptr
[1][1];
147 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][2] = 0.0F
;
148 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][3] = 1.0F
;
151 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
154 static GLboolean discreet_gl_prim
[GL_POLYGON
+1] = {
157 0, /* 2 line_strip */
167 static void flush_prims( radeonContextPtr rmesa
)
170 struct radeon_dma_region tmp
= rmesa
->dma
.current
;
173 tmp
.aos_size
= rmesa
->vb
.vertex_size
;
174 tmp
.aos_stride
= rmesa
->vb
.vertex_size
;
175 tmp
.aos_start
= GET_START(&tmp
);
177 rmesa
->dma
.current
.ptr
= rmesa
->dma
.current
.start
+=
178 (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) * rmesa
->vb
.vertex_size
* 4;
180 rmesa
->tcl
.vertex_format
= rmesa
->vb
.vertex_format
;
181 rmesa
->tcl
.aos_components
[0] = &tmp
;
182 rmesa
->tcl
.nr_aos_components
= 1;
183 rmesa
->dma
.flush
= NULL
;
185 /* Optimize the primitive list:
187 if (rmesa
->vb
.nrprims
> 1) {
188 for (j
= 0, i
= 1 ; i
< rmesa
->vb
.nrprims
; i
++) {
189 int pj
= rmesa
->vb
.primlist
[j
].prim
& 0xf;
190 int pi
= rmesa
->vb
.primlist
[i
].prim
& 0xf;
192 if (pj
== pi
&& discreet_gl_prim
[pj
] &&
193 rmesa
->vb
.primlist
[i
].start
== rmesa
->vb
.primlist
[j
].end
) {
194 rmesa
->vb
.primlist
[j
].end
= rmesa
->vb
.primlist
[i
].end
;
198 if (j
!= i
) rmesa
->vb
.primlist
[j
] = rmesa
->vb
.primlist
[i
];
201 rmesa
->vb
.nrprims
= j
+1;
204 for (i
= 0 ; i
< rmesa
->vb
.nrprims
; i
++) {
205 if (RADEON_DEBUG
& DEBUG_PRIMS
)
206 fprintf(stderr
, "vtxfmt prim %d: %s %d..%d\n", i
,
207 _mesa_lookup_enum_by_nr( rmesa
->vb
.primlist
[i
].prim
&
209 rmesa
->vb
.primlist
[i
].start
,
210 rmesa
->vb
.primlist
[i
].end
);
212 radeonEmitPrimitive( rmesa
->glCtx
,
213 rmesa
->vb
.primlist
[i
].start
,
214 rmesa
->vb
.primlist
[i
].end
,
215 rmesa
->vb
.primlist
[i
].prim
);
218 rmesa
->vb
.nrprims
= 0;
219 radeonReleaseDmaRegion( rmesa
, &tmp
, __FUNCTION__
);
223 static void start_prim( radeonContextPtr rmesa
, GLuint mode
)
225 if (RADEON_DEBUG
& DEBUG_VFMT
)
226 fprintf(stderr
, "%s %d\n", __FUNCTION__
, rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
228 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
= rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
229 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
= mode
;
232 static void note_last_prim( radeonContextPtr rmesa
, GLuint flags
)
234 if (RADEON_DEBUG
& DEBUG_VFMT
)
235 fprintf(stderr
, "%s %d\n", __FUNCTION__
, rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
237 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
238 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
|= flags
;
239 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].end
= rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
241 if (++(rmesa
->vb
.nrprims
) == RADEON_MAX_PRIMS
)
242 flush_prims( rmesa
);
247 static void copy_vertex( radeonContextPtr rmesa
, GLuint n
, GLfloat
*dst
)
250 GLfloat
*src
= (GLfloat
*)(rmesa
->dma
.current
.address
+
251 rmesa
->dma
.current
.ptr
+
252 (rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
) *
253 rmesa
->vb
.vertex_size
* 4);
255 if (RADEON_DEBUG
& DEBUG_VFMT
)
256 fprintf(stderr
, "copy_vertex %d\n", rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
);
258 for (i
= 0 ; i
< rmesa
->vb
.vertex_size
; i
++) {
263 /* NOTE: This actually reads the copied vertices back from uncached
264 * memory. Could also use the counter/notify mechanism to populate
265 * tmp on the fly as vertices are generated.
267 static GLuint
copy_dma_verts( radeonContextPtr rmesa
, GLfloat (*tmp
)[15] )
270 GLuint nr
= (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) - rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
;
272 if (RADEON_DEBUG
& DEBUG_VFMT
)
273 fprintf(stderr
, "%s %d verts\n", __FUNCTION__
, nr
);
275 switch( rmesa
->vb
.prim
[0] )
281 for (i
= 0 ; i
< ovf
; i
++)
282 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
286 for (i
= 0 ; i
< ovf
; i
++)
287 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
291 for (i
= 0 ; i
< ovf
; i
++)
292 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
297 copy_vertex( rmesa
, nr
-1, tmp
[0] );
300 case GL_TRIANGLE_FAN
:
305 copy_vertex( rmesa
, 0, tmp
[0] );
308 copy_vertex( rmesa
, 0, tmp
[0] );
309 copy_vertex( rmesa
, nr
-1, tmp
[1] );
312 case GL_TRIANGLE_STRIP
:
314 for (i
= 0 ; i
< ovf
; i
++)
315 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
319 case 0: ovf
= 0; break;
320 case 1: ovf
= 1; break;
321 default: ovf
= 2 + (nr
&1); break;
323 for (i
= 0 ; i
< ovf
; i
++)
324 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
332 static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller
)
334 GET_CURRENT_CONTEXT(ctx
);
335 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
337 if (RADEON_DEBUG
& (DEBUG_VFMT
|DEBUG_FALLBACKS
))
338 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
340 if (ctx
->Driver
.NeedFlush
)
341 radeonVtxfmtFlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
344 _mesa_update_state( ctx
); /* clear state so fell_back sticks */
346 _tnl_wakeup_exec( ctx
);
347 ctx
->Driver
.FlushVertices
= radeonFlushVertices
;
349 assert( rmesa
->dma
.flush
== 0 );
350 rmesa
->vb
.fell_back
= GL_TRUE
;
351 rmesa
->vb
.installed
= GL_FALSE
;
355 static void VFMT_FALLBACK( const char *caller
)
357 GET_CURRENT_CONTEXT(ctx
);
358 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
361 GLuint ind
= rmesa
->vb
.vertex_format
;
365 if (RADEON_DEBUG
& (DEBUG_FALLBACKS
|DEBUG_VFMT
))
366 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
368 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
369 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__
);
373 /* Copy vertices out of dma:
375 nrverts
= copy_dma_verts( rmesa
, tmp
);
377 /* Finish the prim at this point:
379 note_last_prim( rmesa
, 0 );
380 flush_prims( rmesa
);
382 /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
384 prim
= rmesa
->vb
.prim
[0];
385 ctx
->Driver
.CurrentExecPrimitive
= GL_POLYGON
+1;
386 _tnl_wakeup_exec( ctx
);
387 ctx
->Driver
.FlushVertices
= radeonFlushVertices
;
389 assert(rmesa
->dma
.flush
== 0);
390 rmesa
->vb
.fell_back
= GL_TRUE
;
391 rmesa
->vb
.installed
= GL_FALSE
;
392 CALL_Begin(GET_DISPATCH(), (prim
));
394 if (rmesa
->vb
.installed_color_3f_sz
== 4)
395 alpha
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
397 /* Replay saved vertices
399 for (i
= 0 ; i
< nrverts
; i
++) {
401 if (ind
& RADEON_CP_VC_FRMT_N0
) {
402 CALL_Normal3fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
406 if (ind
& RADEON_CP_VC_FRMT_PKCOLOR
) {
407 radeon_color_t
*col
= (radeon_color_t
*)&tmp
[i
][offset
];
408 CALL_Color4ub(GET_DISPATCH(), (col
->red
, col
->green
, col
->blue
, col
->alpha
));
411 else if (ind
& RADEON_CP_VC_FRMT_FPALPHA
) {
412 CALL_Color4fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
415 else if (ind
& RADEON_CP_VC_FRMT_FPCOLOR
) {
416 CALL_Color3fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
420 if (ind
& RADEON_CP_VC_FRMT_PKSPEC
) {
421 radeon_color_t
*spec
= (radeon_color_t
*)&tmp
[i
][offset
];
422 CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (spec
->red
, spec
->green
, spec
->blue
));
426 if (ind
& RADEON_CP_VC_FRMT_ST0
) {
427 CALL_TexCoord2fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
431 if (ind
& RADEON_CP_VC_FRMT_ST1
) {
432 CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE1_ARB
, &tmp
[i
][offset
]));
435 CALL_Vertex3fv(GET_DISPATCH(), (&tmp
[i
][0]));
438 /* Replay current vertex
440 if (ind
& RADEON_CP_VC_FRMT_N0
)
441 CALL_Normal3fv(GET_DISPATCH(), (rmesa
->vb
.normalptr
));
443 if (ind
& RADEON_CP_VC_FRMT_PKCOLOR
)
444 CALL_Color4ub(GET_DISPATCH(), (rmesa
->vb
.colorptr
->red
, rmesa
->vb
.colorptr
->green
, rmesa
->vb
.colorptr
->blue
, rmesa
->vb
.colorptr
->alpha
));
445 else if (ind
& RADEON_CP_VC_FRMT_FPALPHA
)
446 CALL_Color4fv(GET_DISPATCH(), (rmesa
->vb
.floatcolorptr
));
447 else if (ind
& RADEON_CP_VC_FRMT_FPCOLOR
) {
448 if (rmesa
->vb
.installed_color_3f_sz
== 4 && alpha
!= 1.0)
449 CALL_Color4f(GET_DISPATCH(), (rmesa
->vb
.floatcolorptr
[0],
450 rmesa
->vb
.floatcolorptr
[1],
451 rmesa
->vb
.floatcolorptr
[2],
454 CALL_Color3fv(GET_DISPATCH(), (rmesa
->vb
.floatcolorptr
));
457 if (ind
& RADEON_CP_VC_FRMT_PKSPEC
)
458 CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa
->vb
.specptr
->red
, rmesa
->vb
.specptr
->green
, rmesa
->vb
.specptr
->blue
));
460 if (ind
& RADEON_CP_VC_FRMT_ST0
)
461 CALL_TexCoord2fv(GET_DISPATCH(), (rmesa
->vb
.texcoordptr
[0]));
463 if (ind
& RADEON_CP_VC_FRMT_ST1
)
464 CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE1_ARB
, rmesa
->vb
.texcoordptr
[1]));
469 static void wrap_buffer( void )
471 GET_CURRENT_CONTEXT(ctx
);
472 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
476 if (RADEON_DEBUG
& (DEBUG_VFMT
|DEBUG_PRIMS
))
477 fprintf(stderr
, "%s %d\n", __FUNCTION__
, rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
479 /* Don't deal with parity.
481 if ((((rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
482 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
) & 1)) {
484 rmesa
->vb
.initial_counter
++;
488 /* Copy vertices out of dma:
490 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1)
493 nrverts
= copy_dma_verts( rmesa
, tmp
);
495 if (RADEON_DEBUG
& DEBUG_VFMT
)
496 fprintf(stderr
, "%d vertices to copy\n", nrverts
);
498 /* Finish the prim at this point:
500 note_last_prim( rmesa
, 0 );
503 /* Fire any buffered primitives
505 flush_prims( rmesa
);
509 radeonRefillCurrentDmaRegion( rmesa
);
511 /* Reset counter, dmaptr
513 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.ptr
+ rmesa
->dma
.current
.address
);
514 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
515 (rmesa
->vb
.vertex_size
* 4);
517 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
518 rmesa
->vb
.notify
= wrap_buffer
;
520 rmesa
->dma
.flush
= flush_prims
;
522 /* Restart wrapped primitive:
524 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1)
525 start_prim( rmesa
, rmesa
->vb
.prim
[0] );
527 /* Reemit saved vertices
529 for (i
= 0 ; i
< nrverts
; i
++) {
530 if (RADEON_DEBUG
& DEBUG_VERTS
) {
532 fprintf(stderr
, "re-emit vertex %d to %p\n", i
, (void *)rmesa
->vb
.dmaptr
);
533 if (RADEON_DEBUG
& DEBUG_VERBOSE
)
534 for (j
= 0 ; j
< rmesa
->vb
.vertex_size
; j
++)
535 fprintf(stderr
, "\t%08x/%f\n", *(int*)&tmp
[i
][j
], tmp
[i
][j
]);
538 memcpy( rmesa
->vb
.dmaptr
, tmp
[i
], rmesa
->vb
.vertex_size
* 4 );
539 rmesa
->vb
.dmaptr
+= rmesa
->vb
.vertex_size
;
546 static GLboolean
check_vtx_fmt( GLcontext
*ctx
)
548 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
549 GLuint ind
= RADEON_CP_VC_FRMT_Z
;
551 if (rmesa
->TclFallback
|| rmesa
->vb
.fell_back
|| ctx
->CompileFlag
)
554 if (ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
)
555 ctx
->Driver
.FlushVertices( ctx
, FLUSH_UPDATE_CURRENT
);
557 /* Make all this event-driven:
559 if (ctx
->Light
.Enabled
) {
560 ind
|= RADEON_CP_VC_FRMT_N0
;
562 /* TODO: make this data driven: If we receive only ubytes, send
563 * color as ubytes. Also check if converting (with free
564 * checking for overflow) is cheaper than sending floats
567 if (ctx
->Light
.ColorMaterialEnabled
) {
568 ind
|= (RADEON_CP_VC_FRMT_FPCOLOR
|
569 RADEON_CP_VC_FRMT_FPALPHA
);
572 ind
|= RADEON_CP_VC_FRMT_PKCOLOR
; /* for alpha? */
575 /* TODO: make this data driven?
577 ind
|= RADEON_CP_VC_FRMT_PKCOLOR
;
579 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
580 ind
|= RADEON_CP_VC_FRMT_PKSPEC
;
584 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
585 if (ctx
->Texture
.Unit
[0].TexGenEnabled
) {
586 if (rmesa
->TexGenNeedNormals
[0]) {
587 ind
|= RADEON_CP_VC_FRMT_N0
;
590 if (ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][2] != 0.0F
||
591 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][3] != 1.0) {
592 if (RADEON_DEBUG
& (DEBUG_VFMT
|DEBUG_FALLBACKS
))
593 fprintf(stderr
, "%s: rq0\n", __FUNCTION__
);
596 ind
|= RADEON_CP_VC_FRMT_ST0
;
600 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
) {
601 if (ctx
->Texture
.Unit
[1].TexGenEnabled
) {
602 if (rmesa
->TexGenNeedNormals
[1]) {
603 ind
|= RADEON_CP_VC_FRMT_N0
;
606 if (ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][2] != 0.0F
||
607 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][3] != 1.0) {
608 if (RADEON_DEBUG
& (DEBUG_VFMT
|DEBUG_FALLBACKS
))
609 fprintf(stderr
, "%s: rq1\n", __FUNCTION__
);
612 ind
|= RADEON_CP_VC_FRMT_ST1
;
616 if (RADEON_DEBUG
& (DEBUG_VFMT
|DEBUG_STATE
))
617 fprintf(stderr
, "%s: format: 0x%x\n", __FUNCTION__
, ind
);
619 RADEON_NEWPRIM(rmesa
);
620 rmesa
->vb
.vertex_format
= ind
;
621 rmesa
->vb
.vertex_size
= 3;
622 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
624 rmesa
->vb
.normalptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
625 rmesa
->vb
.colorptr
= NULL
;
626 rmesa
->vb
.floatcolorptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
627 rmesa
->vb
.specptr
= NULL
;
628 rmesa
->vb
.floatspecptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
629 rmesa
->vb
.texcoordptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
630 rmesa
->vb
.texcoordptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
632 /* Run through and initialize the vertex components in the order
633 * the hardware understands:
635 if (ind
& RADEON_CP_VC_FRMT_N0
) {
636 rmesa
->vb
.normalptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
637 rmesa
->vb
.vertex_size
+= 3;
638 rmesa
->vb
.normalptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0];
639 rmesa
->vb
.normalptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1];
640 rmesa
->vb
.normalptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2];
643 if (ind
& RADEON_CP_VC_FRMT_PKCOLOR
) {
644 rmesa
->vb
.colorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
645 rmesa
->vb
.vertex_size
+= 1;
646 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] );
647 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] );
648 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] );
649 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->alpha
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] );
652 if (ind
& RADEON_CP_VC_FRMT_FPCOLOR
) {
653 assert(!(ind
& RADEON_CP_VC_FRMT_PKCOLOR
));
654 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
655 rmesa
->vb
.vertex_size
+= 3;
656 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
657 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
658 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
660 if (ind
& RADEON_CP_VC_FRMT_FPALPHA
) {
661 rmesa
->vb
.vertex_size
+= 1;
662 rmesa
->vb
.floatcolorptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
666 if (ind
& RADEON_CP_VC_FRMT_PKSPEC
) {
667 rmesa
->vb
.specptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
668 rmesa
->vb
.vertex_size
+= 1;
669 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] );
670 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] );
671 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] );
674 if (ind
& RADEON_CP_VC_FRMT_ST0
) {
675 rmesa
->vb
.texcoordptr
[0] = &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
676 rmesa
->vb
.vertex_size
+= 2;
677 rmesa
->vb
.texcoordptr
[0][0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][0];
678 rmesa
->vb
.texcoordptr
[0][1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][1];
681 if (ind
& RADEON_CP_VC_FRMT_ST1
) {
682 rmesa
->vb
.texcoordptr
[1] = &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
683 rmesa
->vb
.vertex_size
+= 2;
684 rmesa
->vb
.texcoordptr
[1][0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][0];
685 rmesa
->vb
.texcoordptr
[1][1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
][1];
688 if (rmesa
->vb
.installed_vertex_format
!= rmesa
->vb
.vertex_format
) {
689 if (RADEON_DEBUG
& DEBUG_VFMT
)
690 fprintf(stderr
, "reinstall on vertex_format change\n");
691 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
692 rmesa
->vb
.installed_vertex_format
= rmesa
->vb
.vertex_format
;
695 if (RADEON_DEBUG
& DEBUG_VFMT
)
696 fprintf(stderr
, "%s -- success\n", __FUNCTION__
);
701 void radeonVtxfmtInvalidate( GLcontext
*ctx
)
703 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
705 rmesa
->vb
.recheck
= GL_TRUE
;
706 rmesa
->vb
.fell_back
= GL_FALSE
;
710 static void radeonVtxfmtValidate( GLcontext
*ctx
)
712 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
714 if (RADEON_DEBUG
& DEBUG_VFMT
)
715 fprintf(stderr
, "%s\n", __FUNCTION__
);
717 if (ctx
->Driver
.NeedFlush
)
718 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
720 rmesa
->vb
.recheck
= GL_FALSE
;
722 if (check_vtx_fmt( ctx
)) {
723 if (!rmesa
->vb
.installed
) {
724 if (RADEON_DEBUG
& DEBUG_VFMT
)
725 fprintf(stderr
, "reinstall (new install)\n");
727 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
728 ctx
->Driver
.FlushVertices
= radeonVtxfmtFlushVertices
;
729 rmesa
->vb
.installed
= GL_TRUE
;
731 else if (RADEON_DEBUG
& DEBUG_VFMT
)
732 fprintf(stderr
, "%s: already installed", __FUNCTION__
);
735 if (RADEON_DEBUG
& DEBUG_VFMT
)
736 fprintf(stderr
, "%s: failed\n", __FUNCTION__
);
738 if (rmesa
->vb
.installed
) {
739 if (rmesa
->dma
.flush
)
740 rmesa
->dma
.flush( rmesa
);
741 _tnl_wakeup_exec( ctx
);
742 ctx
->Driver
.FlushVertices
= radeonFlushVertices
;
743 rmesa
->vb
.installed
= GL_FALSE
;
752 static void radeon_Materialfv( GLenum face
, GLenum pname
,
753 const GLfloat
*params
)
755 GET_CURRENT_CONTEXT(ctx
);
756 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
758 if (RADEON_DEBUG
& DEBUG_VFMT
)
759 fprintf(stderr
, "%s\n", __FUNCTION__
);
761 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
762 VFMT_FALLBACK( __FUNCTION__
);
763 CALL_Materialfv(GET_DISPATCH(), (face
, pname
, params
));
766 _mesa_noop_Materialfv( face
, pname
, params
);
767 radeonUpdateMaterial( ctx
);
773 static void radeon_Begin( GLenum mode
)
775 GET_CURRENT_CONTEXT(ctx
);
776 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
778 if (RADEON_DEBUG
& DEBUG_VFMT
)
779 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
780 _mesa_lookup_enum_by_nr( mode
));
782 if (mode
> GL_POLYGON
) {
783 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
787 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
788 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
793 _mesa_update_state( ctx
);
795 if (rmesa
->NewGLState
)
796 radeonValidateState( ctx
);
798 if (rmesa
->vb
.recheck
)
799 radeonVtxfmtValidate( ctx
);
801 if (!rmesa
->vb
.installed
) {
802 CALL_Begin(GET_DISPATCH(), (mode
));
807 if (rmesa
->dma
.flush
&& rmesa
->vb
.counter
< 12) {
808 if (RADEON_DEBUG
& DEBUG_VFMT
)
809 fprintf(stderr
, "%s: flush almost-empty buffers\n", __FUNCTION__
);
810 flush_prims( rmesa
);
813 /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
815 if (!rmesa
->dma
.flush
) {
816 if (rmesa
->dma
.current
.ptr
+ 12*rmesa
->vb
.vertex_size
*4 >
817 rmesa
->dma
.current
.end
) {
818 RADEON_NEWPRIM( rmesa
);
819 radeonRefillCurrentDmaRegion( rmesa
);
822 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
823 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
824 (rmesa
->vb
.vertex_size
* 4);
826 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
827 rmesa
->vb
.notify
= wrap_buffer
;
828 rmesa
->dma
.flush
= flush_prims
;
829 ctx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
833 rmesa
->vb
.prim
[0] = mode
;
834 start_prim( rmesa
, mode
| PRIM_BEGIN
);
839 static void radeon_End( void )
841 GET_CURRENT_CONTEXT(ctx
);
842 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
844 if (RADEON_DEBUG
& DEBUG_VFMT
)
845 fprintf(stderr
, "%s\n", __FUNCTION__
);
847 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
848 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glEnd" );
852 note_last_prim( rmesa
, PRIM_END
);
853 rmesa
->vb
.prim
[0] = GL_POLYGON
+1;
857 /* Fallback on difficult entrypoints:
859 #define PRE_LOOPBACK( FUNC ) \
861 if (RADEON_DEBUG & DEBUG_VFMT) \
862 fprintf(stderr, "%s\n", __FUNCTION__); \
863 VFMT_FALLBACK( __FUNCTION__ ); \
865 #define TAG(x) radeon_fallback_##x
866 #include "vtxfmt_tmp.h"
870 static GLboolean
radeonNotifyBegin( GLcontext
*ctx
, GLenum p
)
872 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
874 if (RADEON_DEBUG
& DEBUG_VFMT
)
875 fprintf(stderr
, "%s\n", __FUNCTION__
);
877 assert(!rmesa
->vb
.installed
);
880 _mesa_update_state( ctx
);
882 if (rmesa
->NewGLState
)
883 radeonValidateState( ctx
);
885 if (ctx
->Driver
.NeedFlush
)
886 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
888 if (rmesa
->vb
.recheck
)
889 radeonVtxfmtValidate( ctx
);
891 if (!rmesa
->vb
.installed
) {
892 if (RADEON_DEBUG
& DEBUG_VFMT
)
893 fprintf(stderr
, "%s -- failed\n", __FUNCTION__
);
901 static void radeonVtxfmtFlushVertices( GLcontext
*ctx
, GLuint flags
)
903 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
905 if (RADEON_DEBUG
& DEBUG_VFMT
)
906 fprintf(stderr
, "%s\n", __FUNCTION__
);
908 assert(rmesa
->vb
.installed
);
910 if (flags
& FLUSH_UPDATE_CURRENT
) {
911 radeon_copy_to_current( ctx
);
912 if (RADEON_DEBUG
& DEBUG_VFMT
)
913 fprintf(stderr
, "reinstall on update_current\n");
914 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
915 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
918 if (flags
& FLUSH_STORED_VERTICES
) {
919 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
920 assert (rmesa
->dma
.flush
== 0 ||
921 rmesa
->dma
.flush
== flush_prims
);
922 if (rmesa
->dma
.flush
== flush_prims
)
923 flush_prims( RADEON_CONTEXT( ctx
) );
924 ctx
->Driver
.NeedFlush
&= ~FLUSH_STORED_VERTICES
;
930 /* At this point, don't expect very many versions of each function to
931 * be generated, so not concerned about freeing them?
935 void radeonVtxfmtInit( GLcontext
*ctx
, GLboolean useCodegen
)
937 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
938 GLvertexformat
*vfmt
= &(rmesa
->vb
.vtxfmt
);
940 MEMSET( vfmt
, 0, sizeof(GLvertexformat
) );
942 /* Hook in chooser functions for codegen, etc:
944 radeonVtxfmtInitChoosers( vfmt
);
946 /* Handled fully in supported states, but no codegen:
948 vfmt
->Materialfv
= radeon_Materialfv
;
949 vfmt
->ArrayElement
= _ae_loopback_array_elt
; /* generic helper */
950 vfmt
->Rectf
= _mesa_noop_Rectf
; /* generic helper */
951 vfmt
->Begin
= radeon_Begin
;
952 vfmt
->End
= radeon_End
;
954 /* Fallback for performance reasons: (Fix with cva/elt path here and
955 * dmatmp2.h style primitive-merging)
957 * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
960 vfmt
->DrawArrays
= radeon_fallback_DrawArrays
;
961 vfmt
->DrawElements
= radeon_fallback_DrawElements
;
962 vfmt
->DrawRangeElements
= radeon_fallback_DrawRangeElements
;
965 /* Not active in supported states; just keep ctx->Current uptodate:
967 vfmt
->FogCoordfvEXT
= _mesa_noop_FogCoordfvEXT
;
968 vfmt
->FogCoordfEXT
= _mesa_noop_FogCoordfEXT
;
969 vfmt
->EdgeFlag
= _mesa_noop_EdgeFlag
;
970 vfmt
->EdgeFlagv
= _mesa_noop_EdgeFlagv
;
971 vfmt
->Indexf
= _mesa_noop_Indexf
;
972 vfmt
->Indexfv
= _mesa_noop_Indexfv
;
975 /* Active but unsupported -- fallback if we receive these:
977 vfmt
->CallList
= radeon_fallback_CallList
;
978 vfmt
->CallLists
= radeon_fallback_CallLists
;
979 vfmt
->EvalCoord1f
= radeon_fallback_EvalCoord1f
;
980 vfmt
->EvalCoord1fv
= radeon_fallback_EvalCoord1fv
;
981 vfmt
->EvalCoord2f
= radeon_fallback_EvalCoord2f
;
982 vfmt
->EvalCoord2fv
= radeon_fallback_EvalCoord2fv
;
983 vfmt
->EvalMesh1
= radeon_fallback_EvalMesh1
;
984 vfmt
->EvalMesh2
= radeon_fallback_EvalMesh2
;
985 vfmt
->EvalPoint1
= radeon_fallback_EvalPoint1
;
986 vfmt
->EvalPoint2
= radeon_fallback_EvalPoint2
;
987 vfmt
->TexCoord3f
= radeon_fallback_TexCoord3f
;
988 vfmt
->TexCoord3fv
= radeon_fallback_TexCoord3fv
;
989 vfmt
->TexCoord4f
= radeon_fallback_TexCoord4f
;
990 vfmt
->TexCoord4fv
= radeon_fallback_TexCoord4fv
;
991 vfmt
->MultiTexCoord3fARB
= radeon_fallback_MultiTexCoord3fARB
;
992 vfmt
->MultiTexCoord3fvARB
= radeon_fallback_MultiTexCoord3fvARB
;
993 vfmt
->MultiTexCoord4fARB
= radeon_fallback_MultiTexCoord4fARB
;
994 vfmt
->MultiTexCoord4fvARB
= radeon_fallback_MultiTexCoord4fvARB
;
995 vfmt
->Vertex4f
= radeon_fallback_Vertex4f
;
996 vfmt
->Vertex4fv
= radeon_fallback_Vertex4fv
;
997 vfmt
->VertexAttrib1fNV
= radeon_fallback_VertexAttrib1fNV
;
998 vfmt
->VertexAttrib1fvNV
= radeon_fallback_VertexAttrib1fvNV
;
999 vfmt
->VertexAttrib2fNV
= radeon_fallback_VertexAttrib2fNV
;
1000 vfmt
->VertexAttrib2fvNV
= radeon_fallback_VertexAttrib2fvNV
;
1001 vfmt
->VertexAttrib3fNV
= radeon_fallback_VertexAttrib3fNV
;
1002 vfmt
->VertexAttrib3fvNV
= radeon_fallback_VertexAttrib3fvNV
;
1003 vfmt
->VertexAttrib4fNV
= radeon_fallback_VertexAttrib4fNV
;
1004 vfmt
->VertexAttrib4fvNV
= radeon_fallback_VertexAttrib4fvNV
;
1006 (void)radeon_fallback_vtxfmt
;
1008 TNL_CONTEXT(ctx
)->Driver
.NotifyBegin
= radeonNotifyBegin
;
1010 rmesa
->vb
.enabled
= 1;
1011 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
1012 rmesa
->vb
.primflags
= 0;
1014 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1015 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1016 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1017 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1018 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ub
);
1019 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1020 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ub
);
1021 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1022 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4f
);
1023 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4fv
);
1024 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3f
);
1025 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3fv
);
1026 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1027 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1028 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1029 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1030 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3f
);
1031 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1032 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1033 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1034 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1035 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1036 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1037 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1038 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1039 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1041 radeonInitCodegen( &rmesa
->vb
.codegen
, useCodegen
);
1044 static void free_funcs( struct dynfn
*l
)
1046 struct dynfn
*f
, *tmp
;
1047 foreach_s (f
, tmp
, l
) {
1048 remove_from_list( f
);
1049 ALIGN_FREE( f
->code
);
1056 void radeonVtxfmtMakeCurrent( GLcontext
*ctx
)
1061 void radeonVtxfmtDestroy( GLcontext
*ctx
)
1063 radeonContextPtr rmesa
= RADEON_CONTEXT( ctx
);
1065 count_funcs( rmesa
);
1066 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1067 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1068 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1069 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1070 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ub
);
1071 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1072 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ub
);
1073 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1074 free_funcs( &rmesa
->vb
.dfn_cache
.Color4f
);
1075 free_funcs( &rmesa
->vb
.dfn_cache
.Color4fv
);
1076 free_funcs( &rmesa
->vb
.dfn_cache
.Color3f
);
1077 free_funcs( &rmesa
->vb
.dfn_cache
.Color3fv
);
1078 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1079 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1080 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1081 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1082 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3f
);
1083 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1084 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1085 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1086 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1087 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1088 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1089 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1090 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1091 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);