diff options
Diffstat (limited to 'src/savage_accel.c')
-rw-r--r-- | src/savage_accel.c | 1242 |
1 files changed, 1242 insertions, 0 deletions
diff --git a/src/savage_accel.c b/src/savage_accel.c new file mode 100644 index 0000000..0ffc863 --- /dev/null +++ b/src/savage_accel.c @@ -0,0 +1,1242 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.18 2002/11/08 18:03:32 alanh Exp $ */ + +/* + * + * Copyright 1995-1997 The XFree86 Project, Inc. + * + */ + +/* + * The accel file for the Savage driver. + * + * Created 20/03/97 by Sebastien Marineau for 3.3.6 + * Modified 17-Nov-2000 by Tim Roberts for 4.0.1 + * Revision: + * + */ + +#include "Xarch.h" +#include "xaalocal.h" +#include "xaarop.h" +#include "miline.h" + +#include "savage_driver.h" +#include "savage_regs.h" +#include "savage_bci.h" + +/* Forward declaration of functions used in the driver */ + +static void SavageSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, + int ydir, + int rop, + unsigned planemask, + int transparency_color); + +static void SavageSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int w, + int h); + +static void SavageSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned planemask); + +static void SavageSubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h); + +static void SavageSubsequentSolidBresenhamLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int e1, + int e2, + int err, + int length, + int octant); + +static void SavageSubsequentSolidTwoPointLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int bias); + +#if 0 +static void SavageSetupForScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int bg, + int fg, + int rop, + unsigned planemask); + +static void SavageSubsequentScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); +#endif + +static void SavageSetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned planemask); + +static void SavageSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); + +static void SavageSubsequentColorExpandScanline( + ScrnInfoPtr pScrn, + int buffer_no); + +static void SavageSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int fg, + int bg, + int rop, + unsigned planemask); + +static void SavageSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int x, + int y, + int w, + int h); + +static void SavageSetupForColor8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int rop, + unsigned planemask, + int trans_col); + +static void SavageSubsequentColor8x8PatternFillRect( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int x, + int y, + int w, + int h); + +static void SavageSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2); + +static void SavageDisableClipping( ScrnInfoPtr ); + +#if 0 +static void SavageSubsequentSolidFillTrap( + ScrnInfoPtr pScrn, + int y, + int h, + int left, + int dxl, + int dyl, + int el, + int right, + int dxr, + int dyr, + int er); +#endif + +/* from savage_image.c: */ + +void SavageSetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, + int depth); + +void SavageSubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); + +void SavageWriteBitmapCPUToScreenColorExpand ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char * src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +); + +unsigned long writedw( unsigned long addr, unsigned long value ); +unsigned long readdw( unsigned long addr ); +unsigned long readfb( unsigned long addr ); +unsigned long writefb( unsigned long addr, unsigned long value ); +void writescan( unsigned long scan, unsigned long color ); + + +/* + * This is used to cache the last known value for routines we want to + * call from the debugger. + */ + +ScrnInfoPtr gpScrn = 0; + + + + +void +SavageInitialize2DEngine(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + SavagePtr psav = SAVPTR(pScrn); + unsigned int vgaCRIndex = hwp->IOBase + 4; + unsigned int vgaCRReg = hwp->IOBase + 5; + + gpScrn = pScrn; + + VGAOUT16(vgaCRIndex, 0x0140); + VGAOUT8(vgaCRIndex, 0x31); + VGAOUT8(vgaCRReg, 0x0c); + + /* Setup plane masks */ + OUTREG(0x8128, ~0); /* enable all write planes */ + OUTREG(0x812C, ~0); /* enable all read planes */ + OUTREG16(0x8134, 0x27); + OUTREG16(0x8136, 0x07); + + switch( psav->Chipset ) { + + case S3_SAVAGE3D: + case S3_SAVAGE_MX: + /* Disable BCI */ + OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0); + /* Setup BCI command overflow buffer */ + OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29)); + /* Program shadow status update. */ + OUTREG(0x48C10, 0x78207220); + if( psav->ShadowStatus ) + { + OUTREG(0x48C0C, psav->ShadowPhysical | 1 ); + /* Enable BCI and command overflow buffer */ + OUTREG(0x48C18, INREG(0x48C18) | 0x0E); + } + else + { + OUTREG(0x48C0C, 0); + /* Enable BCI and command overflow buffer */ + OUTREG(0x48C18, INREG(0x48C18) | 0x0C); + } + break; + + case S3_SAVAGE4: + case S3_PROSAVAGE: + case S3_SUPERSAVAGE: + /* Disable BCI */ + OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0); + /* Program shadow status update */ + OUTREG(0x48C10, 0x00700040); + if( psav->ShadowStatus ) + { + OUTREG(0x48C0C, psav->ShadowPhysical | 1 ); + /* Enable BCI without the COB */ + OUTREG(0x48C18, INREG(0x48C18) | 0x0a); + } + else + { + OUTREG(0x48C0C, 0); + /* Enable BCI without the COB */ + OUTREG(0x48C18, INREG(0x48C18) | 0x08); + } + break; + + case S3_SAVAGE2000: + /* Disable BCI */ + OUTREG(0x48C18, 0); + /* Setup BCI command overflow buffer */ + OUTREG(0x48C18, (psav->cobOffset >> 7) | (psav->cobIndex)); + if( psav->ShadowStatus ) + { + /* Set shadow update threshholds. */ + OUTREG(0x48C10, 0x6090 ); + OUTREG(0x48C14, 0x70A8 ); + /* Enable shadow status update */ + OUTREG(0x48A30, psav->ShadowPhysical ); + /* Enable BCI, command overflow buffer and shadow status. */ + OUTREG(0x48C18, INREG(0x48C18) | 0x00380000 ); + } + else + { + /* Disable shadow status update */ + OUTREG(0x48A30, 0); + /* Enable BCI and command overflow buffer */ + OUTREG(0x48C18, INREG(0x48C18) | 0x00280000 ); + } + break; + } + + /* Use and set global bitmap descriptor. */ + + /* For reasons I do not fully understand yet, on the Savage4, the */ + /* write to the GBD register, MM816C, does not "take" at this time. */ + /* Only the low-order byte is acknowledged, resulting in an incorrect */ + /* stride. Writing the register later, after the mode switch, works */ + /* correctly. This needs to get resolved. */ + + SavageSetGBD(pScrn); +} + + +void +SavageSetGBD( ScrnInfoPtr pScrn ) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + SavagePtr psav = SAVPTR(pScrn); + unsigned int vgaCRIndex = hwp->IOBase + 4; + unsigned int vgaCRReg = hwp->IOBase + 5; + unsigned long GlobalBitmapDescriptor; + + GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE; + BCI_BD_SET_BPP(GlobalBitmapDescriptor, pScrn->bitsPerPixel); + BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, pScrn->displayWidth); + + /* Turn on 16-bit register access. */ + + VGAOUT8(vgaCRIndex, 0x31); + VGAOUT8(vgaCRReg, 0x0c); + + /* Set stride to use GBD. */ + + VGAOUT8(vgaCRIndex, 0x50); + VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); + + /* Enable 2D engine. */ + + VGAOUT16(vgaCRIndex, 0x0140); + + /* Now set the GBD and SBDs. */ + + OUTREG(0x8168, 0); + OUTREG(0x816C, GlobalBitmapDescriptor); + OUTREG(0x8170, 0); + OUTREG(0x8174, GlobalBitmapDescriptor); + OUTREG(0x8178, 0); + OUTREG(0x817C, GlobalBitmapDescriptor); + + OUTREG(PRI_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3); + OUTREG(SEC_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3); +} + + +/* Acceleration init function, sets up pointers to our accelerated functions */ + +Bool +SavageInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + XAAInfoRecPtr xaaptr; + BoxRec AvailFBArea; + + /* Set-up our GE command primitive */ + + if (pScrn->depth == 8) { + psav->PlaneMask = 0xFF; + } + else if (pScrn->depth == 15) { + psav->PlaneMask = 0x7FFF; + } + else if (pScrn->depth == 16) { + psav->PlaneMask = 0xFFFF; + } + else if (pScrn->depth == 24) { + psav->PlaneMask = 0xFFFFFF; + } + + /* General acceleration flags */ + + if (!(xaaptr = psav->AccelInfoRec = XAACreateInfoRec())) + return FALSE; + + xaaptr->Flags = 0 + | PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER + ; + + /* Clipping */ + + xaaptr->SetClippingRectangle = SavageSetClippingRectangle; + xaaptr->DisableClipping = SavageDisableClipping; + xaaptr->ClippingFlags = 0 +#if 0 + | HARDWARE_CLIP_SOLID_FILL + | HARDWARE_CLIP_SOLID_LINE + | HARDWARE_CLIP_DASHED_LINE +#endif + | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY + | HARDWARE_CLIP_MONO_8x8_FILL + | HARDWARE_CLIP_COLOR_8x8_FILL + ; + + xaaptr->Sync = SavageAccelSync; + + + /* ScreenToScreen copies */ + +#if 1 + xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK | ROP_NEEDS_SOURCE; +#endif + + + /* Solid filled rectangles */ + +#if 1 + xaaptr->SetupForSolidFill = SavageSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = SavageSubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; +#endif + + /* Mono 8x8 pattern fills */ + +#if 1 + xaaptr->SetupForMono8x8PatternFill = SavageSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect + = SavageSubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = 0 + | HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_SCREEN_ORIGIN + | ROP_NEEDS_SOURCE + | BIT_ORDER_IN_BYTE_MSBFIRST + ; + if( psav->Chipset == S3_SAVAGE4 ) + xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY; +#endif + + /* Color 8x8 pattern fills */ + + /* + * With the exception of the Savage3D and Savage4, all of the Savage + * chips require that bitmap descriptors have a stride that is a + * multiple of 16 pixels. This includes any descriptor used for + * color pattern fills, which COMPLETELY screws the XAA 8x8 color + * pattern support. + * + * We could double the width ourselves into a reserved frame buffer + * section, but since I went 18 months with only ONE report of this + * error, it seems hardly worth the trouble. + */ + +#if 1 + if( (psav->Chipset == S3_SAVAGE3D) || (psav->Chipset == S3_SAVAGE4) ) + { + xaaptr->SetupForColor8x8PatternFill = + SavageSetupForColor8x8PatternFill; + xaaptr->SubsequentColor8x8PatternFillRect = + SavageSubsequentColor8x8PatternFillRect; + xaaptr->Color8x8PatternFillFlags = 0 + | NO_TRANSPARENCY + | HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + ; + } +#endif + + /* Solid lines */ + +#if 1 + xaaptr->SolidLineFlags = NO_PLANEMASK; + xaaptr->SetupForSolidLine = SavageSetupForSolidFill; + xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine; + xaaptr->SubsequentSolidTwoPointLine = SavageSubsequentSolidTwoPointLine; +#if 0 + xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap; +#endif + + xaaptr->SolidBresenhamLineErrorTermBits = 14; +#endif + + /* ImageWrite */ + + xaaptr->ImageWriteFlags = 0 + | NO_PLANEMASK + | CPU_TRANSFER_PAD_DWORD + | SCANLINE_PAD_DWORD + | BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + ; + xaaptr->SetupForImageWrite = SavageSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect; + xaaptr->NumScanlineImageWriteBuffers = 1; + xaaptr->ImageWriteBase = psav->BciMem; + xaaptr->ImageWriteRange = 120 * 1024; + + /* WriteBitmap color expand */ + +#if 0 + xaaptr->WriteBitmapFlags = NO_PLANEMASK; + xaaptr->WriteBitmap = SavageWriteBitmapCPUToScreenColorExpand; +#endif + + /* Screen to Screen color expansion. Not implemented. */ + +#if 0 + xaaptr->SetupForScreenToScreenColorExpand = + SavageSetupForScreenToScreenColorExpand; + xaaptr->SubsequentScreenToScreenColorExpand = + SavageSubsequentCPUToScreenColorExpand; +#endif + + /* CPU to Screen color expansion */ + + xaaptr->ScanlineCPUToScreenColorExpandFillFlags = 0 + | NO_PLANEMASK + | CPU_TRANSFER_PAD_DWORD + | SCANLINE_PAD_DWORD + | BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + | ROP_NEEDS_SOURCE + ; + + xaaptr->SetupForScanlineCPUToScreenColorExpandFill = + SavageSetupForCPUToScreenColorExpandFill; + xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = + SavageSubsequentScanlineCPUToScreenColorExpandFill; + xaaptr->SubsequentColorExpandScanline = + SavageSubsequentColorExpandScanline; + xaaptr->ColorExpandBase = psav->BciMem; + xaaptr->ScanlineColorExpandBuffers = &xaaptr->ColorExpandBase; + xaaptr->NumScanlineColorExpandBuffers = 1; + + /* Set up screen parameters. */ + + psav->Bpp = pScrn->bitsPerPixel / 8; + psav->Bpl = pScrn->displayWidth * psav->Bpp; + psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl; + if (psav->ScissB > 2047) + psav->ScissB = 2047; + + /* + * Finally, we set up the video memory space available to the pixmap + * cache. In this case, all memory from the end of the virtual screen + * to the end of the command overflow buffer can be used. If you haven't + * enabled the PIXMAP_CACHE flag, then these lines can be omitted. + */ + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = psav->ScissB; + xf86InitFBManager(pScreen, &AvailFBArea); + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory.\n", + psav->ScissB - pScrn->virtualY ); + + return XAAInit(pScreen, xaaptr); +} + + + + +/* The sync function for the GE */ +void +SavageAccelSync(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + psav->WaitIdleEmpty(psav); +} + + +/* + * The XAA ROP helper routines all assume that a solid color is a + * "pattern". The Savage chips, however, apply a non-stippled solid + * color as "source". Thus, we use a slightly customized version. + */ + +static int +SavageHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int ret = 0; + + pm &= infoRec->FullPlanemask; + + if(pm == infoRec->FullPlanemask) { + if(!NO_SRC_ROP(*rop)) + ret |= ROP_PAT; + *rop = XAACopyROP[*rop]; + } else { + switch(*rop) { + case GXnoop: + break; + case GXset: + case GXclear: + case GXinvert: + ret |= ROP_PAT; + *fg = pm; + if(*bg != -1) + *bg = pm; + break; + default: + ret |= ROP_PAT | ROP_SRC; + break; + } + *rop = XAACopyROP_PM[*rop]; + } + + return ret; +} + + +static int +SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int ret = 0; + + pm &= infoRec->FullPlanemask; + + if(pm == infoRec->FullPlanemask) { + if(!NO_SRC_ROP(*rop)) + ret |= ROP_PAT; + *rop = XAACopyROP[*rop]; + } else { + switch(*rop) { + case GXnoop: + break; + case GXset: + case GXclear: + case GXinvert: + ret |= ROP_PAT; + *fg = pm; + break; + default: + ret |= ROP_PAT | ROP_SRC; + break; + } + *rop = XAACopyROP_PM[*rop]; + } + + return ret; +} + + + +/* These are the ScreenToScreen bitblt functions. We support all ROPs, all + * directions, and a planemask by adjusting the ROP and using the mono pattern + * registers. + * + * (That's a lie; we don't really support planemask.) + */ + +static void +SavageSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, + int ydir, + int rop, + unsigned planemask, + int transparency_color) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + + cmd = BCI_CMD_RECT | BCI_CMD_DEST_GBD | BCI_CMD_SRC_GBD; + BCI_CMD_SET_ROP( cmd, XAACopyROP[rop] ); + if (transparency_color != -1) + cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT; + + if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP; + if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP; + + psav->SavedBciCmd = cmd; + psav->SavedBgColor = transparency_color; +} + +static void +SavageSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + if (!w || !h) return; + if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { + w --; + x1 += w; + x2 += w; + w ++; + } + if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { + h --; + y1 += h; + y2 += h; + h ++; + } + + psav->WaitQueue(psav,6); + BCI_SEND(psav->SavedBciCmd); + if (psav->SavedBgColor != -1) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x1, y1)); + BCI_SEND(BCI_X_Y(x2, y2)); + BCI_SEND(BCI_W_H(w, h)); +} + + +/* + * SetupForSolidFill is also called to set up for lines. + */ + +static void +SavageSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned planemask) +{ + SavagePtr psav = SAVPTR(pScrn); + XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn ); + int cmd; + int mix; + + cmd = BCI_CMD_RECT + | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID; + + /* Don't send a color if we don't have to. */ + + if( rop == GXcopy ) + { + if( color == 0 ) + rop = GXclear; + else if( color == xaaptr->FullPlanemask ) + rop = GXset; + } + + mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop ); + + if( mix & ROP_PAT ) + cmd |= BCI_CMD_SEND_COLOR; + + BCI_CMD_SET_ROP( cmd, rop ); + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = color; +} + + +static void +SavageSubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + if( !w || !h ) + return; + + psav->WaitQueue(psav,5); + + BCI_SEND(psav->SavedBciCmd); + if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(psav->SavedFgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); +} + +#if 0 +static void +SavageSetupForScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int bg, + int fg, + int rop, + unsigned planemask) +{ +/* SavagePtr psav = SAVPTR(pScrn); */ +} + +static void +SavageSubsequentScreenToScreenColorExpand( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft) +{ +/* SavagePtr psav = SAVPTR(pScrn); */ +} +#endif + + +static void +SavageSetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned planemask) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + int mix; + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_CLIP_LR + | BCI_CMD_DEST_GBD | BCI_CMD_SRC_MONO; + + mix = SavageHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); + + if( mix & ROP_PAT ) + cmd |= BCI_CMD_SEND_COLOR; + + BCI_CMD_SET_ROP( cmd, rop ); + + if (bg != -1) + cmd |= BCI_CMD_SEND_COLOR; + else + cmd |= BCI_CMD_SRC_TRANSPARENT; + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = fg; + psav->SavedBgColor = bg; +} + + +static void +SavageSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + /* XAA will be sending bitmap data next. */ + /* We should probably wait for empty/idle here. */ + + psav->WaitQueue(psav,20); + + BCI_SEND(psav->SavedBciCmd); + BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); + w = (w + 31) & ~31; + if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(psav->SavedFgColor); + if( psav->SavedBgColor != -1 ) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, 1)); + + psav->Rect.x = x; + psav->Rect.y = y + 1; + psav->Rect.width = w; + psav->Rect.height = h - 1; +} + +static void +SavageSubsequentColorExpandScanline( + ScrnInfoPtr pScrn, + int buffer_no) +{ + /* This gets call after each scanline's image data has been sent. */ + SavagePtr psav = SAVPTR(pScrn); + xRectangle xr = psav->Rect; + BCI_GET_PTR; + + if( xr.height ) + { + psav->WaitQueue(psav,20); + BCI_SEND(BCI_X_Y( xr.x, xr.y)); + BCI_SEND(BCI_W_H( xr.width, 1 )); + psav->Rect.height--; + psav->Rect.y++; + } +} + + +/* + * The meaning of the two pattern paremeters to Setup & Subsequent for + * Mono8x8Patterns varies depending on the flag bits. We specify + * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns + * without caching in the frame buffer. Thus, Setup gets the pattern bits. + * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify + * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated + * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN, + * then Setup would get the unrotated pattern, and Subsequent gets the + * origin values. + */ + +static void +SavageSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int fg, + int bg, + int rop, + unsigned planemask) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + int mix; + + mix = XAAHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_GBD; + + if( mix & ROP_PAT ) + cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_PAT_MONO; + + if (bg == -1) + cmd |= BCI_CMD_PAT_TRANSPARENT; + + BCI_CMD_SET_ROP(cmd, rop); + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = fg; + psav->SavedBgColor = bg; +} + + +static void +SavageSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int x, + int y, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + /* + * I didn't think it was my job to do trivial rejection, but + * miFillGeneralPolygon definitely generates null spans, and XAA + * just passes them through. + */ + + if( !w || !h ) + return; + + psav->WaitQueue(psav,7); + BCI_SEND(psav->SavedBciCmd); + if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(psav->SavedFgColor); + if( psav->SavedBgColor != -1 ) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); + if( psav->SavedBciCmd & BCI_CMD_PAT_MONO ) + { + BCI_SEND(pattern0); + BCI_SEND(pattern1); + } +} + + +static void +SavageSetupForColor8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int rop, + unsigned planemask, + int trans_col) +{ + SavagePtr psav = SAVPTR(pScrn); + + int cmd; + int mix; + unsigned int bd; + int pat_offset; + + /* ViRGEs and Savages do not support transparent color patterns. */ + /* We set the NO_TRANSPARENCY bit, so we should never receive one. */ + + pat_offset = (int) (patternx * psav->Bpp + patterny * psav->Bpl); + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW; + + mix = XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop ); + + BCI_CMD_SET_ROP(cmd, rop); + bd = BCI_BD_BW_DISABLE; + BCI_BD_SET_BPP(bd, pScrn->bitsPerPixel); + BCI_BD_SET_STRIDE(bd, 8); + + psav->SavedBciCmd = cmd; + psav->SavedSbdOffset = pat_offset; + psav->SavedSbd = bd; + psav->SavedBgColor = trans_col; +} + + +static void +SavageSubsequentColor8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int x, + int y, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + if( !w || !h ) + return; + + psav->WaitQueue(psav,6); + BCI_SEND(psav->SavedBciCmd); + BCI_SEND(psav->SavedSbdOffset); + BCI_SEND(psav->SavedSbd); + BCI_SEND(BCI_X_Y(patternx,patterny)); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); +} + + +static void +SavageSubsequentSolidBresenhamLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int e1, + int e2, + int err, + int length, + int octant) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + int cmd; + + cmd = (psav->SavedBciCmd & 0x00ffffff); + cmd |= BCI_CMD_LINE_LAST_PIXEL; + +#ifdef DEBUG_EXTRA + ErrorF("BresenhamLine, (%4d,%4d), len %4d, oct %d, err %4d,%4d,%4d clr %08x\n", + x1, y1, length, octant, e1, e2, err, psav->SavedFgColor ); +#endif + + psav->WaitQueue(psav, 5 ); + BCI_SEND(cmd); + if( cmd & BCI_CMD_SEND_COLOR ) + BCI_SEND( psav->SavedFgColor ); + BCI_SEND(BCI_LINE_X_Y(x1, y1)); + BCI_SEND(BCI_LINE_STEPS(e2-e1, e2)); + BCI_SEND(BCI_LINE_MISC(length, + (octant & YMAJOR), + !(octant & XDECREASING), + !(octant & YDECREASING), + e2+err)); +} + + +static void +SavageSubsequentSolidTwoPointLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int bias) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + int cmd; + int dx, dy; + int min, max, xp, yp, ym; + + dx = x2 - x1; + dy = y2 - y1; + +#ifdef DEBUG_EXTRA + ErrorF("TwoPointLine, (%4d,%4d)-(%4d,%4d), clr %08x, last pt %s\n", + x1, y1, x2, y2, psav->SavedFgColor, (bias & 0x100)?"NO ":"YES"); +#endif + + xp = (dx >= 0); + if( !xp ) { + dx = -dx; + } + + yp = (dy >= 0); + if( !yp ) { + dy = -dy; + } + + ym = (dy > dx); + if( ym ) { + max = dy; + min = dx; + } + else { + max = dx; + min = dy; + } + + if( !(bias & 0x100) ) { + max++; + } + + cmd = (psav->SavedBciCmd & 0x00ffffff); + cmd |= BCI_CMD_LINE_LAST_PIXEL; + + psav->WaitQueue(psav,5); + BCI_SEND( cmd ); + if( cmd & BCI_CMD_SEND_COLOR ) + BCI_SEND( psav->SavedFgColor ); + BCI_SEND( BCI_LINE_X_Y( x1, y1 ) ); + BCI_SEND( BCI_LINE_STEPS( 2 * (min - max), 2 * min ) ); + BCI_SEND( BCI_LINE_MISC( max, ym, xp, yp, 2 * min - max ) ); +} + + + +static void +SavageSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + int cmd; + +#ifdef DEBUG_EXTRA + ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); +#endif + + cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; + psav->WaitQueue(psav,3); + BCI_SEND(cmd); + BCI_SEND(BCI_CLIP_TL(y1, x1)); + BCI_SEND(BCI_CLIP_BR(y2, x2)); + psav->SavedBciCmd |= BCI_CMD_CLIP_CURRENT; +} + + +static void SavageDisableClipping( ScrnInfoPtr pScrn ) +{ + SavagePtr psav = SAVPTR(pScrn); +#ifdef DEBUG_EXTRA + ErrorF("Kill ClipRect\n"); +#endif + psav->SavedBciCmd &= ~BCI_CMD_CLIP_CURRENT; +} + + +/* Routines for debugging. */ + + +unsigned long +writedw( unsigned long addr, unsigned long value ) +{ + SavagePtr psav = SAVPTR(gpScrn); + OUTREG( addr, value ); + return INREG( addr ); +} + +unsigned long +readdw( unsigned long addr ) +{ + SavagePtr psav = SAVPTR(gpScrn); + return INREG( addr ); +} + +unsigned long +readfb( unsigned long addr ) +{ + SavagePtr psav = SAVPTR(gpScrn); + char * videobuffer = (char *) psav->FBBase; + return *(volatile unsigned long*)(videobuffer + (addr & ~3) ); +} + +unsigned long +writefb( unsigned long addr, unsigned long value ) +{ + SavagePtr psav = SAVPTR(gpScrn); + char * videobuffer = (char *) psav->FBBase; + *(unsigned long*)(videobuffer + (addr & ~3)) = value; + return *(volatile unsigned long*)(videobuffer + (addr & ~3) ); +} + +void +writescan( unsigned long scan, unsigned long color ) +{ + SavagePtr psav = SAVPTR(gpScrn); + int i; + char * videobuffer = (char *)psav->FBBase; + videobuffer += scan * gpScrn->displayWidth * gpScrn->bitsPerPixel >> 3; + for( i = gpScrn->displayWidth; --i; ) { + switch( gpScrn->bitsPerPixel ) { + case 8: + *videobuffer++ = color; + break; + case 16: + *(CARD16 *)videobuffer = color; + videobuffer += 2; + break; + case 32: + *(CARD32 *)videobuffer = color; + videobuffer += 4; + break; + } + } +} |