summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c')
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c1456
1 files changed, 890 insertions, 566 deletions
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
index 414dc072d..6d84f5c9c 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c
@@ -1,638 +1,961 @@
/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ Tungsten Graphics Inc., Cedar Park, Texas.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
/*
- * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* Authors:
- * Gareth Hughes <gareth@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
+ *
*/
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+#include "radeon_tex.h"
+#include "radeon_tcl.h"
+#include "radeon_vtxfmt.h"
-
-#include "glheader.h"
#include "api_noop.h"
-#include "colormac.h"
+#include "api_arrayelt.h"
#include "context.h"
-#include "light.h"
-#include "macros.h"
#include "mem.h"
#include "mmath.h"
#include "mtypes.h"
-#include "simple_list.h"
+#include "enums.h"
+#include "glapi.h"
+#include "colormac.h"
+#include "light.h"
+#include "state.h"
#include "vtxfmt.h"
-#include "math/m_xform.h"
#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_array_api.h"
-#include "radeon_context.h"
-#include "radeon_ioctl.h"
-#include "radeon_vb.h"
-#include "radeon_vtxfmt.h"
-
-
-struct radeon_imm_vertex {
- /* The immediate mode vertex cache.
- */
- radeonTnlVertex vertices[8];
-
- /* Current vertices out of the cache. This makes the state machine
- * a lot simpler, and avoids the need to swap lots of function
- * pointers around.
- */
- radeonTnlVertex *v0;
- radeonTnlVertex *v1;
- radeonTnlVertex *v2;
- radeonTnlVertex *v3;
-
- radeon_flush_func *flush_tab;
-
- void (*save_vertex)( GLcontext *ctx, radeonTnlVertex *v );
- void (*flush_vertex)( GLcontext *ctx, radeonTnlVertex *v );
-
- radeon_interp_func interp;
+struct radeon_vb vb;
- GLuint prim;
- GLuint format;
+static void radeonFlushVertices( GLcontext *, GLuint );
- GLvertexformat vtxfmt;
-};
+static void count_func( const char *name, struct dynfn *l )
+{
+ int i = 0;
+ struct dynfn *f;
+ foreach (f, l) i++;
+ if (i) fprintf(stderr, "%s: %d\n", name, i );
+}
+static void count_funcs( radeonContextPtr rmesa )
+{
+ count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f );
+ count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv );
+ count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f );
+ count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv );
+ count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub );
+ count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv );
+ count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub );
+ count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv );
+ count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f );
+ count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv );
+ count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f );
+ count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv );
+ count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
+ count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
+ count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
+ count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
+ count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f );
+ count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv );
+ count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f );
+ count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv );
+ count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f );
+ count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv );
+ count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
+ count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
+ count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
+ count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
+}
-#define VERTEX radeonVertex
-#define TNL_VERTEX radeonTnlVertex
+void radeon_copy_to_current( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A)))
+ assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT);
+ assert(vb.context == ctx);
-#define INTERP_RGBA( t, out, a, b ) \
-do { \
- GLint i; \
- for ( i = 0 ; i < 4 ; i++ ) { \
- GLfloat fa = UBYTE_TO_FLOAT( a[i] ); \
- GLfloat fb = UBYTE_TO_FLOAT( b[i] ); \
- GLfloat fo = LINTERP( t, fa, fb ); \
- UNCLAMPED_FLOAT_TO_UBYTE( out[i], fo ); \
- } \
-} while (0)
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) {
+ ctx->Current.Normal[0] = vb.normalptr[0];
+ ctx->Current.Normal[1] = vb.normalptr[1];
+ ctx->Current.Normal[2] = vb.normalptr[2];
+ }
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) {
+ ctx->Current.Color[0] = UBYTE_TO_FLOAT( vb.ubytecolorptr[0] );
+ ctx->Current.Color[1] = UBYTE_TO_FLOAT( vb.ubytecolorptr[1] );
+ ctx->Current.Color[2] = UBYTE_TO_FLOAT( vb.ubytecolorptr[2] );
+ ctx->Current.Color[3] = UBYTE_TO_FLOAT( vb.ubytecolorptr[3] );
+ }
+
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) {
+ ctx->Current.Color[0] = vb.floatcolorptr[0];
+ ctx->Current.Color[1] = vb.floatcolorptr[1];
+ ctx->Current.Color[2] = vb.floatcolorptr[2];
+ }
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA)
+ ctx->Current.Color[3] = vb.floatcolorptr[3];
+
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) {
+ ctx->Current.SecondaryColor[0] = UBYTE_TO_FLOAT( vb.ubytespecptr[0] );
+ ctx->Current.SecondaryColor[1] = UBYTE_TO_FLOAT( vb.ubytespecptr[1] );
+ ctx->Current.SecondaryColor[2] = UBYTE_TO_FLOAT( vb.ubytespecptr[2] );
+ }
+
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_ST0) {
+ ctx->Current.Texcoord[0][0] = vb.texcoordptr[0][0];
+ ctx->Current.Texcoord[0][1] = vb.texcoordptr[0][1];
+ ctx->Current.Texcoord[0][2] = 0.0F;
+ ctx->Current.Texcoord[0][3] = 1.0F;
+ }
+ if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_ST1) {
+ ctx->Current.Texcoord[1][0] = vb.texcoordptr[1][0];
+ ctx->Current.Texcoord[1][1] = vb.texcoordptr[1][1];
+ ctx->Current.Texcoord[1][2] = 0.0F;
+ ctx->Current.Texcoord[1][3] = 1.0F;
+ }
-/* ================================================================
- * Color functions: Always update ctx->Current.*
- */
+ ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
+}
-/* ================================================================
- * Material functions:
- */
+static GLboolean discreet_gl_prim[GL_POLYGON+1] = {
+ 1, /* 0 points */
+ 1, /* 1 lines */
+ 0, /* 2 line_strip */
+ 0, /* 3 line_loop */
+ 1, /* 4 tris */
+ 0, /* 5 tri_fan */
+ 0, /* 6 tri_strip */
+ 1, /* 7 quads */
+ 0, /* 8 quadstrip */
+ 0, /* 9 poly */
+};
-static __inline void radeon_recalc_base_color( GLcontext *ctx )
+static void flush_prims( radeonContextPtr rmesa )
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct gl_light *light;
-
- COPY_3V( rmesa->state.light.base_color, ctx->Light._BaseColor[0] );
- foreach ( light, &ctx->Light.EnabledList ) {
- ACC_3V( rmesa->state.light.base_color, light->_MatAmbient[0] );
+ int i,j;
+ struct radeon_dma_region tmp = rmesa->dma.current;
+
+ tmp.buf->refcount++;
+ tmp.aos_size = vb.vertex_size;
+ tmp.aos_stride = vb.vertex_size;
+ tmp.aos_start = GET_START(&tmp);
+
+ rmesa->dma.current.ptr = rmesa->dma.current.start +=
+ (vb.initial_counter - vb.counter) * vb.vertex_size * 4;
+
+ rmesa->tcl.vertex_format = rmesa->vb.vertex_format;
+ rmesa->tcl.aos_components[0] = &tmp;
+ rmesa->tcl.nr_aos_components = 1;
+ rmesa->dma.flush = 0;
+
+ /* Optimize the primitive list:
+ */
+ if (rmesa->vb.nrprims > 1) {
+ for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) {
+ int pj = rmesa->vb.primlist[j].prim & 0xf;
+ int pi = rmesa->vb.primlist[i].prim & 0xf;
+
+ if (pj == pi && discreet_gl_prim[pj] &&
+ rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) {
+ rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end;
+ }
+ else {
+ j++;
+ if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i];
+ }
+ }
+ rmesa->vb.nrprims = j+1;
}
-
- UNCLAMPED_FLOAT_TO_UBYTE( rmesa->state.light.base_alpha,
- ctx->Light.Material[0].Diffuse[3] );
-}
-
-/* ================================================================
- * Normal functions:
- */
-
-struct radeon_norm_tab {
- void (*normal3f_multi)( GLfloat x, GLfloat y, GLfloat z );
- void (*normal3fv_multi)( const GLfloat *v );
- void (*normal3f_single)( GLfloat x, GLfloat y, GLfloat z );
- void (*normal3fv_single)( const GLfloat *v );
-};
-
-static struct radeon_norm_tab norm_tab[0x4];
+ for (i = 0 ; i < rmesa->vb.nrprims; i++) {
+ if (RADEON_DEBUG & DEBUG_PRIMS)
+ fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i,
+ _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim &
+ PRIM_MODE_MASK ),
+ rmesa->vb.primlist[i].start,
+ rmesa->vb.primlist[i].end);
+
+ radeonEmitPrimitive( vb.context,
+ rmesa->vb.primlist[i].start,
+ rmesa->vb.primlist[i].end,
+ rmesa->vb.primlist[i].prim );
+ }
+ rmesa->vb.nrprims = 0;
+ radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ );
+}
-#define HAVE_HW_LIGHTING 0
-#define GET_CURRENT_VERTEX \
- GET_CURRENT_CONTEXT(ctx); \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
- radeonTnlVertexPtr v = rmesa->imm.v0
+static void start_prim( radeonContextPtr rmesa, GLuint mode )
+{
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter);
-#define CURRENT_NORMAL rmesa->state.current.normal
-#define BASE_COLOR rmesa->state.light.base_color
-#define BASE_ALPHA rmesa->state.light.base_alpha
+ rmesa->vb.primlist[rmesa->vb.nrprims].start = vb.initial_counter - vb.counter;
+ rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode;
+}
-#define VERT_COLOR( COMP ) v->color[COMP]
+static void note_last_prim( radeonContextPtr rmesa, GLuint flags )
+{
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter);
+ if (rmesa->vb.prim[0] != GL_POLYGON+1) {
+ rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags;
+ rmesa->vb.primlist[rmesa->vb.nrprims].end = vb.initial_counter - vb.counter;
-#define IND (0)
-#define TAG(x) radeon_##x
-#define PRESERVE_NORMAL_DEFS
-#include "tnl_dd/t_dd_imm_napi.h"
+ if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS)
+ flush_prims( rmesa );
+ }
+}
-#define IND (NORM_RESCALE)
-#define TAG(x) radeon_##x##_rescale
-#define PRESERVE_NORMAL_DEFS
-#include "tnl_dd/t_dd_imm_napi.h"
-#define IND (NORM_NORMALIZE)
-#define TAG(x) radeon_##x##_normalize
-#include "tnl_dd/t_dd_imm_napi.h"
+static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst )
+{
+ GLuint i;
+ GLfloat *src = (GLfloat *)(rmesa->dma.current.address +
+ rmesa->dma.current.ptr +
+ (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) *
+ vb.vertex_size * 4);
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n);
-static void radeon_init_norm_funcs( void )
-{
- radeon_init_norm();
- radeon_init_norm_rescale();
- radeon_init_norm_normalize();
+ for (i = 0 ; i < vb.vertex_size; i++) {
+ dst[i] = src[i];
+ }
}
-static void radeon_choose_Normal3f( GLfloat x, GLfloat y, GLfloat z )
+/* NOTE: This actually reads the copied vertices back from uncached
+ * memory. Could also use the counter/notify mechanism to populate
+ * tmp on the fly as vertices are generated.
+ */
+static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[15] )
{
- GET_CURRENT_CONTEXT(ctx);
- GLuint index;
-
- if ( ctx->Light.Enabled ) {
- if ( ctx->Transform.Normalize ) {
- index = NORM_NORMALIZE;
- }
- else if ( !ctx->Transform.RescaleNormals &&
- ctx->_ModelViewInvScale != 1.0 ) {
- index = NORM_RESCALE;
- }
- else {
- index = 0;
- }
-
- if ( ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev ) {
- ctx->Exec->Normal3f = norm_tab[index].normal3f_single;
+ GLuint ovf, i;
+ GLuint nr = (vb.initial_counter - vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start;
+
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr);
+
+ switch( rmesa->vb.prim[0] )
+ {
+ case GL_POINTS:
+ return 0;
+ case GL_LINES:
+ ovf = nr&1;
+ for (i = 0 ; i < ovf ; i++)
+ copy_vertex( rmesa, nr-ovf+i, tmp[i] );
+ return i;
+ case GL_TRIANGLES:
+ ovf = nr%3;
+ for (i = 0 ; i < ovf ; i++)
+ copy_vertex( rmesa, nr-ovf+i, tmp[i] );
+ return i;
+ case GL_QUADS:
+ ovf = nr&3;
+ for (i = 0 ; i < ovf ; i++)
+ copy_vertex( rmesa, nr-ovf+i, tmp[i] );
+ return i;
+ case GL_LINE_STRIP:
+ if (nr == 0)
+ return 0;
+ copy_vertex( rmesa, nr-1, tmp[0] );
+ return 1;
+ case GL_LINE_LOOP:
+ case GL_TRIANGLE_FAN:
+ case GL_POLYGON:
+ if (nr == 0)
+ return 0;
+ else if (nr == 1) {
+ copy_vertex( rmesa, 0, tmp[0] );
+ return 1;
} else {
- ctx->Exec->Normal3f = norm_tab[index].normal3f_multi;
+ copy_vertex( rmesa, 0, tmp[0] );
+ copy_vertex( rmesa, nr-1, tmp[1] );
+ return 2;
}
- } else {
- ctx->Exec->Normal3f = _mesa_noop_Normal3f;
+ case GL_TRIANGLE_STRIP:
+ ovf = MIN2( nr-1, 2 );
+ for (i = 0 ; i < ovf ; i++)
+ copy_vertex( rmesa, nr-ovf+i, tmp[i] );
+ return i;
+ case GL_QUAD_STRIP:
+ ovf = MIN2( nr-1, 2 );
+ if (nr > 2) ovf += nr&1;
+ for (i = 0 ; i < ovf ; i++)
+ copy_vertex( rmesa, nr-ovf+i, tmp[i] );
+ return i;
+ default:
+ assert(0);
+ return 0;
}
-
- glNormal3f( x, y, z );
}
-static void radeon_choose_Normal3fv( const GLfloat *v )
+static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller )
{
- GET_CURRENT_CONTEXT(ctx);
- GLuint index;
+ GLcontext *ctx = vb.context;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- if ( ctx->Light.Enabled ) {
- if ( ctx->Transform.Normalize ) {
- index = NORM_NORMALIZE;
- }
- else if ( !ctx->Transform.RescaleNormals &&
- ctx->_ModelViewInvScale != 1.0 ) {
- index = NORM_RESCALE;
- }
- else {
- index = 0;
- }
+ if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
+ fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
- if ( ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev ) {
- ctx->Exec->Normal3fv = norm_tab[index].normal3fv_single;
- } else {
- ctx->Exec->Normal3fv = norm_tab[index].normal3fv_multi;
- }
- } else {
- ctx->Exec->Normal3fv = _mesa_noop_Normal3fv;
- }
+ if (ctx->Driver.NeedFlush)
+ radeonFlushVertices( ctx, ctx->Driver.NeedFlush );
- glNormal3fv( v );
-}
+ if (ctx->NewState)
+ _mesa_update_state( ctx ); /* clear state so fell_back sticks */
+ _tnl_wakeup_exec( ctx );
+ assert( rmesa->dma.flush == 0 );
+ rmesa->vb.fell_back = GL_TRUE;
+ rmesa->vb.installed = GL_FALSE;
+ vb.context = 0;
+}
-/* ================================================================
- * Texture functions:
- */
+static void VFMT_FALLBACK( const char *caller )
+{
+ GLcontext *ctx = vb.context;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLfloat tmp[3][15];
+ GLuint i, prim;
+ GLuint ind = rmesa->vb.vertex_format;
+ GLuint nrverts;
+ GLfloat alpha = 1.0;
-#define GET_CURRENT \
- GET_CURRENT_CONTEXT(ctx); \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx)
+ if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT))
+ fprintf(stderr, "%s from %s\n", __FUNCTION__, caller);
-#define NUM_TEXTURE_UNITS RADEON_MAX_TEXTURE_UNITS
-#define DO_PROJ_TEX
+ if (rmesa->vb.prim[0] == GL_POLYGON+1) {
+ VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
+ return;
+ }
-#define CURRENT_TEXTURE( unit ) rmesa->state.current.texture[unit]
+ /* Copy vertices out of dma:
+ */
+ nrverts = copy_dma_verts( rmesa, tmp );
-#define TAG(x) radeon_##x
-#include "tnl_dd/t_dd_imm_tapi.h"
+ /* Finish the prim at this point:
+ */
+ note_last_prim( rmesa, 0 );
+ flush_prims( rmesa );
+ /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl.
+ */
+ prim = rmesa->vb.prim[0];
+ ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
+ _tnl_wakeup_exec( ctx );
+ assert(rmesa->dma.flush == 0);
+ rmesa->vb.fell_back = GL_TRUE;
+ rmesa->vb.installed = GL_FALSE;
+ vb.context = 0;
+ glBegin( prim );
+
+ if (rmesa->vb.installed_color_3f_sz == 4)
+ alpha = ctx->Current.Color[3];
-/* ================================================================
- * Vertex functions:
- */
+ /* Replay saved vertices
+ */
+ for (i = 0 ; i < nrverts; i++) {
+ GLuint offset = 3;
+ if (ind & RADEON_CP_VC_FRMT_N0) {
+ glNormal3fv( &tmp[i][offset] );
+ offset += 3;
+ }
-#define GET_CURRENT_VERTEX \
- GET_CURRENT_CONTEXT(ctx); \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
- radeonTnlVertexPtr v = rmesa->imm.v0
+ if (ind & RADEON_CP_VC_FRMT_PKCOLOR) {
+ glColor4ubv( (GLubyte *)&tmp[i][offset] );
+ offset++;
+ }
+ else if (ind & RADEON_CP_VC_FRMT_FPALPHA) {
+ glColor4fv( &tmp[i][offset] );
+ offset+=4;
+ }
+ else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
+ glColor3fv( &tmp[i][offset] );
+ offset+=3;
+ }
-#define CURRENT_VERTEX v->obj
-#define SAVE_VERTEX rmesa->imm.save_vertex( ctx, v )
+ if (ind & RADEON_CP_VC_FRMT_PKSPEC) {
+ _glapi_Dispatch->SecondaryColor3ubvEXT( (GLubyte *)&tmp[i][offset] );
+ offset++;
+ }
-#define TAG(x) radeon_##x
-#include "tnl_dd/t_dd_imm_vapi.h"
+ if (ind & RADEON_CP_VC_FRMT_ST0) {
+ glTexCoord2fv( &tmp[i][offset] );
+ offset += 2;
+ }
+ if (ind & RADEON_CP_VC_FRMT_ST1) {
+ glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, &tmp[i][offset] );
+ offset += 2;
+ }
+ glVertex3fv( &tmp[i][0] );
+ }
+ /* Replay current vertex
+ */
+ if (ind & RADEON_CP_VC_FRMT_N0)
+ glNormal3fv( vb.normalptr );
+
+ if (ind & RADEON_CP_VC_FRMT_PKCOLOR)
+ glColor4ubv( vb.ubytecolorptr );
+ else if (ind & RADEON_CP_VC_FRMT_FPALPHA)
+ glColor4fv( vb.floatcolorptr );
+ else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
+ if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0)
+ glColor4f( vb.floatcolorptr[0],
+ vb.floatcolorptr[1],
+ vb.floatcolorptr[2],
+ alpha );
+ else
+ glColor3fv( vb.floatcolorptr );
+ }
+ if (ind & RADEON_CP_VC_FRMT_PKSPEC)
+ _glapi_Dispatch->SecondaryColor3ubvEXT( vb.ubytespecptr );
-struct radeon_vert_tab {
- void (*save_vertex)( GLcontext *ctx, radeonTnlVertexPtr v );
- void (*interpolate_vertex)( GLfloat t,
- radeonTnlVertex *O,
- const radeonTnlVertex *I,
- const radeonTnlVertex *J );
-};
+ if (ind & RADEON_CP_VC_FRMT_ST0)
+ glTexCoord2fv( vb.texcoordptr[0] );
-static struct radeon_vert_tab vert_tab[0xf];
+ if (ind & RADEON_CP_VC_FRMT_ST1)
+ glMultiTexCoord2fvARB( GL_TEXTURE1_ARB, vb.texcoordptr[1] );
+}
-#define VTX_NORMAL 0x0
-#define VTX_RGBA 0x1
-#define VTX_SPEC 0x2
-#define VTX_TEX0 0x4
-#define VTX_TEX1 0x8
-#define LOCAL_VARS \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx)
-#define CURRENT_COLOR rmesa->state.current.color
-#define CURRENT_SPECULAR rmesa->state.current.specular
+static void wrap_buffer( void )
+{
+ GLcontext *ctx = vb.context;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLfloat tmp[3][15];
+ GLuint i, nrverts;
-#define CURRENT_NORMAL( COMP ) rmesa->state.current.normal[COMP]
-#define CURRENT_TEXTURE( U, COMP ) rmesa->state.current.texture[U][COMP]
+ if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS))
+ fprintf(stderr, "%s %d\n", __FUNCTION__, vb.initial_counter - vb.counter);
-#define FLUSH_VERTEX rmesa->imm.flush_vertex( ctx, v );
+ /* Don't deal with parity.
+ */
+ if ((((vb.initial_counter - vb.counter) -
+ rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) {
+ vb.counter++;
+ vb.initial_counter++;
+ return;
+ }
+ /* Copy vertices out of dma:
+ */
+ nrverts = copy_dma_verts( rmesa, tmp );
-#define IND (VTX_NORMAL)
-#define TAG(x) radeon_##x##_NORMAL
-#define PRESERVE_VERTEX_DEFS
-#include "tnl_dd/t_dd_imm_vertex.h"
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%d vertices to copy\n", nrverts);
+
-#define IND (VTX_NORMAL|VTX_TEX0)
-#define TAG(x) radeon_##x##_NORMAL_TEX0
-#define PRESERVE_VERTEX_DEFS
-#include "tnl_dd/t_dd_imm_vertex.h"
+ /* Finish the prim at this point:
+ */
+ note_last_prim( rmesa, 0 );
+ flush_prims( rmesa );
-#define IND (VTX_NORMAL|VTX_TEX0|VTX_TEX1)
-#define TAG(x) radeon_##x##_NORMAL_TEX0_TEX1
-#define PRESERVE_VERTEX_DEFS
-#include "tnl_dd/t_dd_imm_vertex.h"
+ /* Get new buffer
+ */
+ radeonRefillCurrentDmaRegion( rmesa );
-#define IND (VTX_RGBA)
-#define TAG(x) radeon_##x##_RGBA
-#define PRESERVE_VERTEX_DEFS
-#include "tnl_dd/t_dd_imm_vertex.h"
+ /* Reset counter, dmaptr
+ */
+ vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address);
+ vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
+ (vb.vertex_size * 4);
+ vb.counter--;
+ vb.initial_counter = vb.counter;
+ vb.notify = wrap_buffer;
-#define IND (VTX_RGBA|VTX_TEX0)
-#define TAG(x) radeon_##x##_RGBA_TEX0
-#define PRESERVE_VERTEX_DEFS
-#include "tnl_dd/t_dd_imm_vertex.h"
+ rmesa->dma.flush = flush_prims;
+ start_prim( rmesa, rmesa->vb.prim[0] );
-#define IND (VTX_RGBA|VTX_TEX1)
-#define TAG(x) radeon_##x##_RGBA_TEX0_TEX1
-#include "tnl_dd/t_dd_imm_vertex.h"
+ /* Reemit saved vertices
+ */
+ for (i = 0 ; i < nrverts; i++) {
+ if (RADEON_DEBUG & DEBUG_VERTS) {
+ int j;
+ fprintf(stderr, "re-emit vertex %d to %p\n", i, vb.dmaptr);
+ if (RADEON_DEBUG & DEBUG_VERBOSE)
+ for (j = 0 ; j < vb.vertex_size; j++)
+ fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]);
+ }
-static void radeon_init_vert_funcs( void )
-{
- radeon_init_vert_NORMAL();
- radeon_init_vert_NORMAL_TEX0();
- radeon_init_vert_NORMAL_TEX0_TEX1();
- radeon_init_vert_RGBA();
- radeon_init_vert_RGBA_TEX0();
- radeon_init_vert_RGBA_TEX0_TEX1();
+ memcpy( vb.dmaptr, tmp[i], vb.vertex_size * 4 );
+ vb.dmaptr += vb.vertex_size;
+ vb.counter--;
+ }
}
+static GLboolean check_vtx_fmt( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLuint ind = RADEON_CP_VC_FRMT_Z;
+ if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
+ return GL_FALSE;
+ if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
+ ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
+
+ /* Make all this event-driven:
+ */
+ if (ctx->Light.Enabled) {
+ ind |= RADEON_CP_VC_FRMT_N0;
+
+ /* TODO: make this data driven: If we receive only ubytes, send
+ * color as ubytes. Also check if converting (with free
+ * checking for overflow) is cheaper than sending floats
+ * directly.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ ind |= RADEON_CP_VC_FRMT_FPCOLOR;
+ if (ctx->Color.AlphaEnabled) {
+ ind |= RADEON_CP_VC_FRMT_FPALPHA;
+ }
+ }
+ }
+ else {
+ /* TODO: make this data driven?
+ */
+ ind |= RADEON_CP_VC_FRMT_PKCOLOR;
+
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
+ ind |= RADEON_CP_VC_FRMT_PKSPEC;
+ }
+ }
+ if (ctx->Texture.Unit[0]._ReallyEnabled) {
+ if (ctx->Texture.Unit[0].TexGenEnabled) {
+ if (rmesa->TexGenNeedNormals[0]) {
+ ind |= RADEON_CP_VC_FRMT_N0;
+ }
+ } else {
+ if (ctx->Current.Texcoord[0][2] != 0.0F ||
+ ctx->Current.Texcoord[0][3] != 1.0) {
+ if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
+ fprintf(stderr, "%s: rq0\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+ ind |= RADEON_CP_VC_FRMT_ST0;
+ }
+ }
-#define LOCAL_VARS \
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx)
+ if (ctx->Texture.Unit[1]._ReallyEnabled) {
+ if (ctx->Texture.Unit[1].TexGenEnabled) {
+ if (rmesa->TexGenNeedNormals[1]) {
+ ind |= RADEON_CP_VC_FRMT_N0;
+ }
+ } else {
+ if (ctx->Current.Texcoord[1][2] != 0.0F ||
+ ctx->Current.Texcoord[1][3] != 1.0) {
+ if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS))
+ fprintf(stderr, "%s: rq1\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+ ind |= RADEON_CP_VC_FRMT_ST1;
+ }
+ }
-#define GET_INTERP_FUNC \
- radeon_interp_func interp = rmesa->imm.interp
+ if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE))
+ fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind );
-#define FLUSH_VERTEX rmesa->imm.flush_vertex
+ RADEON_NEWPRIM(rmesa);
+ rmesa->vb.vertex_format = ind;
+ vb.vertex_size = 3;
+ rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
-#define IMM_VERTEX( V ) rmesa->imm.V
-#define IMM_VERTICES( n ) rmesa->imm.vertices[n]
+ vb.normalptr = ctx->Current.Normal;
+ vb.ubytecolorptr = 0;
+ vb.floatcolorptr = ctx->Current.Color;
+ vb.texcoordptr[0] = ctx->Current.Texcoord[0];
+ vb.texcoordptr[1] = ctx->Current.Texcoord[1];
+
+ /* Run through and initialize the vertex components in the order
+ * the hardware understands:
+ */
+ if (ind & RADEON_CP_VC_FRMT_N0) {
+ vb.normalptr = &vb.vertex[vb.vertex_size].f;
+ vb.vertex_size += 3;
+ vb.normalptr[0] = ctx->Current.Normal[0];
+ vb.normalptr[1] = ctx->Current.Normal[1];
+ vb.normalptr[2] = ctx->Current.Normal[2];
+ }
+ if (ind & RADEON_CP_VC_FRMT_PKCOLOR) {
+ vb.ubytecolorptr = &vb.vertex[vb.vertex_size].ub4[0];
+ vb.vertex_size += 1;
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN( vb.ubytecolorptr, ctx->Current.Color );
+ }
-/* TINY_VERTEX_FORMAT:
- */
-#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 16, __FUNCTION__ )
-
-#define EMIT_VERTEX( vb, v ) \
-do { \
- vb[0] = *(GLuint *)&(v->clip[0]); \
- vb[1] = *(GLuint *)&(v->clip[1]); \
- vb[2] = *(GLuint *)&(v->clip[2]); \
- vb[3] = *(GLuint *)&(v->color); \
- vb += 4; \
-} while (0)
+ if (ind & RADEON_CP_VC_FRMT_FPCOLOR) {
+ assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR));
+ vb.floatcolorptr = &vb.vertex[vb.vertex_size].f;
+ vb.vertex_size += 3;
+ vb.floatcolorptr[0] = ctx->Current.Color[0];
+ vb.floatcolorptr[1] = ctx->Current.Color[1];
+ vb.floatcolorptr[2] = ctx->Current.Color[2];
+
+ if (ind & RADEON_CP_VC_FRMT_FPALPHA) {
+ vb.vertex_size += 1;
+ vb.floatcolorptr[3] = ctx->Current.Color[3];
+ }
+ }
+
+ if (ind & RADEON_CP_VC_FRMT_PKSPEC) {
+ vb.ubytespecptr = &vb.vertex[vb.vertex_size].ub4[0];
+ vb.vertex_size += 1;
+ UNCLAMPED_FLOAT_TO_RGB_CHAN( vb.ubytespecptr,
+ ctx->Current.SecondaryColor );
+ }
-#define TAG(x) radeon_##x##_tiny
-#define PRESERVE_PRIM_DEFS
-#include "tnl_dd/t_dd_imm_primtmp.h"
+ if (ind & RADEON_CP_VC_FRMT_ST0) {
+ vb.texcoordptr[0] = &vb.vertex[vb.vertex_size].f;
+ vb.vertex_size += 2;
+ vb.texcoordptr[0][0] = ctx->Current.Texcoord[0][0];
+ vb.texcoordptr[0][1] = ctx->Current.Texcoord[0][1];
+ }
+
+ if (ind & RADEON_CP_VC_FRMT_ST1) {
+ vb.texcoordptr[1] = &vb.vertex[vb.vertex_size].f;
+ vb.vertex_size += 2;
+ vb.texcoordptr[1][0] = ctx->Current.Texcoord[1][0];
+ vb.texcoordptr[1][1] = ctx->Current.Texcoord[1][1];
+ }
+
+ if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) {
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "reinstall on vertex_format change\n");
+ _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
+ rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format;
+ }
+
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s -- success\n", __FUNCTION__);
+
+ return GL_TRUE;
+}
-/* NOTEX_VERTEX_FORMAT:
- */
-#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 24, __FUNCTION__ )
-
-#define EMIT_VERTEX( vb, v ) \
-do { \
- vb[0] = *(GLuint *)&(v->clip[0]); \
- vb[1] = *(GLuint *)&(v->clip[1]); \
- vb[2] = *(GLuint *)&(v->clip[2]); \
- vb[3] = *(GLuint *)&(v->clip[3]); \
- vb[4] = *(GLuint *)&(v->color); \
- vb[5] = *(GLuint *)&(v->specular); \
- vb += 6; \
-} while (0)
-#define TAG(x) radeon_##x##_notex
-#define PRESERVE_PRIM_DEFS
-#include "tnl_dd/t_dd_imm_primtmp.h"
+void radeonVtxfmtInvalidate( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ rmesa->vb.recheck = GL_TRUE;
+ rmesa->vb.fell_back = GL_FALSE;
+}
-/* TEX0_VERTEX_FORMAT:
- */
-#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 32, __FUNCTION__ )
-
-#define EMIT_VERTEX( vb, v ) \
-do { \
- vb[0] = *(GLuint *)&(v->clip[0]); \
- vb[1] = *(GLuint *)&(v->clip[1]); \
- vb[2] = *(GLuint *)&(v->clip[2]); \
- vb[3] = *(GLuint *)&(v->clip[3]); \
- vb[4] = *(GLuint *)&(v->color); \
- vb[5] = *(GLuint *)&(v->specular); \
- vb[6] = *(GLuint *)&(v->texture[0][0]); \
- vb[7] = *(GLuint *)&(v->texture[0][1]); \
- vb += 8; \
-} while (0)
-#define TAG(x) radeon_##x##_tex0
-#define PRESERVE_PRIM_DEFS
-#include "tnl_dd/t_dd_imm_primtmp.h"
+static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode )
+{
+ VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
+}
-/* TEX1_VERTEX_FORMAT:
- */
-#define GET_VERTEX_SPACE( n ) radeonAllocDmaLow( rmesa, n * 40, __FUNCTION__ )
-
-#define EMIT_VERTEX( vb, v ) \
-do { \
- vb[0] = *(GLuint *)&(v->clip[0]); \
- vb[1] = *(GLuint *)&(v->clip[1]); \
- vb[2] = *(GLuint *)&(v->clip[2]); \
- vb[3] = *(GLuint *)&(v->clip[3]); \
- vb[4] = *(GLuint *)&(v->color); \
- vb[5] = *(GLuint *)&(v->specular); \
- vb[6] = *(GLuint *)&(v->texture[0][0]); \
- vb[7] = *(GLuint *)&(v->texture[0][1]); \
- vb[8] = *(GLuint *)&(v->texture[1][0]); \
- vb[9] = *(GLuint *)&(v->texture[1][1]); \
- vb += 10; \
-} while (0)
+static void radeonVtxfmtValidate( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
-#define TAG(x) radeon_##x##_tex1
-#define PRESERVE_PRIM_DEFS
-#include "tnl_dd/t_dd_imm_primtmp.h"
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ if (ctx->Driver.NeedFlush)
+ ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
+ rmesa->vb.recheck = GL_FALSE;
+ if (check_vtx_fmt( ctx )) {
+ if (!rmesa->vb.installed) {
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "reinstall (new install)\n");
+ _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
+ ctx->Driver.FlushVertices = radeonFlushVertices;
+ ctx->Driver.NewList = radeonNewList;
+ rmesa->vb.installed = GL_TRUE;
+ vb.context = ctx;
+ }
+ else if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s: already installed", __FUNCTION__);
+ }
+ else {
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s: failed\n", __FUNCTION__);
+
+ if (rmesa->vb.installed) {
+ if (rmesa->dma.flush)
+ rmesa->dma.flush( rmesa );
+ _tnl_wakeup_exec( ctx );
+ rmesa->vb.installed = GL_FALSE;
+ vb.context = 0;
+ }
+ }
+}
-/* Bzzt: Material changes are lost on fallback.
+/* Materials:
*/
-static void radeon_Materialfv( GLenum face, GLenum pname,
+static void radeon_Materialfv( GLenum face, GLenum pname,
const GLfloat *params )
{
- GET_CURRENT_CONTEXT(ctx);
+ GLcontext *ctx = vb.context;
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ if (rmesa->vb.prim[0] != GL_POLYGON+1) {
+ VFMT_FALLBACK( __FUNCTION__ );
+ glMaterialfv( face, pname, params );
+ return;
+ }
_mesa_noop_Materialfv( face, pname, params );
- radeon_recalc_base_color( ctx );
+ radeonUpdateMaterial( vb.context );
}
-
-
-
-/* ================================================================
- * Fallback functions:
+/* Begin/End
*/
-
-static void radeon_do_fallback( GLcontext *ctx )
+static void radeon_Begin( GLenum mode )
{
+ GLcontext *ctx = vb.context;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- struct radeon_current_state *current = &rmesa->state.current;
+
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s\n", __FUNCTION__);
- /* Tell tnl to restore its exec vtxfmt, rehook its driver callbacks
- * and revive internal state that depended on those callbacks:
- */
- _tnl_wakeup_exec( ctx );
+ if (mode > GL_POLYGON) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
+ return;
+ }
- /* Replay enough vertices that the current primitive is continued
- * correctly:
- */
- if ( rmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END ) {
- glBegin( rmesa->imm.prim );
- /*rmesa->fire_on_fallback( ctx );*/
+ if (rmesa->vb.prim[0] != GL_POLYGON+1) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
+ return;
}
+
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
- /* Replay the current, partially complete vertex:
- */
- if ( current->texture[0][3] == 1.0 ) {
- glMultiTexCoord3fvARB( GL_TEXTURE0_ARB, current->texture[0] );
- } else {
- glMultiTexCoord4fvARB( GL_TEXTURE0_ARB, current->texture[0] );
+ if (rmesa->NewGLState)
+ radeonValidateState( ctx );
+
+ if (rmesa->vb.recheck)
+ radeonVtxfmtValidate( ctx );
+
+ if (!rmesa->vb.installed) {
+ glBegin( mode );
+ return;
}
- if ( current->texture[1][3] == 1.0 ) {
- glMultiTexCoord3fvARB( GL_TEXTURE1_ARB, current->texture[1] );
- } else {
- glMultiTexCoord4fvARB( GL_TEXTURE1_ARB, current->texture[1] );
+
+ if (rmesa->dma.flush && vb.counter < 12) {
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__);
+ flush_prims( rmesa );
}
- /* FIXME: Secondary color, fog coord...
+ /* Need to arrange to save vertices here? Or always copy from dma (yuk)?
*/
+ if (!rmesa->dma.flush) {
+ if (rmesa->dma.current.ptr + 12*vb.vertex_size*4 >
+ rmesa->dma.current.end) {
+ RADEON_NEWPRIM( rmesa );
+ radeonRefillCurrentDmaRegion( rmesa );
+ }
- if ( ctx->Light.Enabled ) {
- glColor4fv( ctx->Current.Color ); /* Catch ColorMaterial */
- glNormal3fv( current->normal );
- } else {
- glColor4ubv( current->color );
+ vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
+ vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
+ (vb.vertex_size * 4);
+ vb.counter--;
+ vb.initial_counter = vb.counter;
+ vb.notify = wrap_buffer;
+ rmesa->dma.flush = flush_prims;
+ vb.context->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
}
+
+
+ rmesa->vb.prim[0] = mode;
+ start_prim( rmesa, mode | PRIM_BEGIN );
}
-#define PRE_LOOPBACK( FUNC ) do { \
- GET_CURRENT_CONTEXT(ctx); \
- radeon_do_fallback( ctx ); \
-} while (0)
-#define TAG(x) radeon_fallback_##x
-#include "vtxfmt_tmp.h"
+static void radeon_End( void )
+{
+ GLcontext *ctx = vb.context;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ if (rmesa->vb.prim[0] == GL_POLYGON+1) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
+ return;
+ }
+
+ note_last_prim( rmesa, PRIM_END );
+ rmesa->vb.prim[0] = GL_POLYGON+1;
+}
+
+
+/* Fallback on difficult entrypoints:
+ */
+#define PRE_LOOPBACK( FUNC ) \
+do { \
+ if (RADEON_DEBUG & DEBUG_VFMT) \
+ fprintf(stderr, "%s\n", __FUNCTION__); \
+ VFMT_FALLBACK( __FUNCTION__ ); \
+} while (0)
+#define TAG(x) radeon_fallback_##x
+#include "vtxfmt_tmp.h"
-static void radeon_Begin( GLenum prim )
+static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p )
{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s\n", __FUNCTION__);
- if ( prim > GL_POLYGON ) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
- }
- if ( rmesa->imm.prim != PRIM_OUTSIDE_BEGIN_END ) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
- return;
- }
+ assert(!rmesa->vb.installed);
- ctx->Driver.NeedFlush |= (FLUSH_STORED_VERTICES |
- FLUSH_UPDATE_CURRENT);
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+ if (rmesa->NewGLState)
+ radeonValidateState( ctx );
- radeonChooseVertexState( ctx );
+ if (ctx->Driver.NeedFlush)
+ ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
+ if (rmesa->vb.recheck)
+ radeonVtxfmtValidate( ctx );
- rmesa->imm.prim = prim;
- rmesa->imm.v0 = &rmesa->imm.vertices[0];
+ if (!rmesa->vb.installed) {
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s -- failed\n", __FUNCTION__);
+ return GL_FALSE;
+ }
- rmesa->imm.save_vertex = radeon_save_vertex_RGBA;
- rmesa->imm.flush_vertex = rmesa->imm.flush_tab[prim];
+ radeon_Begin( p );
+ return GL_TRUE;
}
-static void radeon_End( void )
+static void radeonFlushVertices( GLcontext *ctx, GLuint flags )
{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
- if ( rmesa->imm.prim == PRIM_OUTSIDE_BEGIN_END ) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
- return;
- }
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "%s\n", __FUNCTION__);
- rmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
+ assert(rmesa->vb.installed);
+ assert(vb.context == ctx);
- ctx->Driver.NeedFlush &= ~(FLUSH_STORED_VERTICES |
- FLUSH_UPDATE_CURRENT);
-}
+ if (flags & FLUSH_UPDATE_CURRENT) {
+ radeon_copy_to_current( ctx );
+ if (RADEON_DEBUG & DEBUG_VFMT)
+ fprintf(stderr, "reinstall on update_current\n");
+ _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt );
+ ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
+ }
+ if (flags & FLUSH_STORED_VERTICES) {
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ assert (rmesa->dma.flush == 0 ||
+ rmesa->dma.flush == flush_prims);
+ if (rmesa->dma.flush == flush_prims)
+ flush_prims( RADEON_CONTEXT( ctx ) );
+ ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
+ }
+}
+/* At this point, don't expect very many versions of each function to
+ * be generated, so not concerned about freeing them?
+ */
-void radeonInitTnlModule( GLcontext *ctx )
+void radeonVtxfmtInit( GLcontext *ctx )
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLvertexformat *vfmt = &(rmesa->imm.vtxfmt);
-
- return;
-
- radeon_init_norm_funcs();
- radeon_init_vert_funcs();
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ GLvertexformat *vfmt = &(rmesa->vb.vtxfmt);
MEMSET( vfmt, 0, sizeof(GLvertexformat) );
- /* Handled fully in supported states:
+ /* Hook in chooser functions for codegen, etc:
*/
- vfmt->ArrayElement = NULL; /* FIXME: ... */
- vfmt->Color3f = radeon_choose_Color3f;
- vfmt->Color3fv = radeon_choose_Color3fv;
- vfmt->Color3ub = radeon_choose_Color3ub;
- vfmt->Color3ubv = radeon_choose_Color3ubv;
- vfmt->Color4f = radeon_choose_Color4f;
- vfmt->Color4fv = radeon_choose_Color4fv;
- vfmt->Color4ub = radeon_choose_Color4ub;
- vfmt->Color4ubv = radeon_choose_Color4ubv;
- vfmt->FogCoordfvEXT = radeon_FogCoordfvEXT;
- vfmt->FogCoordfEXT = radeon_FogCoordfEXT;
- vfmt->Materialfv = radeon_Materialfv;
- vfmt->MultiTexCoord1fARB = radeon_MultiTexCoord1fARB;
- vfmt->MultiTexCoord1fvARB = radeon_MultiTexCoord1fvARB;
- vfmt->MultiTexCoord2fARB = radeon_MultiTexCoord2fARB;
- vfmt->MultiTexCoord2fvARB = radeon_MultiTexCoord2fvARB;
- vfmt->MultiTexCoord3fARB = radeon_MultiTexCoord3fARB;
- vfmt->MultiTexCoord3fvARB = radeon_MultiTexCoord3fvARB;
- vfmt->MultiTexCoord4fARB = radeon_MultiTexCoord4fARB;
- vfmt->MultiTexCoord4fvARB = radeon_MultiTexCoord4fvARB;
- vfmt->Normal3f = radeon_choose_Normal3f;
- vfmt->Normal3fv = radeon_choose_Normal3fv;
- vfmt->SecondaryColor3ubEXT = radeon_SecondaryColor3ubEXT;
- vfmt->SecondaryColor3ubvEXT = radeon_SecondaryColor3ubvEXT;
- vfmt->SecondaryColor3fEXT = radeon_SecondaryColor3fEXT;
- vfmt->SecondaryColor3fvEXT = radeon_SecondaryColor3fvEXT;
- vfmt->TexCoord1f = radeon_TexCoord1f;
- vfmt->TexCoord1fv = radeon_TexCoord1fv;
- vfmt->TexCoord2f = radeon_TexCoord2f;
- vfmt->TexCoord2fv = radeon_TexCoord2fv;
- vfmt->TexCoord3f = radeon_TexCoord3f;
- vfmt->TexCoord3fv = radeon_TexCoord3fv;
- vfmt->TexCoord4f = radeon_TexCoord4f;
- vfmt->TexCoord4fv = radeon_TexCoord4fv;
- vfmt->Vertex2f = radeon_Vertex2f;
- vfmt->Vertex2fv = radeon_Vertex2fv;
- vfmt->Vertex3f = radeon_Vertex3f;
- vfmt->Vertex3fv = radeon_Vertex3fv;
- vfmt->Vertex4f = radeon_Vertex4f;
- vfmt->Vertex4fv = radeon_Vertex4fv;
+ radeonVtxfmtInitChoosers( vfmt );
+ /* Handled fully in supported states, but no codegen:
+ */
+ vfmt->Materialfv = radeon_Materialfv;
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
vfmt->Begin = radeon_Begin;
vfmt->End = radeon_End;
- vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
-
- vfmt->DrawArrays = NULL;
- vfmt->DrawElements = NULL;
- vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements; /* discard range */
+ /* Fallback for performance reasons: (Fix with cva/elt path here and
+ * dmatmp2.h style primitive-merging)
+ *
+ * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow
+ * a driver-hook.
+ */
+ vfmt->DrawArrays = radeon_fallback_DrawArrays;
+ vfmt->DrawElements = radeon_fallback_DrawElements;
+ vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements;
/* Not active in supported states; just keep ctx->Current uptodate:
*/
+ vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT;
+ vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT;
vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
vfmt->Indexi = _mesa_noop_Indexi;
@@ -640,10 +963,6 @@ void radeonInitTnlModule( GLcontext *ctx )
/* Active but unsupported -- fallback if we receive these:
- *
- * All of these fallbacks can be fixed with additional code, except
- * CallList, unless we build a play_immediate_noop() command which
- * turns an immediate back into glBegin/glEnd commands...
*/
vfmt->CallList = radeon_fallback_CallList;
vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f;
@@ -654,132 +973,137 @@ void radeonInitTnlModule( GLcontext *ctx )
vfmt->EvalMesh2 = radeon_fallback_EvalMesh2;
vfmt->EvalPoint1 = radeon_fallback_EvalPoint1;
vfmt->EvalPoint2 = radeon_fallback_EvalPoint2;
-
-
- rmesa->imm.prim = PRIM_OUTSIDE_BEGIN_END;
-
- /* THIS IS A HACK!
- */
- _mesa_install_exec_vtxfmt( ctx, vfmt );
+ vfmt->TexCoord3f = radeon_fallback_TexCoord3f;
+ vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv;
+ vfmt->TexCoord4f = radeon_fallback_TexCoord4f;
+ vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv;
+ vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB;
+ vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB;
+ vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB;
+ vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB;
+ vfmt->Vertex4f = radeon_fallback_Vertex4f;
+ vfmt->Vertex4fv = radeon_fallback_Vertex4fv;
+
+ (void)radeon_fallback_vtxfmt;
+
+ TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin;
+
+ vb.context = ctx;
+ rmesa->vb.enabled = 1;
+ rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive;
+ rmesa->vb.primflags = 0;
+
+ make_empty_list( &rmesa->vb.dfn_cache.Vertex2f );
+ make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv );
+ make_empty_list( &rmesa->vb.dfn_cache.Vertex3f );
+ make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv );
+ make_empty_list( &rmesa->vb.dfn_cache.Color4ub );
+ make_empty_list( &rmesa->vb.dfn_cache.Color4ubv );
+ make_empty_list( &rmesa->vb.dfn_cache.Color3ub );
+ make_empty_list( &rmesa->vb.dfn_cache.Color3ubv );
+ make_empty_list( &rmesa->vb.dfn_cache.Color4f );
+ make_empty_list( &rmesa->vb.dfn_cache.Color4fv );
+ make_empty_list( &rmesa->vb.dfn_cache.Color3f );
+ make_empty_list( &rmesa->vb.dfn_cache.Color3fv );
+ make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
+ make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
+ make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
+ make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
+ make_empty_list( &rmesa->vb.dfn_cache.Normal3f );
+ make_empty_list( &rmesa->vb.dfn_cache.Normal3fv );
+ make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f );
+ make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv );
+ make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f );
+ make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv );
+ make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
+ make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
+ make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
+ make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
+
+ radeonInitCodegen( &rmesa->vb.codegen );
}
-
-
-
-
-
-#if 0
-
-
-
-static void radeon_Begin( GLenum prim )
+static void free_funcs( struct dynfn *l )
{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- radeon_prim *tab = &radeon_prim_tab[(int)prim];
-
- if ( prim > GL_POLYGON ) {
- gl_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
- }
-
- if ( rmesa->prim != PRIM_OUTSIDE_BEGIN_END ) {
- gl_error( ctx, GL_INVALID_OPERATION, "glBegin" );
- return;
- }
-
- if ( tab->fire_on_vertex ) {
- rmesa->fire_on_vertex = tab->fire_on_vertex;
- rmesa->fire_on_end = tab->fire_on_end;
- rmesa->fire_on_fallback = tab->fire_on_fallback;
- rmesa->vert = &(rmesa->cache[0]);
- rmesa->prim = prim;
- ctx->Driver.NeedFlush |= (FLUSH_INSIDE_BEGIN_END |
- FLUSH_STORED_VERTICES);
- } else {
- radeon_fallback_vtxfmt( ctx );
+ struct dynfn *f, *tmp;
+ foreach_s (f, tmp, l) {
+ remove_from_list( f );
+ ALIGN_FREE( f->code );
+ FREE( f );
}
}
-static void radeon_End( void )
+void radeonVtxfmtUnbindContext( GLcontext *ctx )
{
- GET_CURRENT_CONTEXT(ctx);
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if ( rmesa->prim == PRIM_OUTSIDE_BEGIN_END ) {
- gl_error( ctx, GL_INVALID_OPERATION, "glEnd" );
- return;
+ if (RADEON_CONTEXT(ctx)->vb.installed) {
+ assert(vb.context == ctx);
+ VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ );
}
- rmesa->fire_on_end( ctx );
- rmesa->prim = PRIM_OUTSIDE_BEGIN_END;
-
- ctx->Exec->Vertex3fv = radeon_noop_Vertex3fv;
- ctx->Exec->Vertex3f = radeon_noop_Vertex3f;
- ctx->Exec->Vertex2f = radeon_noop_Vertex2f;
-
- ctx->Driver.NeedFlush &= ~(FLUSH_INSIDE_BEGIN_END |
- FLUSH_STORED_VERTICES);
+ TNL_CONTEXT(ctx)->Driver.NotifyBegin = 0;
}
-
-
-static GLboolean radeon_flush_vtxfmt( GLcontext *ctx, GLuint flags )
+void radeonVtxfmtMakeCurrent( GLcontext *ctx )
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-
- if ( fxMesa->prim != PRIM_OUTSIDE_BEGIN_END )
- return GL_FALSE;
-
- /* Outside begin/end. All vertices will already be flushed, just
- * update ctx->Current.
- */
- if ( flags & FLUSH_UPDATE_CURRENT ) {
- radeonClipVertexPtr v = &(RADEON_CONTEXT(ctx)->Current);
- COPY_2FV( ctx->Current.Texcoord[0], v->texcoord[0] );
- COPY_2FV( ctx->Current.Texcoord[1], v->texcoord[1] );
- if ( rmesa->accel_light == ACCEL_LIGHT ) {
- COPY_3FV( ctx->Current.Normal, v->normal );
- } else {
- ctx->Current.Color[RCOMP] = UBYTE_TO_CHAN( v->v.color.red );
- ctx->Current.Color[GCOMP] = UBYTE_TO_CHAN( v->v.color.green );
- ctx->Current.Color[BCOMP] = UBYTE_TO_CHAN( v->v.color.blue );
- ctx->Current.Color[ACOMP] = UBYTE_TO_CHAN( v->v.color.alpha );
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+
+#if defined(THREADS)
+ static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */
+ if (!ThreadSafe) {
+ static unsigned long knownID;
+ static GLboolean firstCall = GL_TRUE;
+ if (firstCall) {
+ knownID = _glthread_GetID();
+ firstCall = GL_FALSE;
+ }
+ else if (knownID != _glthread_GetID()) {
+ ThreadSafe = GL_TRUE;
- if ( ctx->Light.ColorMaterialEnabled )
- _mesa_update_color_material( ctx, ctx->Current.Color );
+ if (RADEON_DEBUG & (DEBUG_DRI|DEBUG_VFMT))
+ fprintf(stderr, "**** Multithread situation!\n");
}
}
+ if (ThreadSafe)
+ return;
+#endif
- /* Could clear this flag and set it from each 'choose' function,
- * maybe, but there isn't much of a penalty for leaving it set:
- */
- ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT;
- return GL_TRUE;
+ if (rmesa->vb.enabled) {
+ TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin;
+ }
}
-void radeon_update_lighting( GLcontext *ctx )
-{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- if ( !ctx->Light.Enabled ) {
- rmesa->accel_light = ACCEL_NO_LIGHT;
- }
- else if ( !ctx->Light._NeedVertices && !ctx->Light.Model.TwoSide ) {
- rmesa->accel_light = ACCEL_LIGHT;
- radeon_recalc_basecolor( ctx );
- }
- else {
- radeon->accel_light = 0;
- }
+void radeonVtxfmtDestroy( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+
+ count_funcs( rmesa );
+ free_funcs( &rmesa->vb.dfn_cache.Vertex2f );
+ free_funcs( &rmesa->vb.dfn_cache.Vertex2fv );
+ free_funcs( &rmesa->vb.dfn_cache.Vertex3f );
+ free_funcs( &rmesa->vb.dfn_cache.Vertex3fv );
+ free_funcs( &rmesa->vb.dfn_cache.Color4ub );
+ free_funcs( &rmesa->vb.dfn_cache.Color4ubv );
+ free_funcs( &rmesa->vb.dfn_cache.Color3ub );
+ free_funcs( &rmesa->vb.dfn_cache.Color3ubv );
+ free_funcs( &rmesa->vb.dfn_cache.Color4f );
+ free_funcs( &rmesa->vb.dfn_cache.Color4fv );
+ free_funcs( &rmesa->vb.dfn_cache.Color3f );
+ free_funcs( &rmesa->vb.dfn_cache.Color3fv );
+ free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT );
+ free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT );
+ free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT );
+ free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT );
+ free_funcs( &rmesa->vb.dfn_cache.Normal3f );
+ free_funcs( &rmesa->vb.dfn_cache.Normal3fv );
+ free_funcs( &rmesa->vb.dfn_cache.TexCoord2f );
+ free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv );
+ free_funcs( &rmesa->vb.dfn_cache.TexCoord1f );
+ free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv );
+ free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB );
+ free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
+ free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
+ free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
}
-
-/* How to fallback:
- * - install default vertex format
- * - call glBegin
- * - revive stalled vertices (may be reordered).
- * - re-issue call that caused fallback.
- */
-#endif