add support for more than 2 texture units (max 6, default 4). use hang workarounds...
[profile/ivi/mesa.git] / src / mesa / drivers / dri / r200 / r200_context.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.c,v 1.3 2003/05/06 23:52:08 daenzer Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 /*
32  * Authors:
33  *   Keith Whitwell <keith@tungstengraphics.com>
34  */
35
36 #include "glheader.h"
37 #include "api_arrayelt.h"
38 #include "context.h"
39 #include "simple_list.h"
40 #include "imports.h"
41 #include "matrix.h"
42 #include "extensions.h"
43 #include "state.h"
44
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
47 #include "array_cache/acache.h"
48
49 #include "tnl/tnl.h"
50 #include "tnl/t_pipeline.h"
51
52 #include "drivers/common/driverfuncs.h"
53
54 #include "r200_context.h"
55 #include "r200_ioctl.h"
56 #include "r200_state.h"
57 #include "r200_span.h"
58 #include "r200_pixel.h"
59 #include "r200_tex.h"
60 #include "r200_swtcl.h"
61 #include "r200_tcl.h"
62 #include "r200_vtxfmt.h"
63 #include "r200_maos.h"
64
65 #define DRIVER_DATE     "20030328"
66
67 #include "vblank.h"
68 #include "utils.h"
69 #include "xmlpool.h" /* for symbolic values of enum-type options */
70 #ifndef R200_DEBUG
71 int R200_DEBUG = (0);
72 #endif
73
74
75 /* Return the width and height of the given buffer.
76  */
77 static void r200GetBufferSize( GLframebuffer *buffer,
78                                GLuint *width, GLuint *height )
79 {
80    GET_CURRENT_CONTEXT(ctx);
81    r200ContextPtr rmesa = R200_CONTEXT(ctx);
82
83    LOCK_HARDWARE( rmesa );
84    *width  = rmesa->dri.drawable->w;
85    *height = rmesa->dri.drawable->h;
86    UNLOCK_HARDWARE( rmesa );
87 }
88
89 /* Return various strings for glGetString().
90  */
91 static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
92 {
93    r200ContextPtr rmesa = R200_CONTEXT(ctx);
94    static char buffer[128];
95    unsigned   offset;
96    GLuint agp_mode = rmesa->r200Screen->IsPCI ? 0 :
97       rmesa->r200Screen->AGPMode;
98
99    switch ( name ) {
100    case GL_VENDOR:
101       return (GLubyte *)"Tungsten Graphics, Inc.";
102
103    case GL_RENDERER:
104       offset = driGetRendererString( buffer, "R200", DRIVER_DATE,
105                                      agp_mode );
106
107       sprintf( & buffer[ offset ], " %sTCL",
108                !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
109                ? "" : "NO-" );
110
111       return (GLubyte *)buffer;
112
113    default:
114       return NULL;
115    }
116 }
117
118
119 /* Extension strings exported by the R200 driver.
120  */
121 static const char * const card_extensions[] =
122 {
123     "GL_ARB_multisample",
124     "GL_ARB_multitexture",
125     "GL_ARB_texture_border_clamp",
126     "GL_ARB_texture_compression",
127     "GL_ARB_texture_env_add",
128     "GL_ARB_texture_env_combine",
129     "GL_ARB_texture_env_dot3",
130     "GL_ARB_texture_mirrored_repeat",
131     "GL_ARB_vertex_buffer_object",
132     "GL_EXT_blend_minmax",
133     "GL_EXT_blend_subtract",
134     "GL_EXT_secondary_color",
135     "GL_EXT_stencil_wrap",
136     "GL_EXT_texture_edge_clamp",
137     "GL_EXT_texture_env_combine",
138     "GL_EXT_texture_env_dot3",
139     "GL_EXT_texture_filter_anisotropic",
140     "GL_EXT_texture_lod_bias",
141     "GL_EXT_texture_mirror_clamp",
142     "GL_EXT_texture_rectangle",
143     "GL_ATI_texture_env_combine3",
144     "GL_ATI_texture_mirror_once",
145     "GL_MESA_pack_invert",
146     "GL_MESA_ycbcr_texture",
147     "GL_NV_blend_square",
148     "GL_SGIS_generate_mipmap",
149     NULL
150 };
151
152 extern const struct tnl_pipeline_stage _r200_render_stage;
153 extern const struct tnl_pipeline_stage _r200_tcl_stage;
154
155 static const struct tnl_pipeline_stage *r200_pipeline[] = {
156
157    /* Try and go straight to t&l
158     */
159    &_r200_tcl_stage,  
160
161    /* Catch any t&l fallbacks
162     */
163    &_tnl_vertex_transform_stage,
164    &_tnl_normal_transform_stage,
165    &_tnl_lighting_stage,
166    &_tnl_fog_coordinate_stage,
167    &_tnl_texgen_stage,
168    &_tnl_texture_transform_stage,
169
170    /* Try again to go to tcl? 
171     *     - no good for asymmetric-twoside (do with multipass)
172     *     - no good for asymmetric-unfilled (do with multipass)
173     *     - good for material
174     *     - good for texgen
175     *     - need to manipulate a bit of state
176     *
177     * - worth it/not worth it?
178     */
179                         
180    /* Else do them here.
181     */
182 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
183    &_tnl_render_stage,          /* FALLBACK:  */
184    0,
185 };
186
187
188
189 /* Initialize the driver's misc functions.
190  */
191 static void r200InitDriverFuncs( struct dd_function_table *functions )
192 {
193     functions->GetBufferSize            = r200GetBufferSize;
194     functions->ResizeBuffers           = _swrast_alloc_buffers;
195     functions->GetString                = r200GetString;
196
197     functions->Error                    = NULL;
198     functions->DrawPixels               = NULL;
199     functions->Bitmap                   = NULL;
200 }
201
202 static const struct dri_debug_control debug_control[] =
203 {
204     { "fall",  DEBUG_FALLBACKS },
205     { "tex",   DEBUG_TEXTURE },
206     { "ioctl", DEBUG_IOCTL },
207     { "prim",  DEBUG_PRIMS },
208     { "vert",  DEBUG_VERTS },
209     { "state", DEBUG_STATE },
210     { "code",  DEBUG_CODEGEN },
211     { "vfmt",  DEBUG_VFMT },
212     { "vtxf",  DEBUG_VFMT },
213     { "verb",  DEBUG_VERBOSE },
214     { "dri",   DEBUG_DRI },
215     { "dma",   DEBUG_DMA },
216     { "san",   DEBUG_SANITY },
217     { "sync",  DEBUG_SYNC },
218     { "pix",   DEBUG_PIXEL },
219     { "mem",   DEBUG_MEMORY },
220     { NULL,    0 }
221 };
222
223
224 static int
225 get_ust_nop( int64_t * ust )
226 {
227    *ust = 1;
228    return 0;
229 }
230
231
232 /* Create the device specific rendering context.
233  */
234 GLboolean r200CreateContext( const __GLcontextModes *glVisual,
235                              __DRIcontextPrivate *driContextPriv,
236                              void *sharedContextPrivate)
237 {
238    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
239    r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private);
240    struct dd_function_table functions;
241    r200ContextPtr rmesa;
242    GLcontext *ctx, *shareCtx;
243    int i;
244    int tcl_mode, fthrottle_mode;
245
246    assert(glVisual);
247    assert(driContextPriv);
248    assert(screen);
249
250    /* Allocate the R200 context */
251    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
252    if ( !rmesa )
253       return GL_FALSE;
254
255    /* Parse configuration files.
256     * Do this here so that initialMaxAnisotropy is set before we create
257     * the default textures.
258     */
259    driParseConfigFiles (&rmesa->optionCache, &screen->optionCache,
260                         screen->driScreen->myNum, "r200");
261    rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache,
262                                                  "def_max_anisotropy");
263
264    /* Init default driver functions then plug in our R200-specific functions
265     * (the texture functions are especially important)
266     */
267    _mesa_init_driver_functions(&functions);
268    r200InitDriverFuncs(&functions);
269    r200InitIoctlFuncs(&functions);
270    r200InitStateFuncs(&functions);
271    r200InitTextureFuncs(&functions);
272
273    /* Allocate and initialize the Mesa context */
274    if (sharedContextPrivate)
275       shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
276    else
277       shareCtx = NULL;
278    rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
279                                        &functions, (void *) rmesa);
280    if (!rmesa->glCtx) {
281       FREE(rmesa);
282       return GL_FALSE;
283    }
284    driContextPriv->driverPrivate = rmesa;
285
286    /* Init r200 context data */
287    rmesa->dri.context = driContextPriv;
288    rmesa->dri.screen = sPriv;
289    rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
290    rmesa->dri.hwContext = driContextPriv->hHWContext;
291    rmesa->dri.hwLock = &sPriv->pSAREA->lock;
292    rmesa->dri.fd = sPriv->fd;
293    rmesa->dri.drmMinor = sPriv->drmMinor;
294
295    rmesa->r200Screen = screen;
296    rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
297                                        screen->sarea_priv_offset);
298
299
300    rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address;
301
302    (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
303    make_empty_list( & rmesa->swapped );
304
305    rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
306    assert(rmesa->nr_heaps < R200_NR_TEX_HEAPS);
307    for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
308       rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
309             screen->texSize[i],
310             12,
311             RADEON_NR_TEX_REGIONS,
312             (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
313             & rmesa->sarea->tex_age[i],
314             & rmesa->swapped,
315             sizeof( r200TexObj ),
316             (destroy_texture_object_t *) r200DestroyTexObj );
317    }
318    rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
319                                            "texture_depth");
320    if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
321       rmesa->texture_depth = ( screen->cpp == 4 ) ?
322          DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
323
324    rmesa->swtcl.RenderIndex = ~0;
325    rmesa->lost_context = 1;
326
327    /* Set the maximum texture size small enough that we can guarentee that
328     * all texture units can bind a maximal texture and have them both in
329     * texturable memory at once.
330     */
331
332    ctx = rmesa->glCtx;
333    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache,
334                                                  "texture_units");
335    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
336    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
337
338    driCalculateMaxTextureLevels( rmesa->texture_heaps,
339                                  rmesa->nr_heaps,
340                                  & ctx->Const,
341                                  4,
342                                  11, /* max 2D texture size is 2048x2048 */
343 #if ENABLE_HW_3D_TEXTURE
344                                  8,  /* max 3D texture size is 256^3 */
345 #else
346                                  0,  /* 3D textures unsupported */
347 #endif
348                                  11, /* max cube texture size is 2048x2048 */
349                                  11, /* max texture rectangle size is 2048x2048 */
350                                  12,
351                                  GL_FALSE );
352
353    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
354
355    /* No wide points.
356     */
357    ctx->Const.MinPointSize = 1.0;
358    ctx->Const.MinPointSizeAA = 1.0;
359    ctx->Const.MaxPointSize = 1.0;
360    ctx->Const.MaxPointSizeAA = 1.0;
361
362    ctx->Const.MinLineWidth = 1.0;
363    ctx->Const.MinLineWidthAA = 1.0;
364    ctx->Const.MaxLineWidth = 10.0;
365    ctx->Const.MaxLineWidthAA = 10.0;
366    ctx->Const.LineWidthGranularity = 0.0625;
367
368    /* Initialize the software rasterizer and helper modules.
369     */
370    _swrast_CreateContext( ctx );
371    _ac_CreateContext( ctx );
372    _tnl_CreateContext( ctx );
373    _swsetup_CreateContext( ctx );
374    _ae_create_context( ctx );
375
376    /* Install the customized pipeline:
377     */
378    _tnl_destroy_pipeline( ctx );
379    _tnl_install_pipeline( ctx, r200_pipeline );
380    ctx->Driver.FlushVertices = r200FlushVertices;
381
382    /* Try and keep materials and vertices separate:
383     */
384    _tnl_isolate_materials( ctx, GL_TRUE );
385
386
387    /* Configure swrast and TNL to match hardware characteristics:
388     */
389    _swrast_allow_pixel_fog( ctx, GL_FALSE );
390    _swrast_allow_vertex_fog( ctx, GL_TRUE );
391    _tnl_allow_pixel_fog( ctx, GL_FALSE );
392    _tnl_allow_vertex_fog( ctx, GL_TRUE );
393
394
395    for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
396       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
397       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
398    }
399    _math_matrix_ctr( &rmesa->tmpmat );
400    _math_matrix_set_identity( &rmesa->tmpmat );
401
402    driInitExtensions( ctx, card_extensions, GL_TRUE );
403    if (rmesa->r200Screen->drmSupportsCubeMaps)
404       _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
405    if (rmesa->r200Screen->drmSupportsBlendColor) {
406       _mesa_enable_extension( ctx, "GL_EXT_blend_equation_separate" );
407       _mesa_enable_extension( ctx, "GL_EXT_blend_func_separate" );
408    }
409
410 #if 0
411    r200InitDriverFuncs( ctx );
412    r200InitIoctlFuncs( ctx );
413    r200InitStateFuncs( ctx );
414    r200InitTextureFuncs( ctx );
415 #endif
416    /* plug in a few more device driver functions */
417    /* XXX these should really go right after _mesa_init_driver_functions() */
418    r200InitPixelFuncs( ctx );
419    r200InitSpanFuncs( ctx );
420    r200InitTnlFuncs( ctx );
421    r200InitState( rmesa );
422    r200InitSwtcl( ctx );
423
424    fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
425    rmesa->iw.irq_seq = -1;
426    rmesa->irqsEmitted = 0;
427    rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && 
428                      fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
429                      rmesa->r200Screen->irq);
430
431    rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
432
433    if (!rmesa->do_irqs)
434       fprintf(stderr,
435               "IRQ's not enabled, falling back to %s: %d %d %d\n",
436               rmesa->do_usleeps ? "usleeps" : "busy waits",
437               rmesa->dri.drmMinor,
438               fthrottle_mode,
439               rmesa->r200Screen->irq);
440
441    rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
442        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
443
444    rmesa->prefer_gart_client_texturing = 
445       (getenv("R200_GART_CLIENT_TEXTURES") != 0);
446 #ifndef _SOLO   
447    rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
448    if ( rmesa->get_ust == NULL ) {
449       rmesa->get_ust = get_ust_nop;
450    }
451 #else
452    rmesa->get_ust = get_ust_nop;
453 #endif
454    (*rmesa->get_ust)( & rmesa->swap_ust );
455
456
457 #if DO_DEBUG
458    R200_DEBUG  = driParseDebugString( getenv( "R200_DEBUG" ),
459                                       debug_control );
460    R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ),
461                                       debug_control );
462 #endif
463
464    tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
465    if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
466       fprintf(stderr, "disabling 3D acceleration\n");
467       FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
468    }
469    else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
470             !(rmesa->r200Screen->chipset & R200_CHIPSET_TCL)) {
471       if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
472          rmesa->r200Screen->chipset &= ~R200_CHIPSET_TCL;
473          fprintf(stderr, "Disabling HW TCL support\n");
474       }
475       TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
476    }
477    if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
478       if (tcl_mode >= DRI_CONF_TCL_VTXFMT && !getenv("R200_NO_VTXFMT")) {
479          r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
480       }
481       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
482    }
483    return GL_TRUE;
484 }
485
486
487 /* Destroy the device specific context.
488  */
489 /* Destroy the Mesa and driver specific context data.
490  */
491 void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
492 {
493    GET_CURRENT_CONTEXT(ctx);
494    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
495    r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL;
496
497    /* check if we're deleting the currently bound context */
498    if (rmesa == current) {
499       R200_FIREVERTICES( rmesa );
500       _mesa_make_current2(NULL, NULL, NULL);
501    }
502
503    /* Free r200 context resources */
504    assert(rmesa); /* should never be null */
505    if ( rmesa ) {
506       GLboolean   release_texture_heaps;
507
508
509       release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
510       _swsetup_DestroyContext( rmesa->glCtx );
511       _tnl_DestroyContext( rmesa->glCtx );
512       _ac_DestroyContext( rmesa->glCtx );
513       _swrast_DestroyContext( rmesa->glCtx );
514
515       r200DestroySwtcl( rmesa->glCtx );
516       r200ReleaseArrays( rmesa->glCtx, ~0 );
517
518       if (rmesa->dma.current.buf) {
519          r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
520          r200FlushCmdBuf( rmesa, __FUNCTION__ );
521       }
522
523       if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) {
524          int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
525          if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
526             r200VtxfmtDestroy( rmesa->glCtx );
527       }
528
529       /* free the Mesa context */
530       rmesa->glCtx->DriverCtx = NULL;
531       _mesa_destroy_context( rmesa->glCtx );
532
533       if (rmesa->state.scissor.pClipRects) {
534          FREE(rmesa->state.scissor.pClipRects);
535          rmesa->state.scissor.pClipRects = 0;
536       }
537
538       if ( release_texture_heaps ) {
539          /* This share group is about to go away, free our private
540           * texture object data.
541           */
542          int i;
543
544          for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
545             driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
546             rmesa->texture_heaps[ i ] = NULL;
547          }
548
549          assert( is_empty_list( & rmesa->swapped ) );
550       }
551
552       /* free the option cache */
553       driDestroyOptionCache (&rmesa->optionCache);
554
555       FREE( rmesa );
556    }
557 }
558
559
560
561
562 void
563 r200SwapBuffers( __DRIdrawablePrivate *dPriv )
564 {
565    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
566       r200ContextPtr rmesa;
567       GLcontext *ctx;
568       rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
569       ctx = rmesa->glCtx;
570       if (ctx->Visual.doubleBufferMode) {
571          _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
572          if ( rmesa->doPageFlip ) {
573             r200PageFlip( dPriv );
574          }
575          else {
576             r200CopyBuffer( dPriv );
577          }
578       }
579    }
580    else {
581       /* XXX this shouldn't be an error but we can't handle it for now */
582       _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
583    }
584 }
585
586
587 /* Force the context `c' to be the current context and associate with it
588  * buffer `b'.
589  */
590 GLboolean
591 r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
592                    __DRIdrawablePrivate *driDrawPriv,
593                    __DRIdrawablePrivate *driReadPriv )
594 {
595    if ( driContextPriv ) {
596       r200ContextPtr newCtx = 
597          (r200ContextPtr) driContextPriv->driverPrivate;
598
599       if (R200_DEBUG & DEBUG_DRI)
600          fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
601
602       if ( newCtx->dri.drawable != driDrawPriv ) {
603          driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
604          newCtx->dri.drawable = driDrawPriv;
605          r200UpdateWindow( newCtx->glCtx );
606          r200UpdateViewportOffset( newCtx->glCtx );
607       }
608
609       _mesa_make_current2( newCtx->glCtx,
610                            (GLframebuffer *) driDrawPriv->driverPrivate,
611                            (GLframebuffer *) driReadPriv->driverPrivate );
612
613       if ( !newCtx->glCtx->Viewport.Width ) {
614          _mesa_set_viewport( newCtx->glCtx, 0, 0,
615                              driDrawPriv->w, driDrawPriv->h );
616       }
617
618       if (newCtx->vb.enabled)
619          r200VtxfmtMakeCurrent( newCtx->glCtx );
620
621       _mesa_update_state( newCtx->glCtx );
622       r200ValidateState( newCtx->glCtx );
623
624    } else {
625       if (R200_DEBUG & DEBUG_DRI)
626          fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
627       _mesa_make_current( 0, 0 );
628    }
629
630    if (R200_DEBUG & DEBUG_DRI)
631       fprintf(stderr, "End %s\n", __FUNCTION__);
632    return GL_TRUE;
633 }
634
635 /* Force the context `c' to be unbound from its buffer.
636  */
637 GLboolean
638 r200UnbindContext( __DRIcontextPrivate *driContextPriv )
639 {
640    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
641
642    if (R200_DEBUG & DEBUG_DRI)
643       fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx);
644
645    r200VtxfmtUnbindContext( rmesa->glCtx );
646    return GL_TRUE;
647 }