1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c,v 1.4 2003/05/06 23:52:08 daenzer Exp $ */
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "r200_context.h"
39 #include "r200_state.h"
40 #include "r200_ioctl.h"
43 #include "r200_swtcl.h"
44 #include "r200_vtxfmt.h"
47 #include "api_arrayelt.h"
58 #include "tnl/t_context.h"
59 #include "tnl/t_array_api.h"
61 static void r200VtxFmtFlushVertices( GLcontext
*, GLuint
);
63 static void count_func( const char *name
, struct dynfn
*l
)
68 if (i
) fprintf(stderr
, "%s: %d\n", name
, i
);
71 static void count_funcs( r200ContextPtr rmesa
)
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( "TexCoord3f", &rmesa
->vb
.dfn_cache
.TexCoord3f
);
92 count_func( "TexCoord3fv", &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
93 count_func( "TexCoord2f", &rmesa
->vb
.dfn_cache
.TexCoord2f
);
94 count_func( "TexCoord2fv", &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
95 count_func( "TexCoord1f", &rmesa
->vb
.dfn_cache
.TexCoord1f
);
96 count_func( "TexCoord1fv", &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
97 count_func( "MultiTexCoord3fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
98 count_func( "MultiTexCoord3fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
99 count_func( "MultiTexCoord2fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
100 count_func( "MultiTexCoord2fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
101 count_func( "MultiTexCoord1fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
102 count_func( "MultiTexCoord1fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
103 /* count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT );
104 count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
108 void r200_copy_to_current( GLcontext
*ctx
)
110 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
113 if (R200_DEBUG
& DEBUG_VFMT
)
114 fprintf(stderr
, "%s\n", __FUNCTION__
);
116 assert(ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
);
118 if (rmesa
->vb
.vtxfmt_0
& R200_VTX_N0
) {
119 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0] = rmesa
->vb
.normalptr
[0];
120 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1] = rmesa
->vb
.normalptr
[1];
121 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2] = rmesa
->vb
.normalptr
[2];
124 if (rmesa
->vb
.vtxfmt_0
& R200_VTX_DISCRETE_FOG
) {
125 ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
][0] = rmesa
->vb
.fogptr
[0];
128 switch( VTX_COLOR(rmesa
->vb
.vtxfmt_0
, 0) ) {
129 case R200_VTX_PK_RGBA
:
130 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->red
);
131 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->green
);
132 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->blue
);
133 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->alpha
);
136 case R200_VTX_FP_RGB
:
137 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = rmesa
->vb
.floatcolorptr
[0];
138 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = rmesa
->vb
.floatcolorptr
[1];
139 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = rmesa
->vb
.floatcolorptr
[2];
142 case R200_VTX_FP_RGBA
:
143 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = rmesa
->vb
.floatcolorptr
[0];
144 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = rmesa
->vb
.floatcolorptr
[1];
145 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = rmesa
->vb
.floatcolorptr
[2];
146 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = rmesa
->vb
.floatcolorptr
[3];
153 if (VTX_COLOR(rmesa
->vb
.vtxfmt_0
, 1) == R200_VTX_PK_RGBA
) {
154 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->red
);
155 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->green
);
156 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->blue
);
159 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
160 const unsigned count
= VTX_TEXn_COUNT( rmesa
->vb
.vtxfmt_1
, i
);
161 GLfloat
* const src
= rmesa
->vb
.texcoordptr
[i
];
166 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = src
[1];
167 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = src
[2];
170 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = src
[1];
171 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = 0.0F
;
174 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = 0.0F
;
175 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = 0.0F
;
179 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][0] = src
[0];
180 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][3] = 1.0F
;
184 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
187 static GLboolean discreet_gl_prim
[GL_POLYGON
+1] = {
190 0, /* 2 line_strip */
200 static void flush_prims( r200ContextPtr rmesa
)
203 struct r200_dma_region tmp
= rmesa
->dma
.current
;
206 tmp
.aos_size
= rmesa
->vb
.vertex_size
;
207 tmp
.aos_stride
= rmesa
->vb
.vertex_size
;
208 tmp
.aos_start
= GET_START(&tmp
);
210 rmesa
->dma
.current
.ptr
= rmesa
->dma
.current
.start
+=
211 (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) *
212 rmesa
->vb
.vertex_size
* 4;
214 rmesa
->tcl
.vertex_format
= rmesa
->vb
.vtxfmt_0
;
215 rmesa
->tcl
.aos_components
[0] = &tmp
;
216 rmesa
->tcl
.nr_aos_components
= 1;
217 rmesa
->dma
.flush
= 0;
219 /* Optimize the primitive list:
221 if (rmesa
->vb
.nrprims
> 1) {
222 for (j
= 0, i
= 1 ; i
< rmesa
->vb
.nrprims
; i
++) {
223 int pj
= rmesa
->vb
.primlist
[j
].prim
& 0xf;
224 int pi
= rmesa
->vb
.primlist
[i
].prim
& 0xf;
226 if (pj
== pi
&& discreet_gl_prim
[pj
] &&
227 rmesa
->vb
.primlist
[i
].start
== rmesa
->vb
.primlist
[j
].end
) {
228 rmesa
->vb
.primlist
[j
].end
= rmesa
->vb
.primlist
[i
].end
;
232 if (j
!= i
) rmesa
->vb
.primlist
[j
] = rmesa
->vb
.primlist
[i
];
235 rmesa
->vb
.nrprims
= j
+1;
238 if (rmesa
->vb
.vtxfmt_0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
239 rmesa
->vb
.vtxfmt_1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
240 R200_STATECHANGE( rmesa
, vtx
);
241 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = rmesa
->vb
.vtxfmt_0
;
242 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = rmesa
->vb
.vtxfmt_1
;
246 for (i
= 0 ; i
< rmesa
->vb
.nrprims
; i
++) {
247 if (R200_DEBUG
& DEBUG_PRIMS
)
248 fprintf(stderr
, "vtxfmt prim %d: %s %d..%d\n", i
,
249 _mesa_lookup_enum_by_nr( rmesa
->vb
.primlist
[i
].prim
&
251 rmesa
->vb
.primlist
[i
].start
,
252 rmesa
->vb
.primlist
[i
].end
);
254 if (rmesa
->vb
.primlist
[i
].start
< rmesa
->vb
.primlist
[i
].end
)
255 r200EmitPrimitive( rmesa
->glCtx
,
256 rmesa
->vb
.primlist
[i
].start
,
257 rmesa
->vb
.primlist
[i
].end
,
258 rmesa
->vb
.primlist
[i
].prim
);
261 rmesa
->vb
.nrprims
= 0;
262 r200ReleaseDmaRegion( rmesa
, &tmp
, __FUNCTION__
);
266 static void start_prim( r200ContextPtr rmesa
, GLuint mode
)
268 if (R200_DEBUG
& DEBUG_VFMT
)
269 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
270 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
272 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
=
273 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
274 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
= mode
;
277 static void note_last_prim( r200ContextPtr rmesa
, GLuint flags
)
279 if (R200_DEBUG
& DEBUG_VFMT
)
280 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
281 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
283 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
284 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
|= flags
;
285 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].end
=
286 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
288 if (++(rmesa
->vb
.nrprims
) == R200_MAX_PRIMS
)
289 flush_prims( rmesa
);
294 static void copy_vertex( r200ContextPtr rmesa
, GLuint n
, GLfloat
*dst
)
297 GLfloat
*src
= (GLfloat
*)(rmesa
->dma
.current
.address
+
298 rmesa
->dma
.current
.ptr
+
299 (rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
) *
300 rmesa
->vb
.vertex_size
* 4);
302 if (R200_DEBUG
& DEBUG_VFMT
)
303 fprintf(stderr
, "copy_vertex %d\n", rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
);
305 for (i
= 0 ; i
< rmesa
->vb
.vertex_size
; i
++) {
310 /* NOTE: This actually reads the copied vertices back from uncached
311 * memory. Could also use the counter/notify mechanism to populate
312 * tmp on the fly as vertices are generated.
314 static GLuint
copy_dma_verts( r200ContextPtr rmesa
, GLfloat (*tmp
)[R200_MAX_VERTEX_SIZE
] )
317 GLuint nr
= (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
318 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
;
320 if (R200_DEBUG
& DEBUG_VFMT
)
321 fprintf(stderr
, "%s %d verts\n", __FUNCTION__
, nr
);
323 switch( rmesa
->vb
.prim
[0] )
329 for (i
= 0 ; i
< ovf
; i
++)
330 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
334 for (i
= 0 ; i
< ovf
; i
++)
335 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
339 for (i
= 0 ; i
< ovf
; i
++)
340 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
345 copy_vertex( rmesa
, nr
-1, tmp
[0] );
348 case GL_TRIANGLE_FAN
:
353 copy_vertex( rmesa
, 0, tmp
[0] );
356 copy_vertex( rmesa
, 0, tmp
[0] );
357 copy_vertex( rmesa
, nr
-1, tmp
[1] );
360 case GL_TRIANGLE_STRIP
:
362 for (i
= 0 ; i
< ovf
; i
++)
363 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
367 case 0: ovf
= 0; break;
368 case 1: ovf
= 1; break;
369 default: ovf
= 2 + (nr
&1); break;
371 for (i
= 0 ; i
< ovf
; i
++)
372 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
380 static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller
)
382 GET_CURRENT_CONTEXT(ctx
);
383 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
385 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_FALLBACKS
))
386 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
388 if (ctx
->Driver
.NeedFlush
)
389 r200VtxFmtFlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
392 _mesa_update_state( ctx
); /* clear state so fell_back sticks */
394 _tnl_wakeup_exec( ctx
);
395 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
397 assert( rmesa
->dma
.flush
== 0 );
398 rmesa
->vb
.fell_back
= GL_TRUE
;
399 rmesa
->vb
.installed
= GL_FALSE
;
405 * An interesting optimization of this function would be to have 3 element
406 * table with the dispatch offsets of the TexCoord?fv functions, use count
407 * to look-up the table, and a specialized version of GL_CALL that used the
408 * offset number instead of the name.
410 static void dispatch_multitexcoord( GLuint count
, GLuint unit
, GLfloat
* f
)
414 GL_CALL(MultiTexCoord3fvARB
)( GL_TEXTURE0
+unit
, f
);
417 GL_CALL(MultiTexCoord2fvARB
)( GL_TEXTURE0
+unit
, f
);
420 GL_CALL(MultiTexCoord1fvARB
)( GL_TEXTURE0
+unit
, f
);
423 assert( count
== 0 );
428 void VFMT_FALLBACK( const char *caller
)
430 GET_CURRENT_CONTEXT(ctx
);
431 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
432 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
434 GLuint ind0
= rmesa
->vb
.vtxfmt_0
;
435 GLuint ind1
= rmesa
->vb
.vtxfmt_1
;
441 if (R200_DEBUG
& (DEBUG_FALLBACKS
|DEBUG_VFMT
))
442 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
444 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
445 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__
);
449 /* Copy vertices out of dma:
451 nrverts
= copy_dma_verts( rmesa
, tmp
);
453 /* Finish the prim at this point:
455 note_last_prim( rmesa
, 0 );
456 flush_prims( rmesa
);
458 /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
460 prim
= rmesa
->vb
.prim
[0];
461 ctx
->Driver
.CurrentExecPrimitive
= GL_POLYGON
+1;
462 _tnl_wakeup_exec( ctx
);
463 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
465 assert(rmesa
->dma
.flush
== 0);
466 rmesa
->vb
.fell_back
= GL_TRUE
;
467 rmesa
->vb
.installed
= GL_FALSE
;
468 GL_CALL(Begin
)( prim
);
470 if (rmesa
->vb
.installed_color_3f_sz
== 4)
471 alpha
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
473 /* Replay saved vertices
475 for (i
= 0 ; i
< nrverts
; i
++) {
478 if (ind0
& R200_VTX_N0
) {
479 GL_CALL(Normal3fv
)( &tmp
[i
][offset
] );
483 if (ind0
& R200_VTX_DISCRETE_FOG
) {
484 GL_CALL(FogCoordfvEXT
)( &tmp
[i
][offset
] );
488 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
489 GL_CALL(Color4ubv
)( (GLubyte
*)&tmp
[i
][offset
] );
492 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
493 GL_CALL(Color4fv
)( &tmp
[i
][offset
] );
496 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
497 GL_CALL(Color3fv
)( &tmp
[i
][offset
] );
501 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
502 GL_CALL(SecondaryColor3ubvEXT
)( (GLubyte
*)&tmp
[i
][offset
] );
506 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
507 count
= VTX_TEXn_COUNT( ind1
, unit
);
508 dispatch_multitexcoord( count
, unit
, &tmp
[i
][offset
] );
512 GL_CALL(Vertex3fv
)( &tmp
[i
][0] );
515 /* Replay current vertex
517 if (ind0
& R200_VTX_N0
)
518 GL_CALL(Normal3fv
)( rmesa
->vb
.normalptr
);
519 if (ind0
& R200_VTX_DISCRETE_FOG
) {
520 GL_CALL(FogCoordfvEXT
)( rmesa
->vb
.fogptr
);
523 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
524 GL_CALL(Color4ub
)( rmesa
->vb
.colorptr
->red
,
525 rmesa
->vb
.colorptr
->green
,
526 rmesa
->vb
.colorptr
->blue
,
527 rmesa
->vb
.colorptr
->alpha
);
529 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
530 GL_CALL(Color4fv
)( rmesa
->vb
.floatcolorptr
);
532 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
533 if (rmesa
->vb
.installed_color_3f_sz
== 4 && alpha
!= 1.0) {
534 GL_CALL(Color4f
)( rmesa
->vb
.floatcolorptr
[0],
535 rmesa
->vb
.floatcolorptr
[1],
536 rmesa
->vb
.floatcolorptr
[2],
540 GL_CALL(Color3fv
)( rmesa
->vb
.floatcolorptr
);
544 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
)
545 GL_CALL(SecondaryColor3ubEXT
)( rmesa
->vb
.specptr
->red
,
546 rmesa
->vb
.specptr
->green
,
547 rmesa
->vb
.specptr
->blue
);
549 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
550 count
= VTX_TEXn_COUNT( ind1
, unit
);
551 dispatch_multitexcoord( count
, unit
, rmesa
->vb
.texcoordptr
[unit
] );
557 static void wrap_buffer( void )
559 GET_CURRENT_CONTEXT(ctx
);
560 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
561 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
564 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_PRIMS
))
565 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
566 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
568 /* Don't deal with parity.
570 if ((((rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
571 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
) & 1)) {
573 rmesa
->vb
.initial_counter
++;
577 /* Copy vertices out of dma:
579 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1)
582 nrverts
= copy_dma_verts( rmesa
, tmp
);
584 if (R200_DEBUG
& DEBUG_VFMT
)
585 fprintf(stderr
, "%d vertices to copy\n", nrverts
);
587 /* Finish the prim at this point:
589 note_last_prim( rmesa
, 0 );
592 /* Fire any buffered primitives
594 flush_prims( rmesa
);
598 r200RefillCurrentDmaRegion( rmesa
);
600 /* Reset counter, dmaptr
602 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.ptr
+ rmesa
->dma
.current
.address
);
603 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
604 (rmesa
->vb
.vertex_size
* 4);
606 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
607 rmesa
->vb
.notify
= wrap_buffer
;
609 rmesa
->dma
.flush
= flush_prims
;
611 /* Restart wrapped primitive:
613 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1)
614 start_prim( rmesa
, rmesa
->vb
.prim
[0] );
617 /* Reemit saved vertices
619 for (i
= 0 ; i
< nrverts
; i
++) {
620 if (R200_DEBUG
& DEBUG_VERTS
) {
622 fprintf(stderr
, "re-emit vertex %d to %p\n", i
,
623 (void *)rmesa
->vb
.dmaptr
);
624 if (R200_DEBUG
& DEBUG_VERBOSE
)
625 for (j
= 0 ; j
< rmesa
->vb
.vertex_size
; j
++)
626 fprintf(stderr
, "\t%08x/%f\n", *(int*)&tmp
[i
][j
], tmp
[i
][j
]);
629 memcpy( rmesa
->vb
.dmaptr
, tmp
[i
], rmesa
->vb
.vertex_size
* 4 );
630 rmesa
->vb
.dmaptr
+= rmesa
->vb
.vertex_size
;
637 * Determines the hardware vertex format based on the current state vector.
640 * If the hardware TCL unit is capable of handling the current state vector,
641 * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
644 * Make this color format selection data driven. If we receive only ubytes,
645 * send color as ubytes. Also check if converting (with free checking for
646 * overflow) is cheaper than sending floats directly.
649 * When intializing texture coordinates, it might be faster to just copy the
650 * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that
651 * some of the data (i.e., the last texture coordinate components) get copied
652 * over, but that still may be faster than the conditional branching. If
653 * nothing else, the code will be smaller and easier to follow.
655 static GLboolean
check_vtx_fmt( GLcontext
*ctx
)
657 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
658 GLuint ind0
= R200_VTX_Z0
;
661 GLuint count
[R200_MAX_TEXTURE_UNITS
];
663 if (rmesa
->TclFallback
|| rmesa
->vb
.fell_back
|| ctx
->CompileFlag
)
666 if (ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
)
667 ctx
->Driver
.FlushVertices( ctx
, FLUSH_UPDATE_CURRENT
);
669 /* Make all this event-driven:
671 if (ctx
->Light
.Enabled
) {
674 if (ctx
->Light
.ColorMaterialEnabled
)
675 ind0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
677 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
680 /* TODO: make this data driven?
682 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
684 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
685 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
;
689 if ( ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORD
) {
690 ind0
|= R200_VTX_DISCRETE_FOG
;
693 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
696 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
697 if (rmesa
->TexGenNeedNormals
[i
]) {
701 switch( ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
702 case TEXTURE_CUBE_BIT
:
707 case TEXTURE_RECT_BIT
:
715 ind1
|= count
[i
] << (3 * i
);
720 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_STATE
))
721 fprintf(stderr
, "%s: format: 0x%x, 0x%x\n", __FUNCTION__
, ind0
, ind1
);
724 rmesa
->vb
.vtxfmt_0
= ind0
;
725 rmesa
->vb
.vtxfmt_1
= ind1
;
726 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
728 rmesa
->vb
.vertex_size
= 3;
729 rmesa
->vb
.normalptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
730 rmesa
->vb
.colorptr
= NULL
;
731 rmesa
->vb
.floatcolorptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
732 rmesa
->vb
.fogptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
];
733 rmesa
->vb
.specptr
= NULL
;
734 rmesa
->vb
.floatspecptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
735 rmesa
->vb
.texcoordptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
736 rmesa
->vb
.texcoordptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
737 rmesa
->vb
.texcoordptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
738 rmesa
->vb
.texcoordptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX3
];
739 rmesa
->vb
.texcoordptr
[4] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX4
];
740 rmesa
->vb
.texcoordptr
[5] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX5
];
741 rmesa
->vb
.texcoordptr
[6] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
742 rmesa
->vb
.texcoordptr
[7] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
744 /* Run through and initialize the vertex components in the order
745 * the hardware understands:
747 if (ind0
& R200_VTX_N0
) {
748 rmesa
->vb
.normalptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
749 rmesa
->vb
.vertex_size
+= 3;
750 rmesa
->vb
.normalptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0];
751 rmesa
->vb
.normalptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1];
752 rmesa
->vb
.normalptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2];
755 if (ind0
& R200_VTX_DISCRETE_FOG
) {
756 rmesa
->vb
.fogptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
757 rmesa
->vb
.vertex_size
+= 1;
758 rmesa
->vb
.fogptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
][0];
761 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
762 rmesa
->vb
.colorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
763 rmesa
->vb
.vertex_size
+= 1;
764 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] );
765 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] );
766 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] );
767 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->alpha
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] );
769 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
770 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
771 rmesa
->vb
.vertex_size
+= 4;
772 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
773 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
774 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
775 rmesa
->vb
.floatcolorptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
777 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
778 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
779 rmesa
->vb
.vertex_size
+= 3;
780 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
781 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
782 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
785 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
786 rmesa
->vb
.specptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
787 rmesa
->vb
.vertex_size
+= 1;
788 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] );
789 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] );
790 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] );
794 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
795 if ( count
[i
] != 0 ) {
796 float * const attr
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
];
799 rmesa
->vb
.texcoordptr
[i
] = &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
801 for ( j
= 0 ; j
< count
[i
] ; j
++ ) {
802 rmesa
->vb
.texcoordptr
[i
][j
] = attr
[j
];
805 rmesa
->vb
.vertex_size
+= count
[i
];
809 if (rmesa
->vb
.installed_vertex_format
!= rmesa
->vb
.vtxfmt_0
) {
810 if (R200_DEBUG
& DEBUG_VFMT
)
811 fprintf(stderr
, "reinstall on vertex_format change\n");
812 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
813 rmesa
->vb
.installed_vertex_format
= rmesa
->vb
.vtxfmt_0
;
816 if (R200_DEBUG
& DEBUG_VFMT
)
817 fprintf(stderr
, "%s -- success\n", __FUNCTION__
);
823 void r200VtxfmtInvalidate( GLcontext
*ctx
)
825 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
827 rmesa
->vb
.recheck
= GL_TRUE
;
828 rmesa
->vb
.fell_back
= GL_FALSE
;
832 static void r200VtxfmtValidate( GLcontext
*ctx
)
834 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
836 if (R200_DEBUG
& DEBUG_VFMT
)
837 fprintf(stderr
, "%s\n", __FUNCTION__
);
839 if (ctx
->Driver
.NeedFlush
)
840 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
842 rmesa
->vb
.recheck
= GL_FALSE
;
844 if (check_vtx_fmt( ctx
)) {
845 if (!rmesa
->vb
.installed
) {
846 if (R200_DEBUG
& DEBUG_VFMT
)
847 fprintf(stderr
, "reinstall (new install)\n");
849 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
850 ctx
->Driver
.FlushVertices
= r200VtxFmtFlushVertices
;
851 rmesa
->vb
.installed
= GL_TRUE
;
853 else if (R200_DEBUG
& DEBUG_VFMT
)
854 fprintf(stderr
, "%s: already installed", __FUNCTION__
);
857 if (R200_DEBUG
& DEBUG_VFMT
)
858 fprintf(stderr
, "%s: failed\n", __FUNCTION__
);
860 if (rmesa
->vb
.installed
) {
861 if (rmesa
->dma
.flush
)
862 rmesa
->dma
.flush( rmesa
);
863 _tnl_wakeup_exec( ctx
);
864 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
865 rmesa
->vb
.installed
= GL_FALSE
;
874 static void r200_Materialfv( GLenum face
, GLenum pname
,
875 const GLfloat
*params
)
877 GET_CURRENT_CONTEXT(ctx
);
878 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
880 if (R200_DEBUG
& DEBUG_VFMT
)
881 fprintf(stderr
, "%s\n", __FUNCTION__
);
883 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
884 VFMT_FALLBACK( __FUNCTION__
);
885 GL_CALL(Materialfv
)( face
, pname
, params
);
888 _mesa_noop_Materialfv( face
, pname
, params
);
889 r200UpdateMaterial( ctx
);
895 static void r200_Begin( GLenum mode
)
897 GET_CURRENT_CONTEXT(ctx
);
898 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
900 if (R200_DEBUG
& DEBUG_VFMT
)
901 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
902 _mesa_lookup_enum_by_nr( mode
));
904 if (mode
> GL_POLYGON
) {
905 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
909 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
910 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
915 _mesa_update_state( ctx
);
917 if (rmesa
->NewGLState
)
918 r200ValidateState( ctx
);
920 if (rmesa
->vb
.recheck
)
921 r200VtxfmtValidate( ctx
);
923 if (!rmesa
->vb
.installed
) {
924 GL_CALL(Begin
)( mode
);
929 if (rmesa
->dma
.flush
&& rmesa
->vb
.counter
< 12) {
930 if (R200_DEBUG
& DEBUG_VFMT
)
931 fprintf(stderr
, "%s: flush almost-empty buffers\n", __FUNCTION__
);
932 flush_prims( rmesa
);
935 /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
937 if (!rmesa
->dma
.flush
) {
938 if (rmesa
->dma
.current
.ptr
+ 12*rmesa
->vb
.vertex_size
*4 >
939 rmesa
->dma
.current
.end
) {
940 R200_NEWPRIM( rmesa
);
941 r200RefillCurrentDmaRegion( rmesa
);
944 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
945 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
946 (rmesa
->vb
.vertex_size
* 4);
948 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
949 rmesa
->vb
.notify
= wrap_buffer
;
950 rmesa
->dma
.flush
= flush_prims
;
951 ctx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
955 rmesa
->vb
.prim
[0] = mode
;
956 start_prim( rmesa
, mode
| PRIM_BEGIN
);
961 static void r200_End( void )
963 GET_CURRENT_CONTEXT(ctx
);
964 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
966 if (R200_DEBUG
& DEBUG_VFMT
)
967 fprintf(stderr
, "%s\n", __FUNCTION__
);
969 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
970 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glEnd" );
974 note_last_prim( rmesa
, PRIM_END
);
975 rmesa
->vb
.prim
[0] = GL_POLYGON
+1;
979 /* Fallback on difficult entrypoints:
981 #define PRE_LOOPBACK( FUNC ) \
983 if (R200_DEBUG & DEBUG_VFMT) \
984 fprintf(stderr, "%s\n", __FUNCTION__); \
985 VFMT_FALLBACK( __FUNCTION__ ); \
987 #define TAG(x) r200_fallback_##x
988 #include "vtxfmt_tmp.h"
992 static GLboolean
r200NotifyBegin( GLcontext
*ctx
, GLenum p
)
994 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
996 if (R200_DEBUG
& DEBUG_VFMT
)
997 fprintf(stderr
, "%s\n", __FUNCTION__
);
999 assert(!rmesa
->vb
.installed
);
1002 _mesa_update_state( ctx
);
1004 if (rmesa
->NewGLState
)
1005 r200ValidateState( ctx
);
1007 if (ctx
->Driver
.NeedFlush
)
1008 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
1010 if (rmesa
->vb
.recheck
)
1011 r200VtxfmtValidate( ctx
);
1013 if (!rmesa
->vb
.installed
) {
1014 if (R200_DEBUG
& DEBUG_VFMT
)
1015 fprintf(stderr
, "%s -- failed\n", __FUNCTION__
);
1023 static void r200VtxFmtFlushVertices( GLcontext
*ctx
, GLuint flags
)
1025 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1027 if (R200_DEBUG
& DEBUG_VFMT
)
1028 fprintf(stderr
, "%s\n", __FUNCTION__
);
1030 assert(rmesa
->vb
.installed
);
1032 if (flags
& FLUSH_UPDATE_CURRENT
) {
1033 r200_copy_to_current( ctx
);
1034 if (R200_DEBUG
& DEBUG_VFMT
)
1035 fprintf(stderr
, "reinstall on update_current\n");
1036 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
1037 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
1040 if (flags
& FLUSH_STORED_VERTICES
) {
1041 assert (rmesa
->dma
.flush
== 0 ||
1042 rmesa
->dma
.flush
== flush_prims
);
1043 if (rmesa
->dma
.flush
== flush_prims
)
1044 flush_prims( rmesa
);
1045 ctx
->Driver
.NeedFlush
&= ~FLUSH_STORED_VERTICES
;
1051 /* At this point, don't expect very many versions of each function to
1052 * be generated, so not concerned about freeing them?
1056 void r200VtxfmtInit( GLcontext
*ctx
, GLboolean useCodegen
)
1058 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1059 GLvertexformat
*vfmt
= &(rmesa
->vb
.vtxfmt
);
1061 MEMSET( vfmt
, 0, sizeof(GLvertexformat
) );
1063 /* Hook in chooser functions for codegen, etc:
1065 r200VtxfmtInitChoosers( vfmt
);
1067 /* Handled fully in supported states, but no codegen:
1069 vfmt
->Materialfv
= r200_Materialfv
;
1070 vfmt
->ArrayElement
= _ae_loopback_array_elt
; /* generic helper */
1071 vfmt
->Rectf
= _mesa_noop_Rectf
; /* generic helper */
1072 vfmt
->Begin
= r200_Begin
;
1073 vfmt
->End
= r200_End
;
1075 /* Fallback for performance reasons: (Fix with cva/elt path here and
1076 * dmatmp2.h style primitive-merging)
1078 * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
1081 vfmt
->DrawArrays
= r200_fallback_DrawArrays
;
1082 vfmt
->DrawElements
= r200_fallback_DrawElements
;
1083 vfmt
->DrawRangeElements
= r200_fallback_DrawRangeElements
;
1086 /* Not active in supported states; just keep ctx->Current uptodate:
1088 vfmt
->EdgeFlag
= _mesa_noop_EdgeFlag
;
1089 vfmt
->EdgeFlagv
= _mesa_noop_EdgeFlagv
;
1090 vfmt
->Indexf
= _mesa_noop_Indexf
;
1091 vfmt
->Indexfv
= _mesa_noop_Indexfv
;
1094 /* Active but unsupported -- fallback if we receive these:
1096 vfmt
->CallList
= r200_fallback_CallList
;
1097 vfmt
->CallLists
= r200_fallback_CallLists
;
1098 vfmt
->EvalCoord1f
= r200_fallback_EvalCoord1f
;
1099 vfmt
->EvalCoord1fv
= r200_fallback_EvalCoord1fv
;
1100 vfmt
->EvalCoord2f
= r200_fallback_EvalCoord2f
;
1101 vfmt
->EvalCoord2fv
= r200_fallback_EvalCoord2fv
;
1102 vfmt
->EvalMesh1
= r200_fallback_EvalMesh1
;
1103 vfmt
->EvalMesh2
= r200_fallback_EvalMesh2
;
1104 vfmt
->EvalPoint1
= r200_fallback_EvalPoint1
;
1105 vfmt
->EvalPoint2
= r200_fallback_EvalPoint2
;
1106 vfmt
->TexCoord4f
= r200_fallback_TexCoord4f
;
1107 vfmt
->TexCoord4fv
= r200_fallback_TexCoord4fv
;
1108 vfmt
->MultiTexCoord4fARB
= r200_fallback_MultiTexCoord4fARB
;
1109 vfmt
->MultiTexCoord4fvARB
= r200_fallback_MultiTexCoord4fvARB
;
1110 vfmt
->Vertex4f
= r200_fallback_Vertex4f
;
1111 vfmt
->Vertex4fv
= r200_fallback_Vertex4fv
;
1112 vfmt
->VertexAttrib1fNV
= r200_fallback_VertexAttrib1fNV
;
1113 vfmt
->VertexAttrib1fvNV
= r200_fallback_VertexAttrib1fvNV
;
1114 vfmt
->VertexAttrib2fNV
= r200_fallback_VertexAttrib2fNV
;
1115 vfmt
->VertexAttrib2fvNV
= r200_fallback_VertexAttrib2fvNV
;
1116 vfmt
->VertexAttrib3fNV
= r200_fallback_VertexAttrib3fNV
;
1117 vfmt
->VertexAttrib3fvNV
= r200_fallback_VertexAttrib3fvNV
;
1118 vfmt
->VertexAttrib4fNV
= r200_fallback_VertexAttrib4fNV
;
1119 vfmt
->VertexAttrib4fvNV
= r200_fallback_VertexAttrib4fvNV
;
1120 vfmt
->FogCoordfEXT
= r200_fallback_FogCoordfEXT
;
1121 vfmt
->FogCoordfvEXT
= r200_fallback_FogCoordfvEXT
;
1123 (void)r200_fallback_vtxfmt
;
1125 TNL_CONTEXT(ctx
)->Driver
.NotifyBegin
= r200NotifyBegin
;
1127 rmesa
->vb
.enabled
= 1;
1128 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
1129 rmesa
->vb
.primflags
= 0;
1131 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1132 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1133 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1134 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1135 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ub
);
1136 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1137 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ub
);
1138 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1139 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4f
);
1140 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4fv
);
1141 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3f
);
1142 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3fv
);
1143 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1144 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1145 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1146 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1147 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3f
);
1148 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1149 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1150 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1151 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1152 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1153 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1154 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1155 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1156 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1157 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1158 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1159 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1160 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1161 /* make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT );
1162 make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
1164 r200InitCodegen( &rmesa
->vb
.codegen
, useCodegen
);
1167 static void free_funcs( struct dynfn
*l
)
1169 struct dynfn
*f
, *tmp
;
1170 foreach_s (f
, tmp
, l
) {
1171 remove_from_list( f
);
1172 ALIGN_FREE( f
->code
);
1177 void r200VtxfmtUnbindContext( GLcontext
*ctx
)
1182 void r200VtxfmtMakeCurrent( GLcontext
*ctx
)
1187 void r200VtxfmtDestroy( GLcontext
*ctx
)
1189 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1191 count_funcs( rmesa
);
1192 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1193 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1194 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1195 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1196 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ub
);
1197 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1198 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ub
);
1199 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1200 free_funcs( &rmesa
->vb
.dfn_cache
.Color4f
);
1201 free_funcs( &rmesa
->vb
.dfn_cache
.Color4fv
);
1202 free_funcs( &rmesa
->vb
.dfn_cache
.Color3f
);
1203 free_funcs( &rmesa
->vb
.dfn_cache
.Color3fv
);
1204 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1205 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1206 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1207 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1208 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3f
);
1209 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1210 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1211 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1212 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1213 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1214 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1215 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1216 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1217 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1218 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1219 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1220 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1221 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1222 /* free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT );
1223 free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/