(Stephane Marchesin, me) add hyperz support to radeon and r200 drivers. Only fast...
[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     "20041207"
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_fog_coord",
135     "GL_EXT_secondary_color",
136     "GL_EXT_stencil_wrap",
137     "GL_EXT_texture_edge_clamp",
138     "GL_EXT_texture_env_combine",
139     "GL_EXT_texture_env_dot3",
140     "GL_EXT_texture_filter_anisotropic",
141     "GL_EXT_texture_lod_bias",
142     "GL_EXT_texture_mirror_clamp",
143     "GL_EXT_texture_rectangle",
144     "GL_ATI_texture_env_combine3",
145     "GL_ATI_texture_mirror_once",
146     "GL_MESA_pack_invert",
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    &_tnl_vertex_program_stage,
170
171    /* Try again to go to tcl? 
172     *     - no good for asymmetric-twoside (do with multipass)
173     *     - no good for asymmetric-unfilled (do with multipass)
174     *     - good for material
175     *     - good for texgen
176     *     - need to manipulate a bit of state
177     *
178     * - worth it/not worth it?
179     */
180                         
181    /* Else do them here.
182     */
183 /*    &_r200_render_stage,  */ /* FIXME: bugs with ut2003 */
184    &_tnl_render_stage,          /* FALLBACK:  */
185    0,
186 };
187
188
189
190 /* Initialize the driver's misc functions.
191  */
192 static void r200InitDriverFuncs( struct dd_function_table *functions )
193 {
194     functions->GetBufferSize            = r200GetBufferSize;
195     functions->ResizeBuffers           = _swrast_alloc_buffers;
196     functions->GetString                = r200GetString;
197
198     functions->Error                    = NULL;
199     functions->DrawPixels               = NULL;
200     functions->Bitmap                   = NULL;
201 }
202
203 static const struct dri_debug_control debug_control[] =
204 {
205     { "fall",  DEBUG_FALLBACKS },
206     { "tex",   DEBUG_TEXTURE },
207     { "ioctl", DEBUG_IOCTL },
208     { "prim",  DEBUG_PRIMS },
209     { "vert",  DEBUG_VERTS },
210     { "state", DEBUG_STATE },
211     { "code",  DEBUG_CODEGEN },
212     { "vfmt",  DEBUG_VFMT },
213     { "vtxf",  DEBUG_VFMT },
214     { "verb",  DEBUG_VERBOSE },
215     { "dri",   DEBUG_DRI },
216     { "dma",   DEBUG_DMA },
217     { "san",   DEBUG_SANITY },
218     { "sync",  DEBUG_SYNC },
219     { "pix",   DEBUG_PIXEL },
220     { "mem",   DEBUG_MEMORY },
221     { NULL,    0 }
222 };
223
224
225 static int
226 get_ust_nop( int64_t * ust )
227 {
228    *ust = 1;
229    return 0;
230 }
231
232
233 /* Create the device specific rendering context.
234  */
235 GLboolean r200CreateContext( const __GLcontextModes *glVisual,
236                              __DRIcontextPrivate *driContextPriv,
237                              void *sharedContextPrivate)
238 {
239    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
240    r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private);
241    struct dd_function_table functions;
242    r200ContextPtr rmesa;
243    GLcontext *ctx, *shareCtx;
244    int i;
245    int tcl_mode, fthrottle_mode;
246
247    assert(glVisual);
248    assert(driContextPriv);
249    assert(screen);
250
251    /* Allocate the R200 context */
252    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
253    if ( !rmesa )
254       return GL_FALSE;
255       
256    /* init exp fog table data */
257    r200InitStaticFogData();
258
259    /* Parse configuration files.
260     * Do this here so that initialMaxAnisotropy is set before we create
261     * the default textures.
262     */
263    driParseConfigFiles (&rmesa->optionCache, &screen->optionCache,
264                         screen->driScreen->myNum, "r200");
265    rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache,
266                                                  "def_max_anisotropy");
267
268    if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
269       if ( sPriv->drmMinor < 13 )
270          fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
271                           "disabling.\n",sPriv->drmMinor );
272       else
273          rmesa->using_hyperz = GL_TRUE;
274    }
275
276    /* Init default driver functions then plug in our R200-specific functions
277     * (the texture functions are especially important)
278     */
279    _mesa_init_driver_functions(&functions);
280    r200InitDriverFuncs(&functions);
281    r200InitIoctlFuncs(&functions);
282    r200InitStateFuncs(&functions);
283    r200InitTextureFuncs(&functions);
284
285    /* Allocate and initialize the Mesa context */
286    if (sharedContextPrivate)
287       shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
288    else
289       shareCtx = NULL;
290    rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
291                                        &functions, (void *) rmesa);
292    if (!rmesa->glCtx) {
293       FREE(rmesa);
294       return GL_FALSE;
295    }
296    driContextPriv->driverPrivate = rmesa;
297
298    /* Init r200 context data */
299    rmesa->dri.context = driContextPriv;
300    rmesa->dri.screen = sPriv;
301    rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
302    rmesa->dri.hwContext = driContextPriv->hHWContext;
303    rmesa->dri.hwLock = &sPriv->pSAREA->lock;
304    rmesa->dri.fd = sPriv->fd;
305    rmesa->dri.drmMinor = sPriv->drmMinor;
306
307    rmesa->r200Screen = screen;
308    rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
309                                        screen->sarea_priv_offset);
310
311
312    rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address;
313
314    (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
315    make_empty_list( & rmesa->swapped );
316
317    rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
318    assert(rmesa->nr_heaps < R200_NR_TEX_HEAPS);
319    for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
320       rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
321             screen->texSize[i],
322             12,
323             RADEON_NR_TEX_REGIONS,
324             (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
325             & rmesa->sarea->tex_age[i],
326             & rmesa->swapped,
327             sizeof( r200TexObj ),
328             (destroy_texture_object_t *) r200DestroyTexObj );
329    }
330    rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
331                                            "texture_depth");
332    if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
333       rmesa->texture_depth = ( screen->cpp == 4 ) ?
334          DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
335
336    rmesa->swtcl.RenderIndex = ~0;
337    rmesa->hw.all_dirty = 1;
338
339    /* Set the maximum texture size small enough that we can guarentee that
340     * all texture units can bind a maximal texture and have them both in
341     * texturable memory at once.
342     */
343
344    ctx = rmesa->glCtx;
345    ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache,
346                                                  "texture_units");
347    ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
348    ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
349
350    driCalculateMaxTextureLevels( rmesa->texture_heaps,
351                                  rmesa->nr_heaps,
352                                  & ctx->Const,
353                                  4,
354                                  11, /* max 2D texture size is 2048x2048 */
355 #if ENABLE_HW_3D_TEXTURE
356                                  8,  /* max 3D texture size is 256^3 */
357 #else
358                                  0,  /* 3D textures unsupported */
359 #endif
360                                  11, /* max cube texture size is 2048x2048 */
361                                  11, /* max texture rectangle size is 2048x2048 */
362                                  12,
363                                  GL_FALSE );
364
365    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
366
367    /* No wide points.
368     */
369    ctx->Const.MinPointSize = 1.0;
370    ctx->Const.MinPointSizeAA = 1.0;
371    ctx->Const.MaxPointSize = 1.0;
372    ctx->Const.MaxPointSizeAA = 1.0;
373
374    ctx->Const.MinLineWidth = 1.0;
375    ctx->Const.MinLineWidthAA = 1.0;
376    ctx->Const.MaxLineWidth = 10.0;
377    ctx->Const.MaxLineWidthAA = 10.0;
378    ctx->Const.LineWidthGranularity = 0.0625;
379
380    /* Initialize the software rasterizer and helper modules.
381     */
382    _swrast_CreateContext( ctx );
383    _ac_CreateContext( ctx );
384    _tnl_CreateContext( ctx );
385    _swsetup_CreateContext( ctx );
386    _ae_create_context( ctx );
387
388    /* Install the customized pipeline:
389     */
390    _tnl_destroy_pipeline( ctx );
391    _tnl_install_pipeline( ctx, r200_pipeline );
392    ctx->Driver.FlushVertices = r200FlushVertices;
393
394    /* Try and keep materials and vertices separate:
395     */
396    _tnl_isolate_materials( ctx, GL_TRUE );
397
398
399    /* Configure swrast and TNL to match hardware characteristics:
400     */
401    _swrast_allow_pixel_fog( ctx, GL_FALSE );
402    _swrast_allow_vertex_fog( ctx, GL_TRUE );
403    _tnl_allow_pixel_fog( ctx, GL_FALSE );
404    _tnl_allow_vertex_fog( ctx, GL_TRUE );
405
406
407    for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
408       _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
409       _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
410    }
411    _math_matrix_ctr( &rmesa->tmpmat );
412    _math_matrix_set_identity( &rmesa->tmpmat );
413
414    driInitExtensions( ctx, card_extensions, GL_TRUE );
415    if (rmesa->r200Screen->chipset & R200_CHIPSET_REAL_R200) {
416    /* yuv textures only work with r200 chips for unknown reasons, the
417       others get the bit ordering right but don't actually do YUV-RGB conversion */
418       _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
419    }
420    if (rmesa->glCtx->Mesa_DXTn) {
421       _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
422       _mesa_enable_extension( ctx, "GL_S3_s3tc" );
423    }
424    else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) {
425       _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
426    }
427
428    if (rmesa->r200Screen->drmSupportsCubeMaps)
429       _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
430    if (rmesa->r200Screen->drmSupportsBlendColor) {
431       _mesa_enable_extension( ctx, "GL_EXT_blend_equation_separate" );
432       _mesa_enable_extension( ctx, "GL_EXT_blend_func_separate" );
433    }
434    if(driQueryOptionb(&rmesa->optionCache, "arb_vertex_program"))
435       _mesa_enable_extension( ctx, "GL_ARB_vertex_program");
436    if(driQueryOptionb(&rmesa->optionCache, "nv_vertex_program"))
437       _mesa_enable_extension( ctx, "GL_NV_vertex_program");
438
439 #if 0
440    r200InitDriverFuncs( ctx );
441    r200InitIoctlFuncs( ctx );
442    r200InitStateFuncs( ctx );
443    r200InitTextureFuncs( ctx );
444 #endif
445    /* plug in a few more device driver functions */
446    /* XXX these should really go right after _mesa_init_driver_functions() */
447    r200InitPixelFuncs( ctx );
448    r200InitSpanFuncs( ctx );
449    r200InitTnlFuncs( ctx );
450    r200InitState( rmesa );
451    r200InitSwtcl( ctx );
452
453    fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
454    rmesa->iw.irq_seq = -1;
455    rmesa->irqsEmitted = 0;
456    rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && 
457                      fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
458                      rmesa->r200Screen->irq);
459
460    rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
461
462    if (!rmesa->do_irqs)
463       fprintf(stderr,
464               "IRQ's not enabled, falling back to %s: %d %d %d\n",
465               rmesa->do_usleeps ? "usleeps" : "busy waits",
466               rmesa->dri.drmMinor,
467               fthrottle_mode,
468               rmesa->r200Screen->irq);
469
470    rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
471        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
472
473    rmesa->prefer_gart_client_texturing = 
474       (getenv("R200_GART_CLIENT_TEXTURES") != 0);
475
476    rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
477    if ( rmesa->get_ust == NULL ) {
478       rmesa->get_ust = get_ust_nop;
479    }
480    (*rmesa->get_ust)( & rmesa->swap_ust );
481
482
483 #if DO_DEBUG
484    R200_DEBUG  = driParseDebugString( getenv( "R200_DEBUG" ),
485                                       debug_control );
486    R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ),
487                                       debug_control );
488 #endif
489
490    tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
491    if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
492       fprintf(stderr, "disabling 3D acceleration\n");
493       FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
494    }
495    else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
496             !(rmesa->r200Screen->chipset & R200_CHIPSET_TCL)) {
497       if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
498          rmesa->r200Screen->chipset &= ~R200_CHIPSET_TCL;
499          fprintf(stderr, "Disabling HW TCL support\n");
500       }
501       TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
502    }
503    if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
504       if (tcl_mode >= DRI_CONF_TCL_VTXFMT && !getenv("R200_NO_VTXFMT")) {
505          r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
506       }
507       _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
508    }
509    return GL_TRUE;
510 }
511
512
513 /* Destroy the device specific context.
514  */
515 /* Destroy the Mesa and driver specific context data.
516  */
517 void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
518 {
519    GET_CURRENT_CONTEXT(ctx);
520    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
521    r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL;
522
523    /* check if we're deleting the currently bound context */
524    if (rmesa == current) {
525       R200_FIREVERTICES( rmesa );
526       _mesa_make_current2(NULL, NULL, NULL);
527    }
528
529    /* Free r200 context resources */
530    assert(rmesa); /* should never be null */
531    if ( rmesa ) {
532       GLboolean   release_texture_heaps;
533
534
535       release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
536       _swsetup_DestroyContext( rmesa->glCtx );
537       _tnl_DestroyContext( rmesa->glCtx );
538       _ac_DestroyContext( rmesa->glCtx );
539       _swrast_DestroyContext( rmesa->glCtx );
540
541       r200DestroySwtcl( rmesa->glCtx );
542       r200ReleaseArrays( rmesa->glCtx, ~0 );
543
544       if (rmesa->dma.current.buf) {
545          r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
546          r200FlushCmdBuf( rmesa, __FUNCTION__ );
547       }
548
549       if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) {
550          int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
551          if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
552             r200VtxfmtDestroy( rmesa->glCtx );
553       }
554
555       /* free the Mesa context */
556       rmesa->glCtx->DriverCtx = NULL;
557       _mesa_destroy_context( rmesa->glCtx );
558
559       if (rmesa->state.scissor.pClipRects) {
560          FREE(rmesa->state.scissor.pClipRects);
561          rmesa->state.scissor.pClipRects = 0;
562       }
563
564       if ( release_texture_heaps ) {
565          /* This share group is about to go away, free our private
566           * texture object data.
567           */
568          int i;
569
570          for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
571             driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
572             rmesa->texture_heaps[ i ] = NULL;
573          }
574
575          assert( is_empty_list( & rmesa->swapped ) );
576       }
577
578       /* free the option cache */
579       driDestroyOptionCache (&rmesa->optionCache);
580
581       FREE( rmesa );
582    }
583 }
584
585
586
587
588 void
589 r200SwapBuffers( __DRIdrawablePrivate *dPriv )
590 {
591    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
592       r200ContextPtr rmesa;
593       GLcontext *ctx;
594       rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
595       ctx = rmesa->glCtx;
596       if (ctx->Visual.doubleBufferMode) {
597          _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
598          if ( rmesa->doPageFlip ) {
599             r200PageFlip( dPriv );
600          }
601          else {
602             r200CopyBuffer( dPriv );
603          }
604       }
605    }
606    else {
607       /* XXX this shouldn't be an error but we can't handle it for now */
608       _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
609    }
610 }
611
612
613 /* Force the context `c' to be the current context and associate with it
614  * buffer `b'.
615  */
616 GLboolean
617 r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
618                    __DRIdrawablePrivate *driDrawPriv,
619                    __DRIdrawablePrivate *driReadPriv )
620 {
621    if ( driContextPriv ) {
622       r200ContextPtr newCtx = 
623          (r200ContextPtr) driContextPriv->driverPrivate;
624
625       if (R200_DEBUG & DEBUG_DRI)
626          fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
627
628       if ( newCtx->dri.drawable != driDrawPriv ) {
629          driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
630          newCtx->dri.drawable = driDrawPriv;
631          r200UpdateWindow( newCtx->glCtx );
632          r200UpdateViewportOffset( newCtx->glCtx );
633       }
634
635       _mesa_make_current2( newCtx->glCtx,
636                            (GLframebuffer *) driDrawPriv->driverPrivate,
637                            (GLframebuffer *) driReadPriv->driverPrivate );
638
639       if (newCtx->vb.enabled)
640          r200VtxfmtMakeCurrent( newCtx->glCtx );
641
642       _mesa_update_state( newCtx->glCtx );
643       r200ValidateState( newCtx->glCtx );
644
645    } else {
646       if (R200_DEBUG & DEBUG_DRI)
647          fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
648       _mesa_make_current( 0, 0 );
649    }
650
651    if (R200_DEBUG & DEBUG_DRI)
652       fprintf(stderr, "End %s\n", __FUNCTION__);
653    return GL_TRUE;
654 }
655
656 /* Force the context `c' to be unbound from its buffer.
657  */
658 GLboolean
659 r200UnbindContext( __DRIcontextPrivate *driContextPriv )
660 {
661    r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
662
663    if (R200_DEBUG & DEBUG_DRI)
664       fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx);
665
666    r200VtxfmtUnbindContext( rmesa->glCtx );
667    return GL_TRUE;
668 }