atimach64exa.c revision e35d4d8e
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(xf86ScreenToScrn(pScreenInfo)); 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 = xf86ScreenToScrn(pPix->drawable.pScreen); 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 = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 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 = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 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 = xf86ScreenToScrn(pPixmap->drawable.pScreen); 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 = xf86ScreenToScrn(pPixmap->drawable.pScreen); 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#include "atimach64render.c" 391 392/* Compute log base 2 of val. */ 393static __inline__ int Mach64Log2(int val) 394{ 395 int bits; 396 397 for (bits = 0; val != 0; val >>= 1, ++bits) 398 ; 399 return bits - 1; 400} 401 402/* 403 * Memory layour for EXA with DRI (no local_textures): 404 * | front | back | depth | textures | pixmaps, xv | c | 405 * 406 * 1024x768@16bpp with 8 MB: 407 * | 1.5 MB | 1.5 MB | 1.5 MB | 0 | ~3.5 MB | c | 408 * 409 * 1024x768@32bpp with 8 MB: 410 * | 3.0 MB | 3.0 MB | 1.5 MB | 0 | ~0.5 MB | c | 411 * 412 * "c" is the hw cursor which occupies 1KB 413 */ 414static void 415Mach64SetupMemEXA(ScreenPtr pScreen) 416{ 417 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen); 418 ATIPtr pATI = ATIPTR(pScreenInfo); 419 420 int cpp = (pScreenInfo->bitsPerPixel + 7) / 8; 421 /* front and back buffer */ 422 int bufferSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * cpp; 423 /* always 16-bit z-buffer */ 424 int depthSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * 2; 425 426 ExaDriverPtr pExa = pATI->pExa; 427 428 pExa->memoryBase = pATI->pMemory; 429 pExa->memorySize = pScreenInfo->videoRam * 1024; 430 pExa->offScreenBase = bufferSize; 431 432#ifdef XF86DRI_DEVEL 433 if (pATI->directRenderingEnabled) 434 { 435 ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; 436 Bool is_pci = pATIDRIServer->IsPCI; 437 438 int textureSize = 0; 439 int pixmapCache = 0; 440 int next = 0; 441 442 /* front buffer */ 443 pATIDRIServer->frontOffset = 0; 444 pATIDRIServer->frontPitch = pScreenInfo->displayWidth; 445 next += bufferSize; 446 447 /* back buffer */ 448 pATIDRIServer->backOffset = next; 449 pATIDRIServer->backPitch = pScreenInfo->displayWidth; 450 next += bufferSize; 451 452 /* depth buffer */ 453 pATIDRIServer->depthOffset = next; 454 pATIDRIServer->depthPitch = pScreenInfo->displayWidth; 455 next += depthSize; 456 457 /* ATIScreenInit does check for the this condition. */ 458 if (next > pExa->memorySize) 459 { 460 xf86DrvMsg(pScreen->myNum, X_WARNING, 461 "DRI static buffer allocation failed, disabling DRI --" 462 "need at least %d kB video memory\n", next / 1024 ); 463 ATIDRICloseScreen(pScreen); 464 pATI->directRenderingEnabled = FALSE; 465 } 466 467 /* local textures */ 468 469 /* Reserve approx. half of offscreen memory for local textures */ 470 textureSize = (pExa->memorySize - next) / 2; 471 472 /* In case DRI requires more offscreen memory than available, 473 * should not happen as ATIScreenInit would have not enabled DRI */ 474 if (textureSize < 0) 475 textureSize = 0; 476 477 /* Try for enough pixmap cache for a full viewport */ 478 pixmapCache = (pExa->memorySize - next) - textureSize; 479 if (pixmapCache < bufferSize) 480 textureSize = 0; 481 482 /* Don't allocate a local texture heap for AGP unless requested */ 483 if ( !is_pci && !pATI->OptionLocalTextures ) 484 textureSize = 0; 485 486 if (textureSize > 0) 487 { 488 int l = Mach64Log2(textureSize / MACH64_NR_TEX_REGIONS); 489 if (l < MACH64_LOG_TEX_GRANULARITY) 490 l = MACH64_LOG_TEX_GRANULARITY; 491 pATIDRIServer->logTextureGranularity = l; 492 493 /* Round the texture size down to the nearest whole number of 494 * texture regions. 495 */ 496 textureSize = (textureSize >> l) << l; 497 } 498 499 /* Set a minimum usable local texture heap size. This will fit 500 * two 256x256 textures. We check this after any rounding of 501 * the texture area. 502 */ 503 if (textureSize < 256*256 * cpp * 2) 504 textureSize = 0; 505 506 /* Disable DRI for PCI if cannot allocate a local texture heap */ 507 if ( is_pci && textureSize == 0 ) 508 { 509 xf86DrvMsg(pScreen->myNum, X_WARNING, 510 "Not enough memory for local textures, disabling DRI\n"); 511 ATIDRICloseScreen(pScreen); 512 pATI->directRenderingEnabled = FALSE; 513 } 514 515 pATIDRIServer->textureOffset = next; 516 pATIDRIServer->textureSize = textureSize; 517 next += textureSize; 518 519 /* pExa->offScreenBase is moved to `next' when DRI gets activated */ 520 } 521#endif /* XF86DRI_DEVEL */ 522 523 xf86DrvMsg(pScreen->myNum, X_INFO, 524 "EXA memory management initialized\n" 525 "\t base : %10p\n" 526 "\t offscreen: +%10lx\n" 527 "\t size : +%10lx\n" 528 "\t cursor : %10p\n", 529 pExa->memoryBase, 530 pExa->offScreenBase, 531 pExa->memorySize, 532 pATI->pCursorImage); 533 534 if (TRUE || xf86GetVerbosity() > 1) 535 { 536 int offscreen = pExa->memorySize - pExa->offScreenBase; 537 int viewport = bufferSize; 538 int dvdframe = 720*480*cpp; /* enough for single-buffered DVD */ 539 540 xf86DrvMsg(pScreen->myNum, X_INFO, 541 "Will use %d kB of offscreen memory for EXA\n" 542 "\t\t or %5.2f viewports (composite)\n" 543 "\t\t or %5.2f dvdframes (xvideo)\n", 544 offscreen / 1024, 545 1.0 * offscreen / viewport, 546 1.0 * offscreen / dvdframe); 547 } 548 549#ifdef XF86DRI_DEVEL 550 if (pATI->directRenderingEnabled) 551 { 552 ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; 553 554 xf86DrvMsg(pScreen->myNum, X_INFO, 555 "Will use back buffer at offset 0x%x\n", 556 pATIDRIServer->backOffset); 557 558 xf86DrvMsg(pScreen->myNum, X_INFO, 559 "Will use depth buffer at offset 0x%x\n", 560 pATIDRIServer->depthOffset); 561 562 if (pATIDRIServer->textureSize > 0) 563 { 564 xf86DrvMsg(pScreen->myNum, X_INFO, 565 "Will use %d kB for local textures at offset 0x%x\n", 566 pATIDRIServer->textureSize/1024, 567 pATIDRIServer->textureOffset); 568 } 569 } 570#endif /* XF86DRI_DEVEL */ 571 572 pExa->pixmapOffsetAlign = 64; 573 pExa->pixmapPitchAlign = 64; 574 575 pExa->flags = EXA_OFFSCREEN_PIXMAPS; 576 577 pExa->maxX = ATIMach64MaxX; 578 pExa->maxY = ATIMach64MaxY; 579} 580 581Bool ATIMach64ExaInit(ScreenPtr pScreen) 582{ 583 ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen); 584 ATIPtr pATI = ATIPTR(pScreenInfo); 585 ExaDriverPtr pExa; 586 587 pExa = exaDriverAlloc(); 588 if (!pExa) 589 return FALSE; 590 591 pATI->pExa = pExa; 592 593 pExa->exa_major = 2; 594 pExa->exa_minor = 0; 595 596 Mach64SetupMemEXA(pScreen); 597 598 pExa->WaitMarker = Mach64WaitMarker; 599 600 pExa->PrepareSolid = Mach64PrepareSolid; 601 pExa->Solid = Mach64Solid; 602 pExa->DoneSolid = Mach64DoneSolid; 603 604 pExa->PrepareCopy = Mach64PrepareCopy; 605 pExa->Copy = Mach64Copy; 606 pExa->DoneCopy = Mach64DoneCopy; 607 608 if (pATI->RenderAccelEnabled) { 609 if (pATI->Chip >= ATI_CHIP_264GTPRO) { 610 /* 3D Rage Pro does not support NPOT textures. */ 611 pExa->flags |= EXA_OFFSCREEN_ALIGN_POT; 612 613 pExa->CheckComposite = Mach64CheckComposite; 614 pExa->PrepareComposite = Mach64PrepareComposite; 615 pExa->Composite = Mach64Composite; 616 pExa->DoneComposite = Mach64DoneComposite; 617 } else { 618 xf86DrvMsg(pScreen->myNum, X_INFO, 619 "Render acceleration is not supported for ATI chips " 620 "earlier than the ATI 3D Rage Pro.\n"); 621 pATI->RenderAccelEnabled = FALSE; 622 } 623 } 624 625 xf86DrvMsg(pScreen->myNum, X_INFO, "Render acceleration %s\n", 626 pATI->RenderAccelEnabled ? "enabled" : "disabled"); 627 628 if (!exaDriverInit(pScreen, pATI->pExa)) { 629 free(pATI->pExa); 630 pATI->pExa = NULL; 631 return FALSE; 632 } 633 634 return TRUE; 635} 636#endif 637