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