Merge branch 'master' of git+ssh://joukj@git.freedesktop.org/git/mesa/mesa
[mesa.git] / src / mesa / drivers / dri / r200 / r200_context.c
index ec95f05e6ef1ec25feff8afc4a6606dc222b51fd..5a178442bdb7bb2a494a1d3a9e3876a7c624c4ee 100644 (file)
@@ -1,6 +1,4 @@
-/* $XFree86$ */
-/**************************************************************************
-
+/*
 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 
 The Weather Channel (TM) funded Tungsten Graphics to develop the
 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
 
 The Weather Channel (TM) funded Tungsten Graphics to develop the
@@ -41,15 +39,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "imports.h"
 #include "matrix.h"
 #include "extensions.h"
 #include "imports.h"
 #include "matrix.h"
 #include "extensions.h"
+#include "framebuffer.h"
 #include "state.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "state.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 
 
 #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"
 #include "r200_context.h"
 #include "r200_ioctl.h"
 #include "r200_state.h"
@@ -58,33 +59,32 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r200_tex.h"
 #include "r200_swtcl.h"
 #include "r200_tcl.h"
 #include "r200_tex.h"
 #include "r200_swtcl.h"
 #include "r200_tcl.h"
-#include "r200_vtxfmt.h"
 #include "r200_maos.h"
 #include "r200_maos.h"
-
-#define DRIVER_DATE    "20030328"
+#include "r200_vertprog.h"
+
+#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
+#define need_GL_ARB_point_parameters
+#include "extension_helper.h"
+
+#define DRIVER_DATE    "20060602"
 
 #include "vblank.h"
 #include "utils.h"
 
 #include "vblank.h"
 #include "utils.h"
+#include "xmlpool.h" /* for symbolic values of enum-type options */
 #ifndef R200_DEBUG
 int R200_DEBUG = (0);
 #endif
 
 #ifndef R200_DEBUG
 int R200_DEBUG = (0);
 #endif
 
-
-
-/* Return the width and height of the given buffer.
- */
-static void r200GetBufferSize( GLframebuffer *buffer,
-                              GLuint *width, GLuint *height )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
-   LOCK_HARDWARE( rmesa );
-   *width  = rmesa->dri.drawable->w;
-   *height = rmesa->dri.drawable->h;
-   UNLOCK_HARDWARE( rmesa );
-}
-
 /* Return various strings for glGetString().
  */
 static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
 /* Return various strings for glGetString().
  */
 static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
@@ -92,7 +92,7 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    static char buffer[128];
    unsigned   offset;
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    static char buffer[128];
    unsigned   offset;
-   GLuint agp_mode = rmesa->r200Screen->IsPCI ? 0 :
+   GLuint agp_mode = (rmesa->r200Screen->card_type == RADEON_CARD_PCI)? 0 :
       rmesa->r200Screen->AGPMode;
 
    switch ( name ) {
       rmesa->r200Screen->AGPMode;
 
    switch ( name ) {
@@ -117,44 +117,66 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
 
 /* Extension strings exported by the R200 driver.
  */
 
 /* 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 }
+};
+
+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 }
+};
+
+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 }
+};
+
+const struct dri_extension point_extensions[] = {
+    { "GL_ARB_point_sprite",               NULL },
+    { "GL_ARB_point_parameters",           GL_ARB_point_parameters_functions },
+    { NULL,                                NULL }
 };
 
 };
 
-extern const struct gl_pipeline_stage _r200_render_stage;
-extern const struct gl_pipeline_stage _r200_tcl_stage;
+extern const struct tnl_pipeline_stage _r200_render_stage;
+extern const struct tnl_pipeline_stage _r200_tcl_stage;
 
 
-static const struct gl_pipeline_stage *r200_pipeline[] = {
+static const struct tnl_pipeline_stage *r200_pipeline[] = {
 
    /* Try and go straight to t&l
     */
 
    /* Try and go straight to t&l
     */
@@ -168,7 +190,8 @@ static const struct gl_pipeline_stage *r200_pipeline[] = {
    &_tnl_fog_coordinate_stage,
    &_tnl_texgen_stage,
    &_tnl_texture_transform_stage,
    &_tnl_fog_coordinate_stage,
    &_tnl_texgen_stage,
    &_tnl_texture_transform_stage,
-
+   &_tnl_point_attenuation_stage,
+   &_tnl_vertex_program_stage,
    /* Try again to go to tcl? 
     *     - no good for asymmetric-twoside (do with multipass)
     *     - no good for asymmetric-unfilled (do with multipass)
    /* Try again to go to tcl? 
     *     - no good for asymmetric-twoside (do with multipass)
     *     - no good for asymmetric-unfilled (do with multipass)
@@ -183,22 +206,17 @@ static const struct gl_pipeline_stage *r200_pipeline[] = {
     */
 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
    &_tnl_render_stage,         /* FALLBACK:  */
     */
 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
    &_tnl_render_stage,         /* FALLBACK:  */
-   0,
+   NULL,
 };
 
 
 
 /* Initialize the driver's misc functions.
  */
 };
 
 
 
 /* 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;
-
-    ctx->Driver.Error                  = NULL;
-    ctx->Driver.DrawPixels             = NULL;
-    ctx->Driver.Bitmap                 = NULL;
+    functions->GetBufferSize           = NULL; /* OBSOLETE */
+    functions->GetString               = r200GetString;
 }
 
 static const struct dri_debug_control debug_control[] =
 }
 
 static const struct dri_debug_control debug_control[] =
@@ -223,25 +241,19 @@ 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,
                             void *sharedContextPrivate)
 {
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
  */
 GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                             __DRIcontextPrivate *driContextPriv,
                             void *sharedContextPrivate)
 {
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
-   r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private);
+   radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
+   struct dd_function_table functions;
    r200ContextPtr rmesa;
    GLcontext *ctx, *shareCtx;
    int i;
    r200ContextPtr rmesa;
    GLcontext *ctx, *shareCtx;
    int i;
+   int tcl_mode, fthrottle_mode;
 
    assert(glVisual);
    assert(driContextPriv);
 
    assert(glVisual);
    assert(driContextPriv);
@@ -251,13 +263,47 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
    if ( !rmesa )
       return GL_FALSE;
    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
    if ( !rmesa )
       return GL_FALSE;
+      
+   /* init exp fog table data */
+   r200InitStaticFogData();
 
 
-   /* Allocate the Mesa context */
+   /* 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);
+   r200InitShaderFuncs(&functions); 
+
+   /* Allocate and initialize the Mesa context */
    if (sharedContextPrivate)
       shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
    else
       shareCtx = NULL;
    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;
    if (!rmesa->glCtx) {
       FREE(rmesa);
       return GL_FALSE;
@@ -274,7 +320,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    rmesa->dri.drmMinor = sPriv->drmMinor;
 
    rmesa->r200Screen = screen;
    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);
 
 
                                       screen->sarea_priv_offset);
 
 
@@ -284,28 +330,40 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    make_empty_list( & rmesa->swapped );
 
    rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
    make_empty_list( & rmesa->swapped );
 
    rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
+   assert(rmesa->nr_heaps < RADEON_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,
    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->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->swtcl.RenderIndex = ~0;
-   rmesa->lost_context = 1;
+   rmesa->hw.all_dirty = 1;
 
    /* Set the maximum texture size small enough that we can guarentee that
 
    /* 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
-    * texturable memory at once.
+    * all texture units can bind a maximal texture and have all of them in
+    * texturable memory at once. Depending on the allow_large_textures driconf
+    * setting allow larger textures.
     */
 
    ctx = rmesa->glCtx;
     */
 
    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;
+
+   i = driQueryOptioni( &rmesa->optionCache, "allow_large_textures");
 
    driCalculateMaxTextureLevels( rmesa->texture_heaps,
                                 rmesa->nr_heaps,
 
    driCalculateMaxTextureLevels( rmesa->texture_heaps,
                                 rmesa->nr_heaps,
@@ -320,16 +378,24 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                                 11, /* max cube texture size is 2048x2048 */
                                 11, /* max texture rectangle size is 2048x2048 */
                                 12,
                                 11, /* max cube texture size is 2048x2048 */
                                 11, /* max texture rectangle size is 2048x2048 */
                                 12,
-                                GL_FALSE );
+                                GL_FALSE,
+                                i );
 
    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
 
 
    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
 
-   /* No wide points.
+   /* No wide AA points.
     */
    ctx->Const.MinPointSize = 1.0;
    ctx->Const.MinPointSizeAA = 1.0;
     */
    ctx->Const.MinPointSize = 1.0;
    ctx->Const.MinPointSizeAA = 1.0;
-   ctx->Const.MaxPointSize = 1.0;
    ctx->Const.MaxPointSizeAA = 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;
 
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
@@ -337,10 +403,16 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    ctx->Const.MaxLineWidthAA = 10.0;
    ctx->Const.LineWidthGranularity = 0.0625;
 
    ctx->Const.MaxLineWidthAA = 10.0;
    ctx->Const.LineWidthGranularity = 0.0625;
 
+   ctx->Const.VertexProgram.MaxNativeInstructions = R200_VSF_MAX_INST;
+   ctx->Const.VertexProgram.MaxNativeAttribs = 12;
+   ctx->Const.VertexProgram.MaxNativeTemps = R200_VSF_MAX_TEMPS;
+   ctx->Const.VertexProgram.MaxNativeParameters = R200_VSF_MAX_PARAM;
+   ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
+
    /* Initialize the software rasterizer and helper modules.
     */
    _swrast_CreateContext( ctx );
    /* Initialize the software rasterizer and helper modules.
     */
    _swrast_CreateContext( ctx );
-   _ac_CreateContext( ctx );
+   _vbo_CreateContext( ctx );
    _tnl_CreateContext( ctx );
    _swsetup_CreateContext( ctx );
    _ae_create_context( ctx );
    _tnl_CreateContext( ctx );
    _swsetup_CreateContext( ctx );
    _ae_create_context( ctx );
@@ -349,69 +421,92 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
     */
    _tnl_destroy_pipeline( ctx );
    _tnl_install_pipeline( ctx, r200_pipeline );
     */
    _tnl_destroy_pipeline( ctx );
    _tnl_install_pipeline( ctx, r200_pipeline );
-   ctx->Driver.FlushVertices = r200FlushVertices;
 
    /* Try and keep materials and vertices separate:
     */
 
    /* Try and keep materials and vertices separate:
     */
-   _tnl_isolate_materials( ctx, GL_TRUE );
+/*    _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 );
     */
    _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_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 );
    _math_matrix_set_identity( &rmesa->tmpmat );
 
    driInitExtensions( ctx, card_extensions, GL_TRUE );
-   if (rmesa->r200Screen->drmSupportsCubeMaps)
-      _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
+   if (!(rmesa->r200Screen->chip_flags & 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->drmSupportsCubeMapsR200)
+      _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
+   if (rmesa->r200Screen->drmSupportsBlendColor) {
+       driInitExtensions( ctx, blend_extensions, GL_FALSE );
+   }
+   if(rmesa->r200Screen->drmSupportsVertexProgram)
+      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 (rmesa->r200Screen->drmSupportsPointSprites)
+      driInitExtensions( ctx, point_extensions, GL_FALSE );
+#if 0
    r200InitDriverFuncs( ctx );
    r200InitIoctlFuncs( ctx );
    r200InitStateFuncs( ctx );
    r200InitDriverFuncs( ctx );
    r200InitIoctlFuncs( ctx );
    r200InitStateFuncs( ctx );
-   r200InitSpanFuncs( ctx );
-   r200InitPixelFuncs( ctx );
    r200InitTextureFuncs( 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 );
 
    r200InitState( rmesa );
    r200InitSwtcl( ctx );
 
+   fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
    rmesa->iw.irq_seq = -1;
    rmesa->irqsEmitted = 0;
    rmesa->iw.irq_seq = -1;
    rmesa->irqsEmitted = 0;
-   rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && 
-                    !getenv("R200_NO_IRQS") &&
+   rmesa->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
                     rmesa->r200Screen->irq);
 
                     rmesa->r200Screen->irq);
 
+   rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
+
    if (!rmesa->do_irqs)
    if (!rmesa->do_irqs)
-      fprintf(stderr, 
-             "IRQ's not enabled, falling back to busy waits: %d %d %d\n",
-             rmesa->dri.drmMinor,
-             !!getenv("R200_NO_IRQS"),
+      fprintf(stderr,
+             "IRQ's not enabled, falling back to %s: %d %d\n",
+             rmesa->do_usleeps ? "usleeps" : "busy waits",
+             fthrottle_mode,
              rmesa->r200Screen->irq);
 
              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" ),
 
 #if DO_DEBUG
    R200_DEBUG  = driParseDebugString( getenv( "R200_DEBUG" ),
@@ -420,20 +515,20 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                                      debug_control );
 #endif
 
                                      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");
       fprintf(stderr, "disabling 3D acceleration\n");
-      FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1); 
+      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); 
-   }
-   else {
-      if (!getenv("R200_NO_VTXFMT")) {
-        r200VtxfmtInit( ctx );
+   else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
+           !(rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL)) {
+      if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) {
+        rmesa->r200Screen->chip_flags &= ~RADEON_CHIPSET_TCL;
+        fprintf(stderr, "Disabling HW TCL support\n");
       }
       }
-      _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
+      TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
    }
    }
+
    return GL_TRUE;
 }
 
    return GL_TRUE;
 }
 
@@ -451,7 +546,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
    /* check if we're deleting the currently bound context */
    if (rmesa == current) {
       R200_FIREVERTICES( rmesa );
    /* 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 */
    }
 
    /* Free r200 context resources */
@@ -463,7 +558,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
       release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
       _swsetup_DestroyContext( rmesa->glCtx );
       _tnl_DestroyContext( rmesa->glCtx );
       release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
       _swsetup_DestroyContext( rmesa->glCtx );
       _tnl_DestroyContext( rmesa->glCtx );
-      _ac_DestroyContext( rmesa->glCtx );
+      _vbo_DestroyContext( rmesa->glCtx );
       _swrast_DestroyContext( rmesa->glCtx );
 
       r200DestroySwtcl( rmesa->glCtx );
       _swrast_DestroyContext( rmesa->glCtx );
 
       r200DestroySwtcl( rmesa->glCtx );
@@ -474,17 +569,9 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
         r200FlushCmdBuf( rmesa, __FUNCTION__ );
       }
 
         r200FlushCmdBuf( rmesa, __FUNCTION__ );
       }
 
-      if (!rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
-        if (!getenv("R200_NO_VTXFMT"))
-           r200VtxfmtDestroy( rmesa->glCtx );
-
-      /* free the Mesa context */
-      rmesa->glCtx->DriverCtx = NULL;
-      _mesa_destroy_context( rmesa->glCtx );
-
       if (rmesa->state.scissor.pClipRects) {
         FREE(rmesa->state.scissor.pClipRects);
       if (rmesa->state.scissor.pClipRects) {
         FREE(rmesa->state.scissor.pClipRects);
-        rmesa->state.scissor.pClipRects = 0;
+        rmesa->state.scissor.pClipRects = NULL;
       }
 
       if ( release_texture_heaps ) {
       }
 
       if ( release_texture_heaps ) {
@@ -492,16 +579,22 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
           * texture object data.
           */
          int i;
           * 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;
          }
 
          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 Mesa context */
+      rmesa->glCtx->DriverCtx = NULL;
+      _mesa_destroy_context( rmesa->glCtx );
+
+      /* free the option cache */
+      driDestroyOptionCache (&rmesa->optionCache);
+
       FREE( rmesa );
    }
 }
       FREE( rmesa );
    }
 }
@@ -523,7 +616,7 @@ r200SwapBuffers( __DRIdrawablePrivate *dPriv )
             r200PageFlip( dPriv );
          }
          else {
             r200PageFlip( dPriv );
          }
          else {
-            r200CopyBuffer( dPriv );
+            r200CopyBuffer( dPriv, NULL );
          }
       }
    }
          }
       }
    }
@@ -533,6 +626,30 @@ r200SwapBuffers( __DRIdrawablePrivate *dPriv )
    }
 }
 
    }
 }
 
+void
+r200CopySubBuffer( __DRIdrawablePrivate *dPriv,
+                  int x, int y, int w, int h )
+{
+   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+      r200ContextPtr rmesa;
+      GLcontext *ctx;
+      rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
+      ctx = rmesa->glCtx;
+      if (ctx->Visual.doubleBufferMode) {
+        drm_clip_rect_t rect;
+        rect.x1 = x + dPriv->x;
+        rect.y1 = (dPriv->h - y - h) + dPriv->y;
+        rect.x2 = rect.x1 + w;
+        rect.y2 = rect.y1 + h;
+         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
+        r200CopyBuffer( dPriv, &rect );
+      }
+   }
+   else {
+      /* XXX this shouldn't be an error but we can't handle it for now */
+      _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
+   }
+}
 
 /* Force the context `c' to be the current context and associate with it
  * buffer `b'.
 
 /* Force the context `c' to be the current context and associate with it
  * buffer `b'.
@@ -547,25 +664,26 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
         (r200ContextPtr) driContextPriv->driverPrivate;
 
       if (R200_DEBUG & DEBUG_DRI)
         (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 ) {
 
       if ( newCtx->dri.drawable != driDrawPriv ) {
-        newCtx->dri.drawable = driDrawPriv;
-        r200UpdateWindow( newCtx->glCtx );
-        r200UpdateViewportOffset( newCtx->glCtx );
+        driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
+                               &newCtx->vbl_seq );
       }
 
       }
 
-      _mesa_make_current2( newCtx->glCtx,
-                          (GLframebuffer *) driDrawPriv->driverPrivate,
-                          (GLframebuffer *) driReadPriv->driverPrivate );
+      newCtx->dri.readable = driReadPriv;
 
 
-      if ( !newCtx->glCtx->Viewport.Width ) {
-        _mesa_set_viewport( newCtx->glCtx, 0, 0,
-                            driDrawPriv->w, driDrawPriv->h );
+      if ( newCtx->dri.drawable != driDrawPriv ||
+           newCtx->lastStamp != driDrawPriv->lastStamp ) {
+        newCtx->dri.drawable = driDrawPriv;
+
+        r200SetCliprects(newCtx);
+        r200UpdateViewportOffset( newCtx->glCtx );
       }
 
       }
 
-      if (newCtx->vb.enabled)
-        r200VtxfmtMakeCurrent( newCtx->glCtx );
+      _mesa_make_current( newCtx->glCtx,
+                         (GLframebuffer *) driDrawPriv->driverPrivate,
+                         (GLframebuffer *) driReadPriv->driverPrivate );
 
       _mesa_update_state( newCtx->glCtx );
       r200ValidateState( newCtx->glCtx );
 
       _mesa_update_state( newCtx->glCtx );
       r200ValidateState( newCtx->glCtx );
@@ -573,7 +691,7 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
    } else {
       if (R200_DEBUG & DEBUG_DRI)
         fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
    } 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)
    }
 
    if (R200_DEBUG & DEBUG_DRI)
@@ -589,8 +707,7 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv )
    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
 
    if (R200_DEBUG & DEBUG_DRI)
    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;
 }
    return GL_TRUE;
 }