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 return FALSE; 444 } 445 446 if (!R128GetPixmapOffsetPitch(pDst, &dst_pitch_offset)) { 447 return FALSE; 448 } 449 450 info->state_2d.in_use = TRUE; 451 info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL | 452 R128_GMC_BRUSH_NONE | 453 (datatype >> 8) | 454 R128_GMC_SRC_DATATYPE_COLOR | 455 R128_ROP3_S | 456 R128_DP_SRC_SOURCE_HOST_DATA | 457 R128_GMC_CLR_CMP_CNTL_DIS); 458 info->state_2d.dp_cntl = R128_DST_X_LEFT_TO_RIGHT | 459 R128_DST_Y_TOP_TO_BOTTOM; 460 info->state_2d.dp_write_mask = 0xffffffff; 461 info->state_2d.dst_pitch_offset = dst_pitch_offset; 462 info->state_2d.default_sc_bottom_right = R128_DEFAULT_SC_RIGHT_MAX | 463 R128_DEFAULT_SC_BOTTOM_MAX; 464 Emit2DState(pScrn); 465 466 R128WaitForFifo(pScrn, 3); 467 OUTREG(R128_SRC_Y_X, 0); 468 OUTREG(R128_DST_Y_X, (y << 16) | x); 469 OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); 470 471 R128WaitForFifo(pScrn, 32); 472 cnt = 0; 473 474 for (line = 0; line < h; line++) { 475 s = (void *)src; 476 for (px = 0; px < w; px++) { 477 OUTREG(R128_HOST_DATA0, cpu_to_le32(*s)); 478 s++; 479 cnt++; 480 if (cnt > 31) { 481 R128WaitForFifo(pScrn, 32); 482 cnt = 0; 483 } 484 } 485 src += src_pitch; 486 } 487 info->state_2d.in_use = FALSE; 488 exaMarkSync(pDst->drawable.pScreen); 489 return TRUE; 490} 491 492/* 493 * Memcpy-based DFS. 494 */ 495static Bool 496R128DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 497 char *dst, int dst_pitch) 498{ 499 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 500 R128InfoPtr info = R128PTR(pScrn); 501 char *src = info->FB + exaGetPixmapOffset(pSrc); 502 int src_pitch = exaGetPixmapPitch(pSrc); 503 504 int bpp = pSrc->drawable.bitsPerPixel; 505 int cpp = (bpp + 7) >> 3; 506 int wBytes = w * cpp; 507 508 src += (x * cpp) + (y * src_pitch); 509 510 R128WaitForIdle(pScrn); 511 512 while (h--) { 513 memcpy(dst, src, wBytes); 514 src += src_pitch; 515 dst += dst_pitch; 516 } 517 518 return TRUE; 519} 520 521Bool 522R128EXAInit(ScreenPtr pScreen, int total) 523{ 524 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 525 R128InfoPtr info = R128PTR(pScrn); 526 527 info->ExaDriver = exaDriverAlloc(); 528 if (!info->ExaDriver) { 529 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 530 "Could not allocate EXA driver...\n"); 531 return FALSE; 532 } 533 534 info->ExaDriver->exa_major = EXA_VERSION_MAJOR; 535 info->ExaDriver->exa_minor = EXA_VERSION_MINOR; 536 537 info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset; 538 info->ExaDriver->offScreenBase = pScrn->virtualY * 539 (pScrn->displayWidth * 540 info->CurrentLayout.pixel_bytes); 541 info->ExaDriver->memorySize = total; 542 info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS; 543 544#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) 545 info->ExaDriver->maxPitchBytes = 16320; 546#endif 547 /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */ 548 info->ExaDriver->pixmapPitchAlign = 32; 549 info->ExaDriver->pixmapOffsetAlign = 32; 550 info->ExaDriver->maxX = 2048; 551 info->ExaDriver->maxY = 2048; 552 553 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 554 "Setting up EXA callbacks\n"); 555 556#ifdef R128DRI 557 if (info->directRenderingEnabled) { 558 info->ExaDriver->PrepareSolid = R128CCEPrepareSolid; 559 info->ExaDriver->Solid = R128CCESolid; 560 info->ExaDriver->DoneSolid = R128CCEDoneSolid; 561 562 info->ExaDriver->PrepareCopy = R128CCEPrepareCopy; 563 info->ExaDriver->Copy = R128CCECopy; 564 info->ExaDriver->DoneCopy = R128CCEDoneCopy; 565 566#ifdef RENDER 567 if (info->RenderAccel) { 568 info->ExaDriver->flags |= EXA_OFFSCREEN_ALIGN_POT; 569 info->ExaDriver->CheckComposite = R128CCECheckComposite; 570 info->ExaDriver->PrepareComposite = R128CCEPrepareComposite; 571 info->ExaDriver->Composite = R128CCEComposite; 572 info->ExaDriver->DoneComposite = R128CCEDoneComposite; 573 } 574#endif 575 576 info->ExaDriver->WaitMarker = R128CCESync; 577 } else 578#endif 579 { 580 info->ExaDriver->PrepareSolid = R128PrepareSolid; 581 info->ExaDriver->Solid = R128Solid; 582 info->ExaDriver->DoneSolid = R128DoneSolid; 583 584 info->ExaDriver->PrepareCopy = R128PrepareCopy; 585 info->ExaDriver->Copy = R128Copy; 586 info->ExaDriver->DoneCopy = R128DoneCopy; 587 588 if (pScrn->bitsPerPixel < 24) { 589 info->ExaDriver->UploadToScreen = R128UploadToScreen; 590 } else { 591 info->ExaDriver->UploadToScreen = R128UploadToScreenHW; 592 } 593 info->ExaDriver->DownloadFromScreen = R128DownloadFromScreen; 594 595 /* The registers used for r128 compositing are CCE specific, just like the 596 * registers used for radeon compositing are CP specific. The radeon driver 597 * falls back to different registers when there is no DRI. The equivalent 598 * registers on the r128 (if they even exist) are not listed in the register 599 * file so I can't implement compositing without DRI. 600 */ 601 602 info->ExaDriver->WaitMarker = R128Sync; 603 } 604 605 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 606 "Initializing 2D acceleration engine...\n"); 607 608 R128EngineInit(pScrn); 609 610 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 611 "Initializing EXA driver...\n"); 612 613 if (!exaDriverInit(pScreen, info->ExaDriver)) { 614 free(info->ExaDriver); 615 return FALSE; 616 } 617 618 info->state_2d.composite_setup = FALSE; 619 return TRUE; 620} 621