Re-commit t_vertex.[ch] changes to fd.o server.
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 5 Jan 2004 09:43:42 +0000 (09:43 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Mon, 5 Jan 2004 09:43:42 +0000 (09:43 +0000)
23 files changed:
src/mesa/drivers/dri/gamma/gamma_render.c
src/mesa/drivers/dri/i810/i810render.c
src/mesa/drivers/dri/i830/i830_render.c
src/mesa/drivers/dri/mga/mgarender.c
src/mesa/drivers/dri/r200/r200_swtcl.c
src/mesa/drivers/dri/radeon/radeon_swtcl.c
src/mesa/main/mtypes.h
src/mesa/swrast_setup/ss_context.c
src/mesa/swrast_setup/swrast_setup.h
src/mesa/tnl/t_context.c
src/mesa/tnl/t_context.h
src/mesa/tnl/t_pipeline.c
src/mesa/tnl/t_save_playback.c
src/mesa/tnl/t_vb_fog.c
src/mesa/tnl/t_vb_light.c
src/mesa/tnl/t_vb_normals.c
src/mesa/tnl/t_vb_program.c
src/mesa/tnl/t_vb_render.c
src/mesa/tnl/t_vb_texgen.c
src/mesa/tnl/t_vb_texmat.c
src/mesa/tnl/t_vertex.c
src/mesa/tnl/t_vertex.h
src/mesa/tnl/tnl.h

index 380c7b7044c83c2672fa7d4f26a6221543ce8cb2..a0b8a5dc185d4b57354b0c367e733c8280caae59 100644 (file)
@@ -212,23 +212,7 @@ static GLboolean gamma_run_render( GLcontext *ctx,
 static void gamma_check_render( GLcontext *ctx,
                                 struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
-
-   if (ctx->RenderMode == GL_RENDER) {
-      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
-        inputs |= VERT_BIT_COLOR1;
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX0;
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX1;
-
-      if (ctx->Fog.Enabled)
-        inputs |= VERT_BIT_FOG;
-   }
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 
index 19c5dc07c4af64e9479012ec2c62b375ecddcb0a..c674378953f5e76ccd3a7545f394a625c3e07213 100644 (file)
@@ -161,25 +161,10 @@ static GLboolean i810_run_render( GLcontext *ctx,
 }
 
 
-static void i810_check_render( GLcontext *ctx, struct tnl_pipeline_stage *stage )
+static void i810_check_render( GLcontext *ctx, 
+                              struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
-
-   if (ctx->RenderMode == GL_RENDER) {
-      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
-        inputs |= VERT_BIT_COLOR1;
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX0;
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX1;
-
-      if (ctx->Fog.Enabled)
-        inputs |= VERT_BIT_FOG;
-   }
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 
index caed73ed6781e659b6dc433532386718d262b245..ed4c94437b5afbf63737aba1c2c05501543c115f 100644 (file)
@@ -221,22 +221,7 @@ static GLboolean i830_run_render( GLcontext *ctx,
 static void i830_check_render( GLcontext *ctx, 
                               struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
-   if (ctx->RenderMode == GL_RENDER) {
-      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
-        inputs |= VERT_BIT_COLOR1;
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX0;
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX1;
-
-      if (ctx->Fog.Enabled)
-        inputs |= VERT_BIT_FOG;
-   }
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 static void dtr( struct tnl_pipeline_stage *stage )
index 585200985213d1537f67b095d2707c77f600845d..3dd15e21a67e10d7d37ec25acd66eb3dd41bd70d 100644 (file)
@@ -163,23 +163,7 @@ static GLboolean mga_run_render( GLcontext *ctx,
 
 static void mga_check_render( GLcontext *ctx, struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
-
-   if (ctx->RenderMode == GL_RENDER) {
-      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) 
-        inputs |= VERT_BIT_COLOR1;
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX0;
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX1;
-
-      if (ctx->Fog.Enabled) 
-        inputs |= VERT_BIT_FOG;
-   }
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 
index edf00afcae1095a512ef032bed44d209e4813ab1..231a3ed83f2e4b2f79f7c38b3e43cd1c0f5eb89c 100644 (file)
@@ -662,23 +662,7 @@ static GLboolean r200_run_render( GLcontext *ctx,
 static void r200_check_render( GLcontext *ctx,
                                 struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = _TNL_BIT_POS | _TNL_BIT_COLOR0;
-
-   if (ctx->RenderMode == GL_RENDER) {
-      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
-        inputs |= _TNL_BIT_COLOR1;
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled)
-        inputs |= _TNL_BIT_TEX0;
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled)
-        inputs |= _TNL_BIT_TEX1;
-
-      if (ctx->Fog.Enabled)
-        inputs |= _TNL_BIT_FOG;
-   }
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 
index 61d80c9ac288f3bfa30c31da49e4d307775bb32f..d7f9df762e5028d4c99b1f1fc9a511d8727eb6e7 100644 (file)
@@ -644,23 +644,7 @@ static GLboolean radeon_run_render( GLcontext *ctx,
 static void radeon_check_render( GLcontext *ctx,
                                 struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
-
-   if (ctx->RenderMode == GL_RENDER) {
-      if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
-        inputs |= VERT_BIT_COLOR1;
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX0;
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled)
-        inputs |= VERT_BIT_TEX1;
-
-      if (ctx->Fog.Enabled)
-        inputs |= VERT_BIT_FOG;
-   }
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 
index 7e14da2559535bd7d79bcd58500cb6f4749af157..a5f7e366c1fef249428fbb06ba9c466aafd9c6a7 100644 (file)
@@ -1871,7 +1871,7 @@ struct matrix_stack
 /**
  * \name Bits to indicate what state has changed.  
  *
- * 6 unused flags.
+ * 4 unused flags.
  */
 /*@{*/
 #define _NEW_MODELVIEW         0x1        /**< __GLcontextRec::ModelView */
index eb133f969c8dc7f2fa821a429e3cfdfbc780730a..55fe141c258bf3ff33b5d1195d31fb7d603e5776 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "glheader.h"
 #include "imports.h"
+#include "colormac.h"
 #include "ss_context.h"
 #include "ss_triangle.h"
 #include "ss_vb.h"
@@ -35,6 +36,7 @@
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
+#include "tnl/t_vertex.h"
 
 
 #define _SWSETUP_NEW_VERTS (_NEW_RENDERMODE|   \
@@ -164,3 +166,41 @@ _swsetup_Wakeup( GLcontext *ctx )
    _tnl_need_projected_coords( ctx, GL_TRUE );
    _swsetup_InvalidateState( ctx, ~0 );
 }
+
+
+
+
+
+/* Populate a swrast SWvertex from an attrib-style vertex.
+ */
+void 
+_swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
+{
+   GLfloat tmp[4];
+   GLint i;
+
+   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, dest->win );
+
+   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
+      _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i, dest->texcoord[i] );
+         
+   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0, tmp );
+   UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
+
+   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, tmp );
+   UNCLAMPED_FLOAT_TO_RGB_CHAN( dest->specular, tmp );
+
+   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
+   dest->fog = tmp[0];
+
+   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_INDEX, tmp );
+   dest->index = (GLuint) tmp[0];
+
+/*
+  Need to check how pointsize is related to vertex program attributes:
+
+   _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
+   dest->pointSize = tmp[0];
+*/
+}
+
index 4825c772f11f33ceba70466a2caf8fe80d13c630..5dcbe2675b478f28ec6aa41c74d500c28f85cc85 100644 (file)
@@ -38,6 +38,8 @@
 #ifndef SWRAST_SETUP_H
 #define SWRAST_SETUP_H
 
+#include "swrast/swrast.h"
+
 extern GLboolean
 _swsetup_CreateContext( GLcontext *ctx );
 
@@ -50,4 +52,10 @@ _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state );
 extern void
 _swsetup_Wakeup( GLcontext *ctx );
 
+/* Helper function to translate a hardware vertex (as understood by
+ * the tnl/t_vertex.c code) to a swrast vertex.
+ */
+extern void 
+_swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest );
+
 #endif
index a78d880d01068a0187d964eec45f0a050d1d8c16..8b83372fa736d9e51a8e0fae0633fb3b77ba88cb 100644 (file)
 #include "api_arrayelt.h"
 #include "glheader.h"
 #include "imports.h"
+#include "context.h"
 #include "macros.h"
 #include "mtypes.h"
 #include "dlist.h"
 #include "light.h"
 #include "vtxfmt.h"
+#include "nvfragprog.h"
 
 #include "t_context.h"
 #include "t_array_api.h"
@@ -153,6 +155,30 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
                                         tnl->pipeline.build_state_trigger);
 
    tnl->vtx.eval.new_state |= new_state;
+
+   /* Calculate tnl->render_inputs:
+    */
+   if (ctx->Visual.rgbMode) {
+      tnl->render_inputs = (_TNL_BIT_POS|
+                           _TNL_BIT_COLOR0|
+                           (ctx->Texture._EnabledUnits << _TNL_ATTRIB_TEX0));
+
+      if (NEED_SECONDARY_COLOR(ctx))
+        tnl->render_inputs |= _TNL_BIT_COLOR1;
+   }
+   else {
+      tnl->render_inputs |= (_TNL_BIT_POS|_TNL_BIT_INDEX);
+   }
+    
+   if (ctx->Fog.Enabled)
+      tnl->render_inputs |= _TNL_BIT_FOG;
+
+   if (ctx->Polygon.FrontMode != GL_FILL || 
+       ctx->Polygon.BackMode != GL_FILL)
+      tnl->render_inputs |= _TNL_BIT_EDGEFLAG;
+
+   if (ctx->RenderMode == GL_FEEDBACK)
+      tnl->render_inputs |= _TNL_BIT_TEX0;
 }
 
 
index 1d148be214d9de77387a46a9cc69292db8d58c5d..ab146b293058279e5e410af47b800ba7c6e1f249 100644 (file)
@@ -160,6 +160,7 @@ enum {
 #define _TNL_BIT_TEX(u)  (1 << (_TNL_ATTRIB_TEX0 + (u)))
 
 
+
 #define _TNL_BITS_MAT_ANY  (_TNL_BIT_MAT_FRONT_AMBIENT   |     \
                            _TNL_BIT_MAT_BACK_AMBIENT    |      \
                            _TNL_BIT_MAT_FRONT_DIFFUSE   |      \
@@ -456,6 +457,7 @@ struct tnl_pipeline_stage {
                                 * call to 'run'.
                                 */
 
+
    /* Private data for the pipeline stage:
     */
    void *privatePtr;
@@ -494,6 +496,22 @@ struct tnl_pipeline {
 };
 
 
+struct tnl_clipspace_attr {
+   int attrib;
+   int vertoffset;
+   int vertattrsize;
+   GLfloat *inputptr;
+   int inputstride;
+
+   void (*insert)( const struct tnl_clipspace_attr *a, 
+                  char *v, const GLfloat *input );
+
+   void (*extract)( const struct tnl_clipspace_attr *a, 
+                   GLfloat *output, const char *v );
+
+   const GLfloat *vp;
+};
+
 
 
 typedef void (*points_func)( GLcontext *ctx, GLuint first, GLuint last );
@@ -513,6 +531,26 @@ typedef void (*setup_func)( GLcontext *ctx,
                            GLuint new_inputs);
 
 
+
+
+struct tnl_clipspace {
+   GLboolean need_extras;
+   
+   GLuint new_inputs;
+
+   GLubyte *vertex_buf;
+   GLuint vertex_size;
+   GLuint max_vertex_size;
+
+   struct tnl_clipspace_attr attr[_TNL_ATTRIB_MAX];
+   GLuint attr_count;
+
+   void (*emit)( GLcontext *ctx, GLuint start, GLuint end, void *dest );
+   interp_func interp;
+   copy_pv_func copy_pv;
+};
+
+
 struct tnl_device_driver {
    /***
     *** TNL Pipeline
@@ -643,6 +681,11 @@ typedef struct {
    struct tnl_vertex_arrays array_inputs;
 
 
+   /* Clipspace/ndc/window vertex managment:
+    */
+   struct tnl_clipspace clipspace;
+
+
    /* Probably need a better configuration mechanism:
     */
    GLboolean NeedNdcCoords;
@@ -650,6 +693,10 @@ typedef struct {
    GLboolean CalcDListNormalLengths;
    GLboolean IsolateMaterials;
 
+   /* 
+    */
+   GLuint render_inputs;
+
 
    GLvertexformat exec_vtxfmt;
    GLvertexformat save_vtxfmt;
index bfb8996c8dba237235c5f94444189f94775e94a1..37ec84a06f4c1207bdcc58b3841c16bb920d0e0d 100644 (file)
@@ -127,6 +127,9 @@ void _tnl_run_pipeline( GLcontext *ctx )
    unsigned short __tmp;
 #endif
 
+   if (!tnl->vb.Count)
+      return;
+
    pipe->run_state_changes = 0;
    pipe->run_input_changes = 0;
 
index eaf30a3c18198202e8802468a7bb85d1305ce7f2..37258c0a9f1902f1db59ed7018fbd3083fe41597 100644 (file)
@@ -175,7 +175,8 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
 
    FLUSH_CURRENT(ctx, 0);
 
-   if (node->prim_count) {
+   if (node->prim_count &&
+       node->count) {
 
       if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
               (node->prim[0].mode & PRIM_BEGIN)) {
index 6d688ca04126aade8b31ad93e384e8f426a76c38..2ad41f5bbd20ab19a616ba04d31cf00d182446c3 100644 (file)
@@ -185,6 +185,8 @@ static GLboolean run_fog_stage( GLcontext *ctx,
    }
 
    make_win_fog_coords( ctx, VB->FogCoordPtr, input );
+
+   VB->AttribPtr[_TNL_ATTRIB_FOG] = VB->FogCoordPtr;
    return GL_TRUE;
 }
 
index d7872675ca8fce58e3a4444490b37d96244c40bc..7bdf54bf43b7dd060bae62b2a8a8aca0c2d19789 100644 (file)
@@ -217,6 +217,10 @@ static GLboolean run_lighting( GLcontext *ctx,
     */
    store->light_func_tab[idx]( ctx, VB, stage, input );
 
+   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = VB->ColorPtr[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR1] = VB->SecondaryColorPtr[0];
+   VB->AttribPtr[_TNL_ATTRIB_INDEX] = VB->IndexPtr[0];
+
    return GL_TRUE;
 }
 
index 96a43f688452e4ae6a833936616038c103e90553..2908f1aee082be4cb48d37b7b0d4bf2952a3542e 100644 (file)
@@ -77,6 +77,8 @@ static GLboolean run_normal_stage( GLcontext *ctx,
    }
 
    VB->NormalPtr = &store->normal;
+   VB->AttribPtr[_TNL_ATTRIB_NORMAL] = VB->NormalPtr;
+
    VB->NormalLengthPtr = 0;    /* no longer valid */
    return GL_TRUE;
 }
index 6aa2890247728632193c851493d95fc9ed13e71f..ba8a98f61271454e97ff58be68981238111297d9 100644 (file)
@@ -170,8 +170,17 @@ static GLboolean run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
    VB->SecondaryColorPtr[1] = &store->attribs[VERT_RESULT_BFC1];
    VB->FogCoordPtr = &store->attribs[VERT_RESULT_FOGC];
    VB->PointSizePtr = &store->attribs[VERT_RESULT_PSIZ];
-   for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
-      VB->TexCoordPtr[i] = &store->attribs[VERT_RESULT_TEX0 + i];
+
+   VB->AttribPtr[VERT_ATTRIB_COLOR0] = VB->ColorPtr[0];
+   VB->AttribPtr[VERT_ATTRIB_COLOR1] = VB->SecondaryColorPtr[0];
+   VB->AttribPtr[VERT_ATTRIB_FOG] = VB->FogCoordPtr;
+
+   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+      VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = 
+        &store->attribs[VERT_RESULT_TEX0 + i];
+   }
+
+
 
    /* Cliptest and perspective divide.  Clip functions must clear
     * the clipmask.
index 24cf0285555c605e635bae3f7183acdc91e48ffb..1c5016896833c50ceaec8780027a1c4b53d41430 100644 (file)
@@ -342,38 +342,7 @@ static GLboolean run_render( GLcontext *ctx,
  */
 static void check_render( GLcontext *ctx, struct tnl_pipeline_stage *stage )
 {
-   GLuint inputs = _TNL_BIT_POS;
-   GLuint i;
-
-   if (ctx->Visual.rgbMode) {
-      inputs |= _TNL_BIT_COLOR0;
-
-      if (NEED_SECONDARY_COLOR(ctx))
-        inputs |= _TNL_BIT_COLOR1;
-
-      if (ctx->Texture._EnabledCoordUnits) {
-        for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
-           if (ctx->Texture._EnabledCoordUnits & (1 << i))
-              inputs |= _TNL_BIT_TEX(i);
-        }
-      }
-   }
-   else {
-      inputs |= _TNL_BIT_INDEX;
-   }
-
-   /* How do drivers turn this off?
-    */
-   if (ctx->Fog.Enabled)
-      inputs |= _TNL_BIT_FOG;
-
-   if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL)
-      inputs |= _TNL_BIT_EDGEFLAG;
-
-   if (ctx->RenderMode==GL_FEEDBACK)
-      inputs |= _TNL_BITS_TEX_ANY;
-
-   stage->inputs = inputs;
+   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
 }
 
 
index 45b4164d181437c3fd2339abd34fc0c64214ff4b..1a4f411878649567b53006750c9c8640502880b0 100644 (file)
@@ -524,7 +524,8 @@ static GLboolean run_texgen_stage( GLcontext *ctx,
         if (stage->changed_inputs & (_TNL_BIT_POS | _TNL_BIT_NORMAL | _TNL_BIT_TEX(i)))
            store->TexgenFunc[i]( ctx, store, i );
 
-        VB->TexCoordPtr[i] = &store->texcoord[i];
+        VB->AttribPtr[VERT_ATTRIB_TEX0+i] = 
+           VB->TexCoordPtr[i] = &store->texcoord[i];
       }
 
    return GL_TRUE;
index b6e672a8d4e6aaab89a410e85df549e29a8ac34e..363a76a48761aad57e2e37391ff42e0e7395869c 100644 (file)
@@ -87,7 +87,8 @@ static GLboolean run_texmat_stage( GLcontext *ctx,
                                  ctx->TextureMatrixStack[i].Top,
                                 VB->TexCoordPtr[i]);
 
-        VB->TexCoordPtr[i] = &store->texcoord[i];
+        VB->AttribPtr[VERT_ATTRIB_TEX0+i] = 
+           VB->TexCoordPtr[i] = &store->texcoord[i];
       }
    return GL_TRUE;
 }
index 61ac08efc4dac02a7761e8c5ba1fbef23cd34db7..6ac9f8a90c5e8ad9ecb6bca1cc8d6ee09fb25ab8 100644 (file)
  *    Keith Whitwell <keithw@tungstengraphics.com>
  */
 
+#include "glheader.h"
+#include "context.h"
+#include "colormac.h"
 
+#include "t_context.h"
+#include "t_vertex.h"
 
 
+/* Build and manage clipspace/ndc/window vertices.
+ *
+ * Another new mechanism designed and crying out for codegen.  Before
+ * that, it would be very interesting to investigate the merger of
+ * these vertices and those built in t_vtx_*.
+ */
 
 
-struct attr {
-   int attrib;
-   int vertoffset;
-   int vertattrsize;
-   int *inputptr;
-   int inputstride;
-   void (*insert)( const struct attr *a, char *v, const GLfloat *input );
-   void (*extract)( const struct attr *a, GLfloat *output, const char *v );
-   const GLfloat *vp;
-};
 
+#define GET_VERTEX_STATE(ctx)  &(TNL_CONTEXT(ctx)->clipspace)
 
-static void insert_4f_viewport( const struct attr *a, char *v,
+static void insert_4f_viewport( const struct tnl_clipspace_attr *a, char *v,
                                const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)v;
@@ -54,7 +56,7 @@ static void insert_4f_viewport( const struct attr *a, char *v,
    out[3] = in[3];
 }
 
-static void insert_3f_viewport( const struct attr *a, char *v,
+static void insert_3f_viewport( const struct tnl_clipspace_attr *a, char *v,
                                const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)v;
@@ -65,7 +67,7 @@ static void insert_3f_viewport( const struct attr *a, char *v,
    out[2] = vp[10] * in[2] + vp[14];
 }
 
-static void insert_2f_viewport( const struct attr *a, char *v,
+static void insert_2f_viewport( const struct tnl_clipspace_attr *a, char *v,
                                const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)v;
@@ -76,7 +78,7 @@ static void insert_2f_viewport( const struct attr *a, char *v,
 }
 
 
-static void insert_4f( const struct attr *a, char *v, const GLfloat *in )
+static void insert_4f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
@@ -86,7 +88,7 @@ static void insert_4f( const struct attr *a, char *v, const GLfloat *in )
    out[3] = in[3];
 }
 
-static void insert_3f_xyw( const struct attr *a, char *v, const GLfloat *in )
+static void insert_3f_xyw( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
@@ -96,7 +98,7 @@ static void insert_3f_xyw( const struct attr *a, char *v, const GLfloat *in )
 }
 
 
-static void insert_3f( const struct attr *a, char *v, const GLfloat *in )
+static void insert_3f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
@@ -106,22 +108,63 @@ static void insert_3f( const struct attr *a, char *v, const GLfloat *in )
 }
 
 
-static void insert_2f( const struct attr *a, char *v, const GLfloat *in )
+static void insert_2f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   
+   out[0] = in[0];
+   out[1] = in[1];
+}
+
+static void insert_1f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   
+   out[0] = in[0];
+}
+
+static void insert_3f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
    out[0] = in[0];
    out[1] = in[1];
+   out[2] = in[2];
+   out[3] = 1;
 }
 
-static void insert_1f( const struct attr *a, char *v, const GLfloat *in )
+
+static void insert_2f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
    out[0] = in[0];
+   out[1] = in[1];
+   out[2] = 0;
+   out[3] = 1;
 }
 
-static void insert_4ub_4f_rgba( const struct attr *a, char *v, 
+static void insert_1f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   
+   out[0] = in[0];
+   out[1] = 0;
+   out[2] = 0;
+   out[3] = 1;
+}
+
+static void insert_4chan_4f_rgba( const struct tnl_clipspace_attr *a, char *v, 
+                                 const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
+}
+
+static void insert_4ub_4f_rgba( const struct tnl_clipspace_attr *a, char *v, 
                                const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
@@ -130,7 +173,7 @@ static void insert_4ub_4f_rgba( const struct attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
 }
 
-static void insert_4ub_4f_bgra( const struct attr *a, char *v, 
+static void insert_4ub_4f_bgra( const struct tnl_clipspace_attr *a, char *v, 
                                const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
@@ -139,7 +182,7 @@ static void insert_4ub_4f_bgra( const struct attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
 }
 
-static void insert_3ub_3f_rgb( const struct attr *a, char *v, 
+static void insert_3ub_3f_rgb( const struct tnl_clipspace_attr *a, char *v, 
                               const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
@@ -147,7 +190,7 @@ static void insert_3ub_3f_rgb( const struct attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
 }
 
-static void insert_3ub_3f_bgr( const struct attr *a, char *v, 
+static void insert_3ub_3f_bgr( const struct tnl_clipspace_attr *a, char *v, 
                               const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
@@ -155,7 +198,7 @@ static void insert_3ub_3f_bgr( const struct attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
 }
 
-static void insert_1ub_1f( const struct attr *a, char *v, 
+static void insert_1ub_1f( const struct tnl_clipspace_attr *a, char *v, 
                           const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
@@ -169,7 +212,7 @@ static void insert_1ub_1f( const struct attr *a, char *v,
  * Currently always extracts a full 4 floats.
  */
 
-static void extract_4f_viewport( const struct attr *a, GLfloat *out, 
+static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                 const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
@@ -181,7 +224,7 @@ static void extract_4f_viewport( const struct attr *a, GLfloat *out,
    out[3] = in[3];
 }
 
-static void extract_3f_viewport( const struct attr *a, GLfloat *out, 
+static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                 const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
@@ -194,7 +237,7 @@ static void extract_3f_viewport( const struct attr *a, GLfloat *out,
 }
 
 
-static void extract_2f_viewport( const struct attr *a, GLfloat *out, 
+static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                 const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
@@ -207,7 +250,7 @@ static void extract_2f_viewport( const struct attr *a, GLfloat *out,
 }
 
 
-static void extract_4f( const struct attr *a, GLfloat *out, const char *v  )
+static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v  )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -217,7 +260,7 @@ static void extract_4f( const struct attr *a, GLfloat *out, const char *v  )
    out[3] = in[3];
 }
 
-static void extract_3f_xyw( const struct attr *a, GLfloat *out, const char *v )
+static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -228,7 +271,7 @@ static void extract_3f_xyw( const struct attr *a, GLfloat *out, const char *v )
 }
 
 
-static void extract_3f( const struct attr *a, GLfloat *out, const char *v )
+static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -239,7 +282,7 @@ static void extract_3f( const struct attr *a, GLfloat *out, const char *v )
 }
 
 
-static void extract_2f( const struct attr *a, GLfloat *out, const char *v )
+static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -249,7 +292,7 @@ static void extract_2f( const struct attr *a, GLfloat *out, const char *v )
    out[3] = 1;
 }
 
-static void extract_1f( const struct attr *a, GLfloat *out, const char *v )
+static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -259,50 +302,146 @@ static void extract_1f( const struct attr *a, GLfloat *out, const char *v )
    out[3] = 1;
 }
 
-static void extract_4ub_4f_rgba( const struct attr *a, GLfloat *out, 
+static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                 const char *v )
 {
-   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
+   GLchan *c = (GLchan *)v;
+
+   out[0] = CHAN_TO_FLOAT(c[0]);
+   out[1] = CHAN_TO_FLOAT(c[1]);
+   out[2] = CHAN_TO_FLOAT(c[2]);
+   out[3] = CHAN_TO_FLOAT(c[3]);
 }
 
-static void extract_4ub_4f_bgra( const struct attr *a, GLfloat *out, 
+static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                 const char *v )
 {
-   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
+   out[0] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[2] = UBYTE_TO_FLOAT(v[2]);
+   out[3] = UBYTE_TO_FLOAT(v[3]);
+}
+
+static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out, 
+                                const char *v )
+{
+   out[2] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[0] = UBYTE_TO_FLOAT(v[2]);
+   out[3] = UBYTE_TO_FLOAT(v[3]);
 }
 
-static void extract_3ub_3f_rgb( const struct attr *a, GLfloat *out, 
+static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                const char *v )
 {
-   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
+   out[0] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[2] = UBYTE_TO_FLOAT(v[2]);
    out[3] = 1;
 }
 
-static void extract_3ub_3f_bgr( const struct attr *a, GLfloat *out, 
+static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out, 
                                const char *v )
 {
-   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
-   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
+   out[2] = UBYTE_TO_FLOAT(v[0]);
+   out[1] = UBYTE_TO_FLOAT(v[1]);
+   out[0] = UBYTE_TO_FLOAT(v[2]);
    out[3] = 1;
 }
 
-static void extract_1ub_1f( const struct attr *a, GLfloat *out, const char *v )
+static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
 {
-   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   out[0] = UBYTE_TO_FLOAT(v[0]);
    out[1] = 0;
    out[2] = 0;
    out[3] = 1;
 }
 
+
+typedef void (*extract_func)( const struct tnl_clipspace_attr *a, GLfloat *out, 
+                             const char *v );
+
+typedef void (*insert_func)( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in );
+
+
+struct {
+   extract_func extract;
+   insert_func insert;
+   GLuint attrsize;
+} format_info[EMIT_MAX] = {
+
+   { extract_1f,
+     insert_1f,
+     sizeof(GLfloat) },
+
+   { extract_2f,
+     insert_2f,
+     2 * sizeof(GLfloat) },
+
+   { extract_3f,
+     insert_3f,
+     3 * sizeof(GLfloat) },
+
+   { extract_4f,
+     insert_4f,
+     4 * sizeof(GLfloat) },
+
+   { extract_2f_viewport,
+     insert_2f_viewport,
+     2 * sizeof(GLfloat) },
+
+   { extract_3f_viewport,
+     insert_3f_viewport,
+     3 * sizeof(GLfloat) },
+
+   { extract_4f_viewport,
+     insert_4f_viewport,
+     4 * sizeof(GLfloat) },
+
+   { extract_3f_xyw,
+     insert_3f_xyw,
+     3 * sizeof(GLfloat) },
+
+   { extract_1ub_1f,
+     insert_1ub_1f,
+     sizeof(GLubyte) },
+
+   { extract_3ub_3f_rgb,
+     insert_3ub_3f_rgb,
+     3 * sizeof(GLubyte) },
+
+   { extract_3ub_3f_bgr,
+     insert_3ub_3f_bgr,
+     3 * sizeof(GLubyte) },
+
+   { extract_4ub_4f_rgba,
+     insert_4ub_4f_rgba,
+     4 * sizeof(GLubyte) },
+
+   { extract_4ub_4f_bgra,
+     insert_4ub_4f_bgra,
+     4 * sizeof(GLubyte) },
+
+   { extract_4chan_4f_rgba,
+     insert_4chan_4f_rgba,
+     4 * sizeof(GLchan) },
+
+   { extract_1f,
+     insert_1f_pad,
+     4 * sizeof(GLfloat) },
+
+   { extract_2f,
+     insert_2f_pad,
+     4 * sizeof(GLfloat) },
+
+   { extract_3f,
+     insert_3f_pad,
+     4 * sizeof(GLfloat) },
+
+
+};
+     
+
 /***********************************************************************
  * Generic (non-codegen) functions for whole vertices or groups of
  * vertices
@@ -310,27 +449,30 @@ static void extract_1ub_1f( const struct attr *a, GLfloat *out, const char *v )
 
 static void generic_emit( GLcontext *ctx,
                          GLuint start, GLuint end,
-                         void *dest,
-                         GLuint stride )
+                         void *dest )
 {
-   int i, j;
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   struct tnl_clipspace_attr *a = vtx->attr;
    char *v = (char *)dest;
+   int i, j;
+   GLuint count = vtx->attr_count;
+   GLuint stride;
 
-   vtx->vertex_buf = v - start * stride;
-   vtx->vertex_stride = stride;
+   for (j = 0; j < count; j++) {
+      GLvector4f *vptr = VB->AttribPtr[a[j].attrib];
+      a[j].inputstride = vptr->stride;
+      a[j].inputptr = (GLfloat *)STRIDE_4F(vptr->data, start * vptr->stride);
+   }
 
    end -= start;
-
-   for (j = 0; j < vtx->attr_count; j++) {
-      GLvector4f *vptr = VB->AttrPtr[a[j].attrib];
-      a[j].inputptr = STRIDE_4F(vptr->data, start * vptr->stride);
-   }
+   stride = vtx->vertex_size;
 
    for (i = 0 ; i < end ; i++, v += stride) {
-      for (j = 0; j < vtx->attr_count; j++) {
-        int *in = a[j].inputptr;
+      for (j = 0; j < count; j++) {
+        GLfloat *in = a[j].inputptr;
         (char *)a[j].inputptr += a[j].inputstride;
-        a[j].out( &a[j], v + a[j].vertoffset, in );
+        a[j].insert( &a[j], v + a[j].vertoffset, in );
       }
    }
 }
@@ -341,26 +483,45 @@ static void generic_interp( GLcontext *ctx,
                            GLuint edst, GLuint eout, GLuint ein,
                            GLboolean force_boundary )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   char *vin  = vtx->vertex_buf + ein  * vtx->vertex_stride;
-   char *vout = vtx->vertex_buf + eout * vtx->vertex_stride;
-   char *vdst = vtx->vertex_buf + edst * vtx->vertex_stride;
-   const struct attr *a = vtx->attr;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   char *vin  = vtx->vertex_buf + ein  * vtx->vertex_size;
+   char *vout = vtx->vertex_buf + eout * vtx->vertex_size;
+   char *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
+   const struct tnl_clipspace_attr *a = vtx->attr;
    int attr_count = vtx->attr_count;
    int j;
-   
-   for (j = 0; j < attr_count; j++) {
+
+   if (tnl->NeedNdcCoords) {
+      const GLfloat *dstclip = VB->ClipPtr->data[edst];
+      const GLfloat w = 1.0 / dstclip[3];
+      GLfloat pos[4];
+
+      pos[0] = dstclip[0] * w;
+      pos[1] = dstclip[1] * w;
+      pos[2] = dstclip[2] * w;
+      pos[3] = w;
+
+      a[0].insert( &a[0], vdst, pos );
+   }
+   else {
+      a[0].insert( &a[0], vdst, VB->ClipPtr->data[edst] );
+   }
+
+
+   for (j = 1; j < attr_count; j++) {
       GLfloat fin[4], fout[4], fdst[4];
-      
-      a[j].extract( &a[j], vin, fin );
-      a[j].extract( &a[j], vout, fout );
+        
+      a[j].extract( &a[j], fin, vin + a[j].vertoffset );
+      a[j].extract( &a[j], fout, vout + a[j].vertoffset );
 
       INTERP_F( t, fdst[3], fout[3], fin[3] );
       INTERP_F( t, fdst[2], fout[2], fin[2] );
       INTERP_F( t, fdst[1], fout[1], fin[1] );
       INTERP_F( t, fdst[0], fout[0], fin[0] );
 
-      a[j].insert( &a[j], vdst, fdst );
+      a[j].insert( &a[j], vdst + a[j].vertoffset, fdst );
    }
 }
 
@@ -368,45 +529,77 @@ static void generic_interp( GLcontext *ctx,
 /* Extract color attributes from one vertex and insert them into
  * another.  (Shortcircuit extract/insert with memcpy).
  */
-static void generic_copy_colors( GLcontext *ctx, GLuint edst, GLuint esrc )
+static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   char *vsrc = vert_start + esrc * vert_stride;
-   char *vdst = vert_start + edst * vert_stride;
-   const struct attr *a = vtx->attr;
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   char *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
+   char *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
+   const struct tnl_clipspace_attr *a = vtx->attr;
    int attr_count = vtx->attr_count;
    int j;
 
    for (j = 0; j < attr_count; j++) {
-      if (a[j].attribute == VERT_ATTRIB_COLOR0 ||
-         a[j].attribute == VERT_ATTRIB_COLOR1) {
+      if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
+         a[j].attrib == VERT_ATTRIB_COLOR1) {
 
         memcpy( vdst + a[j].vertoffset,
                 vsrc + a[j].vertoffset,
                 a[j].vertattrsize );
+      }
    }
 }
 
-static void generic_get_attr( GLcontext *ctx, const char *vertex,
-                             GLenum attr, GLfloat *dest )
+
+/* Helper functions for hardware which doesn't put back colors and/or
+ * edgeflags into vertices.
+ */
+static void generic_interp_extras( GLcontext *ctx,
+                                  GLfloat t,
+                                  GLuint dst, GLuint out, GLuint in,
+                                  GLboolean force_boundary )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   const struct attr *a = vtx->attr;
-   int attr_count = vtx->attr_count;
-   int j;
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   for (j = 0; j < attr_count; j++) {
-      if (a[j].attribute == attr) {
-        a[j].extract( &a[j], vin, dest );
-        return;
+   if (VB->ColorPtr[1]) {
+      assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
+
+      INTERP_4F( t,
+                VB->ColorPtr[1]->data[dst],
+                VB->ColorPtr[1]->data[out],
+                VB->ColorPtr[1]->data[in] );
+
+      if (VB->SecondaryColorPtr[1]) {
+        INTERP_3F( t,
+                   VB->SecondaryColorPtr[1]->data[dst],
+                   VB->SecondaryColorPtr[1]->data[out],
+                   VB->SecondaryColorPtr[1]->data[in] );
       }
    }
 
-   /* Else return the value from ctx->Current
-    */
-   memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
+   if (VB->EdgeFlag) {
+      VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
+   }
+
+   generic_interp(ctx, t, dst, out, in, force_boundary);
 }
 
+static void generic_copy_pv_extras( GLcontext *ctx, 
+                                   GLuint dst, GLuint src )
+{
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+   if (VB->ColorPtr[1]) {
+      COPY_4FV( VB->ColorPtr[1]->data[dst], 
+               VB->ColorPtr[1]->data[src] );
+
+      if (VB->SecondaryColorPtr[1]) {
+        COPY_4FV( VB->SecondaryColorPtr[1]->data[dst], 
+                  VB->SecondaryColorPtr[1]->data[src] );
+      }
+   }
+
+   _tnl_copy_pv(ctx, dst, src);
+}
 
 
 
@@ -420,12 +613,11 @@ static void generic_get_attr( GLcontext *ctx, const char *vertex,
 
 static void choose_emit_func( GLcontext *ctx,
                              GLuint start, GLuint end,
-                             void *dest,
-                             GLuint stride )
+                             void *dest )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->emit_func = generic_emit_func;
-   vtx->emit_func( ctx, start, end, dest, stride );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   vtx->emit = generic_emit;
+   vtx->emit( ctx, start, end, dest );
 }
 
 
@@ -434,17 +626,31 @@ static void choose_interp_func( GLcontext *ctx,
                                GLuint edst, GLuint eout, GLuint ein,
                                GLboolean force_boundary )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->interp_func = generic_interp_func;
-   vtx->interp_func( ctx, t, edst, eout, ein, force_boundary );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+
+   if (vtx->need_extras && 
+       (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+      vtx->interp = generic_interp_extras;
+   } else {
+      vtx->interp = generic_interp;
+   }
+
+   vtx->interp( ctx, t, edst, eout, ein, force_boundary );
 }
 
 
-static void choose_copy_color_func(  GLcontext *ctx, GLuint edst, GLuint esrc )
+static void choose_copy_pv_func(  GLcontext *ctx, GLuint edst, GLuint esrc )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->copy_color_func = generic_copy_color_func;
-   vtx->copy_color_func( ctx, edst, esrc );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+
+   if (vtx->need_extras && 
+       (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+      vtx->copy_pv = generic_copy_pv_extras;
+   } else {
+      vtx->copy_pv = generic_copy_pv;
+   }
+
+   vtx->copy_pv( ctx, edst, esrc );
 }
 
 
@@ -452,14 +658,6 @@ static void choose_copy_color_func(  GLcontext *ctx, GLuint edst, GLuint esrc )
  * Public entrypoints, mostly dispatch to the above:
  */
 
-void _tnl_emit( GLcontext *ctx,
-               GLuint start, GLuint end,
-               void *dest,
-               GLuint stride )
-{
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->emit_func( ctx, start, end, dest, stride );
-}
 
 /* Interpolate between two vertices to produce a third:
  */
@@ -468,16 +666,16 @@ void _tnl_interp( GLcontext *ctx,
                  GLuint edst, GLuint eout, GLuint ein,
                  GLboolean force_boundary )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->interp_func( ctx, t, edst, eout, ein, force_boundary );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   vtx->interp( ctx, t, edst, eout, ein, force_boundary );
 }
 
 /* Copy colors from one vertex to another:
  */
-void _tnl_copy_colors(  GLcontext *ctx, GLuint edst, GLuint esrc )
+void _tnl_copy_pv(  GLcontext *ctx, GLuint edst, GLuint esrc )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->copy_color_func( ctx, edst, esrc );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   vtx->copy_pv( ctx, edst, esrc );
 }
 
 
@@ -485,117 +683,136 @@ void _tnl_copy_colors(  GLcontext *ctx, GLuint edst, GLuint esrc )
  * reverse any viewport transformation, swizzling or other conversions
  * which may have been applied:
  */
-void _tnl_get_attr( GLcontext *ctx, void *vertex, GLenum attrib,
-                   GLfloat *dest )
+void _tnl_get_attr( GLcontext *ctx, const void *vin,
+                             GLenum attr, GLfloat *dest )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
-   vtx->get_attr_func( ctx, vertex, attrib, dest );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   const struct tnl_clipspace_attr *a = vtx->attr;
+   int attr_count = vtx->attr_count;
+   int j;
+
+   for (j = 0; j < attr_count; j++) {
+      if (a[j].attrib == attr) {
+        a[j].extract( &a[j], dest, vin );
+        return;
+      }
+   }
+
+   /* Else return the value from ctx->Current
+    */
+   memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
 }
 
+void *_tnl_get_vertex( GLcontext *ctx, GLuint nr )
+{
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
 
+   return vtx->vertex_buf + nr * vtx->vertex_size;
+}
 
-void _tnl_install_attrs( GLcontext *ctx, const struct dri_attr_map *map,
+void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state )
+{
+   if (new_state & (_DD_NEW_TRI_LIGHT_TWOSIDE|_DD_NEW_TRI_UNFILLED) ) {
+      struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+      vtx->new_inputs = ~0;
+      vtx->interp = choose_interp_func;
+      vtx->copy_pv = choose_copy_pv_func;
+   }
+}
+
+
+GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map,
                         GLuint nr, const GLfloat *vp )
 {
-   struct dri_vertex_state *vtx = GET_VERTEX_STATE(ctx);
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   int offset = 0;
    int i;
 
-   assert(nr < _TNL_ATTR_MAX);
+   assert(nr < _TNL_ATTRIB_MAX);
+   assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);
 
    vtx->attr_count = nr;
-   vtx->emit_func = choose_emit_func;
-   vtx->interp_func = choose_interp_func;
-   vtx->copy_color_func = choose_copy_color_func;
-   vtx->get_attr_func = choose_get_attr_func;
+   vtx->emit = choose_emit_func;
+   vtx->interp = choose_interp_func;
+   vtx->copy_pv = choose_copy_pv_func;
+   vtx->new_inputs = ~0;
 
    for (i = 0; i < nr; i++) {
-      GLuint attrib = map[i].attrib;
+      GLuint format = map[i].format;
       vtx->attr[i].attrib = map[i].attrib;
-      vtx->attr[i].hw_format = map[i].hw_format;
+/*       vtx->attr[i].format = map[i].format; */
       vtx->attr[i].vp = vp;
-      vtx->attr[i].insert = attrib_info[attrib].insert;
-      vtx->attr[i].extract = attrib_info[attrib].extract;
-      vtx->attr[i].vertattrsize = attrib_info[attrib].attrsize;
+      vtx->attr[i].insert = format_info[format].insert;
+      vtx->attr[i].extract = format_info[format].extract;
+      vtx->attr[i].vertattrsize = format_info[format].attrsize;
       vtx->attr[i].vertoffset = offset;
-      offset += attrib_info[attrib].attrsize;
+      offset += format_info[format].attrsize;
    }
-}
 
+   assert(offset <= vtx->max_vertex_size);
+   
+   vtx->vertex_size = offset;
 
+   return vtx->vertex_size;
+}
 
 
-/* Populate a swrast SWvertex from an attrib-style vertex.
- */
-void _tnl_translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
+
+void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs )
 {
-   _tnl_get_attr( ctx, vertex, VERT_ATTRIB_POS, dest.win );
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   vtx->new_inputs |= newinputs;
+}
 
-   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
-      _tnl_get_attr( ctx, vertex, VERT_ATTRIB_TEX(i), dest.texcoord[i] );
-         
-   _tnl_get_attr( ctx, vertex, VERT_ATTRIB_COLOR0, tmp );
-   UNCLAMPED_FLOAT_TO_CHAN_RGBA( dest.color, tmp );
 
-   _tnl_get_attr( ctx, vertex, VERT_ATTRIB_COLOR1, tmp );
-   UNCLAMPED_FLOAT_TO_CHAN_RGB( dest.specular, tmp );
 
-   _tnl_get_attr( ctx, vertex, VERT_ATTRIB_FOG, tmp );
-   dest.fog = tmp[0];
+void _tnl_build_vertices( GLcontext *ctx,
+                      GLuint start,
+                      GLuint count,
+                      GLuint newinputs )
+{
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   GLuint stride = vtx->vertex_size;
+   GLubyte *v = ((GLubyte *)vtx->vertex_buf + (start*stride));
 
-   _tnl_get_attr( ctx, vertex, VERT_ATTRIB_INDEX, tmp );
-   dest.index = (GLuint) tmp[0];
+   newinputs |= vtx->new_inputs;
+   vtx->new_inputs = 0;
 
-   _tnl_get_attr( ctx, vertex, VERT_ATTRIB_POINTSIZE, tmp );
-   dest.pointSize = tmp[0];
+   if (newinputs)
+      vtx->emit( ctx, start, count, v );
 }
 
 
-static void interp_extras( GLcontext *ctx,
-                          GLfloat t,
-                          GLuint dst, GLuint out, GLuint in,
-                          GLboolean force_boundary )
+void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
+                                  GLuint start,
+                                  GLuint count,
+                                  void *dest )
 {
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   vtx->emit( ctx, start, count, dest );
+   return (void *)((char *)dest + vtx->vertex_size * (count - start));
+}
 
-   if (VB->ColorPtr[1]) {
-      assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
 
-      INTERP_4F( t,
-                GET_COLOR(VB->ColorPtr[1], dst),
-                GET_COLOR(VB->ColorPtr[1], out),
-                GET_COLOR(VB->ColorPtr[1], in) );
+void _tnl_init_vertices( GLcontext *ctx, 
+                       GLuint vb_size,
+                       GLuint max_vertex_size )
+{
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);  
 
-      if (VB->SecondaryColorPtr[1]) {
-        INTERP_3F( t,
-                   GET_COLOR(VB->SecondaryColorPtr[1], dst),
-                   GET_COLOR(VB->SecondaryColorPtr[1], out),
-                   GET_COLOR(VB->SecondaryColorPtr[1], in) );
-      }
-   }
+   _tnl_install_attrs( ctx, 0, 0, 0 );
 
-   if (VB->EdgeFlag) {
-      VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
-   }
-
-   generic_interp(ctx, t, dst, out, in, force_boundary);
+   vtx->need_extras = GL_TRUE;
+   vtx->max_vertex_size = max_vertex_size;
+   vtx->vertex_buf = (char *)ALIGN_MALLOC(vb_size * 4 * 18, max_vertex_size);
 }
 
-static void copy_pv_extras( GLcontext *ctx, 
-                           GLuint dst, GLuint src )
-{
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
-
-   if (VB->ColorPtr[1]) {
-      COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), 
-               GET_COLOR(VB->ColorPtr[1], src) );
 
-      if (VB->SecondaryColorPtr[1]) {
-        COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), 
-                  GET_COLOR(VB->SecondaryColorPtr[1], src) );
-      }
+void _tnl_free_vertices( GLcontext *ctx )
+{
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   if (vtx->vertex_buf) {
+      ALIGN_FREE(vtx->vertex_buf);
+      vtx->vertex_buf = 0;
    }
-
-   generic_copy_colors(ctx, dst, src);
 }
-
-#endif
index 26f2619c52b029c1e2b8973cb35756450d1f9bf9..050f525e295fab875523de1756ab944239d880ee 100644 (file)
  * and manipulate them directly.  
  */
 
+
+/* It will probably be necessary to allow drivers to specify new
+ * emit-styles to cover all the wierd and wacky things out there.
+ */
 enum tnl_attr_format {
-   EMIT_1F = 1,
-   EMIT_2F = 2,
-   EMIT_3F = 3,
-   EMIT_4F = 4,
+   EMIT_1F,
+   EMIT_2F,
+   EMIT_3F,
+   EMIT_4F,
    EMIT_2F_VIEWPORT,           /* do viewport transform and emit */
    EMIT_3F_VIEWPORT,           /* do viewport transform and emit */
    EMIT_4F_VIEWPORT,           /* do viewport transform and emit */
@@ -46,22 +50,19 @@ enum tnl_attr_format {
    EMIT_3UB_3F_RGB,            /* for specular color */
    EMIT_4UB_4F_BGRA,           /* for color */
    EMIT_4UB_4F_RGBA,           /* for color */
-   EMIT_NOP_1F,
-   EMIT_NOP_1UB,
+   EMIT_4CHAN_4F_RGBA,         /* for swrast color */
+   EMIT_1F_PAD_4F,             /* for swrast texcoords */
+   EMIT_2F_PAD_4F,             /* for swrast texcoords */
+   EMIT_3F_PAD_4F,             /* for swrast texcoords */
+   EMIT_MAX
 };
 
 struct tnl_attr_map {
-   GLuint attr;                        /* VERT_ATTRIB_ enum */
+   GLuint attrib;                      /* _TNL_ATTRIB_ enum */
    enum tnl_attr_format format;
 };
    
 
-/* Emit hardware vertices to a given buffer:
- */
-extern void _tnl_emit( GLcontext *ctx,
-                      GLuint start, GLuint end,
-                      void *dest,
-                      GLuint stride );
 
 /* Interpolate between two vertices to produce a third:
  */
@@ -72,21 +73,47 @@ extern void _tnl_interp( GLcontext *ctx,
 
 /* Copy colors from one vertex to another:
  */
-extern void _tnl_copy_colors(  GLcontext *ctx, GLuint edst, GLuint esrc );
+extern void _tnl_copy_pv(  GLcontext *ctx, GLuint edst, GLuint esrc );
 
 
 /* Extract a named attribute from a hardware vertex.  Will have to
  * reverse any viewport transformation, swizzling or other conversions
  * which may have been applied:
  */
-extern void _tnl_get_attr( GLcontext *ctx, void *vertex, GLenum attrib,
+extern void _tnl_get_attr( GLcontext *ctx, const void *vertex, GLenum attrib,
                           GLfloat *dest );
 
-/* Populate a swrast SWvertex from an attrib-style vertex.
+extern void *_tnl_get_vertex( GLcontext *ctx, GLuint nr );
+
+
+/*
  */
-extern void _tnl_translate( GLcontext *ctx, const void *vertex, 
-                           SWvertex *dest );
+extern GLuint _tnl_install_attrs( GLcontext *ctx,
+                                 const struct tnl_attr_map *map,
+                                 GLuint nr, const GLfloat *vp );
+
+
+
+
+extern void _tnl_free_vertices( GLcontext *ctx );
+
+extern void _tnl_init_vertices( GLcontext *ctx, 
+                               GLuint vb_size,
+                               GLuint max_vertex_size );
+
+extern void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
+                                          GLuint start,
+                                          GLuint count,
+                                          void *dest );
+
+extern void _tnl_build_vertices( GLcontext *ctx,
+                                GLuint start,
+                                GLuint count,
+                                GLuint newinputs );
+
+extern void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs );
 
+extern void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state );
 
 
 #endif
index 349a8c7d605f8ea93d05219709c7ac69798c2db8..9a2241d8fce5e1479d7c8e38eef571d409994c4c 100644 (file)
@@ -74,4 +74,5 @@ _tnl_need_dlist_norm_lengths( GLcontext *ctx, GLboolean flag );
 extern void
 _tnl_isolate_materials( GLcontext *ctx, GLboolean flag );
 
+
 #endif