fix up radeon span functions using latest r200 code from Brian,
[mesa.git] / src / mesa / drivers / dri / r200 / r200_context.c
index ec95f05e6ef1ec25feff8afc4a6606dc222b51fd..1c65fea6a137066afa3649ddcc12ae1055441ab5 100644 (file)
@@ -1,6 +1,5 @@
-/* $XFree86$ */
-/**************************************************************************
-
+/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.c,v 1.3 2003/05/06 23:52:08 daenzer Exp $ */
+/*
 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 
 The Weather Channel (TM) funded Tungsten Graphics to develop the
@@ -41,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "imports.h"
 #include "matrix.h"
 #include "extensions.h"
+#include "framebuffer.h"
 #include "state.h"
 
 #include "swrast/swrast.h"
@@ -50,6 +50,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 
+#include "drivers/common/driverfuncs.h"
+
 #include "r200_context.h"
 #include "r200_ioctl.h"
 #include "r200_state.h"
@@ -61,16 +63,29 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r200_vtxfmt.h"
 #include "r200_maos.h"
 
-#define DRIVER_DATE    "20030328"
+#define need_GL_ARB_multisample
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
+#define need_GL_ATI_fragment_shader
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_secondary_color
+#define need_GL_EXT_blend_equation_separate
+#define need_GL_EXT_blend_func_separate
+#define need_GL_NV_vertex_program
+#include "extension_helper.h"
+
+#define DRIVER_DATE    "20050831"
 
 #include "vblank.h"
 #include "utils.h"
+#include "xmlpool.h" /* for symbolic values of enum-type options */
 #ifndef R200_DEBUG
 int R200_DEBUG = (0);
 #endif
 
 
-
 /* Return the width and height of the given buffer.
  */
 static void r200GetBufferSize( GLframebuffer *buffer,
@@ -117,44 +132,60 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
 
 /* Extension strings exported by the R200 driver.
  */
-static const char * const card_extensions[] =
+const struct dri_extension card_extensions[] =
 {
-    "GL_ARB_multisample",
-    "GL_ARB_multitexture",
-    "GL_ARB_texture_border_clamp",
-    "GL_ARB_texture_compression",
-    "GL_ARB_texture_env_add",
-    "GL_ARB_texture_env_combine",
-    "GL_ARB_texture_env_dot3",
-    "GL_ARB_texture_mirrored_repeat",
-    "GL_EXT_blend_logic_op",
-    "GL_EXT_blend_minmax",
-    "GL_EXT_blend_subtract",
-    "GL_EXT_secondary_color",
-    "GL_EXT_stencil_wrap",
-    "GL_EXT_texture_edge_clamp",
-    "GL_EXT_texture_env_add",
-    "GL_EXT_texture_env_combine",
-    "GL_EXT_texture_env_dot3",
-    "GL_EXT_texture_filter_anisotropic",
-    "GL_EXT_texture_lod_bias",
-    "GL_ATI_texture_env_combine3",
-    "GL_ATI_texture_mirror_once",
-    "GL_IBM_texture_mirrored_repeat",
-    "GL_MESA_pack_invert",
-    "GL_MESA_ycbcr_texture",
-    "GL_NV_blend_square",
-    "GL_NV_texture_rectangle",
-    "GL_SGIS_generate_mipmap",
-    "GL_SGIS_texture_border_clamp",
-    "GL_SGIS_texture_edge_clamp",
-    NULL
+    { "GL_ARB_multisample",                GL_ARB_multisample_functions },
+    { "GL_ARB_multitexture",               NULL },
+    { "GL_ARB_texture_border_clamp",       NULL },
+    { "GL_ARB_texture_compression",        GL_ARB_texture_compression_functions },
+    { "GL_ARB_texture_env_add",            NULL },
+    { "GL_ARB_texture_env_combine",        NULL },
+    { "GL_ARB_texture_env_dot3",           NULL },
+    { "GL_ARB_texture_env_crossbar",       NULL },
+    { "GL_ARB_texture_mirrored_repeat",    NULL },
+    { "GL_ARB_vertex_buffer_object",       GL_ARB_vertex_buffer_object_functions },
+    { "GL_EXT_blend_minmax",               GL_EXT_blend_minmax_functions },
+    { "GL_EXT_blend_subtract",             NULL },
+    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
+    { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
+    { "GL_EXT_stencil_wrap",               NULL },
+    { "GL_EXT_texture_edge_clamp",         NULL },
+    { "GL_EXT_texture_env_combine",        NULL },
+    { "GL_EXT_texture_env_dot3",           NULL },
+    { "GL_EXT_texture_filter_anisotropic", NULL },
+    { "GL_EXT_texture_lod_bias",           NULL },
+    { "GL_EXT_texture_mirror_clamp",       NULL },
+    { "GL_EXT_texture_rectangle",          NULL },
+    { "GL_ATI_texture_env_combine3",       NULL },
+    { "GL_ATI_texture_mirror_once",        NULL },
+    { "GL_MESA_pack_invert",               NULL },
+    { "GL_NV_blend_square",                NULL },
+    { "GL_SGIS_generate_mipmap",           NULL },
+    { NULL,                                NULL }
 };
 
-extern const struct gl_pipeline_stage _r200_render_stage;
-extern const struct gl_pipeline_stage _r200_tcl_stage;
+const struct dri_extension blend_extensions[] = {
+    { "GL_EXT_blend_equation_separate",    GL_EXT_blend_equation_separate_functions },
+    { "GL_EXT_blend_func_separate",        GL_EXT_blend_func_separate_functions },
+    { NULL,                                NULL }
+};
+                                                        
+const struct dri_extension ARB_vp_extension[] = {
+    { "GL_ARB_vertex_program",             GL_ARB_vertex_program_functions }
+};
 
-static const struct gl_pipeline_stage *r200_pipeline[] = {
+const struct dri_extension NV_vp_extension[] = {
+    { "GL_NV_vertex_program",              GL_NV_vertex_program_functions }
+};
+
+const struct dri_extension ATI_fs_extension[] = {
+    { "GL_ATI_fragment_shader",            GL_ATI_fragment_shader_functions }
+};
+
+extern const struct tnl_pipeline_stage _r200_render_stage;
+extern const struct tnl_pipeline_stage _r200_tcl_stage;
+
+static const struct tnl_pipeline_stage *r200_pipeline[] = {
 
    /* Try and go straight to t&l
     */
@@ -168,6 +199,8 @@ static const struct gl_pipeline_stage *r200_pipeline[] = {
    &_tnl_fog_coordinate_stage,
    &_tnl_texgen_stage,
    &_tnl_texture_transform_stage,
+   &_tnl_arb_vertex_program_stage,
+   &_tnl_vertex_program_stage,
 
    /* Try again to go to tcl? 
     *     - no good for asymmetric-twoside (do with multipass)
@@ -183,22 +216,22 @@ static const struct gl_pipeline_stage *r200_pipeline[] = {
     */
 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
    &_tnl_render_stage,         /* FALLBACK:  */
-   0,
+   NULL,
 };
 
 
 
 /* Initialize the driver's misc functions.
  */
-static void r200InitDriverFuncs( GLcontext *ctx )
+static void r200InitDriverFuncs( struct dd_function_table *functions )
 {
-    ctx->Driver.GetBufferSize          = r200GetBufferSize;
-    ctx->Driver.ResizeBuffers           = _swrast_alloc_buffers;
-    ctx->Driver.GetString              = r200GetString;
+    functions->GetBufferSize           = r200GetBufferSize;
+    functions->ResizeBuffers            = _mesa_resize_framebuffer;
+    functions->GetString               = r200GetString;
 
-    ctx->Driver.Error                  = NULL;
-    ctx->Driver.DrawPixels             = NULL;
-    ctx->Driver.Bitmap                 = NULL;
+    functions->Error                   = NULL;
+    functions->DrawPixels              = NULL;
+    functions->Bitmap                  = NULL;
 }
 
 static const struct dri_debug_control debug_control[] =
@@ -223,15 +256,7 @@ static const struct dri_debug_control debug_control[] =
 };
 
 
-static int
-get_ust_nop( int64_t * ust )
-{
-   *ust = 1;
-   return 0;
-}
-
-
-/* Create the device specific context.
+/* Create the device specific rendering context.
  */
 GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                             __DRIcontextPrivate *driContextPriv,
@@ -239,9 +264,11 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
 {
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
    r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private);
+   struct dd_function_table functions;
    r200ContextPtr rmesa;
    GLcontext *ctx, *shareCtx;
    int i;
+   int tcl_mode, fthrottle_mode;
 
    assert(glVisual);
    assert(driContextPriv);
@@ -251,13 +278,46 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
    if ( !rmesa )
       return GL_FALSE;
+      
+   /* init exp fog table data */
+   r200InitStaticFogData();
+
+   /* Parse configuration files.
+    * Do this here so that initialMaxAnisotropy is set before we create
+    * the default textures.
+    */
+   driParseConfigFiles (&rmesa->optionCache, &screen->optionCache,
+                       screen->driScreen->myNum, "r200");
+   rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache,
+                                                 "def_max_anisotropy");
+
+   if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
+      if ( sPriv->drmMinor < 13 )
+        fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
+                         "disabling.\n",sPriv->drmMinor );
+      else
+        rmesa->using_hyperz = GL_TRUE;
+   }
+   if ( sPriv->drmMinor >= 15 )
+      rmesa->texmicrotile = GL_TRUE;
+
+   /* Init default driver functions then plug in our R200-specific functions
+    * (the texture functions are especially important)
+    */
+   _mesa_init_driver_functions(&functions);
+   r200InitDriverFuncs(&functions);
+   r200InitIoctlFuncs(&functions);
+   r200InitStateFuncs(&functions);
+   r200InitTextureFuncs(&functions);
 
-   /* Allocate the Mesa context */
+   /* Allocate and initialize the Mesa context */
    if (sharedContextPrivate)
       shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
    else
       shareCtx = NULL;
-   rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, (void *) rmesa, GL_TRUE);
+   rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
+                                       &functions, (void *) rmesa);
    if (!rmesa->glCtx) {
       FREE(rmesa);
       return GL_FALSE;
@@ -274,7 +334,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    rmesa->dri.drmMinor = sPriv->drmMinor;
 
    rmesa->r200Screen = screen;
-   rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA +
+   rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
                                       screen->sarea_priv_offset);
 
 
@@ -284,20 +344,26 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    make_empty_list( & rmesa->swapped );
 
    rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
+   assert(rmesa->nr_heaps < R200_NR_TEX_HEAPS);
    for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
       rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
            screen->texSize[i],
            12,
            RADEON_NR_TEX_REGIONS,
-           rmesa->sarea->texList[i],
-           & rmesa->sarea->texAge[i],
+           (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
+           & rmesa->sarea->tex_age[i],
            & rmesa->swapped,
            sizeof( r200TexObj ),
            (destroy_texture_object_t *) r200DestroyTexObj );
    }
+   rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
+                                          "texture_depth");
+   if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
+      rmesa->texture_depth = ( screen->cpp == 4 ) ?
+        DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
 
    rmesa->swtcl.RenderIndex = ~0;
-   rmesa->lost_context = 1;
+   rmesa->hw.all_dirty = 1;
 
    /* Set the maximum texture size small enough that we can guarentee that
     * all texture units can bind a maximal texture and have them both in
@@ -305,7 +371,10 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
     */
 
    ctx = rmesa->glCtx;
-   ctx->Const.MaxTextureUnits = 2;
+   ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache,
+                                                "texture_units");
+   ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+   ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
 
    driCalculateMaxTextureLevels( rmesa->texture_heaps,
                                 rmesa->nr_heaps,
@@ -322,14 +391,28 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                                 12,
                                 GL_FALSE );
 
+   /* adjust max texture size a bit. Hack, but I really want to use larger textures
+      which will work just fine in 99.999999% of all cases, especially with texture compression... */
+   if (driQueryOptionb( &rmesa->optionCache, "texture_level_hack" ))
+   {
+     if (ctx->Const.MaxTextureLevels < 12) ctx->Const.MaxTextureLevels += 1;
+   }
+
    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
 
-   /* No wide points.
+   /* No wide AA points.
     */
    ctx->Const.MinPointSize = 1.0;
    ctx->Const.MinPointSizeAA = 1.0;
-   ctx->Const.MaxPointSize = 1.0;
    ctx->Const.MaxPointSizeAA = 1.0;
+   ctx->Const.PointSizeGranularity = 0.0625;
+   if (rmesa->r200Screen->drmSupportsPointSprites)
+      ctx->Const.MaxPointSize = 2047.0;
+   else
+      ctx->Const.MaxPointSize = 1.0;
+
+   /* mesa initialization problem - _mesa_init_point was already called */
+   ctx->Point.MaxSize = ctx->Const.MaxPointSize;
 
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
@@ -356,62 +439,86 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    _tnl_isolate_materials( ctx, GL_TRUE );
 
 
-   /* Configure swrast to match hardware characteristics:
+   /* Configure swrast and TNL to match hardware characteristics:
     */
    _swrast_allow_pixel_fog( ctx, GL_FALSE );
    _swrast_allow_vertex_fog( ctx, GL_TRUE );
+   _tnl_allow_pixel_fog( ctx, GL_FALSE );
+   _tnl_allow_vertex_fog( ctx, GL_TRUE );
 
 
-   _math_matrix_ctr( &rmesa->TexGenMatrix[0] );
-   _math_matrix_ctr( &rmesa->TexGenMatrix[1] );
+   for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
+      _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
+      _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
+   }
    _math_matrix_ctr( &rmesa->tmpmat );
-   _math_matrix_set_identity( &rmesa->TexGenMatrix[0] );
-   _math_matrix_set_identity( &rmesa->TexGenMatrix[1] );
    _math_matrix_set_identity( &rmesa->tmpmat );
 
    driInitExtensions( ctx, card_extensions, GL_TRUE );
+   if (!(rmesa->r200Screen->chipset & R200_CHIPSET_YCBCR_BROKEN)) {
+     /* yuv textures don't work with some chips - R200 / rv280 okay so far
+       others get the bit ordering right but don't actually do YUV-RGB conversion */
+      _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
+   }
+   if (rmesa->glCtx->Mesa_DXTn) {
+      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
+      _mesa_enable_extension( ctx, "GL_S3_s3tc" );
+   }
+   else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) {
+      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
+   }
+
    if (rmesa->r200Screen->drmSupportsCubeMaps)
       _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
-
+   if (rmesa->r200Screen->drmSupportsBlendColor) {
+       driInitExtensions( ctx, blend_extensions, GL_FALSE );
+   }
+   if(driQueryOptionb(&rmesa->optionCache, "arb_vertex_program"))
+      driInitSingleExtension( ctx, ARB_vp_extension );
+   if(driQueryOptionb(&rmesa->optionCache, "nv_vertex_program"))
+      driInitSingleExtension( ctx, NV_vp_extension );
+
+   if ((ctx->Const.MaxTextureUnits == 6) && rmesa->r200Screen->drmSupportsFragShader)
+      driInitSingleExtension( ctx, ATI_fs_extension );
+#if 0
    r200InitDriverFuncs( ctx );
    r200InitIoctlFuncs( ctx );
    r200InitStateFuncs( ctx );
-   r200InitSpanFuncs( ctx );
-   r200InitPixelFuncs( ctx );
    r200InitTextureFuncs( ctx );
+#endif
+   /* plug in a few more device driver functions */
+   /* XXX these should really go right after _mesa_init_driver_functions() */
+   r200InitPixelFuncs( ctx );
+   r200InitSpanFuncs( ctx );
+   r200InitTnlFuncs( ctx );
    r200InitState( rmesa );
    r200InitSwtcl( ctx );
 
+   fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
    rmesa->iw.irq_seq = -1;
    rmesa->irqsEmitted = 0;
    rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && 
-                    !getenv("R200_NO_IRQS") &&
+                    fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
                     rmesa->r200Screen->irq);
 
+   rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
+
    if (!rmesa->do_irqs)
-      fprintf(stderr, 
-             "IRQ's not enabled, falling back to busy waits: %d %d %d\n",
+      fprintf(stderr,
+             "IRQ's not enabled, falling back to %s: %d %d %d\n",
+             rmesa->do_usleeps ? "usleeps" : "busy waits",
              rmesa->dri.drmMinor,
-             !!getenv("R200_NO_IRQS"),
+             fthrottle_mode,
              rmesa->r200Screen->irq);
 
+   rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
+       ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
-   rmesa->do_usleeps = !getenv("R200_NO_USLEEPS");
+   rmesa->prefer_gart_client_texturing = 
+      (getenv("R200_GART_CLIENT_TEXTURES") != 0);
 
-   rmesa->vblank_flags = (rmesa->do_irqs)
-       ? driGetDefaultVBlankFlags() : VBLANK_FLAG_NO_IRQ;
+   (*dri_interface->getUST)( & rmesa->swap_ust );
 
-   rmesa->prefer_agp_client_texturing = 
-      (getenv("R200_AGP_CLIENT_TEXTURES") != 0);
-   
-#ifndef _SOLO
-   rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( "__glXGetUST" );
-   if ( rmesa->get_ust == NULL ) {
-      rmesa->get_ust = get_ust_nop;
-   }
-
-   (*rmesa->get_ust)( & rmesa->swap_ust );
-#endif
 
 #if DO_DEBUG
    R200_DEBUG  = driParseDebugString( getenv( "R200_DEBUG" ),
@@ -420,18 +527,24 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                                      debug_control );
 #endif
 
-   if (getenv("R200_NO_RAST")) {
+   tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
+   if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
       fprintf(stderr, "disabling 3D acceleration\n");
-      FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1); 
-   }
-   else if (getenv("R200_NO_TCL")) {
-      fprintf(stderr, "disabling TCL support\n");
-      TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); 
+      FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
    }
-   else {
-      if (!getenv("R200_NO_VTXFMT")) {
-        r200VtxfmtInit( ctx );
+   else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
+           !(rmesa->r200Screen->chipset & R200_CHIPSET_TCL)) {
+      if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
+        rmesa->r200Screen->chipset &= ~R200_CHIPSET_TCL;
+        fprintf(stderr, "Disabling HW TCL support\n");
       }
+      TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
+   }
+
+   if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
+      if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
+        r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
+
       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
    }
    return GL_TRUE;
@@ -451,7 +564,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
    /* check if we're deleting the currently bound context */
    if (rmesa == current) {
       R200_FIREVERTICES( rmesa );
-      _mesa_make_current2(NULL, NULL, NULL);
+      _mesa_make_current(NULL, NULL, NULL);
    }
 
    /* Free r200 context resources */
@@ -474,9 +587,11 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
         r200FlushCmdBuf( rmesa, __FUNCTION__ );
       }
 
-      if (!rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
-        if (!getenv("R200_NO_VTXFMT"))
+      if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) {
+        int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
+        if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
            r200VtxfmtDestroy( rmesa->glCtx );
+      }
 
       /* free the Mesa context */
       rmesa->glCtx->DriverCtx = NULL;
@@ -484,7 +599,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
 
       if (rmesa->state.scissor.pClipRects) {
         FREE(rmesa->state.scissor.pClipRects);
-        rmesa->state.scissor.pClipRects = 0;
+        rmesa->state.scissor.pClipRects = NULL;
       }
 
       if ( release_texture_heaps ) {
@@ -492,16 +607,18 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
           * texture object data.
           */
          int i;
-        
-        /* this assert is wrong. The default textures are always on swap list
-        assert( is_empty_list( & rmesa->swapped ) ); */
 
          for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
            driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
            rmesa->texture_heaps[ i ] = NULL;
          }
+
+        assert( is_empty_list( & rmesa->swapped ) );
       }
 
+      /* free the option cache */
+      driDestroyOptionCache (&rmesa->optionCache);
+
       FREE( rmesa );
    }
 }
@@ -547,22 +664,18 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
         (r200ContextPtr) driContextPriv->driverPrivate;
 
       if (R200_DEBUG & DEBUG_DRI)
-        fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newCtx->glCtx);
+        fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
 
       if ( newCtx->dri.drawable != driDrawPriv ) {
+        driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
         newCtx->dri.drawable = driDrawPriv;
         r200UpdateWindow( newCtx->glCtx );
         r200UpdateViewportOffset( newCtx->glCtx );
       }
 
-      _mesa_make_current2( newCtx->glCtx,
-                          (GLframebuffer *) driDrawPriv->driverPrivate,
-                          (GLframebuffer *) driReadPriv->driverPrivate );
-
-      if ( !newCtx->glCtx->Viewport.Width ) {
-        _mesa_set_viewport( newCtx->glCtx, 0, 0,
-                            driDrawPriv->w, driDrawPriv->h );
-      }
+      _mesa_make_current( newCtx->glCtx,
+                         (GLframebuffer *) driDrawPriv->driverPrivate,
+                         (GLframebuffer *) driReadPriv->driverPrivate );
 
       if (newCtx->vb.enabled)
         r200VtxfmtMakeCurrent( newCtx->glCtx );
@@ -573,7 +686,7 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
    } else {
       if (R200_DEBUG & DEBUG_DRI)
         fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
-      _mesa_make_current( 0, 0 );
+      _mesa_make_current( NULL, NULL, NULL );
    }
 
    if (R200_DEBUG & DEBUG_DRI)
@@ -589,7 +702,7 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv )
    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
 
    if (R200_DEBUG & DEBUG_DRI)
-      fprintf(stderr, "%s ctx %p\n", __FUNCTION__, rmesa->glCtx);
+      fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx);
 
    r200VtxfmtUnbindContext( rmesa->glCtx );
    return GL_TRUE;