77d36e35172e7443822562ef1183db6172962c3f
[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 "framebuffer.h"
44 #include "state.h"
45
46 #include "swrast/swrast.h"
47 #include "swrast_setup/swrast_setup.h"
48 #include "array_cache/acache.h"
49
50 #include "tnl/tnl.h"
51 #include "tnl/t_pipeline.h"
52
53 #include "drivers/common/driverfuncs.h"
54
55 #include "r200_context.h"
56 #include "r200_ioctl.h"
57 #include "r200_state.h"
58 #include "r200_span.h"
59 #include "r200_pixel.h"
60 #include "r200_tex.h"
61 #include "r200_swtcl.h"
62 #include "r200_tcl.h"
63 #include "r200_vtxfmt.h"
64 #include "r200_maos.h"
65
66 #define need_GL_ARB_multisample
67 #define need_GL_ARB_texture_compression
68 #define need_GL_ARB_vertex_buffer_object
69 #define need_GL_ARB_vertex_program
70 #define need_GL_EXT_blend_minmax
71 #define need_GL_EXT_fog_coord
72 #define need_GL_EXT_secondary_color
73 #define need_GL_EXT_blend_equation_separate
74 #define need_GL_EXT_blend_func_separate
75 #define need_GL_NV_vertex_program
76 #include "extension_helper.h"
77
78 #define DRIVER_DATE "20041207"
79
80 #include "vblank.h"
81 #include "utils.h"
82 #include "xmlpool.h" /* for symbolic values of enum-type options */
83 #ifndef R200_DEBUG
84 int R200_DEBUG = (0);
85 #endif
86
87
88 /* Return the width and height of the given buffer.
89 */
90 static void r200GetBufferSize( GLframebuffer *buffer,
91 GLuint *width, GLuint *height )
92 {
93 GET_CURRENT_CONTEXT(ctx);
94 r200ContextPtr rmesa = R200_CONTEXT(ctx);
95
96 LOCK_HARDWARE( rmesa );
97 *width = rmesa->dri.drawable->w;
98 *height = rmesa->dri.drawable->h;
99 UNLOCK_HARDWARE( rmesa );
100 }
101
102 /* Return various strings for glGetString().
103 */
104 static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
105 {
106 r200ContextPtr rmesa = R200_CONTEXT(ctx);
107 static char buffer[128];
108 unsigned offset;
109 GLuint agp_mode = rmesa->r200Screen->IsPCI ? 0 :
110 rmesa->r200Screen->AGPMode;
111
112 switch ( name ) {
113 case GL_VENDOR:
114 return (GLubyte *)"Tungsten Graphics, Inc.";
115
116 case GL_RENDERER:
117 offset = driGetRendererString( buffer, "R200", DRIVER_DATE,
118 agp_mode );
119
120 sprintf( & buffer[ offset ], " %sTCL",
121 !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)
122 ? "" : "NO-" );
123
124 return (GLubyte *)buffer;
125
126 default:
127 return NULL;
128 }
129 }
130
131
132 /* Extension strings exported by the R200 driver.
133 */
134 const struct dri_extension card_extensions[] =
135 {
136 { "GL_ARB_multisample", GL_ARB_multisample_functions },
137 { "GL_ARB_multitexture", NULL },
138 { "GL_ARB_texture_border_clamp", NULL },
139 { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
140 { "GL_ARB_texture_env_add", NULL },
141 { "GL_ARB_texture_env_combine", NULL },
142 { "GL_ARB_texture_env_dot3", NULL },
143 { "GL_ARB_texture_mirrored_repeat", NULL },
144 { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
145 { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
146 { "GL_EXT_blend_subtract", NULL },
147 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
148 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
149 { "GL_EXT_stencil_wrap", NULL },
150 { "GL_EXT_texture_edge_clamp", NULL },
151 { "GL_EXT_texture_env_combine", NULL },
152 { "GL_EXT_texture_env_dot3", NULL },
153 { "GL_EXT_texture_filter_anisotropic", NULL },
154 { "GL_EXT_texture_lod_bias", NULL },
155 { "GL_EXT_texture_mirror_clamp", NULL },
156 { "GL_EXT_texture_rectangle", NULL },
157 { "GL_ATI_texture_env_combine3", NULL },
158 { "GL_ATI_texture_mirror_once", NULL },
159 { "GL_MESA_pack_invert", NULL },
160 { "GL_NV_blend_square", NULL },
161 { "GL_SGIS_generate_mipmap", NULL },
162 { NULL, NULL }
163 };
164
165 const struct dri_extension blend_extensions[] = {
166 { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions },
167 { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
168 { NULL, NULL }
169 };
170
171 const struct dri_extension ARB_vp_extension[] = {
172 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }
173 };
174
175 const struct dri_extension NV_vp_extension[] = {
176 { "GL_NV_vertex_program", GL_NV_vertex_program_functions }
177 };
178
179 extern const struct tnl_pipeline_stage _r200_render_stage;
180 extern const struct tnl_pipeline_stage _r200_tcl_stage;
181
182 static const struct tnl_pipeline_stage *r200_pipeline[] = {
183
184 /* Try and go straight to t&l
185 */
186 &_r200_tcl_stage,
187
188 /* Catch any t&l fallbacks
189 */
190 &_tnl_vertex_transform_stage,
191 &_tnl_normal_transform_stage,
192 &_tnl_lighting_stage,
193 &_tnl_fog_coordinate_stage,
194 &_tnl_texgen_stage,
195 &_tnl_texture_transform_stage,
196 &_tnl_vertex_program_stage,
197
198 /* Try again to go to tcl?
199 * - no good for asymmetric-twoside (do with multipass)
200 * - no good for asymmetric-unfilled (do with multipass)
201 * - good for material
202 * - good for texgen
203 * - need to manipulate a bit of state
204 *
205 * - worth it/not worth it?
206 */
207
208 /* Else do them here.
209 */
210 /* &_r200_render_stage, */ /* FIXME: bugs with ut2003 */
211 &_tnl_render_stage, /* FALLBACK: */
212 NULL,
213 };
214
215
216
217 /* Initialize the driver's misc functions.
218 */
219 static void r200InitDriverFuncs( struct dd_function_table *functions )
220 {
221 functions->GetBufferSize = r200GetBufferSize;
222 functions->ResizeBuffers = _mesa_resize_framebuffer;
223 functions->GetString = r200GetString;
224
225 functions->Error = NULL;
226 functions->DrawPixels = NULL;
227 functions->Bitmap = NULL;
228 }
229
230 static const struct dri_debug_control debug_control[] =
231 {
232 { "fall", DEBUG_FALLBACKS },
233 { "tex", DEBUG_TEXTURE },
234 { "ioctl", DEBUG_IOCTL },
235 { "prim", DEBUG_PRIMS },
236 { "vert", DEBUG_VERTS },
237 { "state", DEBUG_STATE },
238 { "code", DEBUG_CODEGEN },
239 { "vfmt", DEBUG_VFMT },
240 { "vtxf", DEBUG_VFMT },
241 { "verb", DEBUG_VERBOSE },
242 { "dri", DEBUG_DRI },
243 { "dma", DEBUG_DMA },
244 { "san", DEBUG_SANITY },
245 { "sync", DEBUG_SYNC },
246 { "pix", DEBUG_PIXEL },
247 { "mem", DEBUG_MEMORY },
248 { NULL, 0 }
249 };
250
251
252 /* Create the device specific rendering context.
253 */
254 GLboolean r200CreateContext( const __GLcontextModes *glVisual,
255 __DRIcontextPrivate *driContextPriv,
256 void *sharedContextPrivate)
257 {
258 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
259 r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private);
260 struct dd_function_table functions;
261 r200ContextPtr rmesa;
262 GLcontext *ctx, *shareCtx;
263 int i;
264 int tcl_mode, fthrottle_mode;
265
266 assert(glVisual);
267 assert(driContextPriv);
268 assert(screen);
269
270 /* Allocate the R200 context */
271 rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
272 if ( !rmesa )
273 return GL_FALSE;
274
275 /* init exp fog table data */
276 r200InitStaticFogData();
277
278 /* Parse configuration files.
279 * Do this here so that initialMaxAnisotropy is set before we create
280 * the default textures.
281 */
282 driParseConfigFiles (&rmesa->optionCache, &screen->optionCache,
283 screen->driScreen->myNum, "r200");
284 rmesa->initialMaxAnisotropy = driQueryOptionf(&rmesa->optionCache,
285 "def_max_anisotropy");
286
287 if ( driQueryOptionb( &rmesa->optionCache, "hyperz" ) ) {
288 if ( sPriv->drmMinor < 13 )
289 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
290 "disabling.\n",sPriv->drmMinor );
291 else
292 rmesa->using_hyperz = GL_TRUE;
293 }
294
295 if ( sPriv->drmMinor >= 15 )
296 rmesa->texmicrotile = GL_TRUE;
297
298 /* Init default driver functions then plug in our R200-specific functions
299 * (the texture functions are especially important)
300 */
301 _mesa_init_driver_functions(&functions);
302 r200InitDriverFuncs(&functions);
303 r200InitIoctlFuncs(&functions);
304 r200InitStateFuncs(&functions);
305 r200InitTextureFuncs(&functions);
306
307 /* Allocate and initialize the Mesa context */
308 if (sharedContextPrivate)
309 shareCtx = ((r200ContextPtr) sharedContextPrivate)->glCtx;
310 else
311 shareCtx = NULL;
312 rmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
313 &functions, (void *) rmesa);
314 if (!rmesa->glCtx) {
315 FREE(rmesa);
316 return GL_FALSE;
317 }
318 driContextPriv->driverPrivate = rmesa;
319
320 /* Init r200 context data */
321 rmesa->dri.context = driContextPriv;
322 rmesa->dri.screen = sPriv;
323 rmesa->dri.drawable = NULL; /* Set by XMesaMakeCurrent */
324 rmesa->dri.hwContext = driContextPriv->hHWContext;
325 rmesa->dri.hwLock = &sPriv->pSAREA->lock;
326 rmesa->dri.fd = sPriv->fd;
327 rmesa->dri.drmMinor = sPriv->drmMinor;
328
329 rmesa->r200Screen = screen;
330 rmesa->sarea = (drm_radeon_sarea_t *)((GLubyte *)sPriv->pSAREA +
331 screen->sarea_priv_offset);
332
333
334 rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address;
335
336 (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) );
337 make_empty_list( & rmesa->swapped );
338
339 rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ;
340 assert(rmesa->nr_heaps < R200_NR_TEX_HEAPS);
341 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
342 rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa,
343 screen->texSize[i],
344 12,
345 RADEON_NR_TEX_REGIONS,
346 (drmTextureRegionPtr)rmesa->sarea->tex_list[i],
347 & rmesa->sarea->tex_age[i],
348 & rmesa->swapped,
349 sizeof( r200TexObj ),
350 (destroy_texture_object_t *) r200DestroyTexObj );
351 }
352 rmesa->texture_depth = driQueryOptioni (&rmesa->optionCache,
353 "texture_depth");
354 if (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
355 rmesa->texture_depth = ( screen->cpp == 4 ) ?
356 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
357
358 rmesa->swtcl.RenderIndex = ~0;
359 rmesa->hw.all_dirty = 1;
360
361 /* Set the maximum texture size small enough that we can guarentee that
362 * all texture units can bind a maximal texture and have them both in
363 * texturable memory at once.
364 */
365
366 ctx = rmesa->glCtx;
367 ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->optionCache,
368 "texture_units");
369 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
370 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
371
372 driCalculateMaxTextureLevels( rmesa->texture_heaps,
373 rmesa->nr_heaps,
374 & ctx->Const,
375 4,
376 11, /* max 2D texture size is 2048x2048 */
377 #if ENABLE_HW_3D_TEXTURE
378 8, /* max 3D texture size is 256^3 */
379 #else
380 0, /* 3D textures unsupported */
381 #endif
382 11, /* max cube texture size is 2048x2048 */
383 11, /* max texture rectangle size is 2048x2048 */
384 12,
385 GL_FALSE );
386
387 /* adjust max texture size a bit. Hack, but I really want to use larger textures
388 which will work just fine in 99.999999% of all cases, especially with texture compression... */
389 if (driQueryOptionb( &rmesa->optionCache, "texture_level_hack" ))
390 {
391 if (ctx->Const.MaxTextureLevels < 12) ctx->Const.MaxTextureLevels += 1;
392 }
393
394 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
395
396 /* No wide points.
397 */
398 ctx->Const.MinPointSize = 1.0;
399 ctx->Const.MinPointSizeAA = 1.0;
400 ctx->Const.MaxPointSize = 1.0;
401 ctx->Const.MaxPointSizeAA = 1.0;
402
403 ctx->Const.MinLineWidth = 1.0;
404 ctx->Const.MinLineWidthAA = 1.0;
405 ctx->Const.MaxLineWidth = 10.0;
406 ctx->Const.MaxLineWidthAA = 10.0;
407 ctx->Const.LineWidthGranularity = 0.0625;
408
409 /* Initialize the software rasterizer and helper modules.
410 */
411 _swrast_CreateContext( ctx );
412 _ac_CreateContext( ctx );
413 _tnl_CreateContext( ctx );
414 _swsetup_CreateContext( ctx );
415 _ae_create_context( ctx );
416
417 /* Install the customized pipeline:
418 */
419 _tnl_destroy_pipeline( ctx );
420 _tnl_install_pipeline( ctx, r200_pipeline );
421 ctx->Driver.FlushVertices = r200FlushVertices;
422
423 /* Try and keep materials and vertices separate:
424 */
425 _tnl_isolate_materials( ctx, GL_TRUE );
426
427
428 /* Configure swrast and TNL to match hardware characteristics:
429 */
430 _swrast_allow_pixel_fog( ctx, GL_FALSE );
431 _swrast_allow_vertex_fog( ctx, GL_TRUE );
432 _tnl_allow_pixel_fog( ctx, GL_FALSE );
433 _tnl_allow_vertex_fog( ctx, GL_TRUE );
434
435
436 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
437 _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
438 _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
439 }
440 _math_matrix_ctr( &rmesa->tmpmat );
441 _math_matrix_set_identity( &rmesa->tmpmat );
442
443 driInitExtensions( ctx, card_extensions, GL_TRUE );
444 if (!(rmesa->r200Screen->chipset & R200_CHIPSET_YCBCR_BROKEN)) {
445 /* yuv textures don't work with some chips - R200 / rv280 okay so far
446 others get the bit ordering right but don't actually do YUV-RGB conversion */
447 _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" );
448 }
449 if (rmesa->glCtx->Mesa_DXTn) {
450 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
451 _mesa_enable_extension( ctx, "GL_S3_s3tc" );
452 }
453 else if (driQueryOptionb (&rmesa->optionCache, "force_s3tc_enable")) {
454 _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
455 }
456
457 if (rmesa->r200Screen->drmSupportsCubeMaps)
458 _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
459 if (rmesa->r200Screen->drmSupportsBlendColor) {
460 driInitExtensions( ctx, blend_extensions, GL_FALSE );
461 }
462 if(driQueryOptionb(&rmesa->optionCache, "arb_vertex_program"))
463 driInitSingleExtension( ctx, ARB_vp_extension );
464 if(driQueryOptionb(&rmesa->optionCache, "nv_vertex_program"))
465 driInitSingleExtension( ctx, NV_vp_extension );
466
467 #if 0
468 r200InitDriverFuncs( ctx );
469 r200InitIoctlFuncs( ctx );
470 r200InitStateFuncs( ctx );
471 r200InitTextureFuncs( ctx );
472 #endif
473 /* plug in a few more device driver functions */
474 /* XXX these should really go right after _mesa_init_driver_functions() */
475 r200InitPixelFuncs( ctx );
476 r200InitSpanFuncs( ctx );
477 r200InitTnlFuncs( ctx );
478 r200InitState( rmesa );
479 r200InitSwtcl( ctx );
480
481 fthrottle_mode = driQueryOptioni(&rmesa->optionCache, "fthrottle_mode");
482 rmesa->iw.irq_seq = -1;
483 rmesa->irqsEmitted = 0;
484 rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 &&
485 fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
486 rmesa->r200Screen->irq);
487
488 rmesa->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
489
490 if (!rmesa->do_irqs)
491 fprintf(stderr,
492 "IRQ's not enabled, falling back to %s: %d %d %d\n",
493 rmesa->do_usleeps ? "usleeps" : "busy waits",
494 rmesa->dri.drmMinor,
495 fthrottle_mode,
496 rmesa->r200Screen->irq);
497
498 rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
499 ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
500
501 rmesa->prefer_gart_client_texturing =
502 (getenv("R200_GART_CLIENT_TEXTURES") != 0);
503
504 (*dri_interface->getUST)( & rmesa->swap_ust );
505
506
507 #if DO_DEBUG
508 R200_DEBUG = driParseDebugString( getenv( "R200_DEBUG" ),
509 debug_control );
510 R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ),
511 debug_control );
512 #endif
513
514 tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
515 if (driQueryOptionb(&rmesa->optionCache, "no_rast")) {
516 fprintf(stderr, "disabling 3D acceleration\n");
517 FALLBACK(rmesa, R200_FALLBACK_DISABLE, 1);
518 }
519 else if (tcl_mode == DRI_CONF_TCL_SW || getenv("R200_NO_TCL") ||
520 !(rmesa->r200Screen->chipset & R200_CHIPSET_TCL)) {
521 if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
522 rmesa->r200Screen->chipset &= ~R200_CHIPSET_TCL;
523 fprintf(stderr, "Disabling HW TCL support\n");
524 }
525 TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1);
526 }
527
528 if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) {
529 if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
530 r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN );
531
532 _tnl_need_dlist_norm_lengths( ctx, GL_FALSE );
533 }
534 return GL_TRUE;
535 }
536
537
538 /* Destroy the device specific context.
539 */
540 /* Destroy the Mesa and driver specific context data.
541 */
542 void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
543 {
544 GET_CURRENT_CONTEXT(ctx);
545 r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
546 r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL;
547
548 /* check if we're deleting the currently bound context */
549 if (rmesa == current) {
550 R200_FIREVERTICES( rmesa );
551 _mesa_make_current(NULL, NULL, NULL);
552 }
553
554 /* Free r200 context resources */
555 assert(rmesa); /* should never be null */
556 if ( rmesa ) {
557 GLboolean release_texture_heaps;
558
559
560 release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
561 _swsetup_DestroyContext( rmesa->glCtx );
562 _tnl_DestroyContext( rmesa->glCtx );
563 _ac_DestroyContext( rmesa->glCtx );
564 _swrast_DestroyContext( rmesa->glCtx );
565
566 r200DestroySwtcl( rmesa->glCtx );
567 r200ReleaseArrays( rmesa->glCtx, ~0 );
568
569 if (rmesa->dma.current.buf) {
570 r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
571 r200FlushCmdBuf( rmesa, __FUNCTION__ );
572 }
573
574 if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) {
575 int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode");
576 if (tcl_mode >= DRI_CONF_TCL_VTXFMT)
577 r200VtxfmtDestroy( rmesa->glCtx );
578 }
579
580 /* free the Mesa context */
581 rmesa->glCtx->DriverCtx = NULL;
582 _mesa_destroy_context( rmesa->glCtx );
583
584 if (rmesa->state.scissor.pClipRects) {
585 FREE(rmesa->state.scissor.pClipRects);
586 rmesa->state.scissor.pClipRects = NULL;
587 }
588
589 if ( release_texture_heaps ) {
590 /* This share group is about to go away, free our private
591 * texture object data.
592 */
593 int i;
594
595 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
596 driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
597 rmesa->texture_heaps[ i ] = NULL;
598 }
599
600 assert( is_empty_list( & rmesa->swapped ) );
601 }
602
603 /* free the option cache */
604 driDestroyOptionCache (&rmesa->optionCache);
605
606 FREE( rmesa );
607 }
608 }
609
610
611
612
613 void
614 r200SwapBuffers( __DRIdrawablePrivate *dPriv )
615 {
616 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
617 r200ContextPtr rmesa;
618 GLcontext *ctx;
619 rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
620 ctx = rmesa->glCtx;
621 if (ctx->Visual.doubleBufferMode) {
622 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
623 if ( rmesa->doPageFlip ) {
624 r200PageFlip( dPriv );
625 }
626 else {
627 r200CopyBuffer( dPriv );
628 }
629 }
630 }
631 else {
632 /* XXX this shouldn't be an error but we can't handle it for now */
633 _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
634 }
635 }
636
637
638 /* Force the context `c' to be the current context and associate with it
639 * buffer `b'.
640 */
641 GLboolean
642 r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
643 __DRIdrawablePrivate *driDrawPriv,
644 __DRIdrawablePrivate *driReadPriv )
645 {
646 if ( driContextPriv ) {
647 r200ContextPtr newCtx =
648 (r200ContextPtr) driContextPriv->driverPrivate;
649
650 if (R200_DEBUG & DEBUG_DRI)
651 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
652
653 if ( newCtx->dri.drawable != driDrawPriv ) {
654 driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
655 newCtx->dri.drawable = driDrawPriv;
656 r200UpdateWindow( newCtx->glCtx );
657 r200UpdateViewportOffset( newCtx->glCtx );
658 }
659
660 _mesa_make_current( newCtx->glCtx,
661 (GLframebuffer *) driDrawPriv->driverPrivate,
662 (GLframebuffer *) driReadPriv->driverPrivate );
663
664 if (newCtx->vb.enabled)
665 r200VtxfmtMakeCurrent( newCtx->glCtx );
666
667 _mesa_update_state( newCtx->glCtx );
668 r200ValidateState( newCtx->glCtx );
669
670 } else {
671 if (R200_DEBUG & DEBUG_DRI)
672 fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
673 _mesa_make_current( NULL, NULL, NULL );
674 }
675
676 if (R200_DEBUG & DEBUG_DRI)
677 fprintf(stderr, "End %s\n", __FUNCTION__);
678 return GL_TRUE;
679 }
680
681 /* Force the context `c' to be unbound from its buffer.
682 */
683 GLboolean
684 r200UnbindContext( __DRIcontextPrivate *driContextPriv )
685 {
686 r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
687
688 if (R200_DEBUG & DEBUG_DRI)
689 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx);
690
691 r200VtxfmtUnbindContext( rmesa->glCtx );
692 return GL_TRUE;
693 }