radeon_context.c revision 8a1df968627de01d04f3d692fd81108ba6492c18
1/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.9 2003/09/24 02:43:12 dawes Exp $ */
2/**************************************************************************
3
4Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5                     VA Linux Systems Inc., Fremont, California.
6
7All Rights Reserved.
8
9Permission is hereby granted, free of charge, to any person obtaining
10a copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sublicense, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice (including the
18next paragraph) shall be included in all copies or substantial
19portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29**************************************************************************/
30
31/*
32 * Authors:
33 *   Kevin E. Martin <martin@valinux.com>
34 *   Gareth Hughes <gareth@valinux.com>
35 *   Keith Whitwell <keith@tungstengraphics.com>
36 */
37
38#include "glheader.h"
39#include "api_arrayelt.h"
40#include "context.h"
41#include "simple_list.h"
42#include "imports.h"
43#include "matrix.h"
44#include "extensions.h"
45#include "framebuffer.h"
46
47#include "swrast/swrast.h"
48#include "swrast_setup/swrast_setup.h"
49#include "array_cache/acache.h"
50
51#include "tnl/tnl.h"
52#include "tnl/t_pipeline.h"
53
54#include "drivers/common/driverfuncs.h"
55
56#include "radeon_context.h"
57#include "radeon_ioctl.h"
58#include "radeon_state.h"
59#include "radeon_span.h"
60#include "radeon_tex.h"
61#include "radeon_swtcl.h"
62#include "radeon_tcl.h"
63#include "radeon_vtxfmt.h"
64#include "radeon_maos.h"
65
66#define DRIVER_DATE	"20050528"
67
68#include "vblank.h"
69#include "utils.h"
70#include "xmlpool.h" /* for symbolic values of enum-type options */
71#ifndef RADEON_DEBUG
72int RADEON_DEBUG = (0);
73#endif
74
75
76/* Return the width and height of the given buffer.
77 */
78static void radeonGetBufferSize( GLframebuffer *buffer,
79				 GLuint *width, GLuint *height )
80{
81   GET_CURRENT_CONTEXT(ctx);
82   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
83
84   LOCK_HARDWARE( rmesa );
85   *width  = rmesa->dri.drawable->w;
86   *height = rmesa->dri.drawable->h;
87   UNLOCK_HARDWARE( rmesa );
88}
89
90/* Return various strings for glGetString().
91 */
92static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name )
93{
94   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
95   static char buffer[128];
96   unsigned   offset;
97   GLuint agp_mode = rmesa->radeonScreen->IsPCI ? 0 :
98      rmesa->radeonScreen->AGPMode;
99
100   switch ( name ) {
101   case GL_VENDOR:
102      return (GLubyte *)"Tungsten Graphics, Inc.";
103
104   case GL_RENDERER:
105      offset = driGetRendererString( buffer, "Radeon", DRIVER_DATE,
106				     agp_mode );
107
108      sprintf( & buffer[ offset ], " %sTCL",
109	       !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)
110	       ? "" : "NO-" );
111
112      return (GLubyte *)buffer;
113
114   default:
115      return NULL;
116   }
117}
118
119
120/* Extension strings exported by the R100 driver.
121 */
122static const char * const card_extensions[] =
123{
124    "GL_ARB_multisample",
125    "GL_ARB_multitexture",
126    "GL_ARB_texture_border_clamp",
127    "GL_ARB_texture_compression",
128    "GL_ARB_texture_env_add",
129    "GL_ARB_texture_env_combine",
130    "GL_ARB_texture_env_crossbar",
131    "GL_ARB_texture_env_dot3",
132    "GL_ARB_texture_mirrored_repeat",
133    "GL_EXT_blend_logic_op",
134    "GL_EXT_blend_subtract",
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_ATI_texture_env_combine3",
144    "GL_ATI_texture_mirror_once",
145    "GL_MESA_ycbcr_texture",
146    "GL_NV_blend_square",
147    "GL_SGIS_generate_mipmap",
148    NULL
149};
150
151extern const struct tnl_pipeline_stage _radeon_texrect_stage;
152extern const struct tnl_pipeline_stage _radeon_render_stage;
153extern const struct tnl_pipeline_stage _radeon_tcl_stage;
154
155static const struct tnl_pipeline_stage *radeon_pipeline[] = {
156
157   /* Try and go straight to t&l
158    */
159   &_radeon_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   /* Scale texture rectangle to 0..1.
171    */
172   &_radeon_texrect_stage,
173
174   &_radeon_render_stage,
175   &_tnl_render_stage,		/* FALLBACK:  */
176   NULL,
177};
178
179
180
181/* Initialize the driver's misc functions.
182 */
183static void radeonInitDriverFuncs( struct dd_function_table *functions )
184{
185    functions->GetBufferSize	= radeonGetBufferSize;
186    functions->ResizeBuffers	= _mesa_resize_framebuffer;
187    functions->GetString	= radeonGetString;
188}
189
190static const struct dri_debug_control debug_control[] =
191{
192    { "fall",  DEBUG_FALLBACKS },
193    { "tex",   DEBUG_TEXTURE },
194    { "ioctl", DEBUG_IOCTL },
195    { "prim",  DEBUG_PRIMS },
196    { "vert",  DEBUG_VERTS },
197    { "state", DEBUG_STATE },
198    { "code",  DEBUG_CODEGEN },
199    { "vfmt",  DEBUG_VFMT },
200    { "vtxf",  DEBUG_VFMT },
201    { "verb",  DEBUG_VERBOSE },
202    { "dri",   DEBUG_DRI },
203    { "dma",   DEBUG_DMA },
204    { "san",   DEBUG_SANITY },
205    { "sync",  DEBUG_SYNC },
206    { NULL,    0 }
207};
208
209
210static int
211get_ust_nop( int64_t * ust )
212{
213   *ust = 1;
214   return 0;
215}
216
217
218/* Create the device specific context.
219 */
220GLboolean
221radeonCreateContext( const __GLcontextModes *glVisual,
222                     __DRIcontextPrivate *driContextPriv,
223                     void *sharedContextPrivate)
224{
225   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
226   radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
227   struct dd_function_table functions;
228   radeonContextPtr rmesa;
229   GLcontext *ctx, *shareCtx;
230   int i;
231   int tcl_mode, fthrottle_mode;
232
233   assert(glVisual);
234   assert(driContextPriv);
235   assert(screen);
236
237   /* Allocate the Radeon context */
238   rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) );
239   if ( !rmesa )
240      return GL_FALSE;
241
242   /* Parse configuration files.
243    * Do this here so that initialMaxAnisotropy is set before we create
244    * the default textures.
245    */
246   driParseConfigFiles (&rmesa->optionCache, &screen->optionCache,
247			screen->driScreen->myNum, "radeon");
248   rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache,
249                                                 "def_max_anisotropy");
250
251   if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
252      if ( sPriv->drmMinor < 13 )
253	 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
254			  "disabling.\n",sPriv->drmMinor );
255      else
256	 rmesa->using_hyperz = GL_TRUE;
257   }
258
259   if ( sPriv->drmMinor >= 15 )
260      rmesa->texmicrotile = GL_TRUE;
261
262   /* Init default driver functions then plug in our Radeon-specific functions
263    * (the texture functions are especially important)
264    */
265   _mesa_init_driver_functions( &functions );
266   radeonInitDriverFuncs( &functions );
267   radeonInitTextureFuncs( &functions );
268
269   /* Allocate the Mesa context */
270   if (sharedContextPrivate)
271      shareCtx = ((radeonContextPtr) sharedContextPrivate)->glCtx;
272   else
273      shareCtx = NULL;
274   rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
275                                       &functions, (void *) rmesa);
276   if (!rmesa->glCtx) {
277      FREE(rmesa);
278      return GL_FALSE;
279   }
280   driContextPriv->driverPrivate = rmesa;
281
282   /* Init radeon context data */
283   rmesa->dri.context = driContextPriv;
284   rmesa->dri.screen = sPriv;
285   rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
286   rmesa->dri.hwContext = driContextPriv->hHWContext;
287   rmesa->dri.hwLock = &sPriv->pSAREA->lock;
288   rmesa->dri.fd = sPriv->fd;
289   rmesa->dri.drmMinor = sPriv->drmMinor;
290
291   rmesa->radeonScreen = screen;
292   rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
293				       screen->sarea_priv_offset);
294
295
296   rmesa->dma.buf0_address = rmesa->radeonScreen->buffers->list[0].address;
297
298   (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
299   make_empty_list( & rmesa->swapped );
300
301   rmesa->nr_heaps = screen->numTexHeaps;
302   for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
303      rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
304	    screen->texSize[i],
305	    12,
306	    RADEON_NR_TEX_REGIONS,
307	    (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
308	    & rmesa->sarea->tex_age[i],
309	    & rmesa->swapped,
310	    sizeof( radeonTexObj ),
311	    (destroy_texture_object_t *) radeonDestroyTexObj );
312
313      driSetTextureSwapCounterLocation( rmesa->texture_heaps[i],
314					& rmesa->c_textureSwaps );
315   }
316   rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
317					   "texture_depth");
318   if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
319      rmesa->texture_depth = ( screen->cpp == 4 ) ?
320	 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
321
322   rmesa->swtcl.RenderIndex = ~0;
323   rmesa->hw.all_dirty = GL_TRUE;
324
325   /* Set the maximum texture size small enough that we can guarentee that
326    * all texture units can bind a maximal texture and have them both in
327    * texturable memory at once.
328    */
329
330   ctx = rmesa->glCtx;
331   ctx->Const.MaxTextureUnits = 2;
332   ctx->Const.MaxTextureImageUnits = 2;
333   ctx->Const.MaxTextureCoordUnits = 2;
334
335   driCalculateMaxTextureLevels( rmesa->texture_heaps,
336				 rmesa->nr_heaps,
337				 & ctx->Const,
338				 4,
339				 11, /* max 2D texture size is 2048x2048 */
340				 0,  /* 3D textures unsupported. */
341				 0,  /* cube textures unsupported. */
342				 11, /* max rect texture size is 2048x2048. */
343				 12,
344				 GL_FALSE );
345
346   /* adjust max texture size a bit. Hack, but I really want to use larger textures
347      which will work just fine in 99.999999% of all cases, especially with texture compression... */
348   if (driQueryOptionb( &rmesa->optionCache, "texture_level_hack" ))
349   {
350     if (ctx->Const.MaxTextureLevels < 12) ctx->Const.MaxTextureLevels += 1;
351   }
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   /* Set maxlocksize (and hence vb size) small enough to avoid
369    * fallbacks in radeon_tcl.c.  ie. guarentee that all vertices can
370    * fit in a single dma buffer for indexed rendering of quad strips,
371    * etc.
372    */
373   ctx->Const.MaxArrayLockSize =
374      MIN2( ctx->Const.MaxArrayLockSize,
375 	    RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE );
376
377   rmesa->boxes = 0;
378
379   /* Initialize the software rasterizer and helper modules.
380    */
381   _swrast_CreateContext( ctx );
382   _ac_CreateContext( ctx );
383   _tnl_CreateContext( ctx );
384   _swsetup_CreateContext( ctx );
385   _ae_create_context( ctx );
386
387   /* Install the customized pipeline:
388    */
389   _tnl_destroy_pipeline( ctx );
390   _tnl_install_pipeline( ctx, radeon_pipeline );
391   ctx->Driver.FlushVertices = radeonFlushVertices;
392
393   /* Try and keep materials and vertices separate:
394    */
395   _tnl_isolate_materials( ctx, GL_TRUE );
396
397/*     _mesa_allow_light_in_model( ctx, GL_FALSE ); */
398
399   /* Configure swrast and T&L 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   _math_matrix_ctr( &rmesa->TexGenMatrix[0] );
408   _math_matrix_ctr( &rmesa->TexGenMatrix[1] );
409   _math_matrix_ctr( &rmesa->tmpmat );
410   _math_matrix_set_identity( &rmesa->TexGenMatrix[0] );
411   _math_matrix_set_identity( &rmesa->TexGenMatrix[1] );
412   _math_matrix_set_identity( &rmesa->tmpmat );
413
414   driInitExtensions( ctx, card_extensions, GL_TRUE );
415   if (rmesa->glCtx->Mesa_DXTn) {
416      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
417      _mesa_enable_extension( ctx, "GL_S3_s3tc" );
418   }
419   else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) {
420      _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
421   }
422
423   if (rmesa->dri.drmMinor >= 9)
424      _mesa_enable_extension( ctx, "GL_NV_texture_rectangle");
425
426   /* XXX these should really go right after _mesa_init_driver_functions() */
427   radeonInitIoctlFuncs( ctx );
428   radeonInitStateFuncs( ctx );
429   radeonInitSpanFuncs( ctx );
430   radeonInitState( rmesa );
431   radeonInitSwtcl( ctx );
432
433   _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0,
434			 ctx->Const.MaxArrayLockSize, 32 );
435
436   fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
437   rmesa->iw.irq_seq = -1;
438   rmesa->irqsEmitted = 0;
439   rmesa->do_irqs = (rmesa->radeonScreen->irq != 0 &&
440		     fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
441
442   rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
443
444   rmesa->vblank_flags = (rmesa->radeonScreen->irq != 0)
445       ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
446
447   rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
448   if ( rmesa->get_ust == NULL ) {
449      rmesa->get_ust = get_ust_nop;
450   }
451   (*rmesa->get_ust)( & rmesa->swap_ust );
452
453
454#if DO_DEBUG
455   RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ),
456				       debug_control );
457#endif
458
459   tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
460   if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
461      fprintf(stderr, "disabling 3D acceleration\n");
462      FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
463   } else if (tcl_mode == DRI_CONF_TCL_SW ||
464	      !(rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL)) {
465      if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) {
466	 rmesa->radeonScreen->chipset &= ~RADEON_CHIPSET_TCL;
467	 fprintf(stderr, "Disabling HW TCL support\n");
468      }
469      TCL_FALLBACK(rmesa->glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
470   }
471
472   if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_TCL) {
473      if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
474	 radeonVtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
475
476      _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
477   }
478   return GL_TRUE;
479}
480
481
482/* Destroy the device specific context.
483 */
484/* Destroy the Mesa and driver specific context data.
485 */
486void radeonDestroyContext( __DRIcontextPrivate *driContextPriv )
487{
488   GET_CURRENT_CONTEXT(ctx);
489   radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate;
490   radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
491
492   /* check if we're deleting the currently bound context */
493   if (rmesa == current) {
494      RADEON_FIREVERTICES( rmesa );
495      _mesa_make_current(NULL, NULL, NULL);
496   }
497
498   /* Free radeon context resources */
499   assert(rmesa); /* should never be null */
500   if ( rmesa ) {
501      GLboolean   release_texture_heaps;
502
503
504      release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
505      _swsetup_DestroyContext( rmesa->glCtx );
506      _tnl_DestroyContext( rmesa->glCtx );
507      _ac_DestroyContext( rmesa->glCtx );
508      _swrast_DestroyContext( rmesa->glCtx );
509
510      radeonDestroySwtcl( rmesa->glCtx );
511      radeonReleaseArrays( rmesa->glCtx, ~0 );
512      if (rmesa->dma.current.buf) {
513	 radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
514	 radeonFlushCmdBuf( rmesa, __FUNCTION__ );
515      }
516
517      if (!(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)) {
518	 int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
519	 if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
520	    radeonVtxfmtDestroy( rmesa->glCtx );
521      }
522
523      /* free the Mesa context */
524      rmesa->glCtx->DriverCtx = NULL;
525      _mesa_destroy_context( rmesa->glCtx );
526
527      _mesa_vector4f_free( &rmesa->tcl.ObjClean );
528
529      if (rmesa->state.scissor.pClipRects) {
530	 FREE(rmesa->state.scissor.pClipRects);
531	 rmesa->state.scissor.pClipRects = NULL;
532      }
533
534      if ( release_texture_heaps ) {
535         /* This share group is about to go away, free our private
536          * texture object data.
537          */
538         int i;
539
540         for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
541	    driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
542	    rmesa->texture_heaps[ i ] = NULL;
543         }
544
545	 assert( is_empty_list( & rmesa->swapped ) );
546      }
547
548      /* free the option cache */
549      driDestroyOptionCache (&rmesa->optionCache);
550
551      FREE( rmesa );
552   }
553}
554
555
556
557
558void
559radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
560{
561
562   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
563      radeonContextPtr rmesa;
564      GLcontext *ctx;
565      rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
566      ctx = rmesa->glCtx;
567      if (ctx->Visual.doubleBufferMode) {
568         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
569
570         if ( rmesa->doPageFlip ) {
571            radeonPageFlip( dPriv );
572         }
573         else {
574            radeonCopyBuffer( dPriv );
575         }
576      }
577   }
578   else {
579      /* XXX this shouldn't be an error but we can't handle it for now */
580      _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
581   }
582}
583
584
585/* Force the context `c' to be the current context and associate with it
586 * buffer `b'.
587 */
588GLboolean
589radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
590                   __DRIdrawablePrivate *driDrawPriv,
591                   __DRIdrawablePrivate *driReadPriv )
592{
593   if ( driContextPriv ) {
594      radeonContextPtr newCtx =
595	 (radeonContextPtr) driContextPriv->driverPrivate;
596
597      if (RADEON_DEBUG & DEBUG_DRI)
598	 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) newCtx->glCtx);
599
600      if ( newCtx->dri.drawable != driDrawPriv ) {
601	 driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
602	 newCtx->dri.drawable = driDrawPriv;
603	 radeonUpdateWindow( newCtx->glCtx );
604	 radeonUpdateViewportOffset( newCtx->glCtx );
605      }
606
607      _mesa_make_current( newCtx->glCtx,
608			  (GLframebuffer *) driDrawPriv->driverPrivate,
609			  (GLframebuffer *) driReadPriv->driverPrivate );
610
611      if (newCtx->vb.enabled)
612	 radeonVtxfmtMakeCurrent( newCtx->glCtx );
613
614   } else {
615      if (RADEON_DEBUG & DEBUG_DRI)
616	 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
617      _mesa_make_current( NULL, NULL, NULL );
618   }
619
620   if (RADEON_DEBUG & DEBUG_DRI)
621      fprintf(stderr, "End %s\n", __FUNCTION__);
622   return GL_TRUE;
623}
624
625/* Force the context `c' to be unbound from its buffer.
626 */
627GLboolean
628radeonUnbindContext( __DRIcontextPrivate *driContextPriv )
629{
630   radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate;
631
632   if (RADEON_DEBUG & DEBUG_DRI)
633      fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *) rmesa->glCtx);
634
635   return GL_TRUE;
636}
637