radeon_common_context.c revision 8446f257b3e3ca4a3eb2c79bc357e46343e04e87
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 "drivers/common/meta.h" 41#include "main/context.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 case CHIP_FAMILY_R600: return "R600"; 85 case CHIP_FAMILY_RV610: return "RV610"; 86 case CHIP_FAMILY_RV630: return "RV630"; 87 case CHIP_FAMILY_RV670: return "RV670"; 88 case CHIP_FAMILY_RV620: return "RV620"; 89 case CHIP_FAMILY_RV635: return "RV635"; 90 case CHIP_FAMILY_RS780: return "RS780"; 91 case CHIP_FAMILY_RS880: return "RS880"; 92 case CHIP_FAMILY_RV770: return "RV770"; 93 case CHIP_FAMILY_RV730: return "RV730"; 94 case CHIP_FAMILY_RV710: return "RV710"; 95 case CHIP_FAMILY_RV740: return "RV740"; 96 default: return "unknown"; 97 } 98} 99 100 101/* Return various strings for glGetString(). 102 */ 103static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) 104{ 105 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 106 static char buffer[128]; 107 108 switch (name) { 109 case GL_VENDOR: 110 if (IS_R600_CLASS(radeon->radeonScreen)) 111 return (GLubyte *) "Advanced Micro Devices, Inc."; 112 else if (IS_R300_CLASS(radeon->radeonScreen)) 113 return (GLubyte *) "DRI R300 Project"; 114 else 115 return (GLubyte *) "Tungsten Graphics, Inc."; 116 117 case GL_RENDERER: 118 { 119 unsigned offset; 120 GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : 121 radeon->radeonScreen->AGPMode; 122 const char* chipclass; 123 char hardwarename[32]; 124 125 if (IS_R600_CLASS(radeon->radeonScreen)) 126 chipclass = "R600"; 127 else if (IS_R300_CLASS(radeon->radeonScreen)) 128 chipclass = "R300"; 129 else if (IS_R200_CLASS(radeon->radeonScreen)) 130 chipclass = "R200"; 131 else 132 chipclass = "R100"; 133 134 sprintf(hardwarename, "%s (%s %04X)", 135 chipclass, 136 get_chip_family_name(radeon->radeonScreen->chip_family), 137 radeon->radeonScreen->device_id); 138 139 offset = driGetRendererString(buffer, hardwarename, DRIVER_DATE, 140 agp_mode); 141 142 if (IS_R600_CLASS(radeon->radeonScreen)) { 143 sprintf(&buffer[offset], " TCL"); 144 } else if (IS_R300_CLASS(radeon->radeonScreen)) { 145 sprintf(&buffer[offset], " %sTCL", 146 (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) 147 ? "" : "NO-"); 148 } else { 149 sprintf(&buffer[offset], " %sTCL", 150 !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) 151 ? "" : "NO-"); 152 } 153 154 if (radeon->radeonScreen->driScreen->dri2.enabled) 155 strcat(buffer, " DRI2"); 156 157 return (GLubyte *) buffer; 158 } 159 160 default: 161 return NULL; 162 } 163} 164 165/* Initialize the driver's misc functions. 166 */ 167static void radeonInitDriverFuncs(struct dd_function_table *functions) 168{ 169 functions->GetString = radeonGetString; 170} 171 172/** 173 * Create and initialize all common fields of the context, 174 * including the Mesa context itself. 175 */ 176GLboolean radeonInitContext(radeonContextPtr radeon, 177 struct dd_function_table* functions, 178 const __GLcontextModes * glVisual, 179 __DRIcontext * driContextPriv, 180 void *sharedContextPrivate) 181{ 182 __DRIscreen *sPriv = driContextPriv->driScreenPriv; 183 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); 184 GLcontext* ctx; 185 GLcontext* shareCtx; 186 int fthrottle_mode; 187 188 /* Fill in additional standard functions. */ 189 radeonInitDriverFuncs(functions); 190 191 radeon->radeonScreen = screen; 192 /* Allocate and initialize the Mesa context */ 193 if (sharedContextPrivate) 194 shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; 195 else 196 shareCtx = NULL; 197 radeon->glCtx = _mesa_create_context(glVisual, shareCtx, 198 functions, (void *)radeon); 199 if (!radeon->glCtx) 200 return GL_FALSE; 201 202 ctx = radeon->glCtx; 203 driContextPriv->driverPrivate = radeon; 204 205 meta_init_metaops(ctx, &radeon->meta); 206 207 _mesa_meta_init(ctx); 208 209 /* DRI fields */ 210 radeon->dri.context = driContextPriv; 211 radeon->dri.screen = sPriv; 212 radeon->dri.hwContext = driContextPriv->hHWContext; 213 radeon->dri.hwLock = &sPriv->pSAREA->lock; 214 radeon->dri.hwLockCount = 0; 215 radeon->dri.fd = sPriv->fd; 216 radeon->dri.drmMinor = sPriv->drm_version.minor; 217 218 radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + 219 screen->sarea_priv_offset); 220 221 /* Setup IRQs */ 222 fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); 223 radeon->iw.irq_seq = -1; 224 radeon->irqsEmitted = 0; 225 radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && 226 radeon->radeonScreen->irq); 227 228 radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); 229 230 if (!radeon->do_irqs) 231 fprintf(stderr, 232 "IRQ's not enabled, falling back to %s: %d %d\n", 233 radeon->do_usleeps ? "usleeps" : "busy waits", 234 fthrottle_mode, radeon->radeonScreen->irq); 235 236 radeon->texture_depth = driQueryOptioni (&radeon->optionCache, 237 "texture_depth"); 238 if (radeon->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) 239 radeon->texture_depth = ( glVisual->rgbBits > 16 ) ? 240 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; 241 242 if (IS_R600_CLASS(radeon->radeonScreen)) { 243 radeon->texture_row_align = 256; 244 radeon->texture_rect_row_align = 256; 245 radeon->texture_compressed_row_align = 256; 246 } else if (IS_R200_CLASS(radeon->radeonScreen) || 247 IS_R100_CLASS(radeon->radeonScreen)) { 248 radeon->texture_row_align = 32; 249 radeon->texture_rect_row_align = 64; 250 radeon->texture_compressed_row_align = 32; 251 } else { /* R300 - not sure this is all correct */ 252 int chip_family = radeon->radeonScreen->chip_family; 253 if (chip_family == CHIP_FAMILY_RS600 || 254 chip_family == CHIP_FAMILY_RS690 || 255 chip_family == CHIP_FAMILY_RS740) 256 radeon->texture_row_align = 64; 257 else 258 radeon->texture_row_align = 32; 259 radeon->texture_rect_row_align = 64; 260 radeon->texture_compressed_row_align = 32; 261 } 262 263 radeon_init_dma(radeon); 264 265 return GL_TRUE; 266} 267 268 269 270/** 271 * Destroy the command buffer and state atoms. 272 */ 273static void radeon_destroy_atom_list(radeonContextPtr radeon) 274{ 275 struct radeon_state_atom *atom; 276 277 foreach(atom, &radeon->hw.atomlist) { 278 FREE(atom->cmd); 279 if (atom->lastcmd) 280 FREE(atom->lastcmd); 281 } 282 283} 284 285/** 286 * Cleanup common context fields. 287 * Called by r200DestroyContext/r300DestroyContext 288 */ 289void radeonDestroyContext(__DRIcontext *driContextPriv ) 290{ 291#ifdef RADEON_BO_TRACK 292 FILE *track; 293#endif 294 GET_CURRENT_CONTEXT(ctx); 295 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; 296 radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL; 297 298 assert(radeon); 299 300 _mesa_meta_free(radeon->glCtx); 301 302 if (radeon == current) { 303 _mesa_make_current(NULL, NULL, NULL); 304 } 305 306 radeon_firevertices(radeon); 307 if (!is_empty_list(&radeon->dma.reserved)) { 308 rcommonFlushCmdBuf( radeon, __FUNCTION__ ); 309 } 310 311 radeonFreeDmaRegions(radeon); 312 radeonReleaseArrays(radeon->glCtx, ~0); 313 meta_destroy_metaops(&radeon->meta); 314 if (radeon->vtbl.free_context) 315 radeon->vtbl.free_context(radeon->glCtx); 316 _swsetup_DestroyContext( radeon->glCtx ); 317 _tnl_DestroyContext( radeon->glCtx ); 318 _vbo_DestroyContext( radeon->glCtx ); 319 _swrast_DestroyContext( radeon->glCtx ); 320 321 /* free atom list */ 322 /* free the Mesa context */ 323 _mesa_destroy_context(radeon->glCtx); 324 325 /* _mesa_destroy_context() might result in calls to functions that 326 * depend on the DriverCtx, so don't set it to NULL before. 327 * 328 * radeon->glCtx->DriverCtx = NULL; 329 */ 330 /* free the option cache */ 331 driDestroyOptionCache(&radeon->optionCache); 332 333 rcommonDestroyCmdBuf(radeon); 334 335 radeon_destroy_atom_list(radeon); 336 337 if (radeon->state.scissor.pClipRects) { 338 FREE(radeon->state.scissor.pClipRects); 339 radeon->state.scissor.pClipRects = 0; 340 } 341#ifdef RADEON_BO_TRACK 342 track = fopen("/tmp/tracklog", "w"); 343 if (track) { 344 radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); 345 fclose(track); 346 } 347#endif 348 FREE(radeon); 349} 350 351/* Force the context `c' to be unbound from its buffer. 352 */ 353GLboolean radeonUnbindContext(__DRIcontext * driContextPriv) 354{ 355 radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; 356 357 if (RADEON_DEBUG & RADEON_DRI) 358 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, 359 radeon->glCtx); 360 361 return GL_TRUE; 362} 363 364 365static void 366radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, 367 struct radeon_framebuffer *draw) 368{ 369 /* if radeon->fake */ 370 struct radeon_renderbuffer *rb; 371 372 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { 373 if (!rb->bo) { 374 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 375 radeon->radeonScreen->frontOffset, 376 0, 377 0, 378 RADEON_GEM_DOMAIN_VRAM, 379 0); 380 } 381 rb->cpp = radeon->radeonScreen->cpp; 382 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; 383 } 384 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { 385 if (!rb->bo) { 386 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 387 radeon->radeonScreen->backOffset, 388 0, 389 0, 390 RADEON_GEM_DOMAIN_VRAM, 391 0); 392 } 393 rb->cpp = radeon->radeonScreen->cpp; 394 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; 395 } 396 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { 397 if (!rb->bo) { 398 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 399 radeon->radeonScreen->depthOffset, 400 0, 401 0, 402 RADEON_GEM_DOMAIN_VRAM, 403 0); 404 } 405 rb->cpp = radeon->radeonScreen->cpp; 406 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 407 } 408 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { 409 if (!rb->bo) { 410 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 411 radeon->radeonScreen->depthOffset, 412 0, 413 0, 414 RADEON_GEM_DOMAIN_VRAM, 415 0); 416 } 417 rb->cpp = radeon->radeonScreen->cpp; 418 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 419 } 420} 421 422static void 423radeon_make_renderbuffer_current(radeonContextPtr radeon, 424 struct radeon_framebuffer *draw) 425{ 426 int size = 4096*4096*4; 427 /* if radeon->fake */ 428 struct radeon_renderbuffer *rb; 429 430 if (radeon->radeonScreen->kernel_mm) { 431 radeon_make_kernel_renderbuffer_current(radeon, draw); 432 return; 433 } 434 435 436 if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { 437 if (!rb->bo) { 438 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 439 radeon->radeonScreen->frontOffset + 440 radeon->radeonScreen->fbLocation, 441 size, 442 4096, 443 RADEON_GEM_DOMAIN_VRAM, 444 0); 445 } 446 rb->cpp = radeon->radeonScreen->cpp; 447 rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; 448 } 449 if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { 450 if (!rb->bo) { 451 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 452 radeon->radeonScreen->backOffset + 453 radeon->radeonScreen->fbLocation, 454 size, 455 4096, 456 RADEON_GEM_DOMAIN_VRAM, 457 0); 458 } 459 rb->cpp = radeon->radeonScreen->cpp; 460 rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; 461 } 462 if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { 463 if (!rb->bo) { 464 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 465 radeon->radeonScreen->depthOffset + 466 radeon->radeonScreen->fbLocation, 467 size, 468 4096, 469 RADEON_GEM_DOMAIN_VRAM, 470 0); 471 } 472 rb->cpp = radeon->radeonScreen->cpp; 473 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 474 } 475 if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { 476 if (!rb->bo) { 477 rb->bo = radeon_bo_open(radeon->radeonScreen->bom, 478 radeon->radeonScreen->depthOffset + 479 radeon->radeonScreen->fbLocation, 480 size, 481 4096, 482 RADEON_GEM_DOMAIN_VRAM, 483 0); 484 } 485 rb->cpp = radeon->radeonScreen->cpp; 486 rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; 487 } 488} 489 490static unsigned 491radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) 492{ 493 return _mesa_get_format_bytes(rb->base.Format) * 8; 494} 495 496/* 497 * Check if drawable has been invalidated by dri2InvalidateDrawable(). 498 * Update renderbuffers if so. This prevents a client from accessing 499 * a backbuffer that has a swap pending but not yet completed. 500 * 501 * See intel_prepare_render for equivalent code in intel driver. 502 * 503 */ 504void radeon_prepare_render(radeonContextPtr radeon) 505{ 506 __DRIcontext *driContext = radeon->dri.context; 507 __DRIdrawable *drawable; 508 __DRIscreen *screen; 509 510 screen = driContext->driScreenPriv; 511 if (!screen->dri2.loader) 512 return; 513 514 drawable = driContext->driDrawablePriv; 515 if (drawable->dri2.stamp != driContext->dri2.draw_stamp) { 516 if (drawable->lastStamp != drawable->dri2.stamp) 517 radeon_update_renderbuffers(driContext, drawable, GL_FALSE); 518 519 /* Intel driver does the equivalent of this, no clue if it is needed: 520 * radeon_draw_buffer(radeon->glCtx, &(drawable->driverPrivate)->base); 521 */ 522 driContext->dri2.draw_stamp = drawable->dri2.stamp; 523 } 524 525 drawable = driContext->driReadablePriv; 526 if (drawable->dri2.stamp != driContext->dri2.read_stamp) { 527 if (drawable->lastStamp != drawable->dri2.stamp) 528 radeon_update_renderbuffers(driContext, drawable, GL_FALSE); 529 driContext->dri2.read_stamp = drawable->dri2.stamp; 530 } 531} 532 533void 534radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, 535 GLboolean front_only) 536{ 537 unsigned int attachments[10]; 538 __DRIbuffer *buffers = NULL; 539 __DRIscreen *screen; 540 struct radeon_renderbuffer *rb; 541 int i, count; 542 struct radeon_framebuffer *draw; 543 radeonContextPtr radeon; 544 char *regname; 545 struct radeon_bo *depth_bo = NULL, *bo; 546 547 if (RADEON_DEBUG & RADEON_DRI) 548 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); 549 550 draw = drawable->driverPrivate; 551 screen = context->driScreenPriv; 552 radeon = (radeonContextPtr) context->driverPrivate; 553 554 /* Set this up front, so that in case our buffers get invalidated 555 * while we're getting new buffers, we don't clobber the stamp and 556 * thus ignore the invalidate. */ 557 drawable->lastStamp = drawable->dri2.stamp; 558 559 if (screen->dri2.loader 560 && (screen->dri2.loader->base.version > 2) 561 && (screen->dri2.loader->getBuffersWithFormat != NULL)) { 562 struct radeon_renderbuffer *depth_rb; 563 struct radeon_renderbuffer *stencil_rb; 564 565 i = 0; 566 if ((front_only || radeon->is_front_buffer_rendering || 567 radeon->is_front_buffer_reading || 568 !draw->color_rb[1]) 569 && draw->color_rb[0]) { 570 attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 571 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); 572 } 573 574 if (!front_only) { 575 if (draw->color_rb[1]) { 576 attachments[i++] = __DRI_BUFFER_BACK_LEFT; 577 attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]); 578 } 579 580 depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); 581 stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); 582 583 if ((depth_rb != NULL) && (stencil_rb != NULL)) { 584 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; 585 attachments[i++] = radeon_bits_per_pixel(depth_rb); 586 } else if (depth_rb != NULL) { 587 attachments[i++] = __DRI_BUFFER_DEPTH; 588 attachments[i++] = radeon_bits_per_pixel(depth_rb); 589 } else if (stencil_rb != NULL) { 590 attachments[i++] = __DRI_BUFFER_STENCIL; 591 attachments[i++] = radeon_bits_per_pixel(stencil_rb); 592 } 593 } 594 595 buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable, 596 &drawable->w, 597 &drawable->h, 598 attachments, i / 2, 599 &count, 600 drawable->loaderPrivate); 601 } else if (screen->dri2.loader) { 602 i = 0; 603 if (draw->color_rb[0]) 604 attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 605 if (!front_only) { 606 if (draw->color_rb[1]) 607 attachments[i++] = __DRI_BUFFER_BACK_LEFT; 608 if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH)) 609 attachments[i++] = __DRI_BUFFER_DEPTH; 610 if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL)) 611 attachments[i++] = __DRI_BUFFER_STENCIL; 612 } 613 614 buffers = (*screen->dri2.loader->getBuffers)(drawable, 615 &drawable->w, 616 &drawable->h, 617 attachments, i, 618 &count, 619 drawable->loaderPrivate); 620 } 621 622 if (buffers == NULL) 623 return; 624 625 /* set one cliprect to cover the whole drawable */ 626 drawable->x = 0; 627 drawable->y = 0; 628 drawable->backX = 0; 629 drawable->backY = 0; 630 drawable->numClipRects = 1; 631 drawable->pClipRects[0].x1 = 0; 632 drawable->pClipRects[0].y1 = 0; 633 drawable->pClipRects[0].x2 = drawable->w; 634 drawable->pClipRects[0].y2 = drawable->h; 635 drawable->numBackClipRects = 1; 636 drawable->pBackClipRects[0].x1 = 0; 637 drawable->pBackClipRects[0].y1 = 0; 638 drawable->pBackClipRects[0].x2 = drawable->w; 639 drawable->pBackClipRects[0].y2 = drawable->h; 640 for (i = 0; i < count; i++) { 641 switch (buffers[i].attachment) { 642 case __DRI_BUFFER_FRONT_LEFT: 643 rb = draw->color_rb[0]; 644 regname = "dri2 front buffer"; 645 break; 646 case __DRI_BUFFER_FAKE_FRONT_LEFT: 647 rb = draw->color_rb[0]; 648 regname = "dri2 fake front buffer"; 649 break; 650 case __DRI_BUFFER_BACK_LEFT: 651 rb = draw->color_rb[1]; 652 regname = "dri2 back buffer"; 653 break; 654 case __DRI_BUFFER_DEPTH: 655 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); 656 regname = "dri2 depth buffer"; 657 break; 658 case __DRI_BUFFER_DEPTH_STENCIL: 659 rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH); 660 regname = "dri2 depth / stencil buffer"; 661 break; 662 case __DRI_BUFFER_STENCIL: 663 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); 664 regname = "dri2 stencil buffer"; 665 break; 666 case __DRI_BUFFER_ACCUM: 667 default: 668 fprintf(stderr, 669 "unhandled buffer attach event, attacment type %d\n", 670 buffers[i].attachment); 671 return; 672 } 673 674 if (rb == NULL) 675 continue; 676 677 if (rb->bo) { 678 uint32_t name = radeon_gem_name_bo(rb->bo); 679 if (name == buffers[i].name) 680 continue; 681 } 682 683 if (RADEON_DEBUG & RADEON_DRI) 684 fprintf(stderr, 685 "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n", 686 regname, buffers[i].name, buffers[i].attachment, 687 buffers[i].cpp, buffers[i].pitch); 688 689 rb->cpp = buffers[i].cpp; 690 rb->pitch = buffers[i].pitch; 691 rb->base.Width = drawable->w; 692 rb->base.Height = drawable->h; 693 rb->has_surface = 0; 694 695 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { 696 if (RADEON_DEBUG & RADEON_DRI) 697 fprintf(stderr, "(reusing depth buffer as stencil)\n"); 698 bo = depth_bo; 699 radeon_bo_ref(bo); 700 } else { 701 uint32_t tiling_flags = 0, pitch = 0; 702 int ret; 703 704 bo = radeon_bo_open(radeon->radeonScreen->bom, 705 buffers[i].name, 706 0, 707 0, 708 RADEON_GEM_DOMAIN_VRAM, 709 buffers[i].flags); 710 711 if (bo == NULL) { 712 713 fprintf(stderr, "failed to attach %s %d\n", 714 regname, buffers[i].name); 715 716 } 717 718 ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch); 719 if (tiling_flags & RADEON_TILING_MACRO) 720 bo->flags |= RADEON_BO_FLAGS_MACRO_TILE; 721 if (tiling_flags & RADEON_TILING_MICRO) 722 bo->flags |= RADEON_BO_FLAGS_MICRO_TILE; 723 724 } 725 726 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) { 727 if (draw->base.Visual.depthBits == 16) 728 rb->cpp = 2; 729 depth_bo = bo; 730 } 731 732 radeon_renderbuffer_set_bo(rb, bo); 733 radeon_bo_unref(bo); 734 735 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { 736 rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL); 737 if (rb != NULL) { 738 struct radeon_bo *stencil_bo = NULL; 739 740 if (rb->bo) { 741 uint32_t name = radeon_gem_name_bo(rb->bo); 742 if (name == buffers[i].name) 743 continue; 744 } 745 746 stencil_bo = bo; 747 radeon_bo_ref(stencil_bo); 748 radeon_renderbuffer_set_bo(rb, stencil_bo); 749 radeon_bo_unref(stencil_bo); 750 } 751 } 752 } 753 754 driUpdateFramebufferSize(radeon->glCtx, drawable); 755} 756 757/* Force the context `c' to be the current context and associate with it 758 * buffer `b'. 759 */ 760GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, 761 __DRIdrawable * driDrawPriv, 762 __DRIdrawable * driReadPriv) 763{ 764 radeonContextPtr radeon; 765 struct radeon_framebuffer *drfb; 766 struct gl_framebuffer *readfb; 767 768 if (!driContextPriv) { 769 if (RADEON_DEBUG & RADEON_DRI) 770 fprintf(stderr, "%s ctx is null\n", __FUNCTION__); 771 _mesa_make_current(NULL, NULL, NULL); 772 return GL_TRUE; 773 } 774 775 radeon = (radeonContextPtr) driContextPriv->driverPrivate; 776 drfb = driDrawPriv->driverPrivate; 777 readfb = driReadPriv->driverPrivate; 778 779 if (driContextPriv->driScreenPriv->dri2.enabled) { 780 radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE); 781 if (driDrawPriv != driReadPriv) 782 radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE); 783 _mesa_reference_renderbuffer(&radeon->state.color.rb, 784 &(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base)); 785 _mesa_reference_renderbuffer(&radeon->state.depth.rb, 786 &(radeon_get_renderbuffer(&drfb->base, BUFFER_DEPTH)->base)); 787 } else { 788 radeon_make_renderbuffer_current(radeon, drfb); 789 } 790 791 if (RADEON_DEBUG & RADEON_DRI) 792 fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb); 793 794 driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); 795 if (driReadPriv != driDrawPriv) 796 driUpdateFramebufferSize(radeon->glCtx, driReadPriv); 797 798 _mesa_make_current(radeon->glCtx, &drfb->base, readfb); 799 800 _mesa_update_state(radeon->glCtx); 801 802 if (radeon->glCtx->DrawBuffer == &drfb->base) { 803 if (driDrawPriv->swap_interval == (unsigned)-1) { 804 int i; 805 driDrawPriv->vblFlags = 806 (radeon->radeonScreen->irq != 0) 807 ? driGetDefaultVBlankFlags(&radeon-> 808 optionCache) 809 : VBLANK_FLAG_NO_IRQ; 810 811 driDrawableInitVBlank(driDrawPriv); 812 drfb->vbl_waited = driDrawPriv->vblSeq; 813 814 for (i = 0; i < 2; i++) { 815 if (drfb->color_rb[i]) 816 drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; 817 } 818 819 } 820 821 radeon_window_moved(radeon); 822 radeon_draw_buffer(radeon->glCtx, &drfb->base); 823 } 824 825 826 if (RADEON_DEBUG & RADEON_DRI) 827 fprintf(stderr, "End %s\n", __FUNCTION__); 828 829 return GL_TRUE; 830} 831 832