Killed mmath.[ch]. Moved low-level functions/assembly code into imports.[ch]
[mesa.git] / src / mesa / main / state.c
index d331d434c6170ecc94f9059f8f9b130c68654aee..1051bda11da3c8fdf9fea141a1b97721a5141906 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: state.c,v 1.73 2001/12/14 02:50:02 brianp Exp $ */
+/* $Id: state.c,v 1.99 2003/03/01 01:50:22 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  5.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  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"),
@@ -31,9 +31,6 @@
  */
 
 
-#ifdef PC_HEADER
-#include "all.h"
-#else
 #include "glheader.h"
 #include "accum.h"
 #include "api_loopback.h"
 #include "fog.h"
 #include "hint.h"
 #include "histogram.h"
+#include "imports.h"
 #include "light.h"
 #include "lines.h"
 #include "matrix.h"
-#include "mmath.h"
 #include "pixel.h"
 #include "points.h"
 #include "polygon.h"
 #include "texstate.h"
 #include "mtypes.h"
 #include "varray.h"
-#include "vpstate.h"
+#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+#include "nvprogram.h"
+#endif
 
 #include "math/m_matrix.h"
 #include "math/m_xform.h"
-#endif
 
 
 static int
 generic_noop(void)
 {
 #ifdef DEBUG
-   _mesa_problem(NULL, "undefined function dispatch");
+   _mesa_problem(NULL, "User called no-op dispatch function");
 #endif
    return 0;
 }
@@ -296,6 +294,7 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
 
    /* 1.1 */
    exec->AreTexturesResident = _mesa_AreTexturesResident;
+   exec->AreTexturesResidentEXT = _mesa_AreTexturesResident;
    exec->BindTexture = _mesa_BindTexture;
    exec->ColorPointer = _mesa_ColorPointer;
    exec->CopyTexImage1D = _mesa_CopyTexImage1D;
@@ -307,10 +306,12 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->EdgeFlagPointer = _mesa_EdgeFlagPointer;
    exec->EnableClientState = _mesa_EnableClientState;
    exec->GenTextures = _mesa_GenTextures;
+   exec->GenTexturesEXT = _mesa_GenTextures;
    exec->GetPointerv = _mesa_GetPointerv;
    exec->IndexPointer = _mesa_IndexPointer;
    exec->InterleavedArrays = _mesa_InterleavedArrays;
    exec->IsTexture = _mesa_IsTexture;
+   exec->IsTextureEXT = _mesa_IsTexture;
    exec->NormalPointer = _mesa_NormalPointer;
    exec->PopClientAttrib = _mesa_PopClientAttrib;
    exec->PrioritizeTextures = _mesa_PrioritizeTextures;
@@ -343,18 +344,31 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->CopyConvolutionFilter1D = _mesa_CopyConvolutionFilter1D;
    exec->CopyConvolutionFilter2D = _mesa_CopyConvolutionFilter2D;
    exec->GetColorTable = _mesa_GetColorTable;
+   exec->GetColorTableEXT = _mesa_GetColorTable;
    exec->GetColorTableParameterfv = _mesa_GetColorTableParameterfv;
+   exec->GetColorTableParameterfvEXT = _mesa_GetColorTableParameterfv;
    exec->GetColorTableParameteriv = _mesa_GetColorTableParameteriv;
+   exec->GetColorTableParameterivEXT = _mesa_GetColorTableParameteriv;
    exec->GetConvolutionFilter = _mesa_GetConvolutionFilter;
+   exec->GetConvolutionFilterEXT = _mesa_GetConvolutionFilter;
    exec->GetConvolutionParameterfv = _mesa_GetConvolutionParameterfv;
+   exec->GetConvolutionParameterfvEXT = _mesa_GetConvolutionParameterfv;
    exec->GetConvolutionParameteriv = _mesa_GetConvolutionParameteriv;
+   exec->GetConvolutionParameterivEXT = _mesa_GetConvolutionParameteriv;
    exec->GetHistogram = _mesa_GetHistogram;
+   exec->GetHistogramEXT = _mesa_GetHistogram;
    exec->GetHistogramParameterfv = _mesa_GetHistogramParameterfv;
+   exec->GetHistogramParameterfvEXT = _mesa_GetHistogramParameterfv;
    exec->GetHistogramParameteriv = _mesa_GetHistogramParameteriv;
+   exec->GetHistogramParameterivEXT = _mesa_GetHistogramParameteriv;
    exec->GetMinmax = _mesa_GetMinmax;
+   exec->GetMinmaxEXT = _mesa_GetMinmax;
    exec->GetMinmaxParameterfv = _mesa_GetMinmaxParameterfv;
+   exec->GetMinmaxParameterfvEXT = _mesa_GetMinmaxParameterfv;
    exec->GetMinmaxParameteriv = _mesa_GetMinmaxParameteriv;
+   exec->GetMinmaxParameterivEXT = _mesa_GetMinmaxParameteriv;
    exec->GetSeparableFilter = _mesa_GetSeparableFilter;
+   exec->GetSeparableFilterEXT = _mesa_GetSeparableFilter;
    exec->Histogram = _mesa_Histogram;
    exec->Minmax = _mesa_Minmax;
    exec->ResetHistogram = _mesa_ResetHistogram;
@@ -425,6 +439,10 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->LockArraysEXT = _mesa_LockArraysEXT;
    exec->UnlockArraysEXT = _mesa_UnlockArraysEXT;
 
+   /* 148. GL_EXT_multi_draw_arrays */
+   exec->MultiDrawArraysEXT = _mesa_MultiDrawArraysEXT;
+   exec->MultiDrawElementsEXT = _mesa_MultiDrawElementsEXT;
+
    /* 173. GL_INGR_blend_func_separate */
    exec->BlendFuncSeparateEXT = _mesa_BlendFuncSeparateEXT;
 
@@ -457,7 +475,8 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->WindowPos4sMESA = _mesa_WindowPos4sMESA;
    exec->WindowPos4svMESA = _mesa_WindowPos4svMESA;
 
-   /* ###. GL_NV_vertex_program */
+   /* 233. GL_NV_vertex_program */
+#if FEATURE_NV_vertex_program
    exec->BindProgramNV = _mesa_BindProgramNV;
    exec->DeleteProgramsNV = _mesa_DeleteProgramsNV;
    exec->ExecuteProgramNV = _mesa_ExecuteProgramNV;
@@ -483,6 +502,29 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->ProgramParameters4fvNV = _mesa_ProgramParameters4fvNV;
    exec->TrackMatrixNV = _mesa_TrackMatrixNV;
    exec->VertexAttribPointerNV = _mesa_VertexAttribPointerNV;
+#endif
+
+#if 0 && FEATURE_NV_fragment_program
+   exec->ProgramNamedParameter4fNV = _mesa_ProgramNamedParameter4fNV;
+   exec->ProgramNamedParameter4dNV = _mesa_ProgramNamedParameter4dNV;
+   exec->ProgramNamedParameter4fvNV = _mesa_ProgramNamedParameter4fvNV;
+   exec->ProgramNamedParameter4dvNV = _mesa_ProgramNamedParameter4dvNV;
+   exec->GetProgramNamedParameterfvNV = _mesa_GetProgramNamedParameterfvNV;
+   exec->GetProgramNamedParameterdvNV = _mesa_GetProgramNamedParameterdvNV;
+   exec->ProgramLocalParameter4dARB = _mesa_ProgramLocalParameter4dARB;
+   exec->ProgramLocalParameter4dvARB = _mesa_ProgramLocalParameter4dvARB;
+   exec->ProgramLocalParameter4fARB = _mesa_ProgramLocalParameter4fARB;
+   exec->ProgramLocalParameter4fvARB = _mesa_ProgramLocalParameter4fvARB;
+   exec->GetProgramLocalParameterdvARB = _mesa_GetProgramLocalParameterdvARB;
+   exec->GetProgramLocalParameterfvARB = _mesa_GetProgramLocalParameterfvARB;
+#endif
+
+   /* 262. GL_NV_point_sprite */
+   exec->PointParameteriNV = _mesa_PointParameteriNV;
+   exec->PointParameterivNV = _mesa_PointParameterivNV;
+
+   /* 268. GL_EXT_stencil_two_side */
+   exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT;
 
    /* ARB 1. GL_ARB_multitexture */
    exec->ActiveTextureARB = _mesa_ActiveTextureARB;
@@ -506,23 +548,8 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->CompressedTexSubImage1DARB = _mesa_CompressedTexSubImage1DARB;
    exec->GetCompressedTexImageARB = _mesa_GetCompressedTexImageARB;
 
-   /* GL_ARB_window_pos */
-   exec->WindowPos2dARB = _mesa_WindowPos2dARB;
-   exec->WindowPos2dvARB = _mesa_WindowPos2dvARB;
-   exec->WindowPos2fARB = _mesa_WindowPos2fARB;
-   exec->WindowPos2fvARB = _mesa_WindowPos2fvARB;
-   exec->WindowPos2iARB = _mesa_WindowPos2iARB;
-   exec->WindowPos2ivARB = _mesa_WindowPos2ivARB;
-   exec->WindowPos2sARB = _mesa_WindowPos2sARB;
-   exec->WindowPos2svARB = _mesa_WindowPos2svARB;
-   exec->WindowPos3dARB = _mesa_WindowPos3dARB;
-   exec->WindowPos3dvARB = _mesa_WindowPos3dvARB;
-   exec->WindowPos3fARB = _mesa_WindowPos3fARB;
-   exec->WindowPos3fvARB = _mesa_WindowPos3fvARB;
-   exec->WindowPos3iARB = _mesa_WindowPos3iARB;
-   exec->WindowPos3ivARB = _mesa_WindowPos3ivARB;
-   exec->WindowPos3sARB = _mesa_WindowPos3sARB;
-   exec->WindowPos3svARB = _mesa_WindowPos3svARB;
+   /* ARB 14. GL_ARB_point_parameters */
+   /* reuse EXT_point_parameters functions */
 }
 
 
@@ -532,6 +559,10 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
 /**********************************************************************/
 
 
+/*
+ * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET
+ * in ctx->_TriangleCaps if needed.
+ */
 static void
 update_polygon( GLcontext *ctx )
 {
@@ -541,44 +572,38 @@ update_polygon( GLcontext *ctx )
       ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
 
    /* Any Polygon offsets enabled? */
-   ctx->Polygon._OffsetAny = GL_FALSE;
-   ctx->_TriangleCaps &= ~DD_TRI_OFFSET;
-
    if (ctx->Polygon.OffsetPoint ||
        ctx->Polygon.OffsetLine ||
        ctx->Polygon.OffsetFill) {
       ctx->_TriangleCaps |= DD_TRI_OFFSET;
-      ctx->Polygon._OffsetAny = GL_TRUE;
    }
 }
 
 static void
 calculate_model_project_matrix( GLcontext *ctx )
 {
-   if (!ctx->_NeedEyeCoords) {
-      _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
-                              &ctx->ProjectionMatrix,
-                              &ctx->ModelView );
+   _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix,
+                            ctx->ProjectionMatrixStack.Top,
+                            ctx->ModelviewMatrixStack.Top );
 
-      _math_matrix_analyse( &ctx->_ModelProjectMatrix );
-   }
+   _math_matrix_analyse( &ctx->_ModelProjectMatrix );
 }
 
 static void
 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)
-        ctx->_ModelViewInvScale = (GLfloat) (1.0/GL_SQRT(f));
+        ctx->_ModelViewInvScale = 1.0F / SQRTF(f);
       else
-        ctx->_ModelViewInvScale = (GLfloat) GL_SQRT(f);
+        ctx->_ModelViewInvScale = SQRTF(f);
    }
 }
 
@@ -595,7 +620,6 @@ update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords )
       /* Recalculate all state that depends on _NeedEyeCoords.
        */
       update_modelview_scale(ctx);
-      calculate_model_project_matrix(ctx);
       _mesa_compute_light_positions( ctx );
 
       if (ctx->Driver.LightingSpaceChange)
@@ -610,9 +634,6 @@ update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords )
       if (new_state & _NEW_MODELVIEW)
         update_modelview_scale(ctx);
 
-      if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
-        calculate_model_project_matrix(ctx);
-
       if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
         _mesa_compute_light_positions( ctx );
    }
@@ -646,23 +667,23 @@ update_drawbuffer( GLcontext *ctx )
 /* NOTE: This routine references Tranform attribute values to compute
  * userclip positions in clip space, but is only called on
  * _NEW_PROJECTION.  The _mesa_ClipPlane() function keeps these values
- * uptodate across changes to the Transform attributes.
+ * up to date across changes to the Transform attributes.
  */
 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().
     */
-   if (ctx->Transform._AnyClip) {
+   if (ctx->Transform.ClipPlanesEnabled) {
       GLuint p;
       for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
-        if (ctx->Transform.ClipEnabled[p]) {
+        if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
            _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
                                 ctx->Transform.EyeUserPlane[p],
-                                ctx->ProjectionMatrix.inv );
+                                ctx->ProjectionMatrixStack.Top->inv );
         }
       }
    }
@@ -712,7 +733,7 @@ update_image_transfer_state(GLcontext *ctx)
    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,15 +775,15 @@ update_texture_matrices( GLcontext *ctx )
    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->Driver.TextureMatrix)
-           ctx->Driver.TextureMatrix( ctx, i, &ctx->TextureMatrix[i] );
+      if (ctx->TextureMatrixStack[i].Top->flags & MAT_DIRTY) {
+        _math_matrix_analyse( 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);
+
+        if (ctx->Driver.TextureMatrix)
+           ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
       }
    }
 }
@@ -779,9 +800,9 @@ update_texture_matrices( GLcontext *ctx )
 static void
 update_texture_state( GLcontext *ctx )
 {
-   GLuint i;
+   GLuint unit;
 
-   ctx->Texture._ReallyEnabled = 0;
+   ctx->Texture._EnabledUnits = 0;
    ctx->Texture._GenFlags = 0;
    ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN;
    ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN;
@@ -790,8 +811,8 @@ update_texture_state( GLcontext *ctx )
 
    /* Update texture unit state.
     */
-   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
-      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
 
       texUnit->_ReallyEnabled = 0;
       texUnit->_GenFlags = 0;
@@ -799,49 +820,60 @@ update_texture_state( GLcontext *ctx )
       if (!texUnit->Enabled)
         continue;
 
-      /* Find the texture of highest dimensionality that is enabled
-       * and complete.  We'll use it for texturing.
+      /* Look for the highest-priority texture target that's enabled and
+       * complete.  That's the one we'll use for texturing.
        */
-      if (texUnit->Enabled & TEXTURE0_CUBE) {
+      if (texUnit->Enabled & TEXTURE_CUBE_BIT) {
          struct gl_texture_object *texObj = texUnit->CurrentCubeMap;
          if (!texObj->Complete) {
             _mesa_test_texobj_completeness(ctx, texObj);
          }
          if (texObj->Complete) {
-            texUnit->_ReallyEnabled = TEXTURE0_CUBE;
+            texUnit->_ReallyEnabled = TEXTURE_CUBE_BIT;
             texUnit->_Current = texObj;
          }
       }
 
-      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_3D)) {
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_3D_BIT)) {
          struct gl_texture_object *texObj = texUnit->Current3D;
          if (!texObj->Complete) {
             _mesa_test_texobj_completeness(ctx, texObj);
          }
          if (texObj->Complete) {
-            texUnit->_ReallyEnabled = TEXTURE0_3D;
+            texUnit->_ReallyEnabled = TEXTURE_3D_BIT;
             texUnit->_Current = texObj;
          }
       }
 
-      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_2D)) {
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_RECT_BIT)) {
+         struct gl_texture_object *texObj = texUnit->CurrentRect;
+         if (!texObj->Complete) {
+            _mesa_test_texobj_completeness(ctx, texObj);
+         }
+         if (texObj->Complete) {
+            texUnit->_ReallyEnabled = TEXTURE_RECT_BIT;
+            texUnit->_Current = texObj;
+         }
+      }
+
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_2D_BIT)) {
          struct gl_texture_object *texObj = texUnit->Current2D;
          if (!texObj->Complete) {
             _mesa_test_texobj_completeness(ctx, texObj);
          }
          if (texObj->Complete) {
-            texUnit->_ReallyEnabled = TEXTURE0_2D;
+            texUnit->_ReallyEnabled = TEXTURE_2D_BIT;
             texUnit->_Current = texObj;
          }
       }
 
-      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_1D)) {
+      if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_1D_BIT)) {
          struct gl_texture_object *texObj = texUnit->Current1D;
          if (!texObj->Complete) {
             _mesa_test_texobj_completeness(ctx, texObj);
          }
          if (texObj->Complete) {
-            texUnit->_ReallyEnabled = TEXTURE0_1D;
+            texUnit->_ReallyEnabled = TEXTURE_1D_BIT;
             texUnit->_Current = texObj;
          }
       }
@@ -851,10 +883,8 @@ update_texture_state( GLcontext *ctx )
         continue;
       }
 
-      {
-        GLuint flag = texUnit->_ReallyEnabled << (i * 4);
-        ctx->Texture._ReallyEnabled |= flag;
-      }
+      if (texUnit->_ReallyEnabled)
+         ctx->Texture._EnabledUnits |= (1 << unit);
 
       if (texUnit->TexGenEnabled) {
         if (texUnit->TexGenEnabled & S_BIT) {
@@ -870,12 +900,12 @@ update_texture_state( GLcontext *ctx )
            texUnit->_GenFlags |= texUnit->_GenBitR;
         }
 
-        ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(i);
+        ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
         ctx->Texture._GenFlags |= texUnit->_GenFlags;
       }
 
-      if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
-        ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
+      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
+        ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
    }
 
    if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) {
@@ -889,6 +919,7 @@ update_texture_state( GLcontext *ctx )
 }
 
 
+
 /*
  * If ctx->NewState is non-zero then this function MUST be called before
  * rendering any primitive.  Basically, function pointers and miscellaneous
@@ -912,10 +943,10 @@ void _mesa_update_state( GLcontext *ctx )
    const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
 
    if (MESA_VERBOSE & VERBOSE_STATE)
-      _mesa_print_state("", new_state);
+      _mesa_print_state("_mesa_update_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 +955,7 @@ void _mesa_update_state( GLcontext *ctx )
       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,11 +984,29 @@ void _mesa_update_state( GLcontext *ctx )
    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;
    }
 
 
+#if 0
+   /* XXX this is a bit of a hack.  We should be checking elsewhere if
+    * vertex program mode is enabled.  We set _NeedEyeCoords to zero to
+    * ensure that the combined modelview/projection matrix is computed
+    * in calculate_model_project_matrix().
+    */
+   if (ctx->VertexProgram.Enabled)
+      ctx->_NeedEyeCoords = 0;
+   /* KW: it's now always computed.
+    */
+#endif
+
+   /* Keep ModelviewProject uptodate always to allow tnl
+    * implementations that go model->clip even when eye is required.
+    */
+   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
+      calculate_model_project_matrix(ctx);
+
    /* ctx->_NeedEyeCoords is now uptodate.
     *
     * If the truth value of this variable has changed, update for the
@@ -968,7 +1017,6 @@ void _mesa_update_state( GLcontext *ctx )
     * light positions & normal transforms for other reasons.
     */
    if (new_state & (_NEW_MODELVIEW |
-                   _NEW_PROJECTION |
                    _NEW_LIGHT |
                    _MESA_NEW_NEED_EYE_COORDS))
       update_tnl_spaces( ctx, oldneedeyecoords );
@@ -992,7 +1040,6 @@ void _mesa_update_state( GLcontext *ctx )
    ASSERT(ctx->Driver.GetString);
    ASSERT(ctx->Driver.UpdateState);
    ASSERT(ctx->Driver.Clear);
-   ASSERT(ctx->Driver.SetDrawBuffer);
    ASSERT(ctx->Driver.GetBufferSize);
    if (ctx->Visual.accumRedBits > 0) {
       ASSERT(ctx->Driver.Accum);
@@ -1001,7 +1048,7 @@ void _mesa_update_state( GLcontext *ctx )
    ASSERT(ctx->Driver.ReadPixels);
    ASSERT(ctx->Driver.CopyPixels);
    ASSERT(ctx->Driver.Bitmap);
-   ASSERT(ctx->Driver.ResizeBuffersMESA);
+   ASSERT(ctx->Driver.ResizeBuffers);
    ASSERT(ctx->Driver.TexImage1D);
    ASSERT(ctx->Driver.TexImage2D);
    ASSERT(ctx->Driver.TexImage3D);
@@ -1014,9 +1061,6 @@ void _mesa_update_state( GLcontext *ctx )
    ASSERT(ctx->Driver.CopyTexSubImage2D);
    ASSERT(ctx->Driver.CopyTexSubImage3D);
    if (ctx->Extensions.ARB_texture_compression) {
-      ASSERT(ctx->Driver.BaseCompressedTexFormat);
-      ASSERT(ctx->Driver.CompressedTextureSize);
-      ASSERT(ctx->Driver.GetCompressedTexImage);
 #if 0  /* HW drivers need these, but not SW rasterizers */
       ASSERT(ctx->Driver.CompressedTexImage1D);
       ASSERT(ctx->Driver.CompressedTexImage2D);
@@ -1027,3 +1071,18 @@ void _mesa_update_state( GLcontext *ctx )
 #endif
    }
 }
+
+/* Is this helpful?
+ */
+void
+_mesa_allow_light_in_model( GLcontext *ctx, GLboolean flag )
+{
+   if (flag) 
+      ctx->_NeedEyeCoords &= ~NEED_EYE_DRIVER;
+   else
+      ctx->_NeedEyeCoords |= NEED_EYE_DRIVER;
+
+   ctx->NewState |= _NEW_POINT;        /* one of the bits from
+                                * _MESA_NEW_NEED_EYE_COORDS.
+                                */
+}