patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_vtxfmt.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.5 2002/12/16 16:18:59 dawes Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 Tungsten Graphics Inc., Cedar Park, Texas.
6
7 All Rights Reserved.
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 #include "glheader.h"
36 #include "imports.h"
37 #include "api_noop.h"
38 #include "api_arrayelt.h"
39 #include "context.h"
40 #include "mtypes.h"
41 #include "enums.h"
42 #include "glapi.h"
43 #include "colormac.h"
44 #include "light.h"
45 #include "state.h"
46 #include "vtxfmt.h"
47
48 #include "tnl/tnl.h"
49 #include "tnl/t_context.h"
50 #include "tnl/t_array_api.h"
51
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"
59
60 static void radeonVtxfmtFlushVertices( GLcontext *, GLuint );
61
62 static void count_func( const char *name, struct dynfn *l )
63 {
64 int i = 0;
65 struct dynfn *f;
66 foreach (f, l) i++;
67 if (i) fprintf(stderr, "%s: %d\n", name, i );
68 }
69
70 static void count_funcs( radeonContextPtr rmesa )
71 {
72 count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f );
73 count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv );
74 count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f );
75 count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv );
76 count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub );
77 count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv );
78 count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub );
79 count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv );
80 count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f );
81 count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv );
82 count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f );
83 count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv );
84 count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
85 count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
86 count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
87 count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
88 count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f );
89 count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv );
90 count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f );
91 count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv );
92 count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f );
93 count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv );
94 count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
95 count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
96 count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
97 count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
98 }
99
100
101 void radeon_copy_to_current( GLcontext *ctx )
102 {
103 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
104
105 assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT);
106
107 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) {
108 ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0];
109 ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1];
110 ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2];
111 }
112
113 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) {
114 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red );
115 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green );
116 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue );
117 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha );
118 }
119
120 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) {
121 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0];
122 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1];
123 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2];
124 }
125
126 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA)
127 ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3];
128
129 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) {
130 ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red );
131 ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green );
132 ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue );
133 }
134
135 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_ST0) {
136 ctx->Current.Attrib[VERT_ATTRIB_TEX0][0] = rmesa->vb.texcoordptr[0][0];
137 ctx->Current.Attrib[VERT_ATTRIB_TEX0][1] = rmesa->vb.texcoordptr[0][1];
138 ctx->Current.Attrib[VERT_ATTRIB_TEX0][2] = 0.0F;
139 ctx->Current.Attrib[VERT_ATTRIB_TEX0][3] = 1.0F;
140 }
141
142 if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_ST1) {
143 ctx->Current.Attrib[VERT_ATTRIB_TEX1][0] = rmesa->vb.texcoordptr[1][0];
144 ctx->Current.Attrib[VERT_ATTRIB_TEX1][1] = rmesa->vb.texcoordptr[1][1];
145 ctx->Current.Attrib[VERT_ATTRIB_TEX1][2] = 0.0F;
146 ctx->Current.Attrib[VERT_ATTRIB_TEX1][3] = 1.0F;
147 }
148
149 ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
150 }
151
152 static GLboolean discreet_gl_prim[GL_POLYGON+1] = {
153 1, /* 0 points */
154 1, /* 1 lines */
155 0, /* 2 line_strip */
156 0, /* 3 line_loop */
157 1, /* 4 tris */
158 0, /* 5 tri_fan */
159 0, /* 6 tri_strip */
160 1, /* 7 quads */
161 0, /* 8 quadstrip */
162 0, /* 9 poly */
163 };
164
165 static void flush_prims( radeonContextPtr rmesa )
166 {
167 int i,j;
168 struct radeon_dma_region tmp = rmesa->dma.current;
169
170 tmp.buf->refcount++;
171 tmp.aos_size = rmesa->vb.vertex_size;
172 tmp.aos_stride = rmesa->vb.vertex_size;
173 tmp.aos_start = GET_START(&tmp);
174
175 rmesa->dma.current.ptr = rmesa->dma.current.start +=
176 (rmesa->vb.initial_counter - rmesa->vb.counter) * rmesa->vb.vertex_size * 4;
177
178 rmesa->tcl.vertex_format = rmesa->vb.vertex_format;
179 rmesa->tcl.aos_components[0] = &tmp;
180 rmesa->tcl.nr_aos_components = 1;
181 rmesa->dma.flush = 0;
182
183 /* Optimize the primitive list:
184 */
185 if (rmesa->vb.nrprims > 1) {
186 for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) {
187 int pj = rmesa->vb.primlist[j].prim & 0xf;
188 int pi = rmesa->vb.primlist[i].prim & 0xf;
189
190 if (pj == pi && discreet_gl_prim[pj] &&
191 rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) {
192 rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end;
193 }
194 else {
195 j++;
196 if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i];
197 }
198 }
199 rmesa->vb.nrprims = j+1;
200 }
201
202 for (i = 0 ; i < rmesa->vb.nrprims; i++) {
203 if (RADEON_DEBUG & DEBUG_PRIMS)
204 fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i,
205 _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim &
206 PRIM_MODE_MASK ),
207 rmesa->vb.primlist[i].start,
208 rmesa->vb.primlist[i].end);
209
210 radeonEmitPrimitive( rmesa->glCtx,
211 rmesa->vb.primlist[i].start,
212 rmesa->vb.primlist[i].end,
213 rmesa->vb.primlist[i].prim );
214 }
215
216 rmesa->vb.nrprims = 0;
217 radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ );
218 }
219
220
221 static void start_prim( radeonContextPtr rmesa, GLuint mode )
222 {
223 if (RADEON_DEBUG & DEBUG_VFMT)
224 fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter);
225
226 rmesa->vb.primlist[rmesa->vb.nrprims].start = rmesa->vb.initial_counter - rmesa->vb.counter;
227 rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode;
228 }
229
230 static void note_last_prim( radeonContextPtr rmesa, GLuint flags )
231 {
232 if (RADEON_DEBUG & DEBUG_VFMT)
233 fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter);
234
235 if (rmesa->vb.prim[0] != GL_POLYGON+1) {
236 rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags;
237 rmesa->vb.primlist[rmesa->vb.nrprims].end = rmesa->vb.initial_counter - rmesa->vb.counter;
238
239 if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS)
240 flush_prims( rmesa );
241 }
242 }
243
244
245 static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst )
246 {
247 GLuint i;
248 GLfloat *src = (GLfloat *)(rmesa->dma.current.address +
249 rmesa->dma.current.ptr +
250 (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) *
251 rmesa->vb.vertex_size * 4);
252
253 if (RADEON_DEBUG & DEBUG_VFMT)
254 fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n);
255
256 for (i = 0 ; i < rmesa->vb.vertex_size; i++) {
257 dst[i] = src[i];
258 }
259 }
260
261 /* NOTE: This actually reads the copied vertices back from uncached
262 * memory. Could also use the counter/notify mechanism to populate
263 * tmp on the fly as vertices are generated.
264 */
265 static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[15] )
266 {
267 GLuint ovf, i;
268 GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start;
269
270 if (RADEON_DEBUG & DEBUG_VFMT)
271 fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr);
272
273 switch( rmesa->vb.prim[0] )
274 {
275 case GL_POINTS:
276 return 0;
277 case GL_LINES:
278 ovf = nr&1;
279 for (i = 0 ; i < ovf ; i++)
280 copy_vertex( rmesa, nr-ovf+i, tmp[i] );
281 return i;
282 case GL_TRIANGLES:
283 ovf = nr%3;
284 for (i = 0 ; i < ovf ; i++)
285 copy_vertex( rmesa, nr-ovf+i, tmp[i] );
286 return i;
287 case GL_QUADS:
288 ovf = nr&3;
289 for (i = 0 ; i < ovf ; i++)
290 copy_vertex( rmesa, nr-ovf+i, tmp[i] );
291 return i;
292 case GL_LINE_STRIP:
293 if (nr == 0)
294 return 0;
295 copy_vertex( rmesa, nr-1, tmp[0] );
296 return 1;
297 case GL_LINE_LOOP:
298 case GL_TRIANGLE_FAN:
299 case GL_POLYGON:
300 if (nr == 0)
301 return 0;
302 else if (nr == 1) {
303 copy_vertex( rmesa, 0, tmp[0] );
304 return 1;
305 } else {
306 copy_vertex( rmesa, 0, tmp[0] );
307 copy_vertex( rmesa, nr-1, tmp[1] );
308 return 2;
309 }
310 case GL_TRIANGLE_STRIP:
311 ovf = MIN2(nr, 2);
312 for (i = 0 ; i < ovf ; i++)
313 copy_vertex( rmesa, nr-ovf+i, tmp[i] );
314 return i;
315 case GL_QUAD_STRIP:
316 switch (nr) {
317 case 0: ovf = 0; break;
318 case 1: ovf = 1; break;
319 default: ovf = 2 + (nr&1); break;
320 }
321 for (i = 0 ; i < ovf ; i++)
322 copy_vertex( rmesa, nr-ovf+i, tmp[i] );
323 return i;
324 default:
325 assert(0);
326 return 0;
327 }
328 }
329
330 static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller )
331 {
332 GET_CURRENT_CONTEXT(ctx);
333 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
334
335 if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
336 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
337
338 if (ctx->Driver.NeedFlush)
339 radeonVtxfmtFlushVertices( ctx, ctx->Driver.NeedFlush );
340
341 if (ctx->NewState)
342 _mesa_update_state( ctx ); /* clear state so fell_back sticks */
343
344 _tnl_wakeup_exec( ctx );
345 ctx->Driver.FlushVertices = radeonFlushVertices;
346
347 assert( rmesa->dma.flush == 0 );
348 rmesa->vb.fell_back = GL_TRUE;
349 rmesa->vb.installed = GL_FALSE;
350 }
351
352
353 static void VFMT_FALLBACK( const char *caller )
354 {
355 GET_CURRENT_CONTEXT(ctx);
356 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
357 GLfloat tmp[3][15];
358 GLuint i, prim;
359 GLuint ind = rmesa->vb.vertex_format;
360 GLuint nrverts;
361 GLfloat alpha = 1.0;
362
363 if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT))
364 fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
365
366 if (rmesa->vb.prim[0] == GL_POLYGON+1) {
367 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
368 return;
369 }
370
371 /* Copy vertices out of dma:
372 */
373 nrverts = copy_dma_verts( rmesa, tmp );
374
375 /* Finish the prim at this point:
376 */
377 note_last_prim( rmesa, 0 );
378 flush_prims( rmesa );
379
380 /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
381 */
382 prim = rmesa->vb.prim[0];
383 ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
384 _tnl_wakeup_exec( ctx );
385 ctx->Driver.FlushVertices = radeonFlushVertices;
386
387 assert(rmesa->dma.flush == 0);
388 rmesa->vb.fell_back = GL_TRUE;
389 rmesa->vb.installed = GL_FALSE;
390 glBegin( prim );
391
392 if (rmesa->vb.installed_color_3f_sz == 4)
393 alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
394
395 /* Replay saved vertices
396 */
397 for (i = 0 ; i < nrverts; i++) {
398 GLuint offset = 3;
399 if (ind & RADEON_CP_VC_FRMT_N0) {
400 glNormal3fv( &tmp[i][offset] );
401 offset += 3;
402 }
403
404 if (ind & RADEON_CP_VC_FRMT_PKCOLOR) {
405 radeon_color_t *col = (radeon_color_t *)&tmp[i][offset];
406 glColor4ub( col->red, col->green, col->blue, col->alpha );
407 offset++;
408 }
409 else if (ind & RADEON_CP_VC_FRMT_FPALPHA) {
410 glColor4fv( &tmp[i][offset] );
411 offset+=4;
412 }
413 else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
414 glColor3fv( &tmp[i][offset] );
415 offset+=3;
416 }
417
418 if (ind & RADEON_CP_VC_FRMT_PKSPEC) {
419 radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset];
420 _glapi_Dispatch->SecondaryColor3ubEXT( spec->red, spec->green, spec->blue );
421 offset++;
422 }
423
424 if (ind & RADEON_CP_VC_FRMT_ST0) {
425 glTexCoord2fv( &tmp[i][offset] );
426 offset += 2;
427 }
428
429 if (ind & RADEON_CP_VC_FRMT_ST1) {
430 glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, &tmp[i][offset] );
431 offset += 2;
432 }
433 glVertex3fv( &tmp[i][0] );
434 }
435
436 /* Replay current vertex
437 */
438 if (ind & RADEON_CP_VC_FRMT_N0)
439 glNormal3fv( rmesa->vb.normalptr );
440
441 if (ind & RADEON_CP_VC_FRMT_PKCOLOR)
442 glColor4ub( rmesa->vb.colorptr->red, rmesa->vb.colorptr->green, rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha );
443 else if (ind & RADEON_CP_VC_FRMT_FPALPHA)
444 glColor4fv( rmesa->vb.floatcolorptr );
445 else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
446 if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0)
447 glColor4f( rmesa->vb.floatcolorptr[0],
448 rmesa->vb.floatcolorptr[1],
449 rmesa->vb.floatcolorptr[2],
450 alpha );
451 else
452 glColor3fv( rmesa->vb.floatcolorptr );
453 }
454
455 if (ind & RADEON_CP_VC_FRMT_PKSPEC)
456 _glapi_Dispatch->SecondaryColor3ubEXT( rmesa->vb.specptr->red, rmesa->vb.specptr->green, rmesa->vb.specptr->blue );
457
458 if (ind & RADEON_CP_VC_FRMT_ST0)
459 glTexCoord2fv( rmesa->vb.texcoordptr[0] );
460
461 if (ind & RADEON_CP_VC_FRMT_ST1)
462 glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, rmesa->vb.texcoordptr[1] );
463 }
464
465
466
467 static void wrap_buffer( void )
468 {
469 GET_CURRENT_CONTEXT(ctx);
470 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
471 GLfloat tmp[3][15];
472 GLuint i, nrverts;
473
474 if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS))
475 fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter);
476
477 /* Don't deal with parity.
478 */
479 if ((((rmesa->vb.initial_counter - rmesa->vb.counter) -
480 rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) {
481 rmesa->vb.counter++;
482 rmesa->vb.initial_counter++;
483 return;
484 }
485
486 /* Copy vertices out of dma:
487 */
488 if (rmesa->vb.prim[0] == GL_POLYGON+1)
489 nrverts = 0;
490 else {
491 nrverts = copy_dma_verts( rmesa, tmp );
492
493 if (RADEON_DEBUG & DEBUG_VFMT)
494 fprintf(stderr, "%d vertices to copy\n", nrverts);
495
496 /* Finish the prim at this point:
497 */
498 note_last_prim( rmesa, 0 );
499 }
500
501 /* Fire any buffered primitives
502 */
503 flush_prims( rmesa );
504
505 /* Get new buffer
506 */
507 radeonRefillCurrentDmaRegion( rmesa );
508
509 /* Reset counter, dmaptr
510 */
511 rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address);
512 rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
513 (rmesa->vb.vertex_size * 4);
514 rmesa->vb.counter--;
515 rmesa->vb.initial_counter = rmesa->vb.counter;
516 rmesa->vb.notify = wrap_buffer;
517
518 rmesa->dma.flush = flush_prims;
519
520 /* Restart wrapped primitive:
521 */
522 if (rmesa->vb.prim[0] != GL_POLYGON+1)
523 start_prim( rmesa, rmesa->vb.prim[0] );
524
525 /* Reemit saved vertices
526 */
527 for (i = 0 ; i < nrverts; i++) {
528 if (RADEON_DEBUG & DEBUG_VERTS) {
529 int j;
530 fprintf(stderr, "re-emit vertex %d to %p\n", i, rmesa->vb.dmaptr);
531 if (RADEON_DEBUG & DEBUG_VERBOSE)
532 for (j = 0 ; j < rmesa->vb.vertex_size; j++)
533 fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]);
534 }
535
536 memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 );
537 rmesa->vb.dmaptr += rmesa->vb.vertex_size;
538 rmesa->vb.counter--;
539 }
540 }
541
542
543
544 static GLboolean check_vtx_fmt( GLcontext *ctx )
545 {
546 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
547 GLuint ind = RADEON_CP_VC_FRMT_Z;
548
549 if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
550 return GL_FALSE;
551
552 if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
553 ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
554
555 /* Make all this event-driven:
556 */
557 if (ctx->Light.Enabled) {
558 ind |= RADEON_CP_VC_FRMT_N0;
559
560 /* TODO: make this data driven: If we receive only ubytes, send
561 * color as ubytes. Also check if converting (with free
562 * checking for overflow) is cheaper than sending floats
563 * directly.
564 */
565 if (ctx->Light.ColorMaterialEnabled) {
566 ind |= (RADEON_CP_VC_FRMT_FPCOLOR |
567 RADEON_CP_VC_FRMT_FPALPHA);
568 }
569 else
570 ind |= RADEON_CP_VC_FRMT_PKCOLOR; /* for alpha? */
571 }
572 else {
573 /* TODO: make this data driven?
574 */
575 ind |= RADEON_CP_VC_FRMT_PKCOLOR;
576
577 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
578 ind |= RADEON_CP_VC_FRMT_PKSPEC;
579 }
580 }
581
582 if (ctx->Texture.Unit[0]._ReallyEnabled) {
583 if (ctx->Texture.Unit[0].TexGenEnabled) {
584 if (rmesa->TexGenNeedNormals[0]) {
585 ind |= RADEON_CP_VC_FRMT_N0;
586 }
587 } else {
588 if (ctx->Current.Attrib[VERT_ATTRIB_TEX0][2] != 0.0F ||
589 ctx->Current.Attrib[VERT_ATTRIB_TEX0][3] != 1.0) {
590 if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
591 fprintf(stderr, "%s: rq0\n", __FUNCTION__);
592 return GL_FALSE;
593 }
594 ind |= RADEON_CP_VC_FRMT_ST0;
595 }
596 }
597
598 if (ctx->Texture.Unit[1]._ReallyEnabled) {
599 if (ctx->Texture.Unit[1].TexGenEnabled) {
600 if (rmesa->TexGenNeedNormals[1]) {
601 ind |= RADEON_CP_VC_FRMT_N0;
602 }
603 } else {
604 if (ctx->Current.Attrib[VERT_ATTRIB_TEX1][2] != 0.0F ||
605 ctx->Current.Attrib[VERT_ATTRIB_TEX1][3] != 1.0) {
606 if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
607 fprintf(stderr, "%s: rq1\n", __FUNCTION__);
608 return GL_FALSE;
609 }
610 ind |= RADEON_CP_VC_FRMT_ST1;
611 }
612 }
613
614 if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE))
615 fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind );
616
617 RADEON_NEWPRIM(rmesa);
618 rmesa->vb.vertex_format = ind;
619 rmesa->vb.vertex_size = 3;
620 rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
621
622 rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
623 rmesa->vb.colorptr = NULL;
624 rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
625 rmesa->vb.specptr = NULL;
626 rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
627 rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
628 rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1];
629
630 /* Run through and initialize the vertex components in the order
631 * the hardware understands:
632 */
633 if (ind & RADEON_CP_VC_FRMT_N0) {
634 rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
635 rmesa->vb.vertex_size += 3;
636 rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0];
637 rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1];
638 rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2];
639 }
640
641 if (ind & RADEON_CP_VC_FRMT_PKCOLOR) {
642 rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
643 rmesa->vb.vertex_size += 1;
644 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] );
645 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] );
646 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] );
647 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] );
648 }
649
650 if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
651 assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR));
652 rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
653 rmesa->vb.vertex_size += 3;
654 rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0];
655 rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1];
656 rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2];
657
658 if (ind & RADEON_CP_VC_FRMT_FPALPHA) {
659 rmesa->vb.vertex_size += 1;
660 rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3];
661 }
662 }
663
664 if (ind & RADEON_CP_VC_FRMT_PKSPEC) {
665 rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
666 rmesa->vb.vertex_size += 1;
667 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] );
668 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] );
669 UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] );
670 }
671
672 if (ind & RADEON_CP_VC_FRMT_ST0) {
673 rmesa->vb.texcoordptr[0] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
674 rmesa->vb.vertex_size += 2;
675 rmesa->vb.texcoordptr[0][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][0];
676 rmesa->vb.texcoordptr[0][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][1];
677 }
678
679 if (ind & RADEON_CP_VC_FRMT_ST1) {
680 rmesa->vb.texcoordptr[1] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
681 rmesa->vb.vertex_size += 2;
682 rmesa->vb.texcoordptr[1][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX1][0];
683 rmesa->vb.texcoordptr[1][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1][1];
684 }
685
686 if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) {
687 if (RADEON_DEBUG & DEBUG_VFMT)
688 fprintf(stderr, "reinstall on vertex_format change\n");
689 _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
690 rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format;
691 }
692
693 if (RADEON_DEBUG & DEBUG_VFMT)
694 fprintf(stderr, "%s -- success\n", __FUNCTION__);
695
696 return GL_TRUE;
697 }
698
699 void radeonVtxfmtInvalidate( GLcontext *ctx )
700 {
701 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
702
703 rmesa->vb.recheck = GL_TRUE;
704 rmesa->vb.fell_back = GL_FALSE;
705 }
706
707
708 static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode )
709 {
710 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
711 }
712
713
714 static void radeonVtxfmtValidate( GLcontext *ctx )
715 {
716 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
717
718 if (RADEON_DEBUG & DEBUG_VFMT)
719 fprintf(stderr, "%s\n", __FUNCTION__);
720
721 if (ctx->Driver.NeedFlush)
722 ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
723
724 rmesa->vb.recheck = GL_FALSE;
725
726 if (check_vtx_fmt( ctx )) {
727 if (!rmesa->vb.installed) {
728 if (RADEON_DEBUG & DEBUG_VFMT)
729 fprintf(stderr, "reinstall (new install)\n");
730
731 _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
732 ctx->Driver.FlushVertices = radeonVtxfmtFlushVertices;
733 ctx->Driver.NewList = radeonNewList;
734 rmesa->vb.installed = GL_TRUE;
735 }
736 else if (RADEON_DEBUG & DEBUG_VFMT)
737 fprintf(stderr, "%s: already installed", __FUNCTION__);
738 }
739 else {
740 if (RADEON_DEBUG & DEBUG_VFMT)
741 fprintf(stderr, "%s: failed\n", __FUNCTION__);
742
743 if (rmesa->vb.installed) {
744 if (rmesa->dma.flush)
745 rmesa->dma.flush( rmesa );
746 _tnl_wakeup_exec( ctx );
747 ctx->Driver.FlushVertices = radeonFlushVertices;
748 rmesa->vb.installed = GL_FALSE;
749 }
750 }
751 }
752
753
754
755 /* Materials:
756 */
757 static void radeon_Materialfv( GLenum face, GLenum pname,
758 const GLfloat *params )
759 {
760 GET_CURRENT_CONTEXT(ctx);
761 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
762
763 if (RADEON_DEBUG & DEBUG_VFMT)
764 fprintf(stderr, "%s\n", __FUNCTION__);
765
766 if (rmesa->vb.prim[0] != GL_POLYGON+1) {
767 VFMT_FALLBACK( __FUNCTION__ );
768 glMaterialfv( face, pname, params );
769 return;
770 }
771 _mesa_noop_Materialfv( face, pname, params );
772 radeonUpdateMaterial( ctx );
773 }
774
775
776 /* Begin/End
777 */
778 static void radeon_Begin( GLenum mode )
779 {
780 GET_CURRENT_CONTEXT(ctx);
781 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
782
783 if (RADEON_DEBUG & DEBUG_VFMT)
784 fprintf(stderr, "%s( %s )\n", __FUNCTION__,
785 _mesa_lookup_enum_by_nr( mode ));
786
787 if (mode > GL_POLYGON) {
788 _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
789 return;
790 }
791
792 if (rmesa->vb.prim[0] != GL_POLYGON+1) {
793 _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
794 return;
795 }
796
797 if (ctx->NewState)
798 _mesa_update_state( ctx );
799
800 if (rmesa->NewGLState)
801 radeonValidateState( ctx );
802
803 if (rmesa->vb.recheck)
804 radeonVtxfmtValidate( ctx );
805
806 if (!rmesa->vb.installed) {
807 glBegin( mode );
808 return;
809 }
810
811
812 if (rmesa->dma.flush && rmesa->vb.counter < 12) {
813 if (RADEON_DEBUG & DEBUG_VFMT)
814 fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__);
815 flush_prims( rmesa );
816 }
817
818 /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
819 */
820 if (!rmesa->dma.flush) {
821 if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 >
822 rmesa->dma.current.end) {
823 RADEON_NEWPRIM( rmesa );
824 radeonRefillCurrentDmaRegion( rmesa );
825 }
826
827 rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
828 rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
829 (rmesa->vb.vertex_size * 4);
830 rmesa->vb.counter--;
831 rmesa->vb.initial_counter = rmesa->vb.counter;
832 rmesa->vb.notify = wrap_buffer;
833 rmesa->dma.flush = flush_prims;
834 ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
835 }
836
837
838 rmesa->vb.prim[0] = mode;
839 start_prim( rmesa, mode | PRIM_BEGIN );
840 }
841
842
843
844 static void radeon_End( void )
845 {
846 GET_CURRENT_CONTEXT(ctx);
847 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
848
849 if (RADEON_DEBUG & DEBUG_VFMT)
850 fprintf(stderr, "%s\n", __FUNCTION__);
851
852 if (rmesa->vb.prim[0] == GL_POLYGON+1) {
853 _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
854 return;
855 }
856
857 note_last_prim( rmesa, PRIM_END );
858 rmesa->vb.prim[0] = GL_POLYGON+1;
859 }
860
861
862 /* Fallback on difficult entrypoints:
863 */
864 #define PRE_LOOPBACK( FUNC ) \
865 do { \
866 if (RADEON_DEBUG & DEBUG_VFMT) \
867 fprintf(stderr, "%s\n", __FUNCTION__); \
868 VFMT_FALLBACK( __FUNCTION__ ); \
869 } while (0)
870 #define TAG(x) radeon_fallback_##x
871 #include "vtxfmt_tmp.h"
872
873
874
875 static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p )
876 {
877 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
878
879 if (RADEON_DEBUG & DEBUG_VFMT)
880 fprintf(stderr, "%s\n", __FUNCTION__);
881
882 assert(!rmesa->vb.installed);
883
884 if (ctx->NewState)
885 _mesa_update_state( ctx );
886
887 if (rmesa->NewGLState)
888 radeonValidateState( ctx );
889
890 if (ctx->Driver.NeedFlush)
891 ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
892
893 if (rmesa->vb.recheck)
894 radeonVtxfmtValidate( ctx );
895
896 if (!rmesa->vb.installed) {
897 if (RADEON_DEBUG & DEBUG_VFMT)
898 fprintf(stderr, "%s -- failed\n", __FUNCTION__);
899 return GL_FALSE;
900 }
901
902 radeon_Begin( p );
903 return GL_TRUE;
904 }
905
906 static void radeonVtxfmtFlushVertices( GLcontext *ctx, GLuint flags )
907 {
908 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
909
910 if (RADEON_DEBUG & DEBUG_VFMT)
911 fprintf(stderr, "%s\n", __FUNCTION__);
912
913 assert(rmesa->vb.installed);
914
915 if (flags & FLUSH_UPDATE_CURRENT) {
916 radeon_copy_to_current( ctx );
917 if (RADEON_DEBUG & DEBUG_VFMT)
918 fprintf(stderr, "reinstall on update_current\n");
919 _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
920 ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
921 }
922
923 if (flags & FLUSH_STORED_VERTICES) {
924 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
925 assert (rmesa->dma.flush == 0 ||
926 rmesa->dma.flush == flush_prims);
927 if (rmesa->dma.flush == flush_prims)
928 flush_prims( RADEON_CONTEXT( ctx ) );
929 ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
930 }
931 }
932
933
934
935 /* At this point, don't expect very many versions of each function to
936 * be generated, so not concerned about freeing them?
937 */
938
939
940 void radeonVtxfmtInit( GLcontext *ctx )
941 {
942 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
943 GLvertexformat *vfmt = &(rmesa->vb.vtxfmt);
944
945 MEMSET( vfmt, 0, sizeof(GLvertexformat) );
946
947 /* Hook in chooser functions for codegen, etc:
948 */
949 radeonVtxfmtInitChoosers( vfmt );
950
951 /* Handled fully in supported states, but no codegen:
952 */
953 vfmt->Materialfv = radeon_Materialfv;
954 vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
955 vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
956 vfmt->Begin = radeon_Begin;
957 vfmt->End = radeon_End;
958
959 /* Fallback for performance reasons: (Fix with cva/elt path here and
960 * dmatmp2.h style primitive-merging)
961 *
962 * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
963 * a driver-hook.
964 */
965 vfmt->DrawArrays = radeon_fallback_DrawArrays;
966 vfmt->DrawElements = radeon_fallback_DrawElements;
967 vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements;
968
969
970 /* Not active in supported states; just keep ctx->Current uptodate:
971 */
972 vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT;
973 vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT;
974 vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
975 vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
976 vfmt->Indexi = _mesa_noop_Indexi;
977 vfmt->Indexiv = _mesa_noop_Indexiv;
978
979
980 /* Active but unsupported -- fallback if we receive these:
981 */
982 vfmt->CallList = radeon_fallback_CallList;
983 vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f;
984 vfmt->EvalCoord1fv = radeon_fallback_EvalCoord1fv;
985 vfmt->EvalCoord2f = radeon_fallback_EvalCoord2f;
986 vfmt->EvalCoord2fv = radeon_fallback_EvalCoord2fv;
987 vfmt->EvalMesh1 = radeon_fallback_EvalMesh1;
988 vfmt->EvalMesh2 = radeon_fallback_EvalMesh2;
989 vfmt->EvalPoint1 = radeon_fallback_EvalPoint1;
990 vfmt->EvalPoint2 = radeon_fallback_EvalPoint2;
991 vfmt->TexCoord3f = radeon_fallback_TexCoord3f;
992 vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv;
993 vfmt->TexCoord4f = radeon_fallback_TexCoord4f;
994 vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv;
995 vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB;
996 vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB;
997 vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB;
998 vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB;
999 vfmt->Vertex4f = radeon_fallback_Vertex4f;
1000 vfmt->Vertex4fv = radeon_fallback_Vertex4fv;
1001
1002 (void)radeon_fallback_vtxfmt;
1003
1004 TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin;
1005
1006 rmesa->vb.enabled = 1;
1007 rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
1008 rmesa->vb.primflags = 0;
1009
1010 make_empty_list( &rmesa->vb.dfn_cache.Vertex2f );
1011 make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv );
1012 make_empty_list( &rmesa->vb.dfn_cache.Vertex3f );
1013 make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv );
1014 make_empty_list( &rmesa->vb.dfn_cache.Color4ub );
1015 make_empty_list( &rmesa->vb.dfn_cache.Color4ubv );
1016 make_empty_list( &rmesa->vb.dfn_cache.Color3ub );
1017 make_empty_list( &rmesa->vb.dfn_cache.Color3ubv );
1018 make_empty_list( &rmesa->vb.dfn_cache.Color4f );
1019 make_empty_list( &rmesa->vb.dfn_cache.Color4fv );
1020 make_empty_list( &rmesa->vb.dfn_cache.Color3f );
1021 make_empty_list( &rmesa->vb.dfn_cache.Color3fv );
1022 make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
1023 make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
1024 make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
1025 make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
1026 make_empty_list( &rmesa->vb.dfn_cache.Normal3f );
1027 make_empty_list( &rmesa->vb.dfn_cache.Normal3fv );
1028 make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f );
1029 make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv );
1030 make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f );
1031 make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv );
1032 make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
1033 make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
1034 make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
1035 make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
1036
1037 radeonInitCodegen( &rmesa->vb.codegen );
1038 }
1039
1040 static void free_funcs( struct dynfn *l )
1041 {
1042 struct dynfn *f, *tmp;
1043 foreach_s (f, tmp, l) {
1044 remove_from_list( f );
1045 ALIGN_FREE( f->code );
1046 FREE( f );
1047 }
1048 }
1049
1050
1051
1052 void radeonVtxfmtMakeCurrent( GLcontext *ctx )
1053 {
1054 }
1055
1056
1057 void radeonVtxfmtDestroy( GLcontext *ctx )
1058 {
1059 radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
1060
1061 count_funcs( rmesa );
1062 free_funcs( &rmesa->vb.dfn_cache.Vertex2f );
1063 free_funcs( &rmesa->vb.dfn_cache.Vertex2fv );
1064 free_funcs( &rmesa->vb.dfn_cache.Vertex3f );
1065 free_funcs( &rmesa->vb.dfn_cache.Vertex3fv );
1066 free_funcs( &rmesa->vb.dfn_cache.Color4ub );
1067 free_funcs( &rmesa->vb.dfn_cache.Color4ubv );
1068 free_funcs( &rmesa->vb.dfn_cache.Color3ub );
1069 free_funcs( &rmesa->vb.dfn_cache.Color3ubv );
1070 free_funcs( &rmesa->vb.dfn_cache.Color4f );
1071 free_funcs( &rmesa->vb.dfn_cache.Color4fv );
1072 free_funcs( &rmesa->vb.dfn_cache.Color3f );
1073 free_funcs( &rmesa->vb.dfn_cache.Color3fv );
1074 free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
1075 free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
1076 free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
1077 free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
1078 free_funcs( &rmesa->vb.dfn_cache.Normal3f );
1079 free_funcs( &rmesa->vb.dfn_cache.Normal3fv );
1080 free_funcs( &rmesa->vb.dfn_cache.TexCoord2f );
1081 free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv );
1082 free_funcs( &rmesa->vb.dfn_cache.TexCoord1f );
1083 free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv );
1084 free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
1085 free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
1086 free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
1087 free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
1088 }
1089