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