Replace old matrix stacks with new code based on struct matrix_stack.
Moved vertex program hash table into shared context state.
Implemented reference counting for vertex programs.
Replaced tnl "ProjectedClip" with "Ndc" (normalized device coordinates).
diff --git a/src/mesa/main/clip.c b/src/mesa/main/clip.c
index f18b0b4..700d271 100644
--- a/src/mesa/main/clip.c
+++ b/src/mesa/main/clip.c
@@ -1,4 +1,4 @@
-/* $Id: clip.c,v 1.23 2001/09/15 18:02:49 brianp Exp $ */
+/* $Id: clip.c,v 1.24 2001/12/18 04:06:44 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -74,10 +74,11 @@
     * clipping now takes place.  The clip-space equations are recalculated
     * whenever the projection matrix changes.
     */
-   if (ctx->ModelView.flags & MAT_DIRTY)
-      _math_matrix_analyse( &ctx->ModelView );
+   if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY)
+      _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 
-   _mesa_transform_vector( equation, equation, ctx->ModelView.inv );
+   _mesa_transform_vector( equation, equation,
+                           ctx->ModelviewMatrixStack.Top->inv );
 
    if (TEST_EQ_4V(ctx->Transform.EyeUserPlane[p], equation))
       return;
@@ -90,12 +91,12 @@
     * code in _mesa_update_state().
     */
    if (ctx->Transform.ClipEnabled[p]) {
-      if (ctx->ProjectionMatrix.flags & MAT_DIRTY)
-	 _math_matrix_analyse( &ctx->ProjectionMatrix );
+      if (ctx->ProjectionMatrixStack.Top->flags & MAT_DIRTY)
+	 _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
 
       _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
 			   ctx->Transform.EyeUserPlane[p],
-			   ctx->ProjectionMatrix.inv );
+			   ctx->ProjectionMatrixStack.Top->inv );
    }
 
    if (ctx->Driver.ClipPlane)
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 66ad1fe..37c5722 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -1,4 +1,4 @@
-/* $Id: config.h,v 1.36 2001/11/28 17:18:36 brianp Exp $ */
+/* $Id: config.h,v 1.37 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -55,6 +55,10 @@
 /* Maximum color matrix stack depth: */
 #define MAX_COLOR_STACK_DEPTH 4
 
+/* Vertex program matrix stacks: */
+#define MAX_PROGRAM_MATRICES 8
+#define MAX_PROGRAM_STACK_DEPTH 4
+
 /* Maximum attribute stack depth: */
 #define MAX_ATTRIB_STACK_DEPTH 16
 
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 686d553..cb5674c 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.151 2001/12/17 22:41:45 brianp Exp $ */
+/* $Id: context.c,v 1.152 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -52,6 +52,7 @@
 #include "texobj.h"
 #include "mtypes.h"
 #include "varray.h"
+#include "vpstate.h"
 #include "vtxfmt.h"
 #include "math/m_translate.h"
 #include "math/m_vertices.h"
@@ -487,15 +488,13 @@
    stack->Depth = 0;
    stack->MaxDepth = maxDepth;
    stack->DirtyFlag = dirtyFlag;
-   /* Top matrix */
-   _math_matrix_ctr( &stack->Top );
-   _math_matrix_alloc_inv( &stack->Top );
    /* The stack */
-   stack->Stack = MALLOC(maxDepth * sizeof(GLmatrix));
+   stack->Stack = CALLOC(maxDepth * sizeof(GLmatrix));
    for (i = 0; i < maxDepth; i++) {
       _math_matrix_ctr(&stack->Stack[i]);
       _math_matrix_alloc_inv(&stack->Stack[i]);
    }
+   stack->Top = stack->Stack;
 }
 
 
@@ -503,10 +502,10 @@
 free_matrix_stack( struct matrix_stack *stack )
 {
    GLuint i;
-   _math_matrix_dtr( &stack->Top );
    for (i = 0; i < stack->MaxDepth; i++) {
       _math_matrix_dtr(&stack->Stack[i]);
    }
+   stack->Stack = stack->Top = NULL;
 }
 
 
@@ -527,6 +526,7 @@
 
    ss->DisplayList = _mesa_NewHashTable();
    ss->TexObjects = _mesa_NewHashTable();
+   ss->VertexPrograms = _mesa_NewHashTable();
 
    /* Default Texture objects */
    outOfMemory = GL_FALSE;
@@ -551,12 +551,15 @@
       outOfMemory = GL_TRUE;
    }
 
-   if (!ss->DisplayList || !ss->TexObjects || outOfMemory) {
+   if (!ss->DisplayList || !ss->TexObjects || !ss->VertexPrograms
+       || outOfMemory) {
       /* Ran out of memory at some point.  Free everything and return NULL */
       if (ss->DisplayList)
          _mesa_DeleteHashTable(ss->DisplayList);
       if (ss->TexObjects)
          _mesa_DeleteHashTable(ss->TexObjects);
+      if (ss->VertexPrograms)
+         _mesa_DeleteHashTable(ss->VertexPrograms);
       if (ss->Default1D)
          _mesa_free_texture_object(ss, ss->Default1D);
       if (ss->Default2D)
@@ -601,6 +604,18 @@
    }
    _mesa_DeleteHashTable(ss->TexObjects);
 
+   /* Free vertex programs */
+   while (1) {
+      GLuint prog = _mesa_HashFirstEntry(ss->VertexPrograms);
+      if (prog) {
+         _mesa_delete_program(ctx, prog);
+      }
+      else {
+         break;
+      }
+   }
+   _mesa_DeleteHashTable(ss->VertexPrograms);
+
    FREE(ss);
 }
 
@@ -757,7 +772,7 @@
 static void
 init_attrib_groups( GLcontext *ctx )
 {
-   GLuint i, j;
+   GLuint i;
 
    assert(ctx);
 
@@ -791,49 +806,24 @@
    ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
    ctx->Const.MaxLights = MAX_LIGHTS;
 
-   /* Modelview matrix */
-   _math_matrix_ctr( &ctx->ModelView );
-   _math_matrix_alloc_inv( &ctx->ModelView );
+   /* Initialize matrix stacks */
+   init_matrix_stack(&ctx->ModelviewMatrixStack, MAX_MODELVIEW_STACK_DEPTH,
+                     _NEW_MODELVIEW);
+   init_matrix_stack(&ctx->ProjectionMatrixStack, MAX_PROJECTION_STACK_DEPTH,
+                     _NEW_PROJECTION);
+   init_matrix_stack(&ctx->ColorMatrixStack, MAX_COLOR_STACK_DEPTH,
+                     _NEW_COLOR_MATRIX);
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+      init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH,
+                        _NEW_TEXTURE_MATRIX);
+   for (i = 0; i < MAX_PROGRAM_MATRICES; i++)
+      init_matrix_stack(&ctx->ProgramMatrixStack[i], MAX_PROGRAM_STACK_DEPTH,
+                        _NEW_TRACK_MATRIX);
+   ctx->CurrentStack = &ctx->ModelviewMatrixStack;
 
-   ctx->ModelViewStackDepth = 0;
-   for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
-      _math_matrix_ctr( &ctx->ModelViewStack[i] );
-      _math_matrix_alloc_inv( &ctx->ModelViewStack[i] );
-   }
-#if 0
-   init_matrix_stack(&ctx->ModelviewStack, 32, _NEW_MODELVIEW);
-#endif
-
-   /* Projection matrix - need inv for user clipping in clip space*/
-   _math_matrix_ctr( &ctx->ProjectionMatrix );
-   _math_matrix_alloc_inv( &ctx->ProjectionMatrix );
-
-   ctx->ProjectionStackDepth = 0;
-   for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
-      _math_matrix_ctr( &ctx->ProjectionStack[i] );
-      _math_matrix_alloc_inv( &ctx->ProjectionStack[i] );
-   }
-
-   /* Derived ModelProject matrix */
+   /* Init combined Modelview*Projection matrix */
    _math_matrix_ctr( &ctx->_ModelProjectMatrix );
 
-   /* Texture matrix */
-   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-      _math_matrix_ctr( &ctx->TextureMatrix[i] );
-      ctx->TextureStackDepth[i] = 0;
-      for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
-         _math_matrix_ctr( &ctx->TextureStack[i][j] );
-         ctx->TextureStack[i][j].inv = 0;
-      }
-   }
-
-   /* Color matrix */
-   _math_matrix_ctr(&ctx->ColorMatrix);
-   ctx->ColorStackDepth = 0;
-   for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) {
-      _math_matrix_ctr(&ctx->ColorStack[j]);
-   }
-
    /* Accumulate buffer group */
    ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
 
@@ -1319,8 +1309,8 @@
    _mesa_init_colortable(&ctx->ProxyPostColorMatrixColorTable);
 
    /* GL_NV_vertex_program */
-   ctx->VertexProgram.Binding = 0;
-   ctx->VertexProgram.HashTable = _mesa_NewHashTable();
+   ctx->VertexProgram.Current = NULL;
+   ctx->VertexProgram.CurrentID = 0;
    ctx->VertexProgram.Enabled = GL_FALSE;
    ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
    ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
@@ -1643,39 +1633,34 @@
 _mesa_free_context_data( GLcontext *ctx )
 {
    struct gl_shine_tab *s, *tmps;
-   GLuint i, j;
+   GLuint i;
 
    /* if we're destroying the current context, unbind it first */
    if (ctx == _mesa_get_current_context()) {
       _mesa_make_current(NULL, NULL);
    }
 
-#if 0
-   free_matrix_stack(&ctx->ModelviewStack);
-#endif
-
-   _math_matrix_dtr( &ctx->ModelView );
-   for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
-      _math_matrix_dtr( &ctx->ModelViewStack[i] );
-   }
-   _math_matrix_dtr( &ctx->ProjectionMatrix );
-   for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
-      _math_matrix_dtr( &ctx->ProjectionStack[i] );
-   }
-   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-      _math_matrix_dtr( &ctx->TextureMatrix[i] );
-      for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
-         _math_matrix_dtr( &ctx->TextureStack[i][j] );
-      }
-   }
-
+   /*
+    * Free transformation matrix stacks
+    */
+   free_matrix_stack(&ctx->ModelviewMatrixStack);
+   free_matrix_stack(&ctx->ProjectionMatrixStack);
+   free_matrix_stack(&ctx->ColorMatrixStack);
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+      free_matrix_stack(&ctx->TextureMatrixStack[i]);
+   for (i = 0; i < MAX_PROGRAM_MATRICES; i++)
+      free_matrix_stack(&ctx->ProgramMatrixStack[i]);
+   /* combined Modelview*Projection matrix */
    _math_matrix_dtr( &ctx->_ModelProjectMatrix );
 
-   _math_matrix_dtr(&ctx->ColorMatrix);
-   for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) {
-      _math_matrix_dtr(&ctx->ColorStack[j]);
+
+   if (ctx->VertexProgram.Current) {
+      ctx->VertexProgram.Current->RefCount--;
+      if (ctx->VertexProgram.Current->RefCount <= 0)
+         _mesa_delete_program(ctx, ctx->VertexProgram.CurrentID);
    }
 
+   /* Shared context state (display lists, textures, etc) */
    _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
    ctx->Shared->RefCount--;
    assert(ctx->Shared->RefCount >= 0);
@@ -1685,6 +1670,7 @@
       free_shared_state( ctx, ctx->Shared );
    }
 
+   /* Free lighting shininess exponentiation table */
    foreach_s( s, tmps, ctx->_ShineTabList ) {
       FREE( s );
    }
@@ -1744,9 +1730,6 @@
 
    _mesa_extensions_dtr(ctx);
 
-   /* GL_NV_vertex_program */
-   _mesa_DeleteHashTable(ctx->VertexProgram.HashTable);
-
    FREE(ctx->Exec);
    FREE(ctx->Save);
 }
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 43323b1..24617f4 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -1,4 +1,4 @@
-/* $Id: dlist.c,v 1.82 2001/12/14 03:13:04 brianp Exp $ */
+/* $Id: dlist.c,v 1.83 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -5999,6 +5999,10 @@
 
    /* 233. GL_NV_vertex_program */
    /* XXX Need to implement vertex program in display lists !!! */
+   /* The following commands DO NOT go into display lists:
+    * AreProgramsResidentNV, IsProgramNV, GenProgramsNV, DeleteProgramsNV,
+    * VertexAttribPointerNV
+    */
    table->BindProgramNV = _mesa_BindProgramNV;
    table->DeleteProgramsNV = _mesa_DeleteProgramsNV;
    table->ExecuteProgramNV = _mesa_ExecuteProgramNV;
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 758426d..6f0b1bd 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -1,4 +1,4 @@
-/* $Id: enable.c,v 1.51 2001/12/14 02:50:01 brianp Exp $ */
+/* $Id: enable.c,v 1.52 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -207,7 +207,7 @@
       case GL_CLIP_PLANE4:
       case GL_CLIP_PLANE5:
          {
-            GLuint p = cap-GL_CLIP_PLANE0;
+            GLuint p = cap - GL_CLIP_PLANE0;
 
             if (ctx->Transform.ClipEnabled[p] == state)
                return;
@@ -218,8 +218,8 @@
             if (state) {
                ctx->Transform._AnyClip++;
 
-               if (ctx->ProjectionMatrix.flags & MAT_DIRTY) {
-                  _math_matrix_analyse( &ctx->ProjectionMatrix );
+               if (ctx->ProjectionMatrixStack.Top->flags & MAT_DIRTY) {
+                  _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
                }
 
                /* This derived state also calculated in clip.c and
@@ -228,7 +228,7 @@
                 */
                _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
                                     ctx->Transform.EyeUserPlane[p],
-                                    ctx->ProjectionMatrix.inv );
+                                    ctx->ProjectionMatrixStack.Top->inv );
             }
          }
          break;
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index a6a4d12..efbed8c 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -1,4 +1,4 @@
-/* $Id: get.c,v 1.74 2001/12/14 02:55:08 brianp Exp $ */
+/* $Id: get.c,v 1.75 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -616,11 +616,11 @@
 	 break;
       case GL_MODELVIEW_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = FLOAT_TO_BOOL(ctx->ModelView.m[i]);
+	    params[i] = FLOAT_TO_BOOL(ctx->ModelviewMatrixStack.Top->m[i]);
 	 }
 	 break;
       case GL_MODELVIEW_STACK_DEPTH:
-	 *params = INT_TO_BOOL(ctx->ModelViewStackDepth + 1);
+         *params = INT_TO_BOOL(ctx->ModelviewMatrixStack.Depth + 1);
 	 break;
       case GL_NAME_STACK_DEPTH:
 	 *params = INT_TO_BOOL(ctx->Select.NameStackDepth);
@@ -743,11 +743,11 @@
 	 break;
       case GL_PROJECTION_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = FLOAT_TO_BOOL(ctx->ProjectionMatrix.m[i]);
+	    params[i] = FLOAT_TO_BOOL(ctx->ProjectionMatrixStack.Top->m[i]);
 	 }
 	 break;
       case GL_PROJECTION_STACK_DEPTH:
-	 *params = INT_TO_BOOL(ctx->ProjectionStackDepth + 1);
+	 *params = INT_TO_BOOL(ctx->ProjectionMatrixStack.Depth + 1);
 	 break;
       case GL_READ_BUFFER:
 	 *params = ENUM_TO_BOOL(ctx->Pixel.ReadBuffer);
@@ -868,11 +868,11 @@
       case GL_TEXTURE_MATRIX:
 	 for (i=0;i<16;i++) {
 	    params[i] =
-	       FLOAT_TO_BOOL(ctx->TextureMatrix[texUnit].m[i]);
+	       FLOAT_TO_BOOL(ctx->TextureMatrixStack[texUnit].Top->m[i]);
 	 }
 	 break;
       case GL_TEXTURE_STACK_DEPTH:
-	 *params = INT_TO_BOOL(ctx->TextureStackDepth[texUnit] + 1);
+	 *params = INT_TO_BOOL(ctx->TextureMatrixStack[texUnit].Depth + 1);
 	 break;
       case GL_UNPACK_ALIGNMENT:
 	 *params = INT_TO_BOOL(ctx->Unpack.Alignment);
@@ -1042,7 +1042,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ColorMatrix.m);
+            _math_transposef(tm, ctx->ColorMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1052,7 +1052,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ModelView.m);
+            _math_transposef(tm, ctx->ModelviewMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1062,7 +1062,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ProjectionMatrix.m);
+            _math_transposef(tm, ctx->ProjectionMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1072,7 +1072,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->TextureMatrix[texUnit].m);
+            _math_transposef(tm, ctx->TextureMatrixStack[texUnit].Top->m);
             for (i=0;i<16;i++) {
                params[i] = FLOAT_TO_BOOL(tm[i]);
             }
@@ -1111,11 +1111,11 @@
       /* GL_SGI_color_matrix (also in 1.2 imaging) */
       case GL_COLOR_MATRIX_SGI:
          for (i=0;i<16;i++) {
-	    params[i] = FLOAT_TO_BOOL(ctx->ColorMatrix.m[i]);
+	    params[i] = FLOAT_TO_BOOL(ctx->ColorMatrixStack.Top->m[i]);
 	 }
 	 break;
       case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
-         *params = INT_TO_BOOL(ctx->ColorStackDepth + 1);
+         *params = INT_TO_BOOL(ctx->ColorMatrixStack.Depth + 1);
          break;
       case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
          *params = FLOAT_TO_BOOL(MAX_COLOR_STACK_DEPTH);
@@ -1334,11 +1334,11 @@
       /* GL_NV_vertex_program */
       case GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV:
          CHECK_EXTENSION_B(NV_vertex_program);
-         *params = VP_MAX_MATRIX_DEPTH;
+         *params = MAX_PROGRAM_STACK_DEPTH;
          break;
       case GL_MAX_TRACK_MATRICES_NV:
          CHECK_EXTENSION_B(NV_vertex_program);
-         *params = VP_MAX_MATRICES;
+         *params = MAX_PROGRAM_MATRICES;
          break;
       case GL_VERTEX_PROGRAM_NV:
          CHECK_EXTENSION_B(NV_vertex_program);
@@ -1942,11 +1942,11 @@
          break;
       case GL_MODELVIEW_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = (GLdouble) ctx->ModelView.m[i];
+	    params[i] = (GLdouble) ctx->ModelviewMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_MODELVIEW_STACK_DEPTH:
-	 *params = (GLdouble) (ctx->ModelViewStackDepth + 1);
+	 *params = (GLdouble) (ctx->ModelviewMatrixStack.Depth + 1);
 	 break;
       case GL_NAME_STACK_DEPTH:
 	 *params = (GLdouble) ctx->Select.NameStackDepth;
@@ -2069,11 +2069,11 @@
 	 break;
       case GL_PROJECTION_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = (GLdouble) ctx->ProjectionMatrix.m[i];
+	    params[i] = (GLdouble) ctx->ProjectionMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_PROJECTION_STACK_DEPTH:
-	 *params = (GLdouble) (ctx->ProjectionStackDepth + 1);
+	 *params = (GLdouble) (ctx->ProjectionMatrixStack.Depth + 1);
 	 break;
       case GL_READ_BUFFER:
 	 *params = ENUM_TO_DOUBLE(ctx->Pixel.ReadBuffer);
@@ -2191,11 +2191,11 @@
 	 break;
       case GL_TEXTURE_MATRIX:
          for (i=0;i<16;i++) {
-	    params[i] = (GLdouble) ctx->TextureMatrix[texUnit].m[i];
+	    params[i] = (GLdouble) ctx->TextureMatrixStack[texUnit].Top->m[i];
 	 }
 	 break;
       case GL_TEXTURE_STACK_DEPTH:
-	 *params = (GLdouble) (ctx->TextureStackDepth[texUnit] + 1);
+	 *params = (GLdouble) (ctx->TextureMatrixStack[texUnit].Depth + 1);
 	 break;
       case GL_UNPACK_ALIGNMENT:
 	 *params = (GLdouble) ctx->Unpack.Alignment;
@@ -2368,7 +2368,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ColorMatrix.m);
+            _math_transposef(tm, ctx->ColorMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2378,7 +2378,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ModelView.m);
+            _math_transposef(tm, ctx->ModelviewMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2388,7 +2388,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ProjectionMatrix.m);
+            _math_transposef(tm, ctx->ProjectionMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2398,7 +2398,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->TextureMatrix[texUnit].m);
+            _math_transposef(tm, ctx->TextureMatrixStack[texUnit].Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLdouble) tm[i];
             }
@@ -2437,11 +2437,11 @@
       /* GL_SGI_color_matrix (also in 1.2 imaging) */
       case GL_COLOR_MATRIX_SGI:
          for (i=0;i<16;i++) {
-	    params[i] = (GLdouble) ctx->ColorMatrix.m[i];
+	    params[i] = (GLdouble) ctx->ColorMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
-         *params = (GLdouble) (ctx->ColorStackDepth + 1);
+         *params = (GLdouble) (ctx->ColorMatrixStack.Depth + 1);
          break;
       case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
          *params = (GLdouble) MAX_COLOR_STACK_DEPTH;
@@ -2658,7 +2658,7 @@
          break;
 
       /* GL_NV_vertex_program */
-         /* to do */
+         /* XXX to do */
 
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" );
@@ -3178,11 +3178,11 @@
          break;
       case GL_MODELVIEW_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = ctx->ModelView.m[i];
+	    params[i] = ctx->ModelviewMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_MODELVIEW_STACK_DEPTH:
-	 *params = (GLfloat) (ctx->ModelViewStackDepth + 1);
+	 *params = (GLfloat) (ctx->ModelviewMatrixStack.Depth + 1);
 	 break;
       case GL_NAME_STACK_DEPTH:
 	 *params = (GLfloat) ctx->Select.NameStackDepth;
@@ -3307,11 +3307,11 @@
 	 break;
       case GL_PROJECTION_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = ctx->ProjectionMatrix.m[i];
+	    params[i] = ctx->ProjectionMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_PROJECTION_STACK_DEPTH:
-	 *params = (GLfloat) (ctx->ProjectionStackDepth + 1);
+	 *params = (GLfloat) (ctx->ProjectionMatrixStack.Depth + 1);
 	 break;
       case GL_READ_BUFFER:
 	 *params = ENUM_TO_FLOAT(ctx->Pixel.ReadBuffer);
@@ -3429,11 +3429,11 @@
 	 break;
       case GL_TEXTURE_MATRIX:
          for (i=0;i<16;i++) {
-	    params[i] = ctx->TextureMatrix[texUnit].m[i];
+	    params[i] = ctx->TextureMatrixStack[texUnit].Top->m[i];
 	 }
 	 break;
       case GL_TEXTURE_STACK_DEPTH:
-	 *params = (GLfloat) (ctx->TextureStackDepth[texUnit] + 1);
+	 *params = (GLfloat) (ctx->TextureMatrixStack[texUnit].Depth + 1);
 	 break;
       case GL_UNPACK_ALIGNMENT:
 	 *params = (GLfloat) ctx->Unpack.Alignment;
@@ -3605,16 +3605,16 @@
 
       /* GL_ARB_transpose_matrix */
       case GL_TRANSPOSE_COLOR_MATRIX_ARB:
-         _math_transposef(params, ctx->ColorMatrix.m);
+         _math_transposef(params, ctx->ColorMatrixStack.Top->m);
          break;
       case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB:
-         _math_transposef(params, ctx->ModelView.m);
+         _math_transposef(params, ctx->ModelviewMatrixStack.Top->m);
          break;
       case GL_TRANSPOSE_PROJECTION_MATRIX_ARB:
-         _math_transposef(params, ctx->ProjectionMatrix.m);
+         _math_transposef(params, ctx->ProjectionMatrixStack.Top->m);
          break;
       case GL_TRANSPOSE_TEXTURE_MATRIX_ARB:
-         _math_transposef(params, ctx->TextureMatrix[texUnit].m);
+         _math_transposef(params, ctx->TextureMatrixStack[texUnit].Top->m);
          break;
 
       /* GL_HP_occlusion_test */
@@ -3649,11 +3649,11 @@
       /* GL_SGI_color_matrix (also in 1.2 imaging) */
       case GL_COLOR_MATRIX_SGI:
          for (i=0;i<16;i++) {
-	    params[i] = ctx->ColorMatrix.m[i];
+	    params[i] = ctx->ColorMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
-         *params = (GLfloat) (ctx->ColorStackDepth + 1);
+         *params = (GLfloat) (ctx->ColorMatrixStack.Depth + 1);
          break;
       case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
          *params = (GLfloat) MAX_COLOR_STACK_DEPTH;
@@ -3870,7 +3870,7 @@
          break;
 
       /* GL_NV_vertex_program */
-         /* to do */
+         /* XXX to do */
 
       default:
          GET_FLOAT_ERROR;
@@ -4385,11 +4385,11 @@
          break;
       case GL_MODELVIEW_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = (GLint) ctx->ModelView.m[i];
+	    params[i] = (GLint) ctx->ModelviewMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_MODELVIEW_STACK_DEPTH:
-	 *params = (GLint) (ctx->ModelViewStackDepth + 1);
+	 *params = (GLint) (ctx->ModelviewMatrixStack.Depth + 1);
 	 break;
       case GL_NAME_STACK_DEPTH:
 	 *params = (GLint) ctx->Select.NameStackDepth;
@@ -4512,11 +4512,11 @@
 	 break;
       case GL_PROJECTION_MATRIX:
 	 for (i=0;i<16;i++) {
-	    params[i] = (GLint) ctx->ProjectionMatrix.m[i];
+	    params[i] = (GLint) ctx->ProjectionMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_PROJECTION_STACK_DEPTH:
-	 *params = (GLint) (ctx->ProjectionStackDepth + 1);
+	 *params = (GLint) (ctx->ProjectionMatrixStack.Depth + 1);
 	 break;
       case GL_READ_BUFFER:
 	 *params = (GLint) ctx->Pixel.ReadBuffer;
@@ -4634,11 +4634,11 @@
 	 break;
       case GL_TEXTURE_MATRIX:
          for (i=0;i<16;i++) {
-	    params[i] = (GLint) ctx->TextureMatrix[texUnit].m[i];
+	    params[i] = (GLint) ctx->TextureMatrixStack[texUnit].Top->m[i];
 	 }
 	 break;
       case GL_TEXTURE_STACK_DEPTH:
-	 *params = (GLint) (ctx->TextureStackDepth[texUnit] + 1);
+	 *params = (GLint) (ctx->TextureMatrixStack[texUnit].Depth + 1);
 	 break;
       case GL_UNPACK_ALIGNMENT:
 	 *params = ctx->Unpack.Alignment;
@@ -4813,7 +4813,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ColorMatrix.m);
+            _math_transposef(tm, ctx->ColorMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4823,7 +4823,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ModelView.m);
+            _math_transposef(tm, ctx->ModelviewMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4833,7 +4833,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->ProjectionMatrix.m);
+            _math_transposef(tm, ctx->ProjectionMatrixStack.Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4843,7 +4843,7 @@
          {
             GLfloat tm[16];
             GLuint i;
-            _math_transposef(tm, ctx->TextureMatrix[texUnit].m);
+            _math_transposef(tm, ctx->TextureMatrixStack[texUnit].Top->m);
             for (i=0;i<16;i++) {
                params[i] = (GLint) tm[i];
             }
@@ -4886,12 +4886,12 @@
       case GL_COLOR_MATRIX_SGI:
          CHECK_EXTENSION_I(SGI_color_matrix);
          for (i=0;i<16;i++) {
-	    params[i] = (GLint) ctx->ColorMatrix.m[i];
+	    params[i] = (GLint) ctx->ColorMatrixStack.Top->m[i];
 	 }
 	 break;
       case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
          CHECK_EXTENSION_I(SGI_color_matrix);
-         *params = ctx->ColorStackDepth + 1;
+         *params = ctx->ColorMatrixStack.Depth + 1;
          break;
       case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
          CHECK_EXTENSION_I(SGI_color_matrix);
@@ -5121,7 +5121,7 @@
          break;
 
       /* GL_NV_vertex_program */
-         /* to do */
+         /* XXX to do */
 
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" );
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index c5f7415..9286642 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -1,4 +1,4 @@
-/* $Id: light.c,v 1.47 2001/12/14 02:50:02 brianp Exp $ */
+/* $Id: light.c,v 1.48 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -117,7 +117,7 @@
    case GL_POSITION: {
       GLfloat tmp[4];
       /* transform position by ModelView matrix */
-      TRANSFORM_POINT( tmp, ctx->ModelView.m, params );
+      TRANSFORM_POINT( tmp, ctx->ModelviewMatrixStack.Top->m, params );
       if (TEST_EQ_4V(l->EyePosition, tmp))
 	 return;
       FLUSH_VERTICES(ctx, _NEW_LIGHT);
@@ -131,10 +131,10 @@
    case GL_SPOT_DIRECTION: {
       GLfloat tmp[4];
       /* transform direction by inverse modelview */
-      if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-	 _math_matrix_analyse( &ctx->ModelView );
+      if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
+	 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
       }
-      TRANSFORM_NORMAL( tmp, params, ctx->ModelView.inv );
+      TRANSFORM_NORMAL( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
       if (TEST_EQ_3V(l->EyeDirection, tmp))
 	 return;
       FLUSH_VERTICES(ctx, _NEW_LIGHT);
@@ -1254,7 +1254,7 @@
       COPY_3V( ctx->_EyeZDir, eye_z );
    }
    else {
-      TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m );
+      TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
    }
 
    foreach (light, &ctx->Light.EnabledList) {
@@ -1263,7 +1263,7 @@
 	 COPY_4FV( light->_Position, light->EyePosition );
       }
       else {
-	 TRANSFORM_POINT( light->_Position, ctx->ModelView.inv,
+	 TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
 			  light->EyePosition );
       }
 
@@ -1287,7 +1287,7 @@
          else {
 	    TRANSFORM_NORMAL( light->_NormDirection,
 			      light->EyeDirection,
-			      ctx->ModelView.m);
+			      ctx->ModelviewMatrixStack.Top->m);
 	 }
 
 	 NORMALIZE_3FV( light->_NormDirection );
diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
index 763669e..6dbb414 100644
--- a/src/mesa/main/matrix.c
+++ b/src/mesa/main/matrix.c
@@ -1,8 +1,8 @@
-/* $Id: matrix.c,v 1.37 2001/12/14 02:50:02 brianp Exp $ */
+/* $Id: matrix.c,v 1.38 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  *
@@ -52,61 +52,14 @@
 #endif
 
 
-/**********************************************************************/
-/*                        API functions                               */
-/**********************************************************************/
-
-
-#define GET_ACTIVE_MATRIX(mat, where)					\
-do {									\
-   GLint n;								\
-   if (MESA_VERBOSE&VERBOSE_API) fprintf(stderr, "%s\n", where);	\
-   switch (ctx->Transform.MatrixMode) {					\
-      case GL_MODELVIEW:						\
-	 mat = &ctx->ModelView;						\
-	 ctx->NewState |= _NEW_MODELVIEW;				\
-	 break;								\
-      case GL_PROJECTION:						\
-	 mat = &ctx->ProjectionMatrix;					\
-	 ctx->NewState |= _NEW_PROJECTION;				\
-	 break;								\
-      case GL_TEXTURE:							\
-	 mat = &ctx->TextureMatrix[ctx->Texture.CurrentUnit];		\
-	 ctx->NewState |= _NEW_TEXTURE_MATRIX;				\
-	 break;								\
-      case GL_COLOR:							\
-	 mat = &ctx->ColorMatrix;					\
-	 ctx->NewState |= _NEW_COLOR_MATRIX;				\
-	 break;								\
-      case GL_MATRIX0_NV:						\
-      case GL_MATRIX1_NV:						\
-      case GL_MATRIX2_NV:						\
-      case GL_MATRIX3_NV:						\
-      case GL_MATRIX4_NV:						\
-      case GL_MATRIX5_NV:						\
-      case GL_MATRIX6_NV:						\
-      case GL_MATRIX7_NV:						\
-	 n = ctx->Transform.MatrixMode - GL_MATRIX0_NV;			\
-	 mat = &ctx->VertexProgram.Matrix[n];				\
-	 ctx->NewState |= _NEW_TRACK_MATRIX;				\
-	 break;								\
-      default:								\
-         _mesa_problem(ctx, where);					\
-   }									\
-} while (0)
-
-
 void
 _mesa_Frustum( GLdouble left, GLdouble right,
                GLdouble bottom, GLdouble top,
                GLdouble nearval, GLdouble farval )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   GET_ACTIVE_MATRIX(mat, "glFrustrum");
-
    if (nearval <= 0.0 ||
        farval <= 0.0 ||
        nearval == farval ||
@@ -117,9 +70,11 @@
       return;
    }
 
-   _math_matrix_frustum( mat, (GLfloat) left, (GLfloat) right, 
+   _math_matrix_frustum( ctx->CurrentStack->Top,
+                         (GLfloat) left, (GLfloat) right, 
 			 (GLfloat) bottom, (GLfloat) top, 
 			 (GLfloat) nearval, (GLfloat) farval );
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
@@ -129,11 +84,8 @@
              GLdouble nearval, GLdouble farval )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   GET_ACTIVE_MATRIX(mat, "glOrtho");
-
    if (left == right ||
        bottom == top ||
        nearval == farval)
@@ -142,9 +94,11 @@
       return;
    }
 
-   _math_matrix_ortho( mat, (GLfloat) left, (GLfloat) right, 
+   _math_matrix_ortho( ctx->CurrentStack->Top,
+                       (GLfloat) left, (GLfloat) right, 
 		       (GLfloat) bottom, (GLfloat) top, 
 		       (GLfloat) nearval, (GLfloat) farval );
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
@@ -154,32 +108,43 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
+   if (ctx->Transform.MatrixMode == mode)
+      return;
+   FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+
    switch (mode) {
-      case GL_MATRIX0_NV:
-      case GL_MATRIX1_NV:
-      case GL_MATRIX2_NV:
-      case GL_MATRIX3_NV:
-      case GL_MATRIX4_NV:
-      case GL_MATRIX5_NV:
-      case GL_MATRIX6_NV:
-      case GL_MATRIX7_NV:
-         if (!ctx->Extensions.NV_vertex_program) {
-            _mesa_error( ctx,  GL_INVALID_ENUM, "glMatrixMode" );
-            return;
-         }
-         /* FALL-THROUGH */
-      case GL_MODELVIEW:
-      case GL_PROJECTION:
-      case GL_TEXTURE:
-      case GL_COLOR:
-	 if (ctx->Transform.MatrixMode == mode)
-	    return;
-         ctx->Transform.MatrixMode = mode;
-	 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
-         break;
-      default:
+   case GL_MODELVIEW:
+      ctx->CurrentStack = &ctx->ModelviewMatrixStack;
+      break;
+   case GL_PROJECTION:
+      ctx->CurrentStack = &ctx->ProjectionMatrixStack;
+      break;
+   case GL_TEXTURE:
+      ctx->CurrentStack = &ctx->TextureMatrixStack[ctx->Texture.CurrentUnit];
+      break;
+   case GL_COLOR:
+      ctx->CurrentStack = &ctx->ColorMatrixStack;
+      break;
+   case GL_MATRIX0_NV:
+   case GL_MATRIX1_NV:
+   case GL_MATRIX2_NV:
+   case GL_MATRIX3_NV:
+   case GL_MATRIX4_NV:
+   case GL_MATRIX5_NV:
+   case GL_MATRIX6_NV:
+   case GL_MATRIX7_NV:
+      if (!ctx->Extensions.NV_vertex_program) {
          _mesa_error( ctx,  GL_INVALID_ENUM, "glMatrixMode" );
+         return;
+      }
+      ctx->CurrentStack = &ctx->ProgramMatrixStack[mode - GL_MATRIX0_NV];
+      break;
+   default:
+      _mesa_error( ctx,  GL_INVALID_ENUM, "glMatrixMode" );
+      return;
    }
+
+   ctx->Transform.MatrixMode = mode;
 }
 
 
@@ -188,51 +153,22 @@
 _mesa_PushMatrix( void )
 {
    GET_CURRENT_CONTEXT(ctx);
+   struct matrix_stack *stack = ctx->CurrentStack;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE&VERBOSE_API)
       fprintf(stderr, "glPushMatrix %s\n",
 	      _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
 
-   switch (ctx->Transform.MatrixMode) {
-      case GL_MODELVIEW:
-         if (ctx->ModelViewStackDepth >= MAX_MODELVIEW_STACK_DEPTH - 1) {
-            _mesa_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
-            return;
-         }
-         _math_matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++],
-                      &ctx->ModelView );
-         break;
-      case GL_PROJECTION:
-         if (ctx->ProjectionStackDepth >= MAX_PROJECTION_STACK_DEPTH - 1) {
-            _mesa_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
-            return;
-         }
-         _math_matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++],
-                      &ctx->ProjectionMatrix );
-         break;
-      case GL_TEXTURE:
-         {
-            GLuint t = ctx->Texture.CurrentUnit;
-            if (ctx->TextureStackDepth[t] >= MAX_TEXTURE_STACK_DEPTH - 1) {
-               _mesa_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
-               return;
-            }
-	    _math_matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++],
-                         &ctx->TextureMatrix[t] );
-         }
-         break;
-      case GL_COLOR:
-         if (ctx->ColorStackDepth >= MAX_COLOR_STACK_DEPTH - 1) {
-            _mesa_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
-            return;
-         }
-         _math_matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++],
-                      &ctx->ColorMatrix );
-         break;
-      default:
-         _mesa_problem(ctx, "Bad matrix mode in _mesa_PushMatrix");
+   if (stack->Depth + 1 >= stack->MaxDepth) {
+      _mesa_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix" );
+      return;
    }
+   _math_matrix_copy( &stack->Stack[stack->Depth + 1],
+                      &stack->Stack[stack->Depth] );
+   stack->Depth++;
+   stack->Top = &(stack->Stack[stack->Depth]);
+   ctx->NewState |= stack->DirtyFlag;
 }
 
 
@@ -241,56 +177,20 @@
 _mesa_PopMatrix( void )
 {
    GET_CURRENT_CONTEXT(ctx);
+   struct matrix_stack *stack = ctx->CurrentStack;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE&VERBOSE_API)
       fprintf(stderr, "glPopMatrix %s\n",
 	      _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode));
 
-   switch (ctx->Transform.MatrixMode) {
-      case GL_MODELVIEW:
-         if (ctx->ModelViewStackDepth==0) {
-            _mesa_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
-            return;
-         }
-         _math_matrix_copy( &ctx->ModelView,
-			    &ctx->ModelViewStack[--ctx->ModelViewStackDepth] );
-	 ctx->NewState |= _NEW_MODELVIEW;
-         break;
-      case GL_PROJECTION:
-         if (ctx->ProjectionStackDepth==0) {
-            _mesa_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
-            return;
-         }
-
-         _math_matrix_copy( &ctx->ProjectionMatrix,
-			    &ctx->ProjectionStack[--ctx->ProjectionStackDepth] );
-	 ctx->NewState |= _NEW_PROJECTION;
-         break;
-      case GL_TEXTURE:
-         {
-            GLuint t = ctx->Texture.CurrentUnit;
-            if (ctx->TextureStackDepth[t]==0) {
-               _mesa_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
-               return;
-            }
-	    _math_matrix_copy(&ctx->TextureMatrix[t],
-			      &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]);
-	    ctx->NewState |= _NEW_TEXTURE_MATRIX;
-         }
-         break;
-      case GL_COLOR:
-         if (ctx->ColorStackDepth==0) {
-            _mesa_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
-            return;
-         }
-         _math_matrix_copy(&ctx->ColorMatrix,
-			   &ctx->ColorStack[--ctx->ColorStackDepth]);
-	 ctx->NewState |= _NEW_COLOR_MATRIX;
-         break;
-      default:
-         _mesa_problem(ctx, "Bad matrix mode in _mesa_PopMatrix");
+   if (stack->Depth == 0) {
+      _mesa_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix" );
+      return;
    }
+   stack->Depth--;
+   stack->Top = &(stack->Stack[stack->Depth]);
+   ctx->NewState |= stack->DirtyFlag;
 }
 
 
@@ -299,10 +199,9 @@
 _mesa_LoadIdentity( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   GET_ACTIVE_MATRIX(mat, "glLoadIdentity");
-   _math_matrix_set_identity( mat );
+   _math_matrix_set_identity( ctx->CurrentStack->Top );
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
@@ -310,10 +209,9 @@
 _mesa_LoadMatrixf( const GLfloat *m )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   GET_ACTIVE_MATRIX(mat, "glLoadMatrix");
-   _math_matrix_loadf( mat, m );
+   _math_matrix_loadf( ctx->CurrentStack->Top, m );
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
@@ -336,10 +234,9 @@
 _mesa_MultMatrixf( const GLfloat *m )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   GET_ACTIVE_MATRIX(mat, "glMultMatrix");
-   _math_matrix_mul_floats( mat, m );
+   _math_matrix_mul_floats( ctx->CurrentStack->Top, m );
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
@@ -368,9 +265,8 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
    if (angle != 0.0F) {
-      GLmatrix *mat = 0;
-      GET_ACTIVE_MATRIX(mat, "glRotate");
-      _math_matrix_rotate( mat, angle, x, y, z );
+      _math_matrix_rotate( ctx->CurrentStack->Top, angle, x, y, z);
+      ctx->NewState |= ctx->CurrentStack->DirtyFlag;
    }
 }
 
@@ -388,10 +284,9 @@
 _mesa_Scalef( GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   GET_ACTIVE_MATRIX(mat, "glScale");
-   _math_matrix_scale( mat, x, y, z );
+   _math_matrix_scale( ctx->CurrentStack->Top, x, y, z);
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
@@ -409,10 +304,9 @@
 _mesa_Translatef( GLfloat x, GLfloat y, GLfloat z )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLmatrix *mat = 0;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-   GET_ACTIVE_MATRIX(mat, "glTranslate");
-   _math_matrix_translate( mat, x, y, z );
+   _math_matrix_translate( ctx->CurrentStack->Top, x, y, z);
+   ctx->NewState |= ctx->CurrentStack->DirtyFlag;
 }
 
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 3282017..f597c1d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.55 2001/12/14 02:50:02 brianp Exp $ */
+/* $Id: mtypes.h,v 1.56 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1131,8 +1131,6 @@
  */
 
 #define VP_MAX_INSTRUCTIONS 128
-#define VP_MAX_MATRICES 8
-#define VP_MAX_MATRIX_DEPTH 4
 
 #define VP_NUM_INPUT_REGS 16
 #define VP_NUM_OUTPUT_REGS 15
@@ -1251,7 +1249,8 @@
    GLubyte *String;                      /* Original user code */
    struct vp_instruction *Instructions;  /* Compiled instructions */
    GLenum Target;      /* GL_VERTEX_PROGRAM_NV or GL_VERTEX_STATE_PROGRAM_NV */
-   GLint ErrorPos;
+   GLint ErrorPos;            /* Position in string where error was detected */
+   GLint RefCount;            /* Since programs can be shared among contexts */
    GLboolean Resident;
 };
 
@@ -1259,21 +1258,17 @@
 /*
  * State vars for GL_NV_vertex_program
  */
-struct gl_vertex_program
+struct vertex_program_state
 {
    GLboolean Enabled;                    /* GL_VERTEX_PROGRAM_NV */
    GLboolean PointSizeEnabled;           /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
-   GLboolean TwoSideEnabled;            /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
-   GLuint Binding;                       /* currently bound program */
-   struct _mesa_HashTable *HashTable;    /* all programs */
+   GLboolean TwoSideEnabled;             /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
+   GLuint CurrentID;                     /* currently bound program's ID */
+   struct vp_program *Current;           /* ptr to currently bound program */
    struct vp_machine Machine;            /* machine state */
-   GLmatrix Matrix[VP_MAX_MATRICES];          /* Tracking matrices */
-   GLmatrix MatrixStack[VP_MAX_MATRICES][VP_MAX_MATRIX_DEPTH-1];  /* stacks */
-   GLuint MatrixStackDepth[VP_MAX_MATRICES];
 
    GLenum TrackMatrix[VP_NUM_PROG_REGS / 4];
    GLenum TrackMatrixTransform[VP_NUM_PROG_REGS / 4];
-
 };
 
 
@@ -1294,6 +1289,9 @@
    struct gl_texture_object *Default3D;
    struct gl_texture_object *DefaultCubeMap;
 
+   /* GL_NV_vertex_program */
+   struct _mesa_HashTable *VertexPrograms;
+
    void *DriverData;  /* Device driver shared state */
 };
 
@@ -1439,10 +1437,10 @@
 /* XXX just an idea */
 struct matrix_stack
 {
-   GLmatrix Top;
-   GLmatrix *Stack;
-   GLuint Depth;
-   GLuint MaxDepth;
+   GLmatrix *Top;      /* points into Stack */
+   GLmatrix *Stack;    /* array [MaxDepth] of GLmatrix */
+   GLuint Depth;       /* 0 <= Depth < MaxDepth */
+   GLuint MaxDepth;    /* size of Stack[] array */
    GLuint DirtyFlag;   /* _NEW_MODELVIEW or _NEW_PROJECTION, for example */
 };
 
@@ -1654,32 +1652,17 @@
    /* Core/Driver constants */
    struct gl_constants Const;
 
-   /* Modelview matrix and stack */
-   GLmatrix ModelView;           /* current matrix, not stored on stack */
-   GLuint ModelViewStackDepth;
-   GLmatrix ModelViewStack[MAX_MODELVIEW_STACK_DEPTH - 1];
-#if 1
-   struct matrix_stack ModelviewStack;
-#endif
-
-   /* Projection matrix and stack */
-   GLmatrix ProjectionMatrix;    /* current matrix, not stored on stack */
-   GLuint ProjectionStackDepth;
-   GLmatrix ProjectionStack[MAX_PROJECTION_STACK_DEPTH - 1];
+   /* The various 4x4 matrix stacks */
+   struct matrix_stack ModelviewMatrixStack;
+   struct matrix_stack ProjectionMatrixStack;
+   struct matrix_stack ColorMatrixStack;
+   struct matrix_stack TextureMatrixStack[MAX_TEXTURE_UNITS];
+   struct matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
+   struct matrix_stack *CurrentStack; /* Points to one of the above stacks */
 
    /* Combined modelview and projection matrix */
    GLmatrix _ModelProjectMatrix;
 
-   /* Texture matrix and stack */
-   GLmatrix TextureMatrix[MAX_TEXTURE_UNITS];
-   GLuint TextureStackDepth[MAX_TEXTURE_UNITS];
-   GLmatrix TextureStack[MAX_TEXTURE_UNITS][MAX_TEXTURE_STACK_DEPTH - 1];
-
-   /* Color matrix and stack */
-   GLmatrix ColorMatrix;
-   GLuint ColorStackDepth;
-   GLmatrix ColorStack[MAX_COLOR_STACK_DEPTH - 1];
-
    /* Display lists */
    GLuint CallDepth;		/* Current recursion calling depth */
    GLboolean ExecuteFlag;	/* Execute GL commands? */
@@ -1745,7 +1728,7 @@
    struct gl_color_table PostColorMatrixColorTable;
    struct gl_color_table ProxyPostColorMatrixColorTable;
 
-   struct gl_vertex_program VertexProgram;  /* GL_NV_vertex_program */
+   struct vertex_program_state VertexProgram;  /* GL_NV_vertex_program */
 
    GLenum ErrorValue;        /* Last error code */
    GLenum RenderMode;        /* either GL_RENDER, GL_SELECT, GL_FEEDBACK */
@@ -1759,13 +1742,13 @@
    GLuint _NeedEyeCoords;
    GLuint _NeedNormals;    /* Are vertex normal vectors needed? */
 
-   struct gl_shine_tab *_ShineTable[2];  /* Active shine tables */
-   struct gl_shine_tab *_ShineTabList;   /* Mru list of inactive shine tables */
+   struct gl_shine_tab *_ShineTable[2]; /* Active shine tables */
+   struct gl_shine_tab *_ShineTabList;  /* Mru list of inactive shine tables */
 
    struct gl_list_extensions listext; /* driver dlist extensions */
 
 
-   GLboolean OcclusionResult;  /* GL_HP_occlusion_test */
+   GLboolean OcclusionResult;       /* GL_HP_occlusion_test */
    GLboolean OcclusionResultSaved;  /* GL_HP_occlusion_test */
 
    /* Z buffer stuff */
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index b6fe7b2..c7667a2 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -1,4 +1,4 @@
-/* $Id: pixel.c,v 1.32 2001/12/04 23:45:31 brianp Exp $ */
+/* $Id: pixel.c,v 1.33 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -852,7 +852,7 @@
    const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
    const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
    const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
-   const GLfloat *m = ctx->ColorMatrix.m;
+   const GLfloat *m = ctx->ColorMatrixStack.Top->m;
    GLuint i;
    for (i = 0; i < n; i++) {
       const GLfloat r = rgba[i][RCOMP];
diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c
index 276c54c..d702458 100644
--- a/src/mesa/main/rastpos.c
+++ b/src/mesa/main/rastpos.c
@@ -1,4 +1,4 @@
-/* $Id: rastpos.c,v 1.33 2001/12/14 02:50:02 brianp Exp $ */
+/* $Id: rastpos.c,v 1.34 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -286,7 +286,7 @@
       _mesa_update_state( ctx );
 
    ASSIGN_4V( v, x, y, z, w );
-   TRANSFORM_POINT( eye, ctx->ModelView.m, v );
+   TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, v );
 
    /* raster color */
    if (ctx->Light.Enabled) {
@@ -294,7 +294,7 @@
       GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
 
       if (ctx->_NeedEyeCoords) {
-	 GLfloat *inv = ctx->ModelView.inv;
+	 GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv;
 	 TRANSFORM_NORMAL( eyenorm, objnorm, inv );
 	 norm = eyenorm;
       }
@@ -326,7 +326,7 @@
                       GL_SQRT( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );
 
    /* apply projection matrix:  clip = Proj * eye */
-   TRANSFORM_POINT( clip, ctx->ProjectionMatrix.m, eye );
+   TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
 
    /* clip to view volume */
    if (ctx->Transform.RasterPositionUnclipped) {
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index dd53c81..82b2ea1 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -1,4 +1,4 @@
-/* $Id: state.c,v 1.74 2001/12/14 03:13:04 brianp Exp $ */
+/* $Id: state.c,v 1.75 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -557,8 +557,8 @@
 {
    if (!ctx->_NeedEyeCoords) {
       _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
-			       &ctx->ProjectionMatrix,
-			       &ctx->ModelView );
+			       ctx->ProjectionMatrixStack.Top,
+			       ctx->ModelviewMatrixStack.Top );
 
       _math_matrix_analyse( &ctx->_ModelProjectMatrix );
    }
@@ -568,11 +568,11 @@
 update_modelview_scale( GLcontext *ctx )
 {
    ctx->_ModelViewInvScale = 1.0F;
-   if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
+   if (ctx->ModelviewMatrixStack.Top->flags & (MAT_FLAG_UNIFORM_SCALE |
 			       MAT_FLAG_GENERAL_SCALE |
 			       MAT_FLAG_GENERAL_3D |
 			       MAT_FLAG_GENERAL) ) {
-      const GLfloat *m = ctx->ModelView.inv;
+      const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
       GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
       if (f < 1e-12) f = 1.0;
       if (ctx->_NeedEyeCoords)
@@ -651,7 +651,7 @@
 static void
 update_projection( GLcontext *ctx )
 {
-   _math_matrix_analyse( &ctx->ProjectionMatrix );
+   _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
 
    /* Recompute clip plane positions in clipspace.  This is also done
     * in _mesa_ClipPlane().
@@ -662,7 +662,7 @@
 	 if (ctx->Transform.ClipEnabled[p]) {
 	    _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
 				 ctx->Transform.EyeUserPlane[p],
-				 ctx->ProjectionMatrix.inv );
+				 ctx->ProjectionMatrixStack.Top->inv );
 	 }
       }
    }
@@ -712,7 +712,7 @@
    if (ctx->Pixel.PostConvolutionColorTableEnabled)
       mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
 
-   if (ctx->ColorMatrix.type != MATRIX_IDENTITY ||
+   if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
        ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
        ctx->Pixel.PostColorMatrixBias[0]  != 0.0F ||
        ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
@@ -754,14 +754,14 @@
    ctx->Texture._TexMatEnabled = 0;
 
    for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
-      if (ctx->TextureMatrix[i].flags & MAT_DIRTY) {
-	 _math_matrix_analyse( &ctx->TextureMatrix[i] );
+      if (ctx->TextureMatrixStack[i].Top->flags & MAT_DIRTY) {
+	 _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
 
 	 if (ctx->Driver.TextureMatrix)
-	    ctx->Driver.TextureMatrix( ctx, i, &ctx->TextureMatrix[i] );
+	    ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
 
 	 if (ctx->Texture.Unit[i]._ReallyEnabled &&
-	     ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+	     ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
 	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
       }
    }
@@ -874,7 +874,7 @@
 	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
       }
 
-      if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+      if (ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
 	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
    }
 
@@ -915,7 +915,7 @@
       _mesa_print_state("", new_state);
 
    if (new_state & _NEW_MODELVIEW)
-      _math_matrix_analyse( &ctx->ModelView );
+      _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 
    if (new_state & _NEW_PROJECTION)
       update_projection( ctx );
@@ -924,7 +924,7 @@
       update_texture_matrices( ctx );
 
    if (new_state & _NEW_COLOR_MATRIX)
-      _math_matrix_analyse( &ctx->ColorMatrix );
+      _math_matrix_analyse( ctx->ColorMatrixStack.Top );
 
    /* References ColorMatrix.type (derived above).
     */
@@ -953,7 +953,7 @@
    if (new_state & (_NEW_MODELVIEW|_NEW_LIGHT)) {
       ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT_MODELVIEW;
       if (ctx->Light.Enabled &&
-	  !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
+	  !TEST_MAT_FLAGS( ctx->ModelviewMatrixStack.Top, MAT_FLAGS_LENGTH_PRESERVING))
 	    ctx->_NeedEyeCoords |= NEED_EYE_LIGHT_MODELVIEW;
    }
 
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index f711ab3..827a6bd 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.61 2001/12/13 16:02:11 brianp Exp $ */
+/* $Id: texstate.c,v 1.62 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1706,10 +1706,10 @@
 	    GLfloat tmp[4];
 
             /* Transform plane equation by the inverse modelview matrix */
-            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               _math_matrix_analyse( &ctx->ModelView );
+            if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
+               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
             }
-            _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
+            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 	    if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
 	       return;
 	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -1762,10 +1762,10 @@
 	 else if (pname==GL_EYE_PLANE) {
 	    GLfloat tmp[4];
             /* Transform plane equation by the inverse modelview matrix */
-	    if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               _math_matrix_analyse( &ctx->ModelView );
+	    if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
+               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
             }
-            _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
+            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 	    if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
 		return;
 	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -1815,10 +1815,10 @@
 	 else if (pname==GL_EYE_PLANE) {
 	    GLfloat tmp[4];
             /* Transform plane equation by the inverse modelview matrix */
-            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               _math_matrix_analyse( &ctx->ModelView );
+            if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
+               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
             }
-            _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
+            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 	    if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
 	       return;
 	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -1862,10 +1862,10 @@
 	 else if (pname==GL_EYE_PLANE) {
 	    GLfloat tmp[4];
             /* Transform plane equation by the inverse modelview matrix */
-            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
-               _math_matrix_analyse( &ctx->ModelView );
+            if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
+               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
             }
-            _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
+            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
 	    if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
 	       return;
 	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
diff --git a/src/mesa/math/m_matrix.c b/src/mesa/math/m_matrix.c
index 91f26f1..e06b568 100644
--- a/src/mesa/math/m_matrix.c
+++ b/src/mesa/math/m_matrix.c
@@ -1,8 +1,8 @@
-/* $Id: m_matrix.c,v 1.9 2001/09/18 23:06:14 kschultz Exp $ */
+/* $Id: m_matrix.c,v 1.10 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  *
@@ -975,11 +975,10 @@
 void
 _math_matrix_ctr( GLmatrix *m )
 {
-   if ( m->m == 0 ) {
-      m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
-   }
-   MEMCPY( m->m, Identity, sizeof(Identity) );
-   m->inv = 0;
+   m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+   if (m->m)
+      MEMCPY( m->m, Identity, sizeof(Identity) );
+   m->inv = NULL;
    m->type = MATRIX_IDENTITY;
    m->flags = 0;
 }
@@ -987,13 +986,13 @@
 void
 _math_matrix_dtr( GLmatrix *m )
 {
-   if ( m->m != 0 ) {
+   if (m->m) {
       ALIGN_FREE( m->m );
-      m->m = 0;
+      m->m = NULL;
    }
-   if ( m->inv != 0 ) {
+   if (m->inv) {
       ALIGN_FREE( m->inv );
-      m->inv = 0;
+      m->inv = NULL;
    }
 }
 
@@ -1001,9 +1000,10 @@
 void
 _math_matrix_alloc_inv( GLmatrix *m )
 {
-   if ( m->inv == 0 ) {
+   if (!m->inv) {
       m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
-      MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
+      if (m->inv)
+         MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
    }
 }
 
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c
index dc2c677..4441141 100644
--- a/src/mesa/swrast/s_fog.c
+++ b/src/mesa/swrast/s_fog.c
@@ -1,4 +1,4 @@
-/* $Id: s_fog.c,v 1.15 2001/12/17 04:54:35 brianp Exp $ */
+/* $Id: s_fog.c,v 1.16 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -195,9 +195,10 @@
                             const GLdepth z[],
                             GLfloat fogFact[] )
 {
-   const GLboolean ortho = (ctx->ProjectionMatrix.m[15] != 0.0F);
-   const GLfloat p10 = ctx->ProjectionMatrix.m[10];
-   const GLfloat p14 = ctx->ProjectionMatrix.m[14];
+   const GLfloat *proj = ctx->ProjectionMatrixStack.Top->m;
+   const GLboolean ortho = (proj[15] != 0.0F);
+   const GLfloat p10 = proj[10];
+   const GLfloat p14 = proj[14];
    const GLfloat tz = ctx->Viewport._WindowMap.m[MAT_TZ];
    GLfloat szInv;
    GLuint i;
diff --git a/src/mesa/swrast_setup/ss_vbtmp.h b/src/mesa/swrast_setup/ss_vbtmp.h
index 682ca90..759c4d5 100644
--- a/src/mesa/swrast_setup/ss_vbtmp.h
+++ b/src/mesa/swrast_setup/ss_vbtmp.h
@@ -1,4 +1,4 @@
-/* $Id: ss_vbtmp.h,v 1.17 2001/07/17 19:39:32 keithw Exp $ */
+/* $Id: ss_vbtmp.h,v 1.18 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -73,8 +73,8 @@
       }
    }
 
-   proj = VB->ProjectedClipPtr->data[0];
-   proj_stride = VB->ProjectedClipPtr->stride;
+   proj = VB->NdcPtr->data[0];
+   proj_stride = VB->NdcPtr->stride;
 
    if (IND & FOG) {
       fog = VB->FogCoordPtr->data;
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index 130a3fe..ae1d7f5 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -1,4 +1,4 @@
-/* $Id: t_context.c,v 1.22 2001/07/19 15:54:35 brianp Exp $ */
+/* $Id: t_context.c,v 1.23 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -102,7 +102,7 @@
    _tnl_install_pipeline( ctx, _tnl_default_pipeline );
 
 
-   tnl->NeedProjCoords = GL_TRUE;
+   tnl->NeedNdcCoords = GL_TRUE;
    tnl->LoopbackDListCassettes = GL_FALSE;
    tnl->CalcDListNormalLengths = GL_TRUE;
 
@@ -210,8 +210,8 @@
 _tnl_need_projected_coords( GLcontext *ctx, GLboolean mode )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   if (tnl->NeedProjCoords != mode) {
-      tnl->NeedProjCoords = mode;
+   if (tnl->NeedNdcCoords != mode) {
+      tnl->NeedNdcCoords = mode;
       _tnl_InvalidateState( ctx, _NEW_PROJECTION );
    }
 }
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index dd0bfad..7b1954a 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -1,4 +1,4 @@
-/* $Id: t_context.h,v 1.33 2001/12/14 02:51:44 brianp Exp $ */
+/* $Id: t_context.h,v 1.34 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -260,7 +260,7 @@
    GLvector4f  *ObjPtr;		                /* VERT_OBJ_BIT */
    GLvector4f  *EyePtr;		                /* VERT_EYE */
    GLvector4f  *ClipPtr;	                /* VERT_CLIP */
-   GLvector4f  *ProjectedClipPtr;               /* VERT_CLIP (2) */
+   GLvector4f  *NdcPtr;                         /* VERT_CLIP (2) */
    GLubyte     ClipOrMask;	                /* VERT_CLIP (3) */
    GLubyte     *ClipMask;		        /* VERT_CLIP (4) */
    GLvector3f  *NormalPtr;	                /* VERT_NORMAL_BIT */
@@ -535,7 +535,7 @@
 
    /* Probably need a better configuration mechanism:
     */
-   GLboolean NeedProjCoords;
+   GLboolean NeedNdcCoords;
    GLboolean LoopbackDListCassettes;
    GLboolean CalcDListNormalLengths;
 
diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c
index 9e3d440..eebeba2 100644
--- a/src/mesa/tnl/t_vb_fog.c
+++ b/src/mesa/tnl/t_vb_fog.c
@@ -1,4 +1,4 @@
-/* $Id: t_vb_fog.c,v 1.13 2001/12/14 02:51:45 brianp Exp $ */
+/* $Id: t_vb_fog.c,v 1.14 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -145,7 +145,7 @@
       VB->FogCoordPtr = &store->fogcoord;
 
       if (!ctx->_NeedEyeCoords) {
-	 GLfloat *m = ctx->ModelView.m;
+	 const GLfloat *m = ctx->ModelviewMatrixStack.Top->m;
 	 GLfloat plane[4];
 
 	 /* Use this to store calculated eye z values:
diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c
index aff84b0..457acd2 100644
--- a/src/mesa/tnl/t_vb_normals.c
+++ b/src/mesa/tnl/t_vb_normals.c
@@ -1,4 +1,4 @@
-/* $Id: t_vb_normals.c,v 1.10 2001/12/14 02:51:45 brianp Exp $ */
+/* $Id: t_vb_normals.c,v 1.11 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -62,7 +62,7 @@
    ASSERT(store->NormalTransform);
 
    if (stage->changed_inputs)
-      store->NormalTransform( &ctx->ModelView,
+      store->NormalTransform( ctx->ModelviewMatrixStack.Top,
 			      ctx->_ModelViewInvScale,
 			      VB->NormalPtr,
 			      VB->NormalLengthPtr,
@@ -84,7 +84,7 @@
    if (ctx->_NeedEyeCoords) {
       GLuint transform = NORM_TRANSFORM_NO_ROT;
 
-      if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
+      if (ctx->ModelviewMatrixStack.Top->flags & (MAT_FLAG_GENERAL |
 				  MAT_FLAG_ROTATION |
 				  MAT_FLAG_GENERAL_3D |
 				  MAT_FLAG_PERSPECTIVE))
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index b713031..aea3c86 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -1,4 +1,4 @@
-/* $Id: t_vb_program.c,v 1.4 2001/12/15 22:31:23 brianp Exp $ */
+/* $Id: t_vb_program.c,v 1.5 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -718,7 +718,6 @@
    struct vp_stage_data *store = VP_STAGE_DATA(stage);
    struct vertex_buffer *VB = &tnl->vb;
    struct vp_machine *machine = &(ctx->VertexProgram.Machine);
-   struct vp_program *program;
    GLint i;
 
    /* convenience pointers */
@@ -734,9 +733,6 @@
    GLfloat (*texture2)[4] = (GLfloat (*)[4]) store->texCoord[2].data;
    GLfloat (*texture3)[4] = (GLfloat (*)[4]) store->texCoord[3].data;
 
-   program = (struct vp_program *) _mesa_HashLookup(ctx->VertexProgram.HashTable, ctx->VertexProgram.Binding);
-   assert(program);
-
    _mesa_init_tracked_matrices(ctx);
    _mesa_init_vp_registers(ctx);  /* sets temp regs to (0,0,0,1) */
 
@@ -770,7 +766,8 @@
       }
 
       /* execute the program */
-      _mesa_exec_program(ctx, program);
+      ASSERT(ctx->VertexProgram.Current);
+      _mesa_exec_program(ctx, ctx->VertexProgram.Current);
 
 #if 0
       printf("Output %d: %f, %f, %f, %f\n", i,
@@ -819,8 +816,8 @@
    store->ormask = 0;
    store->andmask = CLIP_ALL_BITS;
 
-   if (tnl->NeedProjCoords) {
-      VB->ProjectedClipPtr =
+   if (tnl->NeedNdcCoords) {
+      VB->NdcPtr =
          _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
                                             &store->ndcCoords,
                                             store->clipmask,
@@ -829,7 +826,7 @@
 
    }
    else {
-      VB->ProjectedClipPtr = 0;
+      VB->NdcPtr = 0;
       _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
                                             0,
                                             store->clipmask,
diff --git a/src/mesa/tnl/t_vb_texmat.c b/src/mesa/tnl/t_vb_texmat.c
index a0ed3e5..8cff96a 100644
--- a/src/mesa/tnl/t_vb_texmat.c
+++ b/src/mesa/tnl/t_vb_texmat.c
@@ -1,4 +1,4 @@
-/* $Id: t_vb_texmat.c,v 1.6 2001/12/14 02:51:45 brianp Exp $ */
+/* $Id: t_vb_texmat.c,v 1.7 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -86,7 +86,8 @@
    for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
       if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) {
 	 if (stage->changed_inputs & VERT_TEX(i))
-	    (void) TransformRaw( &store->texcoord[i], &ctx->TextureMatrix[i],
+	    (void) TransformRaw( &store->texcoord[i],
+                                 ctx->TextureMatrixStack[i].Top,
 				 VB->TexCoordPtr[i]);
 
 	 VB->TexCoordPtr[i] = &store->texcoord[i];
diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c
index f54d73b..8ceb9db 100644
--- a/src/mesa/tnl/t_vb_vertex.c
+++ b/src/mesa/tnl/t_vb_vertex.c
@@ -1,4 +1,4 @@
-/* $Id: t_vb_vertex.c,v 1.10 2001/12/14 02:51:45 brianp Exp $ */
+/* $Id: t_vb_vertex.c,v 1.11 2001/12/18 04:06:46 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -57,7 +57,7 @@
     */
    GLvector4f *save_eyeptr;
    GLvector4f *save_clipptr;
-   GLvector4f *save_projptr;
+   GLvector4f *save_ndcptr;
 };
 
 #define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr)
@@ -142,16 +142,18 @@
       if (ctx->_NeedEyeCoords) {
 	 /* Separate modelview and project transformations:
 	  */
-	 if (ctx->ModelView.type == MATRIX_IDENTITY)
+	 if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
 	    VB->EyePtr = VB->ObjPtr;
 	 else
-	    VB->EyePtr = TransformRaw( &store->eye, &ctx->ModelView,
+	    VB->EyePtr = TransformRaw( &store->eye,
+                                       ctx->ModelviewMatrixStack.Top,
 				       VB->ObjPtr);
 
-	 if (ctx->ProjectionMatrix.type == MATRIX_IDENTITY)
+	 if (ctx->ProjectionMatrixStack.Top->type == MATRIX_IDENTITY)
 	    VB->ClipPtr = VB->EyePtr;
 	 else
-	    VB->ClipPtr = TransformRaw( &store->clip, &ctx->ProjectionMatrix,
+	    VB->ClipPtr = TransformRaw( &store->clip,
+                                        ctx->ProjectionMatrixStack.Top,
 					VB->EyePtr );
       }
       else {
@@ -184,16 +186,17 @@
       store->ormask = 0;
       store->andmask = CLIP_ALL_BITS;
 
-      if (tnl->NeedProjCoords) {
-	 VB->ProjectedClipPtr =
+      if (tnl->NeedNdcCoords) {
+	 VB->NdcPtr =
 	    _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
                                                &store->proj,
                                                store->clipmask,
                                                &store->ormask,
                                                &store->andmask );
 
-      } else {
-	 VB->ProjectedClipPtr = 0;
+      }
+      else {
+	 VB->NdcPtr = 0;
 	 _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
                                                0,
                                                store->clipmask,
@@ -227,14 +230,14 @@
 
       store->save_eyeptr = VB->EyePtr;
       store->save_clipptr = VB->ClipPtr;
-      store->save_projptr = VB->ProjectedClipPtr;
+      store->save_ndcptr = VB->NdcPtr;
    }
    else {
       /* Replay the sideeffects.
        */
       VB->EyePtr = store->save_eyeptr;
       VB->ClipPtr = store->save_clipptr;
-      VB->ProjectedClipPtr = store->save_projptr;
+      VB->NdcPtr = store->save_ndcptr;
       VB->ClipMask = store->clipmask;
       VB->ClipOrMask = store->ormask;
       if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ_BIT))
diff --git a/src/mesa/x86/gen_matypes.c b/src/mesa/x86/gen_matypes.c
index 006a054..12021d7 100644
--- a/src/mesa/x86/gen_matypes.c
+++ b/src/mesa/x86/gen_matypes.c
@@ -1,4 +1,4 @@
-/* $Id: gen_matypes.c,v 1.4 2001/12/16 11:28:20 brianp Exp $ */
+/* $Id: gen_matypes.c,v 1.5 2001/12/18 04:06:45 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -122,7 +122,7 @@
    OFFSET( "VB_OBJ_PTR             ", struct vertex_buffer, ObjPtr );
    OFFSET( "VB_EYE_PTR             ", struct vertex_buffer, EyePtr );
    OFFSET( "VB_CLIP_PTR            ", struct vertex_buffer, ClipPtr );
-   OFFSET( "VB_PROJ_CLIP_PTR       ", struct vertex_buffer, ProjectedClipPtr );
+   OFFSET( "VB_PROJ_CLIP_PTR       ", struct vertex_buffer, NdcPtr );
    OFFSET( "VB_CLIP_OR_MASK        ", struct vertex_buffer, ClipOrMask );
    OFFSET( "VB_CLIP_MASK           ", struct vertex_buffer, ClipMask );
    OFFSET( "VB_NORMAL_PTR          ", struct vertex_buffer, NormalPtr );