Fix crash when debug output is enabled and sarea is notset in r200Clear
[mesa.git] / src / mesa / main / context.c
index 465d6b3f89ab0ea04806488ea176a32b52661e42..eafe292a1f2d686bd48f8eae6d082f13898d885f 100644 (file)
@@ -1,14 +1,9 @@
-/**
- * \file context.c
- * Mesa context/visual/framebuffer management functions.
- * \author Brian Paul
- */
-
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.3
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008  VMware, Inc.  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"),
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+/**
+ * \file context.c
+ * Mesa context/visual/framebuffer management functions.
+ * \author Brian Paul
+ */
 
 /**
  * \mainpage Mesa Main Module
 
 
 #include "glheader.h"
+#include "mfeatures.h"
 #include "imports.h"
+#if FEATURE_accum
 #include "accum.h"
+#endif
 #include "api_exec.h"
 #include "arrayobj.h"
+#if FEATURE_attrib_stack
 #include "attrib.h"
+#endif
 #include "blend.h"
 #include "buffers.h"
 #include "bufferobj.h"
+#if FEATURE_colortable
 #include "colortab.h"
+#endif
 #include "context.h"
+#include "cpuinfo.h"
 #include "debug.h"
 #include "depth.h"
+#if FEATURE_dlist
 #include "dlist.h"
+#endif
+#if FEATURE_evaluators
 #include "eval.h"
+#endif
 #include "enums.h"
 #include "extensions.h"
 #include "fbobject.h"
+#if FEATURE_feedback
 #include "feedback.h"
+#endif
 #include "fog.h"
 #include "framebuffer.h"
 #include "get.h"
+#if FEATURE_histogram
 #include "histogram.h"
+#endif
 #include "hint.h"
 #include "hash.h"
 #include "light.h"
 #include "lines.h"
 #include "macros.h"
 #include "matrix.h"
+#include "multisample.h"
 #include "pixel.h"
 #include "pixelstore.h"
 #include "points.h"
 #include "polygon.h"
+#if FEATURE_ARB_occlusion_query
 #include "queryobj.h"
+#endif
+#if FEATURE_drawpix
 #include "rastpos.h"
+#endif
+#include "scissor.h"
+#include "shared.h"
 #include "simple_list.h"
 #include "state.h"
 #include "stencil.h"
 #include "mtypes.h"
 #include "varray.h"
 #include "version.h"
+#include "viewport.h"
 #include "vtxfmt.h"
 #include "glapi/glthread.h"
 #include "glapi/glapioffsets.h"
-#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+#include "glapi/glapitable.h"
 #include "shader/program.h"
-#endif
 #include "shader/shader_api.h"
+#if FEATURE_ATI_fragment_shader
 #include "shader/atifragshader.h"
+#endif
 #if _HAVE_FULL_GL
-#include "math/m_translate.h"
 #include "math/m_matrix.h"
-#include "math/m_xform.h"
-#include "math/mathmod.h"
 #endif
 
 #ifdef USE_SPARC_ASM
@@ -157,7 +179,7 @@ GLfloat _mesa_ubyte_to_float_color_tab[256];
 /**
  * Swap buffers notification callback.
  * 
- * \param gc GL context.
+ * \param ctx GL context.
  *
  * Called by window system just before swapping buffers.
  * We have to finish any pending rendering.
@@ -165,6 +187,7 @@ GLfloat _mesa_ubyte_to_float_color_tab[256];
 void
 _mesa_notifySwapBuffers(__GLcontext *ctx)
 {
+   FLUSH_CURRENT( ctx, 0 );
    if (ctx->Driver.Flush) {
       ctx->Driver.Flush(ctx);
    }
@@ -331,6 +354,36 @@ _mesa_destroy_visual( GLvisual *vis )
 /**********************************************************************/
 /*@{*/
 
+
+/**
+ * This is lame.  gdb only seems to recognize enum types that are
+ * actually used somewhere.  We want to be able to print/use enum
+ * values such as TEXTURE_2D_INDEX in gdb.  But we don't actually use
+ * the gl_texture_index type anywhere.  Thus, this lame function.
+ */
+static void
+dummy_enum_func(void)
+{
+   gl_buffer_index bi;
+   gl_colortable_index ci;
+   gl_face_index fi;
+   gl_frag_attrib fa;
+   gl_frag_result fr;
+   gl_texture_index ti;
+   gl_vert_attrib va;
+   gl_vert_result vr;
+
+   (void) bi;
+   (void) ci;
+   (void) fi;
+   (void) fa;
+   (void) fr;
+   (void) ti;
+   (void) va;
+   (void) vr;
+}
+
+
 /**
  * One-time initialization mutex lock.
  *
@@ -364,19 +417,14 @@ one_time_init( GLcontext *ctx )
       assert( sizeof(GLint) == 4 );
       assert( sizeof(GLuint) == 4 );
 
-      _mesa_init_sqrt_table();
+      _mesa_get_cpu_features();
 
-#if _HAVE_FULL_GL
-      _math_init();
+      _mesa_init_sqrt_table();
 
       for (i = 0; i < 256; i++) {
          _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
       }
-#endif
 
-#ifdef USE_SPARC_ASM
-      _mesa_init_sparc_glapi_relocs();
-#endif
       if (_mesa_getenv("MESA_DEBUG")) {
          _glapi_noop_enable_warnings(GL_TRUE);
          _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
@@ -393,359 +441,8 @@ one_time_init( GLcontext *ctx )
       alreadyCalled = GL_TRUE;
    }
    _glthread_UNLOCK_MUTEX(OneTimeLock);
-}
-
-
-/**
- * Allocate and initialize a shared context state structure.
- * Initializes the display list, texture objects and vertex programs hash
- * tables, allocates the texture objects. If it runs out of memory, frees
- * everything already allocated before returning NULL.
- *
- * \return pointer to a gl_shared_state structure on success, or NULL on
- * failure.
- */
-static GLboolean
-alloc_shared_state( GLcontext *ctx )
-{
-   struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
-   if (!ss)
-      return GL_FALSE;
-
-   ctx->Shared = ss;
-
-   _glthread_INIT_MUTEX(ss->Mutex);
-
-   ss->DisplayList = _mesa_NewHashTable();
-   ss->TexObjects = _mesa_NewHashTable();
-#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
-   ss->Programs = _mesa_NewHashTable();
-#endif
-
-#if FEATURE_ARB_vertex_program
-   ss->DefaultVertexProgram = (struct gl_vertex_program *)
-      ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
-   if (!ss->DefaultVertexProgram)
-      goto cleanup;
-#endif
-#if FEATURE_ARB_fragment_program
-   ss->DefaultFragmentProgram = (struct gl_fragment_program *)
-      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-   if (!ss->DefaultFragmentProgram)
-      goto cleanup;
-#endif
-#if FEATURE_ATI_fragment_shader
-   ss->ATIShaders = _mesa_NewHashTable();
-   ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
-   if (!ss->DefaultFragmentShader)
-      goto cleanup;
-#endif
-
-#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
-   ss->BufferObjects = _mesa_NewHashTable();
-#endif
-
-   ss->ArrayObjects = _mesa_NewHashTable();
-
-#if FEATURE_ARB_shader_objects
-   ss->ShaderObjects = _mesa_NewHashTable();
-#endif
-
-   ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
-   if (!ss->Default1D)
-      goto cleanup;
-
-   ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
-   if (!ss->Default2D)
-      goto cleanup;
-
-   ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
-   if (!ss->Default3D)
-      goto cleanup;
-
-   ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
-   if (!ss->DefaultCubeMap)
-      goto cleanup;
-
-   ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
-   if (!ss->DefaultRect)
-      goto cleanup;
-
-   ss->Default1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT);
-   if (!ss->Default1DArray)
-      goto cleanup;
 
-   ss->Default2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT);
-   if (!ss->Default2DArray)
-      goto cleanup;
-
-   /* Effectively bind the default textures to all texture units */
-   ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default1DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default2DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-
-   _glthread_INIT_MUTEX(ss->TexMutex);
-   ss->TextureStateStamp = 0;
-
-
-#if FEATURE_EXT_framebuffer_object
-   ss->FrameBuffers = _mesa_NewHashTable();
-   if (!ss->FrameBuffers)
-      goto cleanup;
-   ss->RenderBuffers = _mesa_NewHashTable();
-   if (!ss->RenderBuffers)
-      goto cleanup;
-#endif
-
-
-   return GL_TRUE;
-
- cleanup:
-   /* Ran out of memory at some point.  Free everything and return NULL */
-   if (ss->DisplayList)
-      _mesa_DeleteHashTable(ss->DisplayList);
-   if (ss->TexObjects)
-      _mesa_DeleteHashTable(ss->TexObjects);
-#if FEATURE_NV_vertex_program
-   if (ss->Programs)
-      _mesa_DeleteHashTable(ss->Programs);
-#endif
-#if FEATURE_ARB_vertex_program
-   _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
-#endif
-#if FEATURE_ARB_fragment_program
-   _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
-#endif
-#if FEATURE_ATI_fragment_shader
-   if (ss->DefaultFragmentShader)
-      _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
-#endif
-#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
-   if (ss->BufferObjects)
-      _mesa_DeleteHashTable(ss->BufferObjects);
-#endif
-
-   if (ss->ArrayObjects)
-      _mesa_DeleteHashTable (ss->ArrayObjects);
-
-#if FEATURE_ARB_shader_objects
-   if (ss->ShaderObjects)
-      _mesa_DeleteHashTable (ss->ShaderObjects);
-#endif
-
-#if FEATURE_EXT_framebuffer_object
-   if (ss->FrameBuffers)
-      _mesa_DeleteHashTable(ss->FrameBuffers);
-   if (ss->RenderBuffers)
-      _mesa_DeleteHashTable(ss->RenderBuffers);
-#endif
-
-   if (ss->Default1D)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
-   if (ss->Default2D)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
-   if (ss->Default3D)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
-   if (ss->DefaultCubeMap)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
-   if (ss->DefaultRect)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
-   if (ss->Default1DArray)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->Default1DArray);
-   if (ss->Default2DArray)
-      (*ctx->Driver.DeleteTexture)(ctx, ss->Default2DArray);
-
-   _mesa_free(ss);
-
-   return GL_FALSE;
-}
-
-
-/**
- * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
- */
-static void
-delete_displaylist_cb(GLuint id, void *data, void *userData)
-{
-   struct mesa_display_list *list = (struct mesa_display_list *) data;
-   GLcontext *ctx = (GLcontext *) userData;
-   _mesa_delete_list(ctx, list);
-}
-
-/**
- * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
- */
-static void
-delete_texture_cb(GLuint id, void *data, void *userData)
-{
-   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
-   GLcontext *ctx = (GLcontext *) userData;
-   ctx->Driver.DeleteTexture(ctx, texObj);
-}
-
-/**
- * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
- */
-static void
-delete_program_cb(GLuint id, void *data, void *userData)
-{
-   struct gl_program *prog = (struct gl_program *) data;
-   GLcontext *ctx = (GLcontext *) userData;
-   ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
-   prog->RefCount = 0;  /* now going away */
-   ctx->Driver.DeleteProgram(ctx, prog);
-}
-
-/**
- * Callback for deleting an ATI fragment shader object.
- * Called by _mesa_HashDeleteAll().
- */
-static void
-delete_fragshader_cb(GLuint id, void *data, void *userData)
-{
-   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
-   GLcontext *ctx = (GLcontext *) userData;
-   _mesa_delete_ati_fragment_shader(ctx, shader);
-}
-
-/**
- * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
- */
-static void
-delete_bufferobj_cb(GLuint id, void *data, void *userData)
-{
-   struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
-   GLcontext *ctx = (GLcontext *) userData;
-   ctx->Driver.DeleteBuffer(ctx, bufObj);
-}
-
-/**
- * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
- */
-static void
-delete_arrayobj_cb(GLuint id, void *data, void *userData)
-{
-   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
-   GLcontext *ctx = (GLcontext *) userData;
-   _mesa_delete_array_object(ctx, arrayObj);
-}
-
-/**
- * Callback for freeing shader program data. Call it before delete_shader_cb
- * to avoid memory access error.
- */
-static void
-free_shader_program_data_cb(GLuint id, void *data, void *userData)
-{
-   GLcontext *ctx = (GLcontext *) userData;
-   struct gl_shader_program *shProg = (struct gl_shader_program *) data;
-
-   if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
-       _mesa_free_shader_program_data(ctx, shProg);
-   }
-}
-
-/**
- * Callback for deleting shader and shader programs objects.
- * Called by _mesa_HashDeleteAll().
- */
-static void
-delete_shader_cb(GLuint id, void *data, void *userData)
-{
-   GLcontext *ctx = (GLcontext *) userData;
-   struct gl_shader *sh = (struct gl_shader *) data;
-   if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
-      _mesa_free_shader(ctx, sh);
-   }
-   else {
-      struct gl_shader_program *shProg = (struct gl_shader_program *) data;
-      ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
-      _mesa_free_shader_program(ctx, shProg);
-   }
-}
-
-
-/**
- * Deallocate a shared state object and all children structures.
- *
- * \param ctx GL context.
- * \param ss shared state pointer.
- * 
- * Frees the display lists, the texture objects (calling the driver texture
- * deletion callback to free its private data) and the vertex programs, as well
- * as their hash tables.
- *
- * \sa alloc_shared_state().
- */
-static void
-free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
-{
-   /*
-    * Free display lists
-    */
-   _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
-   _mesa_DeleteHashTable(ss->DisplayList);
-
-#if FEATURE_ARB_shader_objects
-   _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
-   _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
-   _mesa_DeleteHashTable(ss->ShaderObjects);
-#endif
-
-#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
-   _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
-   _mesa_DeleteHashTable(ss->Programs);
-#endif
-#if FEATURE_ARB_vertex_program
-   _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
-#endif
-#if FEATURE_ARB_fragment_program
-   _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
-#endif
-
-#if FEATURE_ATI_fragment_shader
-   _mesa_HashDeleteAll(ss->ATIShaders, delete_fragshader_cb, ctx);
-   _mesa_DeleteHashTable(ss->ATIShaders);
-   _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
-#endif
-
-#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
-   _mesa_HashDeleteAll(ss->BufferObjects, delete_bufferobj_cb, ctx);
-   _mesa_DeleteHashTable(ss->BufferObjects);
-#endif
-
-   _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
-   _mesa_DeleteHashTable(ss->ArrayObjects);
-
-#if FEATURE_EXT_framebuffer_object
-   _mesa_DeleteHashTable(ss->FrameBuffers);
-   _mesa_DeleteHashTable(ss->RenderBuffers);
-#endif
-
-   /*
-    * Free texture objects (after FBOs since some textures might have
-    * been bound to FBOs).
-    */
-   ASSERT(ctx->Driver.DeleteTexture);
-   /* the default textures */
-   ctx->Driver.DeleteTexture(ctx, ss->Default1D);
-   ctx->Driver.DeleteTexture(ctx, ss->Default2D);
-   ctx->Driver.DeleteTexture(ctx, ss->Default3D);
-   ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
-   ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
-   ctx->Driver.DeleteTexture(ctx, ss->Default1DArray);
-   ctx->Driver.DeleteTexture(ctx, ss->Default2DArray);
-   /* all other textures */
-   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
-   _mesa_DeleteHashTable(ss->TexObjects);
-
-   _glthread_DESTROY_MUTEX(ss->Mutex);
-
-   _mesa_free(ss);
+   dummy_enum_func();
 }
 
 
@@ -758,12 +455,12 @@ _mesa_init_current(GLcontext *ctx)
    GLuint i;
 
    /* Init all to (0,0,0,1) */
-   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+   for (i = 0; i < Elements(ctx->Current.Attrib); i++) {
       ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
    }
 
    /* redo special cases: */
-   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
+   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
    ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
    ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
    ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
@@ -773,11 +470,33 @@ _mesa_init_current(GLcontext *ctx)
 
 
 /**
- * Init vertex/fragment program native limits from logical limits.
+ * Init vertex/fragment program limits.
+ * Important: drivers should override these with actual limits.
  */
 static void
-init_natives(struct gl_program_constants *prog)
+init_program_limits(GLenum type, struct gl_program_constants *prog)
 {
+   prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS;
+   prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS;
+   prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS;
+   prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS;
+   prog->MaxTemps = MAX_PROGRAM_TEMPS;
+   prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
+   prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
+   prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
+
+   if (type == GL_VERTEX_PROGRAM_ARB) {
+      prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+      prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
+      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+   }
+   else {
+      prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+      prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
+      prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
+   }
+
+   /* copy the above limits to init native limits */
    prog->MaxNativeInstructions = prog->MaxInstructions;
    prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
    prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
@@ -802,8 +521,8 @@ _mesa_init_constants(GLcontext *ctx)
    assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
    assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
 
-   assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_COORD_UNITS);
-   assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_IMAGE_UNITS);
+   /* Max texture size should be <= max viewport size (render to texture) */
+   assert((1 << (MAX_TEXTURE_LEVELS - 1)) <= MAX_WIDTH);
 
    /* Constants, may be overriden (usually only reduced) by device drivers */
    ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
@@ -839,33 +558,10 @@ _mesa_init_constants(GLcontext *ctx)
    ctx->Const.MaxViewportWidth = MAX_WIDTH;
    ctx->Const.MaxViewportHeight = MAX_HEIGHT;
 #if FEATURE_ARB_vertex_program
-   ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
-   ctx->Const.VertexProgram.MaxAluInstructions = 0;
-   ctx->Const.VertexProgram.MaxTexInstructions = 0;
-   ctx->Const.VertexProgram.MaxTexIndirections = 0;
-   ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
-   ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS;
-   ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
-   ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
-   ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
-   ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
-   ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
-   init_natives(&ctx->Const.VertexProgram);
+   init_program_limits(GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram);
 #endif
-
 #if FEATURE_ARB_fragment_program
-   ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
-   ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
-   ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
-   ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
-   ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
-   ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS;
-   ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
-   ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
-   ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
-   ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
-   ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
-   init_natives(&ctx->Const.FragmentProgram);
+   init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram);
 #endif
    ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
    ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
@@ -890,6 +586,15 @@ _mesa_init_constants(GLcontext *ctx)
    ctx->Const.MaxVarying = MAX_VARYING;
 #endif
 
+   /* GL_ARB_framebuffer_object */
+   ctx->Const.MaxSamples = 0;
+
+   /* GL_ATI_envmap_bumpmap */
+   ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
+
+   /* GL_EXT_provoking_vertex */
+   ctx->Const.QuadsFollowProvokingVertexConvention = GL_TRUE;
+
    /* sanity checks */
    ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
                                              ctx->Const.MaxTextureCoordUnits));
@@ -900,6 +605,10 @@ _mesa_init_constants(GLcontext *ctx)
    ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
    ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
    ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
+
+   /* check that we don't exceed various 32-bit bitfields */
+   ASSERT(VERT_RESULT_MAX <= 32);
+   ASSERT(FRAG_ATTRIB_MAX <= 32);
 }
 
 
@@ -918,13 +627,21 @@ check_context_limits(GLcontext *ctx)
    assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
    assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
 
-   assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
-   assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
+   /* number of coord units cannot be greater than number of image units */
+   assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits);
+
+   assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
+   assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
+   assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
+   assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE);
 
    /* make sure largest texture image is <= MAX_WIDTH in size */
-   assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH);
-   assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH);
-   assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH);
+   assert((1 << (ctx->Const.MaxTextureLevels - 1)) <= MAX_WIDTH);
+   assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= MAX_WIDTH);
+   assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= MAX_WIDTH);
+
+   assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
+   assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
 
    assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
 
@@ -952,19 +669,36 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_extensions( ctx );
 
    /* Attribute Groups */
+#if FEATURE_accum
    _mesa_init_accum( ctx );
+#endif
+#if FEATURE_attrib_stack
    _mesa_init_attrib( ctx );
+#endif
    _mesa_init_buffer_objects( ctx );
    _mesa_init_color( ctx );
+#if FEATURE_colortable
    _mesa_init_colortables( ctx );
+#endif
    _mesa_init_current( ctx );
    _mesa_init_depth( ctx );
    _mesa_init_debug( ctx );
+#if FEATURE_dlist
    _mesa_init_display_list( ctx );
+#endif
+#if FEATURE_evaluators
    _mesa_init_eval( ctx );
+#endif
+   _mesa_init_fbobjects( ctx );
+#if FEATURE_feedback
    _mesa_init_feedback( ctx );
+#else
+   ctx->RenderMode = GL_RENDER;
+#endif
    _mesa_init_fog( ctx );
+#if FEATURE_histogram
    _mesa_init_histogram( ctx );
+#endif
    _mesa_init_hint( ctx );
    _mesa_init_line( ctx );
    _mesa_init_lighting( ctx );
@@ -975,8 +709,12 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_point( ctx );
    _mesa_init_polygon( ctx );
    _mesa_init_program( ctx );
+#if FEATURE_ARB_occlusion_query
    _mesa_init_query( ctx );
+#endif
+#if FEATURE_drawpix
    _mesa_init_rastpos( ctx );
+#endif
    _mesa_init_scissor( ctx );
    _mesa_init_shader_state( ctx );
    _mesa_init_stencil( ctx );
@@ -987,13 +725,39 @@ init_attrib_groups(GLcontext *ctx)
    if (!_mesa_init_texture( ctx ))
       return GL_FALSE;
 
+#if FEATURE_texture_s3tc
    _mesa_init_texture_s3tc( ctx );
+#endif
+#if FEATURE_texture_fxt1
    _mesa_init_texture_fxt1( ctx );
+#endif
 
    /* Miscellaneous */
    ctx->NewState = _NEW_ALL;
    ctx->ErrorValue = (GLenum) GL_NO_ERROR;
-   ctx->_Facing = 0;
+   ctx->varying_vp_inputs = ~0;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Update default objects in a GL context with respect to shared state.
+ *
+ * \param ctx GL context.
+ *
+ * Removes references to old default objects, (texture objects, program
+ * objects, etc.) and changes to reference those from the current shared
+ * state.
+ */
+static GLboolean
+update_default_objects(GLcontext *ctx)
+{
+   assert(ctx);
+
+   _mesa_update_default_objects_program(ctx);
+   _mesa_update_default_objects_texture(ctx);
+   _mesa_update_default_objects_buffer_objects(ctx);
 
    return GL_TRUE;
 }
@@ -1071,6 +835,8 @@ _mesa_initialize_context(GLcontext *ctx,
                          const struct dd_function_table *driverFunctions,
                          void *driverContext)
 {
+   struct gl_shared_state *shared;
+
    /*ASSERT(driverContext);*/
    assert(driverFunctions->NewTextureObject);
    assert(driverFunctions->FreeTexImageData);
@@ -1094,20 +860,22 @@ _mesa_initialize_context(GLcontext *ctx,
 
    if (share_list) {
       /* share state with another context */
-      ctx->Shared = share_list->Shared;
+      shared = share_list->Shared;
    }
    else {
       /* allocate new, unshared state */
-      if (!alloc_shared_state( ctx )) {
+      shared = _mesa_alloc_shared_state(ctx);
+      if (!shared)
          return GL_FALSE;
-      }
    }
-   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
-   ctx->Shared->RefCount++;
-   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+   _glthread_LOCK_MUTEX(shared->Mutex);
+   ctx->Shared = shared;
+   shared->RefCount++;
+   _glthread_UNLOCK_MUTEX(shared->Mutex);
 
    if (!init_attrib_groups( ctx )) {
-      free_shared_state(ctx, ctx->Shared);
+      _mesa_free_shared_state(ctx, ctx->Shared);
       return GL_FALSE;
    }
 
@@ -1115,24 +883,25 @@ _mesa_initialize_context(GLcontext *ctx,
    ctx->Exec = alloc_dispatch_table();
    ctx->Save = alloc_dispatch_table();
    if (!ctx->Exec || !ctx->Save) {
-      free_shared_state(ctx, ctx->Shared);
+      _mesa_free_shared_state(ctx, ctx->Shared);
       if (ctx->Exec)
          _mesa_free(ctx->Exec);
    }
+#if FEATURE_dispatch
    _mesa_init_exec_table(ctx->Exec);
+#endif
    ctx->CurrentDispatch = ctx->Exec;
-#if _HAVE_FULL_GL
+#if FEATURE_dlist
    _mesa_init_dlist_table(ctx->Save);
    _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
+#endif
    /* Neutral tnl module stuff */
    _mesa_init_exec_vtxfmt( ctx ); 
    ctx->TnlModule.Current = NULL;
    ctx->TnlModule.SwapCount = 0;
-#endif
 
    ctx->FragmentProgram._MaintainTexEnvProgram
       = (_mesa_getenv("MESA_TEX_PROG") != NULL);
-   ctx->FragmentProgram._UseTexEnvProgram = ctx->FragmentProgram._MaintainTexEnvProgram;
 
    ctx->VertexProgram._MaintainTnlProgram
       = (_mesa_getenv("MESA_TNL_PROG") != NULL);
@@ -1141,6 +910,10 @@ _mesa_initialize_context(GLcontext *ctx,
       ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
    }
 
+#ifdef FEATURE_extra_context_init
+   _mesa_initialize_context_extra(ctx);
+#endif
+
    ctx->FirstTimeCurrent = GL_TRUE;
 
    return GL_TRUE;
@@ -1157,7 +930,7 @@ _mesa_initialize_context(GLcontext *ctx,
  * \param share_list another context to share display lists with or NULL
  * \param driverFunctions points to the dd_function_table into which the
  *        driver has plugged in all its special functions.
- * \param driverCtx points to the device driver's private context state
+ * \param driverContext points to the device driver's private context state
  * 
  * \return pointer to a new __GLcontextRec or NULL if error.
  */
@@ -1197,18 +970,21 @@ _mesa_create_context(const GLvisual *visual,
 void
 _mesa_free_context_data( GLcontext *ctx )
 {
-   /* if we're destroying the current context, unbind it first */
-   if (ctx == _mesa_get_current_context()) {
-      _mesa_make_current(NULL, NULL, NULL);
-   }
-   else {
-      /* unreference WinSysDraw/Read buffers */
-      _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
-      _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
-      _mesa_unreference_framebuffer(&ctx->DrawBuffer);
-      _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+   GLint RefCount;
+
+   if (!_mesa_get_current_context()){
+      /* No current context, but we may need one in order to delete
+       * texture objs, etc.  So temporarily bind the context now.
+       */
+      _mesa_make_current(ctx, NULL, NULL);
    }
 
+   /* unreference WinSysDraw/Read buffers */
+   _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
+   _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
+   _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
+   _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);
+
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
    _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
@@ -1217,20 +993,36 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
 
+#if FEATURE_attrib_stack
+   _mesa_free_attrib_data(ctx);
+#endif
    _mesa_free_lighting_data( ctx );
+#if FEATURE_evaluators
    _mesa_free_eval_data( ctx );
+#endif
    _mesa_free_texture_data( ctx );
    _mesa_free_matrix_data( ctx );
    _mesa_free_viewport_data( ctx );
+#if FEATURE_colortable
    _mesa_free_colortables_data( ctx );
+#endif
    _mesa_free_program_data(ctx);
    _mesa_free_shader_state(ctx);
+#if FEATURE_ARB_occlusion_query
    _mesa_free_query_data(ctx);
+#endif
+
+   _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
+
+#if FEATURE_ARB_pixel_buffer_object
+   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
+   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
+#endif
 
 #if FEATURE_ARB_vertex_buffer_object
-   _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
+   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
+   _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL);
 #endif
-   _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
 
    /* free dispatch tables */
    _mesa_free(ctx->Exec);
@@ -1238,16 +1030,21 @@ _mesa_free_context_data( GLcontext *ctx )
 
    /* Shared context state (display lists, textures, etc) */
    _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
-   ctx->Shared->RefCount--;
-   assert(ctx->Shared->RefCount >= 0);
+   RefCount = --ctx->Shared->RefCount;
    _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
-   if (ctx->Shared->RefCount == 0) {
+   assert(RefCount >= 0);
+   if (RefCount == 0) {
       /* free shared state */
-      free_shared_state( ctx, ctx->Shared );
+      _mesa_free_shared_state( ctx, ctx->Shared );
    }
 
    if (ctx->Extensions.String)
       _mesa_free((void *) ctx->Extensions.String);
+
+   /* unbind the context if it's currently bound */
+   if (ctx == _mesa_get_current_context()) {
+      _mesa_make_current(NULL, NULL, NULL);
+   }
 }
 
 
@@ -1475,12 +1272,10 @@ initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
  * \param drawBuffer  the drawing framebuffer
  * \param readBuffer  the reading framebuffer
  */
-void
+GLboolean
 _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
                     GLframebuffer *readBuffer )
 {
-   GET_CURRENT_CONTEXT(oldCtx);
-
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(newCtx, "_mesa_make_current()\n");
 
@@ -1490,14 +1285,14 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
       if (!check_compatible(newCtx, drawBuffer)) {
          _mesa_warning(newCtx,
               "MakeCurrent: incompatible visuals for context and drawbuffer");
-         return;
+         return GL_FALSE;
       }
    }
    if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
       if (!check_compatible(newCtx, readBuffer)) {
          _mesa_warning(newCtx,
               "MakeCurrent: incompatible visuals for context and readbuffer");
-         return;
+         return GL_FALSE;
       }
    }
 
@@ -1505,13 +1300,6 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
    _glapi_set_context((void *) newCtx);
    ASSERT(_mesa_get_current_context() == newCtx);
 
-   if (oldCtx) {
-      _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer);
-      _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer);
-      _mesa_unreference_framebuffer(&oldCtx->DrawBuffer);
-      _mesa_unreference_framebuffer(&oldCtx->ReadBuffer);
-   }
-         
    if (!newCtx) {
       _glapi_set_dispatch(NULL);  /* none current */
    }
@@ -1531,10 +1319,12 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
           * or not bound to a user-created FBO.
           */
          if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
-         /* fix up the fb fields - these will end up wrong otherwise
-          * if the DRIdrawable changes, and everything relies on them.
-          * This is a bit messy (same as needed in _mesa_BindFramebufferEXT)
-         */
+            /* KW: merge conflict here, revisit. 
+             */
+            /* fix up the fb fields - these will end up wrong otherwise
+             * if the DRIdrawable changes, and everything relies on them.
+             * This is a bit messy (same as needed in _mesa_BindFramebufferEXT)
+             */
             unsigned int i;
             GLenum buffers[MAX_DRAW_BUFFERS];
 
@@ -1548,9 +1338,11 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
          }
          if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
             _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
-            _mesa_readbuffer_update_fields(newCtx, newCtx->Pixel.ReadBuffer);
          }
 
+         /* XXX only set this flag if we're really changing the draw/read
+          * framebuffer bindings.
+          */
         newCtx->NewState |= _NEW_BUFFERS;
 
 #if 1
@@ -1605,6 +1397,8 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
         newCtx->FirstTimeCurrent = GL_FALSE;
       }
    }
+   
+   return GL_TRUE;
 }
 
 
@@ -1618,12 +1412,25 @@ GLboolean
 _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
 {
    if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
-      ctx->Shared->RefCount--;
-      if (ctx->Shared->RefCount == 0) {
-         free_shared_state(ctx, ctx->Shared);
-      }
+      struct gl_shared_state *oldSharedState = ctx->Shared;
+      GLint RefCount;
+
       ctx->Shared = ctxToShare->Shared;
+      
+      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
       ctx->Shared->RefCount++;
+      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+      update_default_objects(ctx);
+
+      _glthread_LOCK_MUTEX(oldSharedState->Mutex);
+      RefCount = --oldSharedState->RefCount;
+      _glthread_UNLOCK_MUTEX(oldSharedState->Mutex);
+
+      if (RefCount == 0) {
+         _mesa_free_shared_state(ctx, oldSharedState);
+      }
+
       return GL_TRUE;
    }
    else {
@@ -1713,6 +1520,7 @@ _mesa_Finish(void)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+   FLUSH_CURRENT( ctx, 0 );
    if (ctx->Driver.Finish) {
       ctx->Driver.Finish(ctx);
    }
@@ -1730,10 +1538,24 @@ _mesa_Flush(void)
 {
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+   FLUSH_CURRENT( ctx, 0 );
    if (ctx->Driver.Flush) {
       ctx->Driver.Flush(ctx);
    }
 }
 
 
+/**
+ * Set mvp_with_dp4 flag.  If a driver has a preference for DP4 over
+ * MUL/MAD, or vice versa, call this function to register that.
+ * Otherwise we default to MUL/MAD.
+ */
+void
+_mesa_set_mvp_with_dp4( GLcontext *ctx,
+                        GLboolean flag )
+{
+   ctx->mvp_with_dp4 = flag;
+}
+
+
 /*@}*/