1/* 2 * hardware acceleration for Visualize FX 4 3 * 4 * Copyright (C) 2024 Michael Lorenz 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24/* $NetBSD: summit_accel.c,v 1.9 2025/02/25 13:21:24 macallan Exp $ */ 25 26#include <sys/types.h> 27#include <dev/ic/summitreg.h> 28 29 30#include "ngle.h" 31#include "mipict.h" 32 33//#define DEBUG 34 35void 36 exaPrepareAccess(DrawablePtr pDrawable, int index); 37 38void 39 exaFinishAccess(DrawablePtr pDrawable, int index); 40 41#ifdef DEBUG 42#define ENTER xf86Msg(X_ERROR, "%s\n", __func__) 43#define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__) 44#define DBGMSG xf86Msg 45#else 46#define ENTER 47#define DBGMSG if (0) xf86Msg 48#define LEAVE 49#endif 50 51#define SUMMIT_READ_MODE(m) \ 52 if ((m) != fPtr->read_mode) { \ 53 SummitWait(fPtr); \ 54 NGLEWrite4(fPtr, VISFX_VRAM_READ_MODE, (m)); \ 55 fPtr->read_mode = (m); \ 56 } 57 58#define SUMMIT_WRITE_MODE(m) \ 59 if ((m) != fPtr->write_mode) { \ 60 SummitWait(fPtr); \ 61 NGLEWrite4(fPtr, VISFX_VRAM_WRITE_MODE, (m)); \ 62 fPtr->write_mode = (m); \ 63 } 64 65static inline void 66SummitWait(NGLEPtr fPtr) 67{ 68 int reg, count = 0;; 69 70 ENTER; 71 do { 72 reg = NGLERead4(fPtr, VISFX_STATUS); 73 count++; 74 } while ((reg & 0x01000000) != 0); 75 if (reg != 0) { 76 xf86Msg(X_ERROR, "%s status %08x\n", __func__, reg); 77 xf86Msg(X_ERROR, "fault %08x\n", NGLERead4(fPtr, 0x641040)); 78 } 79 DBGMSG(X_ERROR, "%s: %d\n", __func__, count); 80} 81 82static void 83SummitWaitMarker(ScreenPtr pScreen, int Marker) 84{ 85 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 86 NGLEPtr fPtr = NGLEPTR(pScrn); 87 int reg, count = 0; 88 89 ENTER; 90 do { 91 reg = NGLERead4(fPtr, VISFX_STATUS); 92 count++; 93 } while ((reg & 0x01000000) != 0); 94 if (reg != 0) { 95 xf86Msg(X_ERROR, "%s status %08x\n", __func__, reg); 96 xf86Msg(X_ERROR, "fault %08x\n", NGLERead4(fPtr, 0x641040)); 97 } 98 DBGMSG(X_ERROR, "%s: %d\n", __func__, count); 99} 100 101static void 102SummitWaitFifo(NGLEPtr fPtr, int count) 103{ 104 int reg; 105 do { 106 reg = NGLERead4(fPtr, VISFX_FIFO); 107 } while (reg < count); 108#ifdef DEBUG 109 if (reg != 0x800) xf86Msg(X_ERROR, "%s %x\n", __func__, reg); 110#endif 111} 112 113static Bool 114SummitPrepareCopy 115( 116 PixmapPtr pSrcPixmap, 117 PixmapPtr pDstPixmap, 118 int xdir, 119 int ydir, 120 int alu, 121 Pixel planemask 122) 123{ 124 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 125 NGLEPtr fPtr = NGLEPTR(pScrn); 126 int dstoff = exaGetPixmapOffset(pDstPixmap); 127 int srcoff = exaGetPixmapOffset(pSrcPixmap); 128 uint32_t sm, dm; 129 int y; 130 131 ENTER; 132 133 sm = dm = OTC01 | BIN8F | BUFFL; 134 DBGMSG(X_ERROR, "%s %d %d\n", __func__, srcoff, dstoff); 135 136 y = (srcoff >> 13); /* pitch is 8192 bytes in 24 bit */ 137 if (y >= fPtr->fbi.fbi_height) { 138 sm = OTC01 | BIN8F | BUFBL; 139 y -= fPtr->fbi.fbi_height; 140 } 141 fPtr->offset = y; 142 SUMMIT_READ_MODE(sm); 143 144 y = (dstoff >> 13); /* pitch is 8192 bytes in 24 bit */ 145 if (y >= fPtr->fbi.fbi_height) { 146 dm = OTC01 | BIN8F | BUFBL; 147 y -= fPtr->fbi.fbi_height; 148 } 149 fPtr->offsetd = y; 150 SUMMIT_WRITE_MODE(dm); 151 152 SummitWaitFifo(fPtr, 8); 153 if (alu == GXcopy) { 154 NGLEWrite4(fPtr, VISFX_FOE, 0); 155 } else { 156 NGLEWrite4(fPtr, VISFX_FOE, FOE_BLEND_ROP); 157 NGLEWrite4(fPtr, VISFX_IBO, alu); 158 } 159 NGLEWrite4(fPtr, VISFX_PLANE_MASK, planemask); 160 LEAVE; 161 return TRUE; 162} 163 164static void 165SummitCopy 166( 167 PixmapPtr pDstPixmap, 168 int xs, 169 int ys, 170 int xd, 171 int yd, 172 int wi, 173 int he 174) 175{ 176 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 177 NGLEPtr fPtr = NGLEPTR(pScrn); 178 179 ENTER; 180 SummitWaitFifo(fPtr, 8); 181 NGLEWrite4(fPtr, VISFX_COPY_SRC, (xs << 16) | (ys + fPtr->offset)); 182 NGLEWrite4(fPtr, VISFX_COPY_WH, (wi << 16) | he); 183 NGLEWrite4(fPtr, VISFX_COPY_DST, (xd << 16) | (yd + fPtr->offsetd)); 184 185 LEAVE; 186} 187 188static void 189SummitDoneCopy(PixmapPtr pDstPixmap) 190{ 191 ENTER; 192 LEAVE; 193} 194 195static Bool 196SummitPrepareSolid( 197 PixmapPtr pPixmap, 198 int alu, 199 Pixel planemask, 200 Pixel fg) 201{ 202 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 203 NGLEPtr fPtr = NGLEPTR(pScrn); 204 int ofs = exaGetPixmapOffset(pPixmap); 205 int y; 206 uint32_t wm = OTC32 | BIN8F | BUFFL | 0x8c0, rm = OTC01 | BIN8F | BUFFL; 207 208 ENTER; 209 y = (ofs >> 13); /* pitch is 8192 bytes in 24 bit */ 210 if (y >= fPtr->fbi.fbi_height) { 211 wm = OTC32 | BIN8F | BUFBL | 0x8c0; 212 rm = OTC01 | BIN8F | BUFBL; 213 y -= fPtr->fbi.fbi_height; 214 } 215 SUMMIT_READ_MODE(rm); 216 SUMMIT_WRITE_MODE(wm); 217 fPtr->offset = y; 218 SummitWaitFifo(fPtr, 10); 219 if (alu == GXcopy) { 220 NGLEWrite4(fPtr, VISFX_FOE, 0); 221 } else { 222 NGLEWrite4(fPtr, VISFX_FOE, FOE_BLEND_ROP); 223 NGLEWrite4(fPtr, VISFX_IBO, alu); 224 } 225 NGLEWrite4(fPtr, VISFX_FG_COLOUR, fg); 226 NGLEWrite4(fPtr, VISFX_PLANE_MASK, planemask); 227 LEAVE; 228 return TRUE; 229} 230 231static void 232SummitSolid( 233 PixmapPtr pPixmap, 234 int x1, 235 int y1, 236 int x2, 237 int y2) 238{ 239 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 240 NGLEPtr fPtr = NGLEPTR(pScrn); 241 int wi = x2 - x1, he = y2 - y1; 242 243 ENTER; 244 245 y1 += fPtr->offset; 246 247 SummitWaitFifo(fPtr, 6); 248 NGLEWrite4(fPtr, VISFX_START, (x1 << 16) | y1); 249 NGLEWrite4(fPtr, VISFX_SIZE, (wi << 16) | he); 250 251 LEAVE; 252} 253 254static Bool 255SummitUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 256 char *src, int src_pitch) 257{ 258 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 259 NGLEPtr fPtr = NGLEPTR(pScrn); 260 int ofs = exaGetPixmapOffset(pDst); 261 int i; 262 uint32_t *line, mode = OTC01 | BIN8F | BUFFL; 263 uint8_t *dst; 264 265 ENTER; 266 y += (ofs >> 13); /* pitch is 8192 bytes in 24 bit */ 267 if (y >= fPtr->fbi.fbi_height) { 268 mode = OTC01 | BIN8F | BUFBL; 269 y -= fPtr->fbi.fbi_height; 270 } 271 272 dst = fPtr->fbmem; 273 dst += (y << 13) + (x << 2); 274 275 SUMMIT_WRITE_MODE(mode); 276 NGLEWrite4(fPtr, VISFX_PLANE_MASK, 0xffffffff); 277 NGLEWrite4(fPtr, VISFX_FOE, 0); 278 279 while (h--) { 280 /* 281 * it *should* be impossible to overrun the FIFO using BINC 282 * writes, but overruns are annoying if they do happen so be 283 * overly cautious and make sure there is at least some room 284 */ 285 SummitWaitFifo(fPtr, w + 1); 286 NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DEST, (y << 16) | x); 287 line = (uint32_t *)src; 288 289 for (i = 0; i < w; i++) 290 NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DATA_INCRX, line[i]); 291 //memcpy(dst, src, w << 2); 292 src += src_pitch; 293 dst += 8192; 294 y++; 295 } 296 297 LEAVE; 298 299 return TRUE; 300} 301 302static Bool 303SummitDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 304 char *dst, int dst_pitch) 305{ 306 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 307 NGLEPtr fPtr = NGLEPTR(pScrn); 308 uint8_t *src; 309 int ofs = exaGetPixmapOffset(pSrc); 310 uint32_t mode = OTC01 | BIN8F | BUFFL; 311 312 ENTER; 313 314 y += (ofs >> 13); 315 if (y >= fPtr->fbi.fbi_height) { 316 mode = OTC01 | BIN8F | BUFBL; 317 y -= fPtr->fbi.fbi_height; 318 } 319 SUMMIT_READ_MODE(mode); 320 SummitWait(fPtr); 321 NGLEWrite4(fPtr, VISFX_RPH, VISFX_RPH_LTR); 322 SummitWait(fPtr); 323 324 src = fPtr->fbmem; 325 src += (y << 13) + (x << 2); 326 327 while (h--) { 328 memcpy(dst, src, w << 2); 329 src += 8192; 330 dst += dst_pitch; 331 } 332 333 LEAVE; 334 335 return TRUE; 336} 337 338Bool 339SummitPrepareAccess(PixmapPtr pPixmap, int index) 340{ 341 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 342 NGLEPtr fPtr = NGLEPTR(pScrn); 343 int ofs = exaGetPixmapOffset(pPixmap); 344 int y; 345 346 ENTER; 347 //xf86Msg(X_ERROR, "%s %d\n", __func__, ofs); 348 if (ofs == 0) { 349 /* accessing the visible framebuffer */ 350 SUMMIT_READ_MODE(OTC01 | BIN8F | BUFFL); 351 SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFFL); 352 } else { 353 SUMMIT_READ_MODE(OTC01 | BIN8F | BUFBL); 354 SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFBL); 355 y = ofs >> 13; 356 y -= fPtr->fbi.fbi_height; 357 pPixmap->devPrivate.ptr = fPtr->fbmem + (y << 13); 358 } 359 NGLEWrite4(fPtr, VISFX_FOE, 0); 360 NGLEWrite4(fPtr, VISFX_RPH, VISFX_RPH_LTR); 361 //NGLEWrite4(fPtr, VISFX_CONTROL, 0x200); 362 SummitWait(fPtr); 363 LEAVE; 364 return TRUE; 365} 366 367void 368SummitFinishAccess(PixmapPtr pPixmap, int index) 369{ 370 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 371 NGLEPtr fPtr = NGLEPTR(pScrn); 372 373 ENTER; 374 //NGLEWrite4(fPtr, VISFX_CONTROL, 0); 375 //SummitWait(fPtr); 376 LEAVE; 377} 378 379PixmapPtr 380SummitGetDrawablePixmap(DrawablePtr pDrawable) 381{ 382 if (pDrawable->type == DRAWABLE_WINDOW) 383 return pDrawable->pScreen->GetWindowPixmap((WindowPtr) pDrawable); 384 else 385 return (PixmapPtr) pDrawable; 386} 387 388static void 389SummitDrawGlyph8(NGLEPtr fPtr, int32_t fg, PixmapPtr mask, int p, 390 int xm, int ym, int xd, int yd, int w, int h) 391{ 392 uint8_t *gdata = mask->devPrivate.ptr; 393 uint32_t msk; 394 int i, j, needs_coords; 395 396 gdata += xm; 397 gdata += (p * ym); 398 for (i = 0; i < h; i++) { 399 SummitWaitFifo(fPtr, w * 2); 400 needs_coords = 1; 401 for (j = 0; j < w; j++) { 402 msk = gdata[j]; 403 if (msk == 0) { 404 needs_coords = 1; 405 continue; 406 } 407 if (needs_coords) { 408 NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DEST, 409 ((yd + i) << 16) | (xd + j)); 410 needs_coords = 0; 411 } 412 msk = (msk << 24) | fg; 413 NGLEWrite4(fPtr, 414 VISFX_VRAM_WRITE_DATA_INCRX, msk); 415 } 416 gdata += p; 417 } 418} 419 420static void 421SummitDrawGlyph32(NGLEPtr fPtr, uint32_t fg, PixmapPtr mask, int p, 422 int xm, int ym, int xd, int yd, int w, int h) 423{ 424 uint32_t *gdata = mask->devPrivate.ptr; 425 uint32_t msk; 426 int i, j, needs_coords; 427 428 gdata += xm; 429 gdata += (p * ym); 430 431 for (i = 0; i < h; i++) { 432 SummitWaitFifo(fPtr, w * 2); 433 needs_coords = 1; 434 for (j = 0; j < w; j++) { 435 msk = gdata[j] & 0xff000000; 436 if (msk == 0) { 437 needs_coords = 1; 438 continue; 439 } 440 if (needs_coords) { 441 NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DEST, 442 ((yd + i) << 16) | (xd + j)); 443 needs_coords = 0; 444 } 445 msk |= fg; 446 NGLEWrite4(fPtr, 447 VISFX_VRAM_WRITE_DATA_INCRX, msk); 448 } 449 gdata += p >> 2; 450 } 451} 452 453static void 454SummitGlyphs (CARD8 op, 455 PicturePtr pSrc, 456 PicturePtr pDst, 457 PictFormatPtr maskFormat, 458 INT16 xSrc, 459 INT16 ySrc, 460 int nlist, 461 GlyphListPtr list, 462 GlyphPtr *glyphs) 463{ 464 ScreenPtr pScreen = pDst->pDrawable->pScreen; 465 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 466 NGLEPtr fPtr = NGLEPTR(pScrn); 467 PicturePtr pPicture; 468 PixmapPtr mask, dst; 469 GlyphPtr glyph; 470 int xDst = list->xOff, yDst = list->yOff; 471 int x = 0, y = 0, i, n, ofs, p, j, wi, he, xs, ys; 472 int dw, dh; 473 uint32_t fg = 0xffffffff, msk; 474 475 if (op != PictOpOver) goto fallback; 476 477 if (!exaDrawableIsOffscreen(pDst->pDrawable)) goto fallback; 478 479 dst = SummitGetDrawablePixmap(pDst->pDrawable); 480 ofs = exaGetPixmapOffset(dst); 481 ofs = ofs >> 13; 482 dw = pDst->pDrawable->width; 483 dh = pDst->pDrawable->height; 484 485 if (pDst->pDrawable->type == DRAWABLE_WINDOW) { 486 x += pDst->pDrawable->x; 487 y += pDst->pDrawable->y; 488 } 489 490 if (pSrc->pSourcePict != NULL) { 491 if (pSrc->pSourcePict->type == SourcePictTypeSolidFill) { 492 fg = pSrc->pSourcePict->solidFill.color; 493 } 494 } 495 fg &= 0x00ffffff; 496 497 if (ofs == 0) { 498 /* accessing the visible framebuffer */ 499 SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFFL); 500 } else { 501 SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFBL); 502 } 503 504 SummitWaitFifo(fPtr, 4); 505 NGLEWrite4(fPtr, VISFX_FOE, FOE_BLEND_ROP); 506 NGLEWrite4(fPtr, VISFX_IBO, 507 IBO_ADD | SRC(IBO_SRC) | DST(IBO_ONE_MINUS_SRC)); 508 509 while (nlist--) { 510 x += list->xOff; 511 y += list->yOff; 512 n = list->len; 513 while (n--) { 514 glyph = *glyphs++; 515 pPicture = GlyphPicture (glyph)[pScreen->myNum]; 516 if (pPicture) { 517 int xd = x - glyph->info.x; 518 int yd = y - glyph->info.y; 519 RegionRec region; 520 BoxPtr pbox; 521 int nbox; 522 523 if (ofs == 0) { 524 /* 525 * we're drawing to the visible screen, 526 * so we must take care not to scribble 527 * over other windows 528 */ 529 if (!miComputeCompositeRegion(®ion, 530 pSrc, pPicture, pDst, 531 0, 0, 0, 0, xd, yd, 532 glyph->info.width, 533 glyph->info.height)) 534 goto skip; 535 536 fbGetDrawablePixmap(pPicture->pDrawable, 537 mask, wi, he); 538 exaPrepareAccess(pPicture->pDrawable, 539 EXA_PREPARE_SRC); 540 p = exaGetPixmapPitch(mask); 541 542 nbox = RegionNumRects(®ion); 543 pbox = RegionRects(®ion); 544 while (nbox--) { 545 if (pPicture->format == PICT_a8) { 546 SummitDrawGlyph8(fPtr, 547 fg, mask, p, 548 pbox->x1 - xd, 549 pbox->y1 - yd, 550 pbox->x1, pbox->y1, 551 pbox->x2 - pbox->x1, 552 pbox->y2 - pbox->y1); 553 } else { 554 SummitDrawGlyph32(fPtr, 555 fg, mask, p, 556 pbox->x1 - xd, 557 pbox->y1 - yd, 558 pbox->x1, pbox->y1, 559 pbox->x2 - pbox->x1, 560 pbox->y2 - pbox->y1); 561 } 562 pbox++; 563 } 564 RegionUninit(®ion); 565 exaFinishAccess(pPicture->pDrawable, 566 EXA_PREPARE_SRC); 567 } else { 568 /* 569 * drawing into off-screen memory, we 570 * only need to clip to the destination 571 * pixmap's boundaries 572 */ 573 574 fbGetDrawablePixmap(pPicture->pDrawable, 575 mask, wi, he); 576 577 xs = 0; 578 ys = 0; 579 wi = glyph->info.width; 580 he = glyph->info.height; 581 582 if (xd < 0) { 583 xs -= xd; 584 wi += xd; 585 xd = 0; 586 } 587 588 if (yd < 0) { 589 ys -= yd; 590 he += yd; 591 yd = 0; 592 } 593 594 if ((xd + wi) > dw) { 595 wi -= (xd + wi - dw); 596 } 597 598 if ((yd + he) > dh) { 599 he -= (yd + he - dh); 600 } 601 602 if ((he <= 0) || (wi <= 0)) 603 goto skip; 604 605 yd += (ofs - fPtr->fbi.fbi_height); 606 607 exaPrepareAccess(pPicture->pDrawable, 608 EXA_PREPARE_SRC); 609 p = exaGetPixmapPitch(mask); 610 611 if (pPicture->format == PICT_a8) { 612 SummitDrawGlyph8(fPtr, 613 fg, mask, p, 614 xs, ys, 615 xd, yd, 616 wi, he); 617 } else { 618 SummitDrawGlyph32(fPtr, 619 fg, mask, p, 620 xs, ys, 621 xd, yd, 622 wi, he); 623 } 624 exaFinishAccess(pPicture->pDrawable, 625 EXA_PREPARE_SRC); 626 } 627 } 628skip: 629 x += glyph->info.xOff; 630 y += glyph->info.yOff; 631 } 632 list++; 633 } 634 return; 635fallback: 636 fPtr->glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); 637} 638 639Bool 640SummitInitAccel(ScreenPtr pScreen) 641{ 642 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 643 PictureScreenPtr ps = GetPictureScreen(pScreen); 644 NGLEPtr fPtr = NGLEPTR(pScrn); 645 ExaDriverPtr pExa; 646 int bpp = pScrn->bitsPerPixel >> 3, ret; 647 648 pExa = exaDriverAlloc(); 649 if (!pExa) 650 return FALSE; 651 652 fPtr->pExa = pExa; 653 654 pExa->exa_major = EXA_VERSION_MAJOR; 655 pExa->exa_minor = EXA_VERSION_MINOR; 656 657 pExa->memoryBase = fPtr->fbmem; 658 pExa->memorySize = fPtr->fbi.fbi_stride * (fPtr->fbi.fbi_height * 2); 659 pExa->offScreenBase = fPtr->fbi.fbi_stride * fPtr->fbi.fbi_height; 660 pExa->pixmapOffsetAlign = fPtr->fbi.fbi_stride; 661 pExa->pixmapPitchAlign = fPtr->fbi.fbi_stride; 662 663 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_MIXED_PIXMAPS; 664 665 pExa->maxX = 2048; 666 pExa->maxY = 2048; 667 668 pExa->WaitMarker = SummitWaitMarker; 669 pExa->Solid = SummitSolid; 670 pExa->DoneSolid = SummitDoneCopy; 671 pExa->Copy = SummitCopy; 672 pExa->DoneCopy = SummitDoneCopy; 673 pExa->PrepareCopy = SummitPrepareCopy; 674 pExa->PrepareSolid = SummitPrepareSolid; 675 pExa->UploadToScreen = SummitUploadToScreen; 676 pExa->DownloadFromScreen = SummitDownloadFromScreen; 677 pExa->PrepareAccess = SummitPrepareAccess; 678 pExa->FinishAccess = SummitFinishAccess; 679 680 fPtr->read_mode = -1; 681 fPtr->write_mode = -1; 682 SUMMIT_READ_MODE(OTC01 | BIN8F | BUFFL); 683 SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFFL); 684 NGLEWrite4(fPtr, VISFX_FOE, FOE_BLEND_ROP); 685 NGLEWrite4(fPtr, VISFX_IBO, GXcopy); 686 NGLEWrite4(fPtr, VISFX_CONTROL, 0); 687 688 ret = exaDriverInit(pScreen, pExa); 689 690 fPtr->glyphs = ps->Glyphs; 691 ps->Glyphs = SummitGlyphs; 692 return ret; 693} 694