1/* 2 * Copyright 1997-2000 by Robin Cutshaw <robin@XFree86.Org> 3 * Copyright 2005 Adam Jackson <ajax@nwnk.net> 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the names of the authors not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. The authors make no representations 12 * about the suitability of this software for any purpose. It is provided 13 * "as is" without express or implied warranty. 14 * 15 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24/* Solid and Copy support derived from the i128 XAA code */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "exa.h" 31#include "miline.h" 32#include "servermd.h" 33#include "picture.h" 34 35#include "xf86.h" 36#include "xf86_OSproc.h" 37#include "xf86Pci.h" 38 39#include "i128.h" 40#include "i128reg.h" 41 42#define PI128_FROM_PIXMAP(x) \ 43 I128Ptr pI128 = I128PTR(xf86ScreenToScrn(x->drawable.pScreen)) 44#define PI128_FROM_SCREEN(x) \ 45 I128Ptr pI128 = I128PTR(xf86ScreenToScrn(x)) 46#define PI128_FROM_PICTURE(x) \ 47 I128Ptr pI128 = I128PTR(xf86ScreenToScrn(x->pDrawable->pScreen)) 48 49/* we might be able to do something smarter than this */ 50#define ENG_PIPELINE_READY() \ 51 while (pI128->mem.rbase_a[BUSY] & BUSY_BUSY) 52#define ENG_DONE() \ 53 while (pI128->mem.rbase_a[FLOW] & (FLOW_DEB | FLOW_MCB | FLOW_PRV)) 54 55#if 1 56#define I128_EXA_DEBUG(x) 57#else 58#define I128_EXA_DEBUG(x) ErrorF x 59#endif 60 61/* technically we should set the caches to bogus things during init... */ 62#define CACHE_DEBUG 0 63 64#define CACHED_UPDATE(val, reg) \ 65 do if (pI128->val != val) { \ 66 if (CACHE_DEBUG) { I128_EXA_DEBUG(("Updated cache for " #reg "\n")); } \ 67 pI128->mem.rbase_a[reg] = pI128->val = val; \ 68 } while (0) 69 70static void 71i128SetBufCtrl(I128Ptr pI128, int dest_bpp) 72{ 73 unsigned int buf_ctrl; 74 75 switch (dest_bpp) { 76 case 8: buf_ctrl = BC_PSIZ_8B; break; 77 case 16: buf_ctrl = BC_PSIZ_16B; break; 78 case 24: 79 case 32: buf_ctrl = BC_PSIZ_32B; break; 80 default: buf_ctrl = 0; break; /* error */ 81 } 82 if (pI128->Chipset == PCI_CHIP_I128_T2R) { 83 if (pI128->MemoryType == I128_MEMORY_SGRAM) 84 buf_ctrl |= BC_MDM_PLN; 85 else 86 buf_ctrl |= BC_BLK_ENA; 87 } 88 89 CACHED_UPDATE(buf_ctrl, BUF_CTRL); 90} 91 92static const CARD32 i128alu[16] = 93{ 94 CR_CLEAR << 8, 95 CR_AND << 8, 96 CR_AND_REV << 8, 97 CR_COPY << 8, 98 CR_AND_INV << 8, 99 CR_NOOP << 8, 100 CR_XOR << 8, 101 CR_OR << 8, 102 CR_NOR << 8, 103 CR_EQUIV << 8, 104 CR_INVERT << 8, 105 CR_OR_REV << 8, 106 CR_COPY_INV << 8, 107 CR_OR_INV << 8, 108 CR_NAND << 8, 109 CR_SET << 8 110}; 111 112/* 8bpp 16bpp 32bpp unused */ 113static const int min_size[] = { 0x62, 0x32, 0x1A, 0x00 }; 114static const int max_size[] = { 0x80, 0x40, 0x20, 0x00 }; 115static const int split_size[] = { 0x20, 0x10, 0x08, 0x00 }; 116 117/* 118 * this is the workhorse for our solid and copy routines. this works because 119 * when CS_SOLID is set, the color comes from the FORE register regardless of 120 * the source pixmap coords. 121 */ 122 123static void 124i128ExaBlit(PixmapPtr dst, int x1, int y1, int x2, int y2, int w, int h) 125{ 126 int wh; 127 PI128_FROM_PIXMAP(dst); 128 129 I128_EXA_DEBUG(("Blit: %d %d %d %d %d %d\n", x1, y1, x2, y2, w, h)); 130 ENG_PIPELINE_READY(); 131 132 /* 133 * this deserves explanation. XY3_DIR == 0 means left to right, top to 134 * bottom. setting bit zero (DIR_LR_BT) switches to bottom to top, and 135 * setting bit one (DIR_RL_TB) switches to right to left. XXX rewrite me. 136 */ 137 if (pI128->blitdir & DIR_RL_TB) { /* right-to-left */ 138 x1 += w; x1--; 139 x2 += w; x2--; 140 } 141 if (pI128->blitdir & DIR_LR_BT) { /* bottom-to-top */ 142 y1 += h; y1--; 143 y2 += h; y2--; 144 } 145 146 if (pI128->Chipset == PCI_CHIP_I128) { 147 int bppi; 148 149 /* The I128-1 has a nasty bitblit bug 150 * that occurs when dest is exactly 8 pages wide 151 */ 152 153 bppi = (pI128->mem.rbase_a[BUF_CTRL] & BC_PSIZ_MSK) >> 24; 154 155 if ((w >= min_size[bppi]) && (w <= max_size[bppi])) { 156 bppi = split_size[bppi]; 157#if 1 158 /* split method */ 159 160 wh = (bppi << 16) | h; 161 CACHED_UPDATE(wh, XY2_WH); 162 pI128->mem.rbase_a[XY0_SRC] = (x1 << 16) | y1; MB; 163 pI128->mem.rbase_a[XY1_DST] = (x2 << 16) | y2; MB; 164 165 ENG_PIPELINE_READY(); 166 167 w -= bppi; 168 169 if (pI128->blitdir & DIR_RL_TB) { 170 /* right to left blit */ 171 x1 -= bppi; 172 x2 -= bppi; 173 } else { 174 /* left to right blit */ 175 x1 += bppi; 176 x2 += bppi; 177 } 178#else 179 /* clip method */ 180 pI128->mem.rbase_a[CLPTL] = (x2 << 16) | y2; 181 pI128->mem.rbase_a[CLPBR] = ((x2 + w) << 16) | (y2 + h); 182 w += bppi; 183#endif 184 } 185 } 186 187 /* this is overkill, but you can never have too much overkill */ 188 wh = (w << 16) | h; 189 CACHED_UPDATE(wh, XY2_WH); 190 191 pI128->mem.rbase_a[XY0_SRC] = (x1 << 16) | y1; MB; 192 pI128->mem.rbase_a[XY1_DST] = (x2 << 16) | y2; MB; 193} 194 195static void 196i128WaitMarker(ScreenPtr pScreen, int Marker) 197{ 198 PI128_FROM_SCREEN(pScreen); 199 ENG_DONE(); 200} 201 202static void 203i128SetPlanemask(I128Ptr pI128, Pixel p) 204{ 205 Pixel planemask; 206 I128_EXA_DEBUG(("SetPlanemask: %d\n", (int)p)); 207 if (p == -1) 208 planemask = -1; 209 else switch (pI128->bitsPerPixel) { 210 case 8: 211 planemask = p * 0x01010101; break; 212 case 16: 213 planemask = p * 0x00010001; break; 214 default: 215 planemask = p; break; 216 } 217 218 CACHED_UPDATE(planemask, MASK); 219} 220 221/* this should be superfluous... */ 222static void 223i128SetClip(I128Ptr pI128) 224{ 225#if 0 226 pI128->clptl = pI128->mem.rbase_a[CLPTL] = 0x00000000; 227 pI128->clpbr = pI128->mem.rbase_a[CLPBR] = (4095 << 16) | 2047; 228#endif 229} 230 231static void 232i128SetBlitDirection(I128Ptr pI128, int dx, int dy) 233{ 234 int blitdir; 235 236 I128_EXA_DEBUG(("SetBlitDirection: %d %d\n", dx, dy)); 237 238 if (dx < 0) { 239 if (dy < 0) blitdir = DIR_RL_BT; 240 else blitdir = DIR_RL_TB; 241 } else { 242 if (dy < 0) blitdir = DIR_LR_BT; 243 else blitdir = DIR_LR_TB; 244 } 245 246 CACHED_UPDATE(blitdir, XY3_DIR); 247} 248 249static void 250i128SetRop(I128Ptr pI128, int alu, int solid) 251{ 252 int cmd; 253 254 I128_EXA_DEBUG(("SetRop: %d %d\n", alu, solid)); 255 256 cmd = i128alu[alu] | CO_BITBLT | (solid ? (CS_SOLID << 16) : 0); 257 258 CACHED_UPDATE(cmd, CMD); 259} 260 261static void 262i128SetSourcePixmap(I128Ptr pI128, PixmapPtr src) 263{ 264 unsigned int sorg = exaGetPixmapOffset(src); 265 unsigned int sptch = exaGetPixmapPitch(src); 266 267 I128_EXA_DEBUG(("SetSourcePixmap: %x, %d\n", sorg, sptch)); 268 269 CACHED_UPDATE(sorg, DE_SORG); 270 CACHED_UPDATE(sptch, DE_SPTCH); 271} 272 273static void 274i128SetDestPixmap(I128Ptr pI128, PixmapPtr dst) 275{ 276 unsigned int dorg = exaGetPixmapOffset(dst); 277 unsigned int dptch = exaGetPixmapPitch(dst); 278 279 I128_EXA_DEBUG(("SetDestPixmap: %x, %d\n", dorg, dptch)); 280 281 CACHED_UPDATE(dorg, DE_DORG); 282 CACHED_UPDATE(dptch, DE_DPTCH); 283} 284 285static void 286i128SetTexture(I128Ptr pI128, PixmapPtr tex) 287{ 288 unsigned int torg = exaGetPixmapOffset(tex); 289 unsigned int tptch = exaGetPixmapPitch(tex); 290 291 I128_EXA_DEBUG(("SetTexture: %x, %d\n", torg, tptch)); 292 293 CACHED_UPDATE(torg, LOD0_ORG); 294 CACHED_UPDATE(tptch, DE_TPTCH); 295} 296 297static const int func_tab[13][2] = { 298 /* source function, destination function */ 299 { ABLEND_SRC_ZERO, ABLEND_DST_ZERO }, /* clear */ 300 { ABLEND_SRC_ONE, ABLEND_DST_ZERO }, /* src */ 301 { ABLEND_SRC_ZERO, ABLEND_DST_ONE }, /* dst */ 302 { ABLEND_SRC_ONE, ABLEND_DST_OMSRC_ALPHA }, /* over */ 303 { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_ONE }, /* overreverse */ 304 { ABLEND_SRC_DST_ALPHA, ABLEND_DST_ZERO }, /* in */ 305 { ABLEND_SRC_ZERO, ABLEND_DST_SRC_ALPHA }, /* inreverse */ 306 { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_ZERO }, /* out */ 307 { ABLEND_SRC_ZERO, ABLEND_DST_OMSRC_ALPHA }, /* outreverse */ 308 { ABLEND_SRC_DST_ALPHA, ABLEND_DST_OMSRC_ALPHA }, /* atop */ 309 { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_SRC_ALPHA }, /* atopreverse */ 310 { ABLEND_SRC_OMDST_ALPHA, ABLEND_DST_OMSRC_ALPHA }, /* xor */ 311 { ABLEND_SRC_ONE, ABLEND_DST_ONE } /* add */ 312}; 313 314static void 315i128SetAlphaForOp(I128Ptr pI128, int op, int enable) 316{ 317 int acntrl = 0; 318 319 if (enable) { 320 acntrl |= ACTL_BE; /* blend enable */ 321 acntrl |= func_tab[op][0]; /* source factor */ 322 acntrl |= func_tab[op][1]; /* dest_factor */ 323 acntrl |= 0; /* ACTL_AMD; / * modulate alpha */ 324 } else { 325 acntrl = 0; 326 } 327 328 I128_EXA_DEBUG(("SetAlphaForOp: %d, %d\n", op, enable)); 329 330 CACHED_UPDATE(acntrl, ACNTRL); 331} 332 333/* we don't need a finalizer, yet */ 334static void 335i128Done(PixmapPtr p) { 336 I128_EXA_DEBUG(("Done\n\n")); 337 return; 338} 339 340/* Solid */ 341 342static Bool 343i128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 344{ 345 PI128_FROM_PIXMAP(pPixmap); 346 347 ENG_PIPELINE_READY(); 348 349 i128SetPlanemask(pI128, planemask); 350 351 if (alu != GXclear && alu != GXset) 352 pI128->mem.rbase_a[FORE] = fg; 353 354 i128SetClip(pI128); 355 i128SetBlitDirection(pI128, 1, 1); /* probably unnecessary/ignored */ 356 357 i128SetAlphaForOp(pI128, 0, 0); 358 i128SetRop(pI128, alu, 1); 359 360 /* no need to set the source, the chip ignores it */ 361 i128SetDestPixmap(pI128, pPixmap); 362 363 return TRUE; 364} 365 366static void 367i128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 368{ 369 i128ExaBlit(pPixmap, 0, 0, x1, y1, x2 - x1, y2 - y1); 370} 371 372/* Copy */ 373 374static Bool 375i128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, 376 int alu, Pixel planemask) 377{ 378 PI128_FROM_PIXMAP(pSrcPixmap); 379 380 ENG_PIPELINE_READY(); 381 382 i128SetPlanemask(pI128, planemask); 383 i128SetClip(pI128); 384 i128SetBlitDirection(pI128, dx, dy); 385 386 i128SetAlphaForOp(pI128, 0, 0); 387 i128SetRop(pI128, alu, 0); 388 389 i128SetSourcePixmap(pI128, pSrcPixmap); 390 i128SetDestPixmap(pI128, pDstPixmap); 391 392 return TRUE; 393} 394 395static void 396i128Copy(PixmapPtr pDstPixmap, int x1, int y1, int x2, int y2, int w, int h) 397{ 398 i128ExaBlit(pDstPixmap, x1, y1, x2, y2, w, h); 399} 400 401/* Composite */ 402 403static const struct source_format source_formats[] = { 404 /* 32bpp */ 405 { PICT_a8r8g8b8, 0x14, 0, 0 }, 406 { PICT_x8r8g8b8, 0x14, 0, 1 }, 407#if 0 408 { PICT_a8b8g8r8, 0x14, 0, 0 }, 409 { PICT_x8b8g8r8, 0x14, 0, 1 }, 410 /* no direct 24bpp formats */ 411 /* 16bpp */ 412 { PICT_r5g6b5, 0x12, 0, 0 }, 413 { PICT_b5g6r5, 0x12, 0, 0 }, 414 { PICT_a1r5g5b5, 0x11, 0, 0 }, 415 { PICT_x1r5g5b5, 0x11, 0, 1 }, 416 { PICT_a1b5g5r5, 0x11, 0, 0 }, 417 { PICT_x1b5g5r5, 0x11, 0, 1 }, 418 { PICT_a4r4g4b4, 0x10, 0, 0 }, 419 { PICT_x4r4g4b4, 0x10, 0, 1 }, 420 { PICT_a4b4g4r4, 0x10, 0, 0 }, 421 { PICT_x4b4g4r4, 0x10, 0, 1 }, 422 /* 8bpp */ 423 { PICT_a8, 0x21, 0, 0 }, 424 { PICT_r3g3b2, 0x0D, 0, 0 }, 425 { PICT_b2g3r3, 0x0D, 0, 0 }, 426 { PICT_a2r2g2b2, 0x30, 0, 0 }, 427 { PICT_a2b2g2r2, 0x30, 0, 0 }, 428 /* 4bpp */ 429 { PICT_a4, 0x20, 0, 0 }, 430#endif 431 /* terminator */ 432 { 0, 0, 0, 0 } 433}; 434 435static struct source_format * 436i128MapSourceFormat(int fmt) 437{ 438 struct source_format *f; 439 for (f = (struct source_format *)source_formats; f->render_format; f++) 440 if (f->render_format == fmt) 441 return f; 442 return NULL; 443} 444 445struct dest_format { 446 int render_format; 447 int i128_format; 448}; 449 450#if 0 451static const struct dest_format dest_formats[] = { 452 { 0, 0 } 453}; 454 455static struct dest_format * 456i128MapDestFormat(int fmt) 457{ 458 return NULL; 459} 460#endif 461 462/* Composite is probably t2r and t2r4 only */ 463static Bool 464i128CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 465 PicturePtr pDstPicture) 466{ 467 PI128_FROM_PICTURE(pDstPicture); 468 469 if (op >= PictOpSaturate) return FALSE; 470 471 /* 472 * no direct alpha mask support. we only have one TMU, so while we 473 * can emulate it, we should emulate it in the generic EXA layer. 474 */ 475 if (pMaskPicture) return FALSE; 476 477 /* when transforms added, be sure to check for linear/nearest */ 478 if (pSrcPicture->transform && pSrcPicture->filter != PictFilterNearest) 479 return FALSE; 480 481 /* no support for external alpha */ 482 if (pSrcPicture->alphaMap || pDstPicture->alphaMap) return FALSE; 483 484 /* driver currently doesn't support repeating */ 485 if (pSrcPicture->repeat) return FALSE; 486 487 pI128->source = i128MapSourceFormat(pSrcPicture->format); 488 if (!pI128->source) 489 return FALSE; 490#if 0 491 if (!i128MapDestFormat(pDstPicture->format)) return FALSE; 492#endif 493 494 return TRUE; 495} 496 497static Bool 498i128PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 499 PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, 500 PixmapPtr pDst) 501{ 502 unsigned int cmd; 503 unsigned int tex_ctl = 0; 504 unsigned int threedctl = 0; 505 PI128_FROM_PIXMAP(pDst); 506 507 /* 2D setup */ 508 i128SetBufCtrl(pI128, pDst->drawable.bitsPerPixel); 509 i128SetPlanemask(pI128, -1); 510 i128SetSourcePixmap(pI128, pSrc); 511 i128SetDestPixmap(pI128, pDst); 512 513 /* TEX_INV command here? */ 514 515 cmd = CO_TRIAN3D; 516 CACHED_UPDATE(cmd, CMD); 517 518 /* 3D setup */ 519 i128SetTexture(pI128, pSrc); 520 521 i128SetAlphaForOp(pI128, op, 1); 522 523 /* it looks pointless to cache these, but we'll need it for DRI */ 524 525 tex_ctl |= TEX_TM; /* enable texture mapping */ 526 tex_ctl |= TEX_NMG | TEX_NMN; /* nearest interpolation */ 527 tex_ctl |= 0; /* TEX_RM; / * modulate RGB */ 528 CACHED_UPDATE(tex_ctl, TEX_CTL); 529 530 threedctl |= 0; /* COMP_TRUE << TCTL_ZOP_SHIFT; / * always pass Z check */ 531 threedctl |= TCTL_ABS; /* enable alpha blend */ 532 threedctl |= TCTL_TBS; /* enable texture blend */ 533 threedctl |= TCTL_RT; /* draw textured rectangle */ 534 CACHED_UPDATE(threedctl, THREEDCTL); 535 536 return TRUE; 537} 538 539static void 540i128Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 541 int dstX, int dstY, int width, int height) 542{ 543 PI128_FROM_PIXMAP(pDst); 544 545 /* 546 * vertex setup. vertex layout must be: 547 * V0 V1 548 * V2 (V3 is implicit) 549 */ 550 551 pI128->mem.rbase_af[V0_X] = 0.0; 552 pI128->mem.rbase_af[V0_Y] = 0.0; 553 pI128->mem.rbase_af[V0_W] = 1.0; 554 pI128->mem.rbase_af[V0_U] = 0.0; 555 pI128->mem.rbase_af[V0_V] = 0.0; 556 pI128->mem.rbase_af[V1_X] = 300.0; 557 pI128->mem.rbase_af[V1_Y] = 0.0; 558 pI128->mem.rbase_af[V1_W] = 1.0; 559 pI128->mem.rbase_af[V1_U] = 1.0; 560 pI128->mem.rbase_af[V1_V] = 0.0; 561 pI128->mem.rbase_af[V2_X] = 0.0; 562 pI128->mem.rbase_af[V2_Y] = 300.0; 563 pI128->mem.rbase_af[V2_W] = 1.0; 564 pI128->mem.rbase_af[V2_U] = 0.0; 565 pI128->mem.rbase_af[V2_V] = 1.0; 566 567 /* and fire */ 568 pI128->mem.rbase_a[TRIGGER3D] = 1; MB; 569 570#if 0 571 static int i = 0; 572 /* test for raster */ 573 if (!(i = (i + 1) % 32)) { 574 ErrorF("Composite test: %d %d %d %d %d %d\n", srcX, srcY, dstX, dstY, 575 width, height); 576 } 577 i128SetRop(pI128, GXxor, 0); 578 i128ExaBlit(pDst, srcX, srcY, dstX, dstY, width, height); 579#endif 580} 581 582#if 0 583/* 584 * upload and download will require a DRM. AGP DMA only works on T2R4, and 585 * then only for upload. we could probably use memory windows on other chips, 586 * but those have goofy alignment restrictions and need to be disabled when 587 * not in use. 588 */ 589static Bool 590i128DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, 591 int dst_pitch) 592{ 593} 594 595static Bool 596i128UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, 597 int src_pitch) 598{ 599} 600#endif 601 602Bool 603I128ExaInit(ScreenPtr pScreen) 604{ 605 ExaDriverPtr pExa; 606 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 607 I128Ptr pI128 = I128PTR(pScrn); 608 609 if (!(pExa = exaDriverAlloc())) { 610 pI128->NoAccel = TRUE; 611 return FALSE; 612 } 613 pI128->ExaDriver = pExa; 614 615 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT; 616 pExa->memoryBase = pI128->MemoryPtr; 617 pExa->memorySize = pI128->MemorySize * 1024; 618 pExa->offScreenBase = (pScrn->virtualX * pScrn->virtualY) * 619 (pScrn->bitsPerPixel / 8) + 4096; 620 /* these two are probably right */ 621 pExa->pixmapOffsetAlign = 16; 622 pExa->pixmapPitchAlign = 16; 623 /* these two are guesses */ 624 pExa->maxX = 2048; 625 pExa->maxY = 2048; 626 627 pExa->WaitMarker = i128WaitMarker; 628 629 pExa->PrepareSolid = i128PrepareSolid; 630 pExa->Solid = i128Solid; 631 pExa->DoneSolid = i128Done; 632 633 pExa->PrepareCopy = i128PrepareCopy; 634 pExa->Copy = i128Copy; 635 pExa->DoneCopy = i128Done; 636 637 if (0 && (pI128->Chipset == PCI_CHIP_I128_T2R || 638 pI128->Chipset == PCI_CHIP_I128_T2R4)) 639 { 640#if 0 641 pExa->DownloadFromScreen = i128DownloadFromScreen; 642 pExa->UploadToScreen = i128UploadToScreen; 643#endif 644 pExa->CheckComposite = i128CheckComposite; 645 pExa->PrepareComposite = i128PrepareComposite; 646 pExa->Composite = i128Composite; 647 pExa->DoneComposite = i128Done; 648 } 649 650 /* 651 * XXX much of this is duplicated from the XAA code, but I expect the XAA 652 * support to disappear eventually. 653 */ 654 pI128->buf_ctrl = 0; /* force write */ 655 i128SetBufCtrl(pI128, pI128->bitsPerPixel); 656 657 /* all of this needs to be properly documented */ 658 { 659 pI128->mem.rbase_a[DE_PGE] = 0x00; 660 pI128->mem.rbase_a[DE_SORG] = pI128->displayOffset; 661 pI128->mem.rbase_a[DE_DORG] = pI128->displayOffset; 662 pI128->mem.rbase_a[DE_MSRC] = 0x00; 663 pI128->mem.rbase_a[DE_WKEY] = 0x00; 664 pI128->mem.rbase_a[DE_SPTCH] = pI128->mem.rbase_g[DB_PTCH]; 665 pI128->mem.rbase_a[DE_DPTCH] = pI128->mem.rbase_g[DB_PTCH]; 666 if (pI128->Chipset == PCI_CHIP_I128_T2R4) 667 pI128->mem.rbase_a[DE_ZPTCH] = pI128->mem.rbase_g[DB_PTCH]; 668 pI128->mem.rbase_a[RMSK] = 0x00000000; 669 pI128->mem.rbase_a[XY4_ZM] = ZOOM_NONE; 670 pI128->mem.rbase_a[LPAT] = 0xffffffff; /* for lines */ 671 pI128->mem.rbase_a[PCTRL] = 0x00000000; /* for lines */ 672 pI128->mem.rbase_a[CLPTL] = 0x00000000; 673 pI128->mem.rbase_a[CLPBR] = (4095 << 16) | 2047 ; 674 pI128->mem.rbase_a[ACNTRL] = 0x00000000; 675 pI128->mem.rbase_a[INTM] = 0x03; 676 } 677 678 /* need this as a float * for vertex setup */ 679 pI128->mem.rbase_af = (float *)pI128->mem.rbase_a; 680 681 if (pI128->Debug) { 682 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I128ExaInit done\n"); 683 I128DumpActiveRegisters(pScrn); 684 } 685 686 return(exaDriverInit(pScreen, pExa)); 687} 688