tga_accel.c revision 7706df26
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c,v 1.15 2001/11/21 22:32:59 alanh Exp $ */ 2 3/* 4 * Copyright 1996,1997 by Alan Hourihane, Wigan, England. 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and its 7 * documentation for any purpose is hereby granted without fee, provided that 8 * the above copyright notice appear in all copies and that both that 9 * copyright notice and this permission notice appear in supporting 10 * documentation, and that the name of Alan Hourihane not be used in 11 * advertising or publicity pertaining to distribution of the software without 12 * specific, written prior permission. Alan Hourihane makes no representations 13 * about the suitability of this software for any purpose. It is provided 14 * "as is" without express or implied warranty. 15 * 16 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 * PERFORMANCE OF THIS SOFTWARE. 23 * 24 * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 25 * 26 * DEC TGA accelerated options. 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include "fb.h" 34#include "micmap.h" 35#include "xf86.h" 36#include "xf86_OSproc.h" 37#include "xf86PciInfo.h" 38#include "xf86Pci.h" 39#include "xf86cmap.h" 40#include "mipointer.h" 41 42#include "mibstore.h" 43#include "miline.h" 44 45#include "tga_regs.h" 46#include "BT.h" 47#include "tga.h" 48 49/* defines */ 50 51#define BLIT_FORWARDS 0 52#define BLIT_BACKWARDS 1 53#define USE_BLOCK_FILL 2 54#define USE_OPAQUE_FILL 3 55#define MIX_SRC 0x03 56 57#define CE_BUFSIZE 256 58 59#define FB_OFFSET(x, y) (((long)(y) * pScrn->displayWidth * (pTga->Bpp)) + (long)(x) * pTga->Bpp) 60 61/* prototypes */ 62 63static void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 64 int y2, int w); 65static void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 66 int y2, int w); 67extern void TGASync(ScrnInfoPtr pScrn); 68static void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 69 unsigned int planemask); 70static void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); 71static void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 72 int rop, unsigned int planemask, 73 int transparency_color); 74static void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 75 int x2, int y2, int w, int h); 76static void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 77 int fg, int bg, int rop, 78 unsigned int planemask); 79static void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, 80 int paty, int x, int y, int w, 81 int h); 82static void TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 83 int fg, int bg, 84 int rop, 85 unsigned int planemask); 86 87static void 88TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 89 int x, int y, int w, 90 int h, int skipleft); 91static void 92TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 93 94 95/* 96 * The following function sets up the supported acceleration. Call it 97 * from the FbInit() function in the SVGA driver. 98 */ 99Bool 100DEC21030AccelInit(ScreenPtr pScreen) 101{ 102 XAAInfoRecPtr TGA_AccelInfoRec; 103 BoxRec AvailFBArea; 104 ScrnInfoPtr pScrn; 105 TGAPtr pTga; 106 107 pScrn = xf86Screens[pScreen->myNum]; 108 pTga = TGAPTR(pScrn); 109 110 /* ErrorF("DEC21030AccelInit called!"); */ 111 112 /* first, create the XAAInfoRec */ 113 TGA_AccelInfoRec = XAACreateInfoRec(); 114 115 /* ErrorF("XAACreateInfoRec called"); */ 116 117 if(pScrn->depth == 8) { 118 pTga->depthflag = BPP8PACKED; 119 pTga->Bpp = 1; 120 } else { 121 pTga->depthflag = BPP24; 122 pTga->Bpp = 4; 123 } 124 125 TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | 126 OFFSCREEN_PIXMAPS; 127 128 TGA_AccelInfoRec->Sync = TGASync; 129 130 /* solid fill */ 131 132 TGA_AccelInfoRec->SolidFillFlags = 0; 133 TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill; 134 TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect; 135 136 /* screen to screen copy */ 137 TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 138 TGA_AccelInfoRec->SetupForScreenToScreenCopy = 139 TGASetupForScreenToScreenCopy; 140 TGA_AccelInfoRec->SubsequentScreenToScreenCopy = 141 TGASubsequentScreenToScreenCopy; 142 143 /* mono 8x8 pattern fill */ 144 145 TGA_AccelInfoRec->Mono8x8PatternFillFlags = 146 HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST; 147 TGA_AccelInfoRec->SetupForMono8x8PatternFill = 148 TGASetupForMono8x8PatternFill; 149 TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect = 150 TGASubsequentMono8x8PatternFillRect; 151 152 /* color expand */ 153 /* does not work for 32bpp (yet) */ 154 TGA_AccelInfoRec->ScanlineCPUToScreenColorExpandFillFlags = 155 BIT_ORDER_IN_BYTE_LSBFIRST; 156 157 TGA_AccelInfoRec->NumScanlineColorExpandBuffers = 1; 158 pTga->buffers[0] = (CARD32 *)xnfalloc(CE_BUFSIZE); 159 TGA_AccelInfoRec->ScanlineColorExpandBuffers = 160 (unsigned char **)pTga->buffers; 161 TGA_AccelInfoRec->SetupForScanlineCPUToScreenColorExpandFill = 162 TGASetupForScanlineCPUToScreenColorExpandFill; 163 TGA_AccelInfoRec->SubsequentScanlineCPUToScreenColorExpandFill = 164 TGASubsequentScanlineCPUToScreenColorExpandFill; 165 TGA_AccelInfoRec->SubsequentColorExpandScanline = 166 TGASubsequentColorExpandScanline; 167 168 /* lines */ 169 170 TGA_AccelInfoRec->PolylinesThinSolid = TGAPolyLines; 171 if(pTga->NoXaaPolySegment == FALSE) 172 TGA_AccelInfoRec->PolySegmentThinSolid = TGAPolySegment; 173 TGA_AccelInfoRec->PolylinesThinSolidFlags = 0x0; 174 TGA_AccelInfoRec->PolySegmentThinSolidFlags = 0x0; 175 176 TGA_AccelInfoRec->PolylinesThinDashed = TGAPolyLinesDashed; 177 if(pTga->NoXaaPolySegment == FALSE) 178 TGA_AccelInfoRec->PolySegmentThinDashed = TGAPolySegmentDashed; 179 TGA_AccelInfoRec->PolylinesThinDashedFlags = 0x0; 180 TGA_AccelInfoRec->PolySegmentThinDashedFlags = 0x0; 181 TGA_AccelInfoRec->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED; 182 TGA_AccelInfoRec->DashPatternMaxLength = 16; 183 184 /* initialize the pixmap cache */ 185 186 AvailFBArea.x1 = 0; 187 AvailFBArea.y1 = 0; /* these gotta be 0 */ 188 AvailFBArea.x2 = pScrn->displayWidth; 189 AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth * 190 pTga->Bpp); 191 xf86InitFBManager(pScreen, &AvailFBArea); 192 193 TGA_AccelInfoRec->PixmapCacheFlags = 0; 194 195 /* initialize XAA */ 196 return(XAAInit(pScreen, TGA_AccelInfoRec)); 197} 198 199static void 200TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 201 int fg, int bg, int rop, 202 unsigned int planemask) 203{ 204#ifdef PROFILE 205 unsigned int start, stop; 206#endif 207 TGAPtr pTga = NULL; 208 unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; 209 TGA_DECL(); 210 211 pTga = TGAPTR(pScrn); 212 TGA_GET_IOBASE(); 213 TGA_GET_OFFSET(); 214 215/* ErrorF("TGASetupForScanlineCPUToScreenColorExpandFill called\n"); */ 216 if(pTga->depthflag == BPP8PACKED) { 217 fgcolor = (fg | (fg << 8) | (fg << 16) | (fg << 24)); 218 bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); 219 pmask = planemask | (planemask << 8) | (planemask << 16) 220 | (planemask << 24); 221 } 222 else { 223 bgcolor = bg; 224 fgcolor = fg; 225 pmask = planemask; 226 } 227 pTga->current_rop = rop | pTga->depthflag; 228 229 if(bg == -1) { 230 pTga->transparent_pattern_p = 1; 231 if(rop == MIX_SRC) { 232 pTga->block_or_opaque_p = USE_BLOCK_FILL; 233 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 234 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 235 if(pTga->depthflag == BPP24) { 236 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 237 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 238 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 239 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 240 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 241 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 242 } 243 } 244 else { 245 pTga->block_or_opaque_p = USE_OPAQUE_FILL; 246 TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 247 } 248 } 249 else { 250 pTga->transparent_pattern_p = 0; 251 TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); 252 TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 253 } 254 TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); /* we know when to 255 reset this */ 256 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 257 258 TGA_SAVE_OFFSET(); 259 260 return; 261} 262 263static void 264TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 265 int x, int y, int w, 266 int h, int skipleft) 267{ 268#ifdef PROFILE 269 unsigned int start, stop; 270#endif 271 TGAPtr pTga; 272 TGA_DECL(); 273 274 pTga = TGAPTR(pScrn); 275 TGA_GET_IOBASE(); 276 TGA_GET_OFFSET(); 277 278/* ErrorF("TGASubsequentScanlineCPUToScreenColorExpandFill called\n"); */ 279/* ErrorF("w = %d, h = %d\n", w, h); */ 280 281 pTga->ce_height = h; 282 pTga->ce_width = w; 283 pTga->ce_x = x; 284 pTga->ce_y = y; 285 pTga->ce_skipleft = skipleft; 286/* ErrorF("skipleft is %d\n", skipleft); */ 287 288 if(pTga->transparent_pattern_p) { 289 if(pTga->block_or_opaque_p == USE_BLOCK_FILL) 290 TGA_FAST_WRITE_REG(BLOCKSTIPPLE | X11 | pTga->depthflag, 291 TGA_MODE_REG); 292 else 293 TGA_FAST_WRITE_REG(TRANSPARENTSTIPPLE | X11 | pTga->depthflag, 294 TGA_MODE_REG); 295/* ErrorF("transparent stipple with x = %d, y = %d, w = %d, h = %d\n", */ 296/* x, y, w, h); */ 297 } 298 else 299 TGA_FAST_WRITE_REG(OPAQUESTIPPLE | X11 | pTga->depthflag, 300 TGA_MODE_REG); 301 302 TGA_SAVE_OFFSET(); 303 return; 304} 305 306static void 307TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 308{ 309#ifdef PROFILE 310 unsigned int start, stop; 311#endif 312 TGAPtr pTga; 313 unsigned char *p = NULL; 314 int width = 0; 315 unsigned int addr; 316 unsigned int pixelmask = 0; 317 unsigned int stipple; 318 unsigned int align_mask; 319 int align = 0; 320 int skipleft; 321 322 CARD32 c = 0, d = 0; 323 CARD32 *e = NULL; 324 int i = 0, num_dwords = 0; 325 TGA_DECL(); 326 327 pTga = TGAPTR(pScrn); 328 TGA_GET_IOBASE(); 329 TGA_GET_OFFSET(); 330 331 align_mask = (pTga->depthflag == BPP24) ? 0x0f : 0x03; 332 333#if 0 334 ErrorF("TGASubsequentColorExpandScanline called\n"); 335 if(pTga->transparent_pattern_p) 336 ErrorF("transparent color expand\n"); 337#endif 338 339 p = (unsigned char *)pTga->buffers[0]; 340 addr = FB_OFFSET(pTga->ce_x, pTga->ce_y); 341 width = pTga->ce_width; 342 skipleft = pTga->ce_skipleft; 343 344 while(width > 0) { 345 if(!pTga->transparent_pattern_p) 346 pixelmask = 0xFFFFFFFF; 347 348 align = (addr & align_mask) / pTga->Bpp; /* no. pixels out of align */ 349 if (align) { 350 if (!pTga->transparent_pattern_p) 351 pixelmask <<= align; 352/* ErrorF("alignment is %d\n", align); */ 353 addr -= align * pTga->Bpp; 354 width += align; 355 356 e = (CARD32 *)p; 357 num_dwords = (width / 32) + 1; 358 if(num_dwords > (CE_BUFSIZE / 4)) { /* shouldn't happen */ 359 ErrorF("TGASubsequentColorExpandScanline passed scanline %d bytes long, truncating\n", num_dwords * 4); 360 num_dwords = CE_BUFSIZE / 4; 361 } 362 for(i = 0; i < num_dwords; i++) { 363 c = e[i]; 364 if(i == 0) 365 e[i] = c << align; 366 else 367 e[i] = (d >> (32 - align)) | (c << align); 368 d = c; 369 } 370 } 371 372 if (!pTga->transparent_pattern_p) { 373 if (skipleft) { 374 pixelmask <<= skipleft; 375 skipleft = 0; 376 } 377 if (width < 32) { 378 pixelmask &= (0xFFFFFFFF >> (32 - width)); 379 } 380 TGA_FAST_WRITE_REG(pixelmask, TGA_PIXELMASK_REG); 381 } 382 else { 383 unsigned int *i = NULL; 384 385/* ErrorF("transparent scanline with x = %d, y = %d, w = %d, h = %d\n", pTga->ce_x, pTga->ce_y, pTga->ce_width, pTga->ce_height); */ 386 if (skipleft) { 387 i = (unsigned int *)p; 388 *i &= (0xFFFFFFFF << skipleft); 389 skipleft = 0; 390 } 391 if (width < 32) { 392 i = (unsigned int *)p; 393 *i &= (0xFFFFFFFF >> (32 - width)); 394 } 395 } 396 397 stipple = *((unsigned int *)p); 398 switch (pTga->Chipset) { 399 case PCI_CHIP_TGA2: 400 *(unsigned int *)(pTga->FbBase + addr) = stipple; WMB; 401 break; 402 case PCI_CHIP_DEC21030: 403 TGA_FAST_WRITE_REG(addr, TGA_ADDRESS_REG); 404 TGA_FAST_WRITE_REG(stipple, TGA_CONTINUE_REG); 405 } 406 addr += 32 * pTga->Bpp; 407 p += 4; 408 width -= 32; 409 } 410 pTga->ce_height--; 411 if(pTga->ce_height == 0) { 412 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, 413 TGA_MODE_REG); 414 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 415 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 416 } 417 else 418 pTga->ce_y += 1; 419 420 TGA_SAVE_OFFSET(); 421 return; 422} 423 424/* Block Fill mode is faster, but only works for certain rops. So we will 425 have to implement Opaque Fill anyway, so we will do that first, then 426 do Block Fill for the special cases 427*/ 428void 429TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 430 unsigned int planemask) 431{ 432#ifdef PROFILE 433 unsigned int start, stop; 434#endif 435 TGAPtr pTga; 436 unsigned int fgcolor = 0, pmask = 0; 437 TGA_DECL(); 438 439 pTga = TGAPTR(pScrn); 440 TGA_GET_IOBASE(); 441 TGA_GET_OFFSET(); 442 /* ErrorF("TGASetupForSolidFill called"); */ 443 444 if(pTga->depthflag == BPP8PACKED) { 445 fgcolor = color | (color << 8) | (color << 16) | (color << 24); 446 pmask = planemask | (planemask << 8) | (planemask << 16) | 447 (planemask << 24); 448 } 449 else { 450 fgcolor = color; 451 pmask = planemask; 452 } 453 454 455 if(rop == MIX_SRC) { /* we can just do a block copy */ 456 pTga->block_or_opaque_p = USE_BLOCK_FILL; 457 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 458 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 459 if(pTga->depthflag == BPP24) { 460 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 461 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 462 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 463 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 464 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 465 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 466 } 467 } 468 else { 469 pTga->block_or_opaque_p = USE_OPAQUE_FILL; 470 pTga->current_rop = rop | pTga->depthflag; 471 TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 472/* ErrorF("opaque fill called\n"); */ 473 } 474 475 pTga->current_planemask = pmask; 476 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG); 477 TGA_SAVE_OFFSET(); 478 return; 479} 480 481void 482TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 483{ 484 unsigned int mode_reg = 0; 485 int i = 0; 486 unsigned int pixel_count = 0; /* the actual # of pixels to be written */ 487 unsigned int write_data = 0; /* the actual data written */ 488 int a1 = 0; 489#ifdef PROFILE 490 unsigned int stop, start; 491#endif 492 TGAPtr pTga; 493 TGA_DECL(); 494 495 pTga = TGAPTR(pScrn); 496 TGA_GET_IOBASE(); 497 TGA_GET_OFFSET(); 498 499 /* ErrorF("TGASubsequentFillRectSolid called\n"); */ 500 501 if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) { 502 mode_reg = OPAQUEFILL | X11 | pTga->depthflag; 503 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 504 /* we have to set this to GXCOPY every time before we exit */ 505 } 506 else 507 mode_reg = BLOCKFILL | X11 | pTga->depthflag; 508 509 TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); 510 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 511 512 if(w > 2048) { 513 ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n", w); 514 w = 2048; 515 } 516 pixel_count = w - 1; 517 518 for(i = 0; i < h; i++) { 519 a1 = FB_OFFSET(x, y + i); 520 if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 521 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 522 write_data = pixel_count; 523 TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG); 524 TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG); 525 } 526 527 mode_reg = SIMPLE | X11 | pTga->depthflag; 528 TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); 529 if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 530 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, 531 TGA_RASTEROP_REG); /* GXCOPY */ 532 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 533 534 TGA_SAVE_OFFSET(); 535 return; 536} 537 538/* we only need to calculate the direction of a move once per move, 539 so we do it in the setup function and leave it */ 540 541void 542TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 543 int rop, unsigned int planemask, 544 int transparency_color) 545 /* xdir 1 = left-to-right, -1 = right to left 546 ydir 1 = top-to-bottom, -1 = bottom to top 547 */ 548{ 549#ifdef PROFILE 550 unsigned int start, stop; 551#endif 552 TGAPtr pTga; 553 unsigned int pmask = 0; 554 TGA_DECL(); 555 556 pTga = TGAPTR(pScrn); 557 TGA_GET_IOBASE(); 558 TGA_GET_OFFSET(); 559 560 /* see section 6.2.9 */ 561 562 if (pTga->depthflag == BPP8PACKED) { 563 pmask = planemask | (planemask << 8) | (planemask << 16) | 564 (planemask << 24); 565 } 566 else 567 pmask = planemask; 568 569 pTga->current_planemask = pmask; 570 TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); 571 572 pTga->current_rop = rop | pTga->depthflag; 573 574 /* do we copy a rectangle from top to bottom or bottom to top? */ 575 if (ydir == -1) { 576 pTga->blitdir = BLIT_FORWARDS; 577 } 578 else { 579 pTga->blitdir = BLIT_BACKWARDS; 580 } 581 TGA_SAVE_OFFSET(); 582 return; 583} 584 585/* 586 * This is the implementation of the SubsequentForScreenToScreenCopy 587 * that sends commands to the coprocessor to perform a screen-to-screen 588 * copy of the specified areas, with the parameters from the SetUp call. 589 */ 590void 591TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 592 int y2, int w, int h) 593{ 594 /* x1, y1 = source coords 595 x2, y2 = destination coords 596 w = width 597 h = height 598 */ 599 600 int i = 0; 601 void (*copy_func)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w); 602#ifdef PROFILE 603 unsigned int stop, start; 604#endif 605 TGAPtr pTga; 606 TGA_DECL(); 607 608 pTga = TGAPTR(pScrn); 609 TGA_GET_IOBASE(); 610 TGA_GET_OFFSET(); 611#if 0 612 ErrorF("TGASubsequentScreenToScreenCopy(,%d,%d,%d,%d,%d,%d):" 613 " COPY %s BLIT %s\n", 614 x1, y1, x2, y2, w, h, (x2 > x1 && (x1 + w) > x2)?"BWD":"FWD", 615 (pTga->blitdir == BLIT_FORWARDS)?"FWD":"BWD"); 616#endif 617 TGASync(pScrn); /* ?? */ 618 619 TGA_FAST_WRITE_REG(COPY | X11 | pTga->depthflag, TGA_MODE_REG); 620 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 621 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 622 623 if(x2 > x1 && (x1 + w) > x2) 624 copy_func = TGACopyLineBackwards; 625 else 626 copy_func = TGACopyLineForwards; 627 628 TGA_SAVE_OFFSET(); 629 if(pTga->blitdir == BLIT_FORWARDS) { 630 for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */ 631 (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); 632 } 633 } 634 else { 635 for(i = 0; i < h; i++) { 636 (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); 637 } 638 } 639 640 TGASync(pScrn); /* ?? */ 641 642 TGA_GET_OFFSET(); 643 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 644 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 645 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 646 TGA_SAVE_OFFSET(); 647 648 return; 649} 650 651 652void 653TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w) 654{ 655 /* copy a line of width w from x1,y1 to x2,y2 using copy mode */ 656 int read; 657 unsigned long source_address, destination_address; 658 unsigned int mask_source, mask_destination; 659 int cando; 660 unsigned int cando_mask; 661 int source_align, destination_align; 662 int pixel_shift; 663#ifdef PROFILE 664 unsigned int start, stop; 665#endif 666 TGAPtr pTga; 667 TGA_DECL(); 668 669 pTga = TGAPTR(pScrn); 670 TGA_GET_IOBASE(); 671 TGA_GET_OFFSET(); 672 673 cando = 32; 674 cando_mask = 0xFFFFFFFFU; 675 if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { 676 cando = 16; 677 cando_mask = 0x0000FFFFU; 678 } 679 680 source_address = FB_OFFSET(x1, y1); 681 destination_address = FB_OFFSET(x2, y2); 682#if 0 683 ErrorF("CPY-FWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx\n", 684 x1, y1, x2, y2, w, source_address, destination_address); 685#endif 686 read = 0; 687 while (read < w) { 688 689 mask_source = cando_mask; 690 if ((w - read) >= cando) 691 mask_destination = cando_mask; 692 else 693 mask_destination = cando_mask >> (cando - (w - read)); 694 695 source_align = source_address & 0x07; 696 source_address -= source_align; 697 mask_source <<= source_align / pTga->Bpp; 698 /* mask_source &= cando_mask; */ 699 700 destination_align = destination_address & 0x07; 701 destination_address -= destination_align; 702 mask_destination <<= destination_align / pTga->Bpp; 703 /* mask_destination &= cando_mask; */ 704 705 if (destination_align >= source_align) 706 pixel_shift = destination_align - source_align; 707 else { 708 pixel_shift = 8 - (source_align - destination_align); 709 /* we need to prime the residue register in this case */ 710 destination_address -= 8; 711 mask_destination <<= 8 / pTga->Bpp; 712 mask_destination &= cando_mask;/* ?? */ 713 } 714 715 TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 716 switch (pTga->Chipset) { 717 case PCI_CHIP_TGA2: 718 *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; 719 *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; 720 break; 721 case PCI_CHIP_DEC21030: 722 /* use GADR and GCTR */ 723 TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); 724 TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); 725 TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); 726 TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); 727 break; 728 } 729 730 source_address += (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 731 destination_address += cando * pTga->Bpp; 732 733 read += cando; 734 read -= destination_align / pTga->Bpp; /* "read" is perhaps better 735 called "written"... */ 736 if (destination_align < source_align) { 737 read -= 8 / pTga->Bpp; 738 } 739 } 740 741 TGA_SAVE_OFFSET(); 742 return; 743} 744 745 746void 747TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 748 int y2, int w) 749 /* x1, y1 = source 750 x2, y2 = destination 751 w = width 752 */ 753{ 754 unsigned long a1, a2; 755 unsigned long source_address, destination_address; 756 unsigned int mask_source, mask_destination; 757 int cando; 758 unsigned int cando_mask; 759 int source_align, destination_align; 760 int pixel_shift; 761 int read; 762#ifdef PROFILE 763 unsigned int start, stop; 764#endif 765 TGAPtr pTga; 766 TGA_DECL(); 767 768 pTga = TGAPTR(pScrn); 769 TGA_GET_IOBASE(); 770 TGA_GET_OFFSET(); 771 772 cando = 32; 773 cando_mask = 0xFFFFFFFFU; 774 if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { 775 cando = 16; 776 cando_mask = 0x0000FFFFU; 777 } 778 779 a1 = FB_OFFSET(x1, y1); 780 a2 = FB_OFFSET(x2, y2); 781 782 source_address = FB_OFFSET((x1 + w) - cando, y1); 783 destination_address = FB_OFFSET((x2 + w) - cando, y2); 784 785#if 0 786 ErrorF("CPY-BWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx" 787 " a1 0x%lx a2 0x%lx\n", 788 x1, y1, x2, y2, w, source_address, destination_address, a1, a2); 789#endif 790 791 read = 0; 792 while (read < w) { 793 mask_source = cando_mask; 794 if ((w - read) >= cando) 795 mask_destination = cando_mask; 796 else { 797 mask_destination = ((unsigned int)cando_mask) << (cando - (w - read)); 798 mask_destination &= cando_mask; /* esp. for cando==16 */ 799 } 800 801 source_align = source_address & 0x07; 802 destination_align = destination_address & 0x07; 803 804 if (read == 0 && destination_align && 805 (source_align > destination_align)) { 806 /* we want to take out all the destination_align pixels in one 807 little copy first, then move on to the main stuff */ 808 unsigned long tmp_src, tmp_dest; 809 unsigned int tmp_src_mask, tmp_dest_mask; 810 811 tmp_src = a1 + (w - (source_align / pTga->Bpp)) * pTga->Bpp; 812 tmp_dest = a2 + (w - (destination_align / pTga->Bpp) - (8 / pTga->Bpp)) * pTga->Bpp; 813 tmp_src_mask = cando_mask; 814 tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align) / pTga->Bpp; 815 tmp_dest_mask <<= 8 / pTga->Bpp; 816 pixel_shift = (8 - source_align) + destination_align; 817#if 0 818 ErrorF("CPY-BWD - preliminary copy: sa = %d, da = %d, ps =%d\n", 819 source_align, destination_align, pixel_shift); 820#endif 821 TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 822 switch (pTga->Chipset) 823 { 824 case PCI_CHIP_TGA2: 825 *(unsigned int *)(pTga->FbBase + tmp_src) = tmp_src_mask; WMB; 826 *(unsigned int *)(pTga->FbBase + tmp_dest) = tmp_dest_mask; WMB; 827 break; 828 case PCI_CHIP_DEC21030: 829 /* use GADR and GCTR */ 830 TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG); 831 TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG); 832 TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG); 833 TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG); 834 break; 835 } 836 837 source_address += (8 - source_align); 838 mask_source >>= (8 - source_align) / pTga->Bpp; 839 mask_source >>= destination_align / pTga->Bpp; 840 mask_destination >>= destination_align / pTga->Bpp; 841 } 842 else if (read == 0 && (source_align != destination_align)) { 843 source_address += (8 - source_align); 844 /* mask_source >>= (8 - source_align); */ 845 /* if we uncomment this, it breaks...TGA tries to 846 optimize away a read of our last pixels... */ 847 } 848 else if (source_align) { 849 source_address += (8 - source_align); 850 mask_source >>= (8 - source_align) / pTga->Bpp; 851 } 852 853 if (destination_align) { 854 destination_address += (8 - destination_align); 855 mask_destination >>= (8 - destination_align) / pTga->Bpp; 856 } 857 858 if (destination_align >= source_align) 859 pixel_shift = destination_align - source_align; 860 else { 861 pixel_shift = (8 - source_align) + destination_align; 862 if (destination_align) { 863 source_address += 8; 864 mask_source >>= 8 / pTga->Bpp; 865 } 866 } 867 868#if 0 869 ErrorF("CPY-BWD - normal: sadr 0x%lx sm 0x%x dadr 0x%lx dm 0x%x" 870 " sa %d da %d ps %d read %d\n", 871 source_address, mask_source, 872 destination_address, mask_destination, 873 source_align, destination_align, pixel_shift, read); 874#endif 875 TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 876 switch (pTga->Chipset) { 877 case PCI_CHIP_TGA2: 878 *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; 879 *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; 880 break; 881 case PCI_CHIP_DEC21030: 882 /* use GADR and GCTR */ 883 TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); 884 TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); 885 TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); 886 TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); 887 break; 888 } 889 890/* if(read == 0) */ 891/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */ 892/* pixel_shift); */ 893 894 if (destination_align > source_align) { 895 source_address -= cando * pTga->Bpp - 8; 896 destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 897 if (read == 0) 898 read += (cando - 8 / pTga->Bpp) + source_align / pTga->Bpp; 899 else 900 read += cando - 8 / pTga->Bpp; 901 } 902 else if (destination_align == source_align) { 903 source_address -= cando * pTga->Bpp; 904 destination_address -= cando * pTga->Bpp; 905 if (read == 0 && destination_align) 906 read += (cando - (8 - destination_align) / pTga->Bpp); 907 else 908 read += cando; 909 } 910 else if (source_align > destination_align) { 911 source_address -= cando * pTga->Bpp - 8; 912 destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 913 /* only happens when read == 0 */ 914 if (destination_align) 915 read += (cando - 16 / pTga->Bpp) + source_align / pTga->Bpp; 916 else 917 read += cando - pixel_shift / pTga->Bpp; 918 } 919 } 920 921 TGA_SAVE_OFFSET(); 922 return; 923} 924 925void 926TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 927 int fg, int bg, int rop, unsigned int planemask) 928{ 929#ifdef PROFILE 930 unsigned int start, stop; 931#endif 932 TGAPtr pTga; 933 unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; 934 TGA_DECL(); 935 936 pTga = TGAPTR(pScrn); 937 TGA_GET_IOBASE(); 938 TGA_GET_OFFSET(); 939 940/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */ 941/* patx, paty, fg, bg, rop, planemask); */ 942 943 if(bg == -1) /* we are transparent */ 944 pTga->transparent_pattern_p = 1; 945 else 946 pTga->transparent_pattern_p = 0; 947 948 if(rop == MIX_SRC) 949 pTga->block_or_opaque_p = USE_BLOCK_FILL; 950 else 951 pTga->block_or_opaque_p = USE_OPAQUE_FILL; 952 953 if(pTga->depthflag == BPP8PACKED) { 954 fgcolor = fg | (fg << 8) | (fg << 16) | (fg << 24); 955 bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); 956 pmask = planemask | (planemask << 8) | (planemask << 16) | 957 (planemask << 24); 958 } 959 else { 960 fgcolor = fg; 961 bgcolor = bg; 962 pmask = planemask; 963 } 964 965 966 if(pTga->transparent_pattern_p && 967 pTga->block_or_opaque_p == USE_BLOCK_FILL) { 968 /* we can use block fill mode to draw a transparent stipple */ 969 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 970 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 971 if(pTga->depthflag == BPP24) { 972 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 973 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 974 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 975 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 976 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 977 TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 978 } 979 } 980 else if(pTga->transparent_pattern_p) { 981 TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 982 } 983 else { 984 TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); 985 TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 986 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 987 } 988 pTga->current_rop = rop; 989 pTga->current_planemask = pmask; 990 TGA_SAVE_OFFSET(); 991 return; 992} 993 994void 995TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 996 int x, int y, int w, int h) 997/* patx and paty = first & second dwords of pattern to be rendered, packed */ 998{ 999 TGAPtr pTga; 1000 int i, j; 1001 unsigned int stipple_mask[8], align, tmp; 1002#ifdef PROFILE 1003 register unsigned int stop, start; 1004#endif 1005 TGA_DECL(); 1006 1007 1008/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */ 1009 1010 pTga = TGAPTR(pScrn); 1011 TGA_GET_IOBASE(); 1012 TGA_GET_OFFSET(); 1013 1014 if(w > 2048) 1015 ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n"); 1016 if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 1017 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 1018 1019 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 1020 if(pTga->depthflag == BPP8PACKED) 1021 align = FB_OFFSET(x, y) % 4; 1022 else 1023 align = x % 4; 1024 1025 for(i = 0; i < 4; i++) { 1026 tmp = (patx >> (i * 8)) & 0xFF; 1027 stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); 1028 } 1029 for(i = 4; i < 8; i++) { 1030 tmp = (paty >> ((i - 4) * 8)) & 0xFF; 1031 stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); 1032 } 1033 if(align) { /* stipples must be aligned to four bytes */ 1034 for(i = 0; i < 8; i++) { 1035 stipple_mask[i] = (stipple_mask[i] << align) | 1036 ((stipple_mask[i] & 0xFF000000) >> (32 - align)); 1037 } 1038 } 1039 1040 if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) { 1041 /* use block fill */ 1042 TGA_FAST_WRITE_REG(BLOCKFILL | X11 | pTga->depthflag, TGA_MODE_REG); 1043 1044 for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 1045 TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 1046 TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 1047 TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 1048 } 1049 } 1050 else if(pTga->transparent_pattern_p) { 1051 /* if we can't use block fill, we'll use transparent fill */ 1052 TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | pTga->depthflag, TGA_MODE_REG); 1053 for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 1054 TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 1055 TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 1056 TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 1057 } 1058 } 1059 else { /* use opaque fill mode */ 1060/* ErrorF("Using opaque fill mode\n"); */ 1061 TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | pTga->depthflag, TGA_MODE_REG); 1062 for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 1063 TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 1064 TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 1065 TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 1066 } 1067 } 1068 1069 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 1070 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 1071 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 1072 1073 TGA_SAVE_OFFSET(); 1074 1075 return; 1076} 1077 1078void 1079TGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 1080 unsigned int planemask) 1081{ 1082#ifdef PROFILE 1083 unsigned int start, stop; 1084#endif 1085 TGAPtr pTga = NULL; 1086 unsigned int fgcolor = 0, pmask = 0; 1087 TGA_DECL(); 1088 1089 pTga = TGAPTR(pScrn); 1090 TGA_GET_IOBASE(); 1091 TGA_GET_OFFSET(); 1092/* ErrorF("TGASetupForSolidLine called\n"); */ 1093 1094 if(pTga->depthflag == BPP8PACKED) { 1095 fgcolor = color | (color << 8) | (color << 16) | (color << 24); 1096 pmask = planemask | (planemask << 8) | (planemask << 16) | 1097 (planemask << 24); 1098 } 1099 else { 1100 fgcolor = color; 1101 pmask = planemask; 1102 } 1103 1104 1105 pTga->current_rop = rop | pTga->depthflag; 1106 TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 1107 pTga->current_planemask = pmask; 1108 TGA_FAST_WRITE_REG(0xFFFF, TGA_DATA_REG); 1109 TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); 1110 TGA_SAVE_OFFSET(); 1111 1112 return; 1113} 1114 1115void 1116TGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, 1117 int dir) 1118{ 1119 if(dir == DEGREES_0) /* line is to the right */ 1120 TGASubsequentSolidLine(pScrn, x, y, x + len, y, 0x0, OMIT_LAST); 1121 else if(dir == DEGREES_270) /* line is down */ 1122 TGASubsequentSolidLine(pScrn, x, y, x, y + len, YMAJOR, OMIT_LAST); 1123 else 1124 ErrorF("TGASubsequentSolidHorVertLine passed dir %d!\n", dir); 1125 1126 return; 1127} 1128 1129void 1130TGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 1131 int octant, int flags) 1132{ 1133#ifdef PROFILE 1134 unsigned int start, stop; 1135#endif 1136 TGAPtr pTga = NULL; 1137 CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; 1138 int length = 0; 1139 TGA_DECL(); 1140 1141 pTga = TGAPTR(pScrn); 1142 TGA_GET_IOBASE(); 1143 TGA_GET_OFFSET(); 1144/* ErrorF("TGASubsequentSolidLine called\n"); */ 1145 1146 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 1147 TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | 1148 ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), TGA_MODE_REG); 1149 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 1150 1151 address = FB_OFFSET(x1, y1); 1152 TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 1153 abs_dx = abs(x2 - x1); 1154 abs_dy = abs(y2 - y1); 1155 if(octant & YMAJOR) 1156 length = abs_dy; 1157 else 1158 length = abs_dx; 1159 1160 if(octant & YMAJOR) { 1161 if(octant & YDECREASING) { 1162 if(octant & XDECREASING) 1163 octant_reg = TGA_SLOPE0_REG; 1164 else 1165 octant_reg = TGA_SLOPE2_REG; 1166 } 1167 else { 1168 if(octant & XDECREASING) 1169 octant_reg = TGA_SLOPE1_REG; 1170 else 1171 octant_reg = TGA_SLOPE3_REG; 1172 } 1173 } 1174 else { 1175 if(octant & YDECREASING) { 1176 if(octant & XDECREASING) 1177 octant_reg = TGA_SLOPE4_REG; 1178 else 1179 octant_reg = TGA_SLOPE6_REG; 1180 } 1181 else { 1182 if(octant & XDECREASING) 1183 octant_reg = TGA_SLOPE5_REG; 1184 else 1185 octant_reg = TGA_SLOPE7_REG; 1186 } 1187 } 1188 1189 TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 1190 if(length > 16 && length % 16) 1191 length -= length % 16; 1192 else 1193 length -= 16; 1194 1195 while(length > 0) { 1196 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); 1197 length -= 16; 1198 } 1199 1200 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 1201 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 1202 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 1203 1204 TGA_SAVE_OFFSET(); 1205 1206 return; 1207} 1208 1209void 1210TGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 1211 int octant) 1212{ 1213#ifdef PROFILE 1214 unsigned int start, stop; 1215#endif 1216 TGAPtr pTga = NULL; 1217 CARD32 abs_dx = 0, abs_dy = 0, octant_reg = 0; 1218 TGA_DECL(); 1219 1220 pTga = TGAPTR(pScrn); 1221 TGA_GET_IOBASE(); 1222 TGA_GET_OFFSET(); 1223/* ErrorF("TGASetupForClippedLine called\n"); */ 1224 1225/* TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG); */ 1226/* TGA_FAST_WRITE_REG(OPAQUELINE | X11 | BPP8PACKED, TGA_MODE_REG); */ 1227 1228 abs_dx = abs(x2 - x1); 1229 abs_dy = abs(y2 - y1); 1230 1231 if(octant & YMAJOR) { 1232 if(octant & YDECREASING) { 1233 if(octant & XDECREASING) 1234 octant_reg = TGA_NOSLOPE0_REG; 1235 else 1236 octant_reg = TGA_NOSLOPE2_REG; 1237 } 1238 else { 1239 if(octant & XDECREASING) 1240 octant_reg = TGA_NOSLOPE1_REG; 1241 else 1242 octant_reg = TGA_NOSLOPE3_REG; 1243 } 1244 } 1245 else { 1246 if(octant & YDECREASING) { 1247 if(octant & XDECREASING) 1248 octant_reg = TGA_NOSLOPE4_REG; 1249 else 1250 octant_reg = TGA_NOSLOPE6_REG; 1251 } 1252 else { 1253 if(octant & XDECREASING) 1254 octant_reg = TGA_NOSLOPE5_REG; 1255 else 1256 octant_reg = TGA_NOSLOPE7_REG; 1257 } 1258 } 1259 1260 TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 1261 1262 TGA_SAVE_OFFSET(); 1263 return; 1264} 1265 1266void 1267TGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len, 1268 int err) 1269 /* we are already in line mode, now we need to 1270 1) write starting pixel address to gaddr 1271 2) write initial error and line length to bresenham 3 1272 3) write the gctr to draw the line, and repeat for lines > 16 pixels 1273 4) set mode back to simple mode 1274 */ 1275{ 1276#ifdef PROFILE 1277 unsigned int start, stop; 1278#endif 1279 TGAPtr pTga = NULL; 1280 CARD32 address = 0; 1281 int length = 0; 1282 TGA_DECL(); 1283 1284 pTga = TGAPTR(pScrn); 1285 TGA_GET_IOBASE(); 1286 TGA_GET_OFFSET(); 1287/* ErrorF("TGASubsequentClippedSolidLine called\n"); */ 1288 1289 address = FB_OFFSET(x1, y1); 1290 TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 1291 1292 TGA_FAST_WRITE_REG(pTga->current_rop | pTga->depthflag, TGA_RASTEROP_REG); 1293 TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); 1294 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 1295 1296 length = len; 1297 TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); 1298 1299 while(length > 0) { 1300 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); 1301 if(length > 16 && length % 16) 1302 length -= length % 16; 1303 else 1304 length -= 16; 1305 } 1306 1307 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 1308 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 1309 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 1310 1311 TGA_SAVE_OFFSET(); 1312 1313 return; 1314 1315} 1316 1317void 1318TGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, 1319 unsigned int planemask, int length, 1320 unsigned char *pattern) 1321{ 1322#ifdef PROFILE 1323 unsigned int start = 0, stop = 0; 1324#endif 1325 TGAPtr pTga = NULL; 1326 unsigned int color1 = 0, color2 = 0, pmask = 0; 1327 TGA_DECL(); 1328 1329 pTga = TGAPTR(pScrn); 1330 TGA_GET_IOBASE(); 1331 TGA_GET_OFFSET(); 1332/* ErrorF("TGASetupForDashedLine called\n"); */ 1333 1334 if(pTga->depthflag == BPP8PACKED) { 1335 color1 = fg | (fg << 8) | (fg << 16) | (fg << 24); 1336 color2 = bg | (bg << 8) | (bg << 16) | (bg << 24); 1337 pmask = planemask | (planemask << 8) | (planemask << 16) 1338 | (planemask << 24); 1339 } 1340 else { 1341 color1 = fg; 1342 color2 = fg; 1343 pmask = planemask; 1344 } 1345 1346 pTga->current_rop = rop | pTga->depthflag; 1347 TGA_FAST_WRITE_REG(color1, TGA_FOREGROUND_REG); 1348 pTga->current_planemask = pmask; 1349 if(bg == -1) /* transparent line */ 1350 pTga->transparent_pattern_p = 1; 1351 else { 1352 pTga->transparent_pattern_p = 0; 1353 TGA_FAST_WRITE_REG(color2, TGA_BACKGROUND_REG); 1354 } 1355 1356 pTga->line_pattern = pattern[0] | (pattern[1] << 8); 1357 pTga->line_pattern_length = length; 1358 1359 TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); 1360 TGA_SAVE_OFFSET(); 1361 1362 return; 1363} 1364 1365void 1366TGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 1367 int y2, int octant, int flags, int phase) 1368{ 1369#ifdef PROFILE 1370 unsigned int start, stop; 1371#endif 1372 TGAPtr pTga = NULL; 1373 CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; 1374 int length = 0; 1375 CARD16 line_mask = 0; 1376 int pattern_overflow = 0; 1377 int l = 0; 1378 TGA_DECL(); 1379 1380 pTga = TGAPTR(pScrn); 1381 TGA_GET_IOBASE(); 1382 TGA_GET_OFFSET(); 1383/* ErrorF("TGASubsequentDashedLine called\n"); */ 1384 1385 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 1386 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 1387 if(pTga->transparent_pattern_p) 1388 TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag | 1389 ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), 1390 TGA_MODE_REG); 1391 else 1392 TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | 1393 ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), 1394 TGA_MODE_REG); 1395 1396 address = FB_OFFSET(x1, y1); 1397 TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 1398 abs_dx = abs(x2 - x1); 1399 abs_dy = abs(y2 - y1); 1400 if(abs_dx > abs_dy) 1401 length = abs_dx; 1402 else 1403 length = abs_dy; 1404 1405 if(octant & YMAJOR) { 1406 if(octant & YDECREASING) { 1407 if(octant & XDECREASING) 1408 octant_reg = TGA_SLOPE0_REG; 1409 else 1410 octant_reg = TGA_SLOPE2_REG; 1411 } 1412 else { 1413 if(octant & XDECREASING) 1414 octant_reg = TGA_SLOPE1_REG; 1415 else 1416 octant_reg = TGA_SLOPE3_REG; 1417 } 1418 } 1419 else { 1420 if(octant & YDECREASING) { 1421 if(octant & XDECREASING) 1422 octant_reg = TGA_SLOPE4_REG; 1423 else 1424 octant_reg = TGA_SLOPE6_REG; 1425 } 1426 else { 1427 if(octant & XDECREASING) 1428 octant_reg = TGA_SLOPE5_REG; 1429 else 1430 octant_reg = TGA_SLOPE7_REG; 1431 } 1432 } 1433 /* set up our first pattern with phase. Keep track of if we overflow the 1434 pattern by pattern_overflow, and correct on the next write */ 1435 1436 if(phase) { 1437 line_mask = pTga->line_pattern >> phase; 1438 l = (pTga->line_pattern_length - phase); 1439 } 1440 else { 1441 line_mask = pTga->line_pattern; 1442 l = pTga->line_pattern_length; 1443 } 1444 1445 while(l < 16) { 1446 line_mask |= pTga->line_pattern << l; 1447 l += pTga->line_pattern_length; 1448 } 1449 pattern_overflow = l - 16; 1450 1451 TGA_FAST_WRITE_REG(line_mask, TGA_DATA_REG); 1452 1453 TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 1454 1455 if(length > 16 && length % 16) 1456 length -= length % 16; 1457 else 1458 length -= 16; 1459 1460 while(length > 0) { 1461 1462 if(pattern_overflow) { 1463 line_mask = pTga->line_pattern >> (pTga->line_pattern_length - 1464 pattern_overflow); 1465 l = pattern_overflow; 1466 } 1467 else { 1468 line_mask = pTga->line_pattern; 1469 l = pTga->line_pattern_length; 1470 } 1471 while(l < 16) { 1472 line_mask |= (pTga->line_pattern << l); 1473 l += pTga->line_pattern_length; 1474 } 1475 pattern_overflow = l - 16; 1476 1477 TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); 1478 length -= 16; 1479 } 1480 1481 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 1482 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 1483 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 1484 1485 TGA_SAVE_OFFSET(); 1486 1487 return; 1488} 1489 1490void 1491TGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len, 1492 int err, int phase) 1493{ 1494#ifdef PROFILE 1495 unsigned int start, stop; 1496#endif 1497 TGAPtr pTga = NULL; 1498 CARD32 address = 0; 1499 int length = 0; 1500 CARD16 line_mask = 0; 1501 int pattern_overflow = 0; 1502 int l = 0; 1503 TGA_DECL(); 1504 1505 pTga = TGAPTR(pScrn); 1506 TGA_GET_IOBASE(); 1507 TGA_GET_OFFSET(); 1508 /* ErrorF("TGASubsequentClippedDashedLine called\n"); */ 1509 1510 address = FB_OFFSET(x1, y1); 1511 TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 1512 1513 TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 1514 TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 1515 1516 if(pTga->transparent_pattern_p) 1517 TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag, TGA_MODE_REG); 1518 else 1519 TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); 1520 1521 length = len; 1522 TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); 1523 1524 1525 if(phase) { 1526 line_mask = pTga->line_pattern >> phase; 1527 l = (pTga->line_pattern_length - phase); 1528 } 1529 else { 1530 line_mask = pTga->line_pattern; 1531 l = pTga->line_pattern_length; 1532 } 1533 1534 while(l < 16) { 1535 line_mask |= pTga->line_pattern << l; 1536 l += pTga->line_pattern_length; 1537 } 1538 pattern_overflow = l - 16; 1539 1540 1541 while(length > 0) { 1542 TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); 1543 1544 if(pattern_overflow) { 1545 line_mask = pTga->line_pattern >> (pTga->line_pattern_length - 1546 pattern_overflow); 1547 l = pattern_overflow; 1548 } 1549 else { 1550 line_mask = pTga->line_pattern; 1551 l = pTga->line_pattern_length; 1552 } 1553 while(l < 16) { 1554 line_mask |= (pTga->line_pattern << l); 1555 l += pTga->line_pattern_length; 1556 } 1557 pattern_overflow = l - 16; 1558 1559 if(length > 16 && length % 16) 1560 length -= length % 16; 1561 else 1562 length -= 16; 1563 } 1564 1565 TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 1566 TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 1567 TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 1568 1569 TGA_SAVE_OFFSET(); 1570 1571 return; 1572} 1573