1 /* 2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, 3 * VA Linux Systems Inc., Fremont, California. 4 * 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining 8 * a copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation on the rights to use, copy, modify, merge, 11 * publish, distribute, sublicense, and/or sell copies of the Software, 12 * and to permit persons to whom the Software is furnished to do so, 13 * subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial 17 * portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 /* 34 * Authors: 35 * Kevin E. Martin <martin (at) xfree86.org> 36 * Rickard E. Faith <faith (at) valinux.com> 37 * Gareth Hughes <gareth (at) valinux.com> 38 * 39 */ 40 41 #include <string.h> 42 #include <stdio.h> 43 #include <sys/types.h> 44 #include <sys/mman.h> 45 46 /* Driver data structures */ 47 #include "radeon.h" 48 #include "radeon_video.h" 49 #include "radeon_reg.h" 50 #include "r600_reg.h" 51 #include "radeon_macros.h" 52 #include "radeon_drm.h" 53 #include "radeon_dri.h" 54 #include "radeon_version.h" 55 56 57 /* X and server generic header files */ 58 #include "xf86.h" 59 #include "windowstr.h" 60 61 /* GLX/DRI/DRM definitions */ 62 #define _XF86DRI_SERVER_ 63 #include "GL/glxtokens.h" 64 #include "sarea.h" 65 66 #include "atipciids.h" 67 68 static size_t radeon_drm_page_size; 69 70 #define RADEON_MAX_DRAWABLES 256 71 72 extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, 73 void **configprivs); 74 75 static void RADEONDRITransitionTo2d(ScreenPtr pScreen); 76 static void RADEONDRITransitionTo3d(ScreenPtr pScreen); 77 static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen); 78 static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen); 79 80 #ifdef DAMAGE 81 static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg); 82 83 #if (DRIINFO_MAJOR_VERSION > 5 || \ 84 (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)) 85 static void RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num); 86 #endif 87 #endif 88 89 /* Initialize the visual configs that are supported by the hardware. 90 * These are combined with the visual configs that the indirect 91 * rendering core supports, and the intersection is exported to the 92 * client. 93 */ 94 static Bool RADEONInitVisualConfigs(ScreenPtr pScreen) 95 { 96 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 97 RADEONInfoPtr info = RADEONPTR(pScrn); 98 int numConfigs = 0; 99 __GLXvisualConfig *pConfigs = 0; 100 RADEONConfigPrivPtr pRADEONConfigs = 0; 101 RADEONConfigPrivPtr *pRADEONConfigPtrs = 0; 102 int i, accum, stencil, db, use_db; 103 104 use_db = !info->dri->noBackBuffer ? 1 : 0; 105 106 switch (info->CurrentLayout.pixel_code) { 107 case 8: /* 8bpp mode is not support */ 108 case 15: /* FIXME */ 109 case 24: /* FIXME */ 110 xf86DrvMsg(pScreen->myNum, X_ERROR, 111 "[dri] RADEONInitVisualConfigs failed " 112 "(depth %d not supported). " 113 "Disabling DRI.\n", info->CurrentLayout.pixel_code); 114 return FALSE; 115 116 #define RADEON_USE_ACCUM 1 117 #define RADEON_USE_STENCIL 1 118 119 case 16: 120 numConfigs = 1; 121 if (RADEON_USE_ACCUM) numConfigs *= 2; 122 if (RADEON_USE_STENCIL) numConfigs *= 2; 123 if (use_db) numConfigs *= 2; 124 125 if (!(pConfigs 126 = (__GLXvisualConfig *)calloc(sizeof(__GLXvisualConfig), 127 numConfigs))) { 128 return FALSE; 129 } 130 if (!(pRADEONConfigs 131 = (RADEONConfigPrivPtr)calloc(sizeof(RADEONConfigPrivRec), 132 numConfigs))) { 133 free(pConfigs); 134 return FALSE; 135 } 136 if (!(pRADEONConfigPtrs 137 = (RADEONConfigPrivPtr *)calloc(sizeof(RADEONConfigPrivPtr), 138 numConfigs))) { 139 free(pConfigs); 140 free(pRADEONConfigs); 141 return FALSE; 142 } 143 144 i = 0; 145 for (db = use_db; db >= 0; db--) { 146 for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) { 147 for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) { 148 pRADEONConfigPtrs[i] = &pRADEONConfigs[i]; 149 150 pConfigs[i].vid = (VisualID)(-1); 151 pConfigs[i].class = -1; 152 pConfigs[i].rgba = TRUE; 153 pConfigs[i].redSize = 5; 154 pConfigs[i].greenSize = 6; 155 pConfigs[i].blueSize = 5; 156 pConfigs[i].alphaSize = 0; 157 pConfigs[i].redMask = 0x0000F800; 158 pConfigs[i].greenMask = 0x000007E0; 159 pConfigs[i].blueMask = 0x0000001F; 160 pConfigs[i].alphaMask = 0x00000000; 161 if (accum) { /* Simulated in software */ 162 pConfigs[i].accumRedSize = 16; 163 pConfigs[i].accumGreenSize = 16; 164 pConfigs[i].accumBlueSize = 16; 165 pConfigs[i].accumAlphaSize = 0; 166 } else { 167 pConfigs[i].accumRedSize = 0; 168 pConfigs[i].accumGreenSize = 0; 169 pConfigs[i].accumBlueSize = 0; 170 pConfigs[i].accumAlphaSize = 0; 171 } 172 if (db) 173 pConfigs[i].doubleBuffer = TRUE; 174 else 175 pConfigs[i].doubleBuffer = FALSE; 176 pConfigs[i].stereo = FALSE; 177 pConfigs[i].bufferSize = 16; 178 pConfigs[i].depthSize = info->dri->depthBits; 179 if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil) 180 : stencil) { 181 pConfigs[i].stencilSize = 8; 182 } else { 183 pConfigs[i].stencilSize = 0; 184 } 185 pConfigs[i].auxBuffers = 0; 186 pConfigs[i].level = 0; 187 if (accum || 188 (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) { 189 pConfigs[i].visualRating = GLX_SLOW_CONFIG; 190 } else { 191 pConfigs[i].visualRating = GLX_NONE; 192 } 193 pConfigs[i].transparentPixel = GLX_NONE; 194 pConfigs[i].transparentRed = 0; 195 pConfigs[i].transparentGreen = 0; 196 pConfigs[i].transparentBlue = 0; 197 pConfigs[i].transparentAlpha = 0; 198 pConfigs[i].transparentIndex = 0; 199 i++; 200 } 201 } 202 } 203 break; 204 205 case 32: 206 numConfigs = 1; 207 if (RADEON_USE_ACCUM) numConfigs *= 2; 208 if (RADEON_USE_STENCIL) numConfigs *= 2; 209 if (use_db) numConfigs *= 2; 210 211 if (!(pConfigs 212 = (__GLXvisualConfig *)calloc(sizeof(__GLXvisualConfig), 213 numConfigs))) { 214 return FALSE; 215 } 216 if (!(pRADEONConfigs 217 = (RADEONConfigPrivPtr)calloc(sizeof(RADEONConfigPrivRec), 218 numConfigs))) { 219 free(pConfigs); 220 return FALSE; 221 } 222 if (!(pRADEONConfigPtrs 223 = (RADEONConfigPrivPtr *)calloc(sizeof(RADEONConfigPrivPtr), 224 numConfigs))) { 225 free(pConfigs); 226 free(pRADEONConfigs); 227 return FALSE; 228 } 229 230 i = 0; 231 for (db = use_db; db >= 0; db--) { 232 for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) { 233 for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) { 234 pRADEONConfigPtrs[i] = &pRADEONConfigs[i]; 235 236 pConfigs[i].vid = (VisualID)(-1); 237 pConfigs[i].class = -1; 238 pConfigs[i].rgba = TRUE; 239 pConfigs[i].redSize = 8; 240 pConfigs[i].greenSize = 8; 241 pConfigs[i].blueSize = 8; 242 pConfigs[i].alphaSize = 8; 243 pConfigs[i].redMask = 0x00FF0000; 244 pConfigs[i].greenMask = 0x0000FF00; 245 pConfigs[i].blueMask = 0x000000FF; 246 pConfigs[i].alphaMask = 0xFF000000; 247 if (accum) { /* Simulated in software */ 248 pConfigs[i].accumRedSize = 16; 249 pConfigs[i].accumGreenSize = 16; 250 pConfigs[i].accumBlueSize = 16; 251 pConfigs[i].accumAlphaSize = 16; 252 } else { 253 pConfigs[i].accumRedSize = 0; 254 pConfigs[i].accumGreenSize = 0; 255 pConfigs[i].accumBlueSize = 0; 256 pConfigs[i].accumAlphaSize = 0; 257 } 258 if (db) 259 pConfigs[i].doubleBuffer = TRUE; 260 else 261 pConfigs[i].doubleBuffer = FALSE; 262 pConfigs[i].stereo = FALSE; 263 pConfigs[i].bufferSize = 32; 264 pConfigs[i].depthSize = info->dri->depthBits; 265 if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil) 266 : stencil) { 267 pConfigs[i].stencilSize = 8; 268 } else { 269 pConfigs[i].stencilSize = 0; 270 } 271 pConfigs[i].auxBuffers = 0; 272 pConfigs[i].level = 0; 273 if (accum || 274 (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) { 275 pConfigs[i].visualRating = GLX_SLOW_CONFIG; 276 } else { 277 pConfigs[i].visualRating = GLX_NONE; 278 } 279 pConfigs[i].transparentPixel = GLX_NONE; 280 pConfigs[i].transparentRed = 0; 281 pConfigs[i].transparentGreen = 0; 282 pConfigs[i].transparentBlue = 0; 283 pConfigs[i].transparentAlpha = 0; 284 pConfigs[i].transparentIndex = 0; 285 i++; 286 } 287 } 288 } 289 break; 290 } 291 292 info->dri->numVisualConfigs = numConfigs; 293 info->dri->pVisualConfigs = pConfigs; 294 info->dri->pVisualConfigsPriv = pRADEONConfigs; 295 GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pRADEONConfigPtrs); 296 return TRUE; 297 } 298 299 /* Create the Radeon-specific context information */ 300 static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual, 301 drm_context_t hwContext, void *pVisualConfigPriv, 302 DRIContextType contextStore) 303 { 304 return TRUE; 305 } 306 307 /* Destroy the Radeon-specific context information */ 308 static void RADEONDestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 309 DRIContextType contextStore) 310 { 311 } 312 313 /* Called when the X server is woken up to allow the last client's 314 * context to be saved and the X server's context to be loaded. This is 315 * not necessary for the Radeon since the client detects when it's 316 * context is not currently loaded and then load's it itself. Since the 317 * registers to start and stop the CP are privileged, only the X server 318 * can start/stop the engine. 319 */ 320 static void RADEONEnterServer(ScreenPtr pScreen) 321 { 322 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 323 RADEONInfoPtr info = RADEONPTR(pScrn); 324 drm_radeon_sarea_t *pSAREAPriv; 325 326 327 RADEON_MARK_SYNC(info, pScrn); 328 329 pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); 330 if (pSAREAPriv->ctx_owner != DRIGetContext(pScrn->pScreen)) { 331 info->accel_state->XInited3D = FALSE; 332 info->cp->needCacheFlush = (info->ChipFamily >= CHIP_FAMILY_R300); 333 } 334 335 #ifdef DAMAGE 336 if (!info->dri->pDamage && info->dri->allowPageFlip) { 337 PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); 338 info->dri->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, 339 pScreen, pPix); 340 341 if (info->dri->pDamage == NULL) { 342 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 343 "No screen damage record, page flipping disabled\n"); 344 info->dri->allowPageFlip = 0; 345 } else { 346 DamageRegister(&pPix->drawable, info->dri->pDamage); 347 348 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 349 "Damage tracking initialized for page flipping\n"); 350 } 351 } 352 #endif 353 } 354 355 /* Called when the X server goes to sleep to allow the X server's 356 * context to be saved and the last client's context to be loaded. This 357 * is not necessary for the Radeon since the client detects when it's 358 * context is not currently loaded and then load's it itself. Since the 359 * registers to start and stop the CP are privileged, only the X server 360 * can start/stop the engine. 361 */ 362 static void RADEONLeaveServer(ScreenPtr pScreen) 363 { 364 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 365 RADEONInfoPtr info = RADEONPTR(pScrn); 366 RING_LOCALS; 367 368 #ifdef DAMAGE 369 if (info->dri->pDamage) { 370 RegionPtr pDamageReg = DamageRegion(info->dri->pDamage); 371 int nrects = pDamageReg ? REGION_NUM_RECTS(pDamageReg) : 0; 372 373 if (nrects) { 374 RADEONDRIRefreshArea(pScrn, pDamageReg); 375 } 376 } 377 #endif 378 379 /* The CP is always running, but if we've generated any CP commands 380 * we must flush them to the kernel module now. 381 */ 382 RADEONCP_RELEASE(pScrn, info); 383 384 #ifdef USE_EXA 385 info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN; 386 #endif 387 } 388 389 /* Contexts can be swapped by the X server if necessary. This callback 390 * is currently only used to perform any functions necessary when 391 * entering or leaving the X server, and in the future might not be 392 * necessary. 393 */ 394 static void RADEONDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 395 DRIContextType oldContextType, 396 void *oldContext, 397 DRIContextType newContextType, 398 void *newContext) 399 { 400 if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && 401 (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ 402 RADEONEnterServer(pScreen); 403 } 404 405 if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && 406 (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ 407 RADEONLeaveServer(pScreen); 408 } 409 } 410 411 #ifdef USE_XAA 412 413 /* The Radeon has depth tiling on all the time. Rely on surface regs to 414 * translate the addresses (only works if allowColorTiling is true). 415 */ 416 417 /* 16-bit depth buffer functions */ 418 #define WRITE_DEPTH16(_x, _y, d) \ 419 *(uint16_t *)(pointer)(buf + 2*(_x + _y*info->dri->frontPitch)) = (d) 420 421 #define READ_DEPTH16(d, _x, _y) \ 422 (d) = *(uint16_t *)(pointer)(buf + 2*(_x + _y*info->dri->frontPitch)) 423 424 /* 32-bit depth buffer (stencil and depth simultaneously) functions */ 425 #define WRITE_DEPTHSTENCIL32(_x, _y, d) \ 426 *(uint32_t *)(pointer)(buf + 4*(_x + _y*info->dri->frontPitch)) = (d) 427 428 #define READ_DEPTHSTENCIL32(d, _x, _y) \ 429 (d) = *(uint32_t *)(pointer)(buf + 4*(_x + _y*info->dri->frontPitch)) 430 431 /* Screen to screen copy of data in the depth buffer */ 432 static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn, 433 int xa, int ya, 434 int xb, int yb, 435 int w, int h) 436 { 437 RADEONInfoPtr info = RADEONPTR(pScrn); 438 unsigned char *buf = info->FB + info->dri->depthOffset; 439 int xstart, xend, xdir; 440 int ystart, yend, ydir; 441 int x, y, d; 442 443 if (xa < xb) xdir = -1, xstart = w-1, xend = 0; 444 else xdir = 1, xstart = 0, xend = w-1; 445 446 if (ya < yb) ydir = -1, ystart = h-1, yend = 0; 447 else ydir = 1, ystart = 0, yend = h-1; 448 449 switch (pScrn->bitsPerPixel) { 450 case 16: 451 for (x = xstart; x != xend; x += xdir) { 452 for (y = ystart; y != yend; y += ydir) { 453 READ_DEPTH16(d, xa+x, ya+y); 454 WRITE_DEPTH16(xb+x, yb+y, d); 455 } 456 } 457 break; 458 459 case 32: 460 for (x = xstart; x != xend; x += xdir) { 461 for (y = ystart; y != yend; y += ydir) { 462 READ_DEPTHSTENCIL32(d, xa+x, ya+y); 463 WRITE_DEPTHSTENCIL32(xb+x, yb+y, d); 464 } 465 } 466 break; 467 468 default: 469 break; 470 } 471 } 472 473 #endif /* USE_XAA */ 474 475 /* Initialize the state of the back and depth buffers */ 476 static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) 477 { 478 /* NOOP. There's no need for the 2d driver to be clearing buffers 479 * for the 3d client. It knows how to do that on its own. 480 */ 481 } 482 483 /* Copy the back and depth buffers when the X server moves a window. 484 * 485 * This routine is a modified form of XAADoBitBlt with the calls to 486 * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source 487 * instead of destination. My origin is upside down so the ydir cases 488 * are reversed. 489 */ 490 static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 491 RegionPtr prgnSrc, CARD32 indx) 492 { 493 #ifdef USE_XAA 494 ScreenPtr pScreen = pParent->drawable.pScreen; 495 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 496 RADEONInfoPtr info = RADEONPTR(pScrn); 497 498 BoxPtr pboxTmp, pboxNext, pboxBase; 499 DDXPointPtr pptTmp; 500 int xdir, ydir; 501 502 int screenwidth = pScrn->virtualX; 503 int screenheight = pScrn->virtualY; 504 505 BoxPtr pbox = REGION_RECTS(prgnSrc); 506 int nbox = REGION_NUM_RECTS(prgnSrc); 507 508 BoxPtr pboxNew1 = NULL; 509 BoxPtr pboxNew2 = NULL; 510 DDXPointPtr pptNew1 = NULL; 511 DDXPointPtr pptNew2 = NULL; 512 DDXPointPtr pptSrc = &ptOldOrg; 513 514 int dx = pParent->drawable.x - ptOldOrg.x; 515 int dy = pParent->drawable.y - ptOldOrg.y; 516 517 /* XXX: Fix in EXA case. */ 518 if (info->useEXA) 519 return; 520 521 /* If the copy will overlap in Y, reverse the order */ 522 if (dy > 0) { 523 ydir = -1; 524 525 if (nbox > 1) { 526 /* Keep ordering in each band, reverse order of bands */ 527 pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec)*nbox); 528 if (!pboxNew1) return; 529 530 pptNew1 = (DDXPointPtr)malloc(sizeof(DDXPointRec)*nbox); 531 if (!pptNew1) { 532 free(pboxNew1); 533 return; 534 } 535 536 pboxBase = pboxNext = pbox+nbox-1; 537 538 while (pboxBase >= pbox) { 539 while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) 540 pboxNext--; 541 542 pboxTmp = pboxNext+1; 543 pptTmp = pptSrc + (pboxTmp - pbox); 544 545 while (pboxTmp <= pboxBase) { 546 *pboxNew1++ = *pboxTmp++; 547 *pptNew1++ = *pptTmp++; 548 } 549 550 pboxBase = pboxNext; 551 } 552 553 pboxNew1 -= nbox; 554 pbox = pboxNew1; 555 pptNew1 -= nbox; 556 pptSrc = pptNew1; 557 } 558 } else { 559 /* No changes required */ 560 ydir = 1; 561 } 562 563 /* If the regions will overlap in X, reverse the order */ 564 if (dx > 0) { 565 xdir = -1; 566 567 if (nbox > 1) { 568 /* reverse order of rects in each band */ 569 pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec)*nbox); 570 pptNew2 = (DDXPointPtr)malloc(sizeof(DDXPointRec)*nbox); 571 572 if (!pboxNew2 || !pptNew2) { 573 free(pptNew2); 574 free(pboxNew2); 575 free(pptNew1); 576 free(pboxNew1); 577 return; 578 } 579 580 pboxBase = pboxNext = pbox; 581 582 while (pboxBase < pbox+nbox) { 583 while ((pboxNext < pbox+nbox) 584 && (pboxNext->y1 == pboxBase->y1)) 585 pboxNext++; 586 587 pboxTmp = pboxNext; 588 pptTmp = pptSrc + (pboxTmp - pbox); 589 590 while (pboxTmp != pboxBase) { 591 *pboxNew2++ = *--pboxTmp; 592 *pptNew2++ = *--pptTmp; 593 } 594 595 pboxBase = pboxNext; 596 } 597 598 pboxNew2 -= nbox; 599 pbox = pboxNew2; 600 pptNew2 -= nbox; 601 pptSrc = pptNew2; 602 } 603 } else { 604 /* No changes are needed */ 605 xdir = 1; 606 } 607 608 /* pretty much a hack. */ 609 info->accel_state->dst_pitch_offset = info->dri->backPitchOffset; 610 if (info->tilingEnabled) 611 info->accel_state->dst_pitch_offset |= RADEON_DST_TILE_MACRO; 612 613 (*info->accel_state->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, 614 (uint32_t)(-1), -1); 615 616 for (; nbox-- ; pbox++) { 617 int xa = pbox->x1; 618 int ya = pbox->y1; 619 int destx = xa + dx; 620 int desty = ya + dy; 621 int w = pbox->x2 - xa + 1; 622 int h = pbox->y2 - ya + 1; 623 624 if (destx < 0) xa -= destx, w += destx, destx = 0; 625 if (desty < 0) ya -= desty, h += desty, desty = 0; 626 if (destx + w > screenwidth) w = screenwidth - destx; 627 if (desty + h > screenheight) h = screenheight - desty; 628 629 if (w <= 0) continue; 630 if (h <= 0) continue; 631 632 (*info->accel_state->accel->SubsequentScreenToScreenCopy)(pScrn, 633 xa, ya, 634 destx, desty, 635 w, h); 636 637 if (info->dri->depthMoves) { 638 RADEONScreenToScreenCopyDepth(pScrn, 639 xa, ya, 640 destx, desty, 641 w, h); 642 } 643 } 644 645 info->accel_state->dst_pitch_offset = info->dri->frontPitchOffset;; 646 647 free(pptNew2); 648 free(pboxNew2); 649 free(pptNew1); 650 free(pboxNew1); 651 652 info->accel_state->accel->NeedToSync = TRUE; 653 #endif /* USE_XAA */ 654 } 655 656 static void RADEONDRIInitGARTValues(RADEONInfoPtr info) 657 { 658 int s, l; 659 660 info->dri->gartOffset = 0; 661 662 /* Initialize the CP ring buffer data */ 663 info->dri->ringStart = info->dri->gartOffset; 664 info->dri->ringMapSize = info->dri->ringSize*1024*1024 + radeon_drm_page_size; 665 info->dri->ringSizeLog2QW = RADEONMinBits(info->dri->ringSize*1024*1024/8)-1; 666 667 info->dri->ringReadOffset = info->dri->ringStart + info->dri->ringMapSize; 668 info->dri->ringReadMapSize = radeon_drm_page_size; 669 670 /* Reserve space for vertex/indirect buffers */ 671 info->dri->bufStart = info->dri->ringReadOffset + info->dri->ringReadMapSize; 672 info->dri->bufMapSize = info->dri->bufSize*1024*1024; 673 674 /* Reserve the rest for GART textures */ 675 info->dri->gartTexStart = info->dri->bufStart + info->dri->bufMapSize; 676 s = (info->dri->gartSize*1024*1024 - info->dri->gartTexStart); 677 l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); 678 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; 679 info->dri->gartTexMapSize = (s >> l) << l; 680 info->dri->log2GARTTexGran = l; 681 } 682 683 /* AGP Mode Quirk List - Certain hostbridge/gfx-card combos don't work with 684 * the standard AGPMode settings, so we detect and handle these 685 * on a case-by-base basis with quirks. To see if an AGPMode is valid, test 686 * it by setting Option "AGPMode" "1" (or "2", or "4", or "8"). */ 687 typedef struct { 688 unsigned int hostbridgeVendor; 689 unsigned int hostbridgeDevice; 690 unsigned int chipVendor; 691 unsigned int chipDevice; 692 unsigned int subsysVendor; 693 unsigned int subsysDevice; 694 unsigned int defaultMode; 695 } radeon_agpmode_quirk, *radeon_agpmode_quirk_ptr; 696 697 /* Keep sorted by hostbridge vendor and device */ 698 static radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { 699 700 /* Intel E7505 Memory Controller Hub / RV350 AR [Radeon 9600XT] Needs AGPMode 4 (deb #515326) */ 701 { PCI_VENDOR_INTEL,0x2550, PCI_VENDOR_ATI,0x4152, 0x1458,0x4038, 4 }, 702 /* Intel 82865G/PE/P DRAM Controller/Host-Hub / Mobility 9800 Needs AGPMode 4 (deb #462590) */ 703 { PCI_VENDOR_INTEL,0x2570, PCI_VENDOR_ATI,0x4a4e, PCI_VENDOR_DELL,0x5106, 4 }, 704 /* Intel 82865G/PE/P DRAM Controller/Host-Hub / RV280 [Radeon 9200 SE] Needs AGPMode 4 (lp #300304) */ 705 { PCI_VENDOR_INTEL,0x2570, PCI_VENDOR_ATI,0x5964, 0x148c,0x2073, 4 }, 706 /* Intel 82855PM host bridge / Mobility M7 LW Needs AGPMode 4 (lp: #353996) */ 707 { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x4c57, PCI_VENDOR_IBM,0x0530, 4 }, 708 /* Intel 82855PM Processor to I/O Controller / Mobility M6 LY Needs AGPMode 1 (deb #467235) */ 709 { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x4c59, PCI_VENDOR_IBM,0x052f, 1 }, 710 /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */ 711 { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x4e50, PCI_VENDOR_IBM,0x0550, 1 }, 712 /* Intel 82855PM host bridge / FireGL Mobility T2 RV350 Needs AGPMode 2 (fdo #20647) */ 713 { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x4e54, PCI_VENDOR_IBM,0x054f, 2 }, 714 /* Intel 82855PM host bridge / Mobility M9+ / VaioPCG-V505DX Needs AGPMode 2 (fdo #17928) */ 715 { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x5c61, PCI_VENDOR_SONY,0x816b, 2 }, 716 /* Intel 82855PM Processor to I/O Controller / Mobility M9+ Needs AGPMode 8 (phoronix forum) */ 717 { PCI_VENDOR_INTEL,0x3340, PCI_VENDOR_ATI,0x5c61, PCI_VENDOR_SONY,0x8195, 8 }, 718 /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ 719 { PCI_VENDOR_INTEL,0x3575, PCI_VENDOR_ATI,0x4c59, PCI_VENDOR_DELL,0x00e3, 2 }, 720 /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ 721 { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4c66, PCI_VENDOR_DELL,0x0149, 1 }, 722 /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ 723 { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4e50, 0x1025,0x0061, 1 }, 724 /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #203007) */ 725 { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4e50, 0x1025,0x0064, 1 }, 726 /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #141551) */ 727 { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4e50, PCI_VENDOR_ASUS,0x1942, 1 }, 728 /* Intel 82852/82855 host bridge / Mobility 9600/9700 Needs AGPMode 1 (deb #510208) */ 729 { PCI_VENDOR_INTEL,0x3580, PCI_VENDOR_ATI,0x4e50, 0x10cf,0x127f, 1 }, 730 /* Intel 82443BX/ZX/DX Host bridge / RV280 [Radeon 9200] Needs AGPMode 1 (lp #370205) */ 731 { PCI_VENDOR_INTEL,0x7190, PCI_VENDOR_ATI,0x5961, 0x174b,0x7c13, 1 }, 732 733 /* Ali Corp M1671 Super P4 Northbridge / Mobility M6 LY Needs AGPMode 1 (lp #146303)*/ 734 { 0x10b9,0x1671, PCI_VENDOR_ATI,0x4c59, 0x103c,0x0027, 1 }, 735 736 /* SiS Host Bridge 655 / R420 [Radeon X800] Needs AGPMode 4 (lp #371296) */ 737 { 0x1039,0x0655, PCI_VENDOR_ATI,0x4a4b, PCI_VENDOR_ATI,0x4422, 4 }, 738 /* SiS Host Bridge / RV280 Needs AGPMode 4 */ 739 { 0x1039,0x0741, PCI_VENDOR_ATI,0x5964, 0x148c,0x2073, 4 }, 740 741 /* ASRock K7VT4A+ AGP 8x / ATI Radeon 9250 AGP Needs AGPMode 4 (lp #133192) */ 742 { 0x1849,0x3189, PCI_VENDOR_ATI,0x5960, 0x1787,0x5960, 4 }, 743 744 /* VIA K8M800 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (fdo #12544) */ 745 { PCI_VENDOR_VIA,0x0204, PCI_VENDOR_ATI,0x5960, 0x17af,0x2020, 4 }, 746 /* VIA KT880 Host Bridge / RV350 [Radeon 9550] Needs AGPMode 4 (fdo #19981) */ 747 { PCI_VENDOR_VIA,0x0269, PCI_VENDOR_ATI,0x4153, PCI_VENDOR_ASUS,0x003c, 4 }, 748 /* VIA VT8363 Host Bridge / R200 QL [Radeon 8500] Needs AGPMode 2 (lp #141551) */ 749 { PCI_VENDOR_VIA,0x0305, PCI_VENDOR_ATI,0x514c, PCI_VENDOR_ATI,0x013a, 2 }, 750 /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 (deb #515512) */ 751 { PCI_VENDOR_VIA,0x0691, PCI_VENDOR_ATI,0x5960, PCI_VENDOR_ASUS,0x004c, 2 }, 752 /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 */ 753 { PCI_VENDOR_VIA,0x0691, PCI_VENDOR_ATI,0x5960, PCI_VENDOR_ASUS,0x0054, 2 }, 754 /* VIA VT8377 Host Bridge / R200 QM [Radeon 9100] Needs AGPMode 4 (deb #461144) */ 755 { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x514d, 0x174b,0x7149, 4 }, 756 /* VIA VT8377 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (lp #312693) */ 757 { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5960, 0x1462,0x0380, 4 }, 758 /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (ati ML) */ 759 { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5964, 0x148c,0x2073, 4 }, 760 /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (fdo #12544) */ 761 { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5964, PCI_VENDOR_ASUS,0xc008, 4 }, 762 /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (deb #545040) */ 763 { PCI_VENDOR_VIA,0x3189, PCI_VENDOR_ATI,0x5960, PCI_VENDOR_ASUS,0x004c, 4 }, 764 765 /* ATI Host Bridge / RV280 [M9+] Needs AGPMode 1 (phoronix forum) */ 766 { PCI_VENDOR_ATI,0xcbb2, PCI_VENDOR_ATI,0x5c61, PCI_VENDOR_SONY,0x8175, 1 }, 767 768 /* HP Host Bridge / R300 [FireGL X1] Needs AGPMode 2 (fdo #7770) */ 769 { PCI_VENDOR_HP,0x122e, PCI_VENDOR_ATI,0x4e47, PCI_VENDOR_ATI,0x0152, 2 }, 770 771 /* nVidia Host Bridge / R420 [X800 Pro] Needs AGPMode 4 (fdo #22726) */ 772 { 0x10de,0x00e1, PCI_VENDOR_ATI,0x4a49, PCI_VENDOR_ATI,0x0002, 4 }, 773 774 { 0, 0, 0, 0, 0, 0, 0 }, 775 }; 776 777 /* Set AGP transfer mode according to requests and constraints */ 778 static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen) 779 { 780 unsigned char *RADEONMMIO = info->MMIO; 781 unsigned long mode = drmAgpGetMode(info->dri->drmFD); /* Default mode */ 782 unsigned int vendor = drmAgpVendorId(info->dri->drmFD); 783 unsigned int device = drmAgpDeviceId(info->dri->drmFD); 784 785 if (info->ChipFamily < CHIP_FAMILY_R600) { 786 /* ignore agp 3.0 mode bit from the chip as it's buggy on some cards with 787 pcie-agp rialto bridge chip - use the one from bridge which must match */ 788 uint32_t agp_status = (INREG(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode; 789 Bool is_v3 = (agp_status & RADEON_AGPv3_MODE); 790 unsigned int defaultMode; 791 MessageType from; 792 793 if (is_v3) { 794 defaultMode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; 795 } else { 796 if (agp_status & RADEON_AGP_4X_MODE) defaultMode = 4; 797 else if (agp_status & RADEON_AGP_2X_MODE) defaultMode = 2; 798 else defaultMode = 1; 799 } 800 801 /* Apply AGPMode Quirks */ 802 radeon_agpmode_quirk_ptr p = radeon_agpmode_quirk_list; 803 while (p && p->chipDevice != 0) { 804 if (vendor == p->hostbridgeVendor && 805 device == p->hostbridgeDevice && 806 PCI_DEV_VENDOR_ID(info->PciInfo) == p->chipVendor && 807 PCI_DEV_DEVICE_ID(info->PciInfo) == p->chipDevice && 808 PCI_SUB_VENDOR_ID(info->PciInfo) == p->subsysVendor && 809 PCI_SUB_DEVICE_ID(info->PciInfo) == p->subsysDevice) 810 { 811 defaultMode = p->defaultMode; 812 } 813 ++p; 814 } 815 816 from = X_DEFAULT; 817 818 if (xf86GetOptValInteger(info->Options, OPTION_AGP_MODE, &info->dri->agpMode)) { 819 if ((info->dri->agpMode < (is_v3 ? 4 : 1)) || 820 (info->dri->agpMode > (is_v3 ? 8 : 4)) || 821 (info->dri->agpMode & (info->dri->agpMode - 1))) { 822 xf86DrvMsg(pScreen->myNum, X_ERROR, 823 "Illegal AGP Mode: %d (valid values: %s), leaving at " 824 "%dx\n", info->dri->agpMode, is_v3 ? "4, 8" : "1, 2, 4", 825 defaultMode); 826 info->dri->agpMode = defaultMode; 827 } else 828 from = X_CONFIG; 829 } else 830 info->dri->agpMode = defaultMode; 831 832 xf86DrvMsg(pScreen->myNum, from, "Using AGP %dx\n", info->dri->agpMode); 833 834 mode &= ~RADEON_AGP_MODE_MASK; 835 if (is_v3) { 836 /* only set one mode bit for AGPv3 */ 837 switch (info->dri->agpMode) { 838 case 8: mode |= RADEON_AGPv3_8X_MODE; break; 839 case 4: default: mode |= RADEON_AGPv3_4X_MODE; 840 } 841 /*TODO: need to take care of other bits valid for v3 mode 842 * currently these bits are not used in all tested cards. 843 */ 844 } else { 845 switch (info->dri->agpMode) { 846 case 4: mode |= RADEON_AGP_4X_MODE; 847 case 2: mode |= RADEON_AGP_2X_MODE; 848 case 1: default: mode |= RADEON_AGP_1X_MODE; 849 } 850 } 851 852 /* AGP Fast Writes. 853 * TODO: take into account that certain agp modes don't support fast 854 * writes at all */ 855 mode &= ~RADEON_AGP_FW_MODE; /* Disable per default */ 856 if (xf86ReturnOptValBool(info->Options, OPTION_AGP_FW, FALSE)) { 857 xf86DrvMsg(pScreen->myNum, X_WARNING, 858 "WARNING: Using the AGPFastWrite option is not recommended.\n"); 859 xf86Msg(X_NONE, "\tThis option does not provide much of a noticable speed" 860 " boost, while it\n\twill probably hard lock your machine." 861 " All bets are off!\n"); 862 863 /* Black list some host/AGP bridges. */ 864 if ((vendor == PCI_VENDOR_AMD) && (device == PCI_CHIP_AMD761)) 865 xf86DrvMsg(pScreen->myNum, X_PROBED, "Ignoring AGPFastWrite option " 866 "for the AMD 761 northbridge.\n"); 867 else { 868 xf86DrvMsg(pScreen->myNum, X_CONFIG, "Enabling AGP Fast Writes.\n"); 869 mode |= RADEON_AGP_FW_MODE; 870 } 871 } /* Don't mention this otherwise, so that people don't get funny ideas */ 872 } else 873 info->dri->agpMode = 8; /* doesn't matter at this point */ 874 875 xf86DrvMsg(pScreen->myNum, X_INFO, 876 "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x 0x%04x/0x%04x]\n", 877 mode, vendor, device, 878 PCI_DEV_VENDOR_ID(info->PciInfo), 879 PCI_DEV_DEVICE_ID(info->PciInfo), 880 PCI_SUB_VENDOR_ID(info->PciInfo), 881 PCI_SUB_DEVICE_ID(info->PciInfo)); 882 883 if (drmAgpEnable(info->dri->drmFD, mode) < 0) { 884 xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n"); 885 drmAgpRelease(info->dri->drmFD); 886 return FALSE; 887 } 888 889 /* Workaround for some hardware bugs */ 890 if (info->ChipFamily < CHIP_FAMILY_R200) 891 OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000); 892 893 /* Modify the mode if the default mode 894 * is not appropriate for this 895 * particular combination of graphics 896 * card and AGP chipset. 897 */ 898 899 return TRUE; 900 } 901 902 /* Initialize Radeon's AGP registers */ 903 static void RADEONSetAgpBase(RADEONInfoPtr info, ScreenPtr pScreen) 904 { 905 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 906 unsigned char *RADEONMMIO = info->MMIO; 907 908 if (info->ChipFamily >= CHIP_FAMILY_R600) 909 return; 910 911 /* drm already does this, so we can probably remove this. 912 * agp_base_2 ? 913 */ 914 if (info->ChipFamily == CHIP_FAMILY_RV515) 915 OUTMC(pScrn, RV515_MC_AGP_BASE, drmAgpBase(info->dri->drmFD)); 916 else if ((info->ChipFamily >= CHIP_FAMILY_R520) && 917 (info->ChipFamily <= CHIP_FAMILY_RV570)) 918 OUTMC(pScrn, R520_MC_AGP_BASE, drmAgpBase(info->dri->drmFD)); 919 else if ((info->ChipFamily == CHIP_FAMILY_RS690) || 920 (info->ChipFamily == CHIP_FAMILY_RS740)) 921 OUTMC(pScrn, RS690_MC_AGP_BASE, drmAgpBase(info->dri->drmFD)); 922 else if (info->ChipFamily < CHIP_FAMILY_RV515) 923 OUTREG(RADEON_AGP_BASE, drmAgpBase(info->dri->drmFD)); 924 } 925 926 /* Initialize the AGP state. Request memory for use in AGP space, and 927 * initialize the Radeon registers to point to that memory. 928 */ 929 static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen) 930 { 931 int ret; 932 933 if (drmAgpAcquire(info->dri->drmFD) < 0) { 934 xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n"); 935 return FALSE; 936 } 937 938 if (!RADEONSetAgpMode(info, pScreen)) 939 return FALSE; 940 941 RADEONDRIInitGARTValues(info); 942 943 if ((ret = drmAgpAlloc(info->dri->drmFD, info->dri->gartSize*1024*1024, 0, NULL, 944 &info->dri->agpMemHandle)) < 0) { 945 xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret); 946 drmAgpRelease(info->dri->drmFD); 947 return FALSE; 948 } 949 xf86DrvMsg(pScreen->myNum, X_INFO, 950 "[agp] %d kB allocated with handle 0x%08x\n", 951 info->dri->gartSize*1024, 952 (unsigned int)info->dri->agpMemHandle); 953 954 if (drmAgpBind(info->dri->drmFD, 955 info->dri->agpMemHandle, info->dri->gartOffset) < 0) { 956 xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n"); 957 drmAgpFree(info->dri->drmFD, info->dri->agpMemHandle); 958 drmAgpRelease(info->dri->drmFD); 959 return FALSE; 960 } 961 962 if (drmAddMap(info->dri->drmFD, info->dri->ringStart, info->dri->ringMapSize, 963 DRM_AGP, DRM_READ_ONLY, &info->dri->ringHandle) < 0) { 964 xf86DrvMsg(pScreen->myNum, X_ERROR, 965 "[agp] Could not add ring mapping\n"); 966 return FALSE; 967 } 968 xf86DrvMsg(pScreen->myNum, X_INFO, 969 "[agp] ring handle = 0x%08x\n", 970 (unsigned int)info->dri->ringHandle); 971 972 if (drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize, 973 &info->dri->ring) < 0) { 974 xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n"); 975 return FALSE; 976 } 977 xf86DrvMsg(pScreen->myNum, X_INFO, 978 "[agp] Ring mapped at 0x%08lx\n", 979 (unsigned long)info->dri->ring); 980 981 if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize, 982 DRM_AGP, DRM_READ_ONLY, &info->dri->ringReadPtrHandle) < 0) { 983 xf86DrvMsg(pScreen->myNum, X_ERROR, 984 "[agp] Could not add ring read ptr mapping\n"); 985 return FALSE; 986 } 987 xf86DrvMsg(pScreen->myNum, X_INFO, 988 "[agp] ring read ptr handle = 0x%08x\n", 989 (unsigned int)info->dri->ringReadPtrHandle); 990 991 if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize, 992 &info->dri->ringReadPtr) < 0) { 993 xf86DrvMsg(pScreen->myNum, X_ERROR, 994 "[agp] Could not map ring read ptr\n"); 995 return FALSE; 996 } 997 xf86DrvMsg(pScreen->myNum, X_INFO, 998 "[agp] Ring read ptr mapped at 0x%08lx\n", 999 (unsigned long)info->dri->ringReadPtr); 1000 1001 if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize, 1002 DRM_AGP, 0, &info->dri->bufHandle) < 0) { 1003 xf86DrvMsg(pScreen->myNum, X_ERROR, 1004 "[agp] Could not add vertex/indirect buffers mapping\n"); 1005 return FALSE; 1006 } 1007 xf86DrvMsg(pScreen->myNum, X_INFO, 1008 "[agp] vertex/indirect buffers handle = 0x%08x\n", 1009 (unsigned int)info->dri->bufHandle); 1010 1011 if (drmMap(info->dri->drmFD, info->dri->bufHandle, info->dri->bufMapSize, 1012 &info->dri->buf) < 0) { 1013 xf86DrvMsg(pScreen->myNum, X_ERROR, 1014 "[agp] Could not map vertex/indirect buffers\n"); 1015 return FALSE; 1016 } 1017 xf86DrvMsg(pScreen->myNum, X_INFO, 1018 "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", 1019 (unsigned long)info->dri->buf); 1020 1021 if (drmAddMap(info->dri->drmFD, info->dri->gartTexStart, info->dri->gartTexMapSize, 1022 DRM_AGP, 0, &info->dri->gartTexHandle) < 0) { 1023 xf86DrvMsg(pScreen->myNum, X_ERROR, 1024 "[agp] Could not add GART texture map mapping\n"); 1025 return FALSE; 1026 } 1027 xf86DrvMsg(pScreen->myNum, X_INFO, 1028 "[agp] GART texture map handle = 0x%08x\n", 1029 (unsigned int)info->dri->gartTexHandle); 1030 1031 if (drmMap(info->dri->drmFD, info->dri->gartTexHandle, info->dri->gartTexMapSize, 1032 &info->dri->gartTex) < 0) { 1033 xf86DrvMsg(pScreen->myNum, X_ERROR, 1034 "[agp] Could not map GART texture map\n"); 1035 return FALSE; 1036 } 1037 xf86DrvMsg(pScreen->myNum, X_INFO, 1038 "[agp] GART Texture map mapped at 0x%08lx\n", 1039 (unsigned long)info->dri->gartTex); 1040 1041 RADEONSetAgpBase(info, pScreen); 1042 1043 return TRUE; 1044 } 1045 1046 /* Initialize the PCI GART state. Request memory for use in PCI space, 1047 * and initialize the Radeon registers to point to that memory. 1048 */ 1049 static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen) 1050 { 1051 int ret; 1052 int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; 1053 1054 ret = drmScatterGatherAlloc(info->dri->drmFD, info->dri->gartSize*1024*1024, 1055 &info->dri->pciMemHandle); 1056 if (ret < 0) { 1057 xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret); 1058 return FALSE; 1059 } 1060 xf86DrvMsg(pScreen->myNum, X_INFO, 1061 "[pci] %d kB allocated with handle 0x%08lx\n", 1062 info->dri->gartSize*1024, info->dri->pciMemHandle); 1063 1064 RADEONDRIInitGARTValues(info); 1065 1066 if (drmAddMap(info->dri->drmFD, info->dri->ringStart, info->dri->ringMapSize, 1067 DRM_SCATTER_GATHER, flags, &info->dri->ringHandle) < 0) { 1068 xf86DrvMsg(pScreen->myNum, X_ERROR, 1069 "[pci] Could not add ring mapping\n"); 1070 return FALSE; 1071 } 1072 xf86DrvMsg(pScreen->myNum, X_INFO, 1073 "[pci] ring handle = 0x%08lx, size = 0x%08x\n", info->dri->ringHandle, info->dri->ringMapSize); 1074 1075 if ((ret = drmMap(info->dri->drmFD, info->dri->ringHandle, info->dri->ringMapSize, 1076 &info->dri->ring)) < 0) { 1077 xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring: ret %d\n", ret); 1078 return FALSE; 1079 } 1080 xf86DrvMsg(pScreen->myNum, X_INFO, 1081 "[pci] Ring mapped at 0x%08lx\n", 1082 (unsigned long)info->dri->ring); 1083 xf86DrvMsg(pScreen->myNum, X_INFO, 1084 "[pci] Ring contents 0x%08lx\n", 1085 *(unsigned long *)(pointer)info->dri->ring); 1086 1087 if (drmAddMap(info->dri->drmFD, info->dri->ringReadOffset, info->dri->ringReadMapSize, 1088 DRM_SCATTER_GATHER, flags, &info->dri->ringReadPtrHandle) < 0) { 1089 xf86DrvMsg(pScreen->myNum, X_ERROR, 1090 "[pci] Could not add ring read ptr mapping\n"); 1091 return FALSE; 1092 } 1093 xf86DrvMsg(pScreen->myNum, X_INFO, 1094 "[pci] ring read ptr handle = 0x%08lx\n", 1095 info->dri->ringReadPtrHandle); 1096 1097 if (drmMap(info->dri->drmFD, info->dri->ringReadPtrHandle, info->dri->ringReadMapSize, 1098 &info->dri->ringReadPtr) < 0) { 1099 xf86DrvMsg(pScreen->myNum, X_ERROR, 1100 "[pci] Could not map ring read ptr\n"); 1101 return FALSE; 1102 } 1103 xf86DrvMsg(pScreen->myNum, X_INFO, 1104 "[pci] Ring read ptr mapped at 0x%08lx\n", 1105 (unsigned long)info->dri->ringReadPtr); 1106 xf86DrvMsg(pScreen->myNum, X_INFO, 1107 "[pci] Ring read ptr contents 0x%08lx\n", 1108 *(unsigned long *)(pointer)info->dri->ringReadPtr); 1109 1110 if (drmAddMap(info->dri->drmFD, info->dri->bufStart, info->dri->bufMapSize, 1111 DRM_SCATTER_GATHER, 0, &info->dri->bufHandle) < 0) { 1112 xf86DrvMsg(pScreen->myNum, X_ERROR, 1113 "[pci] Could not add vertex/indirect buffers mapping\n"); 1114 return FALSE; 1115 } 1116 xf86DrvMsg(pScreen->myNum, X_INFO, 1117 "[pci] vertex/indirect buffers handle = 0x%08lx\n", 1118 info->dri->bufHandle); 1119 1120 if (drmMap(info->dri->drmFD, info->dri->bufHandle, info->dri->bufMapSize, 1121 &info->dri->buf) < 0) { 1122 xf86DrvMsg(pScreen->myNum, X_ERROR, 1123 "[pci] Could not map vertex/indirect buffers\n"); 1124 return FALSE; 1125 } 1126 xf86DrvMsg(pScreen->myNum, X_INFO, 1127 "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", 1128 (unsigned long)info->dri->buf); 1129 xf86DrvMsg(pScreen->myNum, X_INFO, 1130 "[pci] Vertex/indirect buffers contents 0x%08lx\n", 1131 *(unsigned long *)(pointer)info->dri->buf); 1132 1133 if (drmAddMap(info->dri->drmFD, info->dri->gartTexStart, info->dri->gartTexMapSize, 1134 DRM_SCATTER_GATHER, 0, &info->dri->gartTexHandle) < 0) { 1135 xf86DrvMsg(pScreen->myNum, X_ERROR, 1136 "[pci] Could not add GART texture map mapping\n"); 1137 return FALSE; 1138 } 1139 xf86DrvMsg(pScreen->myNum, X_INFO, 1140 "[pci] GART texture map handle = 0x%08lx\n", 1141 info->dri->gartTexHandle); 1142 1143 if (drmMap(info->dri->drmFD, info->dri->gartTexHandle, info->dri->gartTexMapSize, 1144 &info->dri->gartTex) < 0) { 1145 xf86DrvMsg(pScreen->myNum, X_ERROR, 1146 "[pci] Could not map GART texture map\n"); 1147 return FALSE; 1148 } 1149 xf86DrvMsg(pScreen->myNum, X_INFO, 1150 "[pci] GART Texture map mapped at 0x%08lx\n", 1151 (unsigned long)info->dri->gartTex); 1152 1153 return TRUE; 1154 } 1155 1156 /* Add a map for the MMIO registers that will be accessed by any 1157 * DRI-based clients. 1158 */ 1159 static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen) 1160 { 1161 /* Map registers */ 1162 info->dri->registerSize = info->MMIOSize; 1163 if (drmAddMap(info->dri->drmFD, info->MMIOAddr, info->dri->registerSize, 1164 DRM_REGISTERS, DRM_READ_ONLY, &info->dri->registerHandle) < 0) { 1165 return FALSE; 1166 } 1167 xf86DrvMsg(pScreen->myNum, X_INFO, 1168 "[drm] register handle = 0x%08lx\n", info->dri->registerHandle); 1169 1170 return TRUE; 1171 } 1172 1173 /* Initialize the kernel data structures */ 1174 static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) 1175 { 1176 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1177 int cpp = info->CurrentLayout.pixel_bytes; 1178 drm_radeon_init_t drmInfo; 1179 1180 memset(&drmInfo, 0, sizeof(drm_radeon_init_t)); 1181 if ( info->ChipFamily >= CHIP_FAMILY_R600 ) 1182 drmInfo.func = RADEON_INIT_R600_CP; 1183 else if ( info->ChipFamily >= CHIP_FAMILY_R300 ) 1184 drmInfo.func = RADEON_INIT_R300_CP; 1185 else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) 1186 drmInfo.func = RADEON_INIT_R200_CP; 1187 else 1188 drmInfo.func = RADEON_INIT_CP; 1189 1190 drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); 1191 drmInfo.is_pci = (info->cardType!=CARD_AGP); 1192 drmInfo.cp_mode = RADEON_CSQ_PRIBM_INDBM; 1193 drmInfo.gart_size = info->dri->gartSize*1024*1024; 1194 drmInfo.ring_size = info->dri->ringSize*1024*1024; 1195 drmInfo.usec_timeout = info->cp->CPusecTimeout; 1196 1197 drmInfo.fb_bpp = info->CurrentLayout.pixel_code; 1198 drmInfo.depth_bpp = (info->dri->depthBits - 8) * 2; 1199 1200 drmInfo.front_offset = info->dri->frontOffset; 1201 drmInfo.front_pitch = info->dri->frontPitch * cpp; 1202 drmInfo.back_offset = info->dri->backOffset; 1203 drmInfo.back_pitch = info->dri->backPitch * cpp; 1204 drmInfo.depth_offset = info->dri->depthOffset; 1205 drmInfo.depth_pitch = info->dri->depthPitch * drmInfo.depth_bpp / 8; 1206 1207 drmInfo.fb_offset = info->dri->fbHandle; 1208 drmInfo.mmio_offset = info->dri->registerHandle; 1209 drmInfo.ring_offset = info->dri->ringHandle; 1210 drmInfo.ring_rptr_offset = info->dri->ringReadPtrHandle; 1211 drmInfo.buffers_offset = info->dri->bufHandle; 1212 drmInfo.gart_textures_offset= info->dri->gartTexHandle; 1213 1214 if (drmCommandWrite(info->dri->drmFD, DRM_RADEON_CP_INIT, 1215 &drmInfo, sizeof(drm_radeon_init_t)) < 0) 1216 return FALSE; 1217 1218 /* DRM_RADEON_CP_INIT does an engine reset, which resets some engine 1219 * registers back to their default values, so we need to restore 1220 * those engine register here. 1221 */ 1222 if (info->ChipFamily < CHIP_FAMILY_R600) 1223 RADEONEngineRestore(pScrn); 1224 1225 return TRUE; 1226 } 1227 1228 static void RADEONDRIGartHeapInit(RADEONInfoPtr info, ScreenPtr pScreen) 1229 { 1230 drm_radeon_mem_init_heap_t drmHeap; 1231 1232 /* Start up the simple memory manager for GART space */ 1233 drmHeap.region = RADEON_MEM_REGION_GART; 1234 drmHeap.start = 0; 1235 drmHeap.size = info->dri->gartTexMapSize; 1236 1237 if (drmCommandWrite(info->dri->drmFD, DRM_RADEON_INIT_HEAP, 1238 &drmHeap, sizeof(drmHeap))) { 1239 xf86DrvMsg(pScreen->myNum, X_ERROR, 1240 "[drm] Failed to initialize GART heap manager\n"); 1241 } else { 1242 xf86DrvMsg(pScreen->myNum, X_INFO, 1243 "[drm] Initialized kernel GART heap manager, %d\n", 1244 info->dri->gartTexMapSize); 1245 } 1246 } 1247 1248 /* Add a map for the vertex buffers that will be accessed by any 1249 * DRI-based clients. 1250 */ 1251 static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen) 1252 { 1253 /* Initialize vertex buffers */ 1254 info->dri->bufNumBufs = drmAddBufs(info->dri->drmFD, 1255 info->dri->bufMapSize / RADEON_BUFFER_SIZE, 1256 RADEON_BUFFER_SIZE, 1257 (info->cardType!=CARD_AGP) ? DRM_SG_BUFFER : DRM_AGP_BUFFER, 1258 info->dri->bufStart); 1259 1260 if (info->dri->bufNumBufs <= 0) { 1261 xf86DrvMsg(pScreen->myNum, X_ERROR, 1262 "[drm] Could not create vertex/indirect buffers list\n"); 1263 return FALSE; 1264 } 1265 xf86DrvMsg(pScreen->myNum, X_INFO, 1266 "[drm] Added %d %d byte vertex/indirect buffers\n", 1267 info->dri->bufNumBufs, RADEON_BUFFER_SIZE); 1268 1269 if (!(info->dri->buffers = drmMapBufs(info->dri->drmFD))) { 1270 xf86DrvMsg(pScreen->myNum, X_ERROR, 1271 "[drm] Failed to map vertex/indirect buffers list\n"); 1272 return FALSE; 1273 } 1274 xf86DrvMsg(pScreen->myNum, X_INFO, 1275 "[drm] Mapped %d vertex/indirect buffers\n", 1276 info->dri->buffers->count); 1277 1278 return TRUE; 1279 } 1280 1281 static void RADEONDRIIrqInit(RADEONInfoPtr info, ScreenPtr pScreen) 1282 { 1283 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1284 1285 if (!info->dri->irq) { 1286 info->dri->irq = drmGetInterruptFromBusID( 1287 info->dri->drmFD, 1288 PCI_CFG_BUS(info->PciInfo), 1289 PCI_CFG_DEV(info->PciInfo), 1290 PCI_CFG_FUNC(info->PciInfo)); 1291 1292 if ((drmCtlInstHandler(info->dri->drmFD, info->dri->irq)) != 0) { 1293 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1294 "[drm] failure adding irq handler, " 1295 "there is a device already using that irq\n" 1296 "[drm] falling back to irq-free operation\n"); 1297 info->dri->irq = 0; 1298 } else { 1299 if (info->ChipFamily < CHIP_FAMILY_R600) { 1300 unsigned char *RADEONMMIO = info->MMIO; 1301 info->ModeReg->gen_int_cntl = INREG( RADEON_GEN_INT_CNTL ); 1302 1303 /* Let the DRM know it can safely disable the vblank interrupts */ 1304 radeon_crtc_modeset_ioctl(XF86_CRTC_CONFIG_PTR(pScrn)->crtc[0], 1305 FALSE); 1306 radeon_crtc_modeset_ioctl(XF86_CRTC_CONFIG_PTR(pScrn)->crtc[0], 1307 TRUE); 1308 } 1309 } 1310 } 1311 1312 if (info->dri->irq) 1313 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1314 "[drm] dma control initialized, using IRQ %d\n", 1315 info->dri->irq); 1316 } 1317 1318 1319 /* Initialize the CP state, and start the CP (if used by the X server) */ 1320 static void RADEONDRICPInit(ScrnInfoPtr pScrn) 1321 { 1322 RADEONInfoPtr info = RADEONPTR(pScrn); 1323 1324 /* Turn on bus mastering */ 1325 info->BusCntl &= ~RADEON_BUS_MASTER_DIS; 1326 1327 /* Make sure the CP is on for the X server */ 1328 RADEONCP_START(pScrn, info); 1329 #ifdef USE_XAA 1330 if (!info->useEXA) 1331 info->accel_state->dst_pitch_offset = info->dri->frontPitchOffset; 1332 #endif 1333 } 1334 1335 1336 /* Get the DRM version and do some basic useability checks of DRI */ 1337 Bool RADEONDRIGetVersion(ScrnInfoPtr pScrn) 1338 { 1339 RADEONInfoPtr info = RADEONPTR(pScrn); 1340 int major, minor, patch, fd; 1341 int req_major, req_minor, req_patch; 1342 char *busId; 1343 1344 /* Check that the GLX, DRI, and DRM modules have been loaded by testing 1345 * for known symbols in each module. 1346 */ 1347 if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; 1348 if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; 1349 if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 1350 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1351 "[dri] RADEONDRIGetVersion failed (libdri too old)\n" 1352 "[dri] Disabling DRI.\n"); 1353 return FALSE; 1354 } 1355 1356 /* Check the DRI version */ 1357 DRIQueryVersion(&major, &minor, &patch); 1358 if (major < DRIINFO_MAJOR_VERSION) { 1359 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1360 "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n" 1361 "[dri] This driver was built with %d.%d.x, which is too new;\n" 1362 "[dri] libdri reports a version of %d.%d.%d." 1363 "[dri] A server upgrade may be needed.\n" 1364 "[dri] Disabling DRI.\n", 1365 DRIINFO_MAJOR_VERSION, 0, 1366 major, minor, patch); 1367 return FALSE; 1368 } else if (major > DRIINFO_MAJOR_VERSION) { 1369 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1370 "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n" 1371 "[dri] This driver was built with %d.%d.x, which is too old;\n" 1372 "[dri] libdri reports a version of %d.%d.%d." 1373 "[dri] This driver needs to be upgraded/rebuilt.\n" 1374 "[dri] Disabling DRI.\n", 1375 DRIINFO_MAJOR_VERSION, 0, 1376 major, minor, patch); 1377 return FALSE; 1378 } 1379 1380 /* Check the lib version */ 1381 if (xf86LoaderCheckSymbol("drmGetLibVersion")) 1382 info->dri->pLibDRMVersion = drmGetLibVersion(info->dri->drmFD); 1383 if (info->dri->pLibDRMVersion == NULL) { 1384 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1385 "[dri] RADEONDRIGetVersion failed because libdrm is really " 1386 "way to old to even get a version number out of it.\n" 1387 "[dri] Disabling DRI.\n"); 1388 return FALSE; 1389 } 1390 if (info->dri->pLibDRMVersion->version_major != 1 || 1391 info->dri->pLibDRMVersion->version_minor < 2) { 1392 /* incompatible drm library version */ 1393 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1394 "[dri] RADEONDRIGetVersion failed because of a " 1395 "version mismatch.\n" 1396 "[dri] libdrm module version is %d.%d.%d but " 1397 "version 1.2.x is needed.\n" 1398 "[dri] Disabling DRI.\n", 1399 info->dri->pLibDRMVersion->version_major, 1400 info->dri->pLibDRMVersion->version_minor, 1401 info->dri->pLibDRMVersion->version_patchlevel); 1402 drmFreeVersion(info->dri->pLibDRMVersion); 1403 info->dri->pLibDRMVersion = NULL; 1404 return FALSE; 1405 } 1406 1407 /* Create a bus Id */ 1408 if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 1409 busId = DRICreatePCIBusID(info->PciInfo); 1410 } else { 1411 busId = malloc(64); 1412 sprintf(busId, 1413 "PCI:%d:%d:%d", 1414 PCI_DEV_BUS(info->PciInfo), 1415 PCI_DEV_DEV(info->PciInfo), 1416 PCI_DEV_FUNC(info->PciInfo)); 1417 } 1418 1419 /* Low level DRM open */ 1420 fd = drmOpen(RADEON_DRIVER_NAME, busId); 1421 free(busId); 1422 if (fd < 0) { 1423 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1424 "[dri] RADEONDRIGetVersion failed to open the DRM\n" 1425 "[dri] Disabling DRI.\n"); 1426 return FALSE; 1427 } 1428 1429 /* Get DRM version & close DRM */ 1430 info->dri->pKernelDRMVersion = drmGetVersion(fd); 1431 drmClose(fd); 1432 if (info->dri->pKernelDRMVersion == NULL) { 1433 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1434 "[dri] RADEONDRIGetVersion failed to get the DRM version\n" 1435 "[dri] Disabling DRI.\n"); 1436 return FALSE; 1437 } 1438 1439 /* Now check if we qualify */ 1440 req_major = 1; 1441 if (info->ChipFamily >= CHIP_FAMILY_R300) { 1442 req_minor = 17; 1443 req_patch = 0; 1444 } else if (info->IsIGP) { 1445 req_minor = 10; 1446 req_patch = 0; 1447 } else { /* Many problems have been reported with 1.7 in the 2.4 kernel */ 1448 req_minor = 8; 1449 req_patch = 0; 1450 } 1451 1452 /* We don't, bummer ! */ 1453 if (info->dri->pKernelDRMVersion->version_major != req_major) { 1454 /* Looks like we're trying to start in UMS mode on a KMS kernel. 1455 * This can happen if the radeon kernel module wasn't loaded before 1456 * X starts. 1457 */ 1458 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1459 "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n" 1460 "[dri] This chipset requires a kernel module version of %d.%d.%d,\n" 1461 "[dri] but the kernel reports a version of %d.%d.%d." 1462 "[dri] Make sure your module is loaded prior to starting X, and\n" 1463 "[dri] that this driver was built with support for KMS.\n" 1464 "[dri] Aborting.\n", 1465 req_major, req_minor, req_patch, 1466 info->dri->pKernelDRMVersion->version_major, 1467 info->dri->pKernelDRMVersion->version_minor, 1468 info->dri->pKernelDRMVersion->version_patchlevel); 1469 drmFreeVersion(info->dri->pKernelDRMVersion); 1470 info->dri->pKernelDRMVersion = NULL; 1471 return -1; 1472 } else if (info->dri->pKernelDRMVersion->version_minor < req_minor || 1473 (info->dri->pKernelDRMVersion->version_minor == req_minor && 1474 info->dri->pKernelDRMVersion->version_patchlevel < req_patch)) { 1475 /* Incompatible drm version */ 1476 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1477 "[dri] RADEONDRIGetVersion failed because of a version mismatch.\n" 1478 "[dri] This chipset requires a kernel module version of %d.%d.%d,\n" 1479 "[dri] but the kernel reports a version of %d.%d.%d." 1480 "[dri] Try upgrading your kernel.\n" 1481 "[dri] Disabling DRI.\n", 1482 req_major, req_minor, req_patch, 1483 info->dri->pKernelDRMVersion->version_major, 1484 info->dri->pKernelDRMVersion->version_minor, 1485 info->dri->pKernelDRMVersion->version_patchlevel); 1486 drmFreeVersion(info->dri->pKernelDRMVersion); 1487 info->dri->pKernelDRMVersion = NULL; 1488 return FALSE; 1489 } 1490 1491 return TRUE; 1492 } 1493 1494 Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on) 1495 { 1496 RADEONInfoPtr info = RADEONPTR(pScrn); 1497 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1498 int value = 0; 1499 1500 if (!info->want_vblank_interrupts) 1501 on = FALSE; 1502 1503 if (info->directRenderingEnabled && info->dri->pKernelDRMVersion->version_minor >= 28) { 1504 if (on) { 1505 if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled) 1506 value = DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2; 1507 else 1508 value = DRM_RADEON_VBLANK_CRTC1; 1509 } 1510 1511 if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_VBLANK_CRTC, value)) { 1512 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEON Vblank Crtc Setup Failed %d\n", value); 1513 return FALSE; 1514 } 1515 } 1516 return TRUE; 1517 } 1518 1519 1520 /* Initialize the screen-specific data structures for the DRI and the 1521 * Radeon. This is the main entry point to the device-specific 1522 * initialization code. It calls device-independent DRI functions to 1523 * create the DRI data structures and initialize the DRI state. 1524 */ 1525 Bool RADEONDRIScreenInit(ScreenPtr pScreen) 1526 { 1527 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1528 RADEONInfoPtr info = RADEONPTR(pScrn); 1529 DRIInfoPtr pDRIInfo; 1530 RADEONDRIPtr pRADEONDRI; 1531 1532 info->dri->DRICloseScreen = NULL; 1533 1534 switch (info->CurrentLayout.pixel_code) { 1535 case 8: 1536 case 15: 1537 case 24: 1538 /* These modes are not supported (yet). */ 1539 xf86DrvMsg(pScreen->myNum, X_ERROR, 1540 "[dri] RADEONInitVisualConfigs failed " 1541 "(depth %d not supported). " 1542 "Disabling DRI.\n", info->CurrentLayout.pixel_code); 1543 return FALSE; 1544 1545 /* Only 16 and 32 color depths are supports currently. */ 1546 case 16: 1547 case 32: 1548 break; 1549 } 1550 1551 radeon_drm_page_size = getpagesize(); 1552 1553 /* Create the DRI data structure, and fill it in before calling the 1554 * DRIScreenInit(). 1555 */ 1556 if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; 1557 1558 info->dri->pDRIInfo = pDRIInfo; 1559 pDRIInfo->drmDriverName = RADEON_DRIVER_NAME; 1560 1561 if ( (info->ChipFamily >= CHIP_FAMILY_R600) ) 1562 pDRIInfo->clientDriverName = R600_DRIVER_NAME; 1563 else if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) 1564 pDRIInfo->clientDriverName = R300_DRIVER_NAME; 1565 else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) 1566 pDRIInfo->clientDriverName = R200_DRIVER_NAME; 1567 else 1568 pDRIInfo->clientDriverName = RADEON_DRIVER_NAME; 1569 1570 if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 1571 pDRIInfo->busIdString = DRICreatePCIBusID(info->PciInfo); 1572 } else { 1573 pDRIInfo->busIdString = malloc(64); 1574 sprintf(pDRIInfo->busIdString, 1575 "PCI:%d:%d:%d", 1576 PCI_DEV_BUS(info->PciInfo), 1577 PCI_DEV_DEV(info->PciInfo), 1578 PCI_DEV_FUNC(info->PciInfo)); 1579 } 1580 pDRIInfo->ddxDriverMajorVersion = info->allowColorTiling ? 5 : 4; 1581 pDRIInfo->ddxDriverMinorVersion = 3; 1582 pDRIInfo->ddxDriverPatchVersion = 0; 1583 pDRIInfo->frameBufferPhysicalAddress = (void *)(uintptr_t)info->LinearAddr + info->dri->frontOffset; 1584 pDRIInfo->frameBufferSize = info->FbMapSize - info->FbSecureSize; 1585 pDRIInfo->frameBufferStride = (pScrn->displayWidth * 1586 info->CurrentLayout.pixel_bytes); 1587 pDRIInfo->ddxDrawableTableEntry = RADEON_MAX_DRAWABLES; 1588 pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES 1589 < RADEON_MAX_DRAWABLES 1590 ? SAREA_MAX_DRAWABLES 1591 : RADEON_MAX_DRAWABLES); 1592 /* kill DRIAdjustFrame. We adjust sarea frame info ourselves to work 1593 correctly with pageflip + mergedfb/color tiling */ 1594 pDRIInfo->wrap.AdjustFrame = NULL; 1595 1596 #ifdef NOT_DONE 1597 /* FIXME: Need to extend DRI protocol to pass this size back to 1598 * client for SAREA mapping that includes a device private record 1599 */ 1600 pDRIInfo->SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) 1601 & 0x1000); /* round to page */ 1602 /* + shared memory device private rec */ 1603 #else 1604 /* For now the mapping works by using a fixed size defined 1605 * in the SAREA header 1606 */ 1607 if (sizeof(XF86DRISAREARec)+sizeof(drm_radeon_sarea_t) > SAREA_MAX) { 1608 ErrorF("Data does not fit in SAREA\n"); 1609 return FALSE; 1610 } 1611 pDRIInfo->SAREASize = SAREA_MAX; 1612 #endif 1613 1614 if (!(pRADEONDRI = (RADEONDRIPtr)calloc(sizeof(RADEONDRIRec),1))) { 1615 DRIDestroyInfoRec(info->dri->pDRIInfo); 1616 info->dri->pDRIInfo = NULL; 1617 return FALSE; 1618 } 1619 pDRIInfo->devPrivate = pRADEONDRI; 1620 pDRIInfo->devPrivateSize = sizeof(RADEONDRIRec); 1621 pDRIInfo->contextSize = sizeof(RADEONDRIContextRec); 1622 1623 pDRIInfo->CreateContext = RADEONCreateContext; 1624 pDRIInfo->DestroyContext = RADEONDestroyContext; 1625 pDRIInfo->SwapContext = RADEONDRISwapContext; 1626 pDRIInfo->InitBuffers = RADEONDRIInitBuffers; 1627 pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers; 1628 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 1629 pDRIInfo->TransitionTo2d = RADEONDRITransitionTo2d; 1630 pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d; 1631 pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d; 1632 pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d; 1633 #if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \ 1634 (DRIINFO_MAJOR_VERSION == 5 && \ 1635 DRIINFO_MINOR_VERSION >= 1)) 1636 pDRIInfo->ClipNotify = RADEONDRIClipNotify; 1637 #endif 1638 1639 pDRIInfo->createDummyCtx = TRUE; 1640 pDRIInfo->createDummyCtxPriv = FALSE; 1641 1642 #ifdef USE_EXA 1643 if (info->useEXA) { 1644 #if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3 1645 int major, minor, patch; 1646 1647 DRIQueryVersion(&major, &minor, &patch); 1648 1649 if (minor >= 3) 1650 #endif 1651 #if DRIINFO_MAJOR_VERSION > 5 || \ 1652 (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3) 1653 pDRIInfo->texOffsetStart = RADEONTexOffsetStart; 1654 #endif 1655 } 1656 #endif 1657 1658 if (!DRIScreenInit(pScreen, pDRIInfo, &info->dri->drmFD)) { 1659 xf86DrvMsg(pScreen->myNum, X_ERROR, 1660 "[dri] DRIScreenInit failed. Disabling DRI.\n"); 1661 free(pDRIInfo->devPrivate); 1662 pDRIInfo->devPrivate = NULL; 1663 DRIDestroyInfoRec(pDRIInfo); 1664 pDRIInfo = NULL; 1665 return FALSE; 1666 } 1667 /* Initialize AGP */ 1668 if (info->cardType==CARD_AGP && !RADEONDRIAgpInit(info, pScreen)) { 1669 xf86DrvMsg(pScreen->myNum, X_ERROR, 1670 "[agp] AGP failed to initialize. Disabling the DRI.\n" ); 1671 xf86DrvMsg(pScreen->myNum, X_INFO, 1672 "[agp] You may want to make sure the agpgart kernel " 1673 "module\nis loaded before the radeon kernel module.\n"); 1674 RADEONDRICloseScreen(pScreen); 1675 return FALSE; 1676 } 1677 1678 /* Initialize PCI */ 1679 if ((info->cardType!=CARD_AGP) && !RADEONDRIPciInit(info, pScreen)) { 1680 xf86DrvMsg(pScreen->myNum, X_ERROR, 1681 "[pci] PCI failed to initialize. Disabling the DRI.\n" ); 1682 RADEONDRICloseScreen(pScreen); 1683 return FALSE; 1684 } 1685 1686 /* DRIScreenInit doesn't add all the 1687 * common mappings. Add additional 1688 * mappings here. 1689 */ 1690 if (!RADEONDRIMapInit(info, pScreen)) { 1691 RADEONDRICloseScreen(pScreen); 1692 return FALSE; 1693 } 1694 1695 /* DRIScreenInit adds the frame buffer 1696 map, but we need it as well */ 1697 { 1698 void *scratch_ptr; 1699 int scratch_int; 1700 1701 DRIGetDeviceInfo(pScreen, &info->dri->fbHandle, 1702 &scratch_int, &scratch_int, 1703 &scratch_int, &scratch_int, 1704 &scratch_ptr); 1705 } 1706 1707 /* FIXME: When are these mappings unmapped? */ 1708 1709 if (!RADEONInitVisualConfigs(pScreen)) { 1710 RADEONDRICloseScreen(pScreen); 1711 return FALSE; 1712 } 1713 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n"); 1714 1715 return TRUE; 1716 } 1717 1718 static Bool RADEONDRIDoCloseScreen(CLOSE_SCREEN_ARGS_DECL) 1719 { 1720 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1721 RADEONInfoPtr info = RADEONPTR(pScrn); 1722 1723 RADEONDRICloseScreen(pScreen); 1724 1725 pScreen->CloseScreen = info->dri->DRICloseScreen; 1726 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 1727 } 1728 1729 /* Finish initializing the device-dependent DRI state, and call 1730 * DRIFinishScreenInit() to complete the device-independent DRI 1731 * initialization. 1732 */ 1733 Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) 1734 { 1735 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1736 RADEONInfoPtr info = RADEONPTR(pScrn); 1737 drm_radeon_sarea_t *pSAREAPriv; 1738 RADEONDRIPtr pRADEONDRI; 1739 1740 info->dri->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 1741 /* info->dri->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ 1742 1743 /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit 1744 * because *DRIKernelInit requires that the hardware lock is held by 1745 * the X server, and the first time the hardware lock is grabbed is 1746 * in DRIFinishScreenInit. 1747 */ 1748 if (!DRIFinishScreenInit(pScreen)) { 1749 RADEONDRICloseScreen(pScreen); 1750 return FALSE; 1751 } 1752 1753 /* Initialize the kernel data structures */ 1754 if (!RADEONDRIKernelInit(info, pScreen)) { 1755 RADEONDRICloseScreen(pScreen); 1756 return FALSE; 1757 } 1758 1759 /* Initialize the vertex buffers list */ 1760 if (!RADEONDRIBufInit(info, pScreen)) { 1761 RADEONDRICloseScreen(pScreen); 1762 return FALSE; 1763 } 1764 1765 /* Initialize IRQ */ 1766 RADEONDRIIrqInit(info, pScreen); 1767 1768 /* Initialize kernel GART memory manager */ 1769 RADEONDRIGartHeapInit(info, pScreen); 1770 1771 /* Initialize and start the CP if required */ 1772 RADEONDRICPInit(pScrn); 1773 1774 /* Initialize the SAREA private data structure */ 1775 pSAREAPriv = (drm_radeon_sarea_t*)DRIGetSAREAPrivate(pScreen); 1776 memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); 1777 1778 pRADEONDRI = (RADEONDRIPtr)info->dri->pDRIInfo->devPrivate; 1779 1780 pRADEONDRI->deviceID = info->Chipset; 1781 pRADEONDRI->width = pScrn->virtualX; 1782 pRADEONDRI->height = pScrn->virtualY; 1783 pRADEONDRI->depth = pScrn->depth; 1784 pRADEONDRI->bpp = pScrn->bitsPerPixel; 1785 1786 pRADEONDRI->IsPCI = (info->cardType!=CARD_AGP); 1787 pRADEONDRI->AGPMode = info->dri->agpMode; 1788 1789 pRADEONDRI->frontOffset = info->dri->frontOffset; 1790 pRADEONDRI->frontPitch = info->dri->frontPitch; 1791 pRADEONDRI->backOffset = info->dri->backOffset; 1792 pRADEONDRI->backPitch = info->dri->backPitch; 1793 pRADEONDRI->depthOffset = info->dri->depthOffset; 1794 pRADEONDRI->depthPitch = info->dri->depthPitch; 1795 pRADEONDRI->textureOffset = info->dri->textureOffset; 1796 pRADEONDRI->textureSize = info->dri->textureSize; 1797 pRADEONDRI->log2TexGran = info->dri->log2TexGran; 1798 1799 pRADEONDRI->registerHandle = info->dri->registerHandle; 1800 pRADEONDRI->registerSize = info->dri->registerSize; 1801 1802 pRADEONDRI->statusHandle = info->dri->ringReadPtrHandle; 1803 pRADEONDRI->statusSize = info->dri->ringReadMapSize; 1804 1805 pRADEONDRI->gartTexHandle = info->dri->gartTexHandle; 1806 pRADEONDRI->gartTexMapSize = info->dri->gartTexMapSize; 1807 pRADEONDRI->log2GARTTexGran = info->dri->log2GARTTexGran; 1808 pRADEONDRI->gartTexOffset = info->dri->gartTexStart; 1809 1810 pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 1811 1812 info->directRenderingInited = TRUE; 1813 1814 /* Wrap CloseScreen */ 1815 info->dri->DRICloseScreen = pScreen->CloseScreen; 1816 pScreen->CloseScreen = RADEONDRIDoCloseScreen; 1817 1818 /* disable vblank at startup */ 1819 RADEONDRISetVBlankInterrupt (pScrn, FALSE); 1820 1821 return TRUE; 1822 } 1823 1824 /** 1825 * This function will attempt to get the Radeon hardware back into shape 1826 * after a resume from disc. 1827 * 1828 * Charl P. Botha <http://cpbotha.net> 1829 */ 1830 void RADEONDRIResume(ScreenPtr pScreen) 1831 { 1832 int _ret; 1833 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1834 RADEONInfoPtr info = RADEONPTR(pScrn); 1835 1836 if (info->dri->pKernelDRMVersion->version_minor >= 9) { 1837 xf86DrvMsg(pScreen->myNum, X_INFO, 1838 "[RESUME] Attempting to re-init Radeon hardware.\n"); 1839 } else { 1840 xf86DrvMsg(pScreen->myNum, X_WARNING, 1841 "[RESUME] Cannot re-init Radeon hardware, DRM too old\n" 1842 "(need 1.9.0 or newer)\n"); 1843 return; 1844 } 1845 1846 if (info->cardType==CARD_AGP) { 1847 if (!RADEONSetAgpMode(info, pScreen)) 1848 return; 1849 1850 RADEONSetAgpBase(info, pScreen); 1851 } 1852 1853 _ret = drmCommandNone(info->dri->drmFD, DRM_RADEON_CP_RESUME); 1854 if (_ret) { 1855 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1856 "%s: CP resume %d\n", __FUNCTION__, _ret); 1857 /* FIXME: return? */ 1858 } 1859 1860 if (info->ChipFamily < CHIP_FAMILY_R600) 1861 RADEONEngineRestore(pScrn); 1862 1863 RADEONDRICPInit(pScrn); 1864 } 1865 1866 void RADEONDRIStop(ScreenPtr pScreen) 1867 { 1868 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1869 RADEONInfoPtr info = RADEONPTR(pScrn); 1870 RING_LOCALS; 1871 1872 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 1873 "RADEONDRIStop\n"); 1874 1875 /* Stop the CP */ 1876 if (info->directRenderingInited) { 1877 /* If we've generated any CP commands, we must flush them to the 1878 * kernel module now. 1879 */ 1880 RADEONCP_RELEASE(pScrn, info); 1881 RADEONCP_STOP(pScrn, info); 1882 } 1883 info->directRenderingInited = FALSE; 1884 } 1885 1886 /* The screen is being closed, so clean up any state and free any 1887 * resources used by the DRI. 1888 */ 1889 void RADEONDRICloseScreen(ScreenPtr pScreen) 1890 { 1891 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1892 RADEONInfoPtr info = RADEONPTR(pScrn); 1893 drm_radeon_init_t drmInfo; 1894 1895 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 1896 "RADEONDRICloseScreen\n"); 1897 1898 #ifdef DAMAGE 1899 REGION_UNINIT(pScreen, &info->dri->driRegion); 1900 #endif 1901 1902 if (info->dri->irq) { 1903 RADEONDRISetVBlankInterrupt (pScrn, FALSE); 1904 drmCtlUninstHandler(info->dri->drmFD); 1905 info->dri->irq = 0; 1906 info->ModeReg->gen_int_cntl = 0; 1907 } 1908 1909 /* De-allocate vertex buffers */ 1910 if (info->dri->buffers) { 1911 drmUnmapBufs(info->dri->buffers); 1912 info->dri->buffers = NULL; 1913 } 1914 1915 /* De-allocate all kernel resources */ 1916 memset(&drmInfo, 0, sizeof(drm_radeon_init_t)); 1917 drmInfo.func = RADEON_CLEANUP_CP; 1918 drmCommandWrite(info->dri->drmFD, DRM_RADEON_CP_INIT, 1919 &drmInfo, sizeof(drm_radeon_init_t)); 1920 1921 /* De-allocate all GART resources */ 1922 if (info->dri->gartTex) { 1923 drmUnmap(info->dri->gartTex, info->dri->gartTexMapSize); 1924 info->dri->gartTex = NULL; 1925 } 1926 if (info->dri->buf) { 1927 drmUnmap(info->dri->buf, info->dri->bufMapSize); 1928 info->dri->buf = NULL; 1929 } 1930 if (info->dri->ringReadPtr) { 1931 drmUnmap(info->dri->ringReadPtr, info->dri->ringReadMapSize); 1932 info->dri->ringReadPtr = NULL; 1933 } 1934 if (info->dri->ring) { 1935 drmUnmap(info->dri->ring, info->dri->ringMapSize); 1936 info->dri->ring = NULL; 1937 } 1938 if (info->dri->agpMemHandle != DRM_AGP_NO_HANDLE) { 1939 drmAgpUnbind(info->dri->drmFD, info->dri->agpMemHandle); 1940 drmAgpFree(info->dri->drmFD, info->dri->agpMemHandle); 1941 info->dri->agpMemHandle = DRM_AGP_NO_HANDLE; 1942 drmAgpRelease(info->dri->drmFD); 1943 } 1944 if (info->dri->pciMemHandle) { 1945 drmScatterGatherFree(info->dri->drmFD, info->dri->pciMemHandle); 1946 info->dri->pciMemHandle = 0; 1947 } 1948 1949 if (info->dri->pciGartBackup) { 1950 free(info->dri->pciGartBackup); 1951 info->dri->pciGartBackup = NULL; 1952 } 1953 1954 /* De-allocate all DRI resources */ 1955 DRICloseScreen(pScreen); 1956 1957 /* De-allocate all DRI data structures */ 1958 if (info->dri->pDRIInfo) { 1959 if (info->dri->pDRIInfo->devPrivate) { 1960 free(info->dri->pDRIInfo->devPrivate); 1961 info->dri->pDRIInfo->devPrivate = NULL; 1962 } 1963 DRIDestroyInfoRec(info->dri->pDRIInfo); 1964 info->dri->pDRIInfo = NULL; 1965 } 1966 if (info->dri->pVisualConfigs) { 1967 free(info->dri->pVisualConfigs); 1968 info->dri->pVisualConfigs = NULL; 1969 } 1970 if (info->dri->pVisualConfigsPriv) { 1971 free(info->dri->pVisualConfigsPriv); 1972 info->dri->pVisualConfigsPriv = NULL; 1973 } 1974 } 1975 1976 /* Use callbacks from dri.c to support pageflipping mode for a single 1977 * 3d context without need for any specific full-screen extension. 1978 * 1979 * Also use these callbacks to allocate and free 3d-specific memory on 1980 * demand. 1981 */ 1982 1983 1984 #ifdef DAMAGE 1985 1986 /* Use the damage layer to maintain a list of dirty rectangles. 1987 * These are blitted to the back buffer to keep both buffers clean 1988 * during page-flipping when the 3d application isn't fullscreen. 1989 * 1990 * An alternative to this would be to organize for all on-screen drawing 1991 * operations to be duplicated for the two buffers. That might be 1992 * faster, but seems like a lot more work... 1993 */ 1994 1995 1996 static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg) 1997 { 1998 RADEONInfoPtr info = RADEONPTR(pScrn); 1999 int i, num; 2000 ScreenPtr pScreen = pScrn->pScreen; 2001 drm_radeon_sarea_t *pSAREAPriv = DRIGetSAREAPrivate(pScreen); 2002 #ifdef USE_EXA 2003 PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); 2004 #endif 2005 RegionRec region; 2006 BoxPtr pbox; 2007 2008 if (!info->directRenderingInited || !info->cp->CPStarted) 2009 return; 2010 2011 /* Don't want to do this when no 3d is active and pages are 2012 * right-way-round 2013 */ 2014 if (!pSAREAPriv->pfState && pSAREAPriv->pfCurrentPage == 0) 2015 return; 2016 2017 REGION_NULL(pScreen, ®ion); 2018 REGION_SUBTRACT(pScreen, ®ion, pReg, &info->dri->driRegion); 2019 2020 num = REGION_NUM_RECTS(®ion); 2021 2022 if (!num) { 2023 goto out; 2024 } 2025 2026 pbox = REGION_RECTS(®ion); 2027 2028 /* pretty much a hack. */ 2029 2030 #ifdef USE_EXA 2031 if (info->useEXA) { 2032 uint32_t src_pitch_offset, dst_pitch_offset, datatype; 2033 2034 RADEONGetPixmapOffsetPitch(pPix, &src_pitch_offset); 2035 dst_pitch_offset = src_pitch_offset + (info->dri->backOffset >> 10); 2036 RADEONGetDatatypeBpp(pScrn->bitsPerPixel, &datatype); 2037 info->accel_state->xdir = info->accel_state->ydir = 1; 2038 2039 RADEONDoPrepareCopyCP(pScrn, src_pitch_offset, dst_pitch_offset, datatype, 2040 GXcopy, ~0); 2041 } 2042 #endif 2043 2044 #ifdef USE_XAA 2045 if (!info->useEXA) { 2046 /* Make sure accel has been properly inited */ 2047 if (info->accel_state->accel == NULL || 2048 info->accel_state->accel->SetupForScreenToScreenCopy == NULL) 2049 goto out; 2050 if (info->tilingEnabled) 2051 info->accel_state->dst_pitch_offset |= RADEON_DST_TILE_MACRO; 2052 (*info->accel_state->accel->SetupForScreenToScreenCopy)(pScrn, 2053 1, 1, GXcopy, 2054 (uint32_t)(-1), -1); 2055 } 2056 #endif 2057 2058 for (i = 0 ; i < num ; i++, pbox++) { 2059 int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1); 2060 int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1); 2061 2062 if (xa <= xb && ya <= yb) { 2063 #ifdef USE_EXA 2064 if (info->useEXA) { 2065 RADEONCopyCP(pPix, xa, ya, xa, ya, xb - xa + 1, yb - ya + 1); 2066 } 2067 #endif 2068 2069 #ifdef USE_XAA 2070 if (!info->useEXA) { 2071 (*info->accel_state->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya, 2072 xa + info->dri->backX, 2073 ya + info->dri->backY, 2074 xb - xa + 1, 2075 yb - ya + 1); 2076 } 2077 #endif 2078 } 2079 } 2080 2081 #ifdef USE_XAA 2082 info->accel_state->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO; 2083 #endif 2084 2085 out: 2086 REGION_NULL(pScreen, ®ion); 2087 DamageEmpty(info->dri->pDamage); 2088 } 2089 2090 #endif /* DAMAGE */ 2091 2092 static void RADEONEnablePageFlip(ScreenPtr pScreen) 2093 { 2094 #ifdef DAMAGE 2095 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2096 RADEONInfoPtr info = RADEONPTR(pScrn); 2097 2098 if (info->dri->allowPageFlip) { 2099 drm_radeon_sarea_t *pSAREAPriv = DRIGetSAREAPrivate(pScreen); 2100 BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1, 2101 .y2 = pScrn->virtualY - 1 }; 2102 RegionPtr pReg = REGION_CREATE(pScreen, &box, 1); 2103 2104 pSAREAPriv->pfState = 1; 2105 RADEONDRIRefreshArea(pScrn, pReg); 2106 REGION_DESTROY(pScreen, pReg); 2107 } 2108 #endif 2109 } 2110 2111 static void RADEONDisablePageFlip(ScreenPtr pScreen) 2112 { 2113 /* Tell the clients not to pageflip. How? 2114 * -- Field in sarea, plus bumping the window counters. 2115 * -- DRM needs to cope with Front-to-Back swapbuffers. 2116 */ 2117 drm_radeon_sarea_t *pSAREAPriv = DRIGetSAREAPrivate(pScreen); 2118 2119 pSAREAPriv->pfState = 0; 2120 } 2121 2122 static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen) 2123 { 2124 RADEONDisablePageFlip(pScreen); 2125 } 2126 2127 static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen) 2128 { 2129 /* Let the remaining 3d app start page flipping again */ 2130 RADEONEnablePageFlip(pScreen); 2131 } 2132 2133 static void RADEONDRITransitionTo3d(ScreenPtr pScreen) 2134 { 2135 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2136 RADEONInfoPtr info = RADEONPTR(pScrn); 2137 #ifdef USE_XAA 2138 FBAreaPtr fbarea; 2139 int width, height; 2140 2141 /* EXA allocates these areas up front, so it doesn't do the following 2142 * stuff. 2143 */ 2144 if (!info->useEXA) { 2145 /* reserve offscreen area for back and depth buffers and textures */ 2146 2147 /* If we still have an area for the back buffer reserved, free it 2148 * first so we always start with all free offscreen memory, except 2149 * maybe for Xv 2150 */ 2151 if (info->dri->backArea) { 2152 xf86FreeOffscreenArea(info->dri->backArea); 2153 info->dri->backArea = NULL; 2154 } 2155 2156 xf86PurgeUnlockedOffscreenAreas(pScreen); 2157 2158 xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0); 2159 2160 /* Free Xv linear offscreen memory if necessary 2161 * FIXME: This is hideous. What about telling xv "oh btw you have no memory 2162 * any more?" -- anholt 2163 */ 2164 if (height < (info->dri->depthTexLines + info->dri->backLines)) { 2165 RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr; 2166 xf86FreeOffscreenLinear((FBLinearPtr)portPriv->video_memory); 2167 portPriv->video_memory = NULL; 2168 xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0); 2169 } 2170 2171 /* Reserve placeholder area so the other areas will match the 2172 * pre-calculated offsets 2173 * FIXME: We may have other locked allocations and thus this would allocate 2174 * in the wrong place. The XV surface allocations seem likely. -- anholt 2175 */ 2176 fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 2177 height 2178 - info->dri->depthTexLines 2179 - info->dri->backLines, 2180 pScrn->displayWidth, 2181 NULL, NULL, NULL); 2182 if (!fbarea) 2183 xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve placeholder " 2184 "offscreen area, you might experience screen corruption\n"); 2185 2186 info->dri->backArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, 2187 info->dri->backLines, 2188 pScrn->displayWidth, 2189 NULL, NULL, NULL); 2190 if (!info->dri->backArea) 2191 xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen " 2192 "area for back buffer, you might experience screen " 2193 "corruption\n"); 2194 2195 info->dri->depthTexArea = xf86AllocateOffscreenArea(pScreen, 2196 pScrn->displayWidth, 2197 info->dri->depthTexLines, 2198 pScrn->displayWidth, 2199 NULL, NULL, NULL); 2200 if (!info->dri->depthTexArea) 2201 xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen " 2202 "area for depth buffer and textures, you might " 2203 "experience screen corruption\n"); 2204 2205 xf86FreeOffscreenArea(fbarea); 2206 } 2207 #endif /* USE_XAA */ 2208 2209 info->dri->have3DWindows = 1; 2210 2211 RADEONChangeSurfaces(pScrn); 2212 RADEONEnablePageFlip(pScreen); 2213 2214 info->want_vblank_interrupts = TRUE; 2215 RADEONDRISetVBlankInterrupt(pScrn, TRUE); 2216 2217 if (info->cursor) 2218 xf86ForceHWCursor (pScreen, TRUE); 2219 } 2220 2221 static void RADEONDRITransitionTo2d(ScreenPtr pScreen) 2222 { 2223 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2224 RADEONInfoPtr info = RADEONPTR(pScrn); 2225 drm_radeon_sarea_t *pSAREAPriv = DRIGetSAREAPrivate(pScreen); 2226 2227 /* Try flipping back to the front page if necessary */ 2228 if (pSAREAPriv->pfCurrentPage == 1) 2229 drmCommandNone(info->dri->drmFD, DRM_RADEON_FLIP); 2230 2231 /* Shut down shadowing if we've made it back to the front page */ 2232 if (pSAREAPriv->pfCurrentPage == 0) { 2233 RADEONDisablePageFlip(pScreen); 2234 #ifdef USE_XAA 2235 if (!info->useEXA) { 2236 xf86FreeOffscreenArea(info->dri->backArea); 2237 info->dri->backArea = NULL; 2238 } 2239 #endif 2240 } else { 2241 xf86DrvMsg(pScreen->myNum, X_WARNING, 2242 "[dri] RADEONDRITransitionTo2d: " 2243 "kernel failed to unflip buffers.\n"); 2244 } 2245 2246 #ifdef USE_XAA 2247 if (!info->useEXA) 2248 xf86FreeOffscreenArea(info->dri->depthTexArea); 2249 #endif 2250 2251 info->dri->have3DWindows = 0; 2252 2253 RADEONChangeSurfaces(pScrn); 2254 2255 info->want_vblank_interrupts = FALSE; 2256 RADEONDRISetVBlankInterrupt(pScrn, FALSE); 2257 2258 if (info->cursor) 2259 xf86ForceHWCursor (pScreen, FALSE); 2260 } 2261 2262 #if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \ 2263 (DRIINFO_MAJOR_VERSION == 5 && \ 2264 DRIINFO_MINOR_VERSION >= 1)) 2265 static void 2266 RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) 2267 { 2268 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2269 RADEONInfoPtr info = RADEONPTR(pScrn); 2270 2271 REGION_UNINIT(pScreen, &info->dri->driRegion); 2272 REGION_NULL(pScreen, &info->dri->driRegion); 2273 2274 if (num > 0) { 2275 int i; 2276 2277 for (i = 0; i < num; i++) { 2278 WindowPtr pWin = ppWin[i]; 2279 2280 if (pWin) { 2281 REGION_UNION(pScreen, &info->dri->driRegion, &pWin->clipList, 2282 &info->dri->driRegion); 2283 } 2284 } 2285 } 2286 } 2287 #endif 2288 2289 void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen) 2290 { 2291 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2292 RADEONInfoPtr info = RADEONPTR(pScrn); 2293 2294 if (info->cardType != CARD_PCIE || 2295 info->dri->pKernelDRMVersion->version_minor < 19) 2296 return; 2297 2298 if (info->FbSecureSize==0) 2299 return; 2300 2301 /* set the old default size of pci gart table */ 2302 if (info->dri->pKernelDRMVersion->version_minor < 26) 2303 info->dri->pciGartSize = 32768; 2304 2305 info->dri->pciGartSize = RADEONDRIGetPciAperTableSize(pScrn); 2306 2307 /* allocate space to back up PCIEGART table */ 2308 info->dri->pciGartBackup = xnfcalloc(1, info->dri->pciGartSize); 2309 if (info->dri->pciGartBackup == NULL) 2310 return; 2311 2312 info->dri->pciGartOffset = (info->FbMapSize - info->FbSecureSize); 2313 2314 2315 } 2316 2317 int RADEONDRIGetPciAperTableSize(ScrnInfoPtr pScrn) 2318 { 2319 RADEONInfoPtr info = RADEONPTR(pScrn); 2320 int ret_size; 2321 int num_pages; 2322 2323 num_pages = (info->dri->pciAperSize * 1024 * 1024) / 4096; 2324 2325 if ((info->ChipFamily >= CHIP_FAMILY_R600) || 2326 (info->ChipFamily == CHIP_FAMILY_RS600)) 2327 ret_size = num_pages * sizeof(uint64_t); 2328 else 2329 ret_size = num_pages * sizeof(unsigned int); 2330 2331 return ret_size; 2332 } 2333 2334 int RADEONDRISetParam(ScrnInfoPtr pScrn, unsigned int param, int64_t value) 2335 { 2336 drm_radeon_setparam_t radeonsetparam; 2337 RADEONInfoPtr info = RADEONPTR(pScrn); 2338 int ret; 2339 2340 memset(&radeonsetparam, 0, sizeof(drm_radeon_setparam_t)); 2341 radeonsetparam.param = param; 2342 radeonsetparam.value = value; 2343 ret = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SETPARAM, 2344 &radeonsetparam, sizeof(drm_radeon_setparam_t)); 2345 return ret; 2346 } 2347