Fixed MAXFIFO_S4. Removed WAIT_IDLE_EMPTY from savage_BCI_swap which resulted
[mesa.git] / src / mesa / tnl / t_vertex.c
index 6ac9f8a90c5e8ad9ecb6bca1cc8d6ee09fb25ab8..fc076190e464aa99ca9eb0f93091559867ceaab9 100644 (file)
 
 
 
+
 #define GET_VERTEX_STATE(ctx)  &(TNL_CONTEXT(ctx)->clipspace)
 
-static void insert_4f_viewport( const struct tnl_clipspace_attr *a, char *v,
-                               const GLfloat *in )
+
+/*
+ * These functions take the NDC coordinates pointed to by 'in', apply the
+ * NDC->Viewport mapping and store the results at 'v'.
+ */
+
+static void
+insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
+                      const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)v;
    const GLfloat * const vp = a->vp;
@@ -56,7 +64,7 @@ static void insert_4f_viewport( const struct tnl_clipspace_attr *a, char *v,
    out[3] = in[3];
 }
 
-static void insert_3f_viewport( const struct tnl_clipspace_attr *a, char *v,
+static void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
                                const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)v;
@@ -65,9 +73,10 @@ static void insert_3f_viewport( const struct tnl_clipspace_attr *a, char *v,
    out[0] = vp[0] * in[0] + vp[12];
    out[1] = vp[5] * in[1] + vp[13];
    out[2] = vp[10] * in[2] + vp[14];
+   out[3] = 1;
 }
 
-static void insert_2f_viewport( const struct tnl_clipspace_attr *a, char *v,
+static void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
                                const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)v;
@@ -75,10 +84,81 @@ static void insert_2f_viewport( const struct tnl_clipspace_attr *a, char *v,
    
    out[0] = vp[0] * in[0] + vp[12];
    out[1] = vp[5] * in[1] + vp[13];
+   out[2] = vp[14];
+   out[3] = 1;
 }
 
+static void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
+                               const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat * const vp = a->vp;
+   
+   out[0] = vp[0] * in[0] + vp[12];
+   out[1] = vp[13];
+   out[2] = vp[14];
+   out[3] = 1;
+}
+
+static void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
+                               const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat * const vp = a->vp;
+   
+   out[0] = vp[0] * in[0] + vp[12];
+   out[1] = vp[5] * in[1] + vp[13];
+   out[2] = vp[10] * in[2] + vp[14];
+}
 
-static void insert_4f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
+                               const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat * const vp = a->vp;
+   
+   out[0] = vp[0] * in[0] + vp[12];
+   out[1] = vp[5] * in[1] + vp[13];
+   out[2] = vp[10] * in[2] + vp[14];
+}
+
+static void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
+                               const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat * const vp = a->vp;
+   
+   out[0] = vp[0] * in[0] + vp[12];
+   out[1] = vp[13];
+   out[2] = vp[14];
+}
+
+static void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
+                               const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat * const vp = a->vp;
+   
+   out[0] = vp[0] * in[0] + vp[12];
+   out[1] = vp[5] * in[1] + vp[13];
+}
+
+static void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
+                               const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)v;
+   const GLfloat * const vp = a->vp;
+   
+   out[0] = vp[0] * in[0] + vp[12];
+   out[1] = vp[13];
+}
+
+
+/*
+ * These functions do the same as above, except for the viewport mapping.
+ */
+
+static void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
@@ -88,73 +168,102 @@ static void insert_4f( const struct tnl_clipspace_attr *a, char *v, const GLfloa
    out[3] = in[3];
 }
 
-static void insert_3f_xyw( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
    out[0] = in[0];
    out[1] = in[1];
-   out[2] = in[3];
+   out[2] = in[2];
+   out[3] = 1;
 }
 
-
-static void insert_3f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
    out[0] = in[0];
    out[1] = in[1];
-   out[2] = in[2];
+   out[2] = 0;
+   out[3] = 1;
 }
 
-
-static void insert_2f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
    out[0] = in[0];
-   out[1] = in[1];
+   out[1] = 0;
+   out[2] = 0;
+   out[3] = 1;
 }
 
-static void insert_1f( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
 {
    GLfloat *out = (GLfloat *)(v);
    
    out[0] = in[0];
+   out[1] = in[1];
+   out[2] = in[3];
+}
+
+static void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
+{
+   abort();
 }
 
-static void insert_3f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *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_2f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *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_1f_pad( const struct tnl_clipspace_attr *a, char *v, const GLfloat *in )
+static void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *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, 
+
+static void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   
+   out[0] = in[0];
+   out[1] = in[1];
+}
+
+static void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   
+   out[0] = in[0];
+   out[1] = 0;
+}
+
+static void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
+{
+   GLfloat *out = (GLfloat *)(v);
+   
+   out[0] = in[0];
+}
+
+static void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
                                  const GLfloat *in )
 {
    GLchan *c = (GLchan *)v;
@@ -164,7 +273,37 @@ static void insert_4chan_4f_rgba( const struct tnl_clipspace_attr *a, char *v,
    UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
 }
 
-static void insert_4ub_4f_rgba( const struct tnl_clipspace_attr *a, char *v, 
+static void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *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]); 
+   c[3] = CHAN_MAX;
+}
+
+static void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                                 const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 
+   c[2] = 0;
+   c[3] = CHAN_MAX;
+}
+
+static void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                                 const GLfloat *in )
+{
+   GLchan *c = (GLchan *)v;
+   UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 
+   c[1] = 0;
+   c[2] = 0;
+   c[3] = CHAN_MAX;
+}
+
+static void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
                                const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
@@ -173,7 +312,34 @@ static void insert_4ub_4f_rgba( const struct tnl_clipspace_attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
 }
 
-static void insert_4ub_4f_bgra( const struct tnl_clipspace_attr *a, char *v, 
+static void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
+   v[3] = 0xff;
+}
+
+static void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[2] = 0;
+   v[3] = 0xff;
+}
+
+static void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   v[1] = 0;
+   v[2] = 0;
+   v[3] = 0xff;
+}
+
+static void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v, 
                                const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
@@ -182,7 +348,34 @@ static void insert_4ub_4f_bgra( const struct tnl_clipspace_attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
 }
 
-static void insert_3ub_3f_rgb( const struct tnl_clipspace_attr *a, char *v, 
+static void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
+   v[3] = 0xff;
+}
+
+static void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[0] = 0;
+   v[3] = 0xff;
+}
+
+static void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   v[1] = 0;
+   v[0] = 0;
+   v[3] = 0xff;
+}
+
+static void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
                               const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
@@ -190,15 +383,48 @@ static void insert_3ub_3f_rgb( const struct tnl_clipspace_attr *a, char *v,
    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
 }
 
-static void insert_3ub_3f_bgr( const struct tnl_clipspace_attr *a, char *v, 
+static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                              const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[2] = 0;
+}
+
+static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
                               const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
+   v[1] = 0;
+   v[2] = 0;
+}
+
+static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                                const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
    UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
 }
 
-static void insert_1ub_1f( const struct tnl_clipspace_attr *a, char *v, 
+static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                                const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
+   v[0] = 0;
+}
+
+static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
+                                const GLfloat *in )
+{
+   UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
+   v[1] = 0;
+   v[0] = 0;
+}
+
+
+static void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, 
                           const GLfloat *in )
 {
    UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
@@ -213,11 +439,14 @@ static void insert_1ub_1f( const struct tnl_clipspace_attr *a, char *v,
  */
 
 static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                                const char *v )
+                                const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    const GLfloat * const vp = a->vp;
    
+   /* Although included for completeness, the position coordinate is
+    * usually handled differently during clipping.
+    */
    out[0] = (in[0] - vp[12]) / vp[0];
    out[1] = (in[1] - vp[13]) / vp[5];
    out[2] = (in[2] - vp[14]) / vp[10];
@@ -225,7 +454,7 @@ static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *ou
 }
 
 static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                                const char *v )
+                                const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    const GLfloat * const vp = a->vp;
@@ -238,7 +467,7 @@ static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *ou
 
 
 static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                                const char *v )
+                                const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    const GLfloat * const vp = a->vp;
@@ -250,7 +479,7 @@ static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *ou
 }
 
 
-static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v  )
+static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v  )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -260,18 +489,18 @@ static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const
    out[3] = in[3];
 }
 
-static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
+static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
    out[0] = in[0];
    out[1] = in[1];
-   out[2] = in[3];
-   out[3] = 1;
+   out[2] = 0;
+   out[3] = in[2];
 }
 
 
-static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
+static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -282,7 +511,7 @@ static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const
 }
 
 
-static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
+static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -292,7 +521,7 @@ static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const
    out[3] = 1;
 }
 
-static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
+static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
 {
    const GLfloat *in = (const GLfloat *)v;
    
@@ -303,7 +532,7 @@ static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const
 }
 
 static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                                const char *v )
+                                const GLubyte *v )
 {
    GLchan *c = (GLchan *)v;
 
@@ -314,7 +543,7 @@ static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *
 }
 
 static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                                const char *v )
+                                const GLubyte *v )
 {
    out[0] = UBYTE_TO_FLOAT(v[0]);
    out[1] = UBYTE_TO_FLOAT(v[1]);
@@ -323,7 +552,7 @@ static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *ou
 }
 
 static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                                const char *v )
+                                const GLubyte *v )
 {
    out[2] = UBYTE_TO_FLOAT(v[0]);
    out[1] = UBYTE_TO_FLOAT(v[1]);
@@ -332,7 +561,7 @@ static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *ou
 }
 
 static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                               const char *v )
+                               const GLubyte *v )
 {
    out[0] = UBYTE_TO_FLOAT(v[0]);
    out[1] = UBYTE_TO_FLOAT(v[1]);
@@ -341,7 +570,7 @@ static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out
 }
 
 static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out, 
-                               const char *v )
+                               const GLubyte *v )
 {
    out[2] = UBYTE_TO_FLOAT(v[0]);
    out[1] = UBYTE_TO_FLOAT(v[1]);
@@ -349,7 +578,7 @@ static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out
    out[3] = 1;
 }
 
-static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const char *v )
+static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
 {
    out[0] = UBYTE_TO_FLOAT(v[0]);
    out[1] = 0;
@@ -358,86 +587,96 @@ static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, co
 }
 
 
-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 {
+   const char *name;
    extract_func extract;
-   insert_func insert;
-   GLuint attrsize;
+   insert_func insert[4];
+   const GLuint attrsize;
 } format_info[EMIT_MAX] = {
 
-   { extract_1f,
-     insert_1f,
+   { "1f",
+     extract_1f,
+     { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
      sizeof(GLfloat) },
 
-   { extract_2f,
-     insert_2f,
+   { "2f",
+     extract_2f,
+     { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
      2 * sizeof(GLfloat) },
 
-   { extract_3f,
-     insert_3f,
+   { "3f",
+     extract_3f,
+     { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
      3 * sizeof(GLfloat) },
 
-   { extract_4f,
-     insert_4f,
+   { "4f",
+     extract_4f,
+     { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
      4 * sizeof(GLfloat) },
 
-   { extract_2f_viewport,
-     insert_2f_viewport,
+   { "2f_viewport",
+     extract_2f_viewport,
+     { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
+       insert_2f_viewport_2 },
      2 * sizeof(GLfloat) },
 
-   { extract_3f_viewport,
-     insert_3f_viewport,
+   { "3f_viewport",
+     extract_3f_viewport,
+     { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
+       insert_3f_viewport_3 },
      3 * sizeof(GLfloat) },
 
-   { extract_4f_viewport,
-     insert_4f_viewport,
+   { "4f_viewport",
+     extract_4f_viewport,
+     { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
+       insert_4f_viewport_4 }, 
      4 * sizeof(GLfloat) },
 
-   { extract_3f_xyw,
-     insert_3f_xyw,
+   { "3f_xyw",
+     extract_3f_xyw,
+     { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, 
+       insert_3f_xyw_4 },
      3 * sizeof(GLfloat) },
 
-   { extract_1ub_1f,
-     insert_1ub_1f,
+   { "1ub_1f",
+     extract_1ub_1f,
+     { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
      sizeof(GLubyte) },
 
-   { extract_3ub_3f_rgb,
-     insert_3ub_3f_rgb,
+   { "3ub_3f_rgb",
+     extract_3ub_3f_rgb,
+     { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
+       insert_3ub_3f_rgb_3 },
      3 * sizeof(GLubyte) },
 
-   { extract_3ub_3f_bgr,
-     insert_3ub_3f_bgr,
+   { "3ub_3f_bgr",
+     extract_3ub_3f_bgr,
+     { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
+       insert_3ub_3f_bgr_3 },
      3 * sizeof(GLubyte) },
 
-   { extract_4ub_4f_rgba,
-     insert_4ub_4f_rgba,
+   { "4ub_4f_rgba",
+     extract_4ub_4f_rgba,
+     { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, 
+       insert_4ub_4f_rgba_4 },
      4 * sizeof(GLubyte) },
 
-   { extract_4ub_4f_bgra,
-     insert_4ub_4f_bgra,
+   { "4ub_4f_bgra",
+     extract_4ub_4f_bgra,
+     { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
+       insert_4ub_4f_bgra_4 },
      4 * sizeof(GLubyte) },
 
-   { extract_4chan_4f_rgba,
-     insert_4chan_4f_rgba,
+   { "4chan_4f_rgba",
+     extract_4chan_4f_rgba,
+     { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
+       insert_4chan_4f_rgba_4 },
      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) },
-
+   { "pad",
+     0,
+     { 0, 0, 0, 0 },
+     0 }
 
 };
      
@@ -454,15 +693,16 @@ static void generic_emit( GLcontext *ctx,
    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;
+   GLubyte *v = (GLubyte *)dest;
+   GLuint i, j;
+   const GLuint count = vtx->attr_count;
    GLuint 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);
+      a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
+      a[j].emit = a[j].insert[vptr->size - 1];
    }
 
    end -= start;
@@ -470,9 +710,9 @@ static void generic_emit( GLcontext *ctx,
 
    for (i = 0 ; i < end ; i++, v += stride) {
       for (j = 0; j < count; j++) {
-        GLfloat *in = a[j].inputptr;
-        (char *)a[j].inputptr += a[j].inputstride;
-        a[j].insert( &a[j], v + a[j].vertoffset, in );
+        GLfloat *in = (GLfloat *)a[j].inputptr;
+        a[j].inputptr += a[j].inputstride;
+        a[j].emit( &a[j], v + a[j].vertoffset, in );
       }
    }
 }
@@ -486,27 +726,29 @@ static void generic_interp( GLcontext *ctx,
    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 GLubyte *vin  = vtx->vertex_buf + ein  * vtx->vertex_size;
+   const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
+   GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
    const struct tnl_clipspace_attr *a = vtx->attr;
-   int attr_count = vtx->attr_count;
-   int j;
+   const GLuint attr_count = vtx->attr_count;
+   GLuint j;
 
    if (tnl->NeedNdcCoords) {
       const GLfloat *dstclip = VB->ClipPtr->data[edst];
-      const GLfloat w = 1.0 / dstclip[3];
-      GLfloat pos[4];
+      if (dstclip[3] != 0.0) {
+        const GLfloat w = 1.0f / dstclip[3];
+        GLfloat pos[4];
 
-      pos[0] = dstclip[0] * w;
-      pos[1] = dstclip[1] * w;
-      pos[2] = dstclip[2] * w;
-      pos[3] = w;
+        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 );
+        a[0].insert[4-1]( &a[0], vdst, pos );
+      }
    }
    else {
-      a[0].insert( &a[0], vdst, VB->ClipPtr->data[edst] );
+      a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
    }
 
 
@@ -521,7 +763,7 @@ static void generic_interp( GLcontext *ctx,
       INTERP_F( t, fdst[1], fout[1], fin[1] );
       INTERP_F( t, fdst[0], fout[0], fin[0] );
 
-      a[j].insert( &a[j], vdst + a[j].vertoffset, fdst );
+      a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
    }
 }
 
@@ -532,19 +774,19 @@ static void generic_interp( GLcontext *ctx,
 static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
 {
    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;
+   GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
+   GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
    const struct tnl_clipspace_attr *a = vtx->attr;
-   int attr_count = vtx->attr_count;
-   int j;
+   const GLuint attr_count = vtx->attr_count;
+   GLuint j;
 
    for (j = 0; j < attr_count; j++) {
       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 );
+        _mesa_memcpy( vdst + a[j].vertoffset,
+                       vsrc + a[j].vertoffset,
+                       a[j].vertattrsize );
       }
    }
 }
@@ -575,6 +817,11 @@ static void generic_interp_extras( GLcontext *ctx,
                    VB->SecondaryColorPtr[1]->data[in] );
       }
    }
+   else if (VB->IndexPtr[1]) {
+      VB->IndexPtr[1]->data[dst][0] = LINTERP( t,
+                                              VB->IndexPtr[1]->data[out][0],
+                                              VB->IndexPtr[1]->data[in][0] );
+   }
 
    if (VB->EdgeFlag) {
       VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
@@ -597,15 +844,16 @@ static void generic_copy_pv_extras( GLcontext *ctx,
                   VB->SecondaryColorPtr[1]->data[src] );
       }
    }
+   else if (VB->IndexPtr[1]) {
+      VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
+   }
 
-   _tnl_copy_pv(ctx, dst, src);
+   generic_copy_pv(ctx, dst, src);
 }
 
 
 
 
-
-
 /***********************************************************************
  * Build codegen functions or return generic ones:
  */
@@ -688,21 +936,41 @@ void _tnl_get_attr( GLcontext *ctx, const void *vin,
 {
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
    const struct tnl_clipspace_attr *a = vtx->attr;
-   int attr_count = vtx->attr_count;
-   int j;
+   const GLuint attr_count = vtx->attr_count;
+   GLuint j;
 
    for (j = 0; j < attr_count; j++) {
-      if (a[j].attrib == attr) {
-        a[j].extract( &a[j], dest, vin );
+      if (a[j].attrib == (int)attr) {
+        a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset );
         return;
       }
    }
 
-   /* Else return the value from ctx->Current
+   /* Else return the value from ctx->Current -- dangerous???
     */
-   memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
+   _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
+}
+
+
+/* Complementary operation to the above.
+ */
+void _tnl_set_attr( GLcontext *ctx, void *vout,
+                   GLenum attr, const GLfloat *src )
+{
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   const struct tnl_clipspace_attr *a = vtx->attr;
+   const GLuint attr_count = vtx->attr_count;
+   GLuint j;
+
+   for (j = 0; j < attr_count; j++) {
+      if (a[j].attrib == (int)attr) {
+        a[j].insert[4-1]( &a[j], (GLubyte *)vout + a[j].vertoffset, src );
+        return;
+      }
+   }
 }
 
+
 void *_tnl_get_vertex( GLcontext *ctx, GLuint nr )
 {
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
@@ -722,37 +990,59 @@ void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state )
 
 
 GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map,
-                        GLuint nr, const GLfloat *vp )
+                          GLuint nr, const GLfloat *vp, 
+                          GLuint unpacked_size )
 {
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
-   int offset = 0;
-   int i;
+   GLuint offset = 0;
+   GLuint i, j;
 
    assert(nr < _TNL_ATTRIB_MAX);
    assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);
 
-   vtx->attr_count = nr;
    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 format = map[i].format;
-      vtx->attr[i].attrib = map[i].attrib;
-/*       vtx->attr[i].format = map[i].format; */
-      vtx->attr[i].vp = vp;
-      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 += format_info[format].attrsize;
+   for (j = 0, i = 0; i < nr; i++) {
+      const GLuint format = map[i].format;
+      if (format == EMIT_PAD) {
+        offset += map[i].offset;
+
+/*      fprintf(stderr, "%d: pad %d, offset now %d\n", i,   */
+/*              map[i].offset, offset);   */
+
+      }
+      else {
+        vtx->attr[j].attrib = map[i].attrib;
+        vtx->attr[j].vp = vp;
+        vtx->attr[j].insert = format_info[format].insert;
+        vtx->attr[j].extract = format_info[format].extract;
+        vtx->attr[j].vertattrsize = format_info[format].attrsize;
+
+        if (unpacked_size) 
+           vtx->attr[j].vertoffset = map[i].offset;
+        else
+           vtx->attr[j].vertoffset = offset;
+        
+/*      fprintf(stderr, "%d: %s offset %d\n", i,  */
+/*              format_info[format].name, vtx->attr[j].vertoffset);   */
+        
+        offset += format_info[format].attrsize;
+        j++;
+      }
    }
 
-   assert(offset <= vtx->max_vertex_size);
-   
-   vtx->vertex_size = offset;
+   vtx->attr_count = j;
+
+   if (unpacked_size)
+      vtx->vertex_size = unpacked_size;
+   else
+      vtx->vertex_size = offset;
 
+   assert(vtx->vertex_size <= vtx->max_vertex_size);
+   
    return vtx->vertex_size;
 }
 
@@ -767,30 +1057,30 @@ void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs )
 
 
 void _tnl_build_vertices( GLcontext *ctx,
-                      GLuint start,
-                      GLuint count,
-                      GLuint newinputs )
+                         GLuint start,
+                         GLuint end,
+                         GLuint newinputs )
 {
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
-   GLuint stride = vtx->vertex_size;
-   GLubyte *v = ((GLubyte *)vtx->vertex_buf + (start*stride));
+   const GLuint stride = vtx->vertex_size;
+   GLubyte *vDest = ((GLubyte *)vtx->vertex_buf + (start*stride));
 
    newinputs |= vtx->new_inputs;
    vtx->new_inputs = 0;
 
    if (newinputs)
-      vtx->emit( ctx, start, count, v );
+      vtx->emit( ctx, start, end, vDest );
 }
 
 
 void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
-                                  GLuint start,
-                                  GLuint count,
-                                  void *dest )
+                                   GLuint start,
+                                   GLuint end,
+                                   void *dest )
 {
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
-   vtx->emit( ctx, start, count, dest );
-   return (void *)((char *)dest + vtx->vertex_size * (count - start));
+   vtx->emit( ctx, start, end, dest );
+   return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start));
 }
 
 
@@ -800,11 +1090,14 @@ void _tnl_init_vertices( GLcontext *ctx,
 {
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);  
 
-   _tnl_install_attrs( ctx, 0, 0, 0 );
+   _tnl_install_attrs( ctx, 0, 0, 0, 0 );
 
    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);
+   if (max_vertex_size > vtx->max_vertex_size) {
+      _tnl_free_vertices( ctx );
+      vtx->max_vertex_size = max_vertex_size;
+      vtx->vertex_buf = (GLubyte *)ALIGN_CALLOC(vb_size * max_vertex_size, 32 );
+   }
 }