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
);
106 void r200_copy_to_current( GLcontext
*ctx
)
108 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
111 if (R200_DEBUG
& DEBUG_VFMT
)
112 fprintf(stderr
, "%s\n", __FUNCTION__
);
114 assert(ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
);
116 if (rmesa
->vb
.vtxfmt_0
& R200_VTX_N0
) {
117 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0] = rmesa
->vb
.normalptr
[0];
118 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1] = rmesa
->vb
.normalptr
[1];
119 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2] = rmesa
->vb
.normalptr
[2];
122 switch( VTX_COLOR(rmesa
->vb
.vtxfmt_0
, 0) ) {
123 case R200_VTX_PK_RGBA
:
124 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->red
);
125 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->green
);
126 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->blue
);
127 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = UBYTE_TO_FLOAT( rmesa
->vb
.colorptr
->alpha
);
130 case R200_VTX_FP_RGB
:
131 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] = rmesa
->vb
.floatcolorptr
[0];
132 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] = rmesa
->vb
.floatcolorptr
[1];
133 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] = rmesa
->vb
.floatcolorptr
[2];
136 case R200_VTX_FP_RGBA
:
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];
140 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] = rmesa
->vb
.floatcolorptr
[3];
147 if (VTX_COLOR(rmesa
->vb
.vtxfmt_0
, 1) == R200_VTX_PK_RGBA
) {
148 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->red
);
149 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->green
);
150 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] = UBYTE_TO_FLOAT( rmesa
->vb
.specptr
->blue
);
153 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
154 const unsigned count
= VTX_TEXn_COUNT( rmesa
->vb
.vtxfmt_1
, i
);
155 GLfloat
* const src
= rmesa
->vb
.texcoordptr
[i
];
160 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = src
[1];
161 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = src
[2];
164 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = src
[1];
165 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = 0.0F
;
168 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][1] = 0.0F
;
169 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][2] = 0.0F
;
173 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][0] = src
[0];
174 ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
][3] = 1.0F
;
178 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
181 static GLboolean discreet_gl_prim
[GL_POLYGON
+1] = {
184 0, /* 2 line_strip */
194 static void flush_prims( r200ContextPtr rmesa
)
197 struct r200_dma_region tmp
= rmesa
->dma
.current
;
200 tmp
.aos_size
= rmesa
->vb
.vertex_size
;
201 tmp
.aos_stride
= rmesa
->vb
.vertex_size
;
202 tmp
.aos_start
= GET_START(&tmp
);
204 rmesa
->dma
.current
.ptr
= rmesa
->dma
.current
.start
+=
205 (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) *
206 rmesa
->vb
.vertex_size
* 4;
208 rmesa
->tcl
.vertex_format
= rmesa
->vb
.vtxfmt_0
;
209 rmesa
->tcl
.aos_components
[0] = &tmp
;
210 rmesa
->tcl
.nr_aos_components
= 1;
211 rmesa
->dma
.flush
= 0;
213 /* Optimize the primitive list:
215 if (rmesa
->vb
.nrprims
> 1) {
216 for (j
= 0, i
= 1 ; i
< rmesa
->vb
.nrprims
; i
++) {
217 int pj
= rmesa
->vb
.primlist
[j
].prim
& 0xf;
218 int pi
= rmesa
->vb
.primlist
[i
].prim
& 0xf;
220 if (pj
== pi
&& discreet_gl_prim
[pj
] &&
221 rmesa
->vb
.primlist
[i
].start
== rmesa
->vb
.primlist
[j
].end
) {
222 rmesa
->vb
.primlist
[j
].end
= rmesa
->vb
.primlist
[i
].end
;
226 if (j
!= i
) rmesa
->vb
.primlist
[j
] = rmesa
->vb
.primlist
[i
];
229 rmesa
->vb
.nrprims
= j
+1;
232 if (rmesa
->vb
.vtxfmt_0
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] ||
233 rmesa
->vb
.vtxfmt_1
!= rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
]) {
234 R200_STATECHANGE( rmesa
, vtx
);
235 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_0
] = rmesa
->vb
.vtxfmt_0
;
236 rmesa
->hw
.vtx
.cmd
[VTX_VTXFMT_1
] = rmesa
->vb
.vtxfmt_1
;
240 for (i
= 0 ; i
< rmesa
->vb
.nrprims
; i
++) {
241 if (R200_DEBUG
& DEBUG_PRIMS
)
242 fprintf(stderr
, "vtxfmt prim %d: %s %d..%d\n", i
,
243 _mesa_lookup_enum_by_nr( rmesa
->vb
.primlist
[i
].prim
&
245 rmesa
->vb
.primlist
[i
].start
,
246 rmesa
->vb
.primlist
[i
].end
);
248 if (rmesa
->vb
.primlist
[i
].start
< rmesa
->vb
.primlist
[i
].end
)
249 r200EmitPrimitive( rmesa
->glCtx
,
250 rmesa
->vb
.primlist
[i
].start
,
251 rmesa
->vb
.primlist
[i
].end
,
252 rmesa
->vb
.primlist
[i
].prim
);
255 rmesa
->vb
.nrprims
= 0;
256 r200ReleaseDmaRegion( rmesa
, &tmp
, __FUNCTION__
);
260 static void start_prim( r200ContextPtr rmesa
, GLuint mode
)
262 if (R200_DEBUG
& DEBUG_VFMT
)
263 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
264 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
266 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
=
267 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
268 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
= mode
;
271 static void note_last_prim( r200ContextPtr rmesa
, GLuint flags
)
273 if (R200_DEBUG
& DEBUG_VFMT
)
274 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
275 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
277 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
278 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].prim
|= flags
;
279 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].end
=
280 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
;
282 if (++(rmesa
->vb
.nrprims
) == R200_MAX_PRIMS
)
283 flush_prims( rmesa
);
288 static void copy_vertex( r200ContextPtr rmesa
, GLuint n
, GLfloat
*dst
)
291 GLfloat
*src
= (GLfloat
*)(rmesa
->dma
.current
.address
+
292 rmesa
->dma
.current
.ptr
+
293 (rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
) *
294 rmesa
->vb
.vertex_size
* 4);
296 if (R200_DEBUG
& DEBUG_VFMT
)
297 fprintf(stderr
, "copy_vertex %d\n", rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
+ n
);
299 for (i
= 0 ; i
< rmesa
->vb
.vertex_size
; i
++) {
304 /* NOTE: This actually reads the copied vertices back from uncached
305 * memory. Could also use the counter/notify mechanism to populate
306 * tmp on the fly as vertices are generated.
308 static GLuint
copy_dma_verts( r200ContextPtr rmesa
, GLfloat (*tmp
)[R200_MAX_VERTEX_SIZE
] )
311 GLuint nr
= (rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
312 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
;
314 if (R200_DEBUG
& DEBUG_VFMT
)
315 fprintf(stderr
, "%s %d verts\n", __FUNCTION__
, nr
);
317 switch( rmesa
->vb
.prim
[0] )
323 for (i
= 0 ; i
< ovf
; i
++)
324 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
328 for (i
= 0 ; i
< ovf
; i
++)
329 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
333 for (i
= 0 ; i
< ovf
; i
++)
334 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
339 copy_vertex( rmesa
, nr
-1, tmp
[0] );
342 case GL_TRIANGLE_FAN
:
347 copy_vertex( rmesa
, 0, tmp
[0] );
350 copy_vertex( rmesa
, 0, tmp
[0] );
351 copy_vertex( rmesa
, nr
-1, tmp
[1] );
354 case GL_TRIANGLE_STRIP
:
356 for (i
= 0 ; i
< ovf
; i
++)
357 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
361 case 0: ovf
= 0; break;
362 case 1: ovf
= 1; break;
363 default: ovf
= 2 + (nr
&1); break;
365 for (i
= 0 ; i
< ovf
; i
++)
366 copy_vertex( rmesa
, nr
-ovf
+i
, tmp
[i
] );
374 static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller
)
376 GET_CURRENT_CONTEXT(ctx
);
377 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
379 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_FALLBACKS
))
380 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
382 if (ctx
->Driver
.NeedFlush
)
383 r200VtxFmtFlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
386 _mesa_update_state( ctx
); /* clear state so fell_back sticks */
388 _tnl_wakeup_exec( ctx
);
389 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
391 assert( rmesa
->dma
.flush
== 0 );
392 rmesa
->vb
.fell_back
= GL_TRUE
;
393 rmesa
->vb
.installed
= GL_FALSE
;
399 * An interesting optimization of this function would be to have 3 element
400 * table with the dispatch offsets of the TexCoord?fv functions, use count
401 * to look-up the table, and a specialized version of GL_CALL that used the
402 * offset number instead of the name.
404 static void dispatch_texcoord( GLuint count
, GLfloat
* f
)
408 GL_CALL(TexCoord3fv
)( f
);
411 GL_CALL(TexCoord2fv
)( f
);
414 GL_CALL(TexCoord1fv
)( f
);
417 assert( count
== 0 );
422 static void dispatch_multitexcoord( GLuint count
, GLuint unit
, GLfloat
* f
)
426 GL_CALL(MultiTexCoord3fvARB
)( GL_TEXTURE0
+unit
, f
);
429 GL_CALL(MultiTexCoord2fvARB
)( GL_TEXTURE0
+unit
, f
);
432 GL_CALL(MultiTexCoord1fvARB
)( GL_TEXTURE0
+unit
, f
);
435 assert( count
== 0 );
440 static void VFMT_FALLBACK( const char *caller
)
442 GET_CURRENT_CONTEXT(ctx
);
443 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
444 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
446 GLuint ind0
= rmesa
->vb
.vtxfmt_0
;
447 GLuint ind1
= rmesa
->vb
.vtxfmt_1
;
453 if (R200_DEBUG
& (DEBUG_FALLBACKS
|DEBUG_VFMT
))
454 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
456 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
457 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__
);
461 /* Copy vertices out of dma:
463 nrverts
= copy_dma_verts( rmesa
, tmp
);
465 /* Finish the prim at this point:
467 note_last_prim( rmesa
, 0 );
468 flush_prims( rmesa
);
470 /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
472 prim
= rmesa
->vb
.prim
[0];
473 ctx
->Driver
.CurrentExecPrimitive
= GL_POLYGON
+1;
474 _tnl_wakeup_exec( ctx
);
475 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
477 assert(rmesa
->dma
.flush
== 0);
478 rmesa
->vb
.fell_back
= GL_TRUE
;
479 rmesa
->vb
.installed
= GL_FALSE
;
480 GL_CALL(Begin
)( prim
);
482 if (rmesa
->vb
.installed_color_3f_sz
== 4)
483 alpha
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
485 /* Replay saved vertices
487 for (i
= 0 ; i
< nrverts
; i
++) {
490 if (ind0
& R200_VTX_N0
) {
491 GL_CALL(Normal3fv
)( &tmp
[i
][offset
] );
495 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
496 GL_CALL(Color4ubv
)( (GLubyte
*)&tmp
[i
][offset
] );
499 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
500 GL_CALL(Color4fv
)( &tmp
[i
][offset
] );
503 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
504 GL_CALL(Color3fv
)( &tmp
[i
][offset
] );
508 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
509 GL_CALL(SecondaryColor3ubvEXT
)( (GLubyte
*)&tmp
[i
][offset
] );
513 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
514 count
= VTX_TEXn_COUNT( ind1
, unit
);
515 dispatch_multitexcoord( count
, unit
, &tmp
[i
][offset
] );
519 GL_CALL(Vertex3fv
)( &tmp
[i
][0] );
522 /* Replay current vertex
524 if (ind0
& R200_VTX_N0
)
525 GL_CALL(Normal3fv
)( rmesa
->vb
.normalptr
);
527 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
528 GL_CALL(Color4ub
)( rmesa
->vb
.colorptr
->red
,
529 rmesa
->vb
.colorptr
->green
,
530 rmesa
->vb
.colorptr
->blue
,
531 rmesa
->vb
.colorptr
->alpha
);
533 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
534 GL_CALL(Color4fv
)( rmesa
->vb
.floatcolorptr
);
536 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
537 if (rmesa
->vb
.installed_color_3f_sz
== 4 && alpha
!= 1.0) {
538 GL_CALL(Color4f
)( rmesa
->vb
.floatcolorptr
[0],
539 rmesa
->vb
.floatcolorptr
[1],
540 rmesa
->vb
.floatcolorptr
[2],
544 GL_CALL(Color3fv
)( rmesa
->vb
.floatcolorptr
);
548 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
)
549 GL_CALL(SecondaryColor3ubEXT
)( rmesa
->vb
.specptr
->red
,
550 rmesa
->vb
.specptr
->green
,
551 rmesa
->vb
.specptr
->blue
);
553 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
554 count
= VTX_TEXn_COUNT( ind1
, unit
);
555 dispatch_multitexcoord( count
, unit
, rmesa
->vb
.texcoordptr
[unit
] );
561 static void wrap_buffer( void )
563 GET_CURRENT_CONTEXT(ctx
);
564 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
565 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
568 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_PRIMS
))
569 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
570 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
572 /* Don't deal with parity.
574 if ((((rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
575 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
) & 1)) {
577 rmesa
->vb
.initial_counter
++;
581 /* Copy vertices out of dma:
583 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1)
586 nrverts
= copy_dma_verts( rmesa
, tmp
);
588 if (R200_DEBUG
& DEBUG_VFMT
)
589 fprintf(stderr
, "%d vertices to copy\n", nrverts
);
591 /* Finish the prim at this point:
593 note_last_prim( rmesa
, 0 );
596 /* Fire any buffered primitives
598 flush_prims( rmesa
);
602 r200RefillCurrentDmaRegion( rmesa
);
604 /* Reset counter, dmaptr
606 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.ptr
+ rmesa
->dma
.current
.address
);
607 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
608 (rmesa
->vb
.vertex_size
* 4);
610 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
611 rmesa
->vb
.notify
= wrap_buffer
;
613 rmesa
->dma
.flush
= flush_prims
;
615 /* Restart wrapped primitive:
617 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1)
618 start_prim( rmesa
, rmesa
->vb
.prim
[0] );
621 /* Reemit saved vertices
623 for (i
= 0 ; i
< nrverts
; i
++) {
624 if (R200_DEBUG
& DEBUG_VERTS
) {
626 fprintf(stderr
, "re-emit vertex %d to %p\n", i
,
627 (void *)rmesa
->vb
.dmaptr
);
628 if (R200_DEBUG
& DEBUG_VERBOSE
)
629 for (j
= 0 ; j
< rmesa
->vb
.vertex_size
; j
++)
630 fprintf(stderr
, "\t%08x/%f\n", *(int*)&tmp
[i
][j
], tmp
[i
][j
]);
633 memcpy( rmesa
->vb
.dmaptr
, tmp
[i
], rmesa
->vb
.vertex_size
* 4 );
634 rmesa
->vb
.dmaptr
+= rmesa
->vb
.vertex_size
;
641 * Determines the hardware vertex format based on the current state vector.
644 * If the hardware TCL unit is capable of handling the current state vector,
645 * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
648 * Make this color format selection data driven. If we receive only ubytes,
649 * send color as ubytes. Also check if converting (with free checking for
650 * overflow) is cheaper than sending floats directly.
653 * When intializing texture coordinates, it might be faster to just copy the
654 * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that
655 * some of the data (i.e., the last texture coordinate components) get copied
656 * over, but that still may be faster than the conditional branching. If
657 * nothing else, the code will be smaller and easier to follow.
659 static GLboolean
check_vtx_fmt( GLcontext
*ctx
)
661 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
662 GLuint ind0
= R200_VTX_Z0
;
665 GLuint count
[R200_MAX_TEXTURE_UNITS
];
669 if (rmesa
->TclFallback
|| rmesa
->vb
.fell_back
|| ctx
->CompileFlag
)
672 if (ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
)
673 ctx
->Driver
.FlushVertices( ctx
, FLUSH_UPDATE_CURRENT
);
675 /* Make all this event-driven:
677 if (ctx
->Light
.Enabled
) {
680 if (ctx
->Light
.ColorMaterialEnabled
)
681 ind0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
683 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
686 /* TODO: make this data driven?
688 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
690 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
691 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
;
695 re_cntl
= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] & ~(R200_VTX_STQ0_D3D
|
701 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
704 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
705 if (ctx
->Texture
.Unit
[i
].TexGenEnabled
) {
706 if (rmesa
->TexGenNeedNormals
[i
]) {
711 switch( ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
712 case TEXTURE_CUBE_BIT
:
713 re_cntl
|= R200_VTX_STQ0_D3D
<< (2 * i
);
719 case TEXTURE_RECT_BIT
:
727 ind1
|= count
[i
] << (3 * i
);
732 if ( re_cntl
!= rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] ) {
733 R200_STATECHANGE( rmesa
, set
);
734 rmesa
->hw
.set
.cmd
[SET_RE_CNTL
] = re_cntl
;
737 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_STATE
))
738 fprintf(stderr
, "%s: format: 0x%x, 0x%x\n", __FUNCTION__
, ind0
, ind1
);
741 rmesa
->vb
.vtxfmt_0
= ind0
;
742 rmesa
->vb
.vtxfmt_1
= ind1
;
743 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
745 rmesa
->vb
.vertex_size
= 3;
746 rmesa
->vb
.normalptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
747 rmesa
->vb
.colorptr
= NULL
;
748 rmesa
->vb
.floatcolorptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
749 rmesa
->vb
.specptr
= NULL
;
750 rmesa
->vb
.floatspecptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
751 rmesa
->vb
.texcoordptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
752 rmesa
->vb
.texcoordptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
753 rmesa
->vb
.texcoordptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
754 rmesa
->vb
.texcoordptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX3
];
755 rmesa
->vb
.texcoordptr
[4] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX4
];
756 rmesa
->vb
.texcoordptr
[5] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX5
];
757 rmesa
->vb
.texcoordptr
[6] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
758 rmesa
->vb
.texcoordptr
[7] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
760 /* Run through and initialize the vertex components in the order
761 * the hardware understands:
763 if (ind0
& R200_VTX_N0
) {
764 rmesa
->vb
.normalptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
765 rmesa
->vb
.vertex_size
+= 3;
766 rmesa
->vb
.normalptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0];
767 rmesa
->vb
.normalptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1];
768 rmesa
->vb
.normalptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2];
771 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
772 rmesa
->vb
.colorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
773 rmesa
->vb
.vertex_size
+= 1;
774 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] );
775 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] );
776 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] );
777 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->alpha
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] );
779 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
780 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
781 rmesa
->vb
.vertex_size
+= 4;
782 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
783 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
784 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
785 rmesa
->vb
.floatcolorptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
787 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
788 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
789 rmesa
->vb
.vertex_size
+= 3;
790 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
791 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
792 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
795 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
796 rmesa
->vb
.specptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
797 rmesa
->vb
.vertex_size
+= 1;
798 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] );
799 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] );
800 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] );
804 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
805 if ( count
[i
] != 0 ) {
806 float * const attr
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
];
809 rmesa
->vb
.texcoordptr
[i
] = &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
811 for ( j
= 0 ; j
< count
[i
] ; j
++ ) {
812 rmesa
->vb
.texcoordptr
[i
][j
] = attr
[j
];
815 rmesa
->vb
.vertex_size
+= count
[i
];
819 if (rmesa
->vb
.installed_vertex_format
!= rmesa
->vb
.vtxfmt_0
) {
820 if (R200_DEBUG
& DEBUG_VFMT
)
821 fprintf(stderr
, "reinstall on vertex_format change\n");
822 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
823 rmesa
->vb
.installed_vertex_format
= rmesa
->vb
.vtxfmt_0
;
826 if (R200_DEBUG
& DEBUG_VFMT
)
827 fprintf(stderr
, "%s -- success\n", __FUNCTION__
);
833 void r200VtxfmtInvalidate( GLcontext
*ctx
)
835 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
837 rmesa
->vb
.recheck
= GL_TRUE
;
838 rmesa
->vb
.fell_back
= GL_FALSE
;
842 static void r200VtxfmtValidate( GLcontext
*ctx
)
844 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
846 if (R200_DEBUG
& DEBUG_VFMT
)
847 fprintf(stderr
, "%s\n", __FUNCTION__
);
849 if (ctx
->Driver
.NeedFlush
)
850 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
852 rmesa
->vb
.recheck
= GL_FALSE
;
854 if (check_vtx_fmt( ctx
)) {
855 if (!rmesa
->vb
.installed
) {
856 if (R200_DEBUG
& DEBUG_VFMT
)
857 fprintf(stderr
, "reinstall (new install)\n");
859 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
860 ctx
->Driver
.FlushVertices
= r200VtxFmtFlushVertices
;
861 rmesa
->vb
.installed
= GL_TRUE
;
863 else if (R200_DEBUG
& DEBUG_VFMT
)
864 fprintf(stderr
, "%s: already installed", __FUNCTION__
);
867 if (R200_DEBUG
& DEBUG_VFMT
)
868 fprintf(stderr
, "%s: failed\n", __FUNCTION__
);
870 if (rmesa
->vb
.installed
) {
871 if (rmesa
->dma
.flush
)
872 rmesa
->dma
.flush( rmesa
);
873 _tnl_wakeup_exec( ctx
);
874 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
875 rmesa
->vb
.installed
= GL_FALSE
;
884 static void r200_Materialfv( GLenum face
, GLenum pname
,
885 const GLfloat
*params
)
887 GET_CURRENT_CONTEXT(ctx
);
888 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
890 if (R200_DEBUG
& DEBUG_VFMT
)
891 fprintf(stderr
, "%s\n", __FUNCTION__
);
893 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
894 VFMT_FALLBACK( __FUNCTION__
);
895 GL_CALL(Materialfv
)( face
, pname
, params
);
898 _mesa_noop_Materialfv( face
, pname
, params
);
899 r200UpdateMaterial( ctx
);
905 static void r200_Begin( GLenum mode
)
907 GET_CURRENT_CONTEXT(ctx
);
908 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
910 if (R200_DEBUG
& DEBUG_VFMT
)
911 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
912 _mesa_lookup_enum_by_nr( mode
));
914 if (mode
> GL_POLYGON
) {
915 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
919 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
920 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
925 _mesa_update_state( ctx
);
927 if (rmesa
->NewGLState
)
928 r200ValidateState( ctx
);
930 if (rmesa
->vb
.recheck
)
931 r200VtxfmtValidate( ctx
);
933 if (!rmesa
->vb
.installed
) {
934 GL_CALL(Begin
)( mode
);
939 if (rmesa
->dma
.flush
&& rmesa
->vb
.counter
< 12) {
940 if (R200_DEBUG
& DEBUG_VFMT
)
941 fprintf(stderr
, "%s: flush almost-empty buffers\n", __FUNCTION__
);
942 flush_prims( rmesa
);
945 /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
947 if (!rmesa
->dma
.flush
) {
948 if (rmesa
->dma
.current
.ptr
+ 12*rmesa
->vb
.vertex_size
*4 >
949 rmesa
->dma
.current
.end
) {
950 R200_NEWPRIM( rmesa
);
951 r200RefillCurrentDmaRegion( rmesa
);
954 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
955 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
956 (rmesa
->vb
.vertex_size
* 4);
958 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
959 rmesa
->vb
.notify
= wrap_buffer
;
960 rmesa
->dma
.flush
= flush_prims
;
961 ctx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
965 rmesa
->vb
.prim
[0] = mode
;
966 start_prim( rmesa
, mode
| PRIM_BEGIN
);
971 static void r200_End( void )
973 GET_CURRENT_CONTEXT(ctx
);
974 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
976 if (R200_DEBUG
& DEBUG_VFMT
)
977 fprintf(stderr
, "%s\n", __FUNCTION__
);
979 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
980 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glEnd" );
984 note_last_prim( rmesa
, PRIM_END
);
985 rmesa
->vb
.prim
[0] = GL_POLYGON
+1;
989 /* Fallback on difficult entrypoints:
991 #define PRE_LOOPBACK( FUNC ) \
993 if (R200_DEBUG & DEBUG_VFMT) \
994 fprintf(stderr, "%s\n", __FUNCTION__); \
995 VFMT_FALLBACK( __FUNCTION__ ); \
997 #define TAG(x) r200_fallback_##x
998 #include "vtxfmt_tmp.h"
1002 static GLboolean
r200NotifyBegin( GLcontext
*ctx
, GLenum p
)
1004 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1006 if (R200_DEBUG
& DEBUG_VFMT
)
1007 fprintf(stderr
, "%s\n", __FUNCTION__
);
1009 assert(!rmesa
->vb
.installed
);
1012 _mesa_update_state( ctx
);
1014 if (rmesa
->NewGLState
)
1015 r200ValidateState( ctx
);
1017 if (ctx
->Driver
.NeedFlush
)
1018 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
1020 if (rmesa
->vb
.recheck
)
1021 r200VtxfmtValidate( ctx
);
1023 if (!rmesa
->vb
.installed
) {
1024 if (R200_DEBUG
& DEBUG_VFMT
)
1025 fprintf(stderr
, "%s -- failed\n", __FUNCTION__
);
1033 static void r200VtxFmtFlushVertices( GLcontext
*ctx
, GLuint flags
)
1035 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1037 if (R200_DEBUG
& DEBUG_VFMT
)
1038 fprintf(stderr
, "%s\n", __FUNCTION__
);
1040 assert(rmesa
->vb
.installed
);
1042 if (flags
& FLUSH_UPDATE_CURRENT
) {
1043 r200_copy_to_current( ctx
);
1044 if (R200_DEBUG
& DEBUG_VFMT
)
1045 fprintf(stderr
, "reinstall on update_current\n");
1046 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
1047 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
1050 if (flags
& FLUSH_STORED_VERTICES
) {
1051 assert (rmesa
->dma
.flush
== 0 ||
1052 rmesa
->dma
.flush
== flush_prims
);
1053 if (rmesa
->dma
.flush
== flush_prims
)
1054 flush_prims( rmesa
);
1055 ctx
->Driver
.NeedFlush
&= ~FLUSH_STORED_VERTICES
;
1061 /* At this point, don't expect very many versions of each function to
1062 * be generated, so not concerned about freeing them?
1066 void r200VtxfmtInit( GLcontext
*ctx
, GLboolean useCodegen
)
1068 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1069 GLvertexformat
*vfmt
= &(rmesa
->vb
.vtxfmt
);
1071 MEMSET( vfmt
, 0, sizeof(GLvertexformat
) );
1073 /* Hook in chooser functions for codegen, etc:
1075 r200VtxfmtInitChoosers( vfmt
);
1077 /* Handled fully in supported states, but no codegen:
1079 vfmt
->Materialfv
= r200_Materialfv
;
1080 vfmt
->ArrayElement
= _ae_loopback_array_elt
; /* generic helper */
1081 vfmt
->Rectf
= _mesa_noop_Rectf
; /* generic helper */
1082 vfmt
->Begin
= r200_Begin
;
1083 vfmt
->End
= r200_End
;
1085 /* Fallback for performance reasons: (Fix with cva/elt path here and
1086 * dmatmp2.h style primitive-merging)
1088 * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
1091 vfmt
->DrawArrays
= r200_fallback_DrawArrays
;
1092 vfmt
->DrawElements
= r200_fallback_DrawElements
;
1093 vfmt
->DrawRangeElements
= r200_fallback_DrawRangeElements
;
1096 /* Not active in supported states; just keep ctx->Current uptodate:
1098 vfmt
->FogCoordfvEXT
= _mesa_noop_FogCoordfvEXT
;
1099 vfmt
->FogCoordfEXT
= _mesa_noop_FogCoordfEXT
;
1100 vfmt
->EdgeFlag
= _mesa_noop_EdgeFlag
;
1101 vfmt
->EdgeFlagv
= _mesa_noop_EdgeFlagv
;
1102 vfmt
->Indexf
= _mesa_noop_Indexf
;
1103 vfmt
->Indexfv
= _mesa_noop_Indexfv
;
1106 /* Active but unsupported -- fallback if we receive these:
1108 vfmt
->CallList
= r200_fallback_CallList
;
1109 vfmt
->CallLists
= r200_fallback_CallLists
;
1110 vfmt
->EvalCoord1f
= r200_fallback_EvalCoord1f
;
1111 vfmt
->EvalCoord1fv
= r200_fallback_EvalCoord1fv
;
1112 vfmt
->EvalCoord2f
= r200_fallback_EvalCoord2f
;
1113 vfmt
->EvalCoord2fv
= r200_fallback_EvalCoord2fv
;
1114 vfmt
->EvalMesh1
= r200_fallback_EvalMesh1
;
1115 vfmt
->EvalMesh2
= r200_fallback_EvalMesh2
;
1116 vfmt
->EvalPoint1
= r200_fallback_EvalPoint1
;
1117 vfmt
->EvalPoint2
= r200_fallback_EvalPoint2
;
1118 vfmt
->TexCoord4f
= r200_fallback_TexCoord4f
;
1119 vfmt
->TexCoord4fv
= r200_fallback_TexCoord4fv
;
1120 vfmt
->MultiTexCoord4fARB
= r200_fallback_MultiTexCoord4fARB
;
1121 vfmt
->MultiTexCoord4fvARB
= r200_fallback_MultiTexCoord4fvARB
;
1122 vfmt
->Vertex4f
= r200_fallback_Vertex4f
;
1123 vfmt
->Vertex4fv
= r200_fallback_Vertex4fv
;
1124 vfmt
->VertexAttrib1fNV
= r200_fallback_VertexAttrib1fNV
;
1125 vfmt
->VertexAttrib1fvNV
= r200_fallback_VertexAttrib1fvNV
;
1126 vfmt
->VertexAttrib2fNV
= r200_fallback_VertexAttrib2fNV
;
1127 vfmt
->VertexAttrib2fvNV
= r200_fallback_VertexAttrib2fvNV
;
1128 vfmt
->VertexAttrib3fNV
= r200_fallback_VertexAttrib3fNV
;
1129 vfmt
->VertexAttrib3fvNV
= r200_fallback_VertexAttrib3fvNV
;
1130 vfmt
->VertexAttrib4fNV
= r200_fallback_VertexAttrib4fNV
;
1131 vfmt
->VertexAttrib4fvNV
= r200_fallback_VertexAttrib4fvNV
;
1133 (void)r200_fallback_vtxfmt
;
1135 TNL_CONTEXT(ctx
)->Driver
.NotifyBegin
= r200NotifyBegin
;
1137 rmesa
->vb
.enabled
= 1;
1138 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
1139 rmesa
->vb
.primflags
= 0;
1141 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1142 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1143 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1144 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1145 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ub
);
1146 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1147 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ub
);
1148 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1149 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4f
);
1150 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4fv
);
1151 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3f
);
1152 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3fv
);
1153 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1154 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1155 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1156 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1157 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3f
);
1158 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1159 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1160 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1161 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1162 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1163 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1164 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1165 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1166 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1167 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1168 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1169 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1170 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1172 r200InitCodegen( &rmesa
->vb
.codegen
, useCodegen
);
1175 static void free_funcs( struct dynfn
*l
)
1177 struct dynfn
*f
, *tmp
;
1178 foreach_s (f
, tmp
, l
) {
1179 remove_from_list( f
);
1180 ALIGN_FREE( f
->code
);
1185 void r200VtxfmtUnbindContext( GLcontext
*ctx
)
1190 void r200VtxfmtMakeCurrent( GLcontext
*ctx
)
1195 void r200VtxfmtDestroy( GLcontext
*ctx
)
1197 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1199 count_funcs( rmesa
);
1200 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1201 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1202 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1203 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1204 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ub
);
1205 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1206 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ub
);
1207 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1208 free_funcs( &rmesa
->vb
.dfn_cache
.Color4f
);
1209 free_funcs( &rmesa
->vb
.dfn_cache
.Color4fv
);
1210 free_funcs( &rmesa
->vb
.dfn_cache
.Color3f
);
1211 free_funcs( &rmesa
->vb
.dfn_cache
.Color3fv
);
1212 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1213 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1214 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1215 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1216 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3f
);
1217 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1218 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1219 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1220 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1221 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1222 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1223 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1224 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1225 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1226 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1227 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1228 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1229 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);