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_multitexcoord( GLuint count
, GLuint unit
, GLfloat
* f
)
408 GL_CALL(MultiTexCoord3fvARB
)( GL_TEXTURE0
+unit
, f
);
411 GL_CALL(MultiTexCoord2fvARB
)( GL_TEXTURE0
+unit
, f
);
414 GL_CALL(MultiTexCoord1fvARB
)( GL_TEXTURE0
+unit
, f
);
417 assert( count
== 0 );
422 void VFMT_FALLBACK( const char *caller
)
424 GET_CURRENT_CONTEXT(ctx
);
425 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
426 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
428 GLuint ind0
= rmesa
->vb
.vtxfmt_0
;
429 GLuint ind1
= rmesa
->vb
.vtxfmt_1
;
435 if (R200_DEBUG
& (DEBUG_FALLBACKS
|DEBUG_VFMT
))
436 fprintf(stderr
, "%s from %s\n", __FUNCTION__
, caller
);
438 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
439 VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__
);
443 /* Copy vertices out of dma:
445 nrverts
= copy_dma_verts( rmesa
, tmp
);
447 /* Finish the prim at this point:
449 note_last_prim( rmesa
, 0 );
450 flush_prims( rmesa
);
452 /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
454 prim
= rmesa
->vb
.prim
[0];
455 ctx
->Driver
.CurrentExecPrimitive
= GL_POLYGON
+1;
456 _tnl_wakeup_exec( ctx
);
457 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
459 assert(rmesa
->dma
.flush
== 0);
460 rmesa
->vb
.fell_back
= GL_TRUE
;
461 rmesa
->vb
.installed
= GL_FALSE
;
462 GL_CALL(Begin
)( prim
);
464 if (rmesa
->vb
.installed_color_3f_sz
== 4)
465 alpha
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
467 /* Replay saved vertices
469 for (i
= 0 ; i
< nrverts
; i
++) {
472 if (ind0
& R200_VTX_N0
) {
473 GL_CALL(Normal3fv
)( &tmp
[i
][offset
] );
477 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
478 GL_CALL(Color4ubv
)( (GLubyte
*)&tmp
[i
][offset
] );
481 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
482 GL_CALL(Color4fv
)( &tmp
[i
][offset
] );
485 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
486 GL_CALL(Color3fv
)( &tmp
[i
][offset
] );
490 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
491 GL_CALL(SecondaryColor3ubvEXT
)( (GLubyte
*)&tmp
[i
][offset
] );
495 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
496 count
= VTX_TEXn_COUNT( ind1
, unit
);
497 dispatch_multitexcoord( count
, unit
, &tmp
[i
][offset
] );
501 GL_CALL(Vertex3fv
)( &tmp
[i
][0] );
504 /* Replay current vertex
506 if (ind0
& R200_VTX_N0
)
507 GL_CALL(Normal3fv
)( rmesa
->vb
.normalptr
);
509 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
510 GL_CALL(Color4ub
)( rmesa
->vb
.colorptr
->red
,
511 rmesa
->vb
.colorptr
->green
,
512 rmesa
->vb
.colorptr
->blue
,
513 rmesa
->vb
.colorptr
->alpha
);
515 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
516 GL_CALL(Color4fv
)( rmesa
->vb
.floatcolorptr
);
518 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
519 if (rmesa
->vb
.installed_color_3f_sz
== 4 && alpha
!= 1.0) {
520 GL_CALL(Color4f
)( rmesa
->vb
.floatcolorptr
[0],
521 rmesa
->vb
.floatcolorptr
[1],
522 rmesa
->vb
.floatcolorptr
[2],
526 GL_CALL(Color3fv
)( rmesa
->vb
.floatcolorptr
);
530 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
)
531 GL_CALL(SecondaryColor3ubEXT
)( rmesa
->vb
.specptr
->red
,
532 rmesa
->vb
.specptr
->green
,
533 rmesa
->vb
.specptr
->blue
);
535 for ( unit
= 0 ; unit
< ctx
->Const
.MaxTextureUnits
; unit
++ ) {
536 count
= VTX_TEXn_COUNT( ind1
, unit
);
537 dispatch_multitexcoord( count
, unit
, rmesa
->vb
.texcoordptr
[unit
] );
543 static void wrap_buffer( void )
545 GET_CURRENT_CONTEXT(ctx
);
546 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
547 GLfloat tmp
[3][R200_MAX_VERTEX_SIZE
];
550 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_PRIMS
))
551 fprintf(stderr
, "%s %d\n", __FUNCTION__
,
552 rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
);
554 /* Don't deal with parity.
556 if ((((rmesa
->vb
.initial_counter
- rmesa
->vb
.counter
) -
557 rmesa
->vb
.primlist
[rmesa
->vb
.nrprims
].start
) & 1)) {
559 rmesa
->vb
.initial_counter
++;
563 /* Copy vertices out of dma:
565 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1)
568 nrverts
= copy_dma_verts( rmesa
, tmp
);
570 if (R200_DEBUG
& DEBUG_VFMT
)
571 fprintf(stderr
, "%d vertices to copy\n", nrverts
);
573 /* Finish the prim at this point:
575 note_last_prim( rmesa
, 0 );
578 /* Fire any buffered primitives
580 flush_prims( rmesa
);
584 r200RefillCurrentDmaRegion( rmesa
);
586 /* Reset counter, dmaptr
588 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.ptr
+ rmesa
->dma
.current
.address
);
589 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
590 (rmesa
->vb
.vertex_size
* 4);
592 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
593 rmesa
->vb
.notify
= wrap_buffer
;
595 rmesa
->dma
.flush
= flush_prims
;
597 /* Restart wrapped primitive:
599 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1)
600 start_prim( rmesa
, rmesa
->vb
.prim
[0] );
603 /* Reemit saved vertices
605 for (i
= 0 ; i
< nrverts
; i
++) {
606 if (R200_DEBUG
& DEBUG_VERTS
) {
608 fprintf(stderr
, "re-emit vertex %d to %p\n", i
,
609 (void *)rmesa
->vb
.dmaptr
);
610 if (R200_DEBUG
& DEBUG_VERBOSE
)
611 for (j
= 0 ; j
< rmesa
->vb
.vertex_size
; j
++)
612 fprintf(stderr
, "\t%08x/%f\n", *(int*)&tmp
[i
][j
], tmp
[i
][j
]);
615 memcpy( rmesa
->vb
.dmaptr
, tmp
[i
], rmesa
->vb
.vertex_size
* 4 );
616 rmesa
->vb
.dmaptr
+= rmesa
->vb
.vertex_size
;
623 * Determines the hardware vertex format based on the current state vector.
626 * If the hardware TCL unit is capable of handling the current state vector,
627 * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
630 * Make this color format selection data driven. If we receive only ubytes,
631 * send color as ubytes. Also check if converting (with free checking for
632 * overflow) is cheaper than sending floats directly.
635 * When intializing texture coordinates, it might be faster to just copy the
636 * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that
637 * some of the data (i.e., the last texture coordinate components) get copied
638 * over, but that still may be faster than the conditional branching. If
639 * nothing else, the code will be smaller and easier to follow.
641 static GLboolean
check_vtx_fmt( GLcontext
*ctx
)
643 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
644 GLuint ind0
= R200_VTX_Z0
;
647 GLuint count
[R200_MAX_TEXTURE_UNITS
];
649 if (rmesa
->TclFallback
|| rmesa
->vb
.fell_back
|| ctx
->CompileFlag
)
652 if (ctx
->Driver
.NeedFlush
& FLUSH_UPDATE_CURRENT
)
653 ctx
->Driver
.FlushVertices( ctx
, FLUSH_UPDATE_CURRENT
);
655 /* Make all this event-driven:
657 if (ctx
->Light
.Enabled
) {
660 if (ctx
->Light
.ColorMaterialEnabled
)
661 ind0
|= R200_VTX_FP_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
663 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
666 /* TODO: make this data driven?
668 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_0_SHIFT
;
670 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) {
671 ind0
|= R200_VTX_PK_RGBA
<< R200_VTX_COLOR_1_SHIFT
;
675 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
678 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
679 if (rmesa
->TexGenNeedNormals
[i
]) {
683 switch( ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
684 case TEXTURE_CUBE_BIT
:
689 case TEXTURE_RECT_BIT
:
697 ind1
|= count
[i
] << (3 * i
);
702 if (R200_DEBUG
& (DEBUG_VFMT
|DEBUG_STATE
))
703 fprintf(stderr
, "%s: format: 0x%x, 0x%x\n", __FUNCTION__
, ind0
, ind1
);
706 rmesa
->vb
.vtxfmt_0
= ind0
;
707 rmesa
->vb
.vtxfmt_1
= ind1
;
708 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
710 rmesa
->vb
.vertex_size
= 3;
711 rmesa
->vb
.normalptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
712 rmesa
->vb
.colorptr
= NULL
;
713 rmesa
->vb
.floatcolorptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
714 rmesa
->vb
.specptr
= NULL
;
715 rmesa
->vb
.floatspecptr
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
716 rmesa
->vb
.texcoordptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
717 rmesa
->vb
.texcoordptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
718 rmesa
->vb
.texcoordptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
719 rmesa
->vb
.texcoordptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX3
];
720 rmesa
->vb
.texcoordptr
[4] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX4
];
721 rmesa
->vb
.texcoordptr
[5] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX5
];
722 rmesa
->vb
.texcoordptr
[6] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
723 rmesa
->vb
.texcoordptr
[7] = ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
]; /* dummy */
725 /* Run through and initialize the vertex components in the order
726 * the hardware understands:
728 if (ind0
& R200_VTX_N0
) {
729 rmesa
->vb
.normalptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
730 rmesa
->vb
.vertex_size
+= 3;
731 rmesa
->vb
.normalptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][0];
732 rmesa
->vb
.normalptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][1];
733 rmesa
->vb
.normalptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
][2];
736 if (VTX_COLOR(ind0
, 0) == R200_VTX_PK_RGBA
) {
737 rmesa
->vb
.colorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
738 rmesa
->vb
.vertex_size
+= 1;
739 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0] );
740 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1] );
741 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2] );
742 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.colorptr
->alpha
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3] );
744 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGBA
) {
745 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
746 rmesa
->vb
.vertex_size
+= 4;
747 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
748 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
749 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
750 rmesa
->vb
.floatcolorptr
[3] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
752 else if (VTX_COLOR(ind0
, 0) == R200_VTX_FP_RGB
) {
753 rmesa
->vb
.floatcolorptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
754 rmesa
->vb
.vertex_size
+= 3;
755 rmesa
->vb
.floatcolorptr
[0] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
756 rmesa
->vb
.floatcolorptr
[1] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
757 rmesa
->vb
.floatcolorptr
[2] = ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
760 if (VTX_COLOR(ind0
, 1) == R200_VTX_PK_RGBA
) {
761 rmesa
->vb
.specptr
= &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].color
;
762 rmesa
->vb
.vertex_size
+= 1;
763 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->red
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][0] );
764 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->green
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][1] );
765 UNCLAMPED_FLOAT_TO_CHAN( rmesa
->vb
.specptr
->blue
, ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
][2] );
769 for ( i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++ ) {
770 if ( count
[i
] != 0 ) {
771 float * const attr
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+i
];
774 rmesa
->vb
.texcoordptr
[i
] = &rmesa
->vb
.vertex
[rmesa
->vb
.vertex_size
].f
;
776 for ( j
= 0 ; j
< count
[i
] ; j
++ ) {
777 rmesa
->vb
.texcoordptr
[i
][j
] = attr
[j
];
780 rmesa
->vb
.vertex_size
+= count
[i
];
784 if (rmesa
->vb
.installed_vertex_format
!= rmesa
->vb
.vtxfmt_0
) {
785 if (R200_DEBUG
& DEBUG_VFMT
)
786 fprintf(stderr
, "reinstall on vertex_format change\n");
787 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
788 rmesa
->vb
.installed_vertex_format
= rmesa
->vb
.vtxfmt_0
;
791 if (R200_DEBUG
& DEBUG_VFMT
)
792 fprintf(stderr
, "%s -- success\n", __FUNCTION__
);
798 void r200VtxfmtInvalidate( GLcontext
*ctx
)
800 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
802 rmesa
->vb
.recheck
= GL_TRUE
;
803 rmesa
->vb
.fell_back
= GL_FALSE
;
807 static void r200VtxfmtValidate( GLcontext
*ctx
)
809 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
811 if (R200_DEBUG
& DEBUG_VFMT
)
812 fprintf(stderr
, "%s\n", __FUNCTION__
);
814 if (ctx
->Driver
.NeedFlush
)
815 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
817 rmesa
->vb
.recheck
= GL_FALSE
;
819 if (check_vtx_fmt( ctx
)) {
820 if (!rmesa
->vb
.installed
) {
821 if (R200_DEBUG
& DEBUG_VFMT
)
822 fprintf(stderr
, "reinstall (new install)\n");
824 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
825 ctx
->Driver
.FlushVertices
= r200VtxFmtFlushVertices
;
826 rmesa
->vb
.installed
= GL_TRUE
;
828 else if (R200_DEBUG
& DEBUG_VFMT
)
829 fprintf(stderr
, "%s: already installed", __FUNCTION__
);
832 if (R200_DEBUG
& DEBUG_VFMT
)
833 fprintf(stderr
, "%s: failed\n", __FUNCTION__
);
835 if (rmesa
->vb
.installed
) {
836 if (rmesa
->dma
.flush
)
837 rmesa
->dma
.flush( rmesa
);
838 _tnl_wakeup_exec( ctx
);
839 ctx
->Driver
.FlushVertices
= r200FlushVertices
;
840 rmesa
->vb
.installed
= GL_FALSE
;
849 static void r200_Materialfv( GLenum face
, GLenum pname
,
850 const GLfloat
*params
)
852 GET_CURRENT_CONTEXT(ctx
);
853 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
855 if (R200_DEBUG
& DEBUG_VFMT
)
856 fprintf(stderr
, "%s\n", __FUNCTION__
);
858 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
859 VFMT_FALLBACK( __FUNCTION__
);
860 GL_CALL(Materialfv
)( face
, pname
, params
);
863 _mesa_noop_Materialfv( face
, pname
, params
);
864 r200UpdateMaterial( ctx
);
870 static void r200_Begin( GLenum mode
)
872 GET_CURRENT_CONTEXT(ctx
);
873 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
875 if (R200_DEBUG
& DEBUG_VFMT
)
876 fprintf(stderr
, "%s( %s )\n", __FUNCTION__
,
877 _mesa_lookup_enum_by_nr( mode
));
879 if (mode
> GL_POLYGON
) {
880 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
884 if (rmesa
->vb
.prim
[0] != GL_POLYGON
+1) {
885 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
890 _mesa_update_state( ctx
);
892 if (rmesa
->NewGLState
)
893 r200ValidateState( ctx
);
895 if (rmesa
->vb
.recheck
)
896 r200VtxfmtValidate( ctx
);
898 if (!rmesa
->vb
.installed
) {
899 GL_CALL(Begin
)( mode
);
904 if (rmesa
->dma
.flush
&& rmesa
->vb
.counter
< 12) {
905 if (R200_DEBUG
& DEBUG_VFMT
)
906 fprintf(stderr
, "%s: flush almost-empty buffers\n", __FUNCTION__
);
907 flush_prims( rmesa
);
910 /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
912 if (!rmesa
->dma
.flush
) {
913 if (rmesa
->dma
.current
.ptr
+ 12*rmesa
->vb
.vertex_size
*4 >
914 rmesa
->dma
.current
.end
) {
915 R200_NEWPRIM( rmesa
);
916 r200RefillCurrentDmaRegion( rmesa
);
919 rmesa
->vb
.dmaptr
= (int *)(rmesa
->dma
.current
.address
+ rmesa
->dma
.current
.ptr
);
920 rmesa
->vb
.counter
= (rmesa
->dma
.current
.end
- rmesa
->dma
.current
.ptr
) /
921 (rmesa
->vb
.vertex_size
* 4);
923 rmesa
->vb
.initial_counter
= rmesa
->vb
.counter
;
924 rmesa
->vb
.notify
= wrap_buffer
;
925 rmesa
->dma
.flush
= flush_prims
;
926 ctx
->Driver
.NeedFlush
|= FLUSH_STORED_VERTICES
;
930 rmesa
->vb
.prim
[0] = mode
;
931 start_prim( rmesa
, mode
| PRIM_BEGIN
);
936 static void r200_End( void )
938 GET_CURRENT_CONTEXT(ctx
);
939 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
941 if (R200_DEBUG
& DEBUG_VFMT
)
942 fprintf(stderr
, "%s\n", __FUNCTION__
);
944 if (rmesa
->vb
.prim
[0] == GL_POLYGON
+1) {
945 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glEnd" );
949 note_last_prim( rmesa
, PRIM_END
);
950 rmesa
->vb
.prim
[0] = GL_POLYGON
+1;
954 /* Fallback on difficult entrypoints:
956 #define PRE_LOOPBACK( FUNC ) \
958 if (R200_DEBUG & DEBUG_VFMT) \
959 fprintf(stderr, "%s\n", __FUNCTION__); \
960 VFMT_FALLBACK( __FUNCTION__ ); \
962 #define TAG(x) r200_fallback_##x
963 #include "vtxfmt_tmp.h"
967 static GLboolean
r200NotifyBegin( GLcontext
*ctx
, GLenum p
)
969 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
971 if (R200_DEBUG
& DEBUG_VFMT
)
972 fprintf(stderr
, "%s\n", __FUNCTION__
);
974 assert(!rmesa
->vb
.installed
);
977 _mesa_update_state( ctx
);
979 if (rmesa
->NewGLState
)
980 r200ValidateState( ctx
);
982 if (ctx
->Driver
.NeedFlush
)
983 ctx
->Driver
.FlushVertices( ctx
, ctx
->Driver
.NeedFlush
);
985 if (rmesa
->vb
.recheck
)
986 r200VtxfmtValidate( ctx
);
988 if (!rmesa
->vb
.installed
) {
989 if (R200_DEBUG
& DEBUG_VFMT
)
990 fprintf(stderr
, "%s -- failed\n", __FUNCTION__
);
998 static void r200VtxFmtFlushVertices( GLcontext
*ctx
, GLuint flags
)
1000 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1002 if (R200_DEBUG
& DEBUG_VFMT
)
1003 fprintf(stderr
, "%s\n", __FUNCTION__
);
1005 assert(rmesa
->vb
.installed
);
1007 if (flags
& FLUSH_UPDATE_CURRENT
) {
1008 r200_copy_to_current( ctx
);
1009 if (R200_DEBUG
& DEBUG_VFMT
)
1010 fprintf(stderr
, "reinstall on update_current\n");
1011 _mesa_install_exec_vtxfmt( ctx
, &rmesa
->vb
.vtxfmt
);
1012 ctx
->Driver
.NeedFlush
&= ~FLUSH_UPDATE_CURRENT
;
1015 if (flags
& FLUSH_STORED_VERTICES
) {
1016 assert (rmesa
->dma
.flush
== 0 ||
1017 rmesa
->dma
.flush
== flush_prims
);
1018 if (rmesa
->dma
.flush
== flush_prims
)
1019 flush_prims( rmesa
);
1020 ctx
->Driver
.NeedFlush
&= ~FLUSH_STORED_VERTICES
;
1026 /* At this point, don't expect very many versions of each function to
1027 * be generated, so not concerned about freeing them?
1031 void r200VtxfmtInit( GLcontext
*ctx
, GLboolean useCodegen
)
1033 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1034 GLvertexformat
*vfmt
= &(rmesa
->vb
.vtxfmt
);
1036 MEMSET( vfmt
, 0, sizeof(GLvertexformat
) );
1038 /* Hook in chooser functions for codegen, etc:
1040 r200VtxfmtInitChoosers( vfmt
);
1042 /* Handled fully in supported states, but no codegen:
1044 vfmt
->Materialfv
= r200_Materialfv
;
1045 vfmt
->ArrayElement
= _ae_loopback_array_elt
; /* generic helper */
1046 vfmt
->Rectf
= _mesa_noop_Rectf
; /* generic helper */
1047 vfmt
->Begin
= r200_Begin
;
1048 vfmt
->End
= r200_End
;
1050 /* Fallback for performance reasons: (Fix with cva/elt path here and
1051 * dmatmp2.h style primitive-merging)
1053 * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
1056 vfmt
->DrawArrays
= r200_fallback_DrawArrays
;
1057 vfmt
->DrawElements
= r200_fallback_DrawElements
;
1058 vfmt
->DrawRangeElements
= r200_fallback_DrawRangeElements
;
1061 /* Not active in supported states; just keep ctx->Current uptodate:
1063 vfmt
->FogCoordfvEXT
= _mesa_noop_FogCoordfvEXT
;
1064 vfmt
->FogCoordfEXT
= _mesa_noop_FogCoordfEXT
;
1065 vfmt
->EdgeFlag
= _mesa_noop_EdgeFlag
;
1066 vfmt
->EdgeFlagv
= _mesa_noop_EdgeFlagv
;
1067 vfmt
->Indexf
= _mesa_noop_Indexf
;
1068 vfmt
->Indexfv
= _mesa_noop_Indexfv
;
1071 /* Active but unsupported -- fallback if we receive these:
1073 vfmt
->CallList
= r200_fallback_CallList
;
1074 vfmt
->CallLists
= r200_fallback_CallLists
;
1075 vfmt
->EvalCoord1f
= r200_fallback_EvalCoord1f
;
1076 vfmt
->EvalCoord1fv
= r200_fallback_EvalCoord1fv
;
1077 vfmt
->EvalCoord2f
= r200_fallback_EvalCoord2f
;
1078 vfmt
->EvalCoord2fv
= r200_fallback_EvalCoord2fv
;
1079 vfmt
->EvalMesh1
= r200_fallback_EvalMesh1
;
1080 vfmt
->EvalMesh2
= r200_fallback_EvalMesh2
;
1081 vfmt
->EvalPoint1
= r200_fallback_EvalPoint1
;
1082 vfmt
->EvalPoint2
= r200_fallback_EvalPoint2
;
1083 vfmt
->TexCoord4f
= r200_fallback_TexCoord4f
;
1084 vfmt
->TexCoord4fv
= r200_fallback_TexCoord4fv
;
1085 vfmt
->MultiTexCoord4fARB
= r200_fallback_MultiTexCoord4fARB
;
1086 vfmt
->MultiTexCoord4fvARB
= r200_fallback_MultiTexCoord4fvARB
;
1087 vfmt
->Vertex4f
= r200_fallback_Vertex4f
;
1088 vfmt
->Vertex4fv
= r200_fallback_Vertex4fv
;
1089 vfmt
->VertexAttrib1fNV
= r200_fallback_VertexAttrib1fNV
;
1090 vfmt
->VertexAttrib1fvNV
= r200_fallback_VertexAttrib1fvNV
;
1091 vfmt
->VertexAttrib2fNV
= r200_fallback_VertexAttrib2fNV
;
1092 vfmt
->VertexAttrib2fvNV
= r200_fallback_VertexAttrib2fvNV
;
1093 vfmt
->VertexAttrib3fNV
= r200_fallback_VertexAttrib3fNV
;
1094 vfmt
->VertexAttrib3fvNV
= r200_fallback_VertexAttrib3fvNV
;
1095 vfmt
->VertexAttrib4fNV
= r200_fallback_VertexAttrib4fNV
;
1096 vfmt
->VertexAttrib4fvNV
= r200_fallback_VertexAttrib4fvNV
;
1098 (void)r200_fallback_vtxfmt
;
1100 TNL_CONTEXT(ctx
)->Driver
.NotifyBegin
= r200NotifyBegin
;
1102 rmesa
->vb
.enabled
= 1;
1103 rmesa
->vb
.prim
= &ctx
->Driver
.CurrentExecPrimitive
;
1104 rmesa
->vb
.primflags
= 0;
1106 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1107 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1108 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1109 make_empty_list( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1110 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ub
);
1111 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1112 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ub
);
1113 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1114 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4f
);
1115 make_empty_list( &rmesa
->vb
.dfn_cache
.Color4fv
);
1116 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3f
);
1117 make_empty_list( &rmesa
->vb
.dfn_cache
.Color3fv
);
1118 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1119 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1120 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1121 make_empty_list( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1122 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3f
);
1123 make_empty_list( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1124 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1125 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1126 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1127 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1128 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1129 make_empty_list( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1130 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1131 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1132 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1133 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1134 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1135 make_empty_list( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);
1137 r200InitCodegen( &rmesa
->vb
.codegen
, useCodegen
);
1140 static void free_funcs( struct dynfn
*l
)
1142 struct dynfn
*f
, *tmp
;
1143 foreach_s (f
, tmp
, l
) {
1144 remove_from_list( f
);
1145 ALIGN_FREE( f
->code
);
1150 void r200VtxfmtUnbindContext( GLcontext
*ctx
)
1155 void r200VtxfmtMakeCurrent( GLcontext
*ctx
)
1160 void r200VtxfmtDestroy( GLcontext
*ctx
)
1162 r200ContextPtr rmesa
= R200_CONTEXT( ctx
);
1164 count_funcs( rmesa
);
1165 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2f
);
1166 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex2fv
);
1167 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3f
);
1168 free_funcs( &rmesa
->vb
.dfn_cache
.Vertex3fv
);
1169 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ub
);
1170 free_funcs( &rmesa
->vb
.dfn_cache
.Color4ubv
);
1171 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ub
);
1172 free_funcs( &rmesa
->vb
.dfn_cache
.Color3ubv
);
1173 free_funcs( &rmesa
->vb
.dfn_cache
.Color4f
);
1174 free_funcs( &rmesa
->vb
.dfn_cache
.Color4fv
);
1175 free_funcs( &rmesa
->vb
.dfn_cache
.Color3f
);
1176 free_funcs( &rmesa
->vb
.dfn_cache
.Color3fv
);
1177 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubEXT
);
1178 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3ubvEXT
);
1179 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fEXT
);
1180 free_funcs( &rmesa
->vb
.dfn_cache
.SecondaryColor3fvEXT
);
1181 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3f
);
1182 free_funcs( &rmesa
->vb
.dfn_cache
.Normal3fv
);
1183 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3f
);
1184 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord3fv
);
1185 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2f
);
1186 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord2fv
);
1187 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1f
);
1188 free_funcs( &rmesa
->vb
.dfn_cache
.TexCoord1fv
);
1189 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fARB
);
1190 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord3fvARB
);
1191 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fARB
);
1192 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord2fvARB
);
1193 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fARB
);
1194 free_funcs( &rmesa
->vb
.dfn_cache
.MultiTexCoord1fvARB
);