init secondary color to (0,0,0,1). remove some redundant initializations.
[mesa.git] / src / mesa / main / context.c
index adcdce09cd3132dd6009cde3db7ae7463db8dac2..7de8115ad1c2780a3f7105723eb7b73b7f486f90 100644 (file)
@@ -6,9 +6,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
  * Selecting the <b>Main page</b> link will display a summary of the module
  * (this page).
  *
- * Selecting <b>Compound List</b> will list all C structures.
+ * Selecting <b>Data Structures</b> will list all C structures.
  *
  * Selecting the <b>File List</b> link will list all the source files in
  * the module.
  * Selecting a filename will show a list of all functions defined in that file.
  *
- * Selecting the <b>Compound Members</b> link will display a list of all
+ * Selecting the <b>Data Fields</b> link will display a list of all
  * documented structure members.
  *
- * Selecting the <b>File Members</b> link will display a list
+ * Selecting the <b>Globals</b> link will display a list
  * of all functions, structures, global variables and macros in the module.
  *
  */
@@ -77,7 +77,7 @@
 #include "attrib.h"
 #include "blend.h"
 #include "buffers.h"
-/*#include "clip.h"*/
+#include "bufferobj.h"
 #include "colortab.h"
 #include "context.h"
 #include "debug.h"
@@ -90,6 +90,7 @@
 #include "fog.h"
 #include "get.h"
 #include "glthread.h"
+#include "glapioffsets.h"
 #include "histogram.h"
 #include "hint.h"
 #include "hash.h"
 #include "lines.h"
 #include "macros.h"
 #include "matrix.h"
+#include "occlude.h"
 #include "pixel.h"
 #include "points.h"
 #include "polygon.h"
+#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
+#include "program.h"
+#endif
 #include "rastpos.h"
 #include "simple_list.h"
 #include "state.h"
 #include "texstate.h"
 #include "mtypes.h"
 #include "varray.h"
-#if FEATURE_NV_vertex_program
-#include "nvprogram.h"
-#include "nvvertprog.h"
-#endif
-#if FEATURE_NV_fragment_program
-#include "nvfragprog.h"
-#endif
 #include "vtxfmt.h"
 #if _HAVE_FULL_GL
 #include "math/m_translate.h"
 #include "math/mathmod.h"
 #endif
 
-#if defined(MESA_TRACE)
-#include "Trace/tr_context.h"
-#include "Trace/tr_wrapper.h"
-#endif
-
 #ifdef USE_SPARC_ASM
 #include "SPARC/sparc.h"
 #endif
@@ -394,7 +387,8 @@ __glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes)
        return NULL;
     }
 
-    _mesa_initialize_context(ctx, modes, NULL, imports, GL_FALSE);
+    /* XXX doesn't work at this time */
+    _mesa_initialize_context(ctx, modes, NULL, NULL, NULL);
     ctx->imports = *imports;
 
     return ctx;
@@ -833,16 +827,18 @@ alloc_shared_state( GLcontext *ctx )
 #endif
 
 #if FEATURE_ARB_vertex_program
-   ss->DefaultVertexProgram = _mesa_alloc_program(ctx, GL_VERTEX_PROGRAM_ARB, 0);
+   ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
    if (!ss->DefaultVertexProgram)
       goto cleanup;
 #endif
 #if FEATURE_ARB_fragment_program
-   ss->DefaultFragmentProgram = _mesa_alloc_program(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+   ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
    if (!ss->DefaultFragmentProgram)
       goto cleanup;
 #endif
 
+   ss->BufferObjects = _mesa_NewHashTable();
+
    ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
    if (!ss->Default1D)
       goto cleanup;
@@ -863,14 +859,6 @@ alloc_shared_state( GLcontext *ctx )
    if (!ss->DefaultRect)
       goto cleanup;
 
-#if 0
-   _mesa_save_texture_object(ctx, ss->Default1D);
-   _mesa_save_texture_object(ctx, ss->Default2D);
-   _mesa_save_texture_object(ctx, ss->Default3D);
-   _mesa_save_texture_object(ctx, ss->DefaultCubeMap);
-   _mesa_save_texture_object(ctx, ss->DefaultRect);
-#endif
-
    /* Effectively bind the default textures to all texture units */
    ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
    ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
@@ -892,12 +880,15 @@ alloc_shared_state( GLcontext *ctx )
 #endif
 #if FEATURE_ARB_vertex_program
    if (ss->DefaultVertexProgram)
-      _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+      ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
 #endif
 #if FEATURE_ARB_fragment_program
    if (ss->DefaultFragmentProgram)
-      _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+      ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
 #endif
+   if (ss->BufferObjects)
+      _mesa_DeleteHashTable(ss->BufferObjects);
+
    if (ss->Default1D)
       (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
    if (ss->Default2D)
@@ -965,7 +956,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
          struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
                                                                  prog);
          ASSERT(p);
-         _mesa_delete_program(ctx, p);
+         ctx->Driver.DeleteProgram(ctx, p);
          _mesa_HashRemove(ss->Programs, prog);
       }
       else {
@@ -975,15 +966,21 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
    _mesa_DeleteHashTable(ss->Programs);
 #endif
 
+   _mesa_DeleteHashTable(ss->BufferObjects);
+
    _glthread_DESTROY_MUTEX(ss->Mutex);
 
    FREE(ss);
 }
 
 
-static void _mesa_init_current( GLcontext *ctx )
+/**
+ * Initialize fields of gl_current_attrib (aka ctx->Current.*)
+ */
+static void
+_mesa_init_current( GLcontext *ctx )
 {
-   int i;
+   GLuint i;
 
    /* Current group */
    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
@@ -993,15 +990,19 @@ static void _mesa_init_current( GLcontext *ctx )
    ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.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, 0.0 );
+   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
    ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
-   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
-      ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], 0.0, 0.0, 0.0, 1.0);
+
    ctx->Current.Index = 1;
    ctx->Current.EdgeFlag = GL_TRUE;
 }
 
 
+/**
+ * Initialize fields of gl_constants (aka ctx->Const.*).
+ * Use defaults from config.h.  The device drivers will often override
+ * some of these values (such as number of texture units).
+ */
 static void 
 _mesa_init_constants( GLcontext *ctx )
 {
@@ -1062,9 +1063,19 @@ _mesa_init_constants( GLcontext *ctx )
    ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
    ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
 
+   /* If we're running in the X server, do bounds checking to prevent
+    * segfaults and server crashes!
+    */
+#if defined(XFree86LOADER) && defined(IN_MODULE)
+   ctx->Const.CheckArrayBounds = GL_TRUE;
+#else
+   ctx->Const.CheckArrayBounds = GL_FALSE;
+#endif
+
    ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
 }
 
+
 /**
  * Initialize the attribute groups in a GL context.
  *
@@ -1088,8 +1099,9 @@ init_attrib_groups( GLcontext *ctx )
    _mesa_init_accum( ctx );
    _mesa_init_attrib( ctx );
    _mesa_init_buffers( ctx );
+   _mesa_init_buffer_objects( ctx );
    _mesa_init_color( ctx );
-   _mesa_init_colortable( ctx );
+   _mesa_init_colortables( ctx );
    _mesa_init_current( ctx );
    _mesa_init_depth( ctx );
    _mesa_init_debug( ctx );
@@ -1102,9 +1114,11 @@ init_attrib_groups( GLcontext *ctx )
    _mesa_init_line( ctx );
    _mesa_init_lighting( ctx );
    _mesa_init_matrix( ctx );
+   _mesa_init_occlude( ctx );
    _mesa_init_pixel( ctx );
    _mesa_init_point( ctx );
    _mesa_init_polygon( ctx );
+   _mesa_init_program( ctx );
    _mesa_init_rastpos( ctx );
    _mesa_init_stencil( ctx );
    _mesa_init_transform( ctx );
@@ -1124,14 +1138,214 @@ init_attrib_groups( GLcontext *ctx )
 }
 
 
+/**
+ * If the DRI libGL.so library is old, it may not have the entrypoints for
+ * some recent OpenGL extensions.  Dynamically add them now.
+ * If we're building stand-alone Mesa where libGL.so has both the dispatcher
+ * and driver code, this won't be an issue (and calling this function won't
+ * do any harm).
+ */
+static void
+add_newer_entrypoints(void)
+{
+   unsigned   i;
+   static const struct {
+      const char * const name;
+      unsigned  offset;
+   }
+   newer_entrypoints[] = {
+      /* GL_ARB_window_pos aliases with GL_MESA_window_pos */
+      { "glWindowPos2dARB", 513 },
+      { "glWindowPos2dvARB", 514 },
+      { "glWindowPos2fARB", 515 },
+      { "glWindowPos2fvARB", 516 },
+      { "glWindowPos2iARB", 517 },
+      { "glWindowPos2ivARB", 518 },
+      { "glWindowPos2sARB", 519 },
+      { "glWindowPos2svARB", 520 },
+      { "glWindowPos3dARB", 521 },
+      { "glWindowPos3dvARB", 522 },
+      { "glWindowPos3fARB", 523 },
+      { "glWindowPos3fvARB", 524 },
+      { "glWindowPos3iARB", 525 },
+      { "glWindowPos3ivARB", 526 },
+      { "glWindowPos3sARB", 527 },
+      { "glWindowPos3svARB", 528 },
+#if FEATURE_NV_vertex_program
+      { "glAreProgramsResidentNV", 578 },
+      { "glBindProgramNV", 579 },
+      { "glDeleteProgramsNV", 580 },
+      { "glExecuteProgramNV", 581 },
+      { "glGenProgramsNV", 582 },
+      { "glGetProgramParameterdvNV", 583 },
+      { "glGetProgramParameterfvNV", 584 },
+      { "glGetProgramivNV", 585 },
+      { "glGetProgramStringNV", 586 },
+      { "glGetTrackMatrixivNV", 587 },
+      { "glGetVertexAttribdvNV", 588 },
+      { "glGetVertexAttribfvNV", 589 },
+      { "glGetVertexAttribivNV", 590 },
+      { "glGetVertexAttribPointervNV", 591 },
+      { "glIsProgramNV", 592 },
+      { "glLoadProgramNV", 593 },
+      { "glProgramParameter4dNV", 594 },
+      { "glProgramParameter4dvNV", 595 },
+      { "glProgramParameter4fNV", 596 },
+      { "glProgramParameter4fvNV", 597 },
+      { "glProgramParameters4dvNV", 598 },
+      { "glProgramParameters4fvNV", 599 },
+      { "glRequestResidentProgramsNV", 600 },
+      { "glTrackMatrixNV", 601 },
+      { "glVertexAttribPointerNV", 602 },
+      { "glVertexAttrib1dNV", 603 },
+      { "glVertexAttrib1dvNV", 604 },
+      { "glVertexAttrib1fNV", 605 },
+      { "glVertexAttrib1fvNV", 606 },
+      { "glVertexAttrib1sNV", 607 },
+      { "glVertexAttrib1svNV", 608 },
+      { "glVertexAttrib2dNV", 609 },
+      { "glVertexAttrib2dvNV", 610 },
+      { "glVertexAttrib2fNV", 611 },
+      { "glVertexAttrib2fvNV", 612 },
+      { "glVertexAttrib2sNV", 613 },
+      { "glVertexAttrib2svNV", 614 },
+      { "glVertexAttrib3dNV", 615 },
+      { "glVertexAttrib3dvNV", 616 },
+      { "glVertexAttrib3fNV", 617 },
+      { "glVertexAttrib3fvNV", 618 },
+      { "glVertexAttrib3sNV", 619 },
+      { "glVertexAttrib3svNV", 620 },
+      { "glVertexAttrib4dNV", 621 },
+      { "glVertexAttrib4dvNV", 622 },
+      { "glVertexAttrib4fNV", 623 },
+      { "glVertexAttrib4fvNV", 624 },
+      { "glVertexAttrib4sNV", 625 },
+      { "glVertexAttrib4svNV", 626 },
+      { "glVertexAttrib4ubNV", 627 },
+      { "glVertexAttrib4ubvNV", 628 },
+      { "glVertexAttribs1dvNV", 629 },
+      { "glVertexAttribs1fvNV", 630 },
+      { "glVertexAttribs1svNV", 631 },
+      { "glVertexAttribs2dvNV", 632 },
+      { "glVertexAttribs2fvNV", 633 },
+      { "glVertexAttribs2svNV", 634 },
+      { "glVertexAttribs3dvNV", 635 },
+      { "glVertexAttribs3fvNV", 636 },
+      { "glVertexAttribs3svNV", 637 },
+      { "glVertexAttribs4dvNV", 638 },
+      { "glVertexAttribs4fvNV", 639 },
+      { "glVertexAttribs4svNV", 640 },
+      { "glVertexAttribs4ubvNV", 641 },
+#endif
+      { "glPointParameteriNV", 642 },
+      { "glPointParameterivNV", 643 },
+      { "glMultiDrawArraysEXT", 644 },
+      { "glMultiDrawElementsEXT", 645 },
+      { "glMultiDrawArraysSUN", _gloffset_MultiDrawArraysEXT  },
+      { "glMultiDrawElementsSUN", _gloffset_MultiDrawElementsEXT  },
+      { "glActiveStencilFaceEXT", 646 },
+#if FEATURE_NV_fence
+      { "glDeleteFencesNV", 647 },
+      { "glGenFencesNV", 648 },
+      { "glIsFenceNV", 649 },
+      { "glTestFenceNV", 650 },
+      { "glGetFenceivNV", 651 },
+      { "glFinishFenceNV", 652 },
+      { "glSetFenceNV", 653 },
+#endif
+#if FEATURE_NV_fragment_program
+      { "glProgramNamedParameter4fNV", 682 },
+      { "glProgramNamedParameter4dNV", 683 },
+      { "glProgramNamedParameter4fvNV", 683 },
+      { "glProgramNamedParameter4dvNV", 684 },
+      { "glGetProgramNamedParameterfvNV", 685 },
+      { "glGetProgramNamedParameterdvNV", 686 },
+#endif
+#if FEATURE_ARB_vertex_program
+      { "glVertexAttrib1sARB", _gloffset_VertexAttrib1sNV },
+      { "glVertexAttrib1fARB", _gloffset_VertexAttrib1fNV },
+      { "glVertexAttrib1dARB", _gloffset_VertexAttrib1dNV },
+      { "glVertexAttrib2sARB", _gloffset_VertexAttrib2sNV },
+      { "glVertexAttrib2fARB", _gloffset_VertexAttrib2fNV },
+      { "glVertexAttrib2dARB", _gloffset_VertexAttrib2dNV },
+      { "glVertexAttrib3sARB", _gloffset_VertexAttrib3sNV },
+      { "glVertexAttrib3fARB", _gloffset_VertexAttrib3fNV },
+      { "glVertexAttrib3dARB", _gloffset_VertexAttrib3dNV },
+      { "glVertexAttrib4sARB", _gloffset_VertexAttrib4sNV },
+      { "glVertexAttrib4fARB", _gloffset_VertexAttrib4fNV },
+      { "glVertexAttrib4dARB", _gloffset_VertexAttrib4dNV },
+      { "glVertexAttrib4NubARB", _gloffset_VertexAttrib4ubNV },
+      { "glVertexAttrib1svARB", _gloffset_VertexAttrib1svNV },
+      { "glVertexAttrib1fvARB", _gloffset_VertexAttrib1fvNV },
+      { "glVertexAttrib1dvARB", _gloffset_VertexAttrib1dvNV },
+      { "glVertexAttrib2svARB", _gloffset_VertexAttrib2svNV },
+      { "glVertexAttrib2fvARB", _gloffset_VertexAttrib2fvNV },
+      { "glVertexAttrib2dvARB", _gloffset_VertexAttrib2dvNV },
+      { "glVertexAttrib3svARB", _gloffset_VertexAttrib3svNV },
+      { "glVertexAttrib3fvARB", _gloffset_VertexAttrib3fvNV },
+      { "glVertexAttrib3dvARB", _gloffset_VertexAttrib3dvNV },
+      { "glVertexAttrib4bvARB", _gloffset_VertexAttrib4bvARB },
+      { "glVertexAttrib4svARB", _gloffset_VertexAttrib4svNV },
+      { "glVertexAttrib4ivARB", _gloffset_VertexAttrib4ivARB },
+      { "glVertexAttrib4ubvARB", _gloffset_VertexAttrib4ubvARB },
+      { "glVertexAttrib4usvARB", _gloffset_VertexAttrib4usvARB },
+      { "glVertexAttrib4uivARB", _gloffset_VertexAttrib4uivARB },
+      { "glVertexAttrib4fvARB", _gloffset_VertexAttrib4fvNV },
+      { "glVertexAttrib4dvARB", _gloffset_VertexAttrib4dvNV },
+      { "glVertexAttrib4NbvARB", _gloffset_VertexAttrib4NbvARB },
+      { "glVertexAttrib4NsvARB", _gloffset_VertexAttrib4NsvARB },
+      { "glVertexAttrib4NivARB", _gloffset_VertexAttrib4NivARB },
+      { "glVertexAttrib4NubvARB", _gloffset_VertexAttrib4ubvNV },
+      { "glVertexAttrib4NusvARB", _gloffset_VertexAttrib4NusvARB },
+      { "glVertexAttrib4NuivARB", _gloffset_VertexAttrib4NuivARB },
+      { "glVertexAttribPointerARB", _gloffset_VertexAttribPointerARB },
+      { "glEnableVertexAttribArrayARB", _gloffset_EnableVertexAttribArrayARB },
+      { "glDisableVertexAttribArrayARB", _gloffset_DisableVertexAttribArrayARB },
+      { "glProgramStringARB", _gloffset_ProgramStringARB },
+      { "glBindProgramARB", _gloffset_BindProgramNV },
+      { "glDeleteProgramsARB", _gloffset_DeleteProgramsNV },
+      { "glGenProgramsARB", _gloffset_GenProgramsNV },
+      { "glIsProgramARB", _gloffset_IsProgramNV },
+      { "glProgramEnvParameter4dARB", _gloffset_ProgramEnvParameter4dARB },
+      { "glProgramEnvParameter4dvARB", _gloffset_ProgramEnvParameter4dvARB },
+      { "glProgramEnvParameter4fARB", _gloffset_ProgramEnvParameter4fARB },
+      { "glProgramEnvParameter4fvARB", _gloffset_ProgramEnvParameter4fvARB },
+      { "glProgramLocalParameter4dARB", _gloffset_ProgramLocalParameter4dARB },
+      { "glProgramLocalParameter4dvARB", _gloffset_ProgramLocalParameter4dvARB },
+      { "glProgramLocalParameter4fARB", _gloffset_ProgramLocalParameter4fARB },
+      { "glProgramLocalParameter4fvARB", _gloffset_ProgramLocalParameter4fvARB },
+      { "glGetProgramEnvParameterdvARB", _gloffset_GetProgramEnvParameterdvARB },
+      { "glGetProgramEnvParameterfvARB", _gloffset_GetProgramEnvParameterfvARB },
+      { "glGetProgramLocalParameterdvARB", _gloffset_GetProgramLocalParameterdvARB },
+      { "glGetProgramLocalParameterfvARB", _gloffset_GetProgramLocalParameterfvARB },
+      { "glGetProgramivARB", _gloffset_GetProgramivARB },
+      { "glGetProgramStringARB", _gloffset_GetProgramStringARB },
+      { "glGetVertexAttribdvARB", _gloffset_GetVertexAttribdvNV },
+      { "glGetVertexAttribfvARB", _gloffset_GetVertexAttribfvNV },
+      { "glGetVertexAttribivARB", _gloffset_GetVertexAttribivNV },
+      { "glGetVertexAttribPointervARB", _gloffset_GetVertexAttribPointervNV },
+#endif
+      { "glMultiModeDrawArraysIBM", _gloffset_MultiModeDrawArraysIBM },
+      { "glMultiModeDrawElementsIBM", _gloffset_MultiModeDrawElementsIBM },
+   };
+   
+   for ( i = 0 ; i < Elements(newer_entrypoints) ; i++ ) {
+      _glapi_add_entrypoint( newer_entrypoints[i].name,
+                            newer_entrypoints[i].offset );
+   }
+}
+
 
 /**
- * Initialize a GLcontext struct
+ * Initialize a GLcontext struct (rendering context).
  *
  * This includes allocating all the other structs and arrays which hang off of
  * the context by pointers.
+ * Note that the driver needs to pass in its dd_function_table here since
+ * we need to at least call driverFunctions->NewTextureObject to create the
+ * default texture objects.
  * 
- * \sa _mesa_create_context() for the parameter description.
+ * Called by _mesa_create_context().
  *
  * Performs the imports and exports callback tables initialization, and
  * miscellaneous one-time initializations. If no shared context is supplied one
@@ -1140,23 +1354,30 @@ init_attrib_groups( GLcontext *ctx )
  * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
  * for debug flags.
  *
- * \note the direct parameter is ignored (obsolete).
+ * \param ctx the context to initialize
+ * \param visual describes the visual attributes for this context
+ * \param share_list points to context to share textures, display lists,
+ *        etc with, or NULL
+ * \param driverFunctions table of device driver functions for this context
+ *        to use
+ * \param driverContext pointer to driver-specific context data
  */
 GLboolean
 _mesa_initialize_context( GLcontext *ctx,
                           const GLvisual *visual,
                           GLcontext *share_list,
-                          void *driver_ctx,
-                          GLboolean direct )
+                          const struct dd_function_table *driverFunctions,
+                          void *driverContext )
 {
    GLuint dispatchSize;
 
-   ASSERT(driver_ctx);
+   ASSERT(driverContext);
+   assert(driverFunctions->NewTextureObject);
 
    /* If the driver wants core Mesa to use special imports, it'll have to
     * override these defaults.
     */
-   _mesa_init_default_imports( &(ctx->imports), driver_ctx );
+   _mesa_init_default_imports( &(ctx->imports), driverContext );
 
    /* initialize the exports (Mesa functions called by the window system) */
    _mesa_init_default_exports( &(ctx->exports) );
@@ -1164,20 +1385,17 @@ _mesa_initialize_context( GLcontext *ctx,
    /* misc one-time initializations */
    one_time_init(ctx);
 
-   ctx->DriverCtx = driver_ctx;
    ctx->Visual = *visual;
    ctx->DrawBuffer = NULL;
    ctx->ReadBuffer = NULL;
 
-   /* Set these pointers to defaults now in case they're not set since
-    * we need them while creating the default textures.
+   /* 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
+    * textures.
     */
-   if (!ctx->Driver.NewTextureObject)
-      ctx->Driver.NewTextureObject = _mesa_new_texture_object;
-   if (!ctx->Driver.DeleteTexture)
-      ctx->Driver.DeleteTexture = _mesa_delete_texture_object;
-   if (!ctx->Driver.NewTextureImage)
-      ctx->Driver.NewTextureImage = _mesa_new_texture_image;
+   ctx->Driver = *driverFunctions;
+   ctx->DriverCtx = driverContext;
 
    if (share_list) {
       /* share state with another context */
@@ -1195,91 +1413,11 @@ _mesa_initialize_context( GLcontext *ctx,
 
    if (!init_attrib_groups( ctx )) {
       free_shared_state(ctx, ctx->Shared);
-      fprintf(stderr, "%s: failed to init attrib groups\n", __FUNCTION__);
       return GL_FALSE;
    }
 
-
-   /* TODO: move this to somewhere program-specific.
-    */
-   _glapi_add_entrypoint("glAreProgramsResidentNV", 578);
-   _glapi_add_entrypoint("glBindProgramNV", 579);
-   _glapi_add_entrypoint("glDeleteProgramsNV", 580);
-   _glapi_add_entrypoint("glExecuteProgramNV", 581);
-   _glapi_add_entrypoint("glGenProgramsNV", 582);
-   _glapi_add_entrypoint("glGetProgramParameterdvNV", 583);
-   _glapi_add_entrypoint("glGetProgramParameterfvNV", 584);
-   _glapi_add_entrypoint("glGetProgramivNV", 585);
-   _glapi_add_entrypoint("glGetProgramStringNV", 586);
-   _glapi_add_entrypoint("glGetTrackMatrixivNV", 587);
-   _glapi_add_entrypoint("glGetVertexAttribdvNV", 588);
-   _glapi_add_entrypoint("glGetVertexAttribfvNV", 589);
-   _glapi_add_entrypoint("glGetVertexAttribivNV", 590);
-   _glapi_add_entrypoint("glGetVertexAttribPointervNV", 591);
-   _glapi_add_entrypoint("glIsProgramNV", 592);
-   _glapi_add_entrypoint("glLoadProgramNV", 593);
-   _glapi_add_entrypoint("glProgramParameter4dNV", 594);
-   _glapi_add_entrypoint("glProgramParameter4dvNV", 595);
-   _glapi_add_entrypoint("glProgramParameter4fNV", 596);
-   _glapi_add_entrypoint("glProgramParameter4fvNV", 597);
-   _glapi_add_entrypoint("glProgramParameters4dvNV", 598);
-   _glapi_add_entrypoint("glProgramParameters4fvNV", 599);
-   _glapi_add_entrypoint("glRequestResidentProgramsNV", 600);
-   _glapi_add_entrypoint("glTrackMatrixNV", 601);
-   _glapi_add_entrypoint("glVertexAttribPointerNV", 602);
-   _glapi_add_entrypoint("glVertexAttrib1dNV", 603);
-   _glapi_add_entrypoint("glVertexAttrib1dvNV", 604);
-   _glapi_add_entrypoint("glVertexAttrib1fNV", 605);
-   _glapi_add_entrypoint("glVertexAttrib1fvNV", 606);
-   _glapi_add_entrypoint("glVertexAttrib1sNV", 607);
-   _glapi_add_entrypoint("glVertexAttrib1svNV", 608);
-   _glapi_add_entrypoint("glVertexAttrib2dNV", 609);
-   _glapi_add_entrypoint("glVertexAttrib2dvNV", 610);
-   _glapi_add_entrypoint("glVertexAttrib2fNV", 611);
-   _glapi_add_entrypoint("glVertexAttrib2fvNV", 612);
-   _glapi_add_entrypoint("glVertexAttrib2sNV", 613);
-   _glapi_add_entrypoint("glVertexAttrib2svNV", 614);
-   _glapi_add_entrypoint("glVertexAttrib3dNV", 615);
-   _glapi_add_entrypoint("glVertexAttrib3dvNV", 616);
-   _glapi_add_entrypoint("glVertexAttrib3fNV", 617);
-   _glapi_add_entrypoint("glVertexAttrib3fvNV", 618);
-   _glapi_add_entrypoint("glVertexAttrib3sNV", 619);
-   _glapi_add_entrypoint("glVertexAttrib3svNV", 620);
-   _glapi_add_entrypoint("glVertexAttrib4dNV", 621);
-   _glapi_add_entrypoint("glVertexAttrib4dvNV", 622);
-   _glapi_add_entrypoint("glVertexAttrib4fNV", 623);
-   _glapi_add_entrypoint("glVertexAttrib4fvNV", 624);
-   _glapi_add_entrypoint("glVertexAttrib4sNV", 625);
-   _glapi_add_entrypoint("glVertexAttrib4svNV", 626);
-   _glapi_add_entrypoint("glVertexAttrib4ubNV", 627);
-   _glapi_add_entrypoint("glVertexAttrib4ubvNV", 628);
-   _glapi_add_entrypoint("glVertexAttribs1dvNV", 629);
-   _glapi_add_entrypoint("glVertexAttribs1fvNV", 630);
-   _glapi_add_entrypoint("glVertexAttribs1svNV", 631);
-   _glapi_add_entrypoint("glVertexAttribs2dvNV", 632);
-   _glapi_add_entrypoint("glVertexAttribs2fvNV", 633);
-   _glapi_add_entrypoint("glVertexAttribs2svNV", 634);
-   _glapi_add_entrypoint("glVertexAttribs3dvNV", 635);
-   _glapi_add_entrypoint("glVertexAttribs3fvNV", 636);
-   _glapi_add_entrypoint("glVertexAttribs3svNV", 637);
-   _glapi_add_entrypoint("glVertexAttribs4dvNV", 638);
-   _glapi_add_entrypoint("glVertexAttribs4fvNV", 639);
-   _glapi_add_entrypoint("glVertexAttribs4svNV", 640);
-   _glapi_add_entrypoint("glVertexAttribs4ubvNV", 641);
-   _glapi_add_entrypoint("glPointParameteriNV", 642);
-   _glapi_add_entrypoint("glPointParameterivNV", 643);
-   _glapi_add_entrypoint("glMultiDrawArraysEXT", 644);
-   _glapi_add_entrypoint("glMultiDrawElementsEXT", 645);
-   _glapi_add_entrypoint("glActiveStencilFaceEXT", 646);
-   _glapi_add_entrypoint("glDeleteFencesNV", 647);
-   _glapi_add_entrypoint("glGenFencesNV", 648);
-   _glapi_add_entrypoint("glIsFenceNV", 649);
-   _glapi_add_entrypoint("glTestFenceNV", 650);
-   _glapi_add_entrypoint("glGetFenceivNV", 651);
-   _glapi_add_entrypoint("glFinishFenceNV", 652);
-   _glapi_add_entrypoint("glSetFenceNV", 653);
-   /* XXX add NV_fragment_program and ARB_vertex_program functions */
-
+   /* libGL ABI coordination */
+   add_newer_entrypoints();
 
    /* 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
@@ -1302,48 +1440,51 @@ _mesa_initialize_context( GLcontext *ctx,
 
 #if _HAVE_FULL_GL
    _mesa_init_dlist_table(ctx->Save, dispatchSize);
+   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
 
-   ctx->ExecPrefersFloat = GL_FALSE;
-   ctx->SavePrefersFloat = GL_FALSE;
 
    /* Neutral tnl module stuff */
    _mesa_init_exec_vtxfmt( ctx ); 
    ctx->TnlModule.Current = NULL;
    ctx->TnlModule.SwapCount = 0;
-
 #endif
 
-   fprintf(stderr, "%s: succeded\n", __FUNCTION__);
    return GL_TRUE;
 }
 
+
 /**
  * Allocate and initialize a GLcontext 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 share_list another context to share display lists with or NULL
- * \param driver_ctx pointer to device driver's context state struct
- * \param direct obsolete, ignored
+ * \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
  * 
  * \return pointer to a new __GLcontextRec or NULL if error.
  */
 GLcontext *
 _mesa_create_context( const GLvisual *visual,
                       GLcontext *share_list,
-                      void *driver_ctx,
-                      GLboolean direct )
+                      const struct dd_function_table *driverFunctions,
+                      void *driverContext )
 
 {
    GLcontext *ctx;
 
    ASSERT(visual);
-   ASSERT(driver_ctx);
+   ASSERT(driverContext);
 
    ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
    if (!ctx)
       return NULL;
 
-   if (_mesa_initialize_context(ctx, visual, share_list, driver_ctx, direct)) {
+   if (_mesa_initialize_context(ctx, visual, share_list,
+                                driverFunctions, driverContext)) {
       return ctx;
    }
    else {
@@ -1352,6 +1493,7 @@ _mesa_create_context( const GLvisual *visual,
    }
 }
 
+
 /**
  * Free the data associated with the given context.
  * 
@@ -1372,19 +1514,19 @@ _mesa_free_context_data( GLcontext *ctx )
    _mesa_free_texture_data( ctx );
    _mesa_free_matrix_data( ctx );
    _mesa_free_viewport_data( ctx );
-   _mesa_free_colortable_data( ctx );
+   _mesa_free_colortables_data( ctx );
 #if FEATURE_NV_vertex_program
    if (ctx->VertexProgram.Current) {
       ctx->VertexProgram.Current->Base.RefCount--;
       if (ctx->VertexProgram.Current->Base.RefCount <= 0)
-         _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base));
+         ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
    }
 #endif
 #if FEATURE_NV_fragment_program
    if (ctx->FragmentProgram.Current) {
       ctx->FragmentProgram.Current->Base.RefCount--;
       if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
-         _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base));
+         ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
    }
 #endif
 
@@ -1398,18 +1540,20 @@ _mesa_free_context_data( GLcontext *ctx )
       free_shared_state( ctx, ctx->Shared );
    }
 
-   _mesa_extensions_dtr(ctx);
+   if (ctx->Extensions.String)
+      FREE((void *) ctx->Extensions.String);
 
    FREE(ctx->Exec);
    FREE(ctx->Save);
 }
 
+
 /**
  * Destroy a GLcontext structure.
  *
  * \param ctx GL context.
  * 
- * Calls _mesa_free_context_data() and free the structure.
+ * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
  */
 void
 _mesa_destroy_context( GLcontext *ctx )
@@ -1420,6 +1564,7 @@ _mesa_destroy_context( GLcontext *ctx )
    }
 }
 
+
 #if _HAVE_FULL_GL
 /**
  * Copy attribute groups from one context to another.
@@ -1788,7 +1933,7 @@ _mesa_record_error( GLcontext *ctx, GLenum error )
  * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
  * dd_function_table::Finish driver callback, if not NULL.
  */
-void
+void GLAPIENTRY
 _mesa_Finish( void )
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -1804,7 +1949,7 @@ _mesa_Finish( void )
  * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
  * dd_function_table::Flush driver callback, if not NULL.
  */
-void
+void GLAPIENTRY
 _mesa_Flush( void )
 {
    GET_CURRENT_CONTEXT(ctx);