radeon_common_context.c revision 1036ef2bf468611d37b5df06fc4424f2002e3837
1/************************************************************************** 2 3Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 4 VA Linux Systems Inc., Fremont, California. 5Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 6 7The Weather Channel (TM) funded Tungsten Graphics to develop the 8initial release of the Radeon 8500 driver under the XFree86 license. 9This notice must be preserved. 10 11All Rights Reserved. 12 13Permission is hereby granted, free of charge, to any person obtaining 14a copy of this software and associated documentation files (the 15"Software"), to deal in the Software without restriction, including 16without limitation the rights to use, copy, modify, merge, publish, 17distribute, sublicense, and/or sell copies of the Software, and to 18permit persons to whom the Software is furnished to do so, subject to 19the following conditions: 20 21The above copyright notice and this permission notice (including the 22next paragraph) shall be included in all copies or substantial 23portions of the Software. 24 25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 28IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 29LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 33**************************************************************************/ 34 35#include "radeon_common.h" 36#include "xmlpool.h" /* for symbolic values of enum-type options */ 37#include "utils.h" 38#include "vblank.h" 39#include "drirenderbuffer.h" 40#include "main/context.h" 41#include "main/framebuffer.h" 42#include "main/renderbuffer.h" 43#include "main/state.h" 44#include "main/simple_list.h" 45#include "swrast/swrast.h" 46#include "swrast_setup/swrast_setup.h" 47#include "tnl/tnl.h" 48 49#define DRIVER_DATE "20090101" 50 51#ifndef RADEON_DEBUG 52int RADEON_DEBUG = (0); 53#endif 54 55 56static const char* get_chip_family_name(int chip_family) 57{ 58 switch(chip_family) { 59 case CHIP_FAMILY_R100: return "R100"; 60 case CHIP_FAMILY_RV100: return "RV100"; 61 case CHIP_FAMILY_RS100: return "RS100"; 62 case CHIP_FAMILY_RV200: return "RV200"; 63 case CHIP_FAMILY_RS200: return "RS200"; 64 case CHIP_FAMILY_R200: return "R200"; 65 case CHIP_FAMILY_RV250: return "RV250"; 66 case CHIP_FAMILY_RS300: return "RS300"; 67 case CHIP_FAMILY_RV280: return "RV280"; 68 case CHIP_FAMILY_R300: return "R300"; 69 case CHIP_FAMILY_R350: return "R350"; 70 case CHIP_FAMILY_RV350: return "RV350"; 71 case CHIP_FAMILY_RV380: return "RV380"; 72 case CHIP_FAMILY_R420: return "R420"; 73 case CHIP_FAMILY_RV410: return "RV410"; 74 case CHIP_FAMILY_RS400: return "RS400"; 75 case CHIP_FAMILY_RS600: return "RS600"; 76 case CHIP_FAMILY_RS690: return "RS690"; 77 case CHIP_FAMILY_RS740: return "RS740"; 78 case CHIP_FAMILY_RV515: return "RV515"; 79 case CHIP_FAMILY_R520: return "R520"; 80 case CHIP_FAMILY_RV530: return "RV530"; 81 case CHIP_FAMILY_R580: return "R580"; 82 case CHIP_FAMILY_RV560: return "RV560"; 83 case CHIP_FAMILY_RV570: return "RV570"; 84 default: return "unknown"; 85 } 86} 87 88 89/* Return various strings for glGetString(). 90 */ 91static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) 92{ 93 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 94 static char buffer[128]; 95 96 switch (name) { 97 case GL_VENDOR: 98 if (IS_R600_CLASS(radeon->radeonScreen)) 99 return (GLubyte *) "Advanced Micro Devices, Inc."; 100 else if (IS_R300_CLASS(radeon->radeonScreen)) 101 return (GLubyte *) "DRI R300 Project"; 102 else 103 return (GLubyte *) "Tungsten Graphics, Inc."; 104 105 case GL_RENDERER: 106 { 107 unsigned offset; 108 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : 109 radeon->radeonScreen->AGPMode; 110 const char* chipclass; 111 char hardwarename[32]; 112 113 if (IS_R600_CLASS(radeon->radeonScreen)) 114 chipclass = "R600"; 115 else if (IS_R300_CLASS(radeon->radeonScreen)) 116 chipclass = "R300"; 117 else if (IS_R200_CLASS(radeon->radeonScreen)) 118 chipclass = "R200"; 119 else 120 chipclass = "R100"; 121 122 sprintf(hardwarename, "%s (%s %04X)", 123 chipclass, 124 get_chip_family_name(radeon->radeonScreen->chip_family), 125 radeon->radeonScreen->device_id); 126 127 offset = driGetRendererString(buffer, hardwarename, DRIVER_DATE, 128 agp_mode); 129 130 if (IS_R600_CLASS(radeon->radeonScreen)) { 131 sprintf(&buffer[offset], " TCL"); 132 } else if (IS_R300_CLASS(radeon->radeonScreen)) { 133 sprintf(&buffer[offset], " %sTCL", 134 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) 135 ? "" : "NO-"); 136 } else { 137 sprintf(&buffer[offset], " %sTCL", 138 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) 139 ? "" : "NO-"); 140 } 141 142 if (radeon->radeonScreen->driScreen->dri2.enabled) 143 strcat(buffer, " DRI2"); 144 145 return (GLubyte *) buffer; 146 } 147 148 default: 149 return NULL; 150 } 151} 152 153/* Initialize the driver's misc functions. 154 */ 155static void radeonInitDriverFuncs(struct dd_function_table *functions) 156{ 157 functions->GetString = radeonGetString; 158} 159 160/** 161 * Create and initialize all common fields of the context, 162 * including the Mesa context itself. 163 */ 164GLboolean radeonInitContext(radeonContextPtr radeon, 165 struct dd_function_table* functions, 166 const __GLcontextModes * glVisual, 167 __DRIcontextPrivate * driContextPriv, 168 void *sharedContextPrivate) 169{ 170 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; 171 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); 172 GLcontext* ctx; 173 GLcontext* shareCtx; 174 int fthrottle_mode; 175 176 /* Fill in additional standard functions. */ 177 radeonInitDriverFuncs(functions); 178 179 radeon->radeonScreen = screen; 180 /* Allocate and initialize the Mesa context */ 181 if (sharedContextPrivate) 182 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; 183 else 184 shareCtx = NULL; 185 radeon->glCtx = _mesa_create_context(glVisual, shareCtx, 186 functions, (void *)radeon); 187 if (!radeon->glCtx) 188 return GL_FALSE; 189 190 ctx = radeon->glCtx; 191 driContextPriv->driverPrivate = radeon; 192 193 /* DRI fields */ 194 radeon->dri.context = driContextPriv; 195 radeon->dri.screen = sPriv; 196 radeon->dri.hwContext = driContextPriv->hHWContext; 197 radeon->dri.hwLock = &sPriv->pSAREA->lock; 198 radeon->dri.fd = sPriv->fd; 199 radeon->dri.drmMinor = sPriv->drm_version.minor; 200 201 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + 202 screen->sarea_priv_offset); 203 204 /* Setup IRQs */ 205 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); 206 radeon->iw.irq_seq = -1; 207 radeon->irqsEmitted = 0; 208 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && 209 radeon->radeonScreen->irq); 210 211 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); 212 213 if (!radeon->do_irqs) 214 fprintf(stderr, 215 "IRQ's not enabled, falling back to %s: %d %d\n", 216 radeon->do_usleeps ? "usleeps" : "busy waits", 217 fthrottle_mode, radeon->radeonScreen->irq); 218 219 radeon->texture_depth = driQueryOptioni (&radeon->optionCache, 220 "texture_depth"); 221 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) 222 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ? 223 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; 224 225 radeon->texture_row_align = 32; 226 227 return GL_TRUE; 228} 229 230 231 232/** 233 * Destroy the command buffer and state atoms. 234 */ 235static void radeon_destroy_atom_list(radeonContextPtr radeon) 236{ 237 struct radeon_state_atom *atom; 238 239 foreach(atom, &radeon->hw.atomlist) { 240 FREE(atom->cmd); 241 if (atom->lastcmd) 242 FREE(atom->lastcmd); 243 } 244 245} 246 247/** 248 * Cleanup common context fields. 249 * Called by r200DestroyContext/r300DestroyContext 250 */ 251void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) 252{ 253#ifdef RADEON_BO_TRACK 254 FILE *track; 255#endif 256 GET_CURRENT_CONTEXT(ctx); 257 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; 258 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; 259 260 /* +r6/r7 */ 261 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; 262 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); 263 /* --------- */ 264 265 if (radeon == current) { 266 radeon_firevertices(radeon); 267 _mesa_make_current(NULL, NULL, NULL); 268 } 269 270 assert(radeon); 271 if (radeon) 272 { 273 274#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */ 275 if (IS_R600_CLASS(screen)) 276 { 277 r600DestroyContext(driContextPriv); 278 } 279#endif 280 281 if (radeon->dma.current) { 282 rcommonFlushCmdBuf( radeon, __FUNCTION__ ); 283 } 284 285 radeonReleaseArrays(radeon->glCtx, ~0); 286 287 if (radeon->vtbl.free_context) 288 radeon->vtbl.free_context(radeon->glCtx); 289 _swsetup_DestroyContext( radeon->glCtx ); 290 _tnl_DestroyContext( radeon->glCtx ); 291 _vbo_DestroyContext( radeon->glCtx ); 292 _swrast_DestroyContext( radeon->glCtx ); 293 294 /* free atom list */ 295 /* free the Mesa context */ 296 _mesa_destroy_context(radeon->glCtx); 297 298 /* _mesa_destroy_context() might result in calls to functions that 299 * depend on the DriverCtx, so don't set it to NULL before. 300 * 301 * radeon->glCtx->DriverCtx = NULL; 302 */ 303 /* free the option cache */ 304 driDestroyOptionCache(&radeon->optionCache); 305 306 rcommonDestroyCmdBuf(radeon); 307 308#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */ 309 if (!IS_R600_CLASS(screen)) 310#endif 311 radeon_destroy_atom_list(radeon); 312 313 if (radeon->state.scissor.pClipRects) { 314 FREE(radeon->state.scissor.pClipRects); 315 radeon->state.scissor.pClipRects = 0; 316 } 317 } 318#ifdef RADEON_BO_TRACK 319 track = fopen("/tmp/tracklog", "w"); 320 if (track) { 321 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); 322 fclose(track); 323 } 324#endif 325 FREE(radeon); 326} 327 328/* Force the context `c' to be unbound from its buffer. 329 */ 330GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) 331{ 332 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; 333 334 if (RADEON_DEBUG & DEBUG_DRI) 335 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, 336 radeon->glCtx); 337 338 return GL_TRUE; 339} 340 341 342static void 343radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, 344 struct radeon_framebuffer *draw) 345{ 346 /* if radeon->fake */ 347 struct radeon_renderbuffer *rb; 348 349 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { 350 if (!rb->bo) { 351#ifdef RADEON_DEBUG_BO 352 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 353 radeon->radeonScreen->frontOffset, 354 0, 355 0, 356 RADEON_GEM_DOMAIN_VRAM, 357 0, 358 "Front Buf"); 359#else 360 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 361 radeon->radeonScreen->frontOffset, 362 0, 363 0, 364 RADEON_GEM_DOMAIN_VRAM, 365 0); 366#endif /* RADEON_DEBUG_BO */ 367 } 368 rb->cpp = radeon->radeonScreen->cpp; 369 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; 370 } 371 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { 372 if (!rb->bo) { 373#ifdef RADEON_DEBUG_BO 374 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 375 radeon->radeonScreen->backOffset, 376 0, 377 0, 378 RADEON_GEM_DOMAIN_VRAM, 379 0, 380 "Back Buf"); 381#else 382 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 383 radeon->radeonScreen->backOffset, 384 0, 385 0, 386 RADEON_GEM_DOMAIN_VRAM, 387 0); 388#endif /* RADEON_DEBUG_BO */ 389 } 390 rb->cpp = radeon->radeonScreen->cpp; 391 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; 392 } 393 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { 394 if (!rb->bo) { 395#ifdef RADEON_DEBUG_BO 396 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 397 radeon->radeonScreen->depthOffset, 398 0, 399 0, 400 RADEON_GEM_DOMAIN_VRAM, 401 0, 402 "Z Buf"); 403#else 404 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 405 radeon->radeonScreen->depthOffset, 406 0, 407 0, 408 RADEON_GEM_DOMAIN_VRAM, 409 0); 410#endif /* RADEON_DEBUG_BO */ 411 } 412 rb->cpp = radeon->radeonScreen->cpp; 413 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 414 } 415 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { 416 if (!rb->bo) { 417#ifdef RADEON_DEBUG_BO 418 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 419 radeon->radeonScreen->depthOffset, 420 0, 421 0, 422 RADEON_GEM_DOMAIN_VRAM, 423 0, 424 "Stencil Buf"); 425#else 426 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 427 radeon->radeonScreen->depthOffset, 428 0, 429 0, 430 RADEON_GEM_DOMAIN_VRAM, 431 0); 432#endif /* RADEON_DEBUG_BO */ 433 } 434 rb->cpp = radeon->radeonScreen->cpp; 435 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 436 } 437} 438 439static void 440radeon_make_renderbuffer_current(radeonContextPtr radeon, 441 struct radeon_framebuffer *draw) 442{ 443 int size = 4096*4096*4; 444 /* if radeon->fake */ 445 struct radeon_renderbuffer *rb; 446 447 if (radeon->radeonScreen->kernel_mm) { 448 radeon_make_kernel_renderbuffer_current(radeon, draw); 449 return; 450 } 451 452 453 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { 454 if (!rb->bo) { 455#ifdef RADEON_DEBUG_BO 456 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 457 radeon->radeonScreen->frontOffset + 458 radeon->radeonScreen->fbLocation, 459 size, 460 4096, 461 RADEON_GEM_DOMAIN_VRAM, 462 0, 463 "Front Buf"); 464#else 465 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 466 radeon->radeonScreen->frontOffset + 467 radeon->radeonScreen->fbLocation, 468 size, 469 4096, 470 RADEON_GEM_DOMAIN_VRAM, 471 0); 472#endif /* RADEON_DEBUG_BO */ 473 } 474 rb->cpp = radeon->radeonScreen->cpp; 475 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; 476 } 477 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { 478 if (!rb->bo) { 479#ifdef RADEON_DEBUG_BO 480 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 481 radeon->radeonScreen->backOffset + 482 radeon->radeonScreen->fbLocation, 483 size, 484 4096, 485 RADEON_GEM_DOMAIN_VRAM, 486 0, 487 "Back Buf"); 488#else 489 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 490 radeon->radeonScreen->backOffset + 491 radeon->radeonScreen->fbLocation, 492 size, 493 4096, 494 RADEON_GEM_DOMAIN_VRAM, 495 0); 496#endif /* RADEON_DEBUG_BO */ 497 } 498 rb->cpp = radeon->radeonScreen->cpp; 499 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; 500 } 501 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { 502 if (!rb->bo) { 503#ifdef RADEON_DEBUG_BO 504 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 505 radeon->radeonScreen->depthOffset + 506 radeon->radeonScreen->fbLocation, 507 size, 508 4096, 509 RADEON_GEM_DOMAIN_VRAM, 510 0, 511 "Z Buf"); 512#else 513 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 514 radeon->radeonScreen->depthOffset + 515 radeon->radeonScreen->fbLocation, 516 size, 517 4096, 518 RADEON_GEM_DOMAIN_VRAM, 519 0); 520#endif /* RADEON_DEBUG_BO */ 521 } 522 rb->cpp = radeon->radeonScreen->cpp; 523 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 524 } 525 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { 526 if (!rb->bo) { 527#ifdef RADEON_DEBUG_BO 528 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 529 radeon->radeonScreen->depthOffset + 530 radeon->radeonScreen->fbLocation, 531 size, 532 4096, 533 RADEON_GEM_DOMAIN_VRAM, 534 0, 535 "Stencil Buf"); 536#else 537 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 538 radeon->radeonScreen->depthOffset + 539 radeon->radeonScreen->fbLocation, 540 size, 541 4096, 542 RADEON_GEM_DOMAIN_VRAM, 543 0); 544#endif /* RADEON_DEBUG_BO */ 545 } 546 rb->cpp = radeon->radeonScreen->cpp; 547 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 548 } 549} 550 551static unsigned 552radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) 553{ 554 switch (rb->base._ActualFormat) { 555 case GL_RGB5: 556 case GL_DEPTH_COMPONENT16: 557 return 16; 558 case GL_RGB8: 559 case GL_RGBA8: 560 case GL_DEPTH_COMPONENT24: 561 case GL_DEPTH24_STENCIL8_EXT: 562 case GL_STENCIL_INDEX8_EXT: 563 return 32; 564 default: 565 return 0; 566 } 567} 568 569void 570radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) 571{ 572 unsigned int attachments[10]; 573 __DRIbuffer *buffers = NULL; 574 __DRIscreen *screen; 575 struct radeon_renderbuffer *rb; 576 int i, count; 577 struct radeon_framebuffer *draw; 578 radeonContextPtr radeon; 579 char *regname; 580 struct radeon_bo *depth_bo = NULL, *bo; 581 582 if (RADEON_DEBUG & DEBUG_DRI) 583 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); 584 585 draw = drawable->driverPrivate; 586 screen = context->driScreenPriv; 587 radeon = (radeonContextPtr) context->driverPrivate; 588 589 if (screen->dri2.loader 590 && (screen->dri2.loader->base.version > 2) 591 && (screen->dri2.loader->getBuffersWithFormat != NULL)) { 592 struct radeon_renderbuffer *depth_rb; 593 struct radeon_renderbuffer *stencil_rb; 594 595 i = 0; 596 if ((radeon->is_front_buffer_rendering || !draw->color_rb[1]) 597 && draw->color_rb[0]) { 598 attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 599 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); 600 } 601 602 if (draw->color_rb[1]) { 603 attachments[i++] = __DRI_BUFFER_BACK_LEFT; 604 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]); 605 } 606 607 depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); 608 stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); 609 610 if ((depth_rb != NULL) && (stencil_rb != NULL)) { 611 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; 612 attachments[i++] = radeon_bits_per_pixel(depth_rb); 613 } else if (depth_rb != NULL) { 614 attachments[i++] = __DRI_BUFFER_DEPTH; 615 attachments[i++] = radeon_bits_per_pixel(depth_rb); 616 } else if (stencil_rb != NULL) { 617 attachments[i++] = __DRI_BUFFER_STENCIL; 618 attachments[i++] = radeon_bits_per_pixel(stencil_rb); 619 } 620 621 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable, 622 &drawable->w, 623 &drawable->h, 624 attachments, i / 2, 625 &count, 626 drawable->loaderPrivate); 627 } else if (screen->dri2.loader) { 628 i = 0; 629 if (draw->color_rb[0]) 630 attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 631 if (draw->color_rb[1]) 632 attachments[i++] = __DRI_BUFFER_BACK_LEFT; 633 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) 634 attachments[i++] = __DRI_BUFFER_DEPTH; 635 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) 636 attachments[i++] = __DRI_BUFFER_STENCIL; 637 638 buffers = (*screen->dri2.loader->getBuffers)(drawable, 639 &drawable->w, 640 &drawable->h, 641 attachments, i, 642 &count, 643 drawable->loaderPrivate); 644 } 645 646 if (buffers == NULL) 647 return; 648 649 /* set one cliprect to cover the whole drawable */ 650 drawable->x = 0; 651 drawable->y = 0; 652 drawable->backX = 0; 653 drawable->backY = 0; 654 drawable->numClipRects = 1; 655 drawable->pClipRects[0].x1 = 0; 656 drawable->pClipRects[0].y1 = 0; 657 drawable->pClipRects[0].x2 = drawable->w; 658 drawable->pClipRects[0].y2 = drawable->h; 659 drawable->numBackClipRects = 1; 660 drawable->pBackClipRects[0].x1 = 0; 661 drawable->pBackClipRects[0].y1 = 0; 662 drawable->pBackClipRects[0].x2 = drawable->w; 663 drawable->pBackClipRects[0].y2 = drawable->h; 664 for (i = 0; i < count; i++) { 665 switch (buffers[i].attachment) { 666 case __DRI_BUFFER_FRONT_LEFT: 667 rb = draw->color_rb[0]; 668 regname = "dri2 front buffer"; 669 break; 670 case __DRI_BUFFER_FAKE_FRONT_LEFT: 671 rb = draw->color_rb[0]; 672 regname = "dri2 fake front buffer"; 673 break; 674 case __DRI_BUFFER_BACK_LEFT: 675 rb = draw->color_rb[1]; 676 regname = "dri2 back buffer"; 677 break; 678 case __DRI_BUFFER_DEPTH: 679 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); 680 regname = "dri2 depth buffer"; 681 break; 682 case __DRI_BUFFER_DEPTH_STENCIL: 683 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); 684 regname = "dri2 depth / stencil buffer"; 685 break; 686 case __DRI_BUFFER_STENCIL: 687 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); 688 regname = "dri2 stencil buffer"; 689 break; 690 case __DRI_BUFFER_ACCUM: 691 default: 692 fprintf(stderr, 693 "unhandled buffer attach event, attacment type %d\n", 694 buffers[i].attachment); 695 return; 696 } 697 698 if (rb == NULL) 699 continue; 700 701 if (rb->bo) { 702 uint32_t name = radeon_gem_name_bo(rb->bo); 703 if (name == buffers[i].name) 704 continue; 705 } 706 707 if (RADEON_DEBUG & DEBUG_DRI) 708 fprintf(stderr, 709 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", 710 regname, buffers[i].name, buffers[i].attachment, 711 buffers[i].cpp, buffers[i].pitch); 712 713 rb->cpp = buffers[i].cpp; 714 rb->pitch = buffers[i].pitch; 715 rb->width = drawable->w; 716 rb->height = drawable->h; 717 rb->has_surface = 0; 718 719 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { 720 if (RADEON_DEBUG & DEBUG_DRI) 721 fprintf(stderr, "(reusing depth buffer as stencil)\n"); 722 bo = depth_bo; 723 radeon_bo_ref(bo); 724 } else { 725#ifdef RADEON_DEBUG_BO 726 bo = radeon_bo_open(radeon->radeonScreen->bom, 727 buffers[i].name, 728 0, 729 0, 730 RADEON_GEM_DOMAIN_VRAM, 731 buffers[i].flags, 732 regname); 733#else 734 bo = radeon_bo_open(radeon->radeonScreen->bom, 735 buffers[i].name, 736 0, 737 0, 738 RADEON_GEM_DOMAIN_VRAM, 739 buffers[i].flags); 740#endif /* RADEON_DEBUG_BO */ 741 if (bo == NULL) { 742 743 fprintf(stderr, "failed to attach %s %d\n", 744 regname, buffers[i].name); 745 746 } 747 } 748 749 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) { 750 if (draw->base.Visual.depthBits == 16) 751 rb->cpp = 2; 752 depth_bo = bo; 753 } 754 755 radeon_renderbuffer_set_bo(rb, bo); 756 radeon_bo_unref(bo); 757 758 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { 759 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); 760 if (rb != NULL) { 761 struct radeon_bo *stencil_bo = NULL; 762 763 if (rb->bo) { 764 uint32_t name = radeon_gem_name_bo(rb->bo); 765 if (name == buffers[i].name) 766 continue; 767 } 768 769 stencil_bo = bo; 770 radeon_bo_ref(stencil_bo); 771 radeon_renderbuffer_set_bo(rb, stencil_bo); 772 radeon_bo_unref(stencil_bo); 773 } 774 } 775 } 776 777 driUpdateFramebufferSize(radeon->glCtx, drawable); 778} 779 780/* Force the context `c' to be the current context and associate with it 781 * buffer `b'. 782 */ 783GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, 784 __DRIdrawablePrivate * driDrawPriv, 785 __DRIdrawablePrivate * driReadPriv) 786{ 787 radeonContextPtr radeon; 788 struct radeon_framebuffer *drfb; 789 struct gl_framebuffer *readfb; 790 791 if (!driContextPriv) { 792 if (RADEON_DEBUG & DEBUG_DRI) 793 fprintf(stderr, "%s ctx is null\n", __FUNCTION__); 794 _mesa_make_current(NULL, NULL, NULL); 795 return GL_TRUE; 796 } 797 798 radeon = (radeonContextPtr) driContextPriv->driverPrivate; 799 drfb = driDrawPriv->driverPrivate; 800 readfb = driReadPriv->driverPrivate; 801 802 if (driContextPriv->driScreenPriv->dri2.enabled) { 803 radeon_update_renderbuffers(driContextPriv, driDrawPriv); 804 if (driDrawPriv != driReadPriv) 805 radeon_update_renderbuffers(driContextPriv, driReadPriv); 806 _mesa_reference_renderbuffer(&radeon->state.color.rb, 807 &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base)); 808 _mesa_reference_renderbuffer(&radeon->state.depth.rb, 809 &(radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH)->base)); 810 } else { 811 radeon_make_renderbuffer_current(radeon, drfb); 812 } 813 814 if (RADEON_DEBUG & DEBUG_DRI) 815 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb); 816 817 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); 818 if (driReadPriv != driDrawPriv) 819 driUpdateFramebufferSize(radeon->glCtx, driReadPriv); 820 821 _mesa_make_current(radeon->glCtx, &drfb->base, readfb); 822 823 _mesa_update_state(radeon->glCtx); 824 825 if (radeon->glCtx->DrawBuffer == &drfb->base) { 826 if (driDrawPriv->swap_interval == (unsigned)-1) { 827 int i; 828 driDrawPriv->vblFlags = 829 (radeon->radeonScreen->irq != 0) 830 ? driGetDefaultVBlankFlags(&radeon-> 831 optionCache) 832 : VBLANK_FLAG_NO_IRQ; 833 834 driDrawableInitVBlank(driDrawPriv); 835 drfb->vbl_waited = driDrawPriv->vblSeq; 836 837 for (i = 0; i < 2; i++) { 838 if (drfb->color_rb[i]) 839 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; 840 } 841 842 } 843 844 radeon_window_moved(radeon); 845 radeon_draw_buffer(radeon->glCtx, &drfb->base); 846 } 847 848 849 if (RADEON_DEBUG & DEBUG_DRI) 850 fprintf(stderr, "End %s\n", __FUNCTION__); 851 852 return GL_TRUE; 853} 854 855