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