r200_context.c revision 5f1ba3e21b62cee1a4f900a2e6964728f3eeea9b
1/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.c,v 1.3 2003/05/06 23:52:08 daenzer Exp $ */ 2/* 3Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 5The Weather Channel (TM) funded Tungsten Graphics to develop the 6initial release of the Radeon 8500 driver under the XFree86 license. 7This notice must be preserved. 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 * 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 84int R200_DEBUG = (0); 85#endif 86 87 88/* Return the width and height of the given buffer. 89 */ 90static 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 */ 104static 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 */ 134static 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 165static 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 171static const struct dri_extension ARB_vp_extension[] = { 172 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions } 173}; 174 175static const struct dri_extension NV_vp_extension[] = { 176 { "GL_NV_vertex_program", GL_NV_vertex_program_functions } 177}; 178 179extern const struct tnl_pipeline_stage _r200_render_stage; 180extern const struct tnl_pipeline_stage _r200_tcl_stage; 181 182static 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 */ 219static 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 230static 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 */ 254GLboolean 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 if (rmesa->r200Screen->chipset & R200_CHIPSET_TCL) { 528 if (tcl_mode >= DRI_CONF_TCL_VTXFMT && !getenv("R200_NO_VTXFMT")) { 529 r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); 530 } 531 _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); 532 } 533 return GL_TRUE; 534} 535 536 537/* Destroy the device specific context. 538 */ 539/* Destroy the Mesa and driver specific context data. 540 */ 541void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) 542{ 543 GET_CURRENT_CONTEXT(ctx); 544 r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; 545 r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL; 546 547 /* check if we're deleting the currently bound context */ 548 if (rmesa == current) { 549 R200_FIREVERTICES( rmesa ); 550 _mesa_make_current(NULL, NULL, NULL); 551 } 552 553 /* Free r200 context resources */ 554 assert(rmesa); /* should never be null */ 555 if ( rmesa ) { 556 GLboolean release_texture_heaps; 557 558 559 release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); 560 _swsetup_DestroyContext( rmesa->glCtx ); 561 _tnl_DestroyContext( rmesa->glCtx ); 562 _ac_DestroyContext( rmesa->glCtx ); 563 _swrast_DestroyContext( rmesa->glCtx ); 564 565 r200DestroySwtcl( rmesa->glCtx ); 566 r200ReleaseArrays( rmesa->glCtx, ~0 ); 567 568 if (rmesa->dma.current.buf) { 569 r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); 570 r200FlushCmdBuf( rmesa, __FUNCTION__ ); 571 } 572 573 if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) { 574 int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); 575 if (tcl_mode >= DRI_CONF_TCL_VTXFMT) 576 r200VtxfmtDestroy( rmesa->glCtx ); 577 } 578 579 /* free the Mesa context */ 580 rmesa->glCtx->DriverCtx = NULL; 581 _mesa_destroy_context( rmesa->glCtx ); 582 583 if (rmesa->state.scissor.pClipRects) { 584 FREE(rmesa->state.scissor.pClipRects); 585 rmesa->state.scissor.pClipRects = NULL; 586 } 587 588 if ( release_texture_heaps ) { 589 /* This share group is about to go away, free our private 590 * texture object data. 591 */ 592 int i; 593 594 for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { 595 driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); 596 rmesa->texture_heaps[ i ] = NULL; 597 } 598 599 assert( is_empty_list( & rmesa->swapped ) ); 600 } 601 602 /* free the option cache */ 603 driDestroyOptionCache (&rmesa->optionCache); 604 605 FREE( rmesa ); 606 } 607} 608 609 610 611 612void 613r200SwapBuffers( __DRIdrawablePrivate *dPriv ) 614{ 615 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { 616 r200ContextPtr rmesa; 617 GLcontext *ctx; 618 rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; 619 ctx = rmesa->glCtx; 620 if (ctx->Visual.doubleBufferMode) { 621 _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ 622 if ( rmesa->doPageFlip ) { 623 r200PageFlip( dPriv ); 624 } 625 else { 626 r200CopyBuffer( dPriv ); 627 } 628 } 629 } 630 else { 631 /* XXX this shouldn't be an error but we can't handle it for now */ 632 _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); 633 } 634} 635 636 637/* Force the context `c' to be the current context and associate with it 638 * buffer `b'. 639 */ 640GLboolean 641r200MakeCurrent( __DRIcontextPrivate *driContextPriv, 642 __DRIdrawablePrivate *driDrawPriv, 643 __DRIdrawablePrivate *driReadPriv ) 644{ 645 if ( driContextPriv ) { 646 r200ContextPtr newCtx = 647 (r200ContextPtr) driContextPriv->driverPrivate; 648 649 if (R200_DEBUG & DEBUG_DRI) 650 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx); 651 652 if ( newCtx->dri.drawable != driDrawPriv ) { 653 driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags ); 654 newCtx->dri.drawable = driDrawPriv; 655 r200UpdateWindow( newCtx->glCtx ); 656 r200UpdateViewportOffset( newCtx->glCtx ); 657 } 658 659 _mesa_make_current( newCtx->glCtx, 660 (GLframebuffer *) driDrawPriv->driverPrivate, 661 (GLframebuffer *) driReadPriv->driverPrivate ); 662 663 if (newCtx->vb.enabled) 664 r200VtxfmtMakeCurrent( newCtx->glCtx ); 665 666 _mesa_update_state( newCtx->glCtx ); 667 r200ValidateState( newCtx->glCtx ); 668 669 } else { 670 if (R200_DEBUG & DEBUG_DRI) 671 fprintf(stderr, "%s ctx is null\n", __FUNCTION__); 672 _mesa_make_current( NULL, NULL, NULL ); 673 } 674 675 if (R200_DEBUG & DEBUG_DRI) 676 fprintf(stderr, "End %s\n", __FUNCTION__); 677 return GL_TRUE; 678} 679 680/* Force the context `c' to be unbound from its buffer. 681 */ 682GLboolean 683r200UnbindContext( __DRIcontextPrivate *driContextPriv ) 684{ 685 r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; 686 687 if (R200_DEBUG & DEBUG_DRI) 688 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx); 689 690 r200VtxfmtUnbindContext( rmesa->glCtx ); 691 return GL_TRUE; 692} 693