smi_exa.c revision b12e5c03
1/* 2Copyright (C) 2006 Dennis De Winter All Rights Reserved. 3Copyright (C) 2007 Alex Deucher All Rights Reserved. 4 5Permission is hereby granted, free of charge, to any person obtaining a copy of 6this software and associated documentation files (the "Software"), to deal in 7the Software without restriction, including without limitation the rights to 8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9of the Software, and to permit persons to whom the Software is furnished to do 10so, subject to the following conditions: 11 12The above copyright notice and this permission notice shall be included in all 13copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 17NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22*/ 23 24#ifdef HAVE_CONFIG_H 25#include "config.h" 26#endif 27 28#include "smi.h" 29 30#if SMI501_CLI_DEBUG 31# include "smi_501.h" 32# undef WRITE_DPR 33# define WRITE_DPR(pSmi, dpr, data) \ 34 do { \ 35 if (pSmi->batch_active) \ 36 BATCH_LOAD_REG((pSmi->DPRBase - pSmi->MapBase) + \ 37 dpr, data); \ 38 else \ 39 MMIO_OUT32(pSmi->DPRBase, dpr, data); \ 40 DEBUG("DPR%02X = %08X\n", dpr, data); \ 41 } while (0) 42#endif 43 44static void 45SMI_EXASync(ScreenPtr pScreen, int marker); 46 47static Bool 48SMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 49 int xdir, int ydir, int alu, Pixel planemask); 50 51static void 52SMI_Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height); 53 54static void 55SMI_DoneCopy(PixmapPtr pDstPixmap); 56 57static Bool 58SMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg); 59 60static void 61SMI_Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2); 62 63static void 64SMI_DoneSolid(PixmapPtr pPixmap); 65 66Bool 67SMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); 68 69Bool 70SMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); 71 72static Bool 73SMI_CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture); 74static Bool 75SMI_PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, 76 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst); 77static void 78SMI_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 79 int dstX, int dstY, int width, int height); 80static void 81SMI730_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 82 int dstX, int dstY, int width, int height); 83static void 84SMI_DoneComposite(PixmapPtr pDst); 85 86 87#define PIXMAP_FORMAT(pixmap) SMI_DEDataFormat(pixmap->drawable.bitsPerPixel) 88#define PIXMAP_OFFSET(pixmap) IS_MSOC(pSmi) ? \ 89 exaGetPixmapOffset(pixmap) : exaGetPixmapOffset(pixmap) >> 3 90 91Bool 92SMI_EXAInit(ScreenPtr pScreen) 93{ 94 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 95 SMIPtr pSmi = SMIPTR(pScrn); 96 97 ENTER(); 98 99 if (!(pSmi->EXADriverPtr = exaDriverAlloc())) { 100 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate EXADriverRec.\n"); 101 LEAVE(FALSE); 102 } 103 104 /* Require 2.1 semantics: 105 Don't uninitialize the memory manager when swapping out */ 106 pSmi->EXADriverPtr->exa_major = 2; 107 pSmi->EXADriverPtr->exa_minor = 1; 108 109 SMI_EngineReset(pScrn); 110 111 /* Memory Manager */ 112 pSmi->EXADriverPtr->memoryBase = pSmi->FBBase; 113 pSmi->EXADriverPtr->memorySize = pSmi->FBReserved; 114 115 /* The framebuffer is allocated as an offscreen area with the 116 memory manager (It makes easier further resizing) */ 117 pSmi->EXADriverPtr->offScreenBase = 0; 118 119 /* Flags */ 120 pSmi->EXADriverPtr->flags = EXA_TWO_BITBLT_DIRECTIONS; 121 if (pSmi->EXADriverPtr->memorySize > pSmi->EXADriverPtr->offScreenBase) { 122 /* Offscreen Pixmaps */ 123 pSmi->EXADriverPtr->flags |= EXA_OFFSCREEN_PIXMAPS; 124 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 125 "EXA offscreen memory manager enabled.\n"); 126 } 127 else 128 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 129 "Not enough video RAM for EXA offscreen memory manager.\n"); 130 131 /* 12 bit coordinates */ 132 pSmi->EXADriverPtr->maxX = 4096; 133 pSmi->EXADriverPtr->maxY = 4096; 134 135 if (pScrn->bitsPerPixel == 24) { 136 pSmi->EXADriverPtr->maxX = 4096 / 3; 137 138 if (pSmi->Chipset == SMI_LYNX) { 139 pSmi->EXADriverPtr->maxY = 4096 / 3; 140 } 141 } 142 143 pSmi->EXADriverPtr->pixmapPitchAlign = 16; 144 pSmi->EXADriverPtr->pixmapOffsetAlign = 8; 145 146 /* Sync */ 147 pSmi->EXADriverPtr->WaitMarker = SMI_EXASync; 148 149 /* Copy */ 150 pSmi->EXADriverPtr->PrepareCopy = SMI_PrepareCopy; 151 pSmi->EXADriverPtr->Copy = SMI_Copy; 152 pSmi->EXADriverPtr->DoneCopy = SMI_DoneCopy; 153 154 /* Solid */ 155 pSmi->EXADriverPtr->PrepareSolid = SMI_PrepareSolid; 156 pSmi->EXADriverPtr->Solid = SMI_Solid; 157 pSmi->EXADriverPtr->DoneSolid = SMI_DoneSolid; 158 159#if 0 160 /* DFS & UTS */ 161 pSmi->EXADriverPtr->UploadToScreen = SMI_UploadToScreen; 162 pSmi->EXADriverPtr->DownloadFromScreen = SMI_DownloadFromScreen; 163#endif 164 165 /* Composite */ 166 pSmi->EXADriverPtr->CheckComposite = SMI_CheckComposite; 167 pSmi->EXADriverPtr->PrepareComposite = SMI_PrepareComposite; 168 169 if (IS_MSOC(pSmi) || pSmi->Chipset == SMI_COUGAR3DR) 170 pSmi->EXADriverPtr->Composite = SMI730_Composite; 171 else 172 pSmi->EXADriverPtr->Composite = SMI_Composite; 173 174 pSmi->EXADriverPtr->DoneComposite = SMI_DoneComposite; 175 176 if(!exaDriverInit(pScreen, pSmi->EXADriverPtr)) { 177 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "exaDriverInit failed.\n"); 178 LEAVE(FALSE); 179 } 180 181 182 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA Acceleration enabled.\n"); 183 184 LEAVE(TRUE); 185} 186 187static void 188SMI_EXASync(ScreenPtr pScreen, int marker) 189{ 190 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 191 192 ENTER(); 193 194 SMI_AccelSync(pScrn); 195 196 LEAVE(); 197} 198 199/* ----------------------------------------------------- EXA Copy ---------------------------------------------- */ 200 201CARD8 SMI_BltRop[16] = /* table stolen from KAA */ 202{ 203 /* GXclear */ 0x00, /* 0 */ 204 /* GXand */ 0x88, /* src AND dst */ 205 /* GXandReverse */ 0x44, /* src AND NOT dst */ 206 /* GXcopy */ 0xCC, /* src */ 207 /* GXandInverted*/ 0x22, /* NOT src AND dst */ 208 /* GXnoop */ 0xAA, /* dst */ 209 /* GXxor */ 0x66, /* src XOR dst */ 210 /* GXor */ 0xEE, /* src OR dst */ 211 /* GXnor */ 0x11, /* NOT src AND NOT dst */ 212 /* GXequiv */ 0x99, /* NOT src XOR dst */ 213 /* GXinvert */ 0x55, /* NOT dst */ 214 /* GXorReverse */ 0xDD, /* src OR NOT dst */ 215 /* GXcopyInverted*/ 0x33, /* NOT src */ 216 /* GXorInverted */ 0xBB, /* NOT src OR dst */ 217 /* GXnand */ 0x77, /* NOT src OR NOT dst */ 218 /* GXset */ 0xFF, /* 1 */ 219}; 220 221static Bool 222SMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, 223 int alu, Pixel planemask) 224{ 225 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 226 SMIPtr pSmi = SMIPTR(pScrn); 227 int src_pitch, dst_pitch; 228 unsigned long src_offset, dst_offset; 229 230 ENTER(); 231 DEBUG("xdir=%d ydir=%d alu=%02X", xdir, ydir, alu); 232 233 /* Bit Mask not supported > 16 bpp */ 234 if ((pSrcPixmap->drawable.bitsPerPixel > 16) && 235 (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))) 236 LEAVE(FALSE); 237 238 /* calculate pitch in pixel unit */ 239 src_pitch = exaGetPixmapPitch(pSrcPixmap) / (pSrcPixmap->drawable.bitsPerPixel >> 3); 240 dst_pitch = exaGetPixmapPitch(pDstPixmap) / (pDstPixmap->drawable.bitsPerPixel >> 3); 241 /* calculate offset in 8 byte (64 bit) unit */ 242 src_offset = PIXMAP_OFFSET(pSrcPixmap); 243 dst_offset = PIXMAP_OFFSET(pDstPixmap); 244 245 pSmi->AccelCmd = SMI_BltRop[alu] 246 | SMI_BITBLT 247 | SMI_QUICK_START; 248 249 if (xdir < 0 || (ydir < 0)) { 250 pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT; 251 } 252 253 if (pDstPixmap->drawable.bitsPerPixel == 24) { 254 src_pitch *= 3; 255 dst_pitch *= 3; 256 } 257 258#if SMI501_CLI_DEBUG 259 BATCH_BEGIN(7); 260#else 261 WaitQueue(); 262#endif 263 /* Destination and Source Window Widths */ 264 WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 265 /* Destination and Source Row Pitch */ 266 WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 267 268 /* Bit Mask (planemask) - 16 bit only */ 269 if (pSrcPixmap->drawable.bitsPerPixel == 16) { 270 WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); 271 } else { 272 WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 273 } 274 /* Drawing engine data format */ 275 WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pDstPixmap)); 276 /* Destination and Source Base Address (offset) */ 277 WRITE_DPR(pSmi, 0x40, src_offset); 278 WRITE_DPR(pSmi, 0x44, dst_offset); 279 280 WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 281#if SMI501_CLI_DEBUG 282 BATCH_END(); 283#endif 284 285 LEAVE(TRUE); 286} 287 288static void 289SMI_Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, 290 int dstY, int width, int height) 291{ 292 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 293 SMIPtr pSmi = SMIPTR(pScrn); 294 295 ENTER(); 296 DEBUG("srcX=%d srcY=%d dstX=%d dstY=%d width=%d height=%d\n", 297 srcX, srcY, dstX, dstY, width, height); 298 299 if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 300 srcX += width - 1; 301 srcY += height - 1; 302 dstX += width - 1; 303 dstY += height - 1; 304 } 305 306 if (pDstPixmap->drawable.bitsPerPixel == 24) { 307 srcX *= 3; 308 dstX *= 3; 309 width *= 3; 310 311 if (pSmi->Chipset == SMI_LYNX) { 312 srcY *= 3; 313 dstY *= 3; 314 } 315 316 if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 317 srcX += 2; 318 dstX += 2; 319 } 320 } 321 322#if SMI501_CLI_DEBUG 323 BATCH_BEGIN(3); 324#else 325 WaitQueue(); 326#endif 327 WRITE_DPR(pSmi, 0x00, (srcX << 16) + (srcY & 0xFFFF)); 328 WRITE_DPR(pSmi, 0x04, (dstX << 16) + (dstY & 0xFFFF)); 329 WRITE_DPR(pSmi, 0x08, (width << 16) + (height & 0xFFFF)); 330#if SMI501_CLI_DEBUG 331 BATCH_END(); 332#endif 333 334 LEAVE(); 335} 336 337static void 338SMI_DoneCopy(PixmapPtr pDstPixmap) 339{ 340 ENTER(); 341 342 LEAVE(); 343} 344 345/* ----------------------------------------------------- EXA Solid --------------------------------------------- */ 346 347CARD8 SMI_SolidRop[16] = /* table stolen from KAA */ 348{ 349 /* GXclear */ 0x00, /* 0 */ 350 /* GXand */ 0xA0, /* src AND dst */ 351 /* GXandReverse */ 0x50, /* src AND NOT dst */ 352 /* GXcopy */ 0xF0, /* src */ 353 /* GXandInverted*/ 0x0A, /* NOT src AND dst */ 354 /* GXnoop */ 0xAA, /* dst */ 355 /* GXxor */ 0x5A, /* src XOR dst */ 356 /* GXor */ 0xFA, /* src OR dst */ 357 /* GXnor */ 0x05, /* NOT src AND NOT dst */ 358 /* GXequiv */ 0xA5, /* NOT src XOR dst */ 359 /* GXinvert */ 0x55, /* NOT dst */ 360 /* GXorReverse */ 0xF5, /* src OR NOT dst */ 361 /* GXcopyInverted*/ 0x0F, /* NOT src */ 362 /* GXorInverted */ 0xAF, /* NOT src OR dst */ 363 /* GXnand */ 0x5F, /* NOT src OR NOT dst */ 364 /* GXset */ 0xFF, /* 1 */ 365}; 366 367static Bool 368SMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 369{ 370 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 371 SMIPtr pSmi = SMIPTR(pScrn); 372 int dst_pitch; 373 unsigned long dst_offset; 374 375 ENTER(); 376 DEBUG("alu=%02X\n", alu); 377 378 /* HW ignores alpha */ 379 if (pPixmap->drawable.bitsPerPixel == 32) 380 LEAVE(FALSE); 381 382 /* Bit Mask not supported > 16 bpp */ 383 if ((pPixmap->drawable.bitsPerPixel > 16) && 384 (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))) 385 LEAVE(FALSE); 386 387 /* calculate pitch in pixel unit */ 388 dst_pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel >> 3); 389 /* calculate offset in 8 byte (64 bit) unit */ 390 dst_offset = PIXMAP_OFFSET(pPixmap); 391 392 pSmi->AccelCmd = SMI_SolidRop[alu] 393 | SMI_BITBLT 394 | SMI_QUICK_START; 395 396 if (pPixmap->drawable.bitsPerPixel == 24) { 397 dst_pitch *= 3; 398 } 399 400#if SMI501_CLI_DEBUG 401 BATCH_BEGIN(10); 402#else 403 WaitQueue(); 404#endif 405 406 /* Destination Window Width */ 407 WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); 408 /* Destination Row Pitch */ 409 WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); 410 411 /* Bit Mask (planemask) - 16 bit only */ 412 if (pPixmap->drawable.bitsPerPixel == 16) { 413 WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); 414 } else { 415 WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 416 } 417 418 /* Drawing engine data format */ 419 WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pPixmap)); 420 /* Source and Destination Base Address (offset) */ 421 WRITE_DPR(pSmi, 0x40, dst_offset); 422 WRITE_DPR(pSmi, 0x44, dst_offset); 423 /* Foreground Color */ 424 WRITE_DPR(pSmi, 0x14, fg); 425 /* Mono Pattern High and Low */ 426 WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF); 427 WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF); 428 429 WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 430#if SMI501_CLI_DEBUG 431 BATCH_END(); 432#endif 433 434 LEAVE(TRUE); 435} 436 437static void 438SMI_Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 439{ 440 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 441 SMIPtr pSmi = SMIPTR(pScrn); 442 int w, h; 443 444 ENTER(); 445 DEBUG("x1=%d y1=%d x2=%d y2=%d\n", x1, y1, x2, y2); 446 447 w = (x2 - x1); 448 h = (y2 - y1); 449 450 if (pPixmap->drawable.bitsPerPixel == 24) { 451 x1 *= 3; 452 w *= 3; 453 454 if (pSmi->Chipset == SMI_LYNX) { 455 y1 *= 3; 456 } 457 } 458 459#if SMI501_CLI_DEBUG 460 BATCH_BEGIN(2); 461#else 462 WaitQueue(); 463#endif 464 WRITE_DPR(pSmi, 0x04, (x1 << 16) | (y1 & 0xFFFF)); 465 WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 466#if SMI501_CLI_DEBUG 467 BATCH_END(); 468#endif 469 470 LEAVE(); 471} 472 473static void 474SMI_DoneSolid(PixmapPtr pPixmap) 475{ 476 ENTER(); 477 478 LEAVE(); 479} 480 481/* --------------------------------------- EXA DFS & UTS ---------------------------------------- */ 482 483Bool 484SMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 485 char *dst, int dst_pitch) 486{ 487 unsigned char *src = pSrc->devPrivate.ptr; 488 int src_pitch = exaGetPixmapPitch(pSrc); 489 490 ENTER(); 491 DEBUG("x=%d y=%d w=%d h=%d dst=%d dst_pitch=%d\n", 492 x, y, w, h, dst, dst_pitch); 493 494 exaWaitSync(pSrc->drawable.pScreen); 495 496 src += (y * src_pitch) + (x * pSrc->drawable.bitsPerPixel/8); 497 w *= pSrc->drawable.bitsPerPixel/8; 498 499 while (h--) { 500 memcpy(dst, src, w); 501 src += src_pitch; 502 dst += dst_pitch; 503 } 504 505 LEAVE(TRUE); 506} 507 508Bool 509SMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 510 char *src, int src_pitch) 511{ 512 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 513 SMIPtr pSmi = SMIPTR(pScrn); 514 int dst_pixelpitch, src_pixelpitch, align, aligned_pitch; 515 unsigned long dst_offset; 516 517 ENTER(); 518 DEBUG("x=%d y=%d w=%d h=%d src=%d src_pitch=%d\n", 519 x, y, w, h, src, src_pitch); 520 521 if (pDst->drawable.bitsPerPixel == 24) { 522 align = 16; 523 } else { 524 align = 128 / pDst->drawable.bitsPerPixel; 525 } 526 527 aligned_pitch = ((w*pDst->drawable.bitsPerPixel >> 3) + align - 1) & ~(align - 1); 528 529 /* calculate pitch in pixel unit */ 530 dst_pixelpitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); 531 src_pixelpitch = src_pitch / (pDst->drawable.bitsPerPixel >> 3); 532 /* calculate offset in 8 byte (64 bit) unit */ 533 dst_offset = PIXMAP_OFFSET(pDst); 534 535 pSmi->AccelCmd = 0xCC /* GXcopy */ 536 | SMI_HOSTBLT_WRITE 537 | SMI_QUICK_START; 538 539 /* set clipping */ 540 SMI_SetClippingRectangle(pScrn, x, y, x+w, y+h); 541 542#if SMI501_CLI_DEBUG 543 BATCH_BEGIN(9); 544#else 545 WaitQueue(); 546#endif 547 /* Destination and Source Window Widths */ 548 WRITE_DPR(pSmi, 0x3C, (dst_pixelpitch << 16) | (src_pixelpitch & 0xFFFF)); 549 550 if (pDst->drawable.bitsPerPixel == 24) { 551 x *= 3; 552 w *= 3; 553 dst_pixelpitch *= 3; 554 if (pSmi->Chipset == SMI_LYNX) { 555 y *= 3; 556 } 557 } 558 559 /* Source and Destination Row Pitch */ 560 WRITE_DPR(pSmi, 0x10, (dst_pixelpitch << 16) | (src_pixelpitch & 0xFFFF)); 561 /* Drawing engine data format */ 562 WRITE_DPR(pSmi, 0x1C,PIXMAP_FORMAT(pDst)); 563 /* Source and Destination Base Address (offset) */ 564 WRITE_DPR(pSmi, 0x40, 0); 565 WRITE_DPR(pSmi, 0x44, dst_offset); 566 567 WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 568 WRITE_DPR(pSmi, 0x00, 0); 569 WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 570 WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 571#if SMI501_CLI_DEBUG 572 BATCH_END(); 573#endif 574 575 while (h--) { 576 memcpy(pSmi->DataPortBase, src, aligned_pitch); 577 src += src_pitch; 578 } 579 580 /* disable clipping */ 581 SMI_DisableClipping(pScrn); 582 583 exaWaitSync(pDst->drawable.pScreen); 584 585 LEAVE(TRUE); 586} 587 588/* --------------------------------------- EXA Composite ---------------------------------------- */ 589/* This is a very incomplete Composite implementation that only 590 accelerates PictOpSrc with source coordinates transformation by 591 using 2D Engine rotate-BITBLTs */ 592 593#define SMI_ISROTATION_90(t) \ 594 (t->matrix[0][0] == 0 && t->matrix[0][1] == xFixed1 && \ 595 t->matrix[1][0] == -xFixed1 && t->matrix[1][1] == 0) 596 597#define SMI_ISROTATION_270(t) \ 598 (t->matrix[0][0] == 0 && t->matrix[0][1] == -xFixed1 && \ 599 t->matrix[1][0] == xFixed1 && t->matrix[1][1] == 0) 600 601static Bool 602SMI_CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) 603{ 604 ENTER(); 605 606 if(op!=PictOpSrc || pMaskPicture || 607 pSrcPicture->repeatType || !pSrcPicture->transform) 608 LEAVE(FALSE); 609 610 if(!SMI_ISROTATION_90(pSrcPicture->transform) && 611 !SMI_ISROTATION_270(pSrcPicture->transform)) 612 LEAVE(FALSE); 613 614 if(PICT_FORMAT_BPP(pSrcPicture->format) == 24) 615 LEAVE(FALSE); 616 617 LEAVE(TRUE); 618} 619 620static Bool 621SMI_PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, 622 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 623{ 624 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 625 SMIPtr pSmi = SMIPTR(pScrn); 626 int src_pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel >> 3); 627 int dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); 628 629 ENTER(); 630 631#if SMI501_CLI_DEBUG 632 BATCH_BEGIN(7); 633#else 634 WaitQueue(); 635#endif 636 637 /* Destination and Source Window Widths */ 638 WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 639 640 /* Destination and Source Row Pitch */ 641 WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 642 643 /* Drawing engine data format */ 644 WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pDst)); 645 646 /* DE Bit Mask */ 647 WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 648 649 /* Destination and Source Base Address (offset) */ 650 WRITE_DPR(pSmi, 0x40, PIXMAP_OFFSET(pSrc)); 651 WRITE_DPR(pSmi, 0x44, PIXMAP_OFFSET(pDst)); 652 653 /* DE command*/ 654 if(SMI_ISROTATION_90(pSrcPicture->transform)) 655 WRITE_DPR(pSmi, 0x0C, 0xCC /*GXCopy*/ | SMI_ROTATE_BLT | 656 SMI_ROTATE_CW | SMI_QUICK_START); 657 else 658 WRITE_DPR(pSmi, 0x0C, 0xCC /*GXCopy*/ | SMI_ROTATE_BLT | 659 SMI_ROTATE_CCW | SMI_QUICK_START); 660 661#if SMI501_CLI_DEBUG 662 BATCH_END(); 663#endif 664 665 pSmi->renderTransform = pSrcPicture->transform; 666 667 LEAVE(TRUE); 668} 669 670static void 671SMI_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 672 int dstX, int dstY, int width, int height) 673{ 674 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 675 SMIPtr pSmi = SMIPTR(pScrn); 676 PictTransformPtr t = pSmi->renderTransform; 677 PictVector v; 678 679 ENTER(); 680 681 if(SMI_ISROTATION_90(t)){ 682 srcX=srcX+width; 683 dstX=dstX+width-1; 684 }else{ 685 srcY=srcY+height; 686 dstY=dstY+height-1; 687 } 688 689 v.vector[0] = IntToxFixed(srcX); 690 v.vector[1] = IntToxFixed(srcY); 691 v.vector[2] = xFixed1; 692 PictureTransformPoint(t, &v); 693 694#if SMI501_CLI_DEBUG 695 BATCH_BEGIN(3); 696#else 697 WaitQueue(); 698#endif 699 700 WRITE_DPR(pSmi, 0x00, (xFixedToInt(v.vector[0]) << 16) + (xFixedToInt(v.vector[1]) & 0xFFFF)); 701 WRITE_DPR(pSmi, 0x04, (dstX << 16) + (dstY & 0xFFFF)); 702 WRITE_DPR(pSmi, 0x08, (height << 16) + (width & 0xFFFF)); 703#if SMI501_CLI_DEBUG 704 BATCH_END(); 705#endif 706 707 LEAVE(); 708} 709 710static void 711SMI730_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 712 int dstX, int dstY, int width, int height) 713{ 714 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 715 SMIPtr pSmi = SMIPTR(pScrn); 716 int maxPixels; 717 718 ENTER(); 719 720 /* Both SM501 and SM731 cannot rotate-blt more than a certain 721 number of pixels. */ 722 if(IS_MSOC(pSmi)) 723 maxPixels = 128 / pDst->drawable.bitsPerPixel; 724 else 725 maxPixels = 1280 / pDst->drawable.bitsPerPixel; 726 727 while(height>0){ 728 SMI_Composite(pDst, srcX, srcY, maskX, maskY, dstX, dstY, width, min(height, maxPixels)); 729 730 srcY += maxPixels; 731 dstY += maxPixels; 732 height -= maxPixels; 733 } 734 735 LEAVE(); 736} 737 738static void 739SMI_DoneComposite(PixmapPtr pDst) 740{ 741 ENTER(); 742 LEAVE(); 743} 744