another checkpoint of struct immediate replacement code
authorKeith Whitwell <keith@tungstengraphics.com>
Sat, 11 May 2002 08:38:25 +0000 (08:38 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Sat, 11 May 2002 08:38:25 +0000 (08:38 +0000)
src/mesa/tnl/t_vtx_api.c
src/mesa/tnl/t_vtx_exec.c
src/mesa/tnl/t_vtx_x86.c

index 8ae0569584ad58cf194464fd21ca4a11cafe3275..b957f336691811ee8dd8628ffd687d0fc028edde 100644 (file)
@@ -44,36 +44,39 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 /* MultiTexcoord ends up with both of these branches, unfortunately
- * (it may its own version of the macro after size-tracking is working).
+ * (it may get its own version of the macro after size-tracking is
+ * working). 
+ *
+ * Errors (VertexAttribNV when ATTR>15) are handled at a higher level.  
  */
-#define ATTRF( ATTR, N, A, B, C, D )                   \
-{                                                      \
-   GET_CURRENT_CONTEXT( ctx );                         \
-   TNLcontext *tnl = TNL_CONTEXT(ctx);                 \
-                                                       \
-   if (((ATTR) & 0xf) == 0) {                          \
-      int i;                                           \
-                                                       \
-      if (N>0) tnl->dmaptr[0].f = A;                   \
-      if (N>1) tnl->dmaptr[1].f = B;                   \
-      if (N>2) tnl->dmaptr[2].f = C;                   \
-      if (N>3) tnl->dmaptr[3].f = D;                   \
-                                                       \
-      for (i = N; i < tnl->vertex_size; i++)           \
-        *tnl->dmaptr[i].i = tnl->vertex[i].i;          \
-                                                       \
-      tnl->dmaptr += tnl->vertex_size;                 \
-                                                       \
-      if (--tnl->counter == 0)                         \
-        tnl->notify();                                 \
-   }                                                   \
-   else {                                              \
-      GLfloat *dest = tnl->attrptr[(ATTR) & 0xf];      \
-      if (N>0) dest[0] = A;                            \
-      if (N>1) dest[1] = B;                            \
-      if (N>2) dest[2] = C;                            \
-      if (N>3) dest[3] = D;                            \
-   }                                                   \
+#define ATTRF( ATTR, N, A, B, C, D )                           \
+{                                                              \
+   GET_CURRENT_CONTEXT( ctx );                                 \
+   TNLcontext *tnl = TNL_CONTEXT(ctx);                         \
+                                                               \
+   if ((ATTR) == 0) {                                          \
+      int i;                                                   \
+                                                               \
+      if (N>0) tnl->vbptr[0].f = A;                            \
+      if (N>1) tnl->vbptr[1].f = B;                            \
+      if (N>2) tnl->vbptr[2].f = C;                            \
+      if (N>3) tnl->vbptr[3].f = D;                            \
+                                                               \
+      for (i = N; i < tnl->vertex_size; i++)                   \
+        *tnl->vbptr[i].i = tnl->vertex[i].i;                   \
+                                                               \
+      tnl->vbptr += tnl->vertex_size;                          \
+                                                               \
+      if (--tnl->counter == 0)                                 \
+        tnl->notify();                                         \
+   }                                                           \
+   else {                                      \
+      GLfloat *dest = tnl->attrptr[ATTR];                      \
+      if (N>0) dest[0] = A;                                    \
+      if (N>1) dest[1] = B;                                    \
+      if (N>2) dest[2] = C;                                    \
+      if (N>3) dest[3] = D;                                    \
+   }                                                           \
 }
 
 #define ATTR4F( ATTR, A, B, C, D )  ATTRF( ATTR, 4, A, B, C, D )
@@ -266,176 +269,319 @@ static void tnl_TexCoord4fv( const GLfloat *v )
 }
 
 
-/* MultiTexcoord
+/* Miscellaneous: 
+ *
+ * These don't alias NV attributes, but still need similar treatment.
+ * Basically these are attributes with numbers greater than 16.
  */
-static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s  )
+static void tnl_EdgeFlag( GLboolean flag )
+{
+   GLfloat f = flag ? 1 : 0;
+   ATTR1F( VERT_ATTRIB_EDGEFLAG, f);
+}
+
+static void tnl_EdgeFlagv( const GLboolean *flag )
+{
+   GLfloat f = flag[0] ? 1 : 0;
+   ATTR1F( VERT_ATTRIB_EDGEFLAG, f);
+}
+
+static void tnl_Indexi( GLint idx )
+{
+   ATTR1F( VERT_ATTRIB_INDEX, idx );
+}
+
+static void tnl_Indexiv( const GLint *idx )
+{
+   ATTR1F( VERT_ATTRIB_INDEX, idx );
+}
+
+/* Use dispatch switching to build 'ranges' of eval vertices for each
+ * type, avoiding need for flags.  (Make
+ * evalcoords/evalpoints/vertices/attr0 mutually exclusive)
+ */
+static void _tnl_EvalCoord1f( GLfloat u )
+{
+   ATTR1F( VERT_ATTRIB_POS, u );
+}
+
+static void _tnl_EvalCoord1fv( const GLfloat *v )
+{
+   ATTR1F( VERT_ATTRIB_POS, v[0] );
+}
+
+static void _tnl_EvalCoord2f( GLfloat u, GLfloat v )
+{
+   ATTR2F( VERT_ATTRIB_POS, u, v );
+}
+
+static void _tnl_EvalCoord2fv( const GLfloat *v )
+{
+   ATTR2F( VERT_ATTRIB_POS, v[0], v[1] );
+}
+
+
+
+/* Second level dispatch table for MultiTexCoord, Material and 
+ * VertexAttribNV.
+ *
+ * Need this because we want to track things like vertex attribute
+ * sizes, presence/otherwise of attribs in recorded vertices, etc, by
+ * manipulating the state of dispatch tables.  Need therefore a
+ * dispatch slot for each value of 'index' or 'unit' in VertexAttribNV
+ * and MultiTexCoordARB.  Also need a mechnism for keeping this data
+ * consistent with what's coming in via the Vertex/Normal/etc api
+ * above (where aliasing exists with the traditional entrypoints).
+ * Note that MultiTexCoordARB aliases with TexCoord when unit==0.
+ *
+ * Need presence tracking for material components, too, but not size
+ * tracking or help with aliasing.  Could move material to seperate
+ * dispatch without the "*4" below, or even do the checks every time.
+ */
+struct attr_dispatch_tab {
+   void (*tab[32*4])( void );
+   void (*swapped[32*4])( void );
+   int swapcount;
+   int installed_sizes[32];
+};
+
+#define DISPATCH_ATTR1F( ATTR, N,  ) 
+   tnl->vb.attr_dispatch 
+
+/* Result at the back end after second dispatch -- could further
+ * specialize for attr zero -- maybe just in the codegen version.
+ */
+static void tnl_Attr1f( GLint attr, GLfloat s )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR1F( attr, s );
 }
 
-static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
+static void tnl_Attr1fv( GLint attr, const GLfloat *v )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR1F( attr, v[0] );
 }
 
-static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
+static void tnl_Attr2f( GLint attr, GLfloat s, GLfloat t )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR2F( attr, s, t );
 }
 
-static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
+static void tnl_Attr2fv( GLint attr, const GLfloat *v )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR2F( attr, v[0], v[1] );
 }
 
-static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t,
-                                   GLfloat r)
+static void tnl_Attr3f( GLint attr, GLfloat s, GLfloat t, GLfloat r )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR3F( attr, s, t, r );
 }
 
-static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
+static void tnl_Attr3fv( GLint attr, const GLfloat *v )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR3F( attr, v[0], v[1], v[2] );
 }
 
-static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t,
-                                   GLfloat r, GLfloat q )
+static void tnl_Attr4f( GLint attr, GLfloat s, GLfloat t, GLfloat r, GLfloat q )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR4F( attr, s, t, r, q );
 }
 
-static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
+static void tnl_Attr4fv( GLint attr, const GLfloat *v )
 {
-   GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
    ATTR4F( attr, v[0], v[1], v[2], v[3] );
 }
 
 
-/* NV_vertex_program:  
- *
- * *** Need second dispatch layer above this for size tracking.  One
- * *** dispatch layer handles both VertexAttribute and MultiTexCoord 
+/* MultiTexcoord:  Send through second level dispatch.
  */
-static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
+static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s  )
 {
-   ATTR1F( index, s );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR1F( attr, s );
 }
 
-static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
+static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
 {
-   ATTR1F( index, v[0] );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR1F( attr, v[0] );
 }
 
-static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
+static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
 {
-   ATTR2F( index, s, t );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR2F( attr, s, t );
 }
 
-static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
+static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
 {
-   ATTR2F( index, v[0], v[1] );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR2F( attr, v[0], v[1] );
 }
 
-static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t, 
-                                 GLfloat r )
+static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t,
+                                   GLfloat r)
 {
-   ATTR3F( index, s, t, r );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR3F( attr, s, t, r );
 }
 
-static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
+static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
 {
-   ATTR3F( index, v[0], v[1], v[2] );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR3F( attr, v[0], v[1], v[2] );
 }
 
-static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
-                                 GLfloat r, GLfloat q )
+static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t,
+                                   GLfloat r, GLfloat q )
 {
-   ATTR4F( index, s, t, r, q );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR4F( attr, s, t, r, q );
 }
 
-static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
 {
-   ATTR4F( index, v[0], v[1], v[2], v[3] );
+   GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
+   if (attr < MAX_VERT_ATTRS)
+      DISPATCH_ATTR4F( attr, v[0], v[1], v[2], v[3] );
 }
 
 
-/* Miscellaneous:  (These don't alias NV attributes, right?)
+/* NV_vertex_program:
+ *
+ * Check for errors & reroute through second dispatch layer to get
+ * size tracking per-attribute.
  */
-static void tnl_EdgeFlag( GLboolean flag )
+static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
 {
-   GET_TNL;
-   tnl->edgeflagptr[0] = flag;
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR1F( index, s );
+   else
+      DISPATCH_ERROR; 
 }
 
-static void tnl_EdgeFlagv( const GLboolean *flag )
+static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
 {
-   GET_TNL;
-   tnl->edgeflagptr[0] = *flag;
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR1F( index, v[0] );
+   else
+      DISPATCH_ERROR;
 }
 
-static void tnl_Indexi( GLint idx )
+static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
 {
-   GET_TNL;
-   tnl->indexptr[0] = idx;
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR2F( index, s, t );
+   else
+      DISPATCH_ERROR;
 }
 
-static void tnl_Indexiv( const GLint *idx )
+static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
 {
-   GET_TNL;
-   tnl->indexptr[0] = *idx;
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR2F( index, v[0], v[1] );
+   else
+      DISPATCH_ERROR;
 }
 
-
-
-/* Could use dispatch switching to build 'ranges' of eval vertices for
- * each type, avoiding need for flags.  (Make
- * evalcoords/evalpoints/vertices/attr0 mutually exclusive)
- *  --> In which case, may as well use Vertex{12}f{v} here.
- */
-static void _tnl_EvalCoord1f( GLfloat u )
+static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t, 
+                                 GLfloat r )
 {
-   ATTR1F( VERT_ATTRIB_POS, u );
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR3F( index, s, t, r );
+   else
+      DISPATCH_ERROR;
 }
 
-static void _tnl_EvalCoord1fv( const GLfloat *v )
+static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
 {
-   ATTR1F( VERT_ATTRIB_POS, v[0] );
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR3F( index, v[0], v[1], v[2] );
+   else
+      DISPATCH_ERROR;
 }
 
-static void _tnl_EvalCoord2f( GLfloat u, GLfloat v )
+static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
+                                 GLfloat r, GLfloat q )
 {
-   ATTR2F( VERT_ATTRIB_POS, u, v );
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR4F( index, s, t, r, q );
+   else
+      DISPATCH_ERROR;
 }
 
-static void _tnl_EvalCoord2fv( const GLfloat *v )
+static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
 {
-   ATTR2F( VERT_ATTRIB_POS, v[0], v[1] );
+   if (index < MAX_VERT_ATTRS)
+      DISPATCH_ATTR4F( index, v[0], v[1], v[2], v[3] );
+   else
+      DISPATCH_ERROR;
 }
 
 
+
+
+
+
+
 /* Materials:  
- *  *** Treat as more vertex attributes
+ * 
+ * These are treated as per-vertex attributes, at indices above where
+ * the NV_vertex_program leaves off.  There are a lot of good things
+ * about treating materials this way.  
+ *
+ * *** Need a dispatch step (like VertexAttribute GLint attr, and MultiTexCoord)
+ * *** to expand vertex size, etc.  Use the same second level dispatch
+ * *** (keyed by attr number) as above.
+ */
+#define MAT( ATTR, face, params )              \
+do {                                           \
+   if (face != GL_BACK)                                \
+      DISPATCH_ATTRF( ATTR, N, params );       \
+   if (face != GL_FRONT)                       \
+      DISPATCH_ATTRF( ATTR+7, N, params );     \
+} while (0)
+
+
+/* NOTE: Have to remove/dealwith colormaterial crossovers, probably
+ * later on - in the meantime just store everything.
  */
 static void _tnl_Materialfv( GLenum face, GLenum pname, 
                               const GLfloat *params )
 {
-   if (MESA_VERBOSE & DEBUG_VFMT)
-      fprintf(stderr, "%s\n", __FUNCTION__);
-
-   if (tnl->prim[0] != GL_POLYGON+1) {
-      VFMT_FALLBACK( __FUNCTION__ );
-      glMaterialfv( face, pname, params );
+   switch (pname) {
+   case GL_EMISSION:
+      MAT( VERT_ATTRIB_FRONT_EMMISSION, 4, face, params );
+      break;
+   case GL_AMBIENT:
+      MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params );
+      break;
+   case GL_DIFFUSE:
+      MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params );
+      break;
+   case GL_SPECULAR:
+      MAT( VERT_ATTRIB_FRONT_SPECULAR, 4, face, params );
+      break;
+   case GL_SHININESS:
+      MAT( VERT_ATTRIB_FRONT_SHININESS, 1, face, params );
+      break;
+   case GL_COLOR_INDEXES:
+      MAT( VERT_ATTRIB_FRONT_EMMISSION, 3, face, params );
+      break;
+   case GL_AMBIENT_AND_DIFFUSE:
+      MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params );
+      MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params );
+      break;
+   default:
+      _mesa_error( ctx, GL_INVALID_ENUM, where );
       return;
    }
-   _mesa_noop_Materialfv( face, pname, params );
 }
 
 
@@ -455,6 +601,13 @@ static struct dynfn *lookup( struct dynfn *l, int key )
    return 0;
 }
 
+/* Vertex descriptor
+ */
+struct _tnl_vertex_descriptor {
+   GLuint attr_bits[4];
+};
+
+
 /* Can't use the loopback template for this:
  */
 #define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 )                        \
@@ -560,28 +713,28 @@ void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt )
    vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
    vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
    vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
-   vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
-   vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
-   vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
-   vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
+   vfmt->MultiTexCoord1fARB = dd_MultiTexCoord1fARB;
+   vfmt->MultiTexCoord1fvARB = dd_MultiTexCoord1fvARB;
+   vfmt->MultiTexCoord2fARB = dd_MultiTexCoord2fARB;
+   vfmt->MultiTexCoord2fvARB = dd_MultiTexCoord2fvARB;
+   vfmt->MultiTexCoord3fARB = dd_MultiTexCoord3fARB;
+   vfmt->MultiTexCoord3fvARB = dd_MultiTexCoord3fvARB;
+   vfmt->MultiTexCoord4fARB = dd_MultiTexCoord4fARB;
+   vfmt->MultiTexCoord4fvARB = dd_MultiTexCoord4fvARB;
    vfmt->Normal3f = choose_Normal3f;
    vfmt->Normal3fv = choose_Normal3fv;
    vfmt->TexCoord1f = choose_TexCoord1f;
    vfmt->TexCoord1fv = choose_TexCoord1fv;
    vfmt->TexCoord2f = choose_TexCoord2f;
    vfmt->TexCoord2fv = choose_TexCoord2fv;
-   vfmt->Vertex2f = choose_Vertex2f;
-   vfmt->Vertex2fv = choose_Vertex2fv;
-   vfmt->Vertex3f = choose_Vertex3f;
-   vfmt->Vertex3fv = choose_Vertex3fv;
    vfmt->TexCoord3f = choose_TexCoord3f;
    vfmt->TexCoord3fv = choose_TexCoord3fv;
    vfmt->TexCoord4f = choose_TexCoord4f;
    vfmt->TexCoord4fv = choose_TexCoord4fv;
-   vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB;
-   vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB;
-   vfmt->MultiTexCoord4fARB = choose_MultiTexCoord4fARB;
-   vfmt->MultiTexCoord4fvARB = choose_MultiTexCoord4fvARB;
+   vfmt->Vertex2f = choose_Vertex2f;
+   vfmt->Vertex2fv = choose_Vertex2fv;
+   vfmt->Vertex3f = choose_Vertex3f;
+   vfmt->Vertex3fv = choose_Vertex3fv;
    vfmt->Vertex4f = choose_Vertex4f;
    vfmt->Vertex4fv = choose_Vertex4fv;
    vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;
@@ -594,12 +747,7 @@ void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt )
    vfmt->EvalCoord1fv = choose_EvalCoord1fv;
    vfmt->EvalCoord2f = choose_EvalCoord2f;
    vfmt->EvalCoord2fv = choose_EvalCoord2fv;
-   vfmt->EvalMesh1 = choose_EvalMesh1;
-   vfmt->EvalMesh2 = choose_EvalMesh2;
-   vfmt->EvalPoint1 = choose_EvalPoint1;
-   vfmt->EvalPoint2 = choose_EvalPoint2;
-
-   vfmt->Materialfv = _tnl_Materialfv;
+   vfmt->Materialfv = dd_Materialfv;
 }
 
 
@@ -611,13 +759,8 @@ static struct dynfn *codegen_noop( struct _vb *vb, int key )
 
 void _tnl_InitCodegen( struct dfn_generators *gen )
 {
-   gen->Vertex2f = codegen_noop;
-   gen->Vertex2fv = codegen_noop;
-   gen->Vertex3f = codegen_noop;
-   gen->Vertex3fv = codegen_noop;
-   gen->Vertex4f = codegen_noop;
-   gen->Vertex4fv = codegen_noop;
-
+   /* Generate an attribute or vertex command.
+    */
    gen->Attr1f = codegen_noop;
    gen->Attr1fv = codegen_noop;
    gen->Attr2f = codegen_noop;
@@ -626,18 +769,16 @@ void _tnl_InitCodegen( struct dfn_generators *gen )
    gen->Attr3fv = codegen_noop;
    gen->Attr4f = codegen_noop;
    gen->Attr4fv = codegen_noop;
+   
+   /* Index is never zero for these...
+    */
    gen->Attr3ub = codegen_noop;
    gen->Attr3ubv = codegen_noop;
    gen->Attr4ub = codegen_noop;
    gen->Attr4ubv = codegen_noop;
 
-   /* Probably need two versions of this, one for the front end
-    * (double dispatch), one for the back end (do the work) -- but
-    * will also need a second level of CHOOSE functions?
-    *   -- Generate the dispatch layer using the existing templates somehow.
-    *   -- Generate the backend and 2nd level choosers here.
-    *   -- No need for a chooser on the top level.
-    *   -- Can aliasing help -- ie can NVAttr1f == Attr1f/Vertex2f at this level (index is known)
+   /* As above, but deal with the extra (redundant by now) index
+    * argument to the generated function.
     */
    gen->NVAttr1f = codegen_noop;
    gen->NVAttr1fv = codegen_noop;
@@ -648,14 +789,6 @@ void _tnl_InitCodegen( struct dfn_generators *gen )
    gen->NVAttr4f = codegen_noop;
    gen->NVAttr4fv = codegen_noop;
 
-   gen->MTAttr1f = codegen_noop;
-   gen->MTAttr1fv = codegen_noop;
-   gen->MTAttr2f = codegen_noop;
-   gen->MTAttr2fv = codegen_noop;
-   gen->MTAttr3f = codegen_noop;
-   gen->MTAttr3fv = codegen_noop;
-   gen->MTAttr4f = codegen_noop;
-   gen->MTAttr4fv = codegen_noop;
 
    if (!getenv("MESA_NO_CODEGEN")) {
 #if defined(USE_X86_ASM)
index 8470d6ab35a7ab57fb3455d127e174e25043317d..b9eb5bde8dbf9d3b1c4c7eb1ce3344b7d4226c92 100644 (file)
@@ -184,10 +184,6 @@ static void copy_vertex( TNLcontext *tnl, GLuint n, GLfloat *dst )
    }
 }
 
-/* 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_wrapped_verts( TNLcontext *tnl, GLfloat (*tmp)[15] )
 {
    GLuint ovf, i;
index 4713a325bf2d17945c043e1fc85d85445af09452..05cad6290235725ba0af27f083401bfe9c1d8a4e 100644 (file)
@@ -40,6 +40,61 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #if defined(USE_X86_ASM)
 
+
+struct dynfn *tnl_makeX86Vertex2f( TNLcontext *tnl, int key )
+{
+   struct dynfn *dfn = MALLOC_STRUCT( dynfn );
+
+   if (RADEON_DEBUG & DEBUG_CODEGEN)
+      fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
+
+   switch (tnl->vertex_size) {
+   default: {
+      /* Repz convenient as it's possible to emit code for any size
+       * vertex with little tweaking.  Might as well read vertsize
+       * though, and have only one of these.
+       */
+      static  char temp[] = {
+        0x57,                          /* push   %edi */
+        0x56,                          /* push   %esi */
+        0xbe, 0, 0, 0, 0,              /* mov    $VERTEX+2,%esi */
+        0x8b, 0x3d, 0, 0, 0, 0,        /* mov    DMAPTR,%edi */
+        0x8b, 0x44, 0x24, 0x0c,        /* mov    0x0c(%esp,1),%eax */
+        0x8b, 0x54, 0x24, 0x10,        /* mov    0x10(%esp,1),%edx */
+        0x89, 0x07,                    /* mov    %eax,(%edi) */
+        0x89, 0x57, 0x04,              /* mov    %edx,0x4(%edi) */
+        0x83, 0xc7, 0x08,              /* add    $0x8,%edi */
+        0xb9, 0, 0, 0, 0,              /* mov    $VERTSIZE-2,%ecx */
+        0xf3, 0xa5,                    /* repz movsl %ds:(%esi),%es:(%edi)*/
+        0xa1, 0, 0, 0, 0,              /* mov    COUNTER,%eax */
+        0x89, 0x3d, 0, 0, 0, 0,        /* mov    %edi,DMAPTR */
+        0x48,                          /* dec    %eax */
+        0xa3, 0, 0, 0, 0,              /* mov    %eax,COUNTER */
+        0x5e,                          /* pop    %esi */
+        0x5f,                          /* pop    %edi */
+        0x74, 0x01,                    /* je     +1 */
+        0xc3,                          /* ret     */
+        0xff, 0x25, 0, 0, 0, 0         /* jmp    NOTIFY */
+      };
+
+      dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
+      memcpy (dfn->code, temp, sizeof(temp));
+      FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]);
+      FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr);
+      FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-2);
+      FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter);
+      FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr);
+      FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter);
+      FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
+   break;
+   }
+   }
+
+   insert_at_head( &tnl->dfn_cache.Vertex3f, dfn );
+   dfn->key = key;
+   return dfn;
+}
+
 /* Build specialized versions of the immediate calls on the fly for
  * the current state.  Generic x86 versions.
  */
@@ -317,7 +372,7 @@ struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *tnl, int key )
 }
 
 
-struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key )
+struct dynfn *tnl_makeX86Attr4fv( TNLcontext *tnl, int key )
 {
    static  char temp[] = {
       0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
@@ -328,6 +383,8 @@ struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key )
       0x89, 0x4a, 0x04,                /* mov    %ecx,0x4(%edx) */
       0x8b, 0x48, 0x08,                /* mov    0x8(%eax),%ecx */
       0x89, 0x4a, 0x08,                /* mov    %ecx,0x8(%edx) */
+      0x8b, 0x48, 0x0a,                /* mov    0xa(%eax),%ecx */
+      0x89, 0x4a, 0x0a,                /* mov    %ecx,0xa(%edx) */
       0xc3,                            /* ret    */
    };
 
@@ -344,7 +401,7 @@ struct dynfn *tnl_makeX86Normal3fv( TNLcontext *tnl, int key )
    return dfn;
 }
 
-struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key )
+struct dynfn *tnl_makeX86Attr4f( TNLcontext *tnl, int key )
 {
    static  char temp[] = {
       0xba, 0x78, 0x56, 0x34, 0x12,            /*  mov    $DEST,%edx */
@@ -354,6 +411,8 @@ struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key )
       0x89, 0x42, 0x04,                /*  mov    %eax,0x4(%edx) */
       0x8b, 0x44, 0x24, 0x0c,                  /*  mov    0xc(%esp,1),%eax */
       0x89, 0x42, 0x08,                /*  mov    %eax,0x8(%edx) */
+      0x8b, 0x44, 0x24, 0x10,                  /*  mov    0x10(%esp,1),%eax */
+      0x89, 0x42, 0x0a,                /*  mov    %eax,0xa(%edx) */
       0xc3,                            /*  ret     */
    };
 
@@ -370,7 +429,61 @@ struct dynfn *tnl_makeX86Normal3f( TNLcontext *tnl, int key )
    return dfn;
 }
 
-struct dynfn *tnl_makeX86Color4ubv( TNLcontext *tnl, int key )
+
+struct dynfn *tnl_makeX86Attr3fv( TNLcontext *tnl, int key )
+{
+   static  char temp[] = {
+      0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
+      0xba, 0, 0, 0, 0,                /* mov    $DEST,%edx */
+      0x8b, 0x08,                      /* mov    (%eax),%ecx */
+      0x89, 0x0a,                      /* mov    %ecx,(%edx) */
+      0x8b, 0x48, 0x04,                /* mov    0x4(%eax),%ecx */
+      0x89, 0x4a, 0x04,                /* mov    %ecx,0x4(%edx) */
+      0x8b, 0x48, 0x08,                /* mov    0x8(%eax),%ecx */
+      0x89, 0x4a, 0x08,                /* mov    %ecx,0x8(%edx) */
+      0xc3,                            /* ret    */
+   };
+
+   struct dynfn *dfn = MALLOC_STRUCT( dynfn );
+
+   if (TNL_DEBUG & DEBUG_CODEGEN)
+      fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
+
+   insert_at_head( &tnl->dfn_cache.Normal3fv, dfn );
+   dfn->key = key;
+   dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
+   memcpy (dfn->code, temp, sizeof(temp));
+   FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr); 
+   return dfn;
+}
+
+struct dynfn *tnl_makeX86Attr3f( TNLcontext *tnl, int key )
+{
+   static  char temp[] = {
+      0xba, 0x78, 0x56, 0x34, 0x12,            /*  mov    $DEST,%edx */
+      0x8b, 0x44, 0x24, 0x04,                  /*  mov    0x4(%esp,1),%eax */
+      0x89, 0x02,                      /*  mov    %eax,(%edx) */
+      0x8b, 0x44, 0x24, 0x08,                  /*  mov    0x8(%esp,1),%eax */
+      0x89, 0x42, 0x04,                /*  mov    %eax,0x4(%edx) */
+      0x8b, 0x44, 0x24, 0x0c,                  /*  mov    0xc(%esp,1),%eax */
+      0x89, 0x42, 0x08,                /*  mov    %eax,0x8(%edx) */
+      0xc3,                            /*  ret     */
+   };
+
+   struct dynfn *dfn = MALLOC_STRUCT( dynfn );
+
+   if (TNL_DEBUG & DEBUG_CODEGEN)
+      fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
+
+   insert_at_head( &tnl->dfn_cache.Normal3f, dfn );
+   dfn->key = key;
+   dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
+   memcpy (dfn->code, temp, sizeof(temp));
+   FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr); 
+   return dfn;
+}
+
+struct dynfn *tnl_makeX86Attr4ubv( TNLcontext *tnl, int key )
 {
    struct dynfn *dfn = MALLOC_STRUCT( dynfn );
    insert_at_head( &tnl->dfn_cache.Color4ubv, dfn );
@@ -431,7 +544,7 @@ struct dynfn *tnl_makeX86Color4ubv( TNLcontext *tnl, int key )
    }
 }
 
-struct dynfn *tnl_makeX86Color4ub( TNLcontext *tnl, int key )
+struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key )
 {
    if (TNL_DEBUG & DEBUG_CODEGEN)
       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
@@ -469,72 +582,8 @@ struct dynfn *tnl_makeX86Color4ub( TNLcontext *tnl, int key )
 }
 
 
-struct dynfn *tnl_makeX86Color3fv( TNLcontext *tnl, int key )
-{
-   if (key & (TNL_CP_VC_FRMT_PKCOLOR|TNL_CP_VC_FRMT_FPALPHA))
-      return 0;
-   else
-   {
-      static  char temp[] = {
-        0x8b, 0x44, 0x24, 0x04,                /* mov    0x4(%esp,1),%eax */
-        0xba, 0, 0, 0, 0,              /* mov    $DEST,%edx */
-        0x8b, 0x08,                    /* mov    (%eax),%ecx */
-        0x89, 0x0a,                    /* mov    %ecx,(%edx) */
-        0x8b, 0x48, 0x04,              /* mov    0x4(%eax),%ecx */
-        0x89, 0x4a, 0x04,              /* mov    %ecx,0x4(%edx) */
-        0x8b, 0x48, 0x08,              /* mov    0x8(%eax),%ecx */
-        0x89, 0x4a, 0x08,              /* mov    %ecx,0x8(%edx) */
-        0xc3,                          /* ret    */
-      };
-
-      struct dynfn *dfn = MALLOC_STRUCT( dynfn );
 
-      if (TNL_DEBUG & DEBUG_CODEGEN)
-        fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
-      insert_at_head( &tnl->dfn_cache.Color3fv, dfn );
-      dfn->key = key;
-      dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
-      memcpy (dfn->code, temp, sizeof(temp));
-      FIXUP(dfn->code, 5, 0x0, (int)tnl->floatcolorptr); 
-      return dfn;
-   }
-}
-
-struct dynfn *tnl_makeX86Color3f( TNLcontext *tnl, int key )
-{
-   if (key & (TNL_CP_VC_FRMT_PKCOLOR|TNL_CP_VC_FRMT_FPALPHA))
-      return 0;
-   else
-   {
-      static  char temp[] = {
-        0xba, 0x78, 0x56, 0x34, 0x12,          /*  mov    $DEST,%edx */
-        0x8b, 0x44, 0x24, 0x04,                /*  mov    0x4(%esp,1),%eax */
-        0x89, 0x02,                    /*  mov    %eax,(%edx) */
-        0x8b, 0x44, 0x24, 0x08,                /*  mov    0x8(%esp,1),%eax */
-        0x89, 0x42, 0x04,              /*  mov    %eax,0x4(%edx) */
-        0x8b, 0x44, 0x24, 0x0c,                /*  mov    0xc(%esp,1),%eax */
-        0x89, 0x42, 0x08,              /*  mov    %eax,0x8(%edx) */
-        0xc3,                          /*  ret     */
-      };
-
-      struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
-      if (TNL_DEBUG & DEBUG_CODEGEN)
-        fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
-
-      insert_at_head( &tnl->dfn_cache.Color3f, dfn );
-      dfn->key = key;
-      dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
-      memcpy (dfn->code, temp, sizeof(temp));
-      FIXUP(dfn->code, 1, 0x12345678, (int)tnl->floatcolorptr); 
-      return dfn;
-   }
-}
-
-
-
-struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *tnl, int key )
+struct dynfn *tnl_makeX86Attr2fv( TNLcontext *tnl, int key )
 {
    static  char temp[] = {
       0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
@@ -559,7 +608,7 @@ struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *tnl, int key )
    return dfn;
 }
 
-struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *tnl, int key )
+struct dynfn *tnl_makeX86Attr2f( TNLcontext *tnl, int key )
 {
    static  char temp[] = {
       0xba, 0x78, 0x56, 0x34, 0x12,            /* mov    $DEST,%edx */
@@ -583,31 +632,14 @@ struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *tnl, int key )
    return dfn;
 }
 
-struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *tnl, int key )
+
+struct dynfn *tnl_makeX86Attr1fv( TNLcontext *tnl, int key )
 {
    static  char temp[] = {
       0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
-      0x8b, 0x4c, 0x24, 0x08,                  /* mov    0x8(%esp,1),%ecx */
-      0x2d, 0xc0, 0x84, 0x00, 0x00,            /* sub    $0x84c0,%eax */
-      0x83, 0xe0, 0x01,                /* and    $0x1,%eax */
-      0x8b, 0x11,                      /* mov    (%ecx),%edx */
-      0xc1, 0xe0, 0x03,                /* shl    $0x3,%eax */
-      0x8b, 0x49, 0x04,                /* mov    0x4(%ecx),%ecx */
-      0x89, 0x90, 0, 0, 0, 0,/* mov    %edx,DEST(%eax) */
-      0x89, 0x88, 0, 0, 0, 0,/* mov    %ecx,DEST+8(%eax) */
-      0xc3,                            /* ret     */
-   };
-
-   static char temp2[] = {
-      0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
-      0x8b, 0x4c, 0x24, 0x08,                  /* mov    0x8(%esp,1),%ecx */
-      0x2d, 0xc0, 0x84, 0x00, 0x00,            /* sub    $0x84c0,%eax */
-      0x83, 0xe0, 0x01,                /* and    $0x1,%eax */
-      0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov    DEST(,%eax,4),%edx */
-      0x8b, 0x01,                      /* mov    (%ecx),%eax */
-      0x89, 0x02,                      /* mov    %eax,(%edx) */
-      0x8b, 0x41, 0x04,                /* mov    0x4(%ecx),%eax */
-      0x89, 0x42, 0x04,                /* mov    %eax,0x4(%edx) */
+      0xba, 0x78, 0x56, 0x34, 0x12,     /* mov    $DEST,%edx */
+      0x8b, 0x08,                      /* mov    (%eax),%ecx */
+      0x89, 0x0a,                      /* mov    %ecx,(%edx) */
       0xc3,                            /* ret     */
    };
 
@@ -616,104 +648,52 @@ struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *tnl, int key )
    if (TNL_DEBUG & DEBUG_CODEGEN)
       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
 
-   insert_at_head( &tnl->dfn_cache.MultiTexCoord2fvARB, dfn );
+   insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn );
    dfn->key = key;
-
-   if ((key & (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) ==
-      (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) {
-      dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
-      memcpy (dfn->code, temp, sizeof(temp));
-      FIXUP(dfn->code, 26, 0x0, (int)tnl->texcoordptr[0]);     
-      FIXUP(dfn->code, 32, 0x0, (int)tnl->texcoordptr[0]+4);
-   } else {
-      dfn->code = ALIGN_MALLOC( sizeof(temp2), 16 );
-      memcpy (dfn->code, temp2, sizeof(temp2));
-      FIXUP(dfn->code, 19, 0x0, (int)tnl->texcoordptr);
-   }
+   dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
+   memcpy (dfn->code, temp, sizeof(temp));
+   FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]); 
    return dfn;
 }
 
-struct dynfn *tnl_makeX86MultiTexCoord2fARB( TNLcontext *tnl, 
-                                               int key )
+struct dynfn *tnl_makeX86Attr1f( TNLcontext *tnl, int key )
 {
    static  char temp[] = {
+      0xba, 0x78, 0x56, 0x34, 0x12,            /* mov    $DEST,%edx */
       0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
-      0x8b, 0x54, 0x24, 0x08,                  /* mov    0x8(%esp,1),%edx */
-      0x2d, 0xc0, 0x84, 0x00, 0x00,            /* sub    $0x84c0,%eax */
-      0x8b, 0x4c, 0x24, 0x0c,                  /* mov    0xc(%esp,1),%ecx */
-      0x83, 0xe0, 0x01,                /* and    $0x1,%eax */
-      0xc1, 0xe0, 0x03,                /* shl    $0x3,%eax */
-      0x89, 0x90, 0, 0, 0, 0,  /* mov    %edx,DEST(%eax) */
-      0x89, 0x88, 0, 0, 0, 0,  /* mov    %ecx,DEST+8(%eax) */
+      0x89, 0x02,                      /* mov    %eax,(%edx) */
       0xc3,                            /* ret     */
    };
 
-   static char temp2[] = {
-      0x8b, 0x44, 0x24, 0x04,                  /* mov    0x4(%esp,1),%eax */
-      0x8b, 0x54, 0x24, 0x08,                  /* mov    0x8(%esp,1),%edx */
-      0x2d, 0xc0, 0x84, 0x00, 0x00,            /* sub    $0x84c0,%eax */
-      0x8b, 0x4c, 0x24, 0x0c,                  /* mov    0xc(%esp,1),%ecx */
-      0x83, 0xe0, 0x01,                /* and    $0x1,%eax */
-      0x8b, 0x04, 0x85, 0, 0, 0, 0,     /* mov    DEST(,%eax,4),%eax */
-      0x89, 0x10,                      /* mov    %edx,(%eax) */
-      0x89, 0x48, 0x04,                /* mov    %ecx,0x4(%eax) */
-      0xc3,                            /* ret     */
-   };
-
    struct dynfn *dfn = MALLOC_STRUCT( dynfn );
 
    if (TNL_DEBUG & DEBUG_CODEGEN)
       fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key );
 
-   insert_at_head( &tnl->dfn_cache.MultiTexCoord2fARB, dfn );
+   insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
    dfn->key = key;
-
-   if ((key & (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) ==
-       (TNL_CP_VC_FRMT_ST0|TNL_CP_VC_FRMT_ST1)) {
-      dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
-      memcpy (dfn->code, temp, sizeof(temp));
-      FIXUP(dfn->code, 25, 0x0, (int)tnl->texcoordptr[0]); 
-      FIXUP(dfn->code, 31, 0x0, (int)tnl->texcoordptr[0]+4); 
-   }
-   else {
-      /* Note: this might get generated multiple times, even though the
-       * actual emitted code is the same.
-       */
-      dfn->code = ALIGN_MALLOC( sizeof(temp2), 16 );
-      memcpy (dfn->code, temp2, sizeof(temp2));
-      FIXUP(dfn->code, 23, 0x0, (int)tnl->texcoordptr); 
-   }      
+   dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
+   memcpy (dfn->code, temp, sizeof(temp));
+   FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]); 
    return dfn;
 }
 
 
+
 void _tnl_InitX86Codegen( struct dfn_generators *gen )
 {
+   gen->Attr1f = tnl_makeX86Attr1f;
+   gen->Attr1fv = tnl_makeX86Attr1fv;
+   gen->Attr2f = tnl_makeX86Attr2f;
+   gen->Attr2fv = tnl_makeX86Attr2fv;
+   gen->Attr3f = tnl_makeX86Attr3f;
+   gen->Attr3fv = tnl_makeX86Attr3fv;
+   gen->Attr4f = tnl_makeX86Attr4f;
+   gen->Attr4fv = tnl_makeX86Attr4fv;
+   gen->Attr4ub = tnl_makeX86Attr4ub; 
+   gen->Attr4ubv = tnl_makeX86Attr4ubv;
    gen->Vertex3f = tnl_makeX86Vertex3f;
    gen->Vertex3fv = tnl_makeX86Vertex3fv;
-   gen->Color4ub = tnl_makeX86Color4ub; /* PKCOLOR only */
-   gen->Color4ubv = tnl_makeX86Color4ubv; /* PKCOLOR only */
-   gen->Normal3f = tnl_makeX86Normal3f;
-   gen->Normal3fv = tnl_makeX86Normal3fv;
-   gen->TexCoord2f = tnl_makeX86TexCoord2f;
-   gen->TexCoord2fv = tnl_makeX86TexCoord2fv;
-   gen->MultiTexCoord2fARB = tnl_makeX86MultiTexCoord2fARB;
-   gen->MultiTexCoord2fvARB = tnl_makeX86MultiTexCoord2fvARB;
-   gen->Color3f = tnl_makeX86Color3f;
-   gen->Color3fv = tnl_makeX86Color3fv;
-
-   /* Not done:
-    */
-/*     gen->Vertex2f = tnl_makeX86Vertex2f; */
-/*     gen->Vertex2fv = tnl_makeX86Vertex2fv; */
-/*     gen->Color3ub = tnl_makeX86Color3ub; */
-/*     gen->Color3ubv = tnl_makeX86Color3ubv; */
-/*     gen->Color4f = tnl_makeX86Color4f; */
-/*     gen->Color4fv = tnl_makeX86Color4fv; */
-/*     gen->TexCoord1f = tnl_makeX86TexCoord1f; */
-/*     gen->TexCoord1fv = tnl_makeX86TexCoord1fv; */
-/*     gen->MultiTexCoord1fARB = tnl_makeX86MultiTexCoord1fARB; */
-/*     gen->MultiTexCoord1fvARB = tnl_makeX86MultiTexCoord1fvARB; */
 }