Major rework of tnl module
New array_cache module
Support 8 texture units in core mesa (now support 8 everywhere)
Rework core mesa statechange operations to avoid flushing on many
noop statechanges.
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
new file mode 100644
index 0000000..004977c
--- /dev/null
+++ b/src/mesa/main/api_arrayelt.c
@@ -0,0 +1,284 @@
+#include "glheader.h"
+#include "api_noop.h"
+#include "context.h"
+#include "colormac.h"
+#include "light.h"
+#include "macros.h"
+#include "mmath.h"
+#include "mtypes.h"
+
+
+typedef struct {
+   GLint unit;
+   struct gl_client_array *array;
+   void *func;
+} AAtexarray;
+   
+
+typedef struct {
+   struct gl_client_array *array;
+   void *func;
+} AAarray;
+
+typedef struct {
+   AAtexarray texarrays[MAX_TEXTURE_UNITS+1];
+   AAarray arrays[10];
+   GLuint NewState;
+} AAcontext;
+
+
+static void *colorfuncs[2][7] = {
+   { glColor3bv,
+     glColor3ub,
+     glColor3sv,
+     glColor3usv,
+     glColor3iv,
+     glColor3fv,
+     glColor3dv },
+
+   { glColor4bv,
+     glColor4ub,
+     glColor4sv,
+     glColor4usv,
+     glColor4iv,
+     glColor4fv,
+     glColor4dv }
+};
+
+static void *vertexfuncs[3][7] = {
+   { glVertex3bv,
+     glVertex3ub,
+     glVertex3sv,
+     glVertex3usv,
+     glVertex3iv,
+     glVertex3fv,
+     glVertex3dv },
+
+   { glVertex3bv,
+     glVertex3ub,
+     glVertex3sv,
+     glVertex3usv,
+     glVertex3iv,
+     glVertex3fv,
+     glVertex3dv },
+
+   { glVertex4bv,
+     glVertex4ub,
+     glVertex4sv,
+     glVertex4usv,
+     glVertex4iv,
+     glVertex4fv,
+     glVertex4dv }
+};
+
+
+static void *multitexfuncs[4][7] = {
+   { glMultiTexCoord1bv,
+     glMultiTexCoord1ub,
+     glMultiTexCoord1sv,
+     glMultiTexCoord1usv,
+     glMultiTexCoord1iv,
+     glMultiTexCoord1fv,
+     glMultiTexCoord1dv },
+
+   { glMultiTexCoord2bv,
+     glMultiTexCoord2ub,
+     glMultiTexCoord2sv,
+     glMultiTexCoord2usv,
+     glMultiTexCoord2iv,
+     glMultiTexCoord2fv,
+     glMultiTexCoord2dv },
+
+   { glMultiTexCoord3bv,
+     glMultiTexCoord3ub,
+     glMultiTexCoord3sv,
+     glMultiTexCoord3usv,
+     glMultiTexCoord3iv,
+     glMultiTexCoord3fv,
+     glMultiTexCoord3dv },
+
+   { glMultiTexCoord4bv,
+     glMultiTexCoord4ub,
+     glMultiTexCoord4sv,
+     glMultiTexCoord4usv,
+     glMultiTexCoord4iv,
+     glMultiTexCoord4fv,
+     glMultiTexCoord4dv }
+};
+
+static void *indexfuncs[7] = {
+   { glIndexbv,
+     glIndexub,
+     glIndexsv,
+     glIndexusv,
+     glIndexiv,
+     glIndexfv,
+     glIndexdv },
+};
+
+static void *edgeflagfuncs[7] = {
+   { glEdgeFlagbv,
+     glEdgeFlagub,
+     glEdgeFlagsv,
+     glEdgeFlagusv,
+     glEdgeFlagiv,
+     glEdgeFlagfv,
+     glEdgeFlagdv },
+};
+
+static void *normalfuncs[7] = {
+   { glNormal3bv,
+     glNormal3ub,
+     glNormal3sv,
+     glNormal3usv,
+     glNormal3iv,
+     glNormal3fv,
+     glNormal3dv },
+};
+
+static void *fogcoordfuncs[7] = {
+   { glFogCoordbv,
+     glFogCoordub,
+     glFogCoordsv,
+     glFogCoordusv,
+     glFogCoordiv,
+     glFogCoordfv,
+     glFogCoorddv },
+};
+
+static void *secondarycolorfuncs[7] = {
+   { glSecondaryColor3bv,
+     glSecondaryColor3ub,
+     glSecondaryColor3sv,
+     glSecondaryColor3usv,
+     glSecondaryColor3iv,
+     glSecondaryColor3fv,
+     glSecondaryColor3dv },
+};
+
+
+void _aa_create_context( GLcontext *ctx )
+{
+   ctx->aa_context = MALLOC( sizeof(AAcontext) );
+   AA_CONTEXT(ctx)->NewState = ~0;
+}
+
+static void _aa_update_state( GLcontext *ctx )
+{
+   AAcontext *actx = AA_CONTEXT(ctx);
+   AAtexarray *ta = actx->texarrays;
+   AAarray *aa = actx->arrays;
+   int i;
+
+   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 
+      if (ctx->Array.TexCoord[i].Enabled) {
+	 ta->unit = i;
+	 ta->array = &ctx->Array.TexCoord[i];
+	 ta->func = multitexfuncs[ta->array->Size-1][TYPE_IDX(ta->array->Type)];
+	 ta++;
+      }
+
+   ta->func = 0;
+
+   if (ctx->Array.Color.Enabled) {
+      aa->array = &ctx->Array.Color;
+      aa->func = colorfuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   if (ctx->Array.Normal.Enabled) {
+      aa->array = &ctx->Array.Normal;
+      aa->func = normalfuncs[TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   if (ctx->Array.Index.Enabled) {
+      aa->array = &ctx->Array.Index;
+      aa->func = indexfuncs[TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   if (ctx->Array.EdgeFlag.Enabled) {
+      aa->array = &ctx->Array.Edgeflag;
+      aa->func = edgeflagfuncs[TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   if (ctx->Array.FogCoord.Enabled) {
+      aa->array = &ctx->Array.Fogcoord;
+      aa->func = fogcoordfuncs[TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   if (ctx->Array.SecondaryColor.Enabled) {
+      aa->array = &ctx->Array.SecondaryColor;
+      aa->func = secondarycolorfuncs[TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   /* Must be last
+    */
+   if (ctx->Array.Vertex.Enabled) {
+      aa->array = &ctx->Array.Vertex;
+      aa->func = vertexfuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+      aa++;
+   }
+
+   aa->func = 0;
+   actx->NewState = 0;
+}
+
+
+static void _aa_loopback_array_elt( GLint elt )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   AAcontext *actx = AA_CONTEXT(ctx);
+   AAtexarray *ta;
+   AAarray *aa;
+
+   for (ta = actx->texarrays ; ta->func ; ta++) {
+      void (*func)( GLint, const void * ) = 
+	 (void (*)( GLint, const void * )) ta->func; 
+      func( ta->unit, (char *)ta->array->Ptr + elt * ta->array->SizeB );
+   }
+
+   for (aa = actx->arrays ; aa->func ; aa++) {
+      void (*func)( GLint, const void * ) = 
+	 (void (*)( GLint, const void * )) aa->func; 
+      func( (char *)aa->array->Ptr + elt * aa->array->SizeB );
+   }
+}
+
+
+void _aa_exec_array_elt( GLint elt )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   AAcontext *actx = AA_CONTEXT(ctx);
+   
+   if (actx->NewState) 
+      _aa_update_state( ctx );
+
+   ctx->Exec->ArrayElement = _aa_loopback_array_elt;
+   _aa_loopback_array_elt( elt );
+}
+
+/* This works for save as well:
+ */
+void _aa_save_array_elt( GLint elt )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   AAcontext *actx = AA_CONTEXT(ctx);
+   
+   if (actx->NewState) 
+      _aa_update_state( ctx );
+
+   ctx->Save->ArrayElement = _aa_loopback_array_elt;
+   _aa_loopback_array_elt( elt );
+}
+
+
+void aa_invalidate_state( GLcontext *ctx, GLuint new_state )
+{
+   if (AA_CONTEXT(ctx)) 
+      AA_CONTEXT(ctx)->NewState |= new_state;
+}