summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Deucher <agd5f@yahoo.com>2006-04-30 17:51:15 +0000
committerAlex Deucher <agd5f@yahoo.com>2006-04-30 17:51:15 +0000
commit6d688c993ec7baf8f00df59764dd3e04bab24e09 (patch)
tree81f74a3b06394f6f42679cb53fe3ecd706a39f11 /src
parentef46fb29088e7cc50c6072d66c6ac1fe5cd398bd (diff)
- Add exa support (solid, copy, UTS)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/savage_accel.c1133
-rw-r--r--src/savage_bci.h5
-rw-r--r--src/savage_driver.c82
-rw-r--r--src/savage_driver.h14
-rw-r--r--src/savage_exa.c481
-rw-r--r--src/savage_image.c204
-rw-r--r--src/savage_video.c163
-rw-r--r--src/savage_xaa.c1022
9 files changed, 1754 insertions, 1353 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3bdb452..8ae8051 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,8 @@ savage_drv_ladir = @moduledir@/drivers
savage_drv_la_SOURCES = \
savage_accel.c \
+ savage_xaa.c \
+ savage_exa.c \
savage_bci.h \
savage_common.h \
savage_cursor.c \
@@ -38,7 +40,6 @@ savage_drv_la_SOURCES = \
savage_driver.h \
savage_drm.h \
savage_i2c.c \
- savage_image.c \
savage_regs.h \
savage_sarea.h \
savage_shadow.c \
diff --git a/src/savage_accel.c b/src/savage_accel.c
index cbeece6..c80dfa0 100644
--- a/src/savage_accel.c
+++ b/src/savage_accel.c
@@ -20,11 +20,6 @@
#include "config.h"
#endif
-#include <X11/Xarch.h>
-#include "xaalocal.h"
-#include "xaarop.h"
-#include "miline.h"
-
#include "savage_driver.h"
#include "savage_regs.h"
#include "savage_bci.h"
@@ -39,182 +34,6 @@ extern int gSavageEntityIndex;
/* 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 int 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);
-
-#if 0
-static void SavageSubsequentSolidTwoPointLine(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int bias);
-#endif
-
-#if 0
-static void SavageSetupForScreenToScreenColorExpand(
- ScrnInfoPtr pScrn,
- int bg,
- int fg,
- int rop,
- unsigned int 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 int 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 int planemask);
-
-static void SavageSubsequentMono8x8PatternFillRect(
- ScrnInfoPtr pScrn,
- int pattern0,
- int pattern1,
- int x,
- int y,
- int w,
- int h);
-
-#if 0
-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);
-#endif
-
-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 );
@@ -1034,7 +853,7 @@ void SavageSetGBD_M7(ScrnInfoPtr pScrn)
else if (pScrn->bitsPerPixel == 16) {
psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* 16 bit */
- ulTmp = ((psav->lDelta / 2) >> 6) << 24;
+ ulTmp = ((psav->lDelta / 2) >> 6) << 24;
if (psav->IsSecondary)
OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP16 | pScrn->fbOffset);
else
@@ -1043,7 +862,7 @@ void SavageSetGBD_M7(ScrnInfoPtr pScrn)
else if (pScrn->bitsPerPixel == 32) {
psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* 32 bit */
- ulTmp = ((psav->lDelta / 4) >> 5) << 24;
+ ulTmp = ((psav->lDelta / 4) >> 5) << 24;
if (psav->IsSecondary)
OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP32 | pScrn->fbOffset);
else
@@ -1289,7 +1108,7 @@ void SavageSetGBD_PM(ScrnInfoPtr pScrn)
/* program the GBD and SBDs */
OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
- | bci_enable | S3_LITTLE_ENDIAN | 0x10000000 | S3_BD64));
+ | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
@@ -1427,7 +1246,7 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn)
/* program the GBD and SBDs */
OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
- | bci_enable | S3_LITTLE_ENDIAN | 0x10000000 | S3_BD64));
+ | bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
@@ -1456,213 +1275,6 @@ 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;
-
- if(xf86IsEntityShared(pScrn->entityList[0]))
- {
- DevUnion* pPriv;
- SavageEntPtr pEnt;
- pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
- gSavageEntityIndex);
- pEnt = pPriv->ptr;
-
- /*if there are more than one devices sharing this entity, we
- have to assign this call back, otherwise the XAA will be
- disabled */
- if(pEnt->HasSecondary)
- xaaptr->RestoreAccelState = SavageRestoreAccelState;
- }
-
- /* ScreenToScreen copies */
-
-#if 1
-
- xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy;
- xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy;
- xaaptr->ScreenToScreenCopyFlags = 0
- | 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
- | BIT_ORDER_IN_BYTE_MSBFIRST
- | ROP_NEEDS_SOURCE
- ;
- 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 0
- 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;
-#if 0
- xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap;
-#endif
-
- xaaptr->SolidBresenhamLineErrorTermBits = 13;
-#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.
- */
#ifdef XF86DRI
if (psav->directRenderingEnabled) {
@@ -1882,52 +1494,7 @@ SavageInitAccel(ScreenPtr pScreen)
psav->cyMemory = 0x7FFF;
}
- MemBox.x1 = 0;
- MemBox.y1 = 0;
- MemBox.x2 = psav->cxMemory;
- MemBox.y2 = psav->cyMemory;
-
- if (!xf86InitFBManager(pScreen, &MemBox)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
- MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
- return FALSE;
- } else {
- int tmp,width, height;
-
- xf86DrvMsg( pScrn->scrnIndex, X_INFO,
- "Memory manager initialized to (%d,%d) (%d,%d)\n",
- MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
- /*
- * because the alignment requirement,the on-screen need more memory
- * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
- * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
- * here,we should reserve some memory for on-screen
- */
- tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
- + psav->cxMemory -1) / (psav->cxMemory);
- if (tmp)
- xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
-
- if (xf86QueryLargestOffscreenArea(pScreen, &width,
- &height, 0, 0, 0 ) ) {
- xf86DrvMsg( pScrn->scrnIndex, X_INFO,
- "Largest offscreen area available: %d x %d\n",
- width, height );
- }
- }
- psav->reserved = 0;
-
- if(tiledBufferSize > bufferSize)
- {
- psav->reserved = xf86AllocateOffscreenLinear(pScreen,
- (tiledBufferSize - bufferSize),1,0,0,0);
-
- }
- if(psav->reserved)
- xf86DrvMsg( pScrn->scrnIndex, X_INFO,
- "Reserved for tiled front buffer at offset 0x%08x ,size:0x%08x\n",
- psav->reserved->offset, psav->reserved->size);
+ psav->EXAendfb = pSAVAGEDRIServer->backOffset & ~SAVAGE_BUFFER_ALIGN;
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Reserved back buffer at offset 0x%x\n",
@@ -1943,7 +1510,6 @@ SavageInitAccel(ScreenPtr pScreen)
else
#endif
{
- int tmp;
/*
* why this code? because BoxRec members are short int
@@ -1952,687 +1518,26 @@ SavageInitAccel(ScreenPtr pScreen)
if (psav->cyMemory > 0x7FFF) {
psav->cyMemory = 0x7FFF;
}
-
- AvailFBArea.x1 = 0;
- AvailFBArea.y1 = 0;
- AvailFBArea.x2 = psav->cxMemory;
- AvailFBArea.y2 = psav->cyMemory;
- xf86InitFBManager(pScreen, &AvailFBArea);
- /*
- * because the alignment requirement,the on-screen need more memory
- * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
- * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
- * here,we should reserver some memory for on-screen
- */
- tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
- + psav->cxMemory -1) / (psav->cxMemory);
- if (tmp)
- xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d lines for offscreen memory.\n",
- psav->cyMemory - pScrn->virtualY );
- }
-
-#if 0
- 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 );
-#endif
-
-
- 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, unsigned 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 = XAAGetCopyROP(*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 = XAAGetCopyROP_PM(*rop);
- }
-
- return ret;
-}
-
-static int
-SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned 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 = XAAGetCopyROP(*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;
+ if (psav->IsPrimary) {
+ psav->EXAendfb = psav->videoRambytes -
+ 4096 - /* hw cursor*/
+ 0x200000;
+ } else {
+ psav->EXAendfb = psav->videoRambytes -
+ 4096 - /* hw cursor*/
+ psav->cobSize - /*COB*/
+ 0x200000;
}
- *rop = XAAGetCopyROP_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_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW;
-
- BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(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,9);
-
-
- BCI_SEND(psav->SavedBciCmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- if (psav->SavedBgColor != 0xffffffff)
- 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 int 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_PBD_NEW | 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( (unsigned int)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,7);
-
- BCI_SEND(psav->SavedBciCmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- 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 int 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 int 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_PBD_NEW | 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,22);
-
- BCI_SEND(psav->SavedBciCmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- 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 != 0xffffffff )
- 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 int 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_PBD_NEW;
-
- 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,9);
- BCI_SEND(psav->SavedBciCmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
- BCI_SEND(psav->SavedFgColor);
- if( psav->SavedBgColor != 0xffffffff )
- 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);
- }
-}
-
-
-#if 0
-static void
-SavageSetupForColor8x8PatternFill(
- ScrnInfoPtr pScrn,
- int patternx,
- int patterny,
- int rop,
- unsigned planemask,
- int trans_col)
-{
- SavagePtr psav = SAVPTR(pScrn);
-
- int cmd;
- 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;
-
- (void) 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));
-}
-#endif
-
-
-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, 7 );
- BCI_SEND(cmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- 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));
-}
-
-#if 0
-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 ) );
-}
-#endif
-
-
-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;
+ if (psav->useEXA)
+ return SavageEXAInit(pScreen);
+ else
+ return SavageXAAInit(pScreen);
}
-
/* Routines for debugging. */
diff --git a/src/savage_bci.h b/src/savage_bci.h
index 4fabcb7..833a55d 100644
--- a/src/savage_bci.h
+++ b/src/savage_bci.h
@@ -107,12 +107,17 @@
#define BCI_BD_TILE_NONE 0x00000000
#define BCI_BD_TILE_16 0x02000000
#define BCI_BD_TILE_32 0x03000000
+#define BCI_BD_TILE_DESTINATION 0x01000000
+
#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF)
#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16))
#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF)
#define BCI_BD_SET_STRIDE(bd, st) ((bd) |= ((st) & 0xFFFF))
#define BCI_SET_REGISTER 0x96000000
+#define BCI_SET_REGISTER_COUNT(count) ((count) << 16)
+#define BCI_BITPLANE_WRITE_MASK 0xD7
+#define BCI_BITPLANE_READ_MASK 0xD8
#define BCI_W_H(w, h) ((((h) << 16) | (w)) & 0x0FFF0FFF)
#define BCI_X_Y(x, y) ((((y) << 16) | (x)) & 0x0FFF0FFF)
diff --git a/src/savage_driver.c b/src/savage_driver.c
index 019e879..8d5646c 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -193,6 +193,7 @@ typedef enum {
OPTION_PCI_BURST
,OPTION_PCI_RETRY
,OPTION_NOACCEL
+ ,OPTION_ACCELMETHOD
,OPTION_LCD_CENTER
,OPTION_LCDCLOCK
,OPTION_MCLK
@@ -226,6 +227,7 @@ typedef enum {
static const OptionInfoRec SavageOptions[] =
{
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
{ OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
@@ -403,6 +405,18 @@ static const char *xaaSymbols[] = {
NULL
};
+static const char *exaSymbols[] = {
+ "exaDriverAlloc",
+ "exaDriverInit",
+ "exaDriverFini",
+ "exaOffscreenAlloc",
+ "exaOffscreenFree",
+ "exaGetPixmapOffset",
+ "exaGetPixmapPitch",
+ "exaGetPixmapSize",
+ NULL
+};
+
static const char *shadowSymbols[] = {
"ShadowFBInit",
NULL
@@ -446,7 +460,9 @@ static pointer SavageSetup(pointer module, pointer opts, int *errmaj,
setupDone = TRUE;
xf86AddDriver(&SAVAGE, module, 0);
LoaderRefSymLists(vgaHWSymbols, fbSymbols, ramdacSymbols,
- xaaSymbols, shadowSymbols, vbeSymbols, vbeOptSymbols,
+ xaaSymbols,
+ exaSymbols,
+ shadowSymbols, vbeSymbols, vbeOptSymbols,
#ifdef XF86DRI
drmSymbols, driSymbols,
#endif
@@ -1154,6 +1170,22 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->NoAccel = TRUE;
}
+ if(!psav->NoAccel) {
+ from = X_DEFAULT;
+ char *strptr;
+ if((strptr = (char *)xf86GetOptValString(psav->Options, OPTION_ACCELMETHOD))) {
+ if(!xf86NameCmp(strptr,"XAA")) {
+ from = X_CONFIG;
+ psav->useEXA = FALSE;
+ } else if(!xf86NameCmp(strptr,"EXA")) {
+ from = X_CONFIG;
+ psav->useEXA = TRUE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n",
+ psav->useEXA ? "EXA" : "XAA");
+ }
+
if ((s = xf86GetOptValString(psav->Options, OPTION_OVERLAY))) {
if (psav->shadowFB) {
@@ -1980,13 +2012,40 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86LoaderReqSymLists(fbSymbols, NULL);
if( !psav->NoAccel ) {
- if( !xf86LoadSubModule(pScrn, "xaa") ) {
- SavageFreeRec(pScrn);
- vbeFree(psav->pVbe);
- psav->pVbe = NULL;
- return FALSE;
+
+ char *modName = NULL;
+ const char **symNames = NULL;
+
+ if (psav->useEXA) {
+ modName = "exa";
+ symNames = exaSymbols;
+ XF86ModReqInfo req;
+ int errmaj, errmin;
+ memset(&req, 0, sizeof(req));
+ req.majorversion = 2;
+ req.minorversion = 0;
+
+ if( !LoadSubModule(pScrn->module, modName,
+ NULL, NULL, NULL, &req, &errmaj, &errmin) ) {
+ LoaderErrorMsg(NULL, modName, errmaj, errmin);
+ SavageFreeRec(pScrn);
+ vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
+ return FALSE;
+ }
+ } else {
+ modName = "xaa";
+ symNames = xaaSymbols;
+ if( !xf86LoadSubModule(pScrn, modName) ) {
+ SavageFreeRec(pScrn);
+ vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
+ return FALSE;
+ }
}
- xf86LoaderReqSymLists(xaaSymbols, NULL );
+
+ xf86LoaderReqSymLists(symNames, NULL );
+
}
if (psav->hwcursor) {
@@ -2806,7 +2865,7 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn)
}
if (psav->IsSecondary)
psav->FBStart = psav->FBBase + 0x1000000;
- else
+ else
psav->FBStart = psav->FBBase;
}
@@ -3188,7 +3247,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
- if( !psav->shadowFB )
+ if( !psav->shadowFB && !psav->useEXA )
SavageDGAInit(pScreen);
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
@@ -3752,6 +3811,11 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
}
#endif
+ if (psav->EXADriverPtr) {
+ exaDriverFini(pScreen);
+ psav->EXADriverPtr = NULL;
+ }
+
if( psav->AccelInfoRec ) {
XAADestroyInfoRec( psav->AccelInfoRec );
psav->AccelInfoRec = NULL;
diff --git a/src/savage_driver.h b/src/savage_driver.h
index 31a930a..d571771 100644
--- a/src/savage_driver.h
+++ b/src/savage_driver.h
@@ -24,6 +24,7 @@
#include "xf86cmap.h"
#include "vbe.h"
#include "xaa.h"
+#include "exa.h"
#include "xf86xv.h"
#include "savage_regs.h"
@@ -345,6 +346,15 @@ typedef struct _Savage {
int ShadowPitch;
void (*PointerMoved)(int index, int x, int y);
+ /* support for EXA */
+ ExaDriverPtr EXADriverPtr;
+ Bool useEXA;
+ unsigned long EXAendfb;
+ unsigned long pbd_offset;
+ unsigned long sbd_offset;
+ unsigned long pbd_high;
+ unsigned long sbd_high;
+
/* Support for XAA acceleration */
XAAInfoRecPtr AccelInfoRec;
xRectangle Rect;
@@ -534,6 +544,10 @@ void SavageSetGBD(ScrnInfoPtr);
void SavageAccelSync(ScrnInfoPtr);
/*int SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);*/
+/* XAA and EXA */
+Bool SavageXAAInit(ScreenPtr);
+Bool SavageEXAInit(ScreenPtr);
+
/* In savage_i2c.c. */
Bool SavageI2CInit(ScrnInfoPtr pScrn);
diff --git a/src/savage_exa.c b/src/savage_exa.c
new file mode 100644
index 0000000..1cb2711
--- /dev/null
+++ b/src/savage_exa.c
@@ -0,0 +1,481 @@
+/*
+ * The exa accel file for the Savage driver.
+ *
+ * Created 2005-2006 by Alex Deucher
+ * Revision:
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "savage_driver.h"
+#include "savage_regs.h"
+#include "savage_bci.h"
+#include "savage_streams.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dri.h"
+#endif
+
+static void
+SavageEXASync(ScreenPtr pScreen, int marker);
+
+static Bool
+SavagePrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg);
+
+static void
+SavageSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
+
+static void
+SavageDoneSolid(PixmapPtr pPixmap);
+
+static Bool
+SavagePrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir,
+ int alu, Pixel planemask);
+
+static void
+SavageCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height);
+
+static void
+SavageDoneCopy(PixmapPtr pDstPixmap);
+
+Bool
+SavageUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch);
+
+#if 0
+Bool
+SavageDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch);
+#endif
+
+#if 0
+#define GXclear 0x00
+#define GXand 0x88
+#define GXandReverse 0x44
+#define GXcopy 0xCC
+#define GXandInverted 0x22
+#define GXnoop 0xAA
+#define GXxor 0x66
+#define GXor 0xEE
+#define GXnor 0x11
+#define GXequiv 0x99
+#define GXinvert 0x55
+#define GXorReverse 0xDD
+#define GXcopyInverted 0x33
+#define GXorInverted 0xBB
+#define GXnand 0x77
+#define GXset 0xFF
+#endif
+
+static int SavageGetCopyROP(int rop) {
+
+ int ALUCopyROP[16] =
+ {
+ 0x00, /*ROP_0 GXclear */
+ 0x88, /*ROP_DSa GXand */
+ 0x44, /*ROP_SDna GXandReverse */
+ 0xCC, /*ROP_S GXcopy */
+ 0x22, /*ROP_DSna GXandInverted */
+ 0xAA, /*ROP_D GXnoop */
+ 0x66, /*ROP_DSx GXxor */
+ 0xEE, /*ROP_DSo GXor */
+ 0x11, /*ROP_DSon GXnor */
+ 0x99, /*ROP_DSxn GXequiv */
+ 0x55, /*ROP_Dn GXinvert*/
+ 0xDD, /*ROP_SDno GXorReverse */
+ 0x33, /*ROP_Sn GXcopyInverted */
+ 0xBB, /*ROP_DSno GXorInverted */
+ 0x77, /*ROP_DSan GXnand */
+ 0xFF, /*ROP_1 GXset */
+ };
+
+ return (ALUCopyROP[rop]);
+
+}
+
+static int SavageGetCopyROP_PM(int rop) {
+
+ int ALUCopyROP_PM[16] =
+ {
+ 0x00, /*ROP_0*/ /* not used */
+ 0x75, /*ROP_DSPnoa*/
+ 0x45, /*ROP_DPSnaon*/
+ 0xCA, /*ROP_DPSDxax*/
+ 0xD5, /*ROP_DPSana*/
+ 0xAA, /*ROP_D*/ /* not used */
+ 0x6A, /*ROP_DPSax*/
+ 0xEA, /*ROP_DPSao*/
+ 0x15, /*ROP_DPSaon*/
+ 0x95, /*ROP_DPSaxn*/
+ 0x55, /*ROP_Dn*/ /* not used */
+ 0xD5, /*ROP_DPSanan*/
+ 0x2E, /*ROP_PSDPxox*/ /* is that correct ? */
+ 0xBA, /*ROP_DPSnao*/
+ 0x75, /*ROP_DSPnoan*/
+ 0xFF, /*ROP_1*/ /* not used */
+ };
+
+ return (ALUCopyROP_PM[rop]);
+
+}
+
+Bool
+SavageEXAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+
+ if (!(psav->EXADriverPtr = exaDriverAlloc())) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate EXADriverRec.\n");
+ return FALSE;
+ }
+
+ /*ErrorF("in SavageEXAinit\n");*/
+
+ psav->EXADriverPtr->exa_major = 2;
+ psav->EXADriverPtr->exa_minor = 0;
+
+ /* use the linear aperture */
+ psav->EXADriverPtr->memoryBase = psav->FBBase + pScrn->fbOffset;
+
+ psav->EXADriverPtr->memorySize = psav->EXAendfb;
+
+
+ if (psav->bTiled) {
+ if (pScrn->bitsPerPixel == 16) {
+ psav->EXADriverPtr->offScreenBase =
+ ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16) * 2048;
+ } else {
+ psav->EXADriverPtr->offScreenBase =
+ ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16) * 2048;
+ }
+ } else {
+ psav->EXADriverPtr->offScreenBase =
+ ((pScrn->virtualY * psav->lDelta + SAVAGE_BUFFER_ALIGN) & ~SAVAGE_BUFFER_ALIGN);
+ }
+
+ if (psav->EXADriverPtr->memorySize > psav->EXADriverPtr->offScreenBase) {
+ psav->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Not enough video RAM for EXA offscreen memory manager.\n");
+ }
+
+ if (psav->bTiled) {
+ psav->EXADriverPtr->pixmapPitchAlign = 128; /* ~127 */
+ } else {
+ psav->EXADriverPtr->pixmapPitchAlign = 32; /* ~31 */
+ }
+
+ if (psav->Chipset == S3_SAVAGE2000 ||
+ psav->Chipset == S3_SUPERSAVAGE) {
+ psav->EXADriverPtr->pixmapOffsetAlign = 128; /* octword */
+ } else {
+ psav->EXADriverPtr->pixmapOffsetAlign = 64; /* qword */
+ }
+
+ /* engine has 12 bit coordinates */
+ psav->EXADriverPtr->maxX = 4095;
+ psav->EXADriverPtr->maxY = 4095;
+
+ /* Sync */
+ psav->EXADriverPtr->WaitMarker = SavageEXASync;
+#if 1
+ /* Solid fill */
+ psav->EXADriverPtr->PrepareSolid = SavagePrepareSolid;
+ psav->EXADriverPtr->Solid = SavageSolid;
+ psav->EXADriverPtr->DoneSolid = SavageDoneSolid;
+
+ /* Copy */
+ psav->EXADriverPtr->PrepareCopy = SavagePrepareCopy;
+ psav->EXADriverPtr->Copy = SavageCopy;
+ psav->EXADriverPtr->DoneCopy = SavageDoneCopy;
+#endif
+ /* Composite not implemented yet */
+ /* savage3d series only have one tmu */
+
+#if 1
+ /* host data blit */
+ psav->EXADriverPtr->UploadToScreen = SavageUploadToScreen;
+#endif
+#if 0
+ psav->EXADriverPtr->accel.DownloadFromScreen = SavageDownloadFromScreen;
+#endif
+
+ if(!exaDriverInit(pScreen, psav->EXADriverPtr)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "exaDriverinit failed.\n");
+ return FALSE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Savage EXA Acceleration enabled.\n");
+ return TRUE;
+ }
+
+}
+static void
+SavageEXASync(ScreenPtr pScreen, int marker)
+{
+ SavagePtr psav = SAVPTR(xf86Screens[pScreen->myNum]);
+ psav->WaitIdleEmpty(psav);
+}
+
+static unsigned int
+SavageSetBD(SavagePtr psav, PixmapPtr pPixmap)
+{
+ unsigned int pixpitch, bd = 0;
+ unsigned int tile16, tile32;
+
+ /* front buffer can be tiled */
+ if (psav->bTiled && exaGetPixmapOffset(pPixmap) == 0) {
+ switch( psav->Chipset ) {
+ case S3_SAVAGE3D:
+ case S3_SAVAGE_MX:
+ case S3_SAVAGE4:
+ tile16 = BCI_BD_TILE_16;
+ tile32 = BCI_BD_TILE_32;
+ break;
+ case S3_TWISTER:
+ case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_SUPERSAVAGE:
+ case S3_SAVAGE2000:
+ default:
+ tile16 = BCI_BD_TILE_DESTINATION;
+ tile32 = BCI_BD_TILE_DESTINATION;
+ break;
+ }
+ } else {
+ tile16 = BCI_BD_TILE_NONE;
+ tile32 = BCI_BD_TILE_NONE;
+ }
+
+ /* HW uses width */
+ pixpitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel >> 3);
+
+ BCI_BD_SET_BPP(bd, pPixmap->drawable.bitsPerPixel);
+ BCI_BD_SET_STRIDE(bd, pixpitch);
+
+ if (pPixmap->drawable.bitsPerPixel == 32)
+ bd |= BCI_BD_BW_DISABLE | tile32;
+ else
+ bd |= BCI_BD_BW_DISABLE | tile16;
+
+ return bd;
+
+}
+
+static Bool
+SavagePrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ int cmd;
+ BCI_GET_PTR;
+
+ /*ErrorF("in preparesolid\n");*/
+
+ cmd = BCI_CMD_RECT
+ | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
+ | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID
+ | BCI_CMD_SEND_COLOR;
+
+ BCI_CMD_SET_ROP( cmd, SavageGetCopyROP(alu) );
+
+ psav->pbd_offset = exaGetPixmapOffset(pPixmap);
+ psav->pbd_high = SavageSetBD(psav, pPixmap);
+
+ psav->SavedBciCmd = cmd;
+ psav->SavedFgColor = fg;
+
+ psav->WaitQueue(psav,6);
+
+ BCI_SEND(BCI_SET_REGISTER
+ | BCI_SET_REGISTER_COUNT(1)
+ | BCI_BITPLANE_WRITE_MASK);
+ BCI_SEND(planemask);
+
+ BCI_SEND(psav->SavedBciCmd);
+ BCI_SEND(psav->pbd_offset);
+ BCI_SEND(psav->pbd_high);
+ BCI_SEND(psav->SavedFgColor);
+
+ return TRUE;
+}
+
+static void
+SavageSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ int w = x2 - x1;
+ int h = y2 - y1;
+ BCI_GET_PTR;
+
+ if( !w || !h )
+ return;
+
+ psav->WaitQueue(psav,2);
+ BCI_SEND(BCI_X_Y(x1, y1));
+ BCI_SEND(BCI_W_H(w, h));
+
+}
+
+static void
+SavageDoneSolid(PixmapPtr pPixmap)
+{
+}
+
+static Bool
+SavagePrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir,
+ int alu, Pixel planemask)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ int cmd;
+ BCI_GET_PTR;
+
+ /*ErrorF("in preparecopy\n");*/
+
+ cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW;
+
+ BCI_CMD_SET_ROP( cmd, SavageGetCopyROP(alu) );
+
+ if (xdir > 0 ) cmd |= BCI_CMD_RECT_XP;
+ if (ydir > 0 ) cmd |= BCI_CMD_RECT_YP;
+
+ psav->sbd_offset = exaGetPixmapOffset(pSrcPixmap);
+ psav->pbd_offset = exaGetPixmapOffset(pDstPixmap);
+
+ psav->sbd_high = SavageSetBD(psav, pSrcPixmap);
+ psav->pbd_high = SavageSetBD(psav, pDstPixmap);
+
+ psav->SavedBciCmd = cmd;
+
+ psav->WaitQueue(psav,7);
+
+ BCI_SEND(BCI_SET_REGISTER
+ | BCI_SET_REGISTER_COUNT(1)
+ | BCI_BITPLANE_WRITE_MASK);
+ BCI_SEND(planemask);
+
+ BCI_SEND(psav->SavedBciCmd);
+ /* src */
+ BCI_SEND(psav->sbd_offset);
+ BCI_SEND(psav->sbd_high);
+ /* dst */
+ BCI_SEND(psav->pbd_offset);
+ BCI_SEND(psav->pbd_high);
+
+ return TRUE;
+}
+
+static void
+SavageCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ BCI_GET_PTR;
+
+ if (!width || !height) return;
+
+ if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) {
+ width --;
+ srcX += width;
+ dstX += width;
+ width ++;
+ }
+ if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) {
+ height --;
+ srcY += height;
+ dstY += height;
+ height ++;
+ }
+
+ psav->WaitQueue(psav,4);
+ BCI_SEND(BCI_X_Y(srcX, srcY));
+ BCI_SEND(BCI_X_Y(dstX, dstY));
+ BCI_SEND(BCI_W_H(width, height));
+
+}
+
+static void
+SavageDoneCopy(PixmapPtr pDstPixmap)
+{
+}
+
+Bool
+SavageUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ BCI_GET_PTR;
+ int i, j, dwords, Bpp;
+ unsigned int cmd;
+ CARD32 * srcp;
+
+ Bpp = pDst->drawable.bitsPerPixel / 8;
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ psav->sbd_offset = exaGetPixmapOffset(pDst);
+ psav->sbd_high = SavageSetBD(psav, pDst);
+
+ cmd = BCI_CMD_RECT
+ | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
+ | BCI_CMD_DEST_SBD_NEW
+ | BCI_CMD_SRC_COLOR; /* host color data */
+
+ BCI_CMD_SET_ROP( cmd, 0xCC ); /* GXcopy */
+
+ /*ErrorF("in UTS\n");*/
+
+ psav->WaitQueue(psav, 5);
+ BCI_SEND(cmd);
+
+ /* dst */
+ BCI_SEND(psav->sbd_offset);
+ BCI_SEND(psav->sbd_high);
+
+ BCI_SEND(BCI_X_Y(x, y));
+ BCI_SEND(BCI_W_H(w, h));
+
+ for (i = 0; i < h; i++) {
+ srcp = (CARD32 *)src;
+ BCI_RESET;
+ for (j = dwords; j > 0; j--) {
+ CARD32 dw = *srcp;
+ BCI_SEND(dw);
+ srcp++;
+ }
+ src += src_pitch;
+ }
+
+ return TRUE;
+}
+
+#if 0
+Bool
+SavageDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
+ unsigned char *src;
+ int src_pitch = exaGetPixmapPitch(pSrc);
+ int bpp = pSrc->drawable.bitsPerPixel;
+
+ /* do the copy */
+ src = pSrc->devPrivate.ptr;
+ src += (x * bpp / 8) + (y * src_pitch);
+ w *= bpp / 8;
+
+ while (h--) {
+ memcpy(dst, src, w);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+ return TRUE;
+}
+
+#endif
diff --git a/src/savage_image.c b/src/savage_image.c
deleted file mode 100644
index 766c810..0000000
--- a/src/savage_image.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_image.c,v 1.4 2001/05/18 23:35:32 dawes Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "savage_driver.h"
-#include "xaarop.h"
-#include "savage_bci.h"
-
-void SavageSubsequentImageWriteRect (
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int skipleft);
-
-void SavageSetupForImageWrite (
- ScrnInfoPtr pScrn,
- int rop,
- unsigned planemask,
- int transparency_color,
- int bpp,
- int depth);
-
-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);
-
-#if 0
-void SavageWriteBitmapScreenToScreenColorExpand(
- ScrnPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- unsigned char * src,
- int srcwidth,
- int srcx,
- int srcy,
- int bg,
- int fg,
- int rop,
- unsigned int planemask
-)
-{
- SavagePtr psav = SAVPTR(pScrn);
- BCI_GET_PTR;
- unsigned int cmd;
- unsigned char * bd_offset;
- unsigned int bd;
-
- cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
- | BCI_CMD_SEND_COLOR
- | BCI_CMD_DEST_GBD | BCI_CMD_SRC_SBD_MONO_NEW;
- cmd |= (bg != -1) ? BCI_CMD_SEND_COLOR : BCI_CMD_SRC_TRANSPARENT;
- cmd |= s3vAlu[rop];
-
- bd |= BCI_BD_BW_DISABLE;
- BCI_BD_SET_BPP(bd, 1);
- BCI_BD_SET_STRIDE(bd, srcwidth);
- bd_offset = srcwidth * srcy + (srcx >> 3) + src;
-
- psav->WaitQueue(psav,10);
- BCI_SEND(cmd);
- BCI_SEND((unsigned int)bd_offset);
- BCI_SEND(bd);
- BCI_SEND(fg);
- BCI_SEND((bg != -1) ? bg : 0);
- BCI_SEND(BCI_X_Y(srcx, srcy));
- BCI_SEND(BCI_X_Y(x, y));
- BCI_SEND(BCI_W_H(w, h));
-}
-#endif
-
-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
-)
-{
- SavagePtr psav = SAVPTR(pScrn);
- BCI_GET_PTR;
- int i, j, count, reset;
- unsigned int cmd;
- CARD32 * srcp;
-
-/* We aren't using planemask at all here... */
-
- if( !srcwidth )
- return;
-
- cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
- | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR
- | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO;
- cmd |= XAAGetCopyROP(rop) << 16;
-
- if( bg == -1 )
- cmd |= BCI_CMD_SRC_TRANSPARENT;
-
- BCI_SEND(cmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
- BCI_SEND(fg);
- if( bg != -1 )
- BCI_SEND(bg);
-
- /* Bitmaps come in in units of DWORDS, LSBFirst. This is exactly */
- /* reversed of what we expect. */
-
- count = (w + 31) / 32;
-/* src += ((srcx & ~31) / 8); */
-
- /* The BCI region is 128k bytes. A screen-sized mono bitmap can */
- /* exceed that. */
-
- reset = 65536 / count;
-
- for (j = 0; j < h; j ++) {
- BCI_SEND(BCI_X_Y(x, y+j));
- BCI_SEND(BCI_W_H(w, 1));
- srcp = (CARD32 *) src;
- for (i = count; i > 0; srcp ++, i --) {
- /* We have to invert the bits in each byte. */
- CARD32 u = *srcp;
- u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4);
- u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2);
- u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1);
- BCI_SEND(u);
- }
- src += srcwidth;
- if( !--reset ) {
- BCI_RESET;
- reset = 65536 / count;
- }
- }
-}
-
-void
-SavageSetupForImageWrite(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned planemask,
- int transparency_color,
- int bpp,
- int depth)
-{
- SavagePtr psav = SAVPTR(pScrn);
- int cmd;
-
- cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
- | BCI_CMD_CLIP_LR
- | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR;
-
- cmd |= XAAGetCopyROP(rop) << 16;
-
- if( transparency_color != -1 )
- cmd |= BCI_CMD_SRC_TRANSPARENT;
-
- psav->SavedBciCmd = cmd;
- psav->SavedBgColor = transparency_color;
-}
-
-
-void SavageSubsequentImageWriteRect
-(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int skipleft)
-{
- SavagePtr psav = SAVPTR(pScrn);
- BCI_GET_PTR;
-
- psav->WaitQueue( psav, 8 );
- BCI_SEND(psav->SavedBciCmd);
-
- BCI_SEND(psav->GlobalBD.bd2.LoPart);
- BCI_SEND(psav->GlobalBD.bd2.HiPart);
-
- BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
- if( psav->SavedBgColor != 0xffffffff )
- BCI_SEND(psav->SavedBgColor);
- BCI_SEND(BCI_X_Y(x, y));
- BCI_SEND(BCI_W_H(w, h));
-}
diff --git a/src/savage_video.c b/src/savage_video.c
index 65f1ff9..f953787 100644
--- a/src/savage_video.c
+++ b/src/savage_video.c
@@ -38,6 +38,7 @@ static int SavagePutImage( ScrnInfoPtr,
DrawablePtr);
static int SavageQueryImageAttributes(ScrnInfoPtr,
int, unsigned short *, unsigned short *, int *, int *);
+static void SavageFreeMemory(ScrnInfoPtr pScrn, void *mem_struct);
void SavageResetVideo(ScrnInfoPtr pScrn);
@@ -206,13 +207,18 @@ typedef struct {
int hue; /* -128 .. 127 */
Bool interpolation; /* on/off */
- FBAreaPtr area;
+ /*FBAreaPtr area;*/
RegionRec clip;
CARD32 colorKey;
CARD32 videoStatus;
Time offTime;
Time freeTime;
int lastKnownPitch;
+
+ int size;
+ void *video_memory;
+ int video_offset;
+
} SavagePortPrivRec, *SavagePortPrivPtr;
@@ -1005,10 +1011,10 @@ SavageStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
if(shutdown) {
/*SavageClipVWindow(pScrn);*/
SavageStreamsOff( pScrn );
- if(pPriv->area) {
- xf86FreeOffscreenArea(pPriv->area);
- pPriv->area = NULL;
- }
+ if (pPriv->video_memory != NULL) {
+ SavageFreeMemory(pScrn, pPriv->video_memory);
+ pPriv->video_memory = NULL;
+ }
pPriv->videoStatus = 0;
} else {
if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
@@ -1266,15 +1272,87 @@ SavageCopyPlanarData(
}
}
-static FBAreaPtr
+static void
+SavageVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr;
+
+ if (pPriv->video_memory == area)
+ pPriv->video_memory = NULL;
+}
+
+static CARD32
SavageAllocateMemory(
ScrnInfoPtr pScrn,
- FBAreaPtr area,
- int numlines
+ void **mem_struct,
+ int size
){
- ScreenPtr pScreen;
- FBAreaPtr new_area;
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ SavagePtr psav = SAVPTR(pScrn);
+ int offset = 0;
+
+ if (psav->useEXA) {
+ ExaOffscreenArea *area = *mem_struct;
+
+ if (area != NULL) {
+ if (area->size >= size)
+ return area->offset;
+
+ exaOffscreenFree(pScrn->pScreen, area);
+ }
+
+ area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, SavageVideoSave,
+ NULL);
+ *mem_struct = area;
+ if (area == NULL)
+ return 0;
+ offset = area->offset;
+ }
+
+ if (!psav->useEXA) {
+ FBLinearPtr linear = *mem_struct;
+ int cpp = pScrn->bitsPerPixel / 8;
+
+ /* XAA allocates in units of pixels at the screen bpp, so adjust size
+ * appropriately.
+ */
+ size = (size + cpp - 1) / cpp;
+
+ if (linear) {
+ if(linear->size >= size)
+ return linear->offset * cpp;
+
+ if(xf86ResizeOffscreenLinear(linear, size))
+ return linear->offset * cpp;
+ xf86FreeOffscreenLinear(linear);
+ }
+
+ linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
+ NULL, NULL, NULL);
+ *mem_struct = linear;
+
+ if (!linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16,
+ PRIORITY_EXTREME);
+
+ if(max_size < size)
+ return 0;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
+ NULL, NULL, NULL);
+ *mem_struct = linear;
+ if (!linear)
+ return 0;
+ }
+ offset = linear->offset * cpp;
+ }
+#if 0
if(area) {
if((area->box.y2 - area->box.y1) >= numlines)
return area;
@@ -1306,6 +1384,29 @@ SavageAllocateMemory(
}
return new_area;
+#endif
+ return offset;
+}
+
+static void
+SavageFreeMemory(
+ ScrnInfoPtr pScrn,
+ void *mem_struct
+){
+ SavagePtr psav = SAVPTR(pScrn);
+
+ if (psav->useEXA) {
+ ExaOffscreenArea *area = mem_struct;
+
+ if (area != NULL)
+ exaOffscreenFree(pScrn->pScreen, area);
+ }
+ if (!psav->useEXA) {
+ FBLinearPtr linear = mem_struct;
+
+ if (linear != NULL)
+ xf86FreeOffscreenLinear(linear);
+ }
}
static void
@@ -1752,7 +1853,7 @@ SavagePutImage(
ScreenPtr pScreen = pScrn->pScreen;
INT32 x1, x2, y1, y2;
unsigned char *dst_start;
- int pitch, new_h, offset, offsetV=0, offsetU=0;
+ int pitch, new_size, offset, offsetV=0, offsetU=0;
int srcPitch, srcPitch2=0, dstPitch;
int top, left, npixels, nlines;
BoxRec dstBox;
@@ -1790,7 +1891,8 @@ SavagePutImage(
pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3;
dstPitch = ((width << 1) + 15) & ~15;
- new_h = ((dstPitch * height) + pitch - 1) / pitch;
+ /*new_h = ((dstPitch * height) + pitch - 1) / pitch;*/
+ new_size = dstPitch * height;
switch(id) {
case FOURCC_Y211: /* Y211 */
@@ -1816,8 +1918,12 @@ SavagePutImage(
break;
}
- if(!(pPriv->area = SavageAllocateMemory(pScrn, pPriv->area, new_h)))
- return BadAlloc;
+/* if(!(pPriv->area = SavageAllocateMemory(pScrn, pPriv->area, new_h)))
+ return BadAlloc;*/
+ pPriv->video_offset = SavageAllocateMemory(pScrn, &pPriv->video_memory,
+ new_size);
+ if (pPriv->video_offset == 0)
+ return BadAlloc;
/* copy data */
top = y1 >> 16;
@@ -1825,8 +1931,8 @@ SavagePutImage(
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
left <<= 1;
- /*offset = ((pPriv->area->box.y1 * pitch)) + (top * dstPitch);*/
- offset = pPriv->area->box.y1 * psav->lDelta;
+ offset = (pPriv->video_offset) + (top * dstPitch);
+ /*offset = pPriv->area->box.y1 * psav->lDelta;*/
dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD));
switch(id) {
@@ -1837,8 +1943,7 @@ SavagePutImage(
offsetU += tmp;
offsetV += tmp;
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
- if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv
- /*&& (!psav->disableCOB)*/) {
+ if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv) {
SavageCopyPlanarDataBCI(
pScrn,
buf + (top * srcPitch) + (left >> 1),
@@ -1938,7 +2043,7 @@ SavageQueryImageAttributes(
/****************** Offscreen stuff ***************/
typedef struct {
- FBAreaPtr area;
+ void *surface_memory;
Bool isOn;
} OffscreenPrivRec, * OffscreenPrivPtr;
@@ -1950,8 +2055,9 @@ SavageAllocateSurface(
unsigned short h,
XF86SurfacePtr surface
){
- FBAreaPtr area;
+ int offset, size;
int pitch, fbpitch, numlines;
+ void *surface_memory = NULL;
OffscreenPrivPtr pPriv;
if((w > 1024) || (h > 1024))
@@ -1961,32 +2067,38 @@ SavageAllocateSurface(
pitch = ((w << 1) + 15) & ~15;
fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3;
numlines = ((pitch * h) + fbpitch - 1) / fbpitch;
+ size = pitch * h;
- if(!(area = SavageAllocateMemory(pScrn, NULL, numlines)))
+ offset = SavageAllocateMemory(pScrn, &surface_memory, size);
+ if (offset == 0)
return BadAlloc;
surface->width = w;
surface->height = h;
- if(!(surface->pitches = xalloc(sizeof(int))))
+ if(!(surface->pitches = xalloc(sizeof(int)))) {
+ SavageFreeMemory(pScrn, surface_memory);
return BadAlloc;
+ }
if(!(surface->offsets = xalloc(sizeof(int)))) {
xfree(surface->pitches);
+ SavageFreeMemory(pScrn, surface_memory);
return BadAlloc;
}
if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
xfree(surface->pitches);
xfree(surface->offsets);
+ SavageFreeMemory(pScrn, surface_memory);
return BadAlloc;
}
- pPriv->area = area;
+ pPriv->surface_memory = surface_memory;
pPriv->isOn = FALSE;
surface->pScrn = pScrn;
surface->id = id;
surface->pitches[0] = pitch;
- surface->offsets[0] = area->box.y1 * fbpitch;
+ surface->offsets[0] = offset; /*area->box.y1 * fbpitch;*/
surface->devPrivate.ptr = (pointer)pPriv;
return Success;
@@ -2014,11 +2126,12 @@ static int
SavageFreeSurface(
XF86SurfacePtr surface
){
+ ScrnInfoPtr pScrn = surface->pScrn;
OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
if(pPriv->isOn)
SavageStopSurface(surface);
- xf86FreeOffscreenArea(pPriv->area);
+ SavageFreeMemory(pScrn, pPriv->surface_memory);
xfree(surface->pitches);
xfree(surface->offsets);
xfree(surface->devPrivate.ptr);
diff --git a/src/savage_xaa.c b/src/savage_xaa.c
new file mode 100644
index 0000000..4565ffd
--- /dev/null
+++ b/src/savage_xaa.c
@@ -0,0 +1,1022 @@
+/*
+ * 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
+ * Modified Feb-2004 by Alex Deucher - integrating DRI support
+ * Modified 2005-2006 by Alex Deucher - adding exa support
+ * Revision:
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <X11/Xarch.h>
+#include "xaalocal.h"
+#include "xaarop.h"
+#include "miline.h"
+#include "savage_driver.h"
+#include "savage_bci.h"
+
+extern int gSavageEntityIndex;
+
+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 int 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 SavageSetupForCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg,
+ int bg,
+ int rop,
+ unsigned int 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 int planemask);
+
+static void SavageSubsequentMono8x8PatternFillRect(
+ 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 );
+
+/* 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
+);
+
+static
+void SavageRestoreAccelState(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ psav->WaitIdleEmpty(psav);
+
+ return;
+}
+
+
+Bool
+SavageXAAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SavagePtr psav = SAVPTR(pScrn);
+ XAAInfoRecPtr xaaptr;
+ BoxRec AvailFBArea;
+ int tmp;
+
+ /* 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())) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate XAAInfoRec.\n");
+ return FALSE;
+ }
+
+ xaaptr->Flags = 0
+ | PIXMAP_CACHE
+ | OFFSCREEN_PIXMAPS
+ | LINEAR_FRAMEBUFFER
+ ;
+
+
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+ DevUnion* pPriv;
+ SavageEntPtr pEnt;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gSavageEntityIndex);
+ pEnt = pPriv->ptr;
+
+ /*if there are more than one devices sharing this entity, we
+ have to assign this call back, otherwise the XAA will be
+ disabled */
+ if(pEnt->HasSecondary)
+ xaaptr->RestoreAccelState = SavageRestoreAccelState;
+ }
+
+ /* 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 = 0
+ | 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
+ | BIT_ORDER_IN_BYTE_MSBFIRST
+ | ROP_NEEDS_SOURCE
+ ;
+ if( psav->Chipset == S3_SAVAGE4 )
+ xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY;
+#endif
+
+ /* Solid lines */
+
+#if 1
+ xaaptr->SolidLineFlags = NO_PLANEMASK;
+ xaaptr->SetupForSolidLine = SavageSetupForSolidFill;
+ xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine;
+#if 0
+ xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap;
+#endif
+
+ xaaptr->SolidBresenhamLineErrorTermBits = 13;
+#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;
+
+
+ /* 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 = psav->cxMemory;
+ AvailFBArea.y2 = psav->cyMemory;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ /*
+ * because the alignment requirement,the on-screen need more memory
+ * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
+ * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
+ * here,we should reserver some memory for on-screen
+ */
+ tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
+ + psav->cxMemory -1) / (psav->cxMemory);
+ if (tmp)
+ xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d lines for offscreen memory.\n",
+ psav->cyMemory - 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, unsigned 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 = XAAGetCopyROP(*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 = XAAGetCopyROP_PM(*rop);
+ }
+
+ return ret;
+}
+
+
+static int
+SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned 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 = XAAGetCopyROP(*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 = XAAGetCopyROP_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_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW;
+
+ BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(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,9);
+
+
+ BCI_SEND(psav->SavedBciCmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ if (psav->SavedBgColor != 0xffffffff)
+ 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 int 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_PBD_NEW | 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( (unsigned int)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,7);
+
+ BCI_SEND(psav->SavedBciCmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ 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));
+}
+
+static void
+SavageSetupForCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg,
+ int bg,
+ int rop,
+ unsigned int 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_PBD_NEW | 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,22);
+
+ BCI_SEND(psav->SavedBciCmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ 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 != 0xffffffff )
+ 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 int 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_PBD_NEW;
+
+ 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,9);
+ BCI_SEND(psav->SavedBciCmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
+ BCI_SEND(psav->SavedFgColor);
+ if( psav->SavedBgColor != 0xffffffff )
+ 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);
+ }
+}
+
+
+#if 0
+static void
+SavageSetupForColor8x8PatternFill(
+ ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int rop,
+ unsigned planemask,
+ int trans_col)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ int cmd;
+ 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;
+
+ (void) 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));
+}
+#endif
+
+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, 7 );
+ BCI_SEND(cmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ 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
+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;
+}
+
+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
+)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ BCI_GET_PTR;
+ int i, j, count, reset;
+ unsigned int cmd;
+ CARD32 * srcp;
+
+/* We aren't using planemask at all here... */
+
+ if( !srcwidth )
+ return;
+
+ cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
+ | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR
+ | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO;
+ cmd |= XAAGetCopyROP(rop) << 16;
+
+ if( bg == -1 )
+ cmd |= BCI_CMD_SRC_TRANSPARENT;
+
+ BCI_SEND(cmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
+ BCI_SEND(fg);
+ if( bg != -1 )
+ BCI_SEND(bg);
+
+ /* Bitmaps come in in units of DWORDS, LSBFirst. This is exactly */
+ /* reversed of what we expect. */
+
+ count = (w + 31) / 32;
+/* src += ((srcx & ~31) / 8); */
+
+ /* The BCI region is 128k bytes. A screen-sized mono bitmap can */
+ /* exceed that. */
+
+ reset = 65536 / count;
+
+ for (j = 0; j < h; j ++) {
+ BCI_SEND(BCI_X_Y(x, y+j));
+ BCI_SEND(BCI_W_H(w, 1));
+ srcp = (CARD32 *) src;
+ for (i = count; i > 0; srcp ++, i --) {
+ /* We have to invert the bits in each byte. */
+ CARD32 u = *srcp;
+ u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4);
+ u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2);
+ u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1);
+ BCI_SEND(u);
+ }
+ src += srcwidth;
+ if( !--reset ) {
+ BCI_RESET;
+ reset = 65536 / count;
+ }
+ }
+}
+
+void
+SavageSetupForImageWrite(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned planemask,
+ int transparency_color,
+ int bpp,
+ int depth)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ int cmd;
+
+ cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
+ | BCI_CMD_CLIP_LR
+ | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR;
+
+ cmd |= XAAGetCopyROP(rop) << 16;
+
+ if( transparency_color != -1 )
+ cmd |= BCI_CMD_SRC_TRANSPARENT;
+
+ psav->SavedBciCmd = cmd;
+ psav->SavedBgColor = transparency_color;
+}
+
+
+void SavageSubsequentImageWriteRect
+(
+ ScrnInfoPtr pScrn,
+ int x,
+ int y,
+ int w,
+ int h,
+ int skipleft)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ BCI_GET_PTR;
+
+ psav->WaitQueue( psav, 8 );
+ BCI_SEND(psav->SavedBciCmd);
+
+ BCI_SEND(psav->GlobalBD.bd2.LoPart);
+ BCI_SEND(psav->GlobalBD.bd2.HiPart);
+
+ BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
+ if( psav->SavedBgColor != 0xffffffff )
+ BCI_SEND(psav->SavedBgColor);
+ BCI_SEND(BCI_X_Y(x, y));
+ BCI_SEND(BCI_W_H(w, h));
+}
+