Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / main / context.c
index b0f42e537eff1440d104d394f48fd753cfebda75..1625e4c50198a6da101677af6299ae89edc13684 100644 (file)
@@ -86,7 +86,6 @@
 #include "blend.h"
 #include "buffers.h"
 #include "bufferobj.h"
-#include "colortab.h"
 #include "context.h"
 #include "cpuinfo.h"
 #include "debug.h"
@@ -98,7 +97,6 @@
 #include "feedback.h"
 #include "fog.h"
 #include "framebuffer.h"
-#include "histogram.h"
 #include "hint.h"
 #include "hash.h"
 #include "light.h"
 #include "points.h"
 #include "polygon.h"
 #include "queryobj.h"
-#if FEATURE_ARB_sync
 #include "syncobj.h"
-#endif
 #include "rastpos.h"
 #include "remap.h"
 #include "scissor.h"
 #include "shared.h"
+#include "shaderobj.h"
 #include "simple_list.h"
 #include "state.h"
 #include "stencil.h"
 #include "texcompress_s3tc.h"
 #include "texstate.h"
+#include "transformfeedback.h"
 #include "mtypes.h"
 #include "varray.h"
 #include "version.h"
 #include "viewport.h"
 #include "vtxfmt.h"
-#include "glapi/glthread.h"
-#include "glapi/glapitable.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
-#include "shader/shader_api.h"
-#if FEATURE_ATI_fragment_shader
-#include "shader/atifragshader.h"
-#endif
+#include "program/program.h"
+#include "program/prog_print.h"
 #if _HAVE_FULL_GL
 #include "math/m_matrix.h"
 #endif
 #include "sparc/sparc.h"
 #endif
 
+#include "glsl_parser_extras.h"
+#include <stdbool.h>
+
+
 #ifndef MESA_VERBOSE
 int MESA_VERBOSE = 0;
 #endif
@@ -167,7 +163,7 @@ GLfloat _mesa_ubyte_to_float_color_tab[256];
  * We have to finish any pending rendering.
  */
 void
-_mesa_notifySwapBuffers(__GLcontext *ctx)
+_mesa_notifySwapBuffers(struct gl_context *ctx)
 {
    if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS)
       _mesa_debug(ctx, "SwapBuffers\n");
@@ -184,10 +180,9 @@ _mesa_notifySwapBuffers(__GLcontext *ctx)
 /*@{*/
 
 /**
- * Allocates a GLvisual structure and initializes it via
+ * Allocates a struct gl_config structure and initializes it via
  * _mesa_initialize_visual().
  * 
- * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
  * \param dbFlag double buffering
  * \param stereoFlag stereo buffer
  * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
@@ -203,20 +198,18 @@ _mesa_notifySwapBuffers(__GLcontext *ctx)
  * \param alphaBits same as above.
  * \param numSamples not really used.
  * 
- * \return pointer to new GLvisual or NULL if requested parameters can't be
+ * \return pointer to new struct gl_config or NULL if requested parameters can't be
  * met.
  *
  * \note Need to add params for level and numAuxBuffers (at least)
  */
-GLvisual *
-_mesa_create_visual( GLboolean rgbFlag,
-                     GLboolean dbFlag,
+struct gl_config *
+_mesa_create_visual( GLboolean dbFlag,
                      GLboolean stereoFlag,
                      GLint redBits,
                      GLint greenBits,
                      GLint blueBits,
                      GLint alphaBits,
-                     GLint indexBits,
                      GLint depthBits,
                      GLint stencilBits,
                      GLint accumRedBits,
@@ -225,15 +218,15 @@ _mesa_create_visual( GLboolean rgbFlag,
                      GLint accumAlphaBits,
                      GLint numSamples )
 {
-   GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual));
+   struct gl_config *vis = (struct gl_config *) calloc(1, sizeof(struct gl_config));
    if (vis) {
-      if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
+      if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag,
                                    redBits, greenBits, blueBits, alphaBits,
-                                   indexBits, depthBits, stencilBits,
+                                   depthBits, stencilBits,
                                    accumRedBits, accumGreenBits,
                                    accumBlueBits, accumAlphaBits,
                                    numSamples)) {
-         _mesa_free(vis);
+         free(vis);
          return NULL;
       }
    }
@@ -242,23 +235,21 @@ _mesa_create_visual( GLboolean rgbFlag,
 
 /**
  * Makes some sanity checks and fills in the fields of the
- * GLvisual object with the given parameters.  If the caller needs
- * to set additional fields, he should just probably init the whole GLvisual
+ * struct gl_config object with the given parameters.  If the caller needs
+ * to set additional fields, he should just probably init the whole struct gl_config
  * object himself.
  * \return GL_TRUE on success, or GL_FALSE on failure.
  *
  * \sa _mesa_create_visual() above for the parameter description.
  */
 GLboolean
-_mesa_initialize_visual( GLvisual *vis,
-                         GLboolean rgbFlag,
+_mesa_initialize_visual( struct gl_config *vis,
                          GLboolean dbFlag,
                          GLboolean stereoFlag,
                          GLint redBits,
                          GLint greenBits,
                          GLint blueBits,
                          GLint alphaBits,
-                         GLint indexBits,
                          GLint depthBits,
                          GLint stencilBits,
                          GLint accumRedBits,
@@ -280,7 +271,7 @@ _mesa_initialize_visual( GLvisual *vis,
    assert(accumBlueBits >= 0);
    assert(accumAlphaBits >= 0);
 
-   vis->rgbMode          = rgbFlag;
+   vis->rgbMode          = GL_TRUE;
    vis->doubleBufferMode = dbFlag;
    vis->stereoMode       = stereoFlag;
 
@@ -290,7 +281,7 @@ _mesa_initialize_visual( GLvisual *vis,
    vis->alphaBits        = alphaBits;
    vis->rgbBits          = redBits + greenBits + blueBits;
 
-   vis->indexBits      = indexBits;
+   vis->indexBits      = 0;
    vis->depthBits      = depthBits;
    vis->stencilBits    = stencilBits;
 
@@ -305,7 +296,6 @@ _mesa_initialize_visual( GLvisual *vis,
 
    vis->numAuxBuffers = 0;
    vis->level = 0;
-   vis->pixmapMode = 0;
    vis->sampleBuffers = numSamples > 0 ? 1 : 0;
    vis->samples = numSamples;
 
@@ -321,9 +311,9 @@ _mesa_initialize_visual( GLvisual *vis,
  * Frees the visual structure.
  */
 void
-_mesa_destroy_visual( GLvisual *vis )
+_mesa_destroy_visual( struct gl_config *vis )
 {
-   _mesa_free(vis);
+   free(vis);
 }
 
 /*@}*/
@@ -348,23 +338,25 @@ _mesa_destroy_visual( GLvisual *vis )
 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;
+   gl_buffer_index bi = BUFFER_FRONT_LEFT;
+   gl_face_index fi = FACE_POS_X;
+   gl_frag_attrib fa = FRAG_ATTRIB_WPOS;
+   gl_frag_result fr = FRAG_RESULT_DEPTH;
+   gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
+   gl_vert_attrib va = VERT_ATTRIB_POS;
+   gl_vert_result vr = VERT_RESULT_HPOS;
+   gl_geom_attrib ga = GEOM_ATTRIB_POSITION;
+   gl_geom_result gr = GEOM_RESULT_POS;
 
    (void) bi;
-   (void) ci;
    (void) fi;
    (void) fa;
    (void) fr;
    (void) ti;
    (void) va;
    (void) vr;
+   (void) ga;
+   (void) gr;
 }
 
 
@@ -385,7 +377,7 @@ _glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
  * \sa _math_init().
  */
 static void
-one_time_init( GLcontext *ctx )
+one_time_init( struct gl_context *ctx )
 {
    static GLboolean alreadyCalled = GL_FALSE;
    (void) ctx;
@@ -403,9 +395,28 @@ one_time_init( GLcontext *ctx )
 
       _mesa_get_cpu_features();
 
-      _mesa_init_remap_table();
+      switch (ctx->API) {
+#if FEATURE_GL
+      case API_OPENGL:
+        _mesa_init_remap_table();
+        break;
+#endif
+#if FEATURE_ES1
+      case API_OPENGLES:
+        _mesa_init_remap_table_es1();
+        break;
+#endif
+#if FEATURE_ES2
+      case API_OPENGLES2:
+        _mesa_init_remap_table_es2();
+        break;
+#endif
+      default:
+        break;
+      }
 
       _mesa_init_sqrt_table();
+      _mesa_init_get_hash(ctx);
 
       for (i = 0; i < 256; i++) {
          _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
@@ -420,6 +431,11 @@ one_time_init( GLcontext *ctx )
    }
    _glthread_UNLOCK_MUTEX(OneTimeLock);
 
+   /* Hopefully atexit() is widely available.  If not, we may need some
+    * #ifdef tests here.
+    */
+   atexit(_mesa_destroy_shader_compiler);
+
    dummy_enum_func();
 }
 
@@ -428,7 +444,7 @@ one_time_init( GLcontext *ctx )
  * Initialize fields of gl_current_attrib (aka ctx->Current.*)
  */
 static void
-_mesa_init_current(GLcontext *ctx)
+_mesa_init_current(struct gl_context *ctx)
 {
    GLuint i;
 
@@ -448,7 +464,7 @@ _mesa_init_current(GLcontext *ctx)
 
 
 /**
- * Init vertex/fragment program limits.
+ * Init vertex/fragment/geometry program limits.
  * Important: drivers should override these with actual limits.
  */
 static void
@@ -463,15 +479,31 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
    prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
    prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
 
-   if (type == GL_VERTEX_PROGRAM_ARB) {
+   switch (type) {
+   case GL_VERTEX_PROGRAM_ARB:
       prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
       prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
       prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
-   }
-   else {
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
       prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
       prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
       prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
+      break;
+   case MESA_GEOMETRY_PROGRAM:
+      prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+      prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
+      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+
+      prog->MaxGeometryTextureImageUnits = MAX_GEOMETRY_TEXTURE_IMAGE_UNITS;
+      prog->MaxGeometryVaryingComponents = MAX_GEOMETRY_VARYING_COMPONENTS;
+      prog->MaxVertexVaryingComponents = MAX_VERTEX_VARYING_COMPONENTS;
+      prog->MaxGeometryUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS;
+      prog->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
+      prog->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
+      break;
+   default:
+      assert(0 && "Bad program type in init_program_limits()");
    }
 
    /* Set the native limits to zero.  This implies that there is no native
@@ -494,16 +526,10 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
  * some of these values (such as number of texture units).
  */
 static void 
-_mesa_init_constants(GLcontext *ctx)
+_mesa_init_constants(struct gl_context *ctx)
 {
    assert(ctx);
 
-   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
-   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
-
-   /* 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;
    ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
@@ -529,8 +555,6 @@ _mesa_init_constants(GLcontext *ctx)
    ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
    ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
    ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
-   ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
-   ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
    ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
    ctx->Const.MaxLights = MAX_LIGHTS;
    ctx->Const.MaxShininess = 128.0;
@@ -542,6 +566,9 @@ _mesa_init_constants(GLcontext *ctx)
 #endif
 #if FEATURE_ARB_fragment_program
    init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram);
+#endif
+#if FEATURE_ARB_geometry_shader4
+   init_program_limits(MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram);
 #endif
    ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
    ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
@@ -563,6 +590,21 @@ _mesa_init_constants(GLcontext *ctx)
    ctx->Const.MaxVarying = MAX_VARYING;
 #endif
 
+   /* Shading language version */
+   if (ctx->API == API_OPENGL) {
+#if FEATURE_ARB_shading_language_120
+      ctx->Const.GLSLVersion = 120;
+#else
+      ctx->Const.GLSLVersion = 110;
+#endif
+   }
+   else if (ctx->API == API_OPENGLES2) {
+      ctx->Const.GLSLVersion = 100;
+   }
+   else if (ctx->API == API_OPENGLES) {
+      ctx->Const.GLSLVersion = 0; /* GLSL not supported */
+   }
+
    /* GL_ARB_framebuffer_object */
    ctx->Const.MaxSamples = 0;
 
@@ -575,22 +617,13 @@ _mesa_init_constants(GLcontext *ctx)
    /* GL_EXT_provoking_vertex */
    ctx->Const.QuadsFollowProvokingVertexConvention = GL_TRUE;
 
-   /* sanity checks */
-   ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
-                                             ctx->Const.MaxTextureCoordUnits));
-   ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
-   ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
-
-   ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
-   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);
+   /* GL_EXT_transform_feedback */
+   ctx->Const.MaxTransformFeedbackSeparateAttribs = MAX_FEEDBACK_ATTRIBS;
+   ctx->Const.MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
+   ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
 
-   /* check that we don't exceed the size of various bitfields */
-   ASSERT(VERT_RESULT_MAX <=
-         (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
-   ASSERT(FRAG_ATTRIB_MAX <=
-         (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
+   /* GL 3.2: hard-coded for now: */
+   ctx->Const.ProfileMask = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
 }
 
 
@@ -599,19 +632,43 @@ _mesa_init_constants(GLcontext *ctx)
  * Only called the first time a context is bound.
  */
 static void
-check_context_limits(GLcontext *ctx)
+check_context_limits(struct gl_context *ctx)
 {
-   /* Many context limits/constants are limited by the size of
-    * internal arrays.
-    */
+   /* check that we don't exceed the size of various bitfields */
+   assert(VERT_RESULT_MAX <=
+         (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
+   assert(FRAG_ATTRIB_MAX <=
+         (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
+
+   assert(MAX_COMBINED_TEXTURE_IMAGE_UNITS <= 8 * sizeof(GLbitfield));
+
+   /* shader-related checks */
+   assert(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+   assert(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+
+   assert(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
+   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);
+
+   /* Texture unit checks */
+   assert(ctx->Const.MaxTextureImageUnits > 0);
    assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
+   assert(ctx->Const.MaxTextureCoordUnits > 0);
    assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
+   assert(ctx->Const.MaxTextureUnits > 0);
    assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
    assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
-
+   assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
+                                             ctx->Const.MaxTextureCoordUnits));
+   assert(ctx->Const.MaxCombinedTextureImageUnits > 0);
+   assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+   assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS);
    /* number of coord units cannot be greater than number of image units */
    assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits);
 
+
+   /* Texture size checks */
    assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS);
    assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS);
    assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS);
@@ -622,11 +679,21 @@ check_context_limits(GLcontext *ctx)
    assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= MAX_WIDTH);
    assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= MAX_WIDTH);
 
+   /* Texture level checks */
+   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
+   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
+
+   /* Max texture size should be <= max viewport size (render to texture) */
+   assert((1 << (MAX_TEXTURE_LEVELS - 1)) <= MAX_WIDTH);
+
    assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
    assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
 
    assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
 
+   /* if this fails, add more enum values to gl_buffer_index */
+   assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT);
+
    /* XXX probably add more tests */
 }
 
@@ -640,7 +707,7 @@ check_context_limits(GLcontext *ctx)
  * functions for the more complex data structures.
  */
 static GLboolean
-init_attrib_groups(GLcontext *ctx)
+init_attrib_groups(struct gl_context *ctx)
 {
    assert(ctx);
 
@@ -655,7 +722,6 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_attrib( ctx );
    _mesa_init_buffer_objects( ctx );
    _mesa_init_color( ctx );
-   _mesa_init_colortables( ctx );
    _mesa_init_current( ctx );
    _mesa_init_depth( ctx );
    _mesa_init_debug( ctx );
@@ -664,7 +730,6 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_fbobjects( ctx );
    _mesa_init_feedback( ctx );
    _mesa_init_fog( ctx );
-   _mesa_init_histogram( ctx );
    _mesa_init_hint( ctx );
    _mesa_init_line( ctx );
    _mesa_init_lighting( ctx );
@@ -676,14 +741,13 @@ init_attrib_groups(GLcontext *ctx)
    _mesa_init_polygon( ctx );
    _mesa_init_program( ctx );
    _mesa_init_queryobj( ctx );
-#if FEATURE_ARB_sync
    _mesa_init_sync( ctx );
-#endif
    _mesa_init_rastpos( ctx );
    _mesa_init_scissor( ctx );
    _mesa_init_shader_state( ctx );
    _mesa_init_stencil( ctx );
    _mesa_init_transform( ctx );
+   _mesa_init_transform_feedback( ctx );
    _mesa_init_varray( ctx );
    _mesa_init_viewport( ctx );
 
@@ -711,7 +775,7 @@ init_attrib_groups(GLcontext *ctx)
  * state.
  */
 static GLboolean
-update_default_objects(GLcontext *ctx)
+update_default_objects(struct gl_context *ctx)
 {
    assert(ctx);
 
@@ -739,8 +803,8 @@ generic_nop(void)
 /**
  * Allocate and initialize a new dispatch table.
  */
-static struct _glapi_table *
-alloc_dispatch_table(void)
+struct _glapi_table *
+_mesa_alloc_dispatch_table(int size)
 {
    /* 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
@@ -748,9 +812,9 @@ alloc_dispatch_table(void)
     * DRI drivers.
     */
    GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
-                           sizeof(struct _glapi_table) / sizeof(_glapi_proc));
+                           size / sizeof(_glapi_proc));
    struct _glapi_table *table =
-      (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
+      (struct _glapi_table *) malloc(numEntries * sizeof(_glapi_proc));
    if (table) {
       _glapi_proc *entry = (_glapi_proc *) table;
       GLint i;
@@ -763,7 +827,7 @@ alloc_dispatch_table(void)
 
 
 /**
- * Initialize a GLcontext struct (rendering context).
+ * Initialize a struct gl_context struct (rendering context).
  *
  * This includes allocating all the other structs and arrays which hang off of
  * the context by pointers.
@@ -781,6 +845,7 @@ alloc_dispatch_table(void)
  * for debug flags.
  *
  * \param ctx the context to initialize
+ * \param api the GL API type to create the context for
  * \param visual describes the visual attributes for this context
  * \param share_list points to context to share textures, display lists,
  *        etc with, or NULL
@@ -789,27 +854,30 @@ alloc_dispatch_table(void)
  * \param driverContext pointer to driver-specific context data
  */
 GLboolean
-_mesa_initialize_context(GLcontext *ctx,
-                         const GLvisual *visual,
-                         GLcontext *share_list,
-                         const struct dd_function_table *driverFunctions,
-                         void *driverContext)
+_mesa_initialize_context_for_api(struct gl_context *ctx,
+                                gl_api api,
+                                const struct gl_config *visual,
+                                struct gl_context *share_list,
+                                const struct dd_function_table *driverFunctions,
+                                void *driverContext)
 {
    struct gl_shared_state *shared;
+   int i;
 
    /*ASSERT(driverContext);*/
    assert(driverFunctions->NewTextureObject);
    assert(driverFunctions->FreeTexImageData);
 
-   /* misc one-time initializations */
-   one_time_init(ctx);
-
+   ctx->API = api;
    ctx->Visual = *visual;
    ctx->DrawBuffer = NULL;
    ctx->ReadBuffer = NULL;
    ctx->WinSysDrawBuffer = NULL;
    ctx->WinSysReadBuffer = NULL;
 
+   /* misc one-time initializations */
+   one_time_init(ctx);
+
    /* Plug in driver functions and context pointer here.
     * This is important because when we call alloc_shared_state() below
     * we'll call ctx->Driver.NewTextureObject() to create the default
@@ -835,34 +903,40 @@ _mesa_initialize_context(GLcontext *ctx,
    _glthread_UNLOCK_MUTEX(shared->Mutex);
 
    if (!init_attrib_groups( ctx )) {
-      _mesa_free_shared_state(ctx, ctx->Shared);
+      _mesa_release_shared_state(ctx, ctx->Shared);
       return GL_FALSE;
    }
 
+#if FEATURE_dispatch
    /* setup the API dispatch tables */
-   ctx->Exec = alloc_dispatch_table();
-   ctx->Save = alloc_dispatch_table();
-   if (!ctx->Exec || !ctx->Save) {
-      _mesa_free_shared_state(ctx, ctx->Shared);
-      if (ctx->Exec)
-         _mesa_free(ctx->Exec);
+   switch (ctx->API) {
+#if FEATURE_GL
+   case API_OPENGL:
+      ctx->Exec = _mesa_create_exec_table();
+      break;
+#endif
+#if FEATURE_ES1
+   case API_OPENGLES:
+      ctx->Exec = _mesa_create_exec_table_es1();
+      break;
+#endif
+#if FEATURE_ES2
+   case API_OPENGLES2:
+      ctx->Exec = _mesa_create_exec_table_es2();
+      break;
+#endif
+   default:
+      _mesa_problem(ctx, "unknown or unsupported API");
+      break;
+   }
+
+   if (!ctx->Exec) {
+      _mesa_release_shared_state(ctx, ctx->Shared);
       return GL_FALSE;
    }
-#if FEATURE_dispatch
-   _mesa_init_exec_table(ctx->Exec);
 #endif
    ctx->CurrentDispatch = ctx->Exec;
 
-#if FEATURE_dlist
-   _mesa_init_save_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;
-
    ctx->FragmentProgram._MaintainTexEnvProgram
       = (_mesa_getenv("MESA_TEX_PROG") != NULL);
 
@@ -873,68 +947,124 @@ _mesa_initialize_context(GLcontext *ctx,
       ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
    }
 
-#ifdef FEATURE_extra_context_init
-   _mesa_initialize_context_extra(ctx);
+   switch (ctx->API) {
+   case API_OPENGL:
+#if FEATURE_dlist
+      ctx->Save = _mesa_create_save_table();
+      if (!ctx->Save) {
+        _mesa_release_shared_state(ctx, ctx->Shared);
+        free(ctx->Exec);
+        return GL_FALSE;
+      }
+
+      _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
 #endif
+      break;
+   case API_OPENGLES:
+      /**
+       * GL_OES_texture_cube_map says
+       * "Initially all texture generation modes are set to REFLECTION_MAP_OES"
+       */
+      for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+        texUnit->GenS.Mode = GL_REFLECTION_MAP_NV;
+        texUnit->GenT.Mode = GL_REFLECTION_MAP_NV;
+        texUnit->GenR.Mode = GL_REFLECTION_MAP_NV;
+        texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV;
+        texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV;
+        texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV;
+      }
+      break;
+   case API_OPENGLES2:
+      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+      ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
+      ctx->Point.PointSprite = GL_TRUE;  /* always on for ES 2.x */
+      break;
+   }
 
    ctx->FirstTimeCurrent = GL_TRUE;
 
    return GL_TRUE;
 }
 
+GLboolean
+_mesa_initialize_context(struct gl_context *ctx,
+                         const struct gl_config *visual,
+                         struct gl_context *share_list,
+                         const struct dd_function_table *driverFunctions,
+                         void *driverContext)
+{
+   return _mesa_initialize_context_for_api(ctx,
+                                          API_OPENGL,
+                                          visual,
+                                          share_list,
+                                          driverFunctions,
+                                          driverContext);
+}
 
 /**
- * Allocate and initialize a GLcontext structure.
+ * Allocate and initialize a struct gl_context structure.
  * Note that the driver needs to pass in its dd_function_table here since
  * we need to at least call driverFunctions->NewTextureObject to initialize
  * the rendering context.
  *
- * \param visual a GLvisual pointer (we copy the struct contents)
+ * \param api the GL API type to create the context for
+ * \param visual a struct gl_config pointer (we copy the struct contents)
  * \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 driverContext points to the device driver's private context state
  * 
- * \return pointer to a new __GLcontextRec or NULL if error.
+ * \return pointer to a new __struct gl_contextRec or NULL if error.
  */
-GLcontext *
-_mesa_create_context(const GLvisual *visual,
-                     GLcontext *share_list,
-                     const struct dd_function_table *driverFunctions,
-                     void *driverContext)
+struct gl_context *
+_mesa_create_context_for_api(gl_api api,
+                            const struct gl_config *visual,
+                            struct gl_context *share_list,
+                            const struct dd_function_table *driverFunctions,
+                            void *driverContext)
 {
-   GLcontext *ctx;
+   struct gl_context *ctx;
 
    ASSERT(visual);
    /*ASSERT(driverContext);*/
 
-   ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
+   ctx = (struct gl_context *) calloc(1, sizeof(struct gl_context));
    if (!ctx)
       return NULL;
 
-   if (_mesa_initialize_context(ctx, visual, share_list,
-                                driverFunctions, driverContext)) {
+   if (_mesa_initialize_context_for_api(ctx, api, visual, share_list,
+                                       driverFunctions, driverContext)) {
       return ctx;
    }
    else {
-      _mesa_free(ctx);
+      free(ctx);
       return NULL;
    }
 }
 
+struct gl_context *
+_mesa_create_context(const struct gl_config *visual,
+                    struct gl_context *share_list,
+                    const struct dd_function_table *driverFunctions,
+                    void *driverContext)
+{
+   return _mesa_create_context_for_api(API_OPENGL, visual,
+                                      share_list,
+                                      driverFunctions,
+                                      driverContext);
+}
 
 /**
  * Free the data associated with the given context.
  * 
- * But doesn't free the GLcontext struct itself.
+ * But doesn't free the struct gl_context struct itself.
  *
  * \sa _mesa_initialize_context() and init_attrib_groups().
  */
 void
-_mesa_free_context_data( GLcontext *ctx )
+_mesa_free_context_data( struct gl_context *ctx )
 {
-   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.
@@ -957,25 +1087,25 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
 
    _mesa_free_attrib_data(ctx);
+   _mesa_free_buffer_objects(ctx);
    _mesa_free_lighting_data( ctx );
    _mesa_free_eval_data( ctx );
    _mesa_free_texture_data( ctx );
    _mesa_free_matrix_data( ctx );
    _mesa_free_viewport_data( ctx );
-   _mesa_free_colortables_data( ctx );
    _mesa_free_program_data(ctx);
    _mesa_free_shader_state(ctx);
    _mesa_free_queryobj_data(ctx);
-#if FEATURE_ARB_sync
    _mesa_free_sync_data(ctx);
-#endif
    _mesa_free_varray_data(ctx);
+   _mesa_free_transform_feedback(ctx);
 
    _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);
+   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL);
 #endif
 
 #if FEATURE_ARB_vertex_buffer_object
@@ -984,27 +1114,20 @@ _mesa_free_context_data( GLcontext *ctx )
 #endif
 
    /* free dispatch tables */
-   _mesa_free(ctx->Exec);
-   _mesa_free(ctx->Save);
+   free(ctx->Exec);
+   free(ctx->Save);
 
    /* Shared context state (display lists, textures, etc) */
-   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
-   RefCount = --ctx->Shared->RefCount;
-   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
-   assert(RefCount >= 0);
-   if (RefCount == 0) {
-      /* free shared state */
-      _mesa_free_shared_state( ctx, ctx->Shared );
-   }
+   _mesa_release_shared_state( ctx, ctx->Shared );
 
    /* needs to be after freeing shared state */
    _mesa_free_display_list_data(ctx);
 
    if (ctx->Extensions.String)
-      _mesa_free((void *) ctx->Extensions.String);
+      free((void *) ctx->Extensions.String);
 
    if (ctx->VersionString)
-      _mesa_free(ctx->VersionString);
+      free(ctx->VersionString);
 
    /* unbind the context if it's currently bound */
    if (ctx == _mesa_get_current_context()) {
@@ -1014,18 +1137,18 @@ _mesa_free_context_data( GLcontext *ctx )
 
 
 /**
- * Destroy a GLcontext structure.
+ * Destroy a struct gl_context structure.
  *
  * \param ctx GL context.
  * 
- * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
+ * Calls _mesa_free_context_data() and frees the struct gl_context structure itself.
  */
 void
-_mesa_destroy_context( GLcontext *ctx )
+_mesa_destroy_context( struct gl_context *ctx )
 {
    if (ctx) {
       _mesa_free_context_data(ctx);
-      _mesa_free( (void *) ctx );
+      free( (void *) ctx );
    }
 }
 
@@ -1044,7 +1167,7 @@ _mesa_destroy_context( GLcontext *ctx )
  * structures.
  */
 void
-_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
+_mesa_copy_context( const struct gl_context *src, struct gl_context *dst, GLuint mask )
 {
    if (mask & GL_ACCUM_BUFFER_BIT) {
       /* OK to memcpy */
@@ -1110,7 +1233,7 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
       dst->Polygon = src->Polygon;
    }
    if (mask & GL_POLYGON_STIPPLE_BIT) {
-      /* Use loop instead of MEMCPY due to problem with Portland Group's
+      /* Use loop instead of memcpy due to problem with Portland Group's
        * C compiler.  Reported by John Stone.
        */
       GLuint i;
@@ -1163,16 +1286,17 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
  * \return GL_TRUE if compatible, GL_FALSE otherwise.
  */
 static GLboolean 
-check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
+check_compatible(const struct gl_context *ctx, const struct gl_framebuffer *buffer)
 {
-   const GLvisual *ctxvis = &ctx->Visual;
-   const GLvisual *bufvis = &buffer->Visual;
+   const struct gl_config *ctxvis = &ctx->Visual;
+   const struct gl_config *bufvis = &buffer->Visual;
 
    if (ctxvis == bufvis)
       return GL_TRUE;
 
-   if (ctxvis->rgbMode != bufvis->rgbMode)
-      return GL_FALSE;
+   if (buffer == _mesa_get_incomplete_framebuffer())
+      return GL_TRUE;
+
 #if 0
    /* disabling this fixes the fgl_glxgears pbuffer demo */
    if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
@@ -1211,7 +1335,7 @@ check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
  * Really, the device driver should totally take care of this.
  */
 static void
-initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
+initialize_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
 {
    GLuint width, height;
    if (ctx->Driver.GetBufferSize) {
@@ -1228,7 +1352,7 @@ initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
  * Initialize the size if the given width and height are non-zero.
  */
 void
-_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height)
+_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height)
 {
    if (!ctx->ViewportInitialized && width > 0 && height > 0) {
       /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
@@ -1256,8 +1380,8 @@ _mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height)
  * \param readBuffer  the reading framebuffer
  */
 GLboolean
-_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
-                    GLframebuffer *readBuffer )
+_mesa_make_current( struct gl_context *newCtx, struct gl_framebuffer *drawBuffer,
+                    struct gl_framebuffer *readBuffer )
 {
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(newCtx, "_mesa_make_current()\n");
@@ -1367,6 +1491,8 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
       if (newCtx->FirstTimeCurrent) {
          _mesa_compute_version(newCtx);
 
+         newCtx->Extensions.String = _mesa_make_extension_string(newCtx);
+
          check_context_limits(newCtx);
 
          /* We can use this to help debug user's problems.  Tell them to set
@@ -1393,11 +1519,10 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
  * be deleted if nobody else is sharing them.
  */
 GLboolean
-_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
+_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
 {
    if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
       struct gl_shared_state *oldSharedState = ctx->Shared;
-      GLint RefCount;
 
       ctx->Shared = ctxToShare->Shared;
       
@@ -1407,13 +1532,7 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
 
       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);
-      }
+      _mesa_release_shared_state(ctx, oldSharedState);
 
       return GL_TRUE;
    }
@@ -1431,10 +1550,10 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
  * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
  * context.h.
  */
-GLcontext *
+struct gl_context *
 _mesa_get_current_context( void )
 {
-   return (GLcontext *) _glapi_get_context();
+   return (struct gl_context *) _glapi_get_context();
 }
 
 
@@ -1448,10 +1567,10 @@ _mesa_get_current_context( void )
  *
  * \return pointer to dispatch_table.
  *
- * Simply returns __GLcontextRec::CurrentDispatch.
+ * Simply returns __struct gl_contextRec::CurrentDispatch.
  */
 struct _glapi_table *
-_mesa_get_dispatch(GLcontext *ctx)
+_mesa_get_dispatch(struct gl_context *ctx)
 {
    return ctx->CurrentDispatch;
 }
@@ -1477,7 +1596,7 @@ _mesa_get_dispatch(GLcontext *ctx)
  * This is called via _mesa_error().
  */
 void
-_mesa_record_error(GLcontext *ctx, GLenum error)
+_mesa_record_error(struct gl_context *ctx, GLenum error)
 {
    if (!ctx)
       return;
@@ -1497,7 +1616,7 @@ _mesa_record_error(GLcontext *ctx, GLenum error)
  * Flush commands and wait for completion.
  */
 void
-_mesa_finish(GLcontext *ctx)
+_mesa_finish(struct gl_context *ctx)
 {
    FLUSH_CURRENT( ctx, 0 );
    if (ctx->Driver.Finish) {
@@ -1510,7 +1629,7 @@ _mesa_finish(GLcontext *ctx)
  * Flush commands.
  */
 void
-_mesa_flush(GLcontext *ctx)
+_mesa_flush(struct gl_context *ctx)
 {
    FLUSH_CURRENT( ctx, 0 );
    if (ctx->Driver.Flush) {
@@ -1556,7 +1675,7 @@ _mesa_Flush(void)
  * Otherwise we default to MUL/MAD.
  */
 void
-_mesa_set_mvp_with_dp4( GLcontext *ctx,
+_mesa_set_mvp_with_dp4( struct gl_context *ctx,
                         GLboolean flag )
 {
    ctx->mvp_with_dp4 = flag;
@@ -1572,41 +1691,68 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
  * \return GL_TRUE if OK to render, GL_FALSE if not
  */
 GLboolean
-_mesa_valid_to_render(GLcontext *ctx, const char *where)
+_mesa_valid_to_render(struct gl_context *ctx, const char *where)
 {
+   bool vert_from_glsl_shader = false;
+   bool geom_from_glsl_shader = false;
+   bool frag_from_glsl_shader = false;
+
    /* This depends on having up to date derived state (shaders) */
    if (ctx->NewState)
       _mesa_update_state(ctx);
 
    if (ctx->Shader.CurrentProgram) {
+      struct gl_shader_program *const prog = ctx->Shader.CurrentProgram;
+
       /* using shaders */
-      if (!ctx->Shader.CurrentProgram->LinkStatus) {
+      if (!prog->LinkStatus) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "%s(shader not linked), where");
+                     "%s(shader not linked)", where);
          return GL_FALSE;
       }
 #if 0 /* not normally enabled */
       {
          char errMsg[100];
-         if (!_mesa_validate_shader_program(ctx, ctx->Shader.CurrentProgram,
-                                            errMsg)) {
+         if (!_mesa_validate_shader_program(ctx, prog, errMsg)) {
             _mesa_warning(ctx, "Shader program %u is invalid: %s",
-                          ctx->Shader.CurrentProgram->Name, errMsg);
+                          prog->Name, errMsg);
          }
       }
 #endif
+
+      /* Figure out which shader stages are provided by the GLSL program.  For
+       * any stages that are not provided, the corresponding assembly shader
+       * target will be validated below.
+       */
+      vert_from_glsl_shader =
+        prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL;
+      geom_from_glsl_shader =
+        prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL;
+      frag_from_glsl_shader =
+        prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL;
    }
-   else {
-      if (ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "%s(vertex program not valid)", where);
-         return GL_FALSE;
-      }
-      if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "%s(fragment program not valid)", where);
-         return GL_FALSE;
-      }
+
+
+   /* Any shader stages that are not supplied by the GLSL shader and have
+    * assembly shaders enabled must now be validated.
+    */
+   if (!vert_from_glsl_shader
+       && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                 "%s(vertex program not valid)", where);
+      return GL_FALSE;
+   }
+
+   /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
+    * FINISHME: geometry program should validated here.
+    */
+   (void) geom_from_glsl_shader;
+
+   if (!frag_from_glsl_shader
+       && ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                 "%s(fragment program not valid)", where);
+      return GL_FALSE;
    }
 
    if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {