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"
63 static void r200VtxFmtFlushVertices( GLcontext
*, GLuint
);
65 static void count_func( const char *name
, struct dynfn
*l
)
70 if (i
) fprintf(stderr
, "%s: %d\n", name
, i
);
73 static void count_funcs( r200ContextPtr rmesa
)
75 count_func( "Vertex2f", &rmesa
->vb
.dfn_cache
.Vertex2f
);
76 count_func( "Vertex2fv", &rmesa
->vb
.dfn_cache
.Vertex2fv
);
77 count_func( "Vertex3f", &rmesa
->vb
.dfn_cache
.Vertex3f
);
78 count_func( "Vertex3fv", &rmesa
->vb
.dfn_cache
.Vertex3fv
);
79 count_func( "Color4ub", &rmesa
->vb
.dfn_cache
.Color4ub
);
80 count_func( "Color4ubv", &rmesa
->vb
.dfn_cache
.Color4ubv
);
81 count_func( "Color3ub", &rmesa
->vb
.dfn_cache
.Color3ub
);
82 count_func( "Color3ubv", &rmesa
->vb
.dfn_cache
.Color3ubv
);
83 count_func( "Color4f", &rmesa
->vb
.dfn_cache
.Color4f
);
84 count_func( "Color4fv", &rmesa
->vb
.dfn_cache
.Color4fv
);
85 count_func( "Color3f", &rmesa
->vb
.dfn_cache
.Color3f
);
86 count_func( "Color3fv", &rmesa
->vb
.dfn_cache
.Color3fv
);
87 count_func( "SecondaryColor3f", &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
88 count_func( "SecondaryColor3fv", &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
89 count_func( "SecondaryColor3ub", &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
90 count_func( "SecondaryColor3ubv", &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
91 count_func( "Normal3f", &rmesa
->vb
.dfn_cache
.Normal3f
);
92 count_func( "Normal3fv", &rmesa
->vb
.dfn_cache
.Normal3fv
);
93 count_func( "TexCoord3f", &rmesa
->vb
.dfn_cache
.TexCoord3f
);
94 count_func( "TexCoord3fv", &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
95 count_func( "TexCoord2f", &rmesa
->vb
.dfn_cache
.TexCoord2f
);
96 count_func( "TexCoord2fv", &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
97 count_func( "TexCoord1f", &rmesa
->vb
.dfn_cache
.TexCoord1f
);
98 count_func( "TexCoord1fv", &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
99 count_func( "MultiTexCoord3fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
100 count_func( "MultiTexCoord3fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
101 count_func( "MultiTexCoord2fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
102 count_func( "MultiTexCoord2fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
103 count_func( "MultiTexCoord1fARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
104 count_func( "MultiTexCoord1fvARB", &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
105 /* count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT );
106 count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
110 void r200_copy_to_current( GLcontext
*ctx
)
112 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
115 if (R200_DEBUG
& DEBUG_VFMT
)
116 fprintf(stderr
, "%s\n", __FUNCTION__
);
118 assert(ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
);
120 if (rmesa
->vb
.vtxfmt_0
& R200_VTX_N0
) {
121 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0] = rmesa
->vb
.normalptr
[0];
122 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1] = rmesa
->vb
.normalptr
[1];
123 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2] = rmesa
->vb
.normalptr
[2];
126 if (rmesa
->vb
.vtxfmt_0
& R200_VTX_DISCRETE_FOG
) {
127 ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
][0] = rmesa
->vb
.fogptr
[0];
130 switch( VTX_COLOR(rmesa
->vb
.vtxfmt_0
, 0) ) {
131 case R200_VTX_PK_RGBA
:
132 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->red
);
133 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->green
);
134 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->blue
);
135 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->alpha
);
138 case R200_VTX_FP_RGB
:
139 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = rmesa
->vb
.floatcolorptr
[0];
140 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = rmesa
->vb
.floatcolorptr
[1];
141 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = rmesa
->vb
.floatcolorptr
[2];
144 case R200_VTX_FP_RGBA
:
145 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = rmesa
->vb
.floatcolorptr
[0];
146 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = rmesa
->vb
.floatcolorptr
[1];
147 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = rmesa
->vb
.floatcolorptr
[2];
148 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = rmesa
->vb
.floatcolorptr
[3];
155 if (VTX_COLOR(rmesa
->vb
.vtxfmt_0
, 1) == R200_VTX_PK_RGBA
) {
156 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->red
);
157 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->green
);
158 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->blue
);
161 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
162 const unsigned count
= VTX_TEXn_COUNT( rmesa
->vb
.vtxfmt_1
, i
);
163 GLfloat
* const src
= rmesa
->vb
.texcoordptr
[i
];
168 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = src
[1];
169 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = src
[2];
172 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = src
[1];
173 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = 0.0F
;
176 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = 0.0F
;
177 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = 0.0F
;
181 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][0] = src
[0];
182 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][3] = 1.0F
;
186 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
189 static GLboolean discreet_gl_prim
[GL_POLYGON
+1] = {
192 0, /* 2 line_strip */
202 static void flush_prims( r200ContextPtr rmesa
)
205 struct r200_dma_region tmp
= rmesa
->dma
.current
;
208 tmp
.aos_size
= rmesa
->vb
.vertex_size
;
209 tmp
.aos_stride
= rmesa
->vb
.vertex_size
;
210 tmp
.aos_start
= GET_START(&tmp
);
212 rmesa
->dma
.current
.ptr
= rmesa
->dma
.current
.start
+=
213 (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) *
214 rmesa
->vb
.vertex_size
* 4;
216 rmesa
->tcl
.vertex_format
= rmesa
->vb
.vtxfmt_0
;
217 rmesa
->tcl
.aos_components
[0] = &tmp
;
218 rmesa
->tcl
.nr_aos_components
= 1;
219 rmesa
->dma
.flush
= NULL
;
221 /* Optimize the primitive list:
223 if (rmesa
->vb
.nrprims
> 1) {
224 for (j
= 0, i
= 1 ; i
< rmesa
->vb
.nrprims
; i
++) {
225 int pj
= rmesa
->vb
.primlist
[j
].prim
& 0xf;
226 int pi
= rmesa
->vb
.primlist
[i
].prim
& 0xf;
228 if (pj
== pi
&& discreet_gl_prim
[pj
] &&
229 rmesa
->vb
.primlist
[i
].start
== rmesa
->vb
.primlist
[j
].end
) {
230 rmesa
->vb
.primlist
[j
].end
= rmesa
->vb
.primlist
[i
].end
;
234 if (j
!= i
) rmesa
->vb
.primlist
[j
] = rmesa
->vb
.primlist
[i
];
237 rmesa
->vb
.nrprims
= j
+1;
240 if (rmesa
->vb
.vtxfmt_0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
241 rmesa
->vb
.vtxfmt_1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
242 R200_STATECHANGE( rmesa
, vtx
);
243 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = rmesa
->vb
.vtxfmt_0
;
244 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = rmesa
->vb
.vtxfmt_1
;
248 for (i
= 0 ; i
< rmesa
->vb
.nrprims
; i
++) {
249 if (R200_DEBUG
& DEBUG_PRIMS
)
250 fprintf(stderr
, "vtxfmt prim %d: %s %d..%d\n", i
,
251 _mesa_lookup_enum_by_nr( rmesa
->vb
.primlist
[i
].prim
&
253 rmesa
->vb
.primlist
[i
].start
,
254 rmesa
->vb
.primlist
[i
].end
);
256 if (rmesa
->vb
.primlist
[i
].start
< rmesa
->vb
.primlist
[i
].end
)
257 r200EmitPrimitive( rmesa
->glCtx
,
258 rmesa
->vb
.primlist
[i
].start
,
259 rmesa
->vb
.primlist
[i
].end
,
260 rmesa
->vb
.primlist
[i
].prim
);
263 rmesa
->vb
.nrprims
= 0;
264 r200ReleaseDmaRegion( rmesa
, &tmp
, __FUNCTION__
);
268 static void start_prim( r200ContextPtr rmesa
, GLuint mode
)
270 if (R200_DEBUG
& DEBUG_VFMT
)
271 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
272 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
274 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
=
275 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
276 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
= mode
;
279 static void note_last_prim( r200ContextPtr rmesa
, GLuint flags
)
281 if (R200_DEBUG
& DEBUG_VFMT
)
282 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
283 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
285 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
286 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
|= flags
;
287 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].end
=
288 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
290 if (++(rmesa
->vb
.nrprims
) == R200_MAX_PRIMS
)
291 flush_prims( rmesa
);
296 static void copy_vertex( r200ContextPtr rmesa
, GLuint n
, GLfloat
*dst
)
299 GLfloat
*src
= (GLfloat
*)(rmesa
->dma
.current
.address
+
300 rmesa
->dma
.current
.ptr
+
301 (rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
) *
302 rmesa
->vb
.vertex_size
* 4);
304 if (R200_DEBUG
& DEBUG_VFMT
)
305 fprintf(stderr
, "copy_vertex %d\n", rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
);
307 for (i
= 0 ; i
< rmesa
->vb
.vertex_size
; i
++) {
312 /* NOTE: This actually reads the copied vertices back from uncached
313 * memory. Could also use the counter/notify mechanism to populate
314 * tmp on the fly as vertices are generated.
316 static GLuint
copy_dma_verts( r200ContextPtr rmesa
, GLfloat (*tmp
)[R200_MAX_VERTEX_SIZE
] )
319 GLuint nr
= (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
320 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
;
322 if (R200_DEBUG
& DEBUG_VFMT
)
323 fprintf(stderr
, "%s %d verts\n", __FUNCTION__
, nr
);
325 switch( rmesa
->vb
.prim
[0] )
331 for (i
= 0 ; i
< ovf
; i
++)
332 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
336 for (i
= 0 ; i
< ovf
; i
++)
337 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
341 for (i
= 0 ; i
< ovf
; i
++)
342 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
347 copy_vertex( rmesa
, nr
-1, tmp
[0] );
350 case GL_TRIANGLE_FAN
:
355 copy_vertex( rmesa
, 0, tmp
[0] );
358 copy_vertex( rmesa
, 0, tmp
[0] );
359 copy_vertex( rmesa
, nr
-1, tmp
[1] );
362 case GL_TRIANGLE_STRIP
:
364 for (i
= 0 ; i
< ovf
; i
++)
365 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
369 case 0: ovf
= 0; break;
370 case 1: ovf
= 1; break;
371 default: ovf
= 2 + (nr
&1); break;
373 for (i
= 0 ; i
< ovf
; i
++)
374 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
382 static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller
)
384 GET_CURRENT_CONTEXT(ctx
);
385 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
387 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_FALLBACKS
))
388 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
390 if (ctx
->Driver
.NeedFlush
)
391 r200VtxFmtFlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
394 _mesa_update_state( ctx
); /* clear state so fell_back sticks */
396 _tnl_wakeup_exec( ctx
);
397 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
399 assert( rmesa
->dma
.flush
== 0 );
400 rmesa
->vb
.fell_back
= GL_TRUE
;
401 rmesa
->vb
.installed
= GL_FALSE
;
407 * An interesting optimization of this function would be to have 3 element
408 * table with the dispatch offsets of the TexCoord?fv functions, use count
409 * to look-up the table, and a specialized version of GL_CALL that used the
410 * offset number instead of the name.
412 static void dispatch_multitexcoord( GLuint count
, GLuint unit
, GLfloat
* f
)
416 CALL_MultiTexCoord3fvARB(GET_DISPATCH(), (GL_TEXTURE0
+unit
, f
));
419 CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE0
+unit
, f
));
422 CALL_MultiTexCoord1fvARB(GET_DISPATCH(), (GL_TEXTURE0
+unit
, f
));
425 assert( count
== 0 );
430 void VFMT_FALLBACK( const char *caller
)
432 GET_CURRENT_CONTEXT(ctx
);
433 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
434 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
436 GLuint ind0
= rmesa
->vb
.vtxfmt_0
;
437 GLuint ind1
= rmesa
->vb
.vtxfmt_1
;
443 if (R200_DEBUG
& (DEBUG_FALLBACKS
|DEBUG_VFMT
))
444 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
446 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
447 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__
);
451 /* Copy vertices out of dma:
453 nrverts
= copy_dma_verts( rmesa
, tmp
);
455 /* Finish the prim at this point:
457 note_last_prim( rmesa
, 0 );
458 flush_prims( rmesa
);
460 /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
462 prim
= rmesa
->vb
.prim
[0];
463 ctx
->Driver
.CurrentExecPrimitive
= GL_POLYGON
+1;
464 _tnl_wakeup_exec( ctx
);
465 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
467 assert(rmesa
->dma
.flush
== 0);
468 rmesa
->vb
.fell_back
= GL_TRUE
;
469 rmesa
->vb
.installed
= GL_FALSE
;
470 CALL_Begin(GET_DISPATCH(), (prim
));
472 if (rmesa
->vb
.installed_color_3f_sz
== 4)
473 alpha
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
475 /* Replay saved vertices
477 for (i
= 0 ; i
< nrverts
; i
++) {
480 if (ind0
& R200_VTX_N0
) {
481 CALL_Normal3fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
485 if (ind0
& R200_VTX_DISCRETE_FOG
) {
486 CALL_FogCoordfvEXT(GET_DISPATCH(), (&tmp
[i
][offset
]));
490 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
491 CALL_Color4ubv(GET_DISPATCH(), ((GLubyte
*)&tmp
[i
][offset
]));
494 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
495 CALL_Color4fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
498 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
499 CALL_Color3fv(GET_DISPATCH(), (&tmp
[i
][offset
]));
503 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
504 CALL_SecondaryColor3ubvEXT(GET_DISPATCH(), ((GLubyte
*)&tmp
[i
][offset
]));
508 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
509 count
= VTX_TEXn_COUNT( ind1
, unit
);
510 dispatch_multitexcoord( count
, unit
, &tmp
[i
][offset
] );
514 CALL_Vertex3fv(GET_DISPATCH(), (&tmp
[i
][0]));
517 /* Replay current vertex
519 if (ind0
& R200_VTX_N0
)
520 CALL_Normal3fv(GET_DISPATCH(), (rmesa
->vb
.normalptr
));
521 if (ind0
& R200_VTX_DISCRETE_FOG
) {
522 CALL_FogCoordfvEXT(GET_DISPATCH(), (rmesa
->vb
.fogptr
));
525 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
526 CALL_Color4ub(GET_DISPATCH(), (rmesa
->vb
.colorptr
->red
,
527 rmesa
->vb
.colorptr
->green
,
528 rmesa
->vb
.colorptr
->blue
,
529 rmesa
->vb
.colorptr
->alpha
));
531 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
532 CALL_Color4fv(GET_DISPATCH(), (rmesa
->vb
.floatcolorptr
));
534 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
535 if (rmesa
->vb
.installed_color_3f_sz
== 4 && alpha
!= 1.0) {
536 CALL_Color4f(GET_DISPATCH(), (rmesa
->vb
.floatcolorptr
[0],
537 rmesa
->vb
.floatcolorptr
[1],
538 rmesa
->vb
.floatcolorptr
[2],
542 CALL_Color3fv(GET_DISPATCH(), (rmesa
->vb
.floatcolorptr
));
546 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
)
547 CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa
->vb
.specptr
->red
,
548 rmesa
->vb
.specptr
->green
,
549 rmesa
->vb
.specptr
->blue
));
551 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
552 count
= VTX_TEXn_COUNT( ind1
, unit
);
553 dispatch_multitexcoord( count
, unit
, rmesa
->vb
.texcoordptr
[unit
] );
559 static void wrap_buffer( void )
561 GET_CURRENT_CONTEXT(ctx
);
562 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
563 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
566 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_PRIMS
))
567 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
568 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
570 /* Don't deal with parity.
572 if ((((rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
573 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
) & 1)) {
575 rmesa
->vb
.initial_counter
++;
579 /* Copy vertices out of dma:
581 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1)
584 nrverts
= copy_dma_verts( rmesa
, tmp
);
586 if (R200_DEBUG
& DEBUG_VFMT
)
587 fprintf(stderr
, "%d vertices to copy\n", nrverts
);
589 /* Finish the prim at this point:
591 note_last_prim( rmesa
, 0 );
594 /* Fire any buffered primitives
596 flush_prims( rmesa
);
600 r200RefillCurrentDmaRegion( rmesa
);
602 /* Reset counter, dmaptr
604 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.ptr
+ rmesa
->dma
.current
.address
);
605 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
606 (rmesa
->vb
.vertex_size
* 4);
608 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
609 rmesa
->vb
.notify
= wrap_buffer
;
611 rmesa
->dma
.flush
= flush_prims
;
613 /* Restart wrapped primitive:
615 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1)
616 start_prim( rmesa
, rmesa
->vb
.prim
[0] );
619 /* Reemit saved vertices
621 for (i
= 0 ; i
< nrverts
; i
++) {
622 if (R200_DEBUG
& DEBUG_VERTS
) {
624 fprintf(stderr
, "re-emit vertex %d to %p\n", i
,
625 (void *)rmesa
->vb
.dmaptr
);
626 if (R200_DEBUG
& DEBUG_VERBOSE
)
627 for (j
= 0 ; j
< rmesa
->vb
.vertex_size
; j
++)
628 fprintf(stderr
, "\t%08x/%f\n", *(int*)&tmp
[i
][j
], tmp
[i
][j
]);
631 memcpy( rmesa
->vb
.dmaptr
, tmp
[i
], rmesa
->vb
.vertex_size
* 4 );
632 rmesa
->vb
.dmaptr
+= rmesa
->vb
.vertex_size
;
639 * Determines the hardware vertex format based on the current state vector.
642 * If the hardware TCL unit is capable of handling the current state vector,
643 * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
646 * Make this color format selection data driven. If we receive only ubytes,
647 * send color as ubytes. Also check if converting (with free checking for
648 * overflow) is cheaper than sending floats directly.
651 * When intializing texture coordinates, it might be faster to just copy the
652 * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that
653 * some of the data (i.e., the last texture coordinate components) get copied
654 * over, but that still may be faster than the conditional branching. If
655 * nothing else, the code will be smaller and easier to follow.
657 static GLboolean
check_vtx_fmt( GLcontext
*ctx
)
659 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
660 GLuint ind0
= R200_VTX_Z0
;
663 GLuint count
[R200_MAX_TEXTURE_UNITS
];
665 if (rmesa
->TclFallback
|| rmesa
->vb
.fell_back
|| ctx
->CompileFlag
||
666 (ctx
->Fog
.Enabled
&& (ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORD
)))
669 if (ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
)
670 ctx
->Driver
.FlushVertices( ctx
, FLUSH_UPDATE_CURRENT
);
672 /* Make all this event-driven:
674 if (ctx
->Light
.Enabled
) {
677 if (ctx
->Light
.ColorMaterialEnabled
)
678 ind0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
680 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
683 /* TODO: make this data driven?
685 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
687 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
688 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
;
692 if ( ctx
->Fog
.FogCoordinateSource
== GL_FOG_COORD
) {
693 ind0
|= R200_VTX_DISCRETE_FOG
;
696 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
699 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
700 if (rmesa
->TexGenNeedNormals
[i
]) {
704 switch( ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
705 case TEXTURE_CUBE_BIT
:
710 case TEXTURE_RECT_BIT
:
718 ind1
|= count
[i
] << (3 * i
);
723 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_STATE
))
724 fprintf(stderr
, "%s: format: 0x%x, 0x%x\n", __FUNCTION__
, ind0
, ind1
);
727 rmesa
->vb
.vtxfmt_0
= ind0
;
728 rmesa
->vb
.vtxfmt_1
= ind1
;
729 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
731 rmesa
->vb
.vertex_size
= 3;
732 rmesa
->vb
.normalptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
733 rmesa
->vb
.colorptr
= NULL
;
734 rmesa
->vb
.floatcolorptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
735 rmesa
->vb
.fogptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
];
736 rmesa
->vb
.specptr
= NULL
;
737 rmesa
->vb
.floatspecptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
738 rmesa
->vb
.texcoordptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
739 rmesa
->vb
.texcoordptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
740 rmesa
->vb
.texcoordptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
741 rmesa
->vb
.texcoordptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX3
];
742 rmesa
->vb
.texcoordptr
[4] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX4
];
743 rmesa
->vb
.texcoordptr
[5] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX5
];
744 rmesa
->vb
.texcoordptr
[6] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
745 rmesa
->vb
.texcoordptr
[7] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
747 /* Run through and initialize the vertex components in the order
748 * the hardware understands:
750 if (ind0
& R200_VTX_N0
) {
751 rmesa
->vb
.normalptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
752 rmesa
->vb
.vertex_size
+= 3;
753 rmesa
->vb
.normalptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0];
754 rmesa
->vb
.normalptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1];
755 rmesa
->vb
.normalptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2];
758 if (ind0
& R200_VTX_DISCRETE_FOG
) {
759 rmesa
->vb
.fogptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
760 rmesa
->vb
.vertex_size
+= 1;
761 rmesa
->vb
.fogptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
][0];
764 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
765 rmesa
->vb
.colorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
766 rmesa
->vb
.vertex_size
+= 1;
767 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] );
768 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] );
769 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] );
770 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->alpha
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] );
772 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
773 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
774 rmesa
->vb
.vertex_size
+= 4;
775 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
776 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
777 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
778 rmesa
->vb
.floatcolorptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
780 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
781 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
782 rmesa
->vb
.vertex_size
+= 3;
783 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
784 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
785 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
788 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
789 rmesa
->vb
.specptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
790 rmesa
->vb
.vertex_size
+= 1;
791 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] );
792 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] );
793 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] );
797 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
798 if ( count
[i
] != 0 ) {
799 float * const attr
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
];
802 rmesa
->vb
.texcoordptr
[i
] = &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
804 for ( j
= 0 ; j
< count
[i
] ; j
++ ) {
805 rmesa
->vb
.texcoordptr
[i
][j
] = attr
[j
];
808 rmesa
->vb
.vertex_size
+= count
[i
];
812 if (rmesa
->vb
.installed_vertex_format
!= rmesa
->vb
.vtxfmt_0
) {
813 if (R200_DEBUG
& DEBUG_VFMT
)
814 fprintf(stderr
, "reinstall on vertex_format change\n");
815 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
816 rmesa
->vb
.installed_vertex_format
= rmesa
->vb
.vtxfmt_0
;
819 if (R200_DEBUG
& DEBUG_VFMT
)
820 fprintf(stderr
, "%s -- success\n", __FUNCTION__
);
826 void r200VtxfmtInvalidate( GLcontext
*ctx
)
828 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
830 rmesa
->vb
.recheck
= GL_TRUE
;
831 rmesa
->vb
.fell_back
= GL_FALSE
;
835 static void r200VtxfmtValidate( GLcontext
*ctx
)
837 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
839 if (R200_DEBUG
& DEBUG_VFMT
)
840 fprintf(stderr
, "%s\n", __FUNCTION__
);
842 if (ctx
->Driver
.NeedFlush
)
843 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
845 rmesa
->vb
.recheck
= GL_FALSE
;
847 if (check_vtx_fmt( ctx
)) {
848 if (!rmesa
->vb
.installed
) {
849 if (R200_DEBUG
& DEBUG_VFMT
)
850 fprintf(stderr
, "reinstall (new install)\n");
852 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
853 ctx
->Driver
.FlushVertices
= r200VtxFmtFlushVertices
;
854 rmesa
->vb
.installed
= GL_TRUE
;
856 else if (R200_DEBUG
& DEBUG_VFMT
)
857 fprintf(stderr
, "%s: already installed", __FUNCTION__
);
860 if (R200_DEBUG
& DEBUG_VFMT
)
861 fprintf(stderr
, "%s: failed\n", __FUNCTION__
);
863 if (rmesa
->vb
.installed
) {
864 if (rmesa
->dma
.flush
)
865 rmesa
->dma
.flush( rmesa
);
866 _tnl_wakeup_exec( ctx
);
867 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
868 rmesa
->vb
.installed
= GL_FALSE
;
877 static void r200_Materialfv( GLenum face
, GLenum pname
,
878 const GLfloat
*params
)
880 GET_CURRENT_CONTEXT(ctx
);
881 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
883 if (R200_DEBUG
& DEBUG_VFMT
)
884 fprintf(stderr
, "%s\n", __FUNCTION__
);
886 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
887 VFMT_FALLBACK( __FUNCTION__
);
888 CALL_Materialfv(GET_DISPATCH(), (face
, pname
, params
));
891 _mesa_noop_Materialfv( face
, pname
, params
);
892 r200UpdateMaterial( ctx
);
898 static void r200_Begin( GLenum mode
)
900 GET_CURRENT_CONTEXT(ctx
);
901 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
903 if (R200_DEBUG
& DEBUG_VFMT
)
904 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
905 _mesa_lookup_enum_by_nr( mode
));
907 if (mode
> GL_POLYGON
) {
908 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
912 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
913 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
918 _mesa_update_state( ctx
);
920 if (rmesa
->NewGLState
)
921 r200ValidateState( ctx
);
923 if (rmesa
->vb
.recheck
)
924 r200VtxfmtValidate( ctx
);
926 if (!rmesa
->vb
.installed
) {
927 CALL_Begin(GET_DISPATCH(), (mode
));
932 if (rmesa
->dma
.flush
&& rmesa
->vb
.counter
< 12) {
933 if (R200_DEBUG
& DEBUG_VFMT
)
934 fprintf(stderr
, "%s: flush almost-empty buffers\n", __FUNCTION__
);
935 flush_prims( rmesa
);
938 /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
940 if (!rmesa
->dma
.flush
) {
941 if (rmesa
->dma
.current
.ptr
+ 12*rmesa
->vb
.vertex_size
*4 >
942 rmesa
->dma
.current
.end
) {
943 R200_NEWPRIM( rmesa
);
944 r200RefillCurrentDmaRegion( rmesa
);
947 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
948 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
949 (rmesa
->vb
.vertex_size
* 4);
951 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
952 rmesa
->vb
.notify
= wrap_buffer
;
953 rmesa
->dma
.flush
= flush_prims
;
954 ctx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
958 rmesa
->vb
.prim
[0] = mode
;
959 start_prim( rmesa
, mode
| PRIM_BEGIN
);
964 static void r200_End( void )
966 GET_CURRENT_CONTEXT(ctx
);
967 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
969 if (R200_DEBUG
& DEBUG_VFMT
)
970 fprintf(stderr
, "%s\n", __FUNCTION__
);
972 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
973 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glEnd" );
977 note_last_prim( rmesa
, PRIM_END
);
978 rmesa
->vb
.prim
[0] = GL_POLYGON
+1;
982 /* Fallback on difficult entrypoints:
984 #define PRE_LOOPBACK( FUNC ) \
986 if (R200_DEBUG & DEBUG_VFMT) \
987 fprintf(stderr, "%s\n", __FUNCTION__); \
988 VFMT_FALLBACK( __FUNCTION__ ); \
990 #define TAG(x) r200_fallback_##x
991 #include "vtxfmt_tmp.h"
995 static GLboolean
r200NotifyBegin( GLcontext
*ctx
, GLenum p
)
997 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
999 if (R200_DEBUG
& DEBUG_VFMT
)
1000 fprintf(stderr
, "%s\n", __FUNCTION__
);
1002 assert(!rmesa
->vb
.installed
);
1005 _mesa_update_state( ctx
);
1007 if (rmesa
->NewGLState
)
1008 r200ValidateState( ctx
);
1010 if (ctx
->Driver
.NeedFlush
)
1011 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
1013 if (rmesa
->vb
.recheck
)
1014 r200VtxfmtValidate( ctx
);
1016 if (!rmesa
->vb
.installed
) {
1017 if (R200_DEBUG
& DEBUG_VFMT
)
1018 fprintf(stderr
, "%s -- failed\n", __FUNCTION__
);
1026 static void r200VtxFmtFlushVertices( GLcontext
*ctx
, GLuint flags
)
1028 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1030 if (R200_DEBUG
& DEBUG_VFMT
)
1031 fprintf(stderr
, "%s\n", __FUNCTION__
);
1033 assert(rmesa
->vb
.installed
);
1035 if (flags
& FLUSH_UPDATE_CURRENT
) {
1036 r200_copy_to_current( ctx
);
1037 if (R200_DEBUG
& DEBUG_VFMT
)
1038 fprintf(stderr
, "reinstall on update_current\n");
1039 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
1040 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
1043 if (flags
& FLUSH_STORED_VERTICES
) {
1044 assert (rmesa
->dma
.flush
== 0 ||
1045 rmesa
->dma
.flush
== flush_prims
);
1046 if (rmesa
->dma
.flush
== flush_prims
)
1047 flush_prims( rmesa
);
1048 ctx
->Driver
.NeedFlush
&= ~FLUSH_STORED_VERTICES
;
1054 /* At this point, don't expect very many versions of each function to
1055 * be generated, so not concerned about freeing them?
1059 void r200VtxfmtInit( GLcontext
*ctx
, GLboolean useCodegen
)
1061 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1062 GLvertexformat
*vfmt
= &(rmesa
->vb
.vtxfmt
);
1064 MEMSET( vfmt
, 0, sizeof(GLvertexformat
) );
1066 /* Hook in chooser functions for codegen, etc:
1068 r200VtxfmtInitChoosers( vfmt
);
1070 /* Handled fully in supported states, but no codegen:
1072 vfmt
->Materialfv
= r200_Materialfv
;
1073 vfmt
->ArrayElement
= _ae_loopback_array_elt
; /* generic helper */
1074 vfmt
->Rectf
= _mesa_noop_Rectf
; /* generic helper */
1075 vfmt
->Begin
= r200_Begin
;
1076 vfmt
->End
= r200_End
;
1078 /* Fallback for performance reasons: (Fix with cva/elt path here and
1079 * dmatmp2.h style primitive-merging)
1081 * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
1084 vfmt
->DrawArrays
= r200_fallback_DrawArrays
;
1085 vfmt
->DrawElements
= r200_fallback_DrawElements
;
1086 vfmt
->DrawRangeElements
= r200_fallback_DrawRangeElements
;
1089 /* Not active in supported states; just keep ctx->Current uptodate:
1091 vfmt
->EdgeFlag
= _mesa_noop_EdgeFlag
;
1092 vfmt
->EdgeFlagv
= _mesa_noop_EdgeFlagv
;
1093 vfmt
->Indexf
= _mesa_noop_Indexf
;
1094 vfmt
->Indexfv
= _mesa_noop_Indexfv
;
1097 /* Active but unsupported -- fallback if we receive these:
1099 vfmt
->CallList
= r200_fallback_CallList
;
1100 vfmt
->CallLists
= r200_fallback_CallLists
;
1101 vfmt
->EvalCoord1f
= r200_fallback_EvalCoord1f
;
1102 vfmt
->EvalCoord1fv
= r200_fallback_EvalCoord1fv
;
1103 vfmt
->EvalCoord2f
= r200_fallback_EvalCoord2f
;
1104 vfmt
->EvalCoord2fv
= r200_fallback_EvalCoord2fv
;
1105 vfmt
->EvalMesh1
= r200_fallback_EvalMesh1
;
1106 vfmt
->EvalMesh2
= r200_fallback_EvalMesh2
;
1107 vfmt
->EvalPoint1
= r200_fallback_EvalPoint1
;
1108 vfmt
->EvalPoint2
= r200_fallback_EvalPoint2
;
1109 vfmt
->TexCoord4f
= r200_fallback_TexCoord4f
;
1110 vfmt
->TexCoord4fv
= r200_fallback_TexCoord4fv
;
1111 vfmt
->MultiTexCoord4fARB
= r200_fallback_MultiTexCoord4fARB
;
1112 vfmt
->MultiTexCoord4fvARB
= r200_fallback_MultiTexCoord4fvARB
;
1113 vfmt
->Vertex4f
= r200_fallback_Vertex4f
;
1114 vfmt
->Vertex4fv
= r200_fallback_Vertex4fv
;
1115 vfmt
->VertexAttrib1fNV
= r200_fallback_VertexAttrib1fNV
;
1116 vfmt
->VertexAttrib1fvNV
= r200_fallback_VertexAttrib1fvNV
;
1117 vfmt
->VertexAttrib2fNV
= r200_fallback_VertexAttrib2fNV
;
1118 vfmt
->VertexAttrib2fvNV
= r200_fallback_VertexAttrib2fvNV
;
1119 vfmt
->VertexAttrib3fNV
= r200_fallback_VertexAttrib3fNV
;
1120 vfmt
->VertexAttrib3fvNV
= r200_fallback_VertexAttrib3fvNV
;
1121 vfmt
->VertexAttrib4fNV
= r200_fallback_VertexAttrib4fNV
;
1122 vfmt
->VertexAttrib4fvNV
= r200_fallback_VertexAttrib4fvNV
;
1123 vfmt
->FogCoordfEXT
= r200_fallback_FogCoordfEXT
;
1124 vfmt
->FogCoordfvEXT
= r200_fallback_FogCoordfvEXT
;
1126 (void)r200_fallback_vtxfmt
;
1128 TNL_CONTEXT(ctx
)->Driver
.NotifyBegin
= r200NotifyBegin
;
1130 rmesa
->vb
.enabled
= 1;
1131 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
1132 rmesa
->vb
.primflags
= 0;
1134 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1135 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1136 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1137 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1138 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ub
);
1139 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1140 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ub
);
1141 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1142 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4f
);
1143 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4fv
);
1144 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3f
);
1145 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3fv
);
1146 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1147 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1148 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1149 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1150 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3f
);
1151 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1152 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1153 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1154 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1155 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1156 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1157 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1158 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1159 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1160 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1161 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1162 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1163 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1164 /* make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT );
1165 make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
1167 r200InitCodegen( &rmesa
->vb
.codegen
, useCodegen
);
1170 static void free_funcs( struct dynfn
*l
)
1172 struct dynfn
*f
, *tmp
;
1173 foreach_s (f
, tmp
, l
) {
1174 remove_from_list( f
);
1175 _mesa_exec_free( f
->code
);
1180 void r200VtxfmtUnbindContext( GLcontext
*ctx
)
1185 void r200VtxfmtMakeCurrent( GLcontext
*ctx
)
1190 void r200VtxfmtDestroy( GLcontext
*ctx
)
1192 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1194 count_funcs( rmesa
);
1195 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1196 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1197 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1198 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1199 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ub
);
1200 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1201 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ub
);
1202 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1203 free_funcs( &rmesa
->vb
.dfn_cache
.Color4f
);
1204 free_funcs( &rmesa
->vb
.dfn_cache
.Color4fv
);
1205 free_funcs( &rmesa
->vb
.dfn_cache
.Color3f
);
1206 free_funcs( &rmesa
->vb
.dfn_cache
.Color3fv
);
1207 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1208 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1209 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1210 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1211 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3f
);
1212 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1213 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1214 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1215 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1216 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1217 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1218 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1219 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1220 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1221 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1222 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1223 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1224 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1225 /* free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT );
1226 free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/