atimach64exa.c revision 1b12faf6
1/* 2 * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of Marc Aurele La France not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. Marc Aurele La France makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as-is" without express or implied warranty. 13 * 14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22/* 23 * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas. 24 * All Rights Reserved. 25 * 26 * Permission is hereby granted, free of charge, to any person obtaining a copy 27 * of this software and associated documentation files (the "Software"), to 28 * deal in the Software without restriction, including without limitation the 29 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 30 * sell copies of the Software, and to permit persons to whom the Software is 31 * furnished to do so, subject to the following conditions: 32 * 33 * The above copyright notice and this permission notice (including the next 34 * paragraph) shall be included in all copies or substantial portions of the 35 * Software. 36 * 37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 40 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 41 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 42 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 43 * DEALINGS IN THE SOFTWARE. 44 */ 45/* 46 * DRI support by: 47 * Manuel Teira 48 * Leif Delgass <ldelgass@retinalburn.net> 49 * 50 * EXA support by: 51 * Jakub Stachowski <qbast@go2.pl> 52 * George Sapountzis <gsap7@yahoo.gr> 53 */ 54 55#ifdef HAVE_CONFIG_H 56#include "config.h" 57#endif 58 59#include <string.h> 60 61#include "ati.h" 62#include "atichip.h" 63#include "atidri.h" 64#include "atimach64accel.h" 65#include "atimach64io.h" 66#include "atipriv.h" 67#include "atiregs.h" 68 69#ifdef XF86DRI_DEVEL 70#include "mach64_dri.h" 71#include "mach64_sarea.h" 72#endif 73 74#ifdef USE_EXA 75extern CARD8 ATIMach64ALU[]; 76 77extern void 78ATIMach64ValidateClip 79( 80 ATIPtr pATI, 81 int sc_left, 82 int sc_right, 83 int sc_top, 84 int sc_bottom 85); 86 87#if 0 88#define MACH64_TRACE(x) \ 89do { \ 90 ErrorF("Mach64(%s): ", __FUNCTION__); \ 91 ErrorF x; \ 92} while(0) 93#else 94#define MACH64_TRACE(x) do { } while(0) 95#endif 96 97#if 0 98#define MACH64_FALLBACK(x) \ 99do { \ 100 ErrorF("Fallback(%s): ", __FUNCTION__); \ 101 ErrorF x; \ 102 return FALSE; \ 103} while (0) 104#else 105#define MACH64_FALLBACK(x) return FALSE 106#endif 107 108static void 109Mach64WaitMarker(ScreenPtr pScreenInfo, int Marker) 110{ 111 ATIMach64Sync(xf86Screens[pScreenInfo->myNum]); 112} 113 114static Bool 115Mach64GetDatatypeBpp(PixmapPtr pPix, CARD32 *pix_width) 116{ 117 int bpp = pPix->drawable.bitsPerPixel; 118 119 switch (bpp) { 120 case 8: 121 *pix_width = 122 SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | 123 SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | 124 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); 125 break; 126 case 16: 127 *pix_width = 128 SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) | 129 SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) | 130 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); 131 break; 132 case 24: 133 *pix_width = 134 SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | 135 SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | 136 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); 137 break; 138 case 32: 139 *pix_width = 140 SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) | 141 SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) | 142 SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); 143 break; 144 default: 145 MACH64_FALLBACK(("Unsupported bpp: %d\n", bpp)); 146 } 147 148#if X_BYTE_ORDER == X_LITTLE_ENDIAN 149 150 *pix_width |= DP_BYTE_PIX_ORDER; 151 152#endif /* X_BYTE_ORDER */ 153 154 return TRUE; 155} 156 157static Bool 158Mach64GetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset, 159 unsigned int offset, unsigned int pitch) 160{ 161#if 0 162 ScrnInfoPtr pScreenInfo = xf86Screens[pPix->drawable.pScreen->myNum]; 163 ATIPtr pATI = ATIPTR(pScreenInfo); 164 165 if (pitch % pATI->pExa->pixmapPitchAlign != 0) 166 MACH64_FALLBACK(("Bad pitch 0x%08x\n", pitch)); 167 168 if (offset % pATI->pExa->pixmapOffsetAlign != 0) 169 MACH64_FALLBACK(("Bad offset 0x%08x\n", offset)); 170#endif 171 172 /* pixels / 8 = ((bytes * 8) / bpp) / 8 = bytes / bpp */ 173 pitch = pitch / bpp; 174 175 /* bytes / 8 */ 176 offset = offset >> 3; 177 178 *pitch_offset = ((pitch << 22) | (offset << 0)); 179 180 return TRUE; 181} 182 183static Bool 184Mach64GetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset) 185{ 186 CARD32 pitch, offset; 187 int bpp; 188 189 bpp = pPix->drawable.bitsPerPixel; 190 if (bpp == 24) 191 bpp = 8; 192 193 pitch = exaGetPixmapPitch(pPix); 194 offset = exaGetPixmapOffset(pPix); 195 196 return Mach64GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); 197} 198 199static Bool 200Mach64PrepareCopy 201( 202 PixmapPtr pSrcPixmap, 203 PixmapPtr pDstPixmap, 204 int xdir, 205 int ydir, 206 int alu, 207 Pixel planemask 208) 209{ 210 ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 211 ATIPtr pATI = ATIPTR(pScreenInfo); 212 CARD32 src_pitch_offset, dst_pitch_offset, dp_pix_width; 213 214 ATIDRISync(pScreenInfo); 215 216 if (!Mach64GetDatatypeBpp(pDstPixmap, &dp_pix_width)) 217 return FALSE; 218 if (!Mach64GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) 219 return FALSE; 220 if (!Mach64GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) 221 return FALSE; 222 223 ATIMach64WaitForFIFO(pATI, 7); 224 outf(DP_WRITE_MASK, planemask); 225 outf(DP_PIX_WIDTH, dp_pix_width); 226 outf(SRC_OFF_PITCH, src_pitch_offset); 227 outf(DST_OFF_PITCH, dst_pitch_offset); 228 229 outf(DP_SRC, DP_MONO_SRC_ALLONES | 230 SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 231 outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX)); 232 233 outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 234 235 pATI->dst_cntl = 0; 236 237 if (ydir > 0) 238 pATI->dst_cntl |= DST_Y_DIR; 239 if (xdir > 0) 240 pATI->dst_cntl |= DST_X_DIR; 241 242 if (pATI->XModifier == 1) 243 outf(DST_CNTL, pATI->dst_cntl); 244 else 245 pATI->dst_cntl |= DST_24_ROT_EN; 246 247 return TRUE; 248} 249 250static void 251Mach64Copy 252( 253 PixmapPtr pDstPixmap, 254 int srcX, 255 int srcY, 256 int dstX, 257 int dstY, 258 int w, 259 int h 260) 261{ 262 ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 263 ATIPtr pATI = ATIPTR(pScreenInfo); 264 265 srcX *= pATI->XModifier; 266 dstY *= pATI->XModifier; 267 w *= pATI->XModifier; 268 269 ATIDRISync(pScreenInfo); 270 271 /* Disable clipping if it gets in the way */ 272 ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1); 273 274 if (!(pATI->dst_cntl & DST_X_DIR)) 275 { 276 srcX += w - 1; 277 dstX += w - 1; 278 } 279 280 if (!(pATI->dst_cntl & DST_Y_DIR)) 281 { 282 srcY += h - 1; 283 dstY += h - 1; 284 } 285 286 if (pATI->XModifier != 1) 287 outf(DST_CNTL, pATI->dst_cntl | SetBits((dstX / 4) % 6, DST_24_ROT)); 288 289 ATIMach64WaitForFIFO(pATI, 4); 290 outf(SRC_Y_X, SetWord(srcX, 1) | SetWord(srcY, 0)); 291 outf(SRC_WIDTH1, w); 292 outf(DST_Y_X, SetWord(dstX, 1) | SetWord(dstY, 0)); 293 outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); 294 295 /* 296 * On VTB's and later, the engine will randomly not wait for a copy 297 * operation to commit its results to video memory before starting the next 298 * one. The probability of such occurrences increases with GUI_WB_FLUSH 299 * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This 300 * would point to some kind of video memory bandwidth problem were it noti 301 * for the fact that the problem occurs less often (but still occurs) when 302 * copying larger rectangles. 303 */ 304 if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel) 305 { 306 exaMarkSync(pScreenInfo->pScreen); /* Force sync. */ 307 exaWaitSync(pScreenInfo->pScreen); /* Sync and notify EXA. */ 308 } 309} 310 311static void Mach64DoneCopy(PixmapPtr pDstPixmap) { } 312 313static Bool 314Mach64PrepareSolid 315( 316 PixmapPtr pPixmap, 317 int alu, 318 Pixel planemask, 319 Pixel fg 320) 321{ 322 ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum]; 323 ATIPtr pATI = ATIPTR(pScreenInfo); 324 CARD32 dst_pitch_offset, dp_pix_width; 325 326 ATIDRISync(pScreenInfo); 327 328 if (!Mach64GetDatatypeBpp(pPixmap, &dp_pix_width)) 329 return FALSE; 330 if (!Mach64GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) 331 return FALSE; 332 333 ATIMach64WaitForFIFO(pATI, 7); 334 outf(DP_WRITE_MASK, planemask); 335 outf(DP_PIX_WIDTH, dp_pix_width); 336 outf(DST_OFF_PITCH, dst_pitch_offset); 337 338 outf(DP_SRC, DP_MONO_SRC_ALLONES | 339 SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 340 outf(DP_FRGD_CLR, fg); 341 outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX)); 342 343 outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 344 345 if (pATI->XModifier == 1) 346 outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); 347 348 return TRUE; 349} 350 351static void 352Mach64Solid 353( 354 PixmapPtr pPixmap, 355 int x1, 356 int y1, 357 int x2, 358 int y2 359) 360{ 361 ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum]; 362 ATIPtr pATI = ATIPTR(pScreenInfo); 363 364 int x = x1; 365 int y = y1; 366 int w = x2-x1; 367 int h = y2-y1; 368 369 ATIDRISync(pScreenInfo); 370 371 if (pATI->XModifier != 1) 372 { 373 x *= pATI->XModifier; 374 w *= pATI->XModifier; 375 376 outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) | 377 (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)); 378 } 379 380 /* Disable clipping if it gets in the way */ 381 ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1); 382 383 ATIMach64WaitForFIFO(pATI, 2); 384 outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); 385 outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); 386} 387 388static void Mach64DoneSolid(PixmapPtr pPixmap) { } 389 390/* 391 * Memcpy-based UTS. 392 */ 393static Bool 394Mach64UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 395 char *src, int src_pitch) 396{ 397 char *dst = pDst->devPrivate.ptr; 398 int dst_pitch = exaGetPixmapPitch(pDst); 399 400 int bpp = pDst->drawable.bitsPerPixel; 401 int cpp = (bpp + 7) / 8; 402 int wBytes = w * cpp; 403 404 exaWaitSync(pDst->drawable.pScreen); 405 406 dst += (x * cpp) + (y * dst_pitch); 407 408 while (h--) { 409 memcpy(dst, src, wBytes); 410 src += src_pitch; 411 dst += dst_pitch; 412 } 413 414 return TRUE; 415} 416 417/* 418 * Memcpy-based DFS. 419 */ 420static Bool 421Mach64DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 422 char *dst, int dst_pitch) 423{ 424 char *src = pSrc->devPrivate.ptr; 425 int src_pitch = exaGetPixmapPitch(pSrc); 426 427 int bpp = pSrc->drawable.bitsPerPixel; 428 int cpp = (bpp + 7) / 8; 429 int wBytes = w * cpp; 430 431 exaWaitSync(pSrc->drawable.pScreen); 432 433 src += (x * cpp) + (y * src_pitch); 434 435 while (h--) { 436 memcpy(dst, src, wBytes); 437 src += src_pitch; 438 dst += dst_pitch; 439 } 440 441 return TRUE; 442} 443 444#include "atimach64render.c" 445 446/* Compute log base 2 of val. */ 447static __inline__ int Mach64Log2(int val) 448{ 449 int bits; 450 451 for (bits = 0; val != 0; val >>= 1, ++bits) 452 ; 453 return bits - 1; 454} 455 456/* 457 * Memory layour for EXA with DRI (no local_textures): 458 * | front | back | depth | textures | pixmaps, xv | c | 459 * 460 * 1024x768@16bpp with 8 MB: 461 * | 1.5 MB | 1.5 MB | 1.5 MB | 0 | ~3.5 MB | c | 462 * 463 * 1024x768@32bpp with 8 MB: 464 * | 3.0 MB | 3.0 MB | 1.5 MB | 0 | ~0.5 MB | c | 465 * 466 * "c" is the hw cursor which occupies 1KB 467 */ 468static void 469Mach64SetupMemEXA(ScreenPtr pScreen) 470{ 471 ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; 472 ATIPtr pATI = ATIPTR(pScreenInfo); 473 474 int cpp = (pScreenInfo->bitsPerPixel + 7) / 8; 475 /* front and back buffer */ 476 int bufferSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * cpp; 477 /* always 16-bit z-buffer */ 478 int depthSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * 2; 479 480 ExaDriverPtr pExa = pATI->pExa; 481 482 pExa->memoryBase = pATI->pMemory; 483 pExa->memorySize = pScreenInfo->videoRam * 1024; 484 pExa->offScreenBase = bufferSize; 485 486#ifdef XF86DRI_DEVEL 487 if (pATI->directRenderingEnabled) 488 { 489 ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; 490 Bool is_pci = pATIDRIServer->IsPCI; 491 492 int textureSize = 0; 493 int pixmapCache = 0; 494 int next = 0; 495 496 /* front buffer */ 497 pATIDRIServer->frontOffset = 0; 498 pATIDRIServer->frontPitch = pScreenInfo->displayWidth; 499 next += bufferSize; 500 501 /* back buffer */ 502 pATIDRIServer->backOffset = next; 503 pATIDRIServer->backPitch = pScreenInfo->displayWidth; 504 next += bufferSize; 505 506 /* depth buffer */ 507 pATIDRIServer->depthOffset = next; 508 pATIDRIServer->depthPitch = pScreenInfo->displayWidth; 509 next += depthSize; 510 511 /* ATIScreenInit does check for the this condition. */ 512 if (next > pExa->memorySize) 513 { 514 xf86DrvMsg(pScreen->myNum, X_WARNING, 515 "DRI static buffer allocation failed, disabling DRI --" 516 "need at least %d kB video memory\n", next / 1024 ); 517 ATIDRICloseScreen(pScreen); 518 pATI->directRenderingEnabled = FALSE; 519 } 520 521 /* local textures */ 522 523 /* Reserve approx. half of offscreen memory for local textures */ 524 textureSize = (pExa->memorySize - next) / 2; 525 526 /* In case DRI requires more offscreen memory than available, 527 * should not happen as ATIScreenInit would have not enabled DRI */ 528 if (textureSize < 0) 529 textureSize = 0; 530 531 /* Try for enough pixmap cache for a full viewport */ 532 pixmapCache = (pExa->memorySize - next) - textureSize; 533 if (pixmapCache < bufferSize) 534 textureSize = 0; 535 536 /* Don't allocate a local texture heap for AGP unless requested */ 537 if ( !is_pci && !pATI->OptionLocalTextures ) 538 textureSize = 0; 539 540 if (textureSize > 0) 541 { 542 int l = Mach64Log2(textureSize / MACH64_NR_TEX_REGIONS); 543 if (l < MACH64_LOG_TEX_GRANULARITY) 544 l = MACH64_LOG_TEX_GRANULARITY; 545 pATIDRIServer->logTextureGranularity = l; 546 547 /* Round the texture size down to the nearest whole number of 548 * texture regions. 549 */ 550 textureSize = (textureSize >> l) << l; 551 } 552 553 /* Set a minimum usable local texture heap size. This will fit 554 * two 256x256 textures. We check this after any rounding of 555 * the texture area. 556 */ 557 if (textureSize < 256*256 * cpp * 2) 558 textureSize = 0; 559 560 /* Disable DRI for PCI if cannot allocate a local texture heap */ 561 if ( is_pci && textureSize == 0 ) 562 { 563 xf86DrvMsg(pScreen->myNum, X_WARNING, 564 "Not enough memory for local textures, disabling DRI\n"); 565 ATIDRICloseScreen(pScreen); 566 pATI->directRenderingEnabled = FALSE; 567 } 568 569 pATIDRIServer->textureOffset = next; 570 pATIDRIServer->textureSize = textureSize; 571 next += textureSize; 572 573 /* pExa->offScreenBase is moved to `next' when DRI gets activated */ 574 } 575#endif /* XF86DRI_DEVEL */ 576 577 xf86DrvMsg(pScreen->myNum, X_INFO, 578 "EXA memory management initialized\n" 579 "\t base : %10p\n" 580 "\t offscreen: +%10lx\n" 581 "\t size : +%10lx\n" 582 "\t cursor : %10p\n", 583 pExa->memoryBase, 584 pExa->offScreenBase, 585 pExa->memorySize, 586 pATI->pCursorImage); 587 588 if (TRUE || xf86GetVerbosity() > 1) 589 { 590 int offscreen = pExa->memorySize - pExa->offScreenBase; 591 int viewport = bufferSize; 592 int dvdframe = 720*480*cpp; /* enough for single-buffered DVD */ 593 594 xf86DrvMsg(pScreen->myNum, X_INFO, 595 "Will use %d kB of offscreen memory for EXA\n" 596 "\t\t or %5.2f viewports (composite)\n" 597 "\t\t or %5.2f dvdframes (xvideo)\n", 598 offscreen / 1024, 599 1.0 * offscreen / viewport, 600 1.0 * offscreen / dvdframe); 601 } 602 603#ifdef XF86DRI_DEVEL 604 if (pATI->directRenderingEnabled) 605 { 606 ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; 607 608 xf86DrvMsg(pScreen->myNum, X_INFO, 609 "Will use back buffer at offset 0x%x\n", 610 pATIDRIServer->backOffset); 611 612 xf86DrvMsg(pScreen->myNum, X_INFO, 613 "Will use depth buffer at offset 0x%x\n", 614 pATIDRIServer->depthOffset); 615 616 if (pATIDRIServer->textureSize > 0) 617 { 618 xf86DrvMsg(pScreen->myNum, X_INFO, 619 "Will use %d kB for local textures at offset 0x%x\n", 620 pATIDRIServer->textureSize/1024, 621 pATIDRIServer->textureOffset); 622 } 623 } 624#endif /* XF86DRI_DEVEL */ 625 626 pExa->pixmapOffsetAlign = 64; 627 pExa->pixmapPitchAlign = 64; 628 629 pExa->flags = EXA_OFFSCREEN_PIXMAPS; 630 631 pExa->maxX = ATIMach64MaxX; 632 pExa->maxY = ATIMach64MaxY; 633} 634 635Bool ATIMach64ExaInit(ScreenPtr pScreen) 636{ 637 ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; 638 ATIPtr pATI = ATIPTR(pScreenInfo); 639 ExaDriverPtr pExa; 640 641 pExa = exaDriverAlloc(); 642 if (!pExa) 643 return FALSE; 644 645 pATI->pExa = pExa; 646 647 pExa->exa_major = 2; 648 pExa->exa_minor = 0; 649 650 Mach64SetupMemEXA(pScreen); 651 652 pExa->WaitMarker = Mach64WaitMarker; 653 654 pExa->PrepareSolid = Mach64PrepareSolid; 655 pExa->Solid = Mach64Solid; 656 pExa->DoneSolid = Mach64DoneSolid; 657 658 pExa->PrepareCopy = Mach64PrepareCopy; 659 pExa->Copy = Mach64Copy; 660 pExa->DoneCopy = Mach64DoneCopy; 661 662 /* EXA hits more optimized paths when it does not have to fallback because 663 * of missing UTS/DFS, hook memcpy-based UTS/DFS. 664 */ 665 pExa->UploadToScreen = Mach64UploadToScreen; 666 pExa->DownloadFromScreen = Mach64DownloadFromScreen; 667 668 if (pATI->RenderAccelEnabled) { 669 if (pATI->Chip >= ATI_CHIP_264GTPRO) { 670 /* 3D Rage Pro does not support NPOT textures. */ 671 pExa->flags |= EXA_OFFSCREEN_ALIGN_POT; 672 673 pExa->CheckComposite = Mach64CheckComposite; 674 pExa->PrepareComposite = Mach64PrepareComposite; 675 pExa->Composite = Mach64Composite; 676 pExa->DoneComposite = Mach64DoneComposite; 677 } else { 678 xf86DrvMsg(pScreen->myNum, X_INFO, 679 "Render acceleration is not supported for ATI chips " 680 "earlier than the ATI 3D Rage Pro.\n"); 681 pATI->RenderAccelEnabled = FALSE; 682 } 683 } 684 685 xf86DrvMsg(pScreen->myNum, X_INFO, "Render acceleration %s\n", 686 pATI->RenderAccelEnabled ? "enabled" : "disabled"); 687 688 if (!exaDriverInit(pScreen, pATI->pExa)) { 689 free(pATI->pExa); 690 pATI->pExa = NULL; 691 return FALSE; 692 } 693 694 return TRUE; 695} 696#endif 697