r128_exa.c revision 81f79626
1/* 2 * Copyright 2006 Joseph Garvin 3 * Copyright 2012 Connor Behan 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Authors: 26 * Joseph Garvin <joseph.h.garvin@gmail.com> 27 * Connor Behan <connor.behan@gmail.com> 28 * 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include "config.h" 33#endif 34 35#include "r128.h" 36#include "exa.h" 37 38#include "r128_reg.h" 39#include "r128_rop.h" 40 41#include "xf86.h" 42 43/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we 44 * require src and dest datatypes to be equal. 45 */ 46Bool R128GetDatatypeBpp(int bpp, uint32_t *type) 47{ 48 switch (bpp) { 49 case 8: 50 *type = R128_DATATYPE_CI8; 51 return TRUE; 52 case 16: 53 *type = R128_DATATYPE_RGB565; 54 return TRUE; 55 case 24: 56 *type = R128_DATATYPE_RGB888; 57 return TRUE; 58 case 32: 59 *type = R128_DATATYPE_ARGB8888; 60 return TRUE; 61 default: 62 return FALSE; 63 } 64} 65 66static Bool R128GetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset, 67 unsigned int offset, unsigned int pitch) 68{ 69 ScreenPtr pScreen = pPix->drawable.pScreen; 70 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 71 R128InfoPtr info = R128PTR(pScrn); 72 73 if (pitch > 16320 || pitch % info->ExaDriver->pixmapPitchAlign != 0) { 74 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 75 "Bad pitch 0x%08x\n", pitch)); 76 return FALSE; 77 } 78 79 if (offset % info->ExaDriver->pixmapOffsetAlign != 0) { 80 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 81 "Bad offset 0x%08x\n", offset)); 82 return FALSE; 83 } 84 85 *pitch_offset = ((pitch / bpp) << 21) | (offset >> 5); 86 87 return TRUE; 88} 89 90Bool R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset) 91{ 92 uint32_t pitch, offset; 93 int bpp; 94 95 bpp = pPix->drawable.bitsPerPixel; 96 if (bpp == 24) 97 bpp = 8; 98 99 offset = exaGetPixmapOffset(pPix); 100 pitch = exaGetPixmapPitch(pPix); 101 102 return R128GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); 103} 104 105static void Emit2DState(ScrnInfoPtr pScrn) 106{ 107 R128InfoPtr info = R128PTR(pScrn); 108 int has_src = info->state_2d.src_pitch_offset; 109 unsigned char *R128MMIO = info->MMIO; 110 111 R128WaitForFifo(pScrn, (has_src ? 10 : 9)); 112 113 OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right); 114 OUTREG(R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl); 115 OUTREG(R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr); 116 OUTREG(R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr); 117 OUTREG(R128_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr); 118 OUTREG(R128_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr); 119 OUTREG(R128_DP_WRITE_MASK, info->state_2d.dp_write_mask); 120 OUTREG(R128_DP_CNTL, info->state_2d.dp_cntl); 121 122 OUTREG(R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset); 123 if (has_src) OUTREG(R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset); 124} 125 126#ifdef R128DRI 127void EmitCCE2DState(ScrnInfoPtr pScrn) 128{ 129 R128InfoPtr info = R128PTR(pScrn); 130 int has_src = info->state_2d.src_pitch_offset; 131 RING_LOCALS; 132 133 R128CCE_REFRESH( pScrn, info ); 134 135 BEGIN_RING( (has_src ? 20 : 18) ); 136 137 OUT_RING_REG( R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right ); 138 OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl ); 139 OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr ); 140 OUT_RING_REG( R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr ); 141 OUT_RING_REG( R128_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr ); 142 OUT_RING_REG( R128_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr ); 143 OUT_RING_REG( R128_DP_WRITE_MASK, info->state_2d.dp_write_mask ); 144 OUT_RING_REG( R128_DP_CNTL, info->state_2d.dp_cntl ); 145 146 OUT_RING_REG( R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset ); 147 if (has_src) OUT_RING_REG( R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset ); 148 149 ADVANCE_RING(); 150} 151#endif 152 153/* EXA Callbacks */ 154 155static Bool 156R128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 157{ 158 ScreenPtr pScreen = pPixmap->drawable.pScreen; 159 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 160 R128InfoPtr info = R128PTR(pScrn); 161 162 int bpp = pPixmap->drawable.bitsPerPixel; 163 uint32_t datatype, dst_pitch_offset; 164 165 if (!R128GetDatatypeBpp(bpp, &datatype)) { 166 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 167 "R128GetDatatypeBpp failed\n")); 168 return FALSE; 169 } 170 if (!R128GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) { 171 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 172 "R128GetPixmapOffsetPitch failed\n")); 173 return FALSE; 174 } 175 if (info->state_2d.in_use) return FALSE; 176 177 info->state_2d.in_use = TRUE; 178 info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX); 179 info->state_2d.dp_brush_bkgd_clr = 0x00000000; 180 info->state_2d.dp_src_frgd_clr = 0xffffffff; 181 info->state_2d.dp_src_bkgd_clr = 0x00000000; 182 info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL | 183 R128_GMC_BRUSH_SOLID_COLOR | 184 (datatype >> 8) | 185 R128_GMC_SRC_DATATYPE_COLOR | 186 R128_ROP[alu].pattern | 187 R128_GMC_CLR_CMP_CNTL_DIS); 188 info->state_2d.dp_brush_frgd_clr = fg; 189 info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM); 190 info->state_2d.dp_write_mask = planemask; 191 info->state_2d.dst_pitch_offset = dst_pitch_offset; 192 info->state_2d.src_pitch_offset = 0; 193 194#ifdef R128DRI 195 if (info->directRenderingEnabled) { 196 EmitCCE2DState(pScrn); 197 } else 198#endif 199 { 200 Emit2DState(pScrn); 201 } 202 return TRUE; 203} 204 205static void 206R128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 207{ 208 ScreenPtr pScreen = pPixmap->drawable.pScreen; 209 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 210 R128InfoPtr info = R128PTR(pScrn); 211 unsigned char *R128MMIO = info->MMIO; 212 213 R128WaitForFifo(pScrn, 2); 214 OUTREG(R128_DST_Y_X, (y1 << 16) | x1); 215 OUTREG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1)); 216 exaMarkSync(pScreen); 217} 218 219#define R128DoneSolid R128Done 220 221void 222R128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset, 223 uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask) 224{ 225 R128InfoPtr info = R128PTR(pScrn); 226 227 info->state_2d.in_use = TRUE; 228 info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL | 229 R128_GMC_SRC_PITCH_OFFSET_CNTL | 230 R128_GMC_BRUSH_NONE | 231 (datatype >> 8) | 232 R128_GMC_SRC_DATATYPE_COLOR | 233 R128_ROP[alu].rop | 234 R128_DP_SRC_SOURCE_MEMORY | 235 R128_GMC_CLR_CMP_CNTL_DIS); 236 info->state_2d.dp_cntl = ((info->xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) | 237 (info->ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0)); 238 info->state_2d.dp_brush_frgd_clr = 0xffffffff; 239 info->state_2d.dp_brush_bkgd_clr = 0x00000000; 240 info->state_2d.dp_src_frgd_clr = 0xffffffff; 241 info->state_2d.dp_src_bkgd_clr = 0x00000000; 242 info->state_2d.dp_write_mask = planemask; 243 info->state_2d.dst_pitch_offset = dst_pitch_offset; 244 info->state_2d.src_pitch_offset = src_pitch_offset; 245 info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX); 246 247#ifdef R128DRI 248 if (info->directRenderingEnabled) { 249 EmitCCE2DState(pScrn); 250 } else 251#endif 252 { 253 Emit2DState(pScrn); 254 } 255} 256 257static Bool 258R128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask) 259{ 260 ScreenPtr pScreen = pSrcPixmap->drawable.pScreen; 261 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 262 R128InfoPtr info = R128PTR(pScrn); 263 264 int bpp = pDstPixmap->drawable.bitsPerPixel; 265 uint32_t datatype, src_pitch_offset, dst_pitch_offset; 266 267 if (!R128GetDatatypeBpp(bpp, &datatype)) { 268 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 269 "R128GetDatatypeBpp failed\n")); 270 return FALSE; 271 } 272 if (!R128GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) { 273 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 274 "R128GetPixmapOffsetPitch source " 275 "failed\n")); 276 return FALSE; 277 } 278 if (!R128GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) { 279 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 280 "R128GetPixmapOffsetPitch dest failed\n")); 281 return FALSE; 282 } 283 if (info->state_2d.in_use) return FALSE; 284 285 info->xdir = xdir; 286 info->ydir = ydir; 287 288 R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, alu, planemask); 289 290 return TRUE; 291} 292 293static void 294R128Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) 295{ 296 ScreenPtr pScreen = pDstPixmap->drawable.pScreen; 297 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 298 R128InfoPtr info = R128PTR(pScrn); 299 unsigned char *R128MMIO = info->MMIO; 300 301 if (info->xdir < 0) srcX += width - 1, dstX += width - 1; 302 if (info->ydir < 0) srcY += height - 1, dstY += height - 1; 303 304 R128WaitForFifo(pScrn, 3); 305 OUTREG(R128_SRC_Y_X, (srcY << 16) | srcX); 306 OUTREG(R128_DST_Y_X, (dstY << 16) | dstX); 307 OUTREG(R128_DST_HEIGHT_WIDTH, (height << 16) | width); 308 exaMarkSync(pScreen); 309} 310 311#define R128DoneCopy R128Done 312 313static void 314R128Sync(ScreenPtr pScreen, int marker) 315{ 316 R128WaitForIdle(xf86ScreenToScrn(pScreen)); 317} 318 319void 320R128Done(PixmapPtr pPixmap) 321{ 322 ScreenPtr pScreen = pPixmap->drawable.pScreen; 323 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 324 R128InfoPtr info = R128PTR(pScrn); 325 326 info->state_2d.in_use = FALSE; 327#if defined(R128DRI) && defined(RENDER) 328 if (info->state_2d.src_pix) { 329 pScreen->DestroyPixmap(info->state_2d.src_pix); 330 info->state_2d.src_pix = NULL; 331 } 332 if (info->state_2d.msk_pix) { 333 pScreen->DestroyPixmap(info->state_2d.msk_pix); 334 info->state_2d.msk_pix = NULL; 335 } 336#endif 337} 338 339#ifdef R128DRI 340 341#define R128CCEPrepareSolid R128PrepareSolid 342 343static void 344R128CCESolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 345{ 346 ScreenPtr pScreen = pPixmap->drawable.pScreen; 347 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 348 R128InfoPtr info = R128PTR(pScrn); 349 RING_LOCALS; 350 351 R128CCE_REFRESH( pScrn, info ); 352 353 BEGIN_RING( 4 ); 354 355 OUT_RING_REG( R128_DST_Y_X, (y1 << 16) | x1 ); 356 OUT_RING_REG( R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1) ); 357 358 ADVANCE_RING(); 359} 360 361#define R128CCEDoneSolid R128Done 362 363#define R128CCEPrepareCopy R128PrepareCopy 364 365static void 366R128CCECopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 367 int width, int height) 368{ 369 ScreenPtr pScreen = pDstPixmap->drawable.pScreen; 370 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 371 R128InfoPtr info = R128PTR(pScrn); 372 RING_LOCALS; 373 374 R128CCE_REFRESH( pScrn, info ); 375 376 if (info->xdir < 0) srcX += width - 1, dstX += width - 1; 377 if (info->ydir < 0) srcY += height - 1, dstY += height - 1; 378 379 BEGIN_RING( 6 ); 380 381 OUT_RING_REG( R128_SRC_Y_X, (srcY << 16) | srcX ); 382 OUT_RING_REG( R128_DST_Y_X, (dstY << 16) | dstX ); 383 OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (height << 16) | width ); 384 385 ADVANCE_RING(); 386} 387 388#define R128CCEDoneCopy R128Done 389 390static void 391R128CCESync(ScreenPtr pScreen, int marker) 392{ 393 R128CCEWaitForIdle(xf86ScreenToScrn(pScreen)); 394} 395 396#endif 397 398/* 399 * Memcpy-based UTS. 400 */ 401static Bool 402R128UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 403 char *src, int src_pitch) 404{ 405 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 406 R128InfoPtr info = R128PTR(pScrn); 407 char *dst = info->FB + exaGetPixmapOffset(pDst); 408 int dst_pitch = exaGetPixmapPitch(pDst); 409 int bpp = pDst->drawable.bitsPerPixel; 410 int cpp = (bpp + 7) >> 3; 411 int wBytes = w * cpp; 412 413 dst += (x * cpp) + (y * dst_pitch); 414 415 R128WaitForIdle(pScrn); 416 417 while (h--) { 418 memcpy(dst, src, wBytes); 419 src += src_pitch; 420 dst += dst_pitch; 421 } 422 423 return TRUE; 424} 425 426/* 427 * Hostblit-based UTS. 428 * this assumes 32bit pixels 429 */ 430static Bool 431R128UploadToScreenHW(PixmapPtr pDst, int x, int y, int w, int h, 432 char *src, int src_pitch) 433{ 434 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 435 R128InfoPtr info = R128PTR(pScrn); 436 uint32_t dst_pitch_offset, datatype; 437 int cnt, line, px; 438 unsigned char *R128MMIO = info->MMIO; 439 int bpp = pDst->drawable.bitsPerPixel; 440 uint32_t *s; 441 442 if (!R128GetDatatypeBpp(bpp, &datatype)) { 443 R128TRACE(("R128GetDatatypeBpp failed\n")); 444 return FALSE; 445 } 446 447 if (!R128GetPixmapOffsetPitch(pDst, &dst_pitch_offset)) { 448 R128TRACE(("R128GetPixmapOffsetPitch dest failed\n")); 449 return FALSE; 450 } 451 452 info->state_2d.in_use = TRUE; 453 info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL | 454 R128_GMC_BRUSH_NONE | 455 (datatype >> 8) | 456 R128_GMC_SRC_DATATYPE_COLOR | 457 R128_ROP3_S | 458 R128_DP_SRC_SOURCE_HOST_DATA | 459 R128_GMC_CLR_CMP_CNTL_DIS); 460 info->state_2d.dp_cntl = R128_DST_X_LEFT_TO_RIGHT | 461 R128_DST_Y_TOP_TO_BOTTOM; 462 info->state_2d.dp_write_mask = 0xffffffff; 463 info->state_2d.dst_pitch_offset = dst_pitch_offset; 464 info->state_2d.default_sc_bottom_right = R128_DEFAULT_SC_RIGHT_MAX | 465 R128_DEFAULT_SC_BOTTOM_MAX; 466 Emit2DState(pScrn); 467 468 R128WaitForFifo(pScrn, 3); 469 OUTREG(R128_SRC_Y_X, 0); 470 OUTREG(R128_DST_Y_X, (y << 16) | x); 471 OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); 472 473 R128WaitForFifo(pScrn, 32); 474 cnt = 0; 475 476 for (line = 0; line < h; line++) { 477 s = (void *)src; 478 for (px = 0; px < w; px++) { 479 OUTREG(R128_HOST_DATA0, cpu_to_le32(*s)); 480 s++; 481 cnt++; 482 if (cnt > 31) { 483 R128WaitForFifo(pScrn, 32); 484 cnt = 0; 485 } 486 } 487 src += src_pitch; 488 } 489 info->state_2d.in_use = FALSE; 490 exaMarkSync(pDst->drawable.pScreen); 491 return TRUE; 492} 493 494/* 495 * Memcpy-based DFS. 496 */ 497static Bool 498R128DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 499 char *dst, int dst_pitch) 500{ 501 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 502 R128InfoPtr info = R128PTR(pScrn); 503 char *src = info->FB + exaGetPixmapOffset(pSrc); 504 int src_pitch = exaGetPixmapPitch(pSrc); 505 506 int bpp = pSrc->drawable.bitsPerPixel; 507 int cpp = (bpp + 7) >> 3; 508 int wBytes = w * cpp; 509 510 src += (x * cpp) + (y * src_pitch); 511 512 R128WaitForIdle(pScrn); 513 514 while (h--) { 515 memcpy(dst, src, wBytes); 516 src += src_pitch; 517 dst += dst_pitch; 518 } 519 520 return TRUE; 521} 522 523Bool 524R128EXAInit(ScreenPtr pScreen, int total) 525{ 526 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 527 R128InfoPtr info = R128PTR(pScrn); 528 529 info->ExaDriver = exaDriverAlloc(); 530 if (!info->ExaDriver) { 531 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 532 "Could not allocate EXA driver...\n"); 533 return FALSE; 534 } 535 536 info->ExaDriver->exa_major = EXA_VERSION_MAJOR; 537 info->ExaDriver->exa_minor = EXA_VERSION_MINOR; 538 539 info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset; 540 info->ExaDriver->offScreenBase = pScrn->virtualY * 541 (pScrn->displayWidth * 542 info->CurrentLayout.pixel_bytes); 543 info->ExaDriver->memorySize = total; 544 info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS; 545 546#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) 547 info->ExaDriver->maxPitchBytes = 16320; 548#endif 549 /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */ 550 info->ExaDriver->pixmapPitchAlign = 32; 551 info->ExaDriver->pixmapOffsetAlign = 32; 552 info->ExaDriver->maxX = 2048; 553 info->ExaDriver->maxY = 2048; 554 555 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 556 "Setting up EXA callbacks\n"); 557 558#ifdef R128DRI 559 if (info->directRenderingEnabled) { 560 info->ExaDriver->PrepareSolid = R128CCEPrepareSolid; 561 info->ExaDriver->Solid = R128CCESolid; 562 info->ExaDriver->DoneSolid = R128CCEDoneSolid; 563 564 info->ExaDriver->PrepareCopy = R128CCEPrepareCopy; 565 info->ExaDriver->Copy = R128CCECopy; 566 info->ExaDriver->DoneCopy = R128CCEDoneCopy; 567 568#ifdef RENDER 569 if (info->RenderAccel) { 570 info->ExaDriver->flags |= EXA_OFFSCREEN_ALIGN_POT; 571 info->ExaDriver->CheckComposite = R128CCECheckComposite; 572 info->ExaDriver->PrepareComposite = R128CCEPrepareComposite; 573 info->ExaDriver->Composite = R128CCEComposite; 574 info->ExaDriver->DoneComposite = R128CCEDoneComposite; 575 } 576#endif 577 578 info->ExaDriver->WaitMarker = R128CCESync; 579 } else 580#endif 581 { 582 info->ExaDriver->PrepareSolid = R128PrepareSolid; 583 info->ExaDriver->Solid = R128Solid; 584 info->ExaDriver->DoneSolid = R128DoneSolid; 585 586 info->ExaDriver->PrepareCopy = R128PrepareCopy; 587 info->ExaDriver->Copy = R128Copy; 588 info->ExaDriver->DoneCopy = R128DoneCopy; 589 590 if (pScrn->bitsPerPixel < 24) { 591 info->ExaDriver->UploadToScreen = R128UploadToScreen; 592 } else { 593 info->ExaDriver->UploadToScreen = R128UploadToScreenHW; 594 } 595 info->ExaDriver->DownloadFromScreen = R128DownloadFromScreen; 596 597 /* The registers used for r128 compositing are CCE specific, just like the 598 * registers used for radeon compositing are CP specific. The radeon driver 599 * falls back to different registers when there is no DRI. The equivalent 600 * registers on the r128 (if they even exist) are not listed in the register 601 * file so I can't implement compositing without DRI. 602 */ 603 604 info->ExaDriver->WaitMarker = R128Sync; 605 } 606 607 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 608 "Initializing 2D acceleration engine...\n"); 609 610 R128EngineInit(pScrn); 611 612 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 613 "Initializing EXA driver...\n"); 614 615 if (!exaDriverInit(pScreen, info->ExaDriver)) { 616 free(info->ExaDriver); 617 return FALSE; 618 } 619 620 info->state_2d.composite_setup = FALSE; 621 return TRUE; 622} 623