Another vertex program checkpoint: clean-up of vertex attribute storage
authorBrian Paul <brian.paul@tungstengraphics.com>
Sun, 6 Jan 2002 03:54:12 +0000 (03:54 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sun, 6 Jan 2002 03:54:12 +0000 (03:54 +0000)
in vertex_buffer.   Improved vertex program pipeline stage such that
output registers can be processed in a loop.  Getting closer to where
we need to be in order to implement performance optimizations...

src/mesa/main/mtypes.h
src/mesa/swrast_setup/ss_vbtmp.h
src/mesa/tnl/t_array_import.c
src/mesa/tnl/t_context.h
src/mesa/tnl/t_imm_elt.c
src/mesa/tnl/t_imm_exec.c
src/mesa/tnl/t_imm_fixup.c
src/mesa/tnl/t_vb_fog.c
src/mesa/tnl/t_vb_points.c
src/mesa/tnl/t_vb_program.c

index f6a3391215e4829d1ec114d5e1d02e43b5d30753..6c9684ebeba30693e95554a7e5463ddaffff3ba1 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: mtypes.h,v 1.58 2002/01/05 21:53:20 brianp Exp $ */
+/* $Id: mtypes.h,v 1.59 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -1156,40 +1156,6 @@ struct gl_evaluators {
 #define VP_PROG_REG_START   (VP_TEMP_REG_END + 1)
 #define VP_PROG_REG_END     (VP_PROG_REG_START + VP_NUM_PROG_REGS - 1)
 
-/* Input register names */
-#define VP_IN_OPOS (VP_INPUT_REG_START + 0)
-#define VP_IN_WGHT (VP_INPUT_REG_START + 1)
-#define VP_IN_NRML (VP_INPUT_REG_START + 2)
-#define VP_IN_COL0 (VP_INPUT_REG_START + 3)
-#define VP_IN_COL1 (VP_INPUT_REG_START + 4)
-#define VP_IN_FOGC (VP_INPUT_REG_START + 5)
-#define VP_IN_TEX0 (VP_INPUT_REG_START + 8)
-#define VP_IN_TEX1 (VP_INPUT_REG_START + 9)
-#define VP_IN_TEX2 (VP_INPUT_REG_START + 10)
-#define VP_IN_TEX3 (VP_INPUT_REG_START + 11)
-#define VP_IN_TEX4 (VP_INPUT_REG_START + 12)
-#define VP_IN_TEX5 (VP_INPUT_REG_START + 13)
-#define VP_IN_TEX6 (VP_INPUT_REG_START + 14)
-#define VP_IN_TEX7 (VP_INPUT_REG_START + 15)
-
-/* Output register names */
-#define VP_OUT_HPOS (VP_OUTPUT_REG_START + 0)
-#define VP_OUT_COL0 (VP_OUTPUT_REG_START + 1)
-#define VP_OUT_COL1 (VP_OUTPUT_REG_START + 2)
-#define VP_OUT_BFC0 (VP_OUTPUT_REG_START + 3)
-#define VP_OUT_BFC1 (VP_OUTPUT_REG_START + 4)
-#define VP_OUT_FOGC (VP_OUTPUT_REG_START + 5)
-#define VP_OUT_PSIZ (VP_OUTPUT_REG_START + 6)
-#define VP_OUT_TEX0 (VP_OUTPUT_REG_START + 7)
-#define VP_OUT_TEX1 (VP_OUTPUT_REG_START + 8)
-#define VP_OUT_TEX2 (VP_OUTPUT_REG_START + 9)
-#define VP_OUT_TEX3 (VP_OUTPUT_REG_START + 10)
-#define VP_OUT_TEX4 (VP_OUTPUT_REG_START + 11)
-#define VP_OUT_TEX5 (VP_OUTPUT_REG_START + 12)
-#define VP_OUT_TEX6 (VP_OUTPUT_REG_START + 13)
-#define VP_OUT_TEX7 (VP_OUTPUT_REG_START + 14)
-
-
 
 /* Machine state (i.e. the register file) */
 struct vp_machine
index 8e6c41ab4dbfa990740510cef4bd0f8e2fe68c73..01382d33541d7755923625d3650deb3bdd026ab9 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: ss_vbtmp.h,v 1.19 2002/01/05 20:51:12 brianp Exp $ */
+/* $Id: ss_vbtmp.h,v 1.20 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -77,8 +77,8 @@ static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
    proj_stride = VB->NdcPtr->stride;
 
    if (IND & FOG) {
-      fog = (GLfloat *) VB->AttribPtr[VERT_ATTRIB_FOG]->data;
-      fog_stride = VB->AttribPtr[VERT_ATTRIB_FOG]->stride;
+      fog = (GLfloat *) VB->FogCoordPtr->data;
+      fog_stride = VB->FogCoordPtr->stride;
    }
    if (IND & COLOR) {
       if (VB->ColorPtr[0]->Type != CHAN_TYPE)
@@ -99,7 +99,7 @@ static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
       index_stride = VB->IndexPtr[0]->stride;
    }
    if (IND & POINT) {
-      pointSize = VB->PointSizePtr->data;
+      pointSize = (GLfloat *) VB->PointSizePtr->data;
       pointSize_stride = VB->PointSizePtr->stride;
    }
 
@@ -215,6 +215,7 @@ static void TAG(interp)( GLcontext *ctx,
       INTERP_UI( t, dst->index, out->index, in->index );
    }
 
+   /* XXX Point size interpolation??? */
    if (IND & POINT) {
       INTERP_F( t, dst->pointSize, out->pointSize, in->pointSize );
    }
index c9bb9d502c573ad52ad0c8a1623236292dc33c7a..0b93cf913090bcec8b4a456344d0e37e25b08531 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: t_array_import.c,v 1.20 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_array_import.c,v 1.21 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -277,8 +277,8 @@ static void _tnl_upgrade_client_data( GLcontext *ctx,
    }
 
    if ((required & VERT_FOG_BIT)
-       && (VB->AttribPtr[VERT_ATTRIB_FOG]->flags & flags)) {
-      ASSERT(VB->AttribPtr[VERT_ATTRIB_FOG] == &inputs->FogCoord);
+       && (VB->FogCoordPtr->flags & flags)) {
+      ASSERT(VB->FogCoordPtr == &inputs->FogCoord);
       _tnl_import_fogcoord( ctx, writeable, stride );
       VB->importable_data &= ~VERT_FOG_BIT;
    }
@@ -372,7 +372,7 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
       if (inputs & VERT_FOG_BIT) {
         _tnl_import_fogcoord( ctx, 0, 0 );
         tmp->FogCoord.count = VB->Count;
-        VB->AttribPtr[VERT_ATTRIB_FOG] = &tmp->FogCoord;
+        VB->FogCoordPtr = &tmp->FogCoord;
       }
 
       if (inputs & VERT_EDGEFLAG_BIT) {
index cd435d89c4e1ae1f658f2b0c2105e2d401805b70..64abe88bb7b6d21182cd998ce12cf7aa4422ce36 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_context.h,v 1.35 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_context.h,v 1.36 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -254,7 +254,6 @@ typedef struct vertex_buffer
    GLuint     FirstPrimitive;                /* usually zero */
 
    /* Pointers to current data.
-    * XXX Replace ObjPtr, NormalPtr, TexCoordPtr, etc with AttribPtr[] arrays.
     */
    GLuint      *Elts;                          /* VERT_ELT */
    GLvector4f  *ObjPtr;                                /* VERT_OBJ_BIT */
@@ -270,13 +269,15 @@ typedef struct vertex_buffer
    GLvector1ui *IndexPtr[2];                   /* VERT_INDEX_BIT */
    struct gl_client_array *ColorPtr[2];                /* VERT_COLOR0_BIT */
    struct gl_client_array *SecondaryColorPtr[2];/* VERT_COLOR1_BIT */
-   GLvector1f  *PointSizePtr;                  /* VERT_POINT_SIZE */
+   GLvector4f  *PointSizePtr;                  /* VERT_POINT_SIZE */
+   GLvector4f  *FogCoordPtr;                   /* VERT_FOG_BIT */
    GLmaterial (*Material)[2];                   /* VERT_MATERIAL, optional */
    GLuint      *MaterialMask;                  /* VERT_MATERIAL, optional */
    GLuint      *Flag;                          /* VERT_* flags, optional */
    GLuint      *Primitive;                     /* GL_(mode)|PRIM_* flags */
    GLuint      *PrimitiveLength;               /* integers */
 
+   /* Inputs to the vertex program stage */
    GLvector4f *AttribPtr[VERT_ATTRIB_MAX];      /* GL_NV_vertex_program */
 
    GLuint importable_data;
index b127a9e4c3dfde09a6472ce9810d9e5860dbcdf2..83765025ea26860f1e58628e0f6cdfc9d676be09 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: t_imm_elt.c,v 1.14 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_imm_elt.c,v 1.15 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -721,6 +721,7 @@ static void _tnl_trans_elt_4f(GLfloat (*to)[4],
 
 
 
+#if 0
 static void _tnl_trans_elt_3f(GLfloat (*to)[3],
                       const struct gl_client_array *from,
                       GLuint *flags,
@@ -738,7 +739,7 @@ static void _tnl_trans_elt_3f(GLfloat (*to)[3],
                                              start,
                                              n );
 }
-
+#endif
 
 
 
index d02ec2ee2124ee504b1f8efc6f72a440db1e63f5..8df863875aee35a22a2d00bb5836a35bb6adb2b3 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: t_imm_exec.c,v 1.33 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_imm_exec.c,v 1.34 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -232,7 +232,6 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
    GLuint inputs = tnl->pipeline.inputs; /* for copy-to-current */
    const GLuint start = IM->CopyStart;
    const GLuint count = IM->Count - start;
-   GLuint i;
 
    /* TODO: optimize the case where nothing has changed.  (Just bind
     * tmp to vb).
@@ -267,8 +266,6 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
    VB->Elts = 0;
    VB->MaterialMask = 0;
    VB->Material = 0;
-   for (i = 0; i < 16; i++)
-      VB->AttribPtr[i] = NULL;
 
 /*     _tnl_print_vert_flags("copy-orflag", IM->CopyOrFlag); */
 /*     _tnl_print_vert_flags("orflag", IM->OrFlag); */
@@ -309,7 +306,7 @@ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
       tmp->FogCoord.data = IM->Attrib[VERT_ATTRIB_FOG] + start;
       tmp->FogCoord.start = (GLfloat *) (IM->Attrib[VERT_ATTRIB_FOG] + start);
       tmp->FogCoord.count = count;
-      VB->AttribPtr[VERT_ATTRIB_FOG] = &tmp->FogCoord;
+      VB->FogCoordPtr = &tmp->FogCoord;
    }
 
    if (inputs & VERT_COLOR1_BIT) {
index 6d6bfad83fcf0220fc30128c8d5c6d0e49223e86..6e52187a47d946f5f3baacb4c650c8b28f9aec4e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_imm_fixup.c,v 1.31 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_imm_fixup.c,v 1.32 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -145,6 +145,7 @@ fixup_first_4f( GLfloat data[][4], GLuint flag[], GLuint match,
       COPY_4FV(data[i], dflt);
 }
 
+#if 0
 static void
 fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match,
                GLuint start, GLfloat *dflt )
@@ -158,7 +159,7 @@ fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match,
    while ((flag[++i]&match) == 0)
       COPY_3FV(data[i], dflt);
 }
-
+#endif
 
 static void
 fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match,
index b7876a4db9ddd70007809f4c22fbbcca5d215757..d0e87cdbd8a96030fa96d4d17dacb24126073a9a 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: t_vb_fog.c,v 1.15 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_vb_fog.c,v 1.16 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -142,7 +142,7 @@ static GLboolean run_fog_stage( GLcontext *ctx,
       /* fog computed from Z depth */
       /* source = VB->ObjPtr or VB->EyePtr coords */
       /* dest = VB->FogCoordPtr = fog stage private storage */
-      VB->AttribPtr[VERT_ATTRIB_FOG] = &store->fogcoord;
+      VB->FogCoordPtr = &store->fogcoord;
 
       if (!ctx->_NeedEyeCoords) {
         const GLfloat *m = ctx->ModelviewMatrixStack.Top->m;
@@ -181,12 +181,12 @@ static GLboolean run_fog_stage( GLcontext *ctx,
    else {
       /* use glFogCoord() coordinates */
       /* source = VB->FogCoordPtr */
-      input = VB->AttribPtr[VERT_ATTRIB_FOG];
+      input = VB->FogCoordPtr;
       /* dest = fog stage private storage */
-      VB->AttribPtr[VERT_ATTRIB_FOG] = &store->fogcoord;
+      VB->FogCoordPtr = &store->fogcoord;
    }
 
-   make_win_fog_coords( ctx, VB->AttribPtr[VERT_ATTRIB_FOG], input );
+   make_win_fog_coords( ctx, VB->FogCoordPtr, input );
    return GL_TRUE;
 }
 
index c60a0f56b126886b91ea4ee761c8201b40cc1254..429a0ab7cb411b402040337d6173380a5cebc082 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: t_vb_points.c,v 1.5 2001/12/14 02:51:45 brianp Exp $ */
+/* $Id: t_vb_points.c,v 1.6 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,7 +34,7 @@
 
 
 struct point_stage_data {
-   GLvector1f PointSize;
+   GLvector4f PointSize;
 };
 
 #define POINT_STAGE_DATA(stage) ((struct point_stage_data *)stage->privatePtr)
@@ -53,7 +53,7 @@ static GLboolean run_point_stage( GLcontext *ctx,
    const GLfloat p1 = ctx->Point.Params[1];
    const GLfloat p2 = ctx->Point.Params[2];
    const GLfloat pointSize = ctx->Point._Size;
-   GLfloat *size = store->PointSize.data;
+   GLfloat (*size)[4] = store->PointSize.data;
    GLuint i;
 
    if (stage->changed_inputs) {
@@ -61,7 +61,7 @@ static GLboolean run_point_stage( GLcontext *ctx,
       for (i = 0; i < VB->Count; i++) {
         const GLfloat dist = -eye[i][2];
         /* GLfloat dist = GL_SQRT(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);*/
-        size[i] = pointSize / (p0 + dist * (p1 + dist * p2));
+        size[i][0] = pointSize / (p0 + dist * (p1 + dist * p2));
       }
    }
 
@@ -89,7 +89,7 @@ static GLboolean alloc_point_data( GLcontext *ctx,
    if (!store)
       return GL_FALSE;
 
-   _mesa_vector1f_alloc( &store->PointSize, 0, VB->Size, 32 );
+   _mesa_vector4f_alloc( &store->PointSize, 0, VB->Size, 32 );
 
    /* Now run the stage.
     */
@@ -102,7 +102,7 @@ static void free_point_data( struct gl_pipeline_stage *stage )
 {
    struct point_stage_data *store = POINT_STAGE_DATA(stage);
    if (store) {
-      _mesa_vector1f_free( &store->PointSize );
+      _mesa_vector4f_free( &store->PointSize );
       FREE( store );
       stage->privatePtr = 0;
    }
index a711c96c43ec48d8c05f0f8ead08aa1dcc41a365..cfa1397d70eba128077aecbd4347b0b31fb12fbb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_vb_program.c,v 1.6 2002/01/05 20:51:13 brianp Exp $ */
+/* $Id: t_vb_program.c,v 1.7 2002/01/06 03:54:12 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "t_imm_exec.h"
 
 
+/* WARNING: these values _MUST_ match the values in the OutputRegisters[]
+ * array in vpparse.c!!!
+ */
+#define VERT_RESULT_HPOS 0
+#define VERT_RESULT_COL0 1
+#define VERT_RESULT_COL1 2
+#define VERT_RESULT_BFC0 3
+#define VERT_RESULT_BFC1 4
+#define VERT_RESULT_FOGC 5
+#define VERT_RESULT_PSIZ 6
+#define VERT_RESULT_TEX0 7
+#define VERT_RESULT_TEX1 8
+#define VERT_RESULT_TEX2 9
+#define VERT_RESULT_TEX3 10
+#define VERT_RESULT_TEX4 11
+#define VERT_RESULT_TEX5 12
+#define VERT_RESULT_TEX6 13
+#define VERT_RESULT_TEX7 14
+
 
 struct vp_stage_data {
-   GLvector4f clipCoords;             /* post-modelview/projection coords */
-   GLvector4f ndcCoords;              /* normalized device coords */
+   /* The results of running the vertex program go into these arrays. */
+   GLvector4f attribs[15];
+
+   /* These point to the attribs[VERT_RESULT_COL0, COL1, BFC0, BFC1] arrays */
    struct gl_client_array color0[2];  /* front and back */
    struct gl_client_array color1[2];  /* front and back */
-   GLvector4f texCoord[MAX_TEXTURE_UNITS];
-   GLvector4f fogCoord;
-   GLvector1f pointSize;
-   GLubyte *clipmask;
+
+   GLvector4f ndcCoords;              /* normalized device coords */
+   GLubyte *clipmask;                 /* clip flags */
    GLubyte ormask, andmask;
 };
 
@@ -123,21 +143,8 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
    struct vp_machine *machine = &(ctx->VertexProgram.Machine);
    GLint i;
 
-   /* convenience pointers */
-   GLfloat (*clip)[4] = (GLfloat (*)[4]) store->clipCoords.data;
-   GLfloat (*color0)[4] = (GLfloat (*)[4]) store->color0[0].Ptr;
-   GLfloat (*color1)[4] = (GLfloat (*)[4]) store->color1[0].Ptr;
-   GLfloat (*bfcolor0)[4] = (GLfloat (*)[4]) store->color0[1].Ptr;
-   GLfloat (*bfcolor1)[4] = (GLfloat (*)[4]) store->color1[1].Ptr;
-   GLfloat (*fog)[4] = (GLfloat (*)[4]) store->fogCoord.data;
-   GLfloat *pointSize = (GLfloat *) store->pointSize.data;
-   GLfloat (*texture0)[4] = (GLfloat (*)[4]) store->texCoord[0].data;
-   GLfloat (*texture1)[4] = (GLfloat (*)[4]) store->texCoord[1].data;
-   GLfloat (*texture2)[4] = (GLfloat (*)[4]) store->texCoord[2].data;
-   GLfloat (*texture3)[4] = (GLfloat (*)[4]) store->texCoord[3].data;
-
    _mesa_init_tracked_matrices(ctx);
-   _mesa_init_vp_registers(ctx);  /* sets temp regs to (0,0,0,1) */
+   _mesa_init_vp_registers(ctx);  /* init temp and result regs */
 
    for (i = 0; i < VB->Count; i++) {
       GLuint attr;
@@ -185,33 +192,28 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
              machine->Registers[VP_OUT_COL0][3]);
 #endif
 
-      /* store the attribute output registers into the VB arrays */
-      COPY_4V(clip[i], machine->Registers[VP_OUT_HPOS]);
-      COPY_4V(color0[i], machine->Registers[VP_OUT_COL0]);
-      COPY_4V(color1[i], machine->Registers[VP_OUT_COL1]);
-      COPY_4V(bfcolor0[i], machine->Registers[VP_OUT_BFC0]);
-      COPY_4V(bfcolor1[i], machine->Registers[VP_OUT_BFC1]);
-      fog[i][0] = machine->Registers[VP_OUT_FOGC][0];
-      pointSize[i] = machine->Registers[VP_OUT_PSIZ][0];
-      COPY_4V(texture0[i], machine->Registers[VP_OUT_TEX0]);
-      COPY_4V(texture1[i], machine->Registers[VP_OUT_TEX0]);
-      COPY_4V(texture2[i], machine->Registers[VP_OUT_TEX0]);
-      COPY_4V(texture3[i], machine->Registers[VP_OUT_TEX0]);
+      /* copy the output registers into the VB->attribs arrays */
+      /* XXX (optimize) could use a conditional and smaller loop limit here */
+      for (attr = 0; attr < 15; attr++) {
+         COPY_4V( store->attribs[attr].data[i],
+                  machine->Registers[VP_OUTPUT_REG_START + attr] );
+      }
    }
 
-   VB->ClipPtr = &store->clipCoords;
+   /* Setup the VB pointers so that the next pipeline stages get
+    * their data from the right place (the program output arrays).
+    */
+   VB->ClipPtr = &store->attribs[VERT_RESULT_HPOS];
    VB->ClipPtr->size = 4;
    VB->ClipPtr->count = VB->Count;
    VB->ColorPtr[0] = &store->color0[0];
    VB->ColorPtr[1] = &store->color0[1];
    VB->SecondaryColorPtr[0] = &store->color1[0];
    VB->SecondaryColorPtr[1] = &store->color1[1];
-   VB->AttribPtr[VERT_ATTRIB_FOG] = &store->fogCoord;
-   VB->PointSizePtr = &store->pointSize;
-   VB->TexCoordPtr[0] = &store->texCoord[0];
-   VB->TexCoordPtr[1] = &store->texCoord[1];
-   VB->TexCoordPtr[2] = &store->texCoord[2];
-   VB->TexCoordPtr[3] = &store->texCoord[3];
+   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];
 
    /* Cliptest and perspective divide.  Clip functions must clear
     * the clipmask.
@@ -304,23 +306,9 @@ static GLboolean run_validate_program( GLcontext *ctx,
 }
 
 
-
-#if 0
-static void alloc_4chan( struct gl_client_array *a, GLuint sz )
-{
-   a->Ptr = ALIGN_MALLOC( sz * sizeof(GLchan) * 4, 32 );
-   a->Size = 4;
-   a->Type = CHAN_TYPE;
-   a->Stride = 0;
-   a->StrideB = sizeof(GLchan) * 4;
-   a->Enabled = 0;
-   a->Flags = 0;
-}
-#endif
-
-static void alloc_4float( struct gl_client_array *a, GLuint sz )
+static void init_client_array( struct gl_client_array *a, GLvector4f *vec )
 {
-   a->Ptr = ALIGN_MALLOC( sz * sizeof(GLfloat) * 4, 32 );
+   a->Ptr = vec->data;
    a->Size = 4;
    a->Type = GL_FLOAT;
    a->Stride = 0;
@@ -347,20 +335,20 @@ static GLboolean run_init_vp( GLcontext *ctx,
    if (!store)
       return GL_FALSE;
 
-   /* The output of a vertex program is: */
-   _mesa_vector4f_alloc( &store->clipCoords, 0, size, 32 );
+   /* Allocate arrays of vertex output values */
+   for (i = 0; i < 15; i++)
+      _mesa_vector4f_alloc( &store->attribs[i], 0, size, 32 );
+
+   /* Make the color0[] and color1[] arrays point into the attribs[] arrays */
+   init_client_array( &store->color0[0], &store->attribs[VERT_RESULT_COL0] );
+   init_client_array( &store->color0[1], &store->attribs[VERT_RESULT_COL1] );
+   init_client_array( &store->color1[0], &store->attribs[VERT_RESULT_BFC0] );
+   init_client_array( &store->color1[1], &store->attribs[VERT_RESULT_BFC1] );
+
+   /* a few other misc allocations */
    _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
-   alloc_4float( &store->color0[0], size );
-   alloc_4float( &store->color0[1], size );
-   alloc_4float( &store->color1[0], size );
-   alloc_4float( &store->color1[1], size );
-   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
-      _mesa_vector4f_alloc( &store->texCoord[i], 0, VB->Size, 32 );
-   _mesa_vector4f_alloc( &store->fogCoord, 0, size, 32 );
-   _mesa_vector1f_alloc( &store->pointSize, 0, size, 32 );
    store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
 
-
    /* Now validate the stage derived data...
     */
    stage->run = run_validate_program;
@@ -401,17 +389,13 @@ static void dtr( struct gl_pipeline_stage *stage )
 
    if (store) {
       GLuint i;
-      _mesa_vector4f_free( &store->clipCoords );
+
+      /* free the vertex program result arrays */
+      for (i = 0; i < 15; i++)
+         _mesa_vector4f_free( &store->attribs[i] );
+
+      /* free misc arrays */
       _mesa_vector4f_free( &store->ndcCoords );
-      ALIGN_FREE( store->color0[0].Ptr );
-      ALIGN_FREE( store->color0[1].Ptr );
-      ALIGN_FREE( store->color1[0].Ptr );
-      ALIGN_FREE( store->color1[1].Ptr );
-      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
-        if (store->texCoord[i].data)
-            _mesa_vector4f_free( &store->texCoord[i] );
-      _mesa_vector4f_free( &store->fogCoord );
-      _mesa_vector1f_free( &store->pointSize );
       ALIGN_FREE( store->clipmask );
 
       FREE( store );