Changes for multitexture > 3, code clean-ups.
[mesa.git] / src / mesa / main / context.c
index 628e73419164fb5c517ed5613378bba1afb8ff28..3f4bcec2fb516634cb93f409393b7da295e2e2a1 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: context.c,v 1.18 1999/11/08 07:36:43 brianp Exp $ */
+/* $Id: context.c,v 1.93 2000/10/20 19:54:49 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
+ * Version:  3.5
  *
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2000  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"),
  */
 
 
-/* $XFree86: xc/lib/GL/mesa/src/context.c,v 1.4 1999/04/04 00:20:21 dawes Exp $ */
-
-/*
- * If multi-threading is enabled (-DTHREADS) then each thread has it's
- * own rendering context.  A thread obtains the pointer to its GLcontext
- * with the gl_get_thread_context() function.  Otherwise, the global
- * pointer, CC, points to the current context used by all threads in
- * the address space.
- */
-
-
-
 #ifdef PC_HEADER
 #include "all.h"
 #else
-#ifndef XFree86Server
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#else
-#include "GL/xf86glx.h"
-#endif
-#include "accum.h"
-#include "alphabuf.h"
-#include "api.h"
+#include "glheader.h"
+#include "buffers.h"
 #include "clip.h"
+#include "colortab.h"
 #include "context.h"
 #include "cva.h"
-#include "depth.h"
 #include "dlist.h"
 #include "eval.h"
 #include "enums.h"
 #include "extensions.h"
 #include "fog.h"
+#include "get.h"
+#include "glapinoop.h"
+#include "glthread.h"
 #include "hash.h"
+#include "imports.h"
 #include "light.h"
-#include "lines.h"
-#include "dlist.h"
 #include "macros.h"
 #include "matrix.h"
+#include "mem.h"
 #include "mmath.h"
 #include "pb.h"
 #include "pipeline.h"
-#include "points.h"
-#include "pointers.h"
-#include "quads.h"
 #include "shade.h"
 #include "simple_list.h"
-#include "stencil.h"
 #include "stages.h"
-#include "triangle.h"
+#include "state.h"
 #include "translate.h"
 #include "teximage.h"
 #include "texobj.h"
-#include "texstate.h"
 #include "texture.h"
 #include "types.h"
 #include "varray.h"
 #include "vb.h"
-#include "vbcull.h"
-#include "vbfill.h"
 #include "vbrender.h"
 #include "vbxform.h"
 #include "vertices.h"
 #include "xform.h"
 #endif
 
+#if defined(MESA_TRACE)
+#include "Trace/tr_context.h"
+#include "Trace/tr_wrapper.h"
+#endif
 
-/*
- * Memory allocation functions.  Called via the MALLOC, CALLOC and
- * FREE macros when DEBUG symbol is defined.
- * You might want to set breakpoints on these functions or plug in
- * other memory allocation functions.  The Mesa sources should only
- * use the MALLOC and FREE macros (which could also be overriden).
- *
- * XXX these functions should probably go into a new glmemory.c file.
- */
 
-/*
- * Allocate memory (uninitialized)
- */
-void *gl_malloc(size_t bytes)
+
+/**********************************************************************/
+/*****       OpenGL SI-style interface (new in Mesa 3.5)          *****/
+/**********************************************************************/
+
+static GLboolean
+_mesa_DestroyContext(__GLcontext *gc)
 {
-   return malloc(bytes);
+   if (gc) {
+      _mesa_free_context_data(gc);
+      (*gc->imports.free)(gc, gc);
+   }
+   return GL_TRUE;
 }
 
-/*
- * Allocate memory and initialize to zero.
- */
-void *gl_calloc(size_t bytes)
+
+/* exported OpenGL SI interface */
+__GLcontext *
+__glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes)
 {
-   return calloc(1, bytes);
+    GLcontext *ctx;
+
+    ctx = (GLcontext *) (*imports->calloc)(0, 1, sizeof(GLcontext));
+    if (ctx == NULL) {
+       return NULL;
+    }
+    ctx->imports = *imports;
+
+    _mesa_initialize_visual(&ctx->Visual,
+                            modes->rgbMode,
+                            modes->doubleBufferMode,
+                            modes->stereoMode,
+                            modes->redBits,
+                            modes->greenBits,
+                            modes->blueBits,
+                            modes->alphaBits,
+                            modes->indexBits,
+                            modes->depthBits,
+                            modes->stencilBits,
+                            modes->accumRedBits,
+                            modes->accumGreenBits,
+                            modes->accumBlueBits,
+                            modes->accumAlphaBits,
+                            0);
+
+    _mesa_initialize_context(ctx, &ctx->Visual, NULL, imports->wscx, GL_FALSE);
+
+    ctx->exports.destroyContext = _mesa_DestroyContext;
+
+    return ctx;
 }
 
-/*
- * Free memory
- */
-void gl_free(void *ptr)
+
+/* exported OpenGL SI interface */
+void
+__glCoreNopDispatch(void)
 {
-   free(ptr);
+#if 0
+   /* SI */
+   __gl_dispatch = __glNopDispatchState;
+#else
+   /* Mesa */
+   _glapi_set_dispatch(NULL);
+#endif
 }
 
 
@@ -135,189 +146,274 @@ void gl_free(void *ptr)
 /**********************************************************************/
 
 
-#ifdef THREADS
-
-#include "mthreads.h" /* Mesa platform independent threads interface */
-
-static MesaTSD mesa_ctx_tsd;
-
-static void mesa_ctx_thread_init() {
-  MesaInitTSD(&mesa_ctx_tsd);
-}
-
-GLcontext *gl_get_thread_context( void ) {
-  return (GLcontext *) MesaGetTSD(&mesa_ctx_tsd);
-}
-
-static void set_thread_context( GLcontext *ctx ) {
-  MesaSetTSD(&mesa_ctx_tsd, ctx, mesa_ctx_thread_init);
-}
-
-
-#else
-
-/* One Current Context pointer for all threads in the address space */
-GLcontext *CC = NULL;
-struct immediate *CURRENT_INPUT = NULL;
-
-#endif /*THREADS*/
+#if !defined(THREADS)
 
+struct immediate *_mesa_CurrentInput = NULL;
 
+#endif
 
 
 /**********************************************************************/
-/*****                   Profiling functions                      *****/
+/***** GL Visual allocation/destruction                           *****/
 /**********************************************************************/
 
-#ifdef PROFILE
 
-#include <sys/times.h>
-#include <sys/param.h>
+/*
+ * Allocate a new GLvisual object.
+ * Input:  rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
+ *         dbFlag - double buffering?
+ *         stereoFlag - stereo buffer?
+ *         depthBits - requested bits per depth buffer value
+ *                     Any value in [0, 32] is acceptable but the actual
+ *                     depth type will be GLushort or GLuint as needed.
+ *         stencilBits - requested minimum bits per stencil buffer value
+ *         accumBits - requested minimum bits per accum buffer component
+ *         indexBits - number of bits per pixel if rgbFlag==GL_FALSE
+ *         red/green/blue/alphaBits - number of bits per color component
+ *                                    in frame buffer for RGB(A) mode.
+ *                                    We always use 8 in core Mesa though.
+ * Return:  pointer to new GLvisual or NULL if requested parameters can't
+ *          be met.
+ */
+GLvisual *
+_mesa_create_visual( GLboolean rgbFlag,
+                     GLboolean dbFlag,
+                     GLboolean stereoFlag,
+                     GLint redBits,
+                     GLint greenBits,
+                     GLint blueBits,
+                     GLint alphaBits,
+                     GLint indexBits,
+                     GLint depthBits,
+                     GLint stencilBits,
+                     GLint accumRedBits,
+                     GLint accumGreenBits,
+                     GLint accumBlueBits,
+                     GLint accumAlphaBits,
+                     GLint numSamples )
+{
+   GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
+   if (vis) {
+      if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
+                                   redBits, greenBits, blueBits, alphaBits,
+                                   indexBits, depthBits, stencilBits,
+                                   accumRedBits, accumGreenBits,
+                                   accumBlueBits, accumAlphaBits,
+                                   numSamples)) {
+         FREE(vis);
+         return NULL;
+      }
+   }
+   return vis;
+}
 
 
 /*
- * Return system time in seconds.
- * NOTE:  this implementation may not be very portable!
+ * Initialize the fields of the given GLvisual.
+ * Input:  see _mesa_create_visual() above.
+ * Return: GL_TRUE = success
+ *         GL_FALSE = failure.
  */
-GLdouble gl_time( void )
+GLboolean
+_mesa_initialize_visual( GLvisual *vis,
+                         GLboolean rgbFlag,
+                         GLboolean dbFlag,
+                         GLboolean stereoFlag,
+                         GLint redBits,
+                         GLint greenBits,
+                         GLint blueBits,
+                         GLint alphaBits,
+                         GLint indexBits,
+                         GLint depthBits,
+                         GLint stencilBits,
+                         GLint accumRedBits,
+                         GLint accumGreenBits,
+                         GLint accumBlueBits,
+                         GLint accumAlphaBits,
+                         GLint numSamples )
 {
-   static GLdouble prev_time = 0.0;
-   static GLdouble time;
-   struct tms tm;
-   clock_t clk;
+   assert(vis);
 
-   clk = times(&tm);
+   /* This is to catch bad values from device drivers not updated for
+    * Mesa 3.3.  Some device drivers just passed 1.  That's a REALLY
+    * bad value now (a 1-bit depth buffer!?!).
+    */
+   assert(depthBits == 0 || depthBits > 1);
 
-#ifdef CLK_TCK
-   time = (double)clk / (double)CLK_TCK;
-#else
-   time = (double)clk / (double)HZ;
-#endif
+   if (depthBits < 0 || depthBits > 32) {
+      return GL_FALSE;
+   }
+   if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) {
+      return GL_FALSE;
+   }
+   if (accumRedBits < 0 || accumRedBits > (GLint) (8 * sizeof(GLaccum))) {
+      return GL_FALSE;
+   }
+   if (accumGreenBits < 0 || accumGreenBits > (GLint) (8 * sizeof(GLaccum))) {
+      return GL_FALSE;
+   }
+   if (accumBlueBits < 0 || accumBlueBits > (GLint) (8 * sizeof(GLaccum))) {
+      return GL_FALSE;
+   }
+   if (accumAlphaBits < 0 || accumAlphaBits > (GLint) (8 * sizeof(GLaccum))) {
+      return GL_FALSE;
+   }
 
-   if (time>prev_time) {
-      prev_time = time;
-      return time;
+   vis->RGBAflag   = rgbFlag;
+   vis->DBflag     = dbFlag;
+   vis->StereoFlag = stereoFlag;
+   vis->RedBits    = redBits;
+   vis->GreenBits  = greenBits;
+   vis->BlueBits   = blueBits;
+   vis->AlphaBits  = alphaBits;
+
+   vis->IndexBits      = indexBits;
+   vis->DepthBits      = depthBits;
+   vis->AccumRedBits   = (accumRedBits > 0) ? (8 * sizeof(GLaccum)) : 0;
+   vis->AccumGreenBits = (accumGreenBits > 0) ? (8 * sizeof(GLaccum)) : 0;
+   vis->AccumBlueBits  = (accumBlueBits > 0) ? (8 * sizeof(GLaccum)) : 0;
+   vis->AccumAlphaBits = (accumAlphaBits > 0) ? (8 * sizeof(GLaccum)) : 0;
+   vis->StencilBits    = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0;
+
+   if (depthBits == 0) {
+      /* Special case.  Even if we don't have a depth buffer we need
+       * good values for DepthMax for Z vertex transformation purposes
+       * and for per-fragment fog computation.
+       */
+      vis->DepthMax = 1 << 16;
+      vis->DepthMaxF = (GLfloat) vis->DepthMax;
+   }
+   else if (depthBits < 32) {
+      vis->DepthMax = (1 << depthBits) - 1;
+      vis->DepthMaxF = (GLfloat) vis->DepthMax;
    }
    else {
-      return prev_time;
+      /* Special case since shift values greater than or equal to the
+       * number of bits in the left hand expression's type are
+       * undefined.
+       */
+      vis->DepthMax = 0xffffffff;
+      vis->DepthMaxF = (GLfloat) vis->DepthMax;
    }
+
+   return GL_TRUE;
+}
+
+
+void
+_mesa_destroy_visual( GLvisual *vis )
+{
+   FREE(vis);
 }
 
+
+/**********************************************************************/
+/***** GL Framebuffer allocation/destruction                      *****/
+/**********************************************************************/
+
+
 /*
- * Reset the timing/profiling counters
+ * Create a new framebuffer.  A GLframebuffer is a struct which
+ * encapsulates the depth, stencil and accum buffers and related
+ * parameters.
+ * Input:  visual - a GLvisual pointer
+ *         softwareDepth - create/use a software depth buffer?
+ *         softwareStencil - create/use a software stencil buffer?
+ *         softwareAccum - create/use a software accum buffer?
+ *         softwareAlpha - create/use a software alpha buffer?
+
+ * Return:  pointer to new GLframebuffer struct or NULL if error.
  */
-static void init_timings( GLcontext *ctx )
+GLframebuffer *
+_mesa_create_framebuffer( GLvisual *visual,
+                          GLboolean softwareDepth,
+                          GLboolean softwareStencil,
+                          GLboolean softwareAccum,
+                          GLboolean softwareAlpha )
 {
-   ctx->BeginEndCount = 0;
-   ctx->BeginEndTime = 0.0;
-   ctx->VertexCount = 0;
-   ctx->VertexTime = 0.0;
-   ctx->PointCount = 0;
-   ctx->PointTime = 0.0;
-   ctx->LineCount = 0;
-   ctx->LineTime = 0.0;
-   ctx->PolygonCount = 0;
-   ctx->PolygonTime = 0.0;
-   ctx->ClearCount = 0;
-   ctx->ClearTime = 0.0;
-   ctx->SwapCount = 0;
-   ctx->SwapTime = 0.0;
+   GLframebuffer *buffer = CALLOC_STRUCT(gl_frame_buffer);
+   assert(visual);
+   if (buffer) {
+      _mesa_initialize_framebuffer(buffer, visual,
+                                   softwareDepth, softwareStencil,
+                                   softwareAccum, softwareAlpha );
+   }
+   return buffer;
 }
 
 
 /*
- * Print the accumulated timing/profiling data.
+ * Initialize a GLframebuffer object.
+ * Input:  See _mesa_create_framebuffer() above.
  */
-static void print_timings( GLcontext *ctx )
+void
+_mesa_initialize_framebuffer( GLframebuffer *buffer,
+                              GLvisual *visual,
+                              GLboolean softwareDepth,
+                              GLboolean softwareStencil,
+                              GLboolean softwareAccum,
+                              GLboolean softwareAlpha )
 {
-   GLdouble beginendrate;
-   GLdouble vertexrate;
-   GLdouble pointrate;
-   GLdouble linerate;
-   GLdouble polygonrate;
-   GLdouble overhead;
-   GLdouble clearrate;
-   GLdouble swaprate;
-   GLdouble avgvertices;
-
-   if (ctx->BeginEndTime>0.0) {
-      beginendrate = ctx->BeginEndCount / ctx->BeginEndTime;
-   }
-   else {
-      beginendrate = 0.0;
-   }
-   if (ctx->VertexTime>0.0) {
-      vertexrate = ctx->VertexCount / ctx->VertexTime;
-   }
-   else {
-      vertexrate = 0.0;
-   }
-   if (ctx->PointTime>0.0) {
-      pointrate = ctx->PointCount / ctx->PointTime;
-   }
-   else {
-      pointrate = 0.0;
-   }
-   if (ctx->LineTime>0.0) {
-      linerate = ctx->LineCount / ctx->LineTime;
-   }
-   else {
-      linerate = 0.0;
-   }
-   if (ctx->PolygonTime>0.0) {
-      polygonrate = ctx->PolygonCount / ctx->PolygonTime;
-   }
-   else {
-      polygonrate = 0.0;
-   }
-   if (ctx->ClearTime>0.0) {
-      clearrate = ctx->ClearCount / ctx->ClearTime;
+   assert(buffer);
+   assert(visual);
+
+   /* sanity checks */
+   if (softwareDepth ) {
+      assert(visual->DepthBits > 0);
    }
-   else {
-      clearrate = 0.0;
+   if (softwareStencil) {
+      assert(visual->StencilBits > 0);
    }
-   if (ctx->SwapTime>0.0) {
-      swaprate = ctx->SwapCount / ctx->SwapTime;
+   if (softwareAccum) {
+      assert(visual->RGBAflag);
+      assert(visual->AccumRedBits > 0);
+      assert(visual->AccumGreenBits > 0);
+      assert(visual->AccumBlueBits > 0);
    }
-   else {
-      swaprate = 0.0;
+   if (softwareAlpha) {
+      assert(visual->RGBAflag);
+      assert(visual->AlphaBits > 0);
    }
 
-   if (ctx->BeginEndCount>0) {
-      avgvertices = (GLdouble) ctx->VertexCount / (GLdouble) ctx->BeginEndCount;
-   }
-   else {
-      avgvertices = 0.0;
-   }
-
-   overhead = ctx->BeginEndTime - ctx->VertexTime - ctx->PointTime
-              - ctx->LineTime - ctx->PolygonTime;
-
-
-   printf("                          Count   Time (s)    Rate (/s) \n");
-   printf("--------------------------------------------------------\n");
-   printf("glBegin/glEnd           %7d  %8.3f   %10.3f\n",
-          ctx->BeginEndCount, ctx->BeginEndTime, beginendrate);
-   printf("  vertexes transformed  %7d  %8.3f   %10.3f\n",
-          ctx->VertexCount, ctx->VertexTime, vertexrate );
-   printf("  points rasterized     %7d  %8.3f   %10.3f\n",
-          ctx->PointCount, ctx->PointTime, pointrate );
-   printf("  lines rasterized      %7d  %8.3f   %10.3f\n",
-          ctx->LineCount, ctx->LineTime, linerate );
-   printf("  polygons rasterized   %7d  %8.3f   %10.3f\n",
-          ctx->PolygonCount, ctx->PolygonTime, polygonrate );
-   printf("  overhead                       %8.3f\n", overhead );
-   printf("glClear                 %7d  %8.3f   %10.3f\n",
-          ctx->ClearCount, ctx->ClearTime, clearrate );
-   printf("SwapBuffers             %7d  %8.3f   %10.3f\n",
-          ctx->SwapCount, ctx->SwapTime, swaprate );
-   printf("\n");
-
-   printf("Average number of vertices per begin/end: %8.3f\n", avgvertices );
+   buffer->Visual = visual;
+   buffer->UseSoftwareDepthBuffer = softwareDepth;
+   buffer->UseSoftwareStencilBuffer = softwareStencil;
+   buffer->UseSoftwareAccumBuffer = softwareAccum;
+   buffer->UseSoftwareAlphaBuffers = softwareAlpha;
 }
-#endif
 
 
+/*
+ * Free a framebuffer struct and its buffers.
+ */
+void
+_mesa_destroy_framebuffer( GLframebuffer *buffer )
+{
+   if (buffer) {
+      if (buffer->DepthBuffer) {
+         FREE( buffer->DepthBuffer );
+      }
+      if (buffer->Accum) {
+         FREE( buffer->Accum );
+      }
+      if (buffer->Stencil) {
+         FREE( buffer->Stencil );
+      }
+      if (buffer->FrontLeftAlpha) {
+         FREE( buffer->FrontLeftAlpha );
+      }
+      if (buffer->BackLeftAlpha) {
+         FREE( buffer->BackLeftAlpha );
+      }
+      if (buffer->FrontRightAlpha) {
+         FREE( buffer->FrontRightAlpha );
+      }
+      if (buffer->BackRightAlpha) {
+         FREE( buffer->BackRightAlpha );
+      }
+      FREE(buffer);
+   }
+}
 
 
 
@@ -326,17 +422,30 @@ static void print_timings( GLcontext *ctx )
 /**********************************************************************/
 
 
+_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
+
+
 /*
  * This function just calls all the various one-time-init functions in Mesa.
  */
-static void one_time_init( void )
+static void
+one_time_init( void )
 {
    static GLboolean alreadyCalled = GL_FALSE;
+   _glthread_LOCK_MUTEX(OneTimeLock);
    if (!alreadyCalled) {
+      /* do some implementation tests */
+      assert( sizeof(GLbyte) == 1 );
+      assert( sizeof(GLshort) >= 2 );
+      assert( sizeof(GLint) >= 4 );
+      assert( sizeof(GLubyte) == 1 );
+      assert( sizeof(GLushort) >= 2 );
+      assert( sizeof(GLuint) >= 4 );
+
       gl_init_clip();
       gl_init_eval();
-      gl_init_fog();
-      gl_init_math();
+      _mesa_init_fog();
+      _mesa_init_math();
       gl_init_lists();
       gl_init_shade();
       gl_init_texture();
@@ -344,19 +453,30 @@ static void one_time_init( void )
       gl_init_translate();
       gl_init_vbrender();
       gl_init_vbxform();
-      gl_init_vertices();
-      alreadyCalled = GL_TRUE;
-   }
+
+      if (getenv("MESA_DEBUG")) {
+         _glapi_noop_enable_warnings(GL_TRUE);
+      }
+      else {
+         _glapi_noop_enable_warnings(GL_FALSE);
+      }
+
 #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
    fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
 #endif
+
+      alreadyCalled = GL_TRUE;
+   }
+   _glthread_UNLOCK_MUTEX(OneTimeLock);
 }
 
 
+
 /*
  * Allocate and initialize a shared context state structure.
  */
-static struct gl_shared_state *alloc_shared_state( void )
+static struct gl_shared_state *
+alloc_shared_state( void )
 {
    GLuint d;
    struct gl_shared_state *ss;
@@ -366,9 +486,10 @@ static struct gl_shared_state *alloc_shared_state( void )
    if (!ss)
       return NULL;
 
-   ss->DisplayList = NewHashTable();
+   _glthread_INIT_MUTEX(ss->Mutex);
 
-   ss->TexObjects = NewHashTable();
+   ss->DisplayList = _mesa_NewHashTable();
+   ss->TexObjects = _mesa_NewHashTable();
 
    /* Default Texture objects */
    outOfMemory = GL_FALSE;
@@ -381,18 +502,28 @@ static struct gl_shared_state *alloc_shared_state( void )
       ss->DefaultD[d]->RefCount++; /* don't free if not in use */
    }
 
+   ss->DefaultCubeMap = gl_alloc_texture_object(ss, 0, 6);
+   if (!ss->DefaultCubeMap) {
+      outOfMemory = GL_TRUE;
+   }
+   else {
+      ss->DefaultCubeMap->RefCount++;
+   }
+
    if (!ss->DisplayList || !ss->TexObjects || outOfMemory) {
       /* Ran out of memory at some point.  Free everything and return NULL */
       if (ss->DisplayList)
-         DeleteHashTable(ss->DisplayList);
+         _mesa_DeleteHashTable(ss->DisplayList);
       if (ss->TexObjects)
-         DeleteHashTable(ss->TexObjects);
+         _mesa_DeleteHashTable(ss->TexObjects);
       if (ss->DefaultD[1])
          gl_free_texture_object(ss, ss->DefaultD[1]);
       if (ss->DefaultD[2])
          gl_free_texture_object(ss, ss->DefaultD[2]);
       if (ss->DefaultD[3])
          gl_free_texture_object(ss, ss->DefaultD[3]);
+      if (ss->DefaultCubeMap)
+         gl_free_texture_object(ss, ss->DefaultCubeMap);
       FREE(ss);
       return NULL;
    }
@@ -405,11 +536,12 @@ static struct gl_shared_state *alloc_shared_state( void )
 /*
  * Deallocate a shared state context and all children structures.
  */
-static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
+static void
+free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
 {
    /* Free display lists */
    while (1) {
-      GLuint list = HashFirstEntry(ss->DisplayList);
+      GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
       if (list) {
          gl_destroy_list(ctx, list);
       }
@@ -417,7 +549,7 @@ static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
          break;
       }
    }
-   DeleteHashTable(ss->DisplayList);
+   _mesa_DeleteHashTable(ss->DisplayList);
 
    /* Free texture objects */
    while (ss->TexObjectList)
@@ -427,21 +559,19 @@ static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
       /* this function removes from linked list too! */
       gl_free_texture_object(ss, ss->TexObjectList);
    }
-   DeleteHashTable(ss->TexObjects);
+   _mesa_DeleteHashTable(ss->TexObjects);
 
    FREE(ss);
 }
 
 
 
-
-
-
 /*
  * Initialize the nth light.  Note that the defaults for light 0 are
  * different than the other lights.
  */
-static void init_light( struct gl_light *l, GLuint n )
+static void
+init_light( struct gl_light *l, GLuint n )
 {
    make_empty_list( l );
 
@@ -468,7 +598,8 @@ static void init_light( struct gl_light *l, GLuint n )
 
 
 
-static void init_lightmodel( struct gl_lightmodel *lm )
+static void
+init_lightmodel( struct gl_lightmodel *lm )
 {
    ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 );
    lm->LocalViewer = GL_FALSE;
@@ -477,7 +608,8 @@ static void init_lightmodel( struct gl_lightmodel *lm )
 }
 
 
-static void init_material( struct gl_material *m )
+static void
+init_material( struct gl_material *m )
 {
    ASSIGN_4V( m->Ambient,  0.2, 0.2, 0.2, 1.0 );
    ASSIGN_4V( m->Diffuse,  0.8, 0.8, 0.8, 1.0 );
@@ -491,17 +623,40 @@ static void init_material( struct gl_material *m )
 
 
 
-static void init_texture_unit( GLcontext *ctx, GLuint unit )
+static void
+init_texture_unit( GLcontext *ctx, GLuint unit )
 {
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
 
    texUnit->EnvMode = GL_MODULATE;
+   texUnit->CombineModeRGB = GL_MODULATE;
+   texUnit->CombineModeA = GL_MODULATE;
+   texUnit->CombineSourceRGB[0] = GL_TEXTURE;
+   texUnit->CombineSourceRGB[1] = GL_PREVIOUS_EXT;
+   texUnit->CombineSourceRGB[2] = GL_CONSTANT_EXT;
+   texUnit->CombineSourceA[0] = GL_TEXTURE;
+   texUnit->CombineSourceA[1] = GL_PREVIOUS_EXT;
+   texUnit->CombineSourceA[2] = GL_CONSTANT_EXT;
+   texUnit->CombineOperandRGB[0] = GL_SRC_COLOR;
+   texUnit->CombineOperandRGB[1] = GL_SRC_COLOR;
+   texUnit->CombineOperandRGB[2] = GL_SRC_ALPHA;
+   texUnit->CombineOperandA[0] = GL_SRC_ALPHA;
+   texUnit->CombineOperandA[1] = GL_SRC_ALPHA;
+   texUnit->CombineOperandA[2] = GL_SRC_ALPHA;
+   texUnit->CombineScaleShiftRGB = 0;
+   texUnit->CombineScaleShiftA = 0;
+
    ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
    texUnit->TexGenEnabled = 0;
    texUnit->GenModeS = GL_EYE_LINEAR;
    texUnit->GenModeT = GL_EYE_LINEAR;
    texUnit->GenModeR = GL_EYE_LINEAR;
    texUnit->GenModeQ = GL_EYE_LINEAR;
+   texUnit->GenBitS = TEXGEN_EYE_LINEAR;
+   texUnit->GenBitT = TEXGEN_EYE_LINEAR;
+   texUnit->GenBitR = TEXGEN_EYE_LINEAR;
+   texUnit->GenBitQ = TEXGEN_EYE_LINEAR;
+
    /* Yes, these plane coefficients are correct! */
    ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
    ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
@@ -515,10 +670,12 @@ static void init_texture_unit( GLcontext *ctx, GLuint unit )
    texUnit->CurrentD[1] = ctx->Shared->DefaultD[1];
    texUnit->CurrentD[2] = ctx->Shared->DefaultD[2];
    texUnit->CurrentD[3] = ctx->Shared->DefaultD[3];
+   texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
 }
 
 
-static void init_fallback_arrays( GLcontext *ctx )
+static void
+init_fallback_arrays( GLcontext *ctx )
 {
    struct gl_client_array *cl;
    GLuint i;
@@ -566,8 +723,10 @@ static void init_fallback_arrays( GLcontext *ctx )
    cl->Enabled = 1;
 }
 
+
 /* Initialize a 1-D evaluator map */
-static void init_1d_map( struct gl_1d_map *map, int n, const float *initial )
+static void
+init_1d_map( struct gl_1d_map *map, int n, const float *initial )
 {
    map->Order = 1;
    map->u1 = 0.0;
@@ -578,12 +737,12 @@ static void init_1d_map( struct gl_1d_map *map, int n, const float *initial )
       for (i=0;i<n;i++)
          map->Points[i] = initial[i];
    }
-   map->Retain = GL_FALSE;
 }
 
 
 /* Initialize a 2-D evaluator map */
-static void init_2d_map( struct gl_2d_map *map, int n, const float *initial )
+static void
+init_2d_map( struct gl_2d_map *map, int n, const float *initial )
 {
    map->Uorder = 1;
    map->Vorder = 1;
@@ -597,574 +756,606 @@ static void init_2d_map( struct gl_2d_map *map, int n, const float *initial )
       for (i=0;i<n;i++)
          map->Points[i] = initial[i];
    }
-   map->Retain = GL_FALSE;
 }
 
 
-
 /*
- * Initialize a gl_context structure to default values.
+ * Initialize the attribute groups in a GLcontext.
  */
-static void initialize_context( GLcontext *ctx )
+static void
+init_attrib_groups( GLcontext *ctx )
 {
    GLuint i, j;
 
-   if (ctx) {
-      /* Constants, may be overriden by device driver */
-      ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
-      ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
-      ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
-      ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
-
-      /* Modelview matrix */
-      gl_matrix_ctr( &ctx->ModelView );
-      gl_matrix_alloc_inv( &ctx->ModelView );
-
-      ctx->ModelViewStackDepth = 0;
-      for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
-        gl_matrix_ctr( &ctx->ModelViewStack[i] );
-        gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
-      }
-
-      /* Projection matrix - need inv for user clipping in clip space*/
-      gl_matrix_ctr( &ctx->ProjectionMatrix );
-      gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
-
-      gl_matrix_ctr( &ctx->ModelProjectMatrix );
-      gl_matrix_ctr( &ctx->ModelProjectWinMatrix );
-      ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
-
-      ctx->ProjectionStackDepth = 0;
-      ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
-      ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
-
-      for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
-        gl_matrix_ctr( &ctx->ProjectionStack[i] );
-        gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
-      }
-
-      /* Texture matrix */
-      for (i=0; i<MAX_TEXTURE_UNITS; i++) {
-        gl_matrix_ctr( &ctx->TextureMatrix[i] );
-        ctx->TextureStackDepth[i] = 0;
-        for (j = 0 ; j < MAX_TEXTURE_STACK_DEPTH ; j++) {
-           ctx->TextureStack[i][j].inv = 0;
-        }
-      }
-
-      /* Accumulate buffer group */
-      ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
-
-      /* Color buffer group */
-      ctx->Color.IndexMask = 0xffffffff;
-      ctx->Color.ColorMask[0] = 0xff;
-      ctx->Color.ColorMask[1] = 0xff;
-      ctx->Color.ColorMask[2] = 0xff;
-      ctx->Color.ColorMask[3] = 0xff;
-      ctx->Color.SWmasking = GL_FALSE;
-      ctx->Color.ClearIndex = 0;
-      ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
-      ctx->Color.DrawBuffer = GL_FRONT;
-      ctx->Color.AlphaEnabled = GL_FALSE;
-      ctx->Color.AlphaFunc = GL_ALWAYS;
-      ctx->Color.AlphaRef = 0;
-      ctx->Color.BlendEnabled = GL_FALSE;
-      ctx->Color.BlendSrcRGB = GL_ONE;
-      ctx->Color.BlendDstRGB = GL_ZERO;
-      ctx->Color.BlendSrcA = GL_ONE;
-      ctx->Color.BlendDstA = GL_ZERO;
-      ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
-      ctx->Color.BlendFunc = NULL;  /* this pointer set only when needed */
-      ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
-      ctx->Color.IndexLogicOpEnabled = GL_FALSE;
-      ctx->Color.ColorLogicOpEnabled = GL_FALSE;
-      ctx->Color.SWLogicOpEnabled = GL_FALSE;
-      ctx->Color.LogicOp = GL_COPY;
-      ctx->Color.DitherFlag = GL_TRUE;
-      ctx->Color.MultiDrawBuffer = GL_FALSE;
-
-      /* Current group */
-      ASSIGN_4V( ctx->Current.ByteColor, 255, 255, 255, 255);
-      ctx->Current.Index = 1;
-      for (i=0; i<MAX_TEXTURE_UNITS; i++)
-         ASSIGN_4V( ctx->Current.Texcoord[i], 0.0, 0.0, 0.0, 1.0 );
-      ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
-      ctx->Current.RasterDistance = 0.0;
-      ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
-      ctx->Current.RasterIndex = 1;
-      for (i=0; i<MAX_TEXTURE_UNITS; i++)
-         ASSIGN_4V( ctx->Current.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 );
-      ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0];
-      ctx->Current.RasterPosValid = GL_TRUE;
-      ctx->Current.EdgeFlag = GL_TRUE;
-      ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
-      ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
-
-      ctx->Current.Flag = (VERT_NORM|VERT_INDEX|VERT_RGBA|VERT_EDGE|
-                          VERT_TEX0_1|VERT_TEX1_1|VERT_MATERIAL);
-
-      init_fallback_arrays( ctx );
-
-      /* Depth buffer group */
-      ctx->Depth.Test = GL_FALSE;
-      ctx->Depth.Clear = 1.0;
-      ctx->Depth.Func = GL_LESS;
-      ctx->Depth.Mask = GL_TRUE;
-
-      /* Evaluators group */
-      ctx->Eval.Map1Color4 = GL_FALSE;
-      ctx->Eval.Map1Index = GL_FALSE;
-      ctx->Eval.Map1Normal = GL_FALSE;
-      ctx->Eval.Map1TextureCoord1 = GL_FALSE;
-      ctx->Eval.Map1TextureCoord2 = GL_FALSE;
-      ctx->Eval.Map1TextureCoord3 = GL_FALSE;
-      ctx->Eval.Map1TextureCoord4 = GL_FALSE;
-      ctx->Eval.Map1Vertex3 = GL_FALSE;
-      ctx->Eval.Map1Vertex4 = GL_FALSE;
-      ctx->Eval.Map2Color4 = GL_FALSE;
-      ctx->Eval.Map2Index = GL_FALSE;
-      ctx->Eval.Map2Normal = GL_FALSE;
-      ctx->Eval.Map2TextureCoord1 = GL_FALSE;
-      ctx->Eval.Map2TextureCoord2 = GL_FALSE;
-      ctx->Eval.Map2TextureCoord3 = GL_FALSE;
-      ctx->Eval.Map2TextureCoord4 = GL_FALSE;
-      ctx->Eval.Map2Vertex3 = GL_FALSE;
-      ctx->Eval.Map2Vertex4 = GL_FALSE;
-      ctx->Eval.AutoNormal = GL_FALSE;
-      ctx->Eval.MapGrid1un = 1;
-      ctx->Eval.MapGrid1u1 = 0.0;
-      ctx->Eval.MapGrid1u2 = 1.0;
-      ctx->Eval.MapGrid2un = 1;
-      ctx->Eval.MapGrid2vn = 1;
-      ctx->Eval.MapGrid2u1 = 0.0;
-      ctx->Eval.MapGrid2u2 = 1.0;
-      ctx->Eval.MapGrid2v1 = 0.0;
-      ctx->Eval.MapGrid2v2 = 1.0;
-
-      /* Evaluator data */
-      {
-         static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
-         static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
-         static GLfloat index[1] = { 1.0 };
-         static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
-         static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
-
-         init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
-         init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
-         init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
-         init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
-         init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
-         init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
-         init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
-         init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
-         init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
-
-         init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
-         init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
-         init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
-         init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
-         init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
-         init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
-         init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
-         init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
-         init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
+   assert(ctx);
+
+   /* Constants, may be overriden by device drivers */
+   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
+   ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
+   ctx->Const.MaxCubeTextureSize = ctx->Const.MaxTextureSize;
+   ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
+   ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
+   ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
+   ctx->Const.MinPointSize = MIN_POINT_SIZE;
+   ctx->Const.MaxPointSize = MAX_POINT_SIZE;
+   ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
+   ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
+   ctx->Const.PointSizeGranularity = POINT_SIZE_GRANULARITY;
+   ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
+   ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
+   ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
+   ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
+   ctx->Const.LineWidthGranularity = LINE_WIDTH_GRANULARITY;
+   ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS;
+   ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
+   ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
+   ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
+   ctx->Const.NumCompressedTextureFormats = 0;
+
+   /* Modelview matrix */
+   gl_matrix_ctr( &ctx->ModelView );
+   gl_matrix_alloc_inv( &ctx->ModelView );
+
+   ctx->ModelViewStackDepth = 0;
+   for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
+      gl_matrix_ctr( &ctx->ModelViewStack[i] );
+      gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
+   }
+
+   /* Projection matrix - need inv for user clipping in clip space*/
+   gl_matrix_ctr( &ctx->ProjectionMatrix );
+   gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
+
+   gl_matrix_ctr( &ctx->ModelProjectMatrix );
+   gl_matrix_ctr( &ctx->ModelProjectWinMatrix );
+   ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
+
+   ctx->ProjectionStackDepth = 0;
+   ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
+   ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
+
+   for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
+      gl_matrix_ctr( &ctx->ProjectionStack[i] );
+      gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
+   }
+
+   /* Texture matrix */
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+      gl_matrix_ctr( &ctx->TextureMatrix[i] );
+      ctx->TextureStackDepth[i] = 0;
+      for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
+         gl_matrix_ctr( &ctx->TextureStack[i][j] );
+         ctx->TextureStack[i][j].inv = 0;
       }
+   }
 
-      /* Fog group */
-      ctx->Fog.Enabled = GL_FALSE;
-      ctx->Fog.Mode = GL_EXP;
-      ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
-      ctx->Fog.Index = 0.0;
-      ctx->Fog.Density = 1.0;
-      ctx->Fog.Start = 0.0;
-      ctx->Fog.End = 1.0;
-
-      /* Hint group */
-      ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
-      ctx->Hint.PointSmooth = GL_DONT_CARE;
-      ctx->Hint.LineSmooth = GL_DONT_CARE;
-      ctx->Hint.PolygonSmooth = GL_DONT_CARE;
-      ctx->Hint.Fog = GL_DONT_CARE;
-
-      ctx->Hint.AllowDrawWin = GL_TRUE;
-      ctx->Hint.AllowDrawSpn = GL_TRUE;
-      ctx->Hint.AllowDrawMem = GL_TRUE;
-      ctx->Hint.StrictLighting = GL_TRUE;
-
-      /* Pipeline */
-      gl_pipeline_init( ctx );
-      gl_cva_init( ctx );
-
-      /* Extensions */
-      gl_extensions_ctr( ctx );
-
-      ctx->AllowVertexCull = CLIP_CULLED_BIT;
-
-      /* Lighting group */
-      for (i=0;i<MAX_LIGHTS;i++) {
-        init_light( &ctx->Light.Light[i], i );
-      }
-      make_empty_list( &ctx->Light.EnabledList );
-
-      init_lightmodel( &ctx->Light.Model );
-      init_material( &ctx->Light.Material[0] );
-      init_material( &ctx->Light.Material[1] );
-      ctx->Light.ShadeModel = GL_SMOOTH;
-      ctx->Light.Enabled = GL_FALSE;
-      ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
-      ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
-      ctx->Light.ColorMaterialBitmask
-         = gl_material_bitmask( ctx,
-                               GL_FRONT_AND_BACK,
-                               GL_AMBIENT_AND_DIFFUSE, ~0, 0 );
-
-      ctx->Light.ColorMaterialEnabled = GL_FALSE;
-
-      /* Line group */
-      ctx->Line.SmoothFlag = GL_FALSE;
-      ctx->Line.StippleFlag = GL_FALSE;
-      ctx->Line.Width = 1.0;
-      ctx->Line.StipplePattern = 0xffff;
-      ctx->Line.StippleFactor = 1;
-
-      /* Display List group */
-      ctx->List.ListBase = 0;
-
-      /* Pixel group */
-      ctx->Pixel.RedBias = 0.0;
-      ctx->Pixel.RedScale = 1.0;
-      ctx->Pixel.GreenBias = 0.0;
-      ctx->Pixel.GreenScale = 1.0;
-      ctx->Pixel.BlueBias = 0.0;
-      ctx->Pixel.BlueScale = 1.0;
-      ctx->Pixel.AlphaBias = 0.0;
-      ctx->Pixel.AlphaScale = 1.0;
-      ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
-      ctx->Pixel.DepthBias = 0.0;
-      ctx->Pixel.DepthScale = 1.0;
-      ctx->Pixel.IndexOffset = 0;
-      ctx->Pixel.IndexShift = 0;
-      ctx->Pixel.ZoomX = 1.0;
-      ctx->Pixel.ZoomY = 1.0;
-      ctx->Pixel.MapColorFlag = GL_FALSE;
-      ctx->Pixel.MapStencilFlag = GL_FALSE;
-      ctx->Pixel.MapStoSsize = 1;
-      ctx->Pixel.MapItoIsize = 1;
-      ctx->Pixel.MapItoRsize = 1;
-      ctx->Pixel.MapItoGsize = 1;
-      ctx->Pixel.MapItoBsize = 1;
-      ctx->Pixel.MapItoAsize = 1;
-      ctx->Pixel.MapRtoRsize = 1;
-      ctx->Pixel.MapGtoGsize = 1;
-      ctx->Pixel.MapBtoBsize = 1;
-      ctx->Pixel.MapAtoAsize = 1;
-      ctx->Pixel.MapStoS[0] = 0;
-      ctx->Pixel.MapItoI[0] = 0;
-      ctx->Pixel.MapItoR[0] = 0.0;
-      ctx->Pixel.MapItoG[0] = 0.0;
-      ctx->Pixel.MapItoB[0] = 0.0;
-      ctx->Pixel.MapItoA[0] = 0.0;
-      ctx->Pixel.MapItoR8[0] = 0;
-      ctx->Pixel.MapItoG8[0] = 0;
-      ctx->Pixel.MapItoB8[0] = 0;
-      ctx->Pixel.MapItoA8[0] = 0;
-      ctx->Pixel.MapRtoR[0] = 0.0;
-      ctx->Pixel.MapGtoG[0] = 0.0;
-      ctx->Pixel.MapBtoB[0] = 0.0;
-      ctx->Pixel.MapAtoA[0] = 0.0;
-
-      /* Point group */
-      ctx->Point.SmoothFlag = GL_FALSE;
-      ctx->Point.Size = 1.0;
-      ctx->Point.Params[0] = 1.0;
-      ctx->Point.Params[1] = 0.0;
-      ctx->Point.Params[2] = 0.0;
-      ctx->Point.Attenuated = GL_FALSE;
-      ctx->Point.MinSize = 0.0;
-      ctx->Point.MaxSize = (GLfloat) MAX_POINT_SIZE;
-      ctx->Point.Threshold = 1.0;
-
-      /* Polygon group */
-      ctx->Polygon.CullFlag = GL_FALSE;
-      ctx->Polygon.CullFaceMode = GL_BACK;
-      ctx->Polygon.FrontFace = GL_CCW;
-      ctx->Polygon.FrontBit = 0;
-      ctx->Polygon.FrontMode = GL_FILL;
-      ctx->Polygon.BackMode = GL_FILL;
-      ctx->Polygon.Unfilled = GL_FALSE;
-      ctx->Polygon.SmoothFlag = GL_FALSE;
-      ctx->Polygon.StippleFlag = GL_FALSE;
-      ctx->Polygon.OffsetFactor = 0.0F;
-      ctx->Polygon.OffsetUnits = 0.0F;
-      ctx->Polygon.OffsetPoint = GL_FALSE;
-      ctx->Polygon.OffsetLine = GL_FALSE;
-      ctx->Polygon.OffsetFill = GL_FALSE;
-
-      /* Polygon Stipple group */
-      MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
-
-      /* Scissor group */
-      ctx->Scissor.Enabled = GL_FALSE;
-      ctx->Scissor.X = 0;
-      ctx->Scissor.Y = 0;
-      ctx->Scissor.Width = 0;
-      ctx->Scissor.Height = 0;
-
-      /* Stencil group */
-      ctx->Stencil.Enabled = GL_FALSE;
-      ctx->Stencil.Function = GL_ALWAYS;
-      ctx->Stencil.FailFunc = GL_KEEP;
-      ctx->Stencil.ZPassFunc = GL_KEEP;
-      ctx->Stencil.ZFailFunc = GL_KEEP;
-      ctx->Stencil.Ref = 0;
-      ctx->Stencil.ValueMask = 0xff;
-      ctx->Stencil.Clear = 0;
-      ctx->Stencil.WriteMask = 0xff;
-
-      /* Texture group */
-      ctx->Texture.CurrentUnit = 0;      /* multitexture */
-      ctx->Texture.CurrentTransformUnit = 0; /* multitexture */
-      ctx->Texture.Enabled = 0;
-
-      for (i=0; i<MAX_TEXTURE_UNITS; i++)
-         init_texture_unit( ctx, i );
-
-      ctx->Texture.SharedPalette = GL_FALSE;
-      ctx->Texture.Palette[0] = 255;
-      ctx->Texture.Palette[1] = 255;
-      ctx->Texture.Palette[2] = 255;
-      ctx->Texture.Palette[3] = 255;
-      ctx->Texture.PaletteSize = 1;
-      ctx->Texture.PaletteIntFormat = GL_RGBA;
-      ctx->Texture.PaletteFormat = GL_RGBA;
-
-      /* Transformation group */
-      ctx->Transform.MatrixMode = GL_MODELVIEW;
-      ctx->Transform.Normalize = GL_FALSE;
-      ctx->Transform.RescaleNormals = GL_FALSE;
-      for (i=0;i<MAX_CLIP_PLANES;i++) {
-        ctx->Transform.ClipEnabled[i] = GL_FALSE;
-         ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
-      }
-      ctx->Transform.AnyClip = GL_FALSE;
+   /* Color matrix */
+   gl_matrix_ctr(&ctx->ColorMatrix);
+   ctx->ColorStackDepth = 0;
+   for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) {
+      gl_matrix_ctr(&ctx->ColorStack[j]);
+   }
+
+   /* Accumulate buffer group */
+   ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+
+   /* Color buffer group */
+   ctx->Color.IndexMask = 0xffffffff;
+   ctx->Color.ColorMask[0] = 0xff;
+   ctx->Color.ColorMask[1] = 0xff;
+   ctx->Color.ColorMask[2] = 0xff;
+   ctx->Color.ColorMask[3] = 0xff;
+   ctx->Color.ClearIndex = 0;
+   ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+   ctx->Color.DrawBuffer = GL_FRONT;
+   ctx->Color.AlphaEnabled = GL_FALSE;
+   ctx->Color.AlphaFunc = GL_ALWAYS;
+   ctx->Color.AlphaRef = 0;
+   ctx->Color.BlendEnabled = GL_FALSE;
+   ctx->Color.BlendSrcRGB = GL_ONE;
+   ctx->Color.BlendDstRGB = GL_ZERO;
+   ctx->Color.BlendSrcA = GL_ONE;
+   ctx->Color.BlendDstA = GL_ZERO;
+   ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
+   ctx->Color.BlendFunc = NULL;  /* this pointer set only when needed */
+   ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
+   ctx->Color.IndexLogicOpEnabled = GL_FALSE;
+   ctx->Color.ColorLogicOpEnabled = GL_FALSE;
+   ctx->Color.LogicOp = GL_COPY;
+   ctx->Color.DitherFlag = GL_TRUE;
+   ctx->Color.MultiDrawBuffer = GL_FALSE;
+
+   /* Current group */
+   ASSIGN_4V( ctx->Current.ByteColor, 255, 255, 255, 255);
+   ctx->Current.Index = 1;
+   for (i=0; i<MAX_TEXTURE_UNITS; i++)
+      ASSIGN_4V( ctx->Current.Texcoord[i], 0.0, 0.0, 0.0, 1.0 );
+   ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
+   ctx->Current.RasterDistance = 0.0;
+   ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
+   ctx->Current.RasterIndex = 1;
+   for (i=0; i<MAX_TEXTURE_UNITS; i++)
+      ASSIGN_4V( ctx->Current.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 );
+   ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0];
+   ctx->Current.RasterPosValid = GL_TRUE;
+   ctx->Current.EdgeFlag = GL_TRUE;
+   ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
+   ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
+
+   ctx->Current.Flag = (VERT_NORM |
+                        VERT_INDEX | 
+                        VERT_RGBA |
+                        VERT_EDGE |
+                        VERT_TEX0_1 |
+                        VERT_TEX1_1 |
+                        VERT_TEX2_1 | /* XXX fix for MAX_TEXTURE_UNITS > 3 */
+                        VERT_MATERIAL);
+
+   init_fallback_arrays( ctx );
+
+   /* Depth buffer group */
+   ctx->Depth.Test = GL_FALSE;
+   ctx->Depth.Clear = 1.0;
+   ctx->Depth.Func = GL_LESS;
+   ctx->Depth.Mask = GL_TRUE;
+   ctx->Depth.OcclusionTest = GL_FALSE;
+
+   /* Evaluators group */
+   ctx->Eval.Map1Color4 = GL_FALSE;
+   ctx->Eval.Map1Index = GL_FALSE;
+   ctx->Eval.Map1Normal = GL_FALSE;
+   ctx->Eval.Map1TextureCoord1 = GL_FALSE;
+   ctx->Eval.Map1TextureCoord2 = GL_FALSE;
+   ctx->Eval.Map1TextureCoord3 = GL_FALSE;
+   ctx->Eval.Map1TextureCoord4 = GL_FALSE;
+   ctx->Eval.Map1Vertex3 = GL_FALSE;
+   ctx->Eval.Map1Vertex4 = GL_FALSE;
+   ctx->Eval.Map2Color4 = GL_FALSE;
+   ctx->Eval.Map2Index = GL_FALSE;
+   ctx->Eval.Map2Normal = GL_FALSE;
+   ctx->Eval.Map2TextureCoord1 = GL_FALSE;
+   ctx->Eval.Map2TextureCoord2 = GL_FALSE;
+   ctx->Eval.Map2TextureCoord3 = GL_FALSE;
+   ctx->Eval.Map2TextureCoord4 = GL_FALSE;
+   ctx->Eval.Map2Vertex3 = GL_FALSE;
+   ctx->Eval.Map2Vertex4 = GL_FALSE;
+   ctx->Eval.AutoNormal = GL_FALSE;
+   ctx->Eval.MapGrid1un = 1;
+   ctx->Eval.MapGrid1u1 = 0.0;
+   ctx->Eval.MapGrid1u2 = 1.0;
+   ctx->Eval.MapGrid2un = 1;
+   ctx->Eval.MapGrid2vn = 1;
+   ctx->Eval.MapGrid2u1 = 0.0;
+   ctx->Eval.MapGrid2u2 = 1.0;
+   ctx->Eval.MapGrid2v1 = 0.0;
+   ctx->Eval.MapGrid2v2 = 1.0;
+
+   /* Evaluator data */
+   {
+      static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
+      static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
+      static GLfloat index[1] = { 1.0 };
+      static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
+      static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
+
+      init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
+      init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
+      init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
+      init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
+      init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
+      init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
+      init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
+      init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
+      init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
+
+      init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
+      init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
+      init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
+      init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
+      init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
+      init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
+      init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
+      init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
+      init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
+   }
+
+   /* Fog group */
+   ctx->Fog.Enabled = GL_FALSE;
+   ctx->Fog.Mode = GL_EXP;
+   ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
+   ctx->Fog.Index = 0.0;
+   ctx->Fog.Density = 1.0;
+   ctx->Fog.Start = 0.0;
+   ctx->Fog.End = 1.0;
+
+   /* Hint group */
+   ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
+   ctx->Hint.PointSmooth = GL_DONT_CARE;
+   ctx->Hint.LineSmooth = GL_DONT_CARE;
+   ctx->Hint.PolygonSmooth = GL_DONT_CARE;
+   ctx->Hint.Fog = GL_DONT_CARE;
+   ctx->Hint.AllowDrawWin = GL_TRUE;
+   ctx->Hint.AllowDrawFrg = GL_TRUE;
+   ctx->Hint.AllowDrawMem = GL_TRUE;
+   ctx->Hint.StrictLighting = GL_TRUE;
+   ctx->Hint.ClipVolumeClipping = GL_DONT_CARE;
+   ctx->Hint.TextureCompression = GL_DONT_CARE;
+
+   /* Histogram group */
+   ctx->Histogram.Width = 0;
+   ctx->Histogram.Format = GL_RGBA;
+   ctx->Histogram.Sink = GL_FALSE;
+   ctx->Histogram.RedSize       = 0xffffffff;
+   ctx->Histogram.GreenSize     = 0xffffffff;
+   ctx->Histogram.BlueSize      = 0xffffffff;
+   ctx->Histogram.AlphaSize     = 0xffffffff;
+   ctx->Histogram.LuminanceSize = 0xffffffff;
+   for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
+      ctx->Histogram.Count[i][0] = 0;
+      ctx->Histogram.Count[i][1] = 0;
+      ctx->Histogram.Count[i][2] = 0;
+      ctx->Histogram.Count[i][3] = 0;
+   }
+
+   /* Min/Max group */
+   ctx->MinMax.Format = GL_RGBA;
+   ctx->MinMax.Sink = GL_FALSE;
+   ctx->MinMax.Min[RCOMP] = 1000;    ctx->MinMax.Max[RCOMP] = -1000;
+   ctx->MinMax.Min[GCOMP] = 1000;    ctx->MinMax.Max[GCOMP] = -1000;
+   ctx->MinMax.Min[BCOMP] = 1000;    ctx->MinMax.Max[BCOMP] = -1000;
+   ctx->MinMax.Min[ACOMP] = 1000;    ctx->MinMax.Max[ACOMP] = -1000;
+
+   /* Pipeline */
+   gl_pipeline_init( ctx );
+   gl_cva_init( ctx );
+
+   /* Extensions */
+   gl_extensions_ctr( ctx );
+
+   ctx->AllowVertexCull = CLIP_CULLED_BIT;
+
+   /* Lighting group */
+   for (i=0;i<MAX_LIGHTS;i++) {
+      init_light( &ctx->Light.Light[i], i );
+   }
+   make_empty_list( &ctx->Light.EnabledList );
+
+   init_lightmodel( &ctx->Light.Model );
+   init_material( &ctx->Light.Material[0] );
+   init_material( &ctx->Light.Material[1] );
+   ctx->Light.ShadeModel = GL_SMOOTH;
+   ctx->Light.Enabled = GL_FALSE;
+   ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
+   ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
+   ctx->Light.ColorMaterialBitmask
+      = gl_material_bitmask( ctx,
+                             GL_FRONT_AND_BACK,
+                             GL_AMBIENT_AND_DIFFUSE, ~0, 0 );
+
+   ctx->Light.ColorMaterialEnabled = GL_FALSE;
+
+   /* Lighting miscellaneous */
+   ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
+   make_empty_list( ctx->ShineTabList );
+   for (i = 0 ; i < 10 ; i++) {
+      struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
+      s->shininess = -1;
+      s->refcount = 0;
+      insert_at_tail( ctx->ShineTabList, s );
+   }
+   for (i = 0 ; i < 4 ; i++) {
+      ctx->ShineTable[i] = ctx->ShineTabList->prev;
+      ctx->ShineTable[i]->refcount++;
+   }
 
-      /* Viewport group */
-      ctx->Viewport.X = 0;
-      ctx->Viewport.Y = 0;
-      ctx->Viewport.Width = 0;
-      ctx->Viewport.Height = 0;
-      ctx->Viewport.Near = 0.0;
-      ctx->Viewport.Far = 1.0;
-      gl_matrix_ctr(&ctx->Viewport.WindowMap);
+   gl_compute_shine_table( ctx, 0, ctx->Light.Material[0].Shininess );
+   gl_compute_shine_table( ctx, 2, ctx->Light.Material[0].Shininess * .5 );
+   gl_compute_shine_table( ctx, 1, ctx->Light.Material[1].Shininess );
+   gl_compute_shine_table( ctx, 3, ctx->Light.Material[1].Shininess * .5 );
+
+
+   /* Line group */
+   ctx->Line.SmoothFlag = GL_FALSE;
+   ctx->Line.StippleFlag = GL_FALSE;
+   ctx->Line.Width = 1.0;
+   ctx->Line.StipplePattern = 0xffff;
+   ctx->Line.StippleFactor = 1;
+
+   /* Display List group */
+   ctx->List.ListBase = 0;
+
+   /* Pixel group */
+   ctx->Pixel.RedBias = 0.0;
+   ctx->Pixel.RedScale = 1.0;
+   ctx->Pixel.GreenBias = 0.0;
+   ctx->Pixel.GreenScale = 1.0;
+   ctx->Pixel.BlueBias = 0.0;
+   ctx->Pixel.BlueScale = 1.0;
+   ctx->Pixel.AlphaBias = 0.0;
+   ctx->Pixel.AlphaScale = 1.0;
+   ctx->Pixel.DepthBias = 0.0;
+   ctx->Pixel.DepthScale = 1.0;
+   ctx->Pixel.IndexOffset = 0;
+   ctx->Pixel.IndexShift = 0;
+   ctx->Pixel.ZoomX = 1.0;
+   ctx->Pixel.ZoomY = 1.0;
+   ctx->Pixel.MapColorFlag = GL_FALSE;
+   ctx->Pixel.MapStencilFlag = GL_FALSE;
+   ctx->Pixel.MapStoSsize = 1;
+   ctx->Pixel.MapItoIsize = 1;
+   ctx->Pixel.MapItoRsize = 1;
+   ctx->Pixel.MapItoGsize = 1;
+   ctx->Pixel.MapItoBsize = 1;
+   ctx->Pixel.MapItoAsize = 1;
+   ctx->Pixel.MapRtoRsize = 1;
+   ctx->Pixel.MapGtoGsize = 1;
+   ctx->Pixel.MapBtoBsize = 1;
+   ctx->Pixel.MapAtoAsize = 1;
+   ctx->Pixel.MapStoS[0] = 0;
+   ctx->Pixel.MapItoI[0] = 0;
+   ctx->Pixel.MapItoR[0] = 0.0;
+   ctx->Pixel.MapItoG[0] = 0.0;
+   ctx->Pixel.MapItoB[0] = 0.0;
+   ctx->Pixel.MapItoA[0] = 0.0;
+   ctx->Pixel.MapItoR8[0] = 0;
+   ctx->Pixel.MapItoG8[0] = 0;
+   ctx->Pixel.MapItoB8[0] = 0;
+   ctx->Pixel.MapItoA8[0] = 0;
+   ctx->Pixel.MapRtoR[0] = 0.0;
+   ctx->Pixel.MapGtoG[0] = 0.0;
+   ctx->Pixel.MapBtoB[0] = 0.0;
+   ctx->Pixel.MapAtoA[0] = 0.0;
+   ctx->Pixel.HistogramEnabled = GL_FALSE;
+   ctx->Pixel.MinMaxEnabled = GL_FALSE;
+   ctx->Pixel.PixelTextureEnabled = GL_FALSE;
+   ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
+   ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
+   ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
+   ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
+   ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
+   ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
+   ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
+   ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
+   ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
+   ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
+   ctx->Pixel.ColorTableEnabled = GL_FALSE;
+   ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
+   ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
+   ctx->Pixel.Convolution1DEnabled = GL_FALSE;
+   ctx->Pixel.Convolution2DEnabled = GL_FALSE;
+   ctx->Pixel.Separable2DEnabled = GL_FALSE;
+   for (i = 0; i < 3; i++) {
+      ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
+      ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
+      ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
+      ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
+   }
+   ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
+   ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
+
+   /* Point group */
+   ctx->Point.SmoothFlag = GL_FALSE;
+   ctx->Point.UserSize = 1.0;
+   ctx->Point.Size = 1.0;
+   ctx->Point.Params[0] = 1.0;
+   ctx->Point.Params[1] = 0.0;
+   ctx->Point.Params[2] = 0.0;
+   ctx->Point.Attenuated = GL_FALSE;
+   ctx->Point.MinSize = 0.0;
+   ctx->Point.MaxSize = (GLfloat) MAX_POINT_SIZE;
+   ctx->Point.Threshold = 1.0;
+
+   /* Polygon group */
+   ctx->Polygon.CullFlag = GL_FALSE;
+   ctx->Polygon.CullFaceMode = GL_BACK;
+   ctx->Polygon.FrontFace = GL_CCW;
+   ctx->Polygon.FrontBit = 0;
+   ctx->Polygon.FrontMode = GL_FILL;
+   ctx->Polygon.BackMode = GL_FILL;
+   ctx->Polygon.Unfilled = GL_FALSE;
+   ctx->Polygon.SmoothFlag = GL_FALSE;
+   ctx->Polygon.StippleFlag = GL_FALSE;
+   ctx->Polygon.OffsetFactor = 0.0F;
+   ctx->Polygon.OffsetUnits = 0.0F;
+   ctx->Polygon.OffsetPoint = GL_FALSE;
+   ctx->Polygon.OffsetLine = GL_FALSE;
+   ctx->Polygon.OffsetFill = GL_FALSE;
+
+   /* Polygon Stipple group */
+   MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
+
+   /* Scissor group */
+   ctx->Scissor.Enabled = GL_FALSE;
+   ctx->Scissor.X = 0;
+   ctx->Scissor.Y = 0;
+   ctx->Scissor.Width = 0;
+   ctx->Scissor.Height = 0;
+
+   /* Stencil group */
+   ctx->Stencil.Enabled = GL_FALSE;
+   ctx->Stencil.Function = GL_ALWAYS;
+   ctx->Stencil.FailFunc = GL_KEEP;
+   ctx->Stencil.ZPassFunc = GL_KEEP;
+   ctx->Stencil.ZFailFunc = GL_KEEP;
+   ctx->Stencil.Ref = 0;
+   ctx->Stencil.ValueMask = STENCIL_MAX;
+   ctx->Stencil.Clear = 0;
+   ctx->Stencil.WriteMask = STENCIL_MAX;
+
+   /* Texture group */
+   ctx->Texture.CurrentUnit = 0;      /* multitexture */
+   ctx->Texture.CurrentTransformUnit = 0; /* multitexture */
+   ctx->Texture.ReallyEnabled = 0;
+   for (i=0; i<MAX_TEXTURE_UNITS; i++)
+      init_texture_unit( ctx, i );
+   ctx->Texture.SharedPalette = GL_FALSE;
+   _mesa_init_colortable(&ctx->Texture.Palette);
+
+   /* Transformation group */
+   ctx->Transform.MatrixMode = GL_MODELVIEW;
+   ctx->Transform.Normalize = GL_FALSE;
+   ctx->Transform.RescaleNormals = GL_FALSE;
+   for (i=0;i<MAX_CLIP_PLANES;i++) {
+      ctx->Transform.ClipEnabled[i] = GL_FALSE;
+      ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
+   }
+   ctx->Transform.AnyClip = GL_FALSE;
+
+   /* Viewport group */
+   ctx->Viewport.X = 0;
+   ctx->Viewport.Y = 0;
+   ctx->Viewport.Width = 0;
+   ctx->Viewport.Height = 0;
+   ctx->Viewport.Near = 0.0;
+   ctx->Viewport.Far = 1.0;
+   gl_matrix_ctr(&ctx->Viewport.WindowMap);
 
 #define Sz 10
 #define Tz 14
-      ctx->Viewport.WindowMap.m[Sz] = 0.5 * DEPTH_SCALE;
-      ctx->Viewport.WindowMap.m[Tz] = 0.5 * DEPTH_SCALE;
+   ctx->Viewport.WindowMap.m[Sz] = 0.5 * ctx->Visual.DepthMaxF;
+   ctx->Viewport.WindowMap.m[Tz] = 0.5 * ctx->Visual.DepthMaxF;
 #undef Sz
 #undef Tz
 
-      ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
-      ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
-
-      /* Vertex arrays */
-      ctx->Array.Vertex.Size = 4;
-      ctx->Array.Vertex.Type = GL_FLOAT;
-      ctx->Array.Vertex.Stride = 0;
-      ctx->Array.Vertex.StrideB = 0;
-      ctx->Array.Vertex.Ptr = NULL;
-      ctx->Array.Vertex.Enabled = GL_FALSE;
-      ctx->Array.Normal.Type = GL_FLOAT;
-      ctx->Array.Normal.Stride = 0;
-      ctx->Array.Normal.StrideB = 0;
-      ctx->Array.Normal.Ptr = NULL;
-      ctx->Array.Normal.Enabled = GL_FALSE;
-      ctx->Array.Color.Size = 4;
-      ctx->Array.Color.Type = GL_FLOAT;
-      ctx->Array.Color.Stride = 0;
-      ctx->Array.Color.StrideB = 0;
-      ctx->Array.Color.Ptr = NULL;
-      ctx->Array.Color.Enabled = GL_FALSE;
-      ctx->Array.Index.Type = GL_FLOAT;
-      ctx->Array.Index.Stride = 0;
-      ctx->Array.Index.StrideB = 0;
-      ctx->Array.Index.Ptr = NULL;
-      ctx->Array.Index.Enabled = GL_FALSE;
-      for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-         ctx->Array.TexCoord[i].Size = 4;
-         ctx->Array.TexCoord[i].Type = GL_FLOAT;
-         ctx->Array.TexCoord[i].Stride = 0;
-         ctx->Array.TexCoord[i].StrideB = 0;
-         ctx->Array.TexCoord[i].Ptr = NULL;
-         ctx->Array.TexCoord[i].Enabled = GL_FALSE;
-      }
-      ctx->Array.TexCoordInterleaveFactor = 1;
-      ctx->Array.EdgeFlag.Stride = 0;
-      ctx->Array.EdgeFlag.StrideB = 0;
-      ctx->Array.EdgeFlag.Ptr = NULL;
-      ctx->Array.EdgeFlag.Enabled = GL_FALSE;
-      ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
-
-      /* Pixel transfer */
-      ctx->Pack.Alignment = 4;
-      ctx->Pack.RowLength = 0;
-      ctx->Pack.ImageHeight = 0;
-      ctx->Pack.SkipPixels = 0;
-      ctx->Pack.SkipRows = 0;
-      ctx->Pack.SkipImages = 0;
-      ctx->Pack.SwapBytes = GL_FALSE;
-      ctx->Pack.LsbFirst = GL_FALSE;
-      ctx->Unpack.Alignment = 4;
-      ctx->Unpack.RowLength = 0;
-      ctx->Unpack.ImageHeight = 0;
-      ctx->Unpack.SkipPixels = 0;
-      ctx->Unpack.SkipRows = 0;
-      ctx->Unpack.SkipImages = 0;
-      ctx->Unpack.SwapBytes = GL_FALSE;
-      ctx->Unpack.LsbFirst = GL_FALSE;
-
-      /* Feedback */
-      ctx->Feedback.Type = GL_2D;   /* TODO: verify */
-      ctx->Feedback.Buffer = NULL;
-      ctx->Feedback.BufferSize = 0;
-      ctx->Feedback.Count = 0;
-
-      /* Selection/picking */
-      ctx->Select.Buffer = NULL;
-      ctx->Select.BufferSize = 0;
-      ctx->Select.BufferCount = 0;
-      ctx->Select.Hits = 0;
-      ctx->Select.NameStackDepth = 0;
-
-      /* Optimized Accum buffer */
-      ctx->IntegerAccumMode = GL_TRUE;
-      ctx->IntegerAccumScaler = 0.0;
-
-      /* Renderer and client attribute stacks */
-      ctx->AttribStackDepth = 0;
-      ctx->ClientAttribStackDepth = 0;
-
-      /*** Miscellaneous ***/
-      ctx->NewState = NEW_ALL;
-      ctx->RenderMode = GL_RENDER;
-      ctx->StippleCounter = 0;
-      ctx->NeedNormals = GL_FALSE;
-      ctx->DoViewportMapping = GL_TRUE;
-
-      ctx->NeedEyeCoords = GL_FALSE;
-      ctx->NeedEyeNormals = GL_FALSE;
-      ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
-
-      /* Display list */
-      ctx->CallDepth = 0;
-      ctx->ExecuteFlag = GL_TRUE;
-      ctx->CompileFlag = GL_FALSE;
-      ctx->CurrentListPtr = NULL;
-      ctx->CurrentBlock = NULL;
-      ctx->CurrentListNum = 0;
-      ctx->CurrentPos = 0;
-
-      ctx->ErrorValue = (GLenum) GL_NO_ERROR;
-
-      ctx->CatchSignals = GL_TRUE;
-
-      /* For debug/development only */
-      ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
-
-      /* Dither disable */
-      ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
-      if (ctx->NoDither) {
-         if (getenv("MESA_DEBUG")) {
-            fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
-         }
-         ctx->Color.DitherFlag = GL_FALSE;
-      }
-   }
-}
-
+   ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
+   ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
+
+   /* Vertex arrays */
+   ctx->Array.Vertex.Size = 4;
+   ctx->Array.Vertex.Type = GL_FLOAT;
+   ctx->Array.Vertex.Stride = 0;
+   ctx->Array.Vertex.StrideB = 0;
+   ctx->Array.Vertex.Ptr = NULL;
+   ctx->Array.Vertex.Enabled = GL_FALSE;
+   ctx->Array.Normal.Type = GL_FLOAT;
+   ctx->Array.Normal.Stride = 0;
+   ctx->Array.Normal.StrideB = 0;
+   ctx->Array.Normal.Ptr = NULL;
+   ctx->Array.Normal.Enabled = GL_FALSE;
+   ctx->Array.Color.Size = 4;
+   ctx->Array.Color.Type = GL_FLOAT;
+   ctx->Array.Color.Stride = 0;
+   ctx->Array.Color.StrideB = 0;
+   ctx->Array.Color.Ptr = NULL;
+   ctx->Array.Color.Enabled = GL_FALSE;
+   ctx->Array.Index.Type = GL_FLOAT;
+   ctx->Array.Index.Stride = 0;
+   ctx->Array.Index.StrideB = 0;
+   ctx->Array.Index.Ptr = NULL;
+   ctx->Array.Index.Enabled = GL_FALSE;
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+      ctx->Array.TexCoord[i].Size = 4;
+      ctx->Array.TexCoord[i].Type = GL_FLOAT;
+      ctx->Array.TexCoord[i].Stride = 0;
+      ctx->Array.TexCoord[i].StrideB = 0;
+      ctx->Array.TexCoord[i].Ptr = NULL;
+      ctx->Array.TexCoord[i].Enabled = GL_FALSE;
+   }
+   ctx->Array.TexCoordInterleaveFactor = 1;
+   ctx->Array.EdgeFlag.Stride = 0;
+   ctx->Array.EdgeFlag.StrideB = 0;
+   ctx->Array.EdgeFlag.Ptr = NULL;
+   ctx->Array.EdgeFlag.Enabled = GL_FALSE;
+   ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
+
+   /* Pixel transfer */
+   ctx->Pack.Alignment = 4;
+   ctx->Pack.RowLength = 0;
+   ctx->Pack.ImageHeight = 0;
+   ctx->Pack.SkipPixels = 0;
+   ctx->Pack.SkipRows = 0;
+   ctx->Pack.SkipImages = 0;
+   ctx->Pack.SwapBytes = GL_FALSE;
+   ctx->Pack.LsbFirst = GL_FALSE;
+   ctx->Unpack.Alignment = 4;
+   ctx->Unpack.RowLength = 0;
+   ctx->Unpack.ImageHeight = 0;
+   ctx->Unpack.SkipPixels = 0;
+   ctx->Unpack.SkipRows = 0;
+   ctx->Unpack.SkipImages = 0;
+   ctx->Unpack.SwapBytes = GL_FALSE;
+   ctx->Unpack.LsbFirst = GL_FALSE;
+
+   /* Feedback */
+   ctx->Feedback.Type = GL_2D;   /* TODO: verify */
+   ctx->Feedback.Buffer = NULL;
+   ctx->Feedback.BufferSize = 0;
+   ctx->Feedback.Count = 0;
+
+   /* Selection/picking */
+   ctx->Select.Buffer = NULL;
+   ctx->Select.BufferSize = 0;
+   ctx->Select.BufferCount = 0;
+   ctx->Select.Hits = 0;
+   ctx->Select.NameStackDepth = 0;
+
+   /* Optimized Accum buffer */
+   ctx->IntegerAccumMode = GL_TRUE;
+   ctx->IntegerAccumScaler = 0.0;
+
+   /* Renderer and client attribute stacks */
+   ctx->AttribStackDepth = 0;
+   ctx->ClientAttribStackDepth = 0;
+
+   /* Display list */
+   ctx->CallDepth = 0;
+   ctx->ExecuteFlag = GL_TRUE;
+   ctx->CompileFlag = GL_FALSE;
+   ctx->CurrentListPtr = NULL;
+   ctx->CurrentBlock = NULL;
+   ctx->CurrentListNum = 0;
+   ctx->CurrentPos = 0;
+
+   /* Color tables */
+   _mesa_init_colortable(&ctx->ColorTable);
+   _mesa_init_colortable(&ctx->ProxyColorTable);
+   _mesa_init_colortable(&ctx->PostConvolutionColorTable);
+   _mesa_init_colortable(&ctx->ProxyPostConvolutionColorTable);
+   _mesa_init_colortable(&ctx->PostColorMatrixColorTable);
+   _mesa_init_colortable(&ctx->ProxyPostColorMatrixColorTable);
+
+   /* Miscellaneous */
+   ctx->NewState = NEW_ALL;
+   ctx->RenderMode = GL_RENDER;
+   ctx->StippleCounter = 0;
+   ctx->NeedNormals = GL_FALSE;
+   ctx->DoViewportMapping = GL_TRUE;
+   ctx->ImageTransferState = UPDATE_IMAGE_TRANSFER_STATE;
+
+   ctx->NeedEyeCoords = GL_FALSE;
+   ctx->NeedEyeNormals = GL_FALSE;
+   ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
 
+   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
 
-/*
- * Allocate a new GLvisual object.
- * Input:  rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
- *         alphaFlag - alloc software alpha buffers?
- *         dbFlag - double buffering?
- *         stereoFlag - stereo buffer?
- *         depthFits - requested minimum bits per depth buffer value
- *         stencilFits - requested minimum bits per stencil buffer value
- *         accumFits - requested minimum bits per accum buffer component
- *         indexFits - number of bits per pixel if rgbFlag==GL_FALSE
- *         red/green/blue/alphaFits - number of bits per color component
- *                                     in frame buffer for RGB(A) mode.
- * Return:  pointer to new GLvisual or NULL if requested parameters can't
- *          be met.
- */
-GLvisual *gl_create_visual( GLboolean rgbFlag,
-                            GLboolean alphaFlag,
-                            GLboolean dbFlag,
-                            GLboolean stereoFlag,
-                            GLint depthBits,
-                            GLint stencilBits,
-                            GLint accumBits,
-                            GLint indexBits,
-                            GLint redBits,
-                            GLint greenBits,
-                            GLint blueBits,
-                            GLint alphaBits )
-{
-   GLvisual *vis;
+   ctx->CatchSignals = GL_TRUE;
+   ctx->OcclusionResult = GL_FALSE;
+   ctx->OcclusionResultSaved = GL_FALSE;
 
-   if (depthBits > (GLint) (8*sizeof(GLdepth))) {
-      /* can't meet depth buffer requirements */
-      return NULL;
-   }
-   if (stencilBits > (GLint) (8*sizeof(GLstencil))) {
-      /* can't meet stencil buffer requirements */
-      return NULL;
-   }
-   if (accumBits > (GLint) (8*sizeof(GLaccum))) {
-      /* can't meet accum buffer requirements */
-      return NULL;
-   }
+   /* For debug/development only */
+   ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
+   ctx->FirstTimeCurrent = GL_TRUE;
 
-   vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
-   if (!vis) {
-      return NULL;
+   /* Dither disable */
+   ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
+   if (ctx->NoDither) {
+      if (getenv("MESA_DEBUG")) {
+         fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
+      }
+      ctx->Color.DitherFlag = GL_FALSE;
    }
-
-   vis->RGBAflag   = rgbFlag;
-   vis->DBflag     = dbFlag;
-   vis->StereoFlag = stereoFlag;
-   vis->RedBits    = redBits;
-   vis->GreenBits  = greenBits;
-   vis->BlueBits   = blueBits;
-   vis->AlphaBits  = alphaFlag ? 8*sizeof(GLubyte) : alphaBits;
-
-   vis->IndexBits   = indexBits;
-   vis->DepthBits   = (depthBits>0) ? 8*sizeof(GLdepth) : 0;
-   vis->AccumBits   = (accumBits>0) ? 8*sizeof(GLaccum) : 0;
-   vis->StencilBits = (stencilBits>0) ? 8*sizeof(GLstencil) : 0;
-
-   vis->SoftwareAlpha = alphaFlag;
-
-   return vis;
 }
 
 
 
-void gl_destroy_visual( GLvisual *vis )
-{
-   FREE( vis );
-}
-
-
 
 /*
  * Allocate the proxy textures.  If we run out of memory part way through
  * the allocations clean up and return GL_FALSE.
  * Return:  GL_TRUE=success, GL_FALSE=failure
  */
-static GLboolean alloc_proxy_textures( GLcontext *ctx )
+static GLboolean
+alloc_proxy_textures( GLcontext *ctx )
 {
    GLboolean out_of_memory;
    GLint i;
@@ -1189,9 +1380,9 @@ static GLboolean alloc_proxy_textures( GLcontext *ctx )
 
    out_of_memory = GL_FALSE;
    for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
-      ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
-      ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
-      ctx->Texture.Proxy3D->Image[i] = gl_alloc_texture_image();
+      ctx->Texture.Proxy1D->Image[i] = _mesa_alloc_texture_image();
+      ctx->Texture.Proxy2D->Image[i] = _mesa_alloc_texture_image();
+      ctx->Texture.Proxy3D->Image[i] = _mesa_alloc_texture_image();
       if (!ctx->Texture.Proxy1D->Image[i]
           || !ctx->Texture.Proxy2D->Image[i]
           || !ctx->Texture.Proxy3D->Image[i]) {
@@ -1201,13 +1392,13 @@ static GLboolean alloc_proxy_textures( GLcontext *ctx )
    if (out_of_memory) {
       for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
          if (ctx->Texture.Proxy1D->Image[i]) {
-            gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
+            _mesa_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
          }
          if (ctx->Texture.Proxy2D->Image[i]) {
-            gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
+            _mesa_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
          }
          if (ctx->Texture.Proxy3D->Image[i]) {
-            gl_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
+            _mesa_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
          }
       }
       gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
@@ -1221,56 +1412,47 @@ static GLboolean alloc_proxy_textures( GLcontext *ctx )
 }
 
 
-
 /*
- * Allocate and initialize a GLcontext structure.
- * Input:  visual - a GLvisual pointer
- *         sharelist - another context to share display lists with or NULL
- *         driver_ctx - pointer to device driver's context state struct
- * Return:  pointer to a new gl_context struct or NULL if error.
+ * Initialize a GLcontext struct.  This includes allocating all the
+ * other structs and arrays which hang off of the context by pointers.
  */
-GLcontext *gl_create_context( GLvisual *visual,
-                              GLcontext *share_list,
-                              void *driver_ctx,
-                              GLboolean direct )
+GLboolean
+_mesa_initialize_context( GLcontext *ctx,
+                          GLvisual *visual,
+                          GLcontext *share_list,
+                          void *driver_ctx,
+                          GLboolean direct )
 {
-   GLcontext *ctx;
-   GLuint i;
+   GLuint dispatchSize;
 
    (void) direct;  /* not used */
 
-   /* do some implementation tests */
-   assert( sizeof(GLbyte) == 1 );
-   assert( sizeof(GLshort) >= 2 );
-   assert( sizeof(GLint) >= 4 );
-   assert( sizeof(GLubyte) == 1 );
-   assert( sizeof(GLushort) >= 2 );
-   assert( sizeof(GLuint) >= 4 );
-
    /* misc one-time initializations */
    one_time_init();
 
-   ctx = (GLcontext *) CALLOC( sizeof(GLcontext) );
-   if (!ctx) {
-      return NULL;
+   /**
+    ** OpenGL SI stuff
+    **/
+   if (!ctx->imports.malloc) {
+      _mesa_InitDefaultImports(&ctx->imports, driver_ctx, NULL);
    }
+   /* exports are setup by the device driver */
 
    ctx->DriverCtx = driver_ctx;
-   ctx->Visual = visual;
-   ctx->Buffer = NULL;
+   ctx->Visual = *visual;
+   ctx->DrawBuffer = NULL;
+   ctx->ReadBuffer = NULL;
 
    ctx->VB = gl_vb_create_for_immediate( ctx );
    if (!ctx->VB) {
-      FREE( ctx );
-      return NULL;
+      return GL_FALSE;
    }
    ctx->input = ctx->VB->IM;
 
    ctx->PB = gl_alloc_pb();
    if (!ctx->PB) {
-      FREE( ctx->VB );
-      FREE( ctx );
-      return NULL;
+      ALIGN_FREE( ctx->VB );
+      return GL_FALSE;
    }
 
    if (share_list) {
@@ -1281,34 +1463,20 @@ GLcontext *gl_create_context( GLvisual *visual,
       /* allocate new group of display lists */
       ctx->Shared = alloc_shared_state();
       if (!ctx->Shared) {
-         FREE(ctx->VB);
-         FREE(ctx->PB);
-         FREE(ctx);
-         return NULL;
+         ALIGN_FREE( ctx->VB );
+         FREE( ctx->PB );
+         return GL_FALSE;
       }
    }
+   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
    ctx->Shared->RefCount++;
+   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+   init_attrib_groups( ctx );
 
-   initialize_context( ctx );
    gl_reset_vb( ctx->VB );
    gl_reset_input( ctx );
 
-
-   ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
-   make_empty_list( ctx->ShineTabList );
-
-   for (i = 0 ; i < 10 ; i++) {
-      struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
-      s->shininess = -1;
-      s->refcount = 0;
-      insert_at_tail( ctx->ShineTabList, s );
-   }
-
-   for (i = 0 ; i < 4 ; i++) {
-      ctx->ShineTable[i] = ctx->ShineTabList->prev;
-      ctx->ShineTable[i]->refcount++;
-   }
-
    if (visual->DBflag) {
       ctx->Color.DrawBuffer = GL_BACK;
       ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
@@ -1324,259 +1492,247 @@ GLcontext *gl_create_context( GLvisual *visual,
       ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
    }
 
-   
-   /* Fill in some driver defaults now.
-    */
-   ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
-   ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
-   ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
-
-   
-
-#ifdef PROFILE
-   init_timings( ctx );
-#endif
-
-#ifdef GL_VERSION_1_1
    if (!alloc_proxy_textures(ctx)) {
       free_shared_state(ctx, ctx->Shared);
-      FREE(ctx->VB);
-      FREE(ctx->PB);
-      FREE(ctx);
-      return NULL;
+      ALIGN_FREE( ctx->VB );
+      FREE( ctx->PB );
+      return GL_FALSE;
    }
-#endif
-
-   gl_init_api_function_pointers( ctx );
-   ctx->API = ctx->Exec;   /* GL_EXECUTE is default */
-
-   return ctx;
-}
-
-/* Just reads the config files...
- */
-void gl_context_initialize( GLcontext *ctx )
-{
-   gl_read_config_file( ctx );
-}
-
-
 
+   /* register the most recent extension functions with libGL */
+   _glapi_add_entrypoint("glTbufferMask3DFX", 553);
+   _glapi_add_entrypoint("glCompressedTexImage3DARB", 554);
+   _glapi_add_entrypoint("glCompressedTexImage2DARB", 555);
+   _glapi_add_entrypoint("glCompressedTexImage1DARB", 556);
+   _glapi_add_entrypoint("glCompressedTexSubImage3DARB", 557);
+   _glapi_add_entrypoint("glCompressedTexSubImage2DARB", 558);
+   _glapi_add_entrypoint("glCompressedTexSubImage1DARB", 559);
+   _glapi_add_entrypoint("glGetCompressedTexImageARB", 560);
+
+   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
+    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
+    * Mesa we do this to accomodate different versions of libGL and various
+    * DRI drivers.
+    */
+   dispatchSize = MAX2(_glapi_get_dispatch_table_size(),
+                       sizeof(struct _glapi_table) / sizeof(void *));
 
-/*
- * Destroy a gl_context structure.
- */
-void gl_destroy_context( GLcontext *ctx )
-{
-   if (ctx) {
-
-      GLuint i;
-      struct gl_shine_tab *s, *tmps;
-
-#ifdef PROFILE
-      if (getenv("MESA_PROFILE")) {
-         print_timings( ctx );
-      }
+   /* setup API dispatch tables */
+   ctx->Exec = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
+   ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
+   if (!ctx->Exec || !ctx->Save) {
+      free_shared_state(ctx, ctx->Shared);
+      ALIGN_FREE( ctx->VB );
+      FREE( ctx->PB );
+      if (ctx->Exec)
+         FREE( ctx->Exec );
+   }
+   _mesa_init_exec_table(ctx->Exec, dispatchSize);
+   _mesa_init_dlist_table(ctx->Save, dispatchSize);
+   ctx->CurrentDispatch = ctx->Exec;
+
+#if defined(MESA_TRACE)
+   ctx->TraceCtx = CALLOC( sizeof(trace_context_t) );
+#if 0
+   /* Brian: do you want to have CreateContext fail here,
+       or should we just trap in NewTrace (currently done)? */
+   if (!(ctx->TraceCtx)) {
+      free_shared_state(ctx, ctx->Shared);
+      ALIGN_FREE( ctx->VB );
+      FREE( ctx->PB );
+      FREE( ctx->Exec );
+      FREE( ctx->Save );
+      return GL_FALSE;
+   }
 #endif
+   trInitContext(ctx->TraceCtx);
 
-      gl_matrix_dtr( &ctx->ModelView );
-      for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
-        gl_matrix_dtr( &ctx->ModelViewStack[i] );
-      }
-      gl_matrix_dtr( &ctx->ProjectionMatrix );
-      for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
-        gl_matrix_dtr( &ctx->ProjectionStack[i] );
-      }
-
+   ctx->TraceDispatch = (struct _glapi_table *)
+                        CALLOC(dispatchSize * sizeof(void*));
+#if 0
+   if (!(ctx->TraceCtx)) {
+      free_shared_state(ctx, ctx->Shared);
+      ALIGN_FREE( ctx->VB );
       FREE( ctx->PB );
-
-      if(ctx->input != ctx->VB->IM)
-         gl_immediate_free( ctx->input );
-
-      gl_vb_free( ctx->VB );
-
-      ctx->Shared->RefCount--;
-      assert(ctx->Shared->RefCount>=0);
-      if (ctx->Shared->RefCount==0) {
-        /* free shared state */
-        free_shared_state( ctx, ctx->Shared );
-      }
-
-      foreach_s( s, tmps, ctx->ShineTabList ) {
-        FREE( s );
-      }
-      FREE( ctx->ShineTabList );
-
-      /* Free proxy texture objects */
-      gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
-      gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
-      gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
-
-      /* Free evaluator data */
-      if (ctx->EvalMap.Map1Vertex3.Points)
-         FREE( ctx->EvalMap.Map1Vertex3.Points );
-      if (ctx->EvalMap.Map1Vertex4.Points)
-         FREE( ctx->EvalMap.Map1Vertex4.Points );
-      if (ctx->EvalMap.Map1Index.Points)
-         FREE( ctx->EvalMap.Map1Index.Points );
-      if (ctx->EvalMap.Map1Color4.Points)
-         FREE( ctx->EvalMap.Map1Color4.Points );
-      if (ctx->EvalMap.Map1Normal.Points)
-         FREE( ctx->EvalMap.Map1Normal.Points );
-      if (ctx->EvalMap.Map1Texture1.Points)
-         FREE( ctx->EvalMap.Map1Texture1.Points );
-      if (ctx->EvalMap.Map1Texture2.Points)
-         FREE( ctx->EvalMap.Map1Texture2.Points );
-      if (ctx->EvalMap.Map1Texture3.Points)
-         FREE( ctx->EvalMap.Map1Texture3.Points );
-      if (ctx->EvalMap.Map1Texture4.Points)
-         FREE( ctx->EvalMap.Map1Texture4.Points );
-
-      if (ctx->EvalMap.Map2Vertex3.Points)
-         FREE( ctx->EvalMap.Map2Vertex3.Points );
-      if (ctx->EvalMap.Map2Vertex4.Points)
-         FREE( ctx->EvalMap.Map2Vertex4.Points );
-      if (ctx->EvalMap.Map2Index.Points)
-         FREE( ctx->EvalMap.Map2Index.Points );
-      if (ctx->EvalMap.Map2Color4.Points)
-         FREE( ctx->EvalMap.Map2Color4.Points );
-      if (ctx->EvalMap.Map2Normal.Points)
-         FREE( ctx->EvalMap.Map2Normal.Points );
-      if (ctx->EvalMap.Map2Texture1.Points)
-         FREE( ctx->EvalMap.Map2Texture1.Points );
-      if (ctx->EvalMap.Map2Texture2.Points)
-         FREE( ctx->EvalMap.Map2Texture2.Points );
-      if (ctx->EvalMap.Map2Texture3.Points)
-         FREE( ctx->EvalMap.Map2Texture3.Points );
-      if (ctx->EvalMap.Map2Texture4.Points)
-         FREE( ctx->EvalMap.Map2Texture4.Points );
-
-      /* Free cache of immediate buffers. */
-      while (ctx->nr_im_queued-- > 0) {
-         struct immediate * next = ctx->freed_im_queue->next;
-         FREE( ctx->freed_im_queue );
-         ctx->freed_im_queue = next;
-      }
-      gl_extensions_dtr(ctx);
-
-      FREE( (void *) ctx );
-
-#ifndef THREADS
-      if (ctx==CC) {
-         CC = NULL;
-        CURRENT_INPUT = NULL;
-      }
+      FREE( ctx->Exec );
+      FREE( ctx->Save );
+      FREE( ctx->TraceCtx );
+      return GL_FALSE;
+   }
+#endif
+   trInitDispatch(ctx->TraceDispatch);
 #endif
 
-   }
+   return GL_TRUE;
 }
 
 
 
 /*
- * Create a new framebuffer.  A GLframebuffer is a struct which
- * encapsulates the depth, stencil and accum buffers and related
- * parameters.
+ * Allocate and initialize a GLcontext structure.
  * Input:  visual - a GLvisual pointer
- * Return:  pointer to new GLframebuffer struct or NULL if error.
+ *         sharelist - another context to share display lists with or NULL
+ *         driver_ctx - pointer to device driver's context state struct
+ * Return:  pointer to a new __GLcontextRec or NULL if error.
  */
-GLframebuffer *gl_create_framebuffer( GLvisual *visual )
+GLcontext *
+_mesa_create_context( GLvisual *visual,
+                      GLcontext *share_list,
+                      void *driver_ctx,
+                      GLboolean direct )
 {
-   GLframebuffer *buffer;
-
-   buffer = (GLframebuffer *) CALLOC( sizeof(GLframebuffer) );
-   if (!buffer) {
+   GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) );
+   if (!ctx) {
       return NULL;
    }
 
-   buffer->Visual = visual;
-
-   return buffer;
+   if (_mesa_initialize_context(ctx, visual, share_list, driver_ctx, direct)) {
+      return ctx;
+   }
+   else {
+      FREE(ctx);
+      return NULL;
+   }
 }
 
 
 
 /*
- * Free a framebuffer struct and its buffers.
+ * Free the data associated with the given context.
+ * But don't free() the GLcontext struct itself!
  */
-void gl_destroy_framebuffer( GLframebuffer *buffer )
+void
+_mesa_free_context_data( GLcontext *ctx )
 {
-   if (buffer) {
-      if (buffer->Depth) {
-         FREE( buffer->Depth );
-      }
-      if (buffer->Accum) {
-         FREE( buffer->Accum );
-      }
-      if (buffer->Stencil) {
-         FREE( buffer->Stencil );
-      }
-      if (buffer->FrontLeftAlpha) {
-         FREE( buffer->FrontLeftAlpha );
-      }
-      if (buffer->BackLeftAlpha) {
-         FREE( buffer->BackLeftAlpha );
-      }
-      if (buffer->FrontRightAlpha) {
-         FREE( buffer->FrontRightAlpha );
-      }
-      if (buffer->BackRightAlpha) {
-         FREE( buffer->BackRightAlpha );
+   struct gl_shine_tab *s, *tmps;
+   GLuint i, j;
+
+   /* if we're destroying the current context, unbind it first */
+   if (ctx == _mesa_get_current_context()) {
+      _mesa_make_current(NULL, NULL);
+   }
+
+   gl_matrix_dtr( &ctx->ModelView );
+   for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
+      gl_matrix_dtr( &ctx->ModelViewStack[i] );
+   }
+   gl_matrix_dtr( &ctx->ProjectionMatrix );
+   for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
+      gl_matrix_dtr( &ctx->ProjectionStack[i] );
+   }
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+      gl_matrix_dtr( &ctx->TextureMatrix[i] );
+      for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
+         gl_matrix_dtr( &ctx->TextureStack[i][j] );
       }
-      FREE(buffer);
    }
+
+   FREE( ctx->PB );
+
+   if (ctx->input != ctx->VB->IM)
+      gl_immediate_free( ctx->input );
+
+   gl_vb_free( ctx->VB );
+
+   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+   ctx->Shared->RefCount--;
+   assert(ctx->Shared->RefCount >= 0);
+   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+   if (ctx->Shared->RefCount == 0) {
+      /* free shared state */
+      free_shared_state( ctx, ctx->Shared );
+   }
+
+   foreach_s( s, tmps, ctx->ShineTabList ) {
+      FREE( s );
+   }
+   FREE( ctx->ShineTabList );
+
+   /* Free proxy texture objects */
+   gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
+   gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
+   gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
+
+   /* Free evaluator data */
+   if (ctx->EvalMap.Map1Vertex3.Points)
+      FREE( ctx->EvalMap.Map1Vertex3.Points );
+   if (ctx->EvalMap.Map1Vertex4.Points)
+      FREE( ctx->EvalMap.Map1Vertex4.Points );
+   if (ctx->EvalMap.Map1Index.Points)
+      FREE( ctx->EvalMap.Map1Index.Points );
+   if (ctx->EvalMap.Map1Color4.Points)
+      FREE( ctx->EvalMap.Map1Color4.Points );
+   if (ctx->EvalMap.Map1Normal.Points)
+      FREE( ctx->EvalMap.Map1Normal.Points );
+   if (ctx->EvalMap.Map1Texture1.Points)
+      FREE( ctx->EvalMap.Map1Texture1.Points );
+   if (ctx->EvalMap.Map1Texture2.Points)
+      FREE( ctx->EvalMap.Map1Texture2.Points );
+   if (ctx->EvalMap.Map1Texture3.Points)
+      FREE( ctx->EvalMap.Map1Texture3.Points );
+   if (ctx->EvalMap.Map1Texture4.Points)
+      FREE( ctx->EvalMap.Map1Texture4.Points );
+
+   if (ctx->EvalMap.Map2Vertex3.Points)
+      FREE( ctx->EvalMap.Map2Vertex3.Points );
+   if (ctx->EvalMap.Map2Vertex4.Points)
+      FREE( ctx->EvalMap.Map2Vertex4.Points );
+   if (ctx->EvalMap.Map2Index.Points)
+      FREE( ctx->EvalMap.Map2Index.Points );
+   if (ctx->EvalMap.Map2Color4.Points)
+      FREE( ctx->EvalMap.Map2Color4.Points );
+   if (ctx->EvalMap.Map2Normal.Points)
+      FREE( ctx->EvalMap.Map2Normal.Points );
+   if (ctx->EvalMap.Map2Texture1.Points)
+      FREE( ctx->EvalMap.Map2Texture1.Points );
+   if (ctx->EvalMap.Map2Texture2.Points)
+      FREE( ctx->EvalMap.Map2Texture2.Points );
+   if (ctx->EvalMap.Map2Texture3.Points)
+      FREE( ctx->EvalMap.Map2Texture3.Points );
+   if (ctx->EvalMap.Map2Texture4.Points)
+      FREE( ctx->EvalMap.Map2Texture4.Points );
+
+   _mesa_free_colortable_data( &ctx->ColorTable );
+   _mesa_free_colortable_data( &ctx->PostConvolutionColorTable );
+   _mesa_free_colortable_data( &ctx->PostColorMatrixColorTable );
+   _mesa_free_colortable_data( &ctx->Texture.Palette );
+
+   /* Free cache of immediate buffers. */
+   while (ctx->nr_im_queued-- > 0) {
+      struct immediate * next = ctx->freed_im_queue->next;
+      ALIGN_FREE( ctx->freed_im_queue );
+      ctx->freed_im_queue = next;
+   }
+   gl_extensions_dtr(ctx);
+
+   FREE(ctx->Exec);
+   FREE(ctx->Save);
 }
 
 
 
 /*
- * Set the current context, binding the given frame buffer to the context.
+ * Destroy a GLcontext structure.
  */
-void gl_make_current( GLcontext *ctx, GLframebuffer *buffer )
+void
+_mesa_destroy_context( GLcontext *ctx )
 {
-   GET_CONTEXT;
-
-   /* Flush the old context
-    */
-   if (CC) {
-      ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(CC, "gl_make_current");
-   }
-
-#ifdef THREADS
-   /* TODO: unbind old buffer from context? */
-   set_thread_context( ctx );
-#else
-   if (CC && CC->Buffer) {
-      /* unbind frame buffer from context */
-      CC->Buffer = NULL;
-   }
-   CC = ctx;
    if (ctx) {
-      SET_IMMEDIATE(ctx, ctx->input);
-   }
-#endif
-
-   if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
-
-   if (ctx && buffer) {
-      /* TODO: check if ctx and buffer's visual match??? */
-      ctx->Buffer = buffer;      /* Bind the frame buffer to the context */
-      ctx->NewState = NEW_ALL;   /* just to be safe */
-      gl_update_state( ctx );
+      _mesa_free_context_data(ctx);
+      FREE( (void *) ctx );
    }
 }
 
 
+
 /*
- * Return current context handle.
+ * Called by the driver after both the context and driver are fully
+ * initialized.  Currently just reads the config file.
  */
-GLcontext *gl_get_current_context( void )
+void
+_mesa_context_initialize( GLcontext *ctx )
 {
-#ifdef THREADS
-   return gl_get_thread_context();
-#else
-   return CC;
-#endif
+   gl_read_config_file( ctx );
 }
 
 
@@ -1587,7 +1743,8 @@ GLcontext *gl_get_current_context( void )
  *         dst - destination context
  *         mask - bitwise OR of GL_*_BIT flags
  */
-void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
+void
+_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
 {
    if (mask & GL_ACCUM_BUFFER_BIT) {
       MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
@@ -1615,7 +1772,7 @@ void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
    }
    if (mask & GL_LIGHTING_BIT) {
       MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
-/*       gl_reinit_light_attrib( &dst->Light ); */
+      /*       gl_reinit_light_attrib( &dst->Light ); */
    }
    if (mask & GL_LINE_BIT) {
       MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
@@ -1659,26 +1816,132 @@ void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
 }
 
 
+/*
+ * Set the current context, binding the given frame buffer to the context.
+ */
+void
+_mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer )
+{
+   _mesa_make_current2( newCtx, buffer, buffer );
+}
+
 
 /*
- * Someday a GLS library or OpenGL-like debugger may call this function
- * to register it's own set of API entry points.
- * Input: ctx - the context to set API pointers for
- *        api - if NULL, restore original API pointers
- *              else, set API function table to this table.
+ * Bind the given context to the given draw-buffer and read-buffer
+ * and make it the current context for this thread.
  */
-void gl_set_api_table( GLcontext *ctx, const struct gl_api_table *api )
+void
+_mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
+                     GLframebuffer *readBuffer )
 {
-   if (api) {
-      MEMCPY( &ctx->API, api, sizeof(struct gl_api_table) );
+#if 0
+   GLcontext *oldCtx = gl_get_context();
+
+   /* Flush the old context
+    */
+   if (oldCtx) {
+      ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "_mesa_make_current");
+
+      /* unbind frame buffers from context */
+      if (oldCtx->DrawBuffer) {
+         oldCtx->DrawBuffer = NULL;
+      }
+      if (oldCtx->ReadBuffer) {
+         oldCtx->ReadBuffer = NULL;
+      }
+   }
+#endif
+
+   /* We call this function periodically (just here for now) in
+    * order to detect when multithreading has begun.
+    */
+   _glapi_check_multithread();
+
+   _glapi_set_context((void *) newCtx);
+   ASSERT(_mesa_get_current_context() == newCtx);
+   if (newCtx) {
+      SET_IMMEDIATE(newCtx, newCtx->input);
+      _glapi_set_dispatch(newCtx->CurrentDispatch);
    }
    else {
-      MEMCPY( &ctx->API, &ctx->Exec, sizeof(struct gl_api_table) );
+      _glapi_set_dispatch(NULL);  /* none current */
+   }
+
+   if (MESA_VERBOSE) fprintf(stderr, "_mesa_make_current()\n");
+
+   if (newCtx && drawBuffer && readBuffer) {
+      /* TODO: check if newCtx and buffer's visual match??? */
+      newCtx->DrawBuffer = drawBuffer;
+      newCtx->ReadBuffer = readBuffer;
+      newCtx->NewState = NEW_ALL;   /* just to be safe */
+      gl_update_state( newCtx );
+   }
+
+   /* We can use this to help debug user's problems.  Tell the to set
+    * the MESA_INFO env variable before running their app.  Then the
+    * first time each context is made current we'll print some useful
+    * information.
+    */
+   if (newCtx && newCtx->FirstTimeCurrent) {
+      if (getenv("MESA_INFO")) {
+         fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
+         fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
+         fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
+         fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
+#if defined(THREADS)
+         fprintf(stderr, "Mesa thread-safe: YES\n");
+#else
+         fprintf(stderr, "Mesa thread-safe: NO\n");
+#endif
+#if defined(USE_X86_ASM)
+         fprintf(stderr, "Mesa x86-optimized: YES\n");
+#else
+         fprintf(stderr, "Mesa x86-optimized: NO\n");
+#endif
+      }
+      newCtx->FirstTimeCurrent = GL_FALSE;
    }
 }
 
 
 
+/*
+ * Return current context handle for the calling thread.
+ * This isn't the fastest way to get the current context.
+ * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
+ */
+GLcontext *
+_mesa_get_current_context( void )
+{
+   return (GLcontext *) _glapi_get_context();
+}
+
+
+
+/*
+ * This should be called by device drivers just before they do a
+ * swapbuffers.  Any pending rendering commands will be executed.
+ */
+void
+_mesa_swapbuffers(GLcontext *ctx)
+{
+   FLUSH_VB( ctx, "swap buffers" );
+}
+
+
+
+/*
+ * Return pointer to this context's current API dispatch table.
+ * It'll either be the immediate-mode execute dispatcher or the
+ * display list compile dispatcher.
+ */
+struct _glapi_table *
+_mesa_get_dispatch(GLcontext *ctx)
+{
+   return ctx->CurrentDispatch;
+}
+
+
 
 /**********************************************************************/
 /*****                Miscellaneous functions                     *****/
@@ -1692,7 +1955,7 @@ void gl_set_api_table( GLcontext *ctx, const struct gl_api_table *api )
 void gl_problem( const GLcontext *ctx, const char *s )
 {
    fprintf( stderr, "Mesa implementation error: %s\n", s );
-   fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
+   fprintf( stderr, "Report to Mesa bug database at www.mesa3d.org\n" );
    (void) ctx;
 }
 
@@ -1703,28 +1966,19 @@ void gl_problem( const GLcontext *ctx, const char *s )
  * something illogical or if there's likely a bug in their program
  * (like enabled depth testing without a depth buffer).
  */
-void gl_warning( const GLcontext *ctx, const char *s )
+void
+_mesa_warning( const GLcontext *ctx, const char *s )
 {
-   GLboolean debug;
-#ifdef DEBUG
-   debug = GL_TRUE;
-#else
-   if (getenv("MESA_DEBUG")) {
-      debug = GL_TRUE;
-   }
-   else {
-      debug = GL_FALSE;
-   }
-#endif
-   if (debug) {
-      fprintf( stderr, "Mesa warning: %s\n", s );
-   }
-   (void) ctx;
+   (*ctx->imports.warning)((__GLcontext *) ctx, (char *) s);
 }
 
 
 
-void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
+/*
+ * Compile an error into current display list.
+ */
+void
+_mesa_compile_error( GLcontext *ctx, GLenum error, const char *s )
 {
    if (ctx->CompileFlag)
       gl_save_error( ctx, error, s );
@@ -1734,62 +1988,69 @@ void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
 }
 
 
+
 /*
  * This is Mesa's error handler.  Normally, all that's done is the updating
  * of the current error value.  If Mesa is compiled with -DDEBUG or if the
  * environment variable "MESA_DEBUG" is defined then a real error message
  * is printed to stderr.
- * Input:  error - the error value
- *         s - a diagnostic string
+ * Input:  ctx - the GL context
+ *         error - the error value
+ *         where - usually the name of function where error was detected
  */
-void gl_error( GLcontext *ctx, GLenum error, const char *s )
+void
+gl_error( GLcontext *ctx, GLenum error, const char *where )
 {
+   const char *debugEnv = getenv("MESA_DEBUG");
    GLboolean debug;
 
 #ifdef DEBUG
-   debug = GL_TRUE;
+   if (debugEnv && strstr(debugEnv, "silent"))
+      debug = GL_FALSE;
+   else
+      debug = GL_TRUE;
 #else
-   if (getenv("MESA_DEBUG")) {
+   if (debugEnv)
       debug = GL_TRUE;
-   }
-   else {
+   else
       debug = GL_FALSE;
-   }
 #endif
 
    if (debug) {
-      char errstr[1000];
-
+      const char *errstr;
       switch (error) {
         case GL_NO_ERROR:
-           strcpy( errstr, "GL_NO_ERROR" );
+           errstr = "GL_NO_ERROR";
            break;
         case GL_INVALID_VALUE:
-           strcpy( errstr, "GL_INVALID_VALUE" );
+           errstr = "GL_INVALID_VALUE";
            break;
         case GL_INVALID_ENUM:
-           strcpy( errstr, "GL_INVALID_ENUM" );
+           errstr = "GL_INVALID_ENUM";
            break;
         case GL_INVALID_OPERATION:
-           strcpy( errstr, "GL_INVALID_OPERATION" );
+           errstr = "GL_INVALID_OPERATION";
            break;
         case GL_STACK_OVERFLOW:
-           strcpy( errstr, "GL_STACK_OVERFLOW" );
+           errstr = "GL_STACK_OVERFLOW";
            break;
         case GL_STACK_UNDERFLOW:
-           strcpy( errstr, "GL_STACK_UNDERFLOW" );
+           errstr = "GL_STACK_UNDERFLOW";
            break;
         case GL_OUT_OF_MEMORY:
-           strcpy( errstr, "GL_OUT_OF_MEMORY" );
+           errstr = "GL_OUT_OF_MEMORY";
            break;
+         case GL_TABLE_TOO_LARGE:
+            errstr = "GL_TABLE_TOO_LARGE";
+            break;
         default:
-           strcpy( errstr, "unknown" );
+           errstr = "unknown";
            break;
       }
-      fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
+      fprintf(stderr, "Mesa user error: %s in %s\n", errstr, where);
    }
 
-   if (ctx->ErrorValue==GL_NO_ERROR) {
+   if (ctx->ErrorValue == GL_NO_ERROR) {
       ctx->ErrorValue = error;
    }
 
@@ -1801,681 +2062,54 @@ void gl_error( GLcontext *ctx, GLenum error, const char *s )
 
 
 
-/*
- * Execute a glGetError command
- */
-GLenum gl_GetError( GLcontext *ctx )
-{
-   GLenum e = ctx->ErrorValue;
-
-   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL( ctx, "glGetError", (GLenum) 0);
-
-   if (MESA_VERBOSE & VERBOSE_API)
-      fprintf(stderr, "glGetError <-- %s\n", gl_lookup_enum_by_nr(e));
-
-   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
-   return e;
-}
-
-
-
-void gl_ResizeBuffersMESA( GLcontext *ctx )
-{
-   GLuint buf_width, buf_height;
-
-   if (MESA_VERBOSE & VERBOSE_API)
-      fprintf(stderr, "glResizeBuffersMESA\n");
-
-   /* ask device driver for size of output buffer */
-   (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
-
-   /* see if size of device driver's color buffer (window) has changed */
-   if (ctx->Buffer->Width == (GLint) buf_width &&
-       ctx->Buffer->Height == (GLint) buf_height)
-      return;
-
-   ctx->NewState |= NEW_RASTER_OPS;  /* to update scissor / window bounds */
-
-   /* save buffer size */
-   ctx->Buffer->Width = buf_width;
-   ctx->Buffer->Height = buf_height;
-
-   /* Reallocate other buffers if needed. */
-   if (ctx->Visual->DepthBits>0) {
-      /* reallocate depth buffer */
-      (*ctx->Driver.AllocDepthBuffer)( ctx );
-   }
-   if (ctx->Visual->StencilBits>0) {
-      /* reallocate stencil buffer */
-      gl_alloc_stencil_buffer( ctx );
-   }
-   if (ctx->Visual->AccumBits>0) {
-      /* reallocate accum buffer */
-      gl_alloc_accum_buffer( ctx );
-   }
-   if (ctx->Visual->SoftwareAlpha) {
-      gl_alloc_alpha_buffers( ctx );
-   }
-}
-
-
-
-
-/**********************************************************************/
-/*****                   State update logic                       *****/
-/**********************************************************************/
-
-
-/*
- * Since the device driver may or may not support pixel logic ops we
- * have to make some extensive tests to determine whether or not
- * software-implemented logic operations have to be used.
- */
-static void update_pixel_logic( GLcontext *ctx )
-{
-   if (ctx->Visual->RGBAflag) {
-      /* RGBA mode blending w/ Logic Op */
-      if (ctx->Color.ColorLogicOpEnabled) {
-        if (ctx->Driver.LogicOp
-             && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
-           /* Device driver can do logic, don't have to do it in software */
-           ctx->Color.SWLogicOpEnabled = GL_FALSE;
-        }
-        else {
-           /* Device driver can't do logic op so we do it in software */
-           ctx->Color.SWLogicOpEnabled = GL_TRUE;
-        }
-      }
-      else {
-        /* no logic op */
-        if (ctx->Driver.LogicOp) {
-            (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
-         }
-        ctx->Color.SWLogicOpEnabled = GL_FALSE;
-      }
-   }
-   else {
-      /* CI mode Logic Op */
-      if (ctx->Color.IndexLogicOpEnabled) {
-        if (ctx->Driver.LogicOp
-             && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
-           /* Device driver can do logic, don't have to do it in software */
-           ctx->Color.SWLogicOpEnabled = GL_FALSE;
-        }
-        else {
-           /* Device driver can't do logic op so we do it in software */
-           ctx->Color.SWLogicOpEnabled = GL_TRUE;
-        }
-      }
-      else {
-        /* no logic op */
-        if (ctx->Driver.LogicOp) {
-            (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
-         }
-        ctx->Color.SWLogicOpEnabled = GL_FALSE;
-      }
-   }
-}
-
-
-
-/*
- * Check if software implemented RGBA or Color Index masking is needed.
- */
-static void update_pixel_masking( GLcontext *ctx )
+void
+_mesa_Finish( void )
 {
-   if (ctx->Visual->RGBAflag) {
-      GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
-      if (*colorMask == 0xffffffff) {
-         /* disable masking */
-         if (ctx->Driver.ColorMask) {
-            (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
-         }
-         ctx->Color.SWmasking = GL_FALSE;
-      }
-      else {
-         /* Ask driver to do color masking, if it can't then
-          * do it in software
-          */
-         GLboolean red   = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
-         GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
-         GLboolean blue  = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
-         GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
-         if (ctx->Driver.ColorMask
-             && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
-            ctx->Color.SWmasking = GL_FALSE;
-         }
-         else {
-            ctx->Color.SWmasking = GL_TRUE;
-         }
-      }
-   }
-   else {
-      if (ctx->Color.IndexMask==0xffffffff) {
-         /* disable masking */
-         if (ctx->Driver.IndexMask) {
-            (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
-         }
-         ctx->Color.SWmasking = GL_FALSE;
-      }
-      else {
-         /* Ask driver to do index masking, if it can't then
-          * do it in software
-          */
-         if (ctx->Driver.IndexMask
-             && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
-            ctx->Color.SWmasking = GL_FALSE;
-         }
-         else {
-            ctx->Color.SWmasking = GL_TRUE;
-         }
-      }
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFinish");
+   if (ctx->Driver.Finish) {
+      (*ctx->Driver.Finish)( ctx );
    }
 }
 
 
-static void update_fog_mode( GLcontext *ctx )
-{
-   int old_mode = ctx->FogMode;
-
-   if (ctx->Fog.Enabled) {
-      if (ctx->Texture.Enabled)
-         ctx->FogMode = FOG_FRAGMENT;
-      else if (ctx->Hint.Fog == GL_NICEST)
-         ctx->FogMode = FOG_FRAGMENT;
-      else
-         ctx->FogMode = FOG_VERTEX;
-
-      if (ctx->Driver.GetParameteri)
-         if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
-            ctx->FogMode = FOG_FRAGMENT;
-   }
-   else {
-      ctx->FogMode = FOG_NONE;
-   }
-   
-   if (old_mode != ctx->FogMode)
-      ctx->NewState |= NEW_FOG;
-}
-
 
-/*
- * Recompute the value of ctx->RasterMask, etc. according to
- * the current context.
- */
-static void update_rasterflags( GLcontext *ctx )
+void
+_mesa_Flush( void )
 {
-   ctx->RasterMask = 0;
-
-   if (ctx->Color.AlphaEnabled)                ctx->RasterMask |= ALPHATEST_BIT;
-   if (ctx->Color.BlendEnabled)                ctx->RasterMask |= BLEND_BIT;
-   if (ctx->Depth.Test)                        ctx->RasterMask |= DEPTH_BIT;
-   if (ctx->FogMode==FOG_FRAGMENT)     ctx->RasterMask |= FOG_BIT;
-   if (ctx->Color.SWLogicOpEnabled)    ctx->RasterMask |= LOGIC_OP_BIT;
-   if (ctx->Scissor.Enabled)           ctx->RasterMask |= SCISSOR_BIT;
-   if (ctx->Stencil.Enabled)           ctx->RasterMask |= STENCIL_BIT;
-   if (ctx->Color.SWmasking)           ctx->RasterMask |= MASKING_BIT;
-
-   if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
-       && ctx->Color.DrawBuffer != GL_NONE)
-      ctx->RasterMask |= ALPHABUF_BIT;
-
-   if (   ctx->Viewport.X<0
-       || ctx->Viewport.X + ctx->Viewport.Width > ctx->Buffer->Width
-       || ctx->Viewport.Y<0
-       || ctx->Viewport.Y + ctx->Viewport.Height > ctx->Buffer->Height) {
-      ctx->RasterMask |= WINCLIP_BIT;
-   }
-
-   /* If we're not drawing to exactly one color buffer set the
-    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
-    * buffers or the RGBA or CI mask disables all writes.
-    */
-
-   ctx->TriangleCaps &= ~DD_MULTIDRAW;
-
-   if (ctx->Color.MultiDrawBuffer) {
-      ctx->RasterMask |= MULTI_DRAW_BIT;
-      ctx->TriangleCaps |= DD_MULTIDRAW;
-   }
-   else if (ctx->Color.DrawBuffer==GL_NONE) {
-      ctx->RasterMask |= MULTI_DRAW_BIT;
-      ctx->TriangleCaps |= DD_MULTIDRAW;
-   }
-   else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
-      /* all RGBA channels disabled */
-      ctx->RasterMask |= MULTI_DRAW_BIT;
-      ctx->TriangleCaps |= DD_MULTIDRAW;
-      ctx->Color.DrawDestMask = 0;
-   }
-   else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
-      /* all color index bits disabled */
-      ctx->RasterMask |= MULTI_DRAW_BIT;
-      ctx->TriangleCaps |= DD_MULTIDRAW;
-      ctx->Color.DrawDestMask = 0;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFlush");
+   if (ctx->Driver.Flush) {
+      (*ctx->Driver.Flush)( ctx );
    }
 }
 
 
-void gl_print_state( const char *msg, GLuint state )
-{
-   fprintf(stderr,
-          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-          msg,
-          state,
-          (state & NEW_LIGHTING)         ? "lighting, " : "",
-          (state & NEW_RASTER_OPS)       ? "raster-ops, " : "",
-          (state & NEW_TEXTURING)        ? "texturing, " : "",
-          (state & NEW_POLYGON)          ? "polygon, " : "",
-          (state & NEW_DRVSTATE0)        ? "driver-0, " : "",
-          (state & NEW_DRVSTATE1)        ? "driver-1, " : "",
-          (state & NEW_DRVSTATE2)        ? "driver-2, " : "",
-          (state & NEW_DRVSTATE3)        ? "driver-3, " : "",
-          (state & NEW_MODELVIEW)        ? "modelview, " : "",
-          (state & NEW_PROJECTION)       ? "projection, " : "",
-          (state & NEW_TEXTURE_MATRIX)   ? "texture-matrix, " : "",
-          (state & NEW_USER_CLIP)        ? "user-clip, " : "",
-          (state & NEW_TEXTURE_ENV)      ? "texture-env, " : "",
-          (state & NEW_CLIENT_STATE)     ? "client-state, " : "",
-          (state & NEW_FOG)              ? "fog, " : "",
-          (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
-          (state & NEW_VIEWPORT)         ? "viewport, " : "",
-          (state & NEW_TEXTURE_ENABLE)   ? "texture-enable, " : "");
-}
-
-void gl_print_enable_flags( const char *msg, GLuint flags )
-{
-   fprintf(stderr,
-          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
-          msg,
-          flags,
-          (flags & ENABLE_TEX0)       ? "tex-0, " : "",
-          (flags & ENABLE_TEX1)       ? "tex-1, " : "",
-          (flags & ENABLE_LIGHT)      ? "light, " : "",
-          (flags & ENABLE_FOG)        ? "fog, " : "",
-          (flags & ENABLE_USERCLIP)   ? "userclip, " : "",
-          (flags & ENABLE_TEXGEN0)    ? "tex-gen-0, " : "",
-          (flags & ENABLE_TEXGEN1)    ? "tex-gen-1, " : "",
-          (flags & ENABLE_TEXMAT0)    ? "tex-mat-0, " : "",
-          (flags & ENABLE_TEXMAT1)    ? "tex-mat-1, " : "",
-          (flags & ENABLE_NORMALIZE)  ? "normalize, " : "",
-          (flags & ENABLE_RESCALE)    ? "rescale, " : "");
-}
-
-
-/*
- * If ctx->NewState is non-zero then this function MUST be called before
- * rendering any primitive.  Basically, function pointers and miscellaneous
- * flags are updated to reflect the current state of the state machine.
- */
-void gl_update_state( GLcontext *ctx )
-{
-   GLuint i;
-
-   if (MESA_VERBOSE & VERBOSE_STATE)
-      gl_print_state("", ctx->NewState);
-
-   if (ctx->NewState & NEW_CLIENT_STATE)
-      gl_update_client_state( ctx );
-
-   if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
-       (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
-      ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
-
-   if (ctx->NewState & NEW_TEXTURE_ENV) {
-      if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
-         ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
-        ctx->NewState &= ~NEW_TEXTURE_ENV;
-      ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
-      ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
-   }
-
-   if ((ctx->NewState & ~(NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE)) == 0) {
-
-      if (MESA_VERBOSE&VERBOSE_STATE)
-        fprintf(stderr, "update_state: goto finished\n");
-
-      goto finished;
-   }
-
-   if (ctx->NewState & NEW_TEXTURE_MATRIX) {
-      ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
-
-      for (i=0; i < MAX_TEXTURE_UNITS; i++) {
-        if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
-        {
-           gl_matrix_analyze( &ctx->TextureMatrix[i] );
-           ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
-
-           if (ctx->Texture.Unit[i].Enabled &&
-               ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
-              ctx->Enabled |= ENABLE_TEXMAT0 << i;
-        }
-      }
-   }
-
-   if (ctx->NewState & NEW_TEXTURING) {
-      ctx->Texture.NeedNormals = GL_FALSE;
-      gl_update_dirty_texobjs(ctx);
-      ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
-      ctx->Texture.ReallyEnabled = 0;
-
-      for (i=0; i < MAX_TEXTURE_UNITS; i++) {
-        if (ctx->Texture.Unit[i].Enabled) {
-           gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
-
-           ctx->Texture.ReallyEnabled |=
-              ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
-
-           if (ctx->Texture.Unit[i].GenFlags != 0) {
-              ctx->Enabled |= ENABLE_TEXGEN0 << i;
-
-              if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
-              {
-                 ctx->Texture.NeedNormals = GL_TRUE;
-                 ctx->Texture.NeedEyeCoords = GL_TRUE;
-              }
 
-              if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
-              {
-                 ctx->Texture.NeedEyeCoords = GL_TRUE;
-              }
-           }
-        }
-      }
-
-      ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
-      ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
-   }
-
-   if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
-
-
-      if (ctx->NewState & NEW_RASTER_OPS) {
-        update_pixel_logic(ctx);
-        update_pixel_masking(ctx);
-        update_fog_mode(ctx);
-        update_rasterflags(ctx);
-        if (ctx->Driver.Dither) {
-           (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
-        }
-
-        /* Check if incoming colors can be modified during rasterization */
-        if (ctx->Fog.Enabled ||
-            ctx->Texture.Enabled ||
-            ctx->Color.BlendEnabled ||
-            ctx->Color.SWmasking ||
-            ctx->Color.SWLogicOpEnabled) {
-           ctx->MutablePixels = GL_TRUE;
-        }
-        else {
-           ctx->MutablePixels = GL_FALSE;
-        }
-
-        /* update scissor region */
-
-        ctx->Buffer->Xmin = 0;
-        ctx->Buffer->Ymin = 0;
-        ctx->Buffer->Xmax = ctx->Buffer->Width-1;
-        ctx->Buffer->Ymax = ctx->Buffer->Height-1;
-        if (ctx->Scissor.Enabled) {
-           if (ctx->Scissor.X > ctx->Buffer->Xmin) {
-              ctx->Buffer->Xmin = ctx->Scissor.X;
-           }
-           if (ctx->Scissor.Y > ctx->Buffer->Ymin) {
-              ctx->Buffer->Ymin = ctx->Scissor.Y;
-           }
-           if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->Buffer->Xmax) {
-              ctx->Buffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
-           }
-           if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->Buffer->Ymax) {
-              ctx->Buffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
-           }
-        }
-
-        /* The driver isn't managing the depth buffer.
-         */
-        if (ctx->Driver.AllocDepthBuffer == gl_alloc_depth_buffer) 
-        {
-           if (ctx->Depth.Mask) {
-              switch (ctx->Depth.Func) {
-              case GL_LESS:
-                 ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
-                 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
-                 break;
-              case GL_GREATER:
-                 ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
-                 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
-                 break;
-              default:
-                 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
-                 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
-              }
-           }
-           else {
-              ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
-              ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
-           }
-        }
-      }
-
-      if (ctx->NewState & NEW_LIGHTING) {
-        ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
-        if (ctx->Light.Enabled) {
-           if (ctx->Light.Model.TwoSide)
-              ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
-           gl_update_lighting(ctx);
-        }
-      }
-   }
-
-   if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
-
-      ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
-
-      if (ctx->NewState & NEW_POLYGON) {
-        /* Setup CullBits bitmask */
-        if (ctx->Polygon.CullFlag) {
-           ctx->backface_sign = 1;
-           switch(ctx->Polygon.CullFaceMode) {
-           case GL_BACK:
-              if(ctx->Polygon.FrontFace==GL_CCW)
-                 ctx->backface_sign = -1;
-              ctx->Polygon.CullBits = 1;
-              break;
-           case GL_FRONT:
-              if(ctx->Polygon.FrontFace!=GL_CCW)
-                 ctx->backface_sign = -1;
-              ctx->Polygon.CullBits = 2;
-              break;
-           default:
-           case GL_FRONT_AND_BACK:
-              ctx->backface_sign = 0;
-              ctx->Polygon.CullBits = 0;
-              ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
-              break;
-           }
-        }
-        else {
-           ctx->Polygon.CullBits = 3;
-           ctx->backface_sign = 0;
-        }
-
-        /* Any Polygon offsets enabled? */
-        ctx->TriangleCaps &= ~DD_TRI_OFFSET;
-
-        if (ctx->Polygon.OffsetPoint ||
-            ctx->Polygon.OffsetLine ||
-            ctx->Polygon.OffsetFill)
-           ctx->TriangleCaps |= DD_TRI_OFFSET;
-
-        /* reset Z offsets now */
-        ctx->PointZoffset   = 0.0;
-        ctx->LineZoffset    = 0.0;
-        ctx->PolygonZoffset = 0.0;
-      }
-   }
-
-   if (ctx->NewState & ~(NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE|
-                        NEW_DRIVER_STATE|NEW_USER_CLIP|
-                        NEW_POLYGON))
-      gl_update_clipmask(ctx);
-
-   if (ctx->NewState & (NEW_LIGHTING|
-                       NEW_RASTER_OPS|
-                       NEW_TEXTURING|
-                       NEW_TEXTURE_ENV|
-                       NEW_POLYGON|
-                       NEW_DRVSTATE0|
-                       NEW_DRVSTATE1|
-                       NEW_DRVSTATE2|
-                       NEW_DRVSTATE3|
-                       NEW_USER_CLIP))
-   {
-      ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
-      ctx->IndirectTriangles |= DD_SW_RASTERIZE;
-
-      if (MESA_VERBOSE&VERBOSE_CULL)
-        gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
-
-      ctx->Driver.PointsFunc = NULL;
-      ctx->Driver.LineFunc = NULL;
-      ctx->Driver.TriangleFunc = NULL;
-      ctx->Driver.QuadFunc = NULL;
-      ctx->Driver.RectFunc = NULL;
-      ctx->Driver.RenderVBClippedTab = NULL;
-      ctx->Driver.RenderVBCulledTab = NULL;
-      ctx->Driver.RenderVBRawTab = NULL;
-
-      /*
-       * Here the driver sets up all the ctx->Driver function pointers to
-       * it's specific, private functions.
-       */
-      ctx->Driver.UpdateState(ctx);
-
-      if (MESA_VERBOSE&VERBOSE_CULL)
-        gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
-
-      /*
-       * In case the driver didn't hook in an optimized point, line or
-       * triangle function we'll now select "core/fallback" point, line
-       * and triangle functions.
-       */
-      if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
-        gl_set_point_function(ctx);
-        gl_set_line_function(ctx);
-        gl_set_triangle_function(ctx);
-        gl_set_quad_function(ctx);
-
-        if ((ctx->IndirectTriangles & 
-             (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
-            (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) 
-           ctx->IndirectTriangles &= ~DD_TRI_CULL;
-      }
-
-      if (MESA_VERBOSE&VERBOSE_CULL)
-        gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
-
-      gl_set_render_vb_function(ctx);
-   }
-
-   /* Should only be calc'd when !need_eye_coords and not culling.
-    */
-   if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
-      if (ctx->NewState & NEW_MODELVIEW) {
-        gl_matrix_analyze( &ctx->ModelView );
-        ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
-      }
-
-      if (ctx->NewState & NEW_PROJECTION) {
-        gl_matrix_analyze( &ctx->ProjectionMatrix );
-        ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
-
-        if (ctx->Transform.AnyClip) {
-           gl_update_userclip( ctx );
-        }
-      }
-
-      gl_calculate_model_project_matrix( ctx );
-      ctx->ModelProjectWinMatrixUptodate = 0;
-   }
-
-   /* Figure out whether we can light in object space or not.  If we
-    * can, find the current positions of the lights in object space
-    */
-   if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
-                       ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
-       (ctx->NewState & (NEW_LIGHTING | 
-                         NEW_FOG |
-                        NEW_MODELVIEW | 
-                        NEW_PROJECTION |
-                        NEW_TEXTURING |
-                        NEW_RASTER_OPS |
-                        NEW_USER_CLIP)))
-   {
-      GLboolean oldcoord, oldnorm;
-
-      oldcoord = ctx->NeedEyeCoords;
-      oldnorm = ctx->NeedEyeNormals;
-
-      ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
-      ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
-                           ctx->Point.Attenuated);
-      ctx->NeedEyeNormals = GL_FALSE;
-
-      if (ctx->Light.Enabled) {
-        if (ctx->Light.Flags & LIGHT_POSITIONAL) {
-           /* Need length for attenuation */
-           if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
-              ctx->NeedEyeCoords = GL_TRUE;
-        } else if (ctx->Light.NeedVertices) {
-           /* Need angle for spot calculations */
-           if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
-              ctx->NeedEyeCoords = GL_TRUE;
-        }
-        ctx->NeedEyeNormals = ctx->NeedEyeCoords;
-      }
-      if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
-        if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
-        if (ctx->Texture.NeedNormals)
-           ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
-      }
-
-      ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
-
-      if (ctx->NeedEyeCoords)
-        ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
-
-      if (ctx->Light.Enabled) {
-        gl_update_lighting_function(ctx);
-
-        if ( (ctx->NewState & NEW_LIGHTING) ||
-             ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
-              !ctx->NeedEyeCoords) ||
-             oldcoord != ctx->NeedEyeCoords ||
-             oldnorm != ctx->NeedEyeNormals) {
-           gl_compute_light_positions(ctx);
-        }
-
-        ctx->rescale_factor = 1.0F;
-
-        if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
-                                    MAT_FLAG_GENERAL_SCALE |
-                                    MAT_FLAG_GENERAL_3D |
-                                    MAT_FLAG_GENERAL) )
-
-        {
-           GLfloat *m = ctx->ModelView.inv;
-           GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
-           if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
-              ctx->rescale_factor = 1.0/GL_SQRT(f);
-        }
-      }
-
-      gl_update_normal_transform( ctx );
-   }
-
- finished:
-   gl_update_pipelines(ctx);
-   ctx->NewState = 0;
-}
+const char *_mesa_prim_name[GL_POLYGON+2] = {
+   "GL_POINTS",
+   "GL_LINES",
+   "GL_LINE_LOOP",
+   "GL_LINE_STRIP",
+   "GL_TRIANGLES",
+   "GL_TRIANGLE_STRIP",
+   "GL_TRIANGLE_FAN",
+   "GL_QUADS",
+   "GL_QUAD_STRIP",
+   "GL_POLYGON",
+   "culled primitive"
+};
+
+
+GLenum gl_reduce_prim[GL_POLYGON+1] = {
+   GL_POINTS,
+   GL_LINES,
+   GL_LINES,
+   GL_LINES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+};