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