#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "xf86PciInfo.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xf86fbman.h"
#include "miline.h"
#include "servermd.h"
#ifdef XF86DRI
#include "cfb.h"
#include "GL/glxtokens.h"
#endif
#include "mga_bios.h"
#include "mga.h"
#include "mga_reg.h"
#include "mga_map.h"
#include "mga_macros.h"
#ifdef XF86DRI
#include "mga_dri.h"
#endif
#define MGAMoveDWORDS(d,s,c) \
do { \
write_mem_barrier(); \
XAAMoveDWORDS((d),(s),(c)); \
} while (0)
static void MGANAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn,
int srcX, int srcY, int dstX, int dstY,
int w, int h);
static void MGANAME(SubsequentScreenToScreenCopy_FastBlit)(ScrnInfoPtr pScrn,
int srcX, int srcY, int dstX, int dstY,
int w, int h);
static void MGANAME(SetupForScanlineCPUToScreenColorExpandFill)(
ScrnInfoPtr pScrn, int fg,
int bg, int rop, unsigned int planemask);
static void MGANAME(SubsequentScanlineCPUToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft);
static void MGANAME(SubsequentColorExpandScanline)(ScrnInfoPtr pScrn,
int bufno);
static void MGANAME(SubsequentColorExpandScanlineIndirect)(ScrnInfoPtr pScrn,
int bufno);
static void MGANAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
int x, int y, int w, int h);
static void MGANAME(SubsequentSolidFillTrap)(ScrnInfoPtr pScrn, int y, int h,
int left, int dxL, int dyL, int eL,
int right, int dxR, int dyR, int eR);
static void MGANAME(SubsequentSolidHorVertLine) (ScrnInfoPtr pScrn,
int x, int y, int len, int dir);
static void MGANAME(SubsequentSolidTwoPointLine)(ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2, int flags);
static void MGANAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn,
int patx, int paty, int fg, int bg,
int rop, unsigned int planemask);
static void MGANAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn,
int patx, int paty,
int x, int y, int w, int h );
static void MGANAME(SubsequentMono8x8PatternFillRect_Additional)(
ScrnInfoPtr pScrn, int patx, int paty,
int x, int y, int w, int h );
static void MGANAME(SubsequentMono8x8PatternFillTrap)( ScrnInfoPtr pScrn,
int patx, int paty, int y, int h,
int left, int dxL, int dyL, int eL,
int right, int dxR, int dyR, int eR);
static void MGANAME(SetupForScanlineImageWrite)(ScrnInfoPtr pScrn, int rop,
unsigned int planemask,
int transparency_color, int bpp, int depth);
static void MGANAME(SubsequentScanlineImageWriteRect)(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft);
static void MGANAME(SubsequentImageWriteScanline)(ScrnInfoPtr pScrn, int num);
#if PSZ != 24
static void MGANAME(SetupForPlanarScreenToScreenColorExpandFill)(
ScrnInfoPtr pScrn, int fg, int bg, int rop,
unsigned int planemask);
static void MGANAME(SubsequentPlanarScreenToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int srcx, int srcy, int skipleft);
#endif
static void MGANAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask);
static void MGANAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int srcx, int srcy, int skipleft);
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
static void MGANAME(SetupForDashedLine)(ScrnInfoPtr pScrn, int fg, int bg,
int rop, unsigned int planemask, int length,
unsigned char *pattern);
static void MGANAME(SubsequentDashedTwoPointLine)(ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2,
int flags, int phase);
#endif
void MGANAME(RestoreAccelState)(ScrnInfoPtr pScrn);
#if PSZ == 8
void Mga16RestoreAccelState(ScrnInfoPtr pScrn);
void Mga24RestoreAccelState(ScrnInfoPtr pScrn);
void Mga32RestoreAccelState(ScrnInfoPtr pScrn);
#endif
#ifdef XF86DRI
void MGANAME(DRIInitBuffers)(WindowPtr pWin,
RegionPtr prgn, CARD32 index);
void MGANAME(DRIMoveBuffers)(WindowPtr pParent, DDXPointRec ptOldOrg,
RegionPtr prgnSrc, CARD32 index);
#endif
extern void MGASetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2);
extern void MGADisableClipping(ScrnInfoPtr pScrn);
extern void MGAFillSolidRectsDMA(ScrnInfoPtr pScrn, int fg, int rop,
unsigned int planemask, int nBox, BoxPtr pBox);
extern void MGAFillSolidSpansDMA(ScrnInfoPtr pScrn, int fg, int rop,
unsigned int planemask, int n, DDXPointPtr ppt,
int *pwidth, int fSorted);
extern void MGAFillMono8x8PatternRectsTwoPass(ScrnInfoPtr pScrn, int fg, int bg,
int rop, unsigned int planemask, int nBox,
BoxPtr pBox, int pattern0, int pattern1,
int xorigin, int yorigin);
extern void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr);
extern void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr);
extern void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr,
int, int, XAACacheInfoPtr);
#ifdef RENDER
extern Bool
MGASetupForCPUToScreenAlphaTexture (
ScrnInfoPtr pScrn,
int op,
CARD16 red,
CARD16 green,
CARD16 blue,
CARD16 alpha,
int alphaType,
CARD8 *alphaPtr,
int alphaPitch,
int width,
int height,
int flags
);
extern Bool
MGASetupForCPUToScreenAlphaTextureFaked (
ScrnInfoPtr pScrn,
int op,
CARD16 red,
CARD16 green,
CARD16 blue,
CARD16 alpha,
int alphaType,
CARD8 *alphaPtr,
int alphaPitch,
int width,
int height,
int flags
);
extern Bool
MGASetupForCPUToScreenTexture (
ScrnInfoPtr pScrn,
int op,
int texType,
CARD8 *texPtr,
int texPitch,
int width,
int height,
int flags
);
extern void
MGASubsequentCPUToScreenTexture (
ScrnInfoPtr pScrn,
int dstx,
int dsty,
int srcx,
int srcy,
int width,
int height
);
extern CARD32 MGAAlphaTextureFormats[2];
extern CARD32 MGATextureFormats[2];
#if PSZ == 8
#include "mipict.h"
#include "dixstruct.h"
CARD32 MGAAlphaTextureFormats[2] = {PICT_a8, 0};
CARD32 MGATextureFormats[2] = {PICT_a8r8g8b8, 0};
static void
RemoveLinear (FBLinearPtr linear)
{
MGAPtr pMga = (MGAPtr)(linear->devPrivate.ptr);
pMga->LinearScratch = NULL;
}
static void
RenderCallback (ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
if((currentTime.milliseconds > pMga->RenderTime) && pMga->LinearScratch) {
xf86FreeOffscreenLinear(pMga->LinearScratch);
pMga->LinearScratch = NULL;
}
if(!pMga->LinearScratch)
pMga->RenderCallback = NULL;
}
#define RENDER_DELAY 15000
static Bool
AllocateLinear (
ScrnInfoPtr pScrn,
int sizeNeeded
){
MGAPtr pMga = MGAPTR(pScrn);
pMga->RenderTime = currentTime.milliseconds + RENDER_DELAY;
pMga->RenderCallback = RenderCallback;
if(pMga->LinearScratch) {
if(pMga->LinearScratch->size >= sizeNeeded)
return TRUE;
else {
if(xf86ResizeOffscreenLinear(pMga->LinearScratch, sizeNeeded))
return TRUE;
xf86FreeOffscreenLinear(pMga->LinearScratch);
pMga->LinearScratch = NULL;
}
}
pMga->LinearScratch = xf86AllocateOffscreenLinear(
pScrn->pScreen, sizeNeeded, 32,
NULL, RemoveLinear, pMga);
return (pMga->LinearScratch != NULL);
}
static int
GetPowerOfTwo(int w)
{
int Pof2 = 0;
int i = 12;
while(--i) {
if(w & (1 << i)) {
Pof2 = i;
if(w & ((1 << i) - 1))
Pof2++;
break;
}
}
return Pof2;
}
static int tex_padw, tex_padh;
Bool
MGASetupForCPUToScreenAlphaTextureFaked (
ScrnInfoPtr pScrn,
int op,
CARD16 red,
CARD16 green,
CARD16 blue,
CARD16 alpha,
int alphaType,
CARD8 *alphaPtr,
int alphaPitch,
int width,
int height,
int flags
){
int log2w, log2h, i, pitch, sizeNeeded, offset;
MGAPtr pMga = MGAPTR(pScrn);
if(op != PictOpOver)
return FALSE;
if((width > 2048) || (height > 2048))
return FALSE;
log2w = GetPowerOfTwo(width);
log2h = GetPowerOfTwo(height);
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(pMga->Overlay8Plus24) {
i = 0x00ffffff;
WAITFIFO(1);
SET_PLANEMASK(i);
}
pitch = (width + 15) & ~15;
sizeNeeded = pitch * height;
if(pScrn->bitsPerPixel == 16)
sizeNeeded <<= 1;
if(!AllocateLinear(pScrn, sizeNeeded))
return FALSE;
offset = pMga->LinearScratch->offset << 1;
if(pScrn->bitsPerPixel == 32)
offset <<= 1;
if(pMga->AccelInfoRec->NeedToSync)
MGAStormSync(pScrn);
XAA_888_plus_PICT_a8_to_8888(
(blue >> 8) | (green & 0xff00) | ((red & 0xff00) << 8),
alphaPtr, alphaPitch, (CARD32*)(pMga->FbStart + offset),
pitch, width, height);
tex_padw = 1 << log2w;
tex_padh = 1 << log2h;
WAITFIFO(15);
OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw);
OUTREG(MGAREG_TMR1, 0);
OUTREG(MGAREG_TMR2, 0);
OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh);
OUTREG(MGAREG_TMR4, 0x00000000);
OUTREG(MGAREG_TMR5, 0x00000000);
OUTREG(MGAREG_TMR8, 0x00010000);
OUTREG(MGAREG_TEXORG, offset);
OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) |
((width - 1) << 18));
OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) |
((height - 1) << 18));
OUTREG(MGAREG_TEXCTL, 0x1A000106 | ((pitch & 0x07FF) << 9));
OUTREG(MGAREG_TEXCTL2, 0x00000014);
OUTREG(MGAREG_DWGCTL, 0x000c7076);
OUTREG(MGAREG_TEXFILTER, 0x01e00020);
OUTREG(MGAREG_ALPHACTRL, 0x00000154);
return TRUE;
}
Bool
MGASetupForCPUToScreenAlphaTexture (
ScrnInfoPtr pScrn,
int op,
CARD16 red,
CARD16 green,
CARD16 blue,
CARD16 alpha,
int alphaType,
CARD8 *alphaPtr,
int alphaPitch,
int width,
int height,
int flags
){
int log2w, log2h, i, pitch, sizeNeeded, offset;
CARD8 *dst;
MGAPtr pMga = MGAPTR(pScrn);
if(op != PictOpOver)
return FALSE;
if((width > 2048) || (height > 2048))
return FALSE;
log2w = GetPowerOfTwo(width);
log2h = GetPowerOfTwo(height);
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(pMga->Overlay8Plus24) {
i = 0x00ffffff;
WAITFIFO(1);
SET_PLANEMASK(i);
}
pitch = (width + 15) & ~15;
sizeNeeded = (pitch * height) >> 1;
if(pScrn->bitsPerPixel == 32)
sizeNeeded >>= 1;
if(!AllocateLinear(pScrn, sizeNeeded))
return FALSE;
offset = pMga->LinearScratch->offset << 1;
if(pScrn->bitsPerPixel == 32)
offset <<= 1;
if(pMga->AccelInfoRec->NeedToSync)
MGAStormSync(pScrn);
i = height;
dst = pMga->FbStart + offset;
while(i--) {
memcpy(dst, alphaPtr, width);
dst += pitch;
alphaPtr += alphaPitch;
}
tex_padw = 1 << log2w;
tex_padh = 1 << log2h;
WAITFIFO(12);
OUTREG(MGAREG_DR4, red << 7);
OUTREG(MGAREG_DR6, 0);
OUTREG(MGAREG_DR7, 0);
OUTREG(MGAREG_DR8, green << 7);
OUTREG(MGAREG_DR10, 0);
OUTREG(MGAREG_DR11, 0);
OUTREG(MGAREG_DR12, blue << 7);
OUTREG(MGAREG_DR14, 0);
OUTREG(MGAREG_DR15, 0);
OUTREG(MGAREG_ALPHASTART, alpha << 7);
OUTREG(MGAREG_ALPHAXINC, 0);
OUTREG(MGAREG_ALPHAYINC, 0);
WAITFIFO(15);
OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw);
OUTREG(MGAREG_TMR1, 0);
OUTREG(MGAREG_TMR2, 0);
OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh);
OUTREG(MGAREG_TMR4, 0x00000000);
OUTREG(MGAREG_TMR5, 0x00000000);
OUTREG(MGAREG_TMR8, 0x00010000);
OUTREG(MGAREG_TEXORG, offset);
OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) |
((width - 1) << 18));
OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) |
((height - 1) << 18));
OUTREG(MGAREG_TEXCTL, 0x3A000107 | ((pitch & 0x07FF) << 9));
OUTREG(MGAREG_TEXCTL2, 0x00000014);
OUTREG(MGAREG_DWGCTL, 0x000c7076);
OUTREG(MGAREG_TEXFILTER, 0x01e00020);
OUTREG(MGAREG_ALPHACTRL, 0x02000151);
return TRUE;
}
Bool
MGASetupForCPUToScreenTexture (
ScrnInfoPtr pScrn,
int op,
int texType,
CARD8 *texPtr,
int texPitch,
int width,
int height,
int flags
){
int log2w, log2h, i, pitch, sizeNeeded, offset;
MGAPtr pMga = MGAPTR(pScrn);
if(op != PictOpOver)
return FALSE;
if((width > 2048) || (height > 2048))
return FALSE;
log2w = GetPowerOfTwo(width);
log2h = GetPowerOfTwo(height);
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(pMga->Overlay8Plus24) {
i = 0x00ffffff;
WAITFIFO(1);
SET_PLANEMASK(i);
}
pitch = (width + 15) & ~15;
sizeNeeded = pitch * height;
if(pScrn->bitsPerPixel == 16)
sizeNeeded <<= 1;
if(!AllocateLinear(pScrn, sizeNeeded))
return FALSE;
offset = pMga->LinearScratch->offset << 1;
if(pScrn->bitsPerPixel == 32)
offset <<= 1;
if(pMga->AccelInfoRec->NeedToSync)
MGAStormSync(pScrn);
{
CARD8 *dst = (CARD8*)(pMga->FbStart + offset);
i = height;
while(i--) {
memcpy(dst, texPtr, width << 2);
texPtr += texPitch;
dst += pitch << 2;
}
}
tex_padw = 1 << log2w;
tex_padh = 1 << log2h;
WAITFIFO(15);
OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw);
OUTREG(MGAREG_TMR1, 0);
OUTREG(MGAREG_TMR2, 0);
OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh);
OUTREG(MGAREG_TMR4, 0x00000000);
OUTREG(MGAREG_TMR5, 0x00000000);
OUTREG(MGAREG_TMR8, 0x00010000);
OUTREG(MGAREG_TEXORG, offset);
OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) |
((width - 1) << 18));
OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) |
((height - 1) << 18));
OUTREG(MGAREG_TEXCTL, 0x1A000106 | ((pitch & 0x07FF) << 9));
OUTREG(MGAREG_TEXCTL2, 0x00000014);
OUTREG(MGAREG_DWGCTL, 0x000c7076);
OUTREG(MGAREG_TEXFILTER, 0x01e00020);
OUTREG(MGAREG_ALPHACTRL, 0x00000151);
return TRUE;
}
void
MGASubsequentCPUToScreenTexture (
ScrnInfoPtr pScrn,
int dstx,
int dsty,
int srcx,
int srcy,
int width,
int height
){
MGAPtr pMga = MGAPTR(pScrn);
WAITFIFO(4);
OUTREG(MGAREG_TMR6, (srcx << 20) / tex_padw);
OUTREG(MGAREG_TMR7, (srcy << 20) / tex_padh);
OUTREG(MGAREG_FXBNDRY, ((dstx + width) << 16) | (dstx & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dsty << 16) | height);
pMga->AccelInfoRec->NeedToSync = TRUE;
}
#endif
#endif
Bool
MGANAME(AccelInit)(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
MGAPtr pMga = MGAPTR(pScrn);
int maxFastBlitMem, maxlines;
Bool doRender = FALSE;
BoxRec AvailFBArea;
pMga->ScratchBuffer = xalloc(((pScrn->displayWidth * PSZ) + 127) >> 3);
if(!pMga->ScratchBuffer) return FALSE;
pMga->AccelInfoRec = infoPtr = XAACreateInfoRec();
if(!infoPtr) return FALSE;
pMga->RenderTime = 0;
pMga->LinearScratch = 0;
pMga->MaxFastBlitY = 0;
pMga->MaxBlitDWORDS = 0x40000 >> 5;
switch (pMga->Chipset) {
case PCI_CHIP_MGA2064:
pMga->AccelFlags = BLK_OPAQUE_EXPANSION | FASTBLT_BUG;
break;
case PCI_CHIP_MGA2164:
case PCI_CHIP_MGA2164_AGP:
pMga->AccelFlags = BLK_OPAQUE_EXPANSION |
TRANSC_SOLID_FILL |
USE_RECTS_FOR_LINES;
break;
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG550:
if(pMga->SecondCrtc == TRUE) {
pMga->HasFBitBlt = FALSE;
}
pMga->MaxBlitDWORDS = 0x400000 >> 5;
case PCI_CHIP_MGAG200:
case PCI_CHIP_MGAG200_PCI:
doRender = FALSE;
pMga->AccelFlags = TRANSC_SOLID_FILL |
TWO_PASS_COLOR_EXPAND;
#if 1
if((pMga->FbMapSize > 8*1024*1024) && (pScrn->depth == 8))
pMga->AccelFlags |= LARGE_ADDRESSES;
#endif
break;
case PCI_CHIP_MGA1064:
pMga->AccelFlags = 0;
break;
case PCI_CHIP_MGAG100:
case PCI_CHIP_MGAG100_PCI:
default:
pMga->AccelFlags = MGA_NO_PLANEMASK;
break;
}
pMga->AccelFlags |= USE_LINEAR_EXPANSION;
#if PSZ == 24
pMga->AccelFlags |= MGA_NO_PLANEMASK;
#endif
if(pMga->HasSDRAM) {
pMga->Atype = pMga->AtypeNoBLK = MGAAtypeNoBLK;
pMga->AccelFlags &= ~TWO_PASS_COLOR_EXPAND;
} else {
pMga->Atype = MGAAtype;
pMga->AtypeNoBLK = MGAAtypeNoBLK;
}
infoPtr->Flags = PIXMAP_CACHE |
OFFSCREEN_PIXMAPS |
LINEAR_FRAMEBUFFER |
MICROSOFT_ZERO_LINE_BIAS;
infoPtr->Sync = MGAStormSync;
infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
infoPtr->SetupForScreenToScreenCopy =
MGANAME(SetupForScreenToScreenCopy);
infoPtr->SubsequentScreenToScreenCopy =
MGANAME(SubsequentScreenToScreenCopy);
if(pMga->HasFBitBlt) {
infoPtr->FillCacheBltRects = MGAFillCacheBltRects;
infoPtr->FillCacheBltRectsFlags = NO_TRANSPARENCY;
}
infoPtr->SetupForSolidFill = MGANAME(SetupForSolidFill);
infoPtr->SubsequentSolidFillRect = MGANAME(SubsequentSolidFillRect);
infoPtr->SubsequentSolidFillTrap = MGANAME(SubsequentSolidFillTrap);
infoPtr->SetupForSolidLine = infoPtr->SetupForSolidFill;
infoPtr->SubsequentSolidHorVertLine =
MGANAME(SubsequentSolidHorVertLine);
infoPtr->SubsequentSolidTwoPointLine =
MGANAME(SubsequentSolidTwoPointLine);
infoPtr->SetClippingRectangle = MGASetClippingRectangle;
infoPtr->DisableClipping = MGADisableClipping;
infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
HARDWARE_CLIP_DASHED_LINE |
HARDWARE_CLIP_SOLID_FILL |
HARDWARE_CLIP_MONO_8x8_FILL;
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
infoPtr->SetupForDashedLine = MGANAME(SetupForDashedLine);
infoPtr->SubsequentDashedTwoPointLine =
MGANAME(SubsequentDashedTwoPointLine);
infoPtr->DashPatternMaxLength = 128;
#endif
infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS |
HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
HARDWARE_PATTERN_SCREEN_ORIGIN |
BIT_ORDER_IN_BYTE_MSBFIRST;
infoPtr->SetupForMono8x8PatternFill = MGANAME(SetupForMono8x8PatternFill);
infoPtr->SubsequentMono8x8PatternFillRect =
MGANAME(SubsequentMono8x8PatternFillRect);
infoPtr->SubsequentMono8x8PatternFillTrap =
MGANAME(SubsequentMono8x8PatternFillTrap);
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
CPU_TRANSFER_PAD_DWORD |
SCANLINE_PAD_DWORD |
#if X_BYTE_ORDER == X_BIG_ENDIAN
BIT_ORDER_IN_BYTE_MSBFIRST |
#else
BIT_ORDER_IN_BYTE_LSBFIRST |
#endif
LEFT_EDGE_CLIPPING |
LEFT_EDGE_CLIPPING_NEGATIVE_X;
if(pMga->ILOADBase) {
pMga->ColorExpandBase = pMga->ILOADBase;
} else {
pMga->ColorExpandBase = pMga->IOBase;
}
infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
MGANAME(SetupForScanlineCPUToScreenColorExpandFill);
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
MGANAME(SubsequentScanlineCPUToScreenColorExpandFill);
infoPtr->SubsequentColorExpandScanline =
MGANAME(SubsequentColorExpandScanline);
infoPtr->NumScanlineColorExpandBuffers = 1;
infoPtr->ScanlineColorExpandBuffers = &(pMga->ColorExpandBase);
if(pMga->AccelFlags & USE_LINEAR_EXPANSION) {
infoPtr->ScreenToScreenColorExpandFillFlags =
BIT_ORDER_IN_BYTE_LSBFIRST;
infoPtr->SetupForScreenToScreenColorExpandFill =
MGANAME(SetupForScreenToScreenColorExpandFill);
infoPtr->SubsequentScreenToScreenColorExpandFill =
MGANAME(SubsequentScreenToScreenColorExpandFill);
} else {
#if PSZ != 24
infoPtr->SetupForScreenToScreenColorExpandFill =
MGANAME(SetupForPlanarScreenToScreenColorExpandFill);
infoPtr->SubsequentScreenToScreenColorExpandFill =
MGANAME(SubsequentPlanarScreenToScreenColorExpandFill);
infoPtr->CacheColorExpandDensity = PSZ;
infoPtr->CacheMonoStipple = XAACachePlanarMonoStipple;
if(pMga->HasFBitBlt)
infoPtr->ScreenToScreenColorExpandFillFlags = TRANSPARENCY_ONLY;
#endif
}
infoPtr->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD |
SCANLINE_PAD_DWORD |
LEFT_EDGE_CLIPPING |
LEFT_EDGE_CLIPPING_NEGATIVE_X |
NO_TRANSPARENCY |
NO_GXCOPY;
infoPtr->SetupForScanlineImageWrite =
MGANAME(SetupForScanlineImageWrite);
infoPtr->SubsequentScanlineImageWriteRect =
MGANAME(SubsequentScanlineImageWriteRect);
infoPtr->SubsequentImageWriteScanline =
MGANAME(SubsequentImageWriteScanline);
infoPtr->NumScanlineImageWriteBuffers = 1;
infoPtr->ScanlineImageWriteBuffers = &(pMga->ScratchBuffer);
if(pMga->ILOADBase && pMga->UsePCIRetry && infoPtr->SetupForSolidFill) {
infoPtr->FillSolidRects = MGAFillSolidRectsDMA;
infoPtr->FillSolidSpans = MGAFillSolidSpansDMA;
}
if(pMga->AccelFlags & TWO_PASS_COLOR_EXPAND) {
if(infoPtr->SetupForMono8x8PatternFill)
infoPtr->FillMono8x8PatternRects =
MGAFillMono8x8PatternRectsTwoPass;
}
if(infoPtr->SetupForSolidFill) {
infoPtr->ValidatePolyArc = MGAValidatePolyArc;
infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask |
GCLineStyle | GCFillStyle;
infoPtr->ValidatePolyPoint = MGAValidatePolyPoint;
infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
}
if(pMga->AccelFlags & MGA_NO_PLANEMASK) {
infoPtr->ScanlineImageWriteFlags |= NO_PLANEMASK;
infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
infoPtr->ScanlineCPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
infoPtr->SolidFillFlags |= NO_PLANEMASK;
infoPtr->SolidLineFlags |= NO_PLANEMASK;
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
infoPtr->DashedLineFlags |= NO_PLANEMASK;
#endif
infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK;
infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
infoPtr->FillSolidRectsFlags |= NO_PLANEMASK;
infoPtr->FillSolidSpansFlags |= NO_PLANEMASK;
infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK;
infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK;
}
maxFastBlitMem = (pMga->Interleave ? 4096 : 2048) * 1024;
if(pMga->FbMapSize > maxFastBlitMem) {
pMga->MaxFastBlitY = maxFastBlitMem / (pScrn->displayWidth * PSZ / 8);
}
maxlines = (min(pMga->FbUsableSize, 16*1024*1024)) /
(pScrn->displayWidth * PSZ / 8);
#ifdef XF86DRI
if ( pMga->directRenderingEnabled ) {
MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo;
BoxRec MemBox;
int cpp = pScrn->bitsPerPixel / 8;
int widthBytes = pScrn->displayWidth * cpp;
int bufferSize = ((pScrn->virtualY * widthBytes + MGA_BUFFER_ALIGN)
& ~MGA_BUFFER_ALIGN);
int scanlines;
pMGADRIServer->frontOffset = 0;
pMGADRIServer->frontPitch = widthBytes;
pMGADRIServer->textureSize = pMga->FbMapSize - 5 * bufferSize;
if ( pMGADRIServer->textureSize < (int)pMga->FbMapSize / 2 ) {
pMGADRIServer->textureSize = pMga->FbMapSize - 4 * bufferSize;
}
if ( (int)pMga->FbMapSize - maxlines * widthBytes - bufferSize * 2
> pMGADRIServer->textureSize ) {
pMGADRIServer->textureSize = (pMga->FbMapSize -
maxlines * widthBytes -
bufferSize * 2);
}
if ( pMGADRIServer->textureSize < 512 * 1024 ) {
pMGADRIServer->textureOffset = 0;
pMGADRIServer->textureSize = 0;
}
pMGADRIServer->textureOffset = (pMga->FbMapSize -
pMGADRIServer->textureSize +
MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
pMGADRIServer->depthOffset = (pMGADRIServer->textureOffset -
bufferSize +
MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
pMGADRIServer->depthPitch = widthBytes;
pMGADRIServer->backOffset = (pMGADRIServer->depthOffset - bufferSize +
MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
pMGADRIServer->backPitch = widthBytes;
scanlines = pMGADRIServer->backOffset / widthBytes - 1;
if ( scanlines > maxlines ) scanlines = maxlines;
MemBox.x1 = 0;
MemBox.y1 = 0;
MemBox.x2 = pScrn->displayWidth;
MemBox.y2 = scanlines;
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 width, height;
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Memory manager initialized to (%d,%d) (%d,%d)\n",
MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
if ( xf86QueryLargestOffscreenArea( pScreen, &width,
&height, 0, 0, 0 ) ) {
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Largest offscreen area available: %d x %d\n",
width, height );
}
}
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Reserved back buffer at offset 0x%x\n",
pMGADRIServer->backOffset );
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Reserved depth buffer at offset 0x%x\n",
pMGADRIServer->depthOffset );
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Reserved %d kb for textures at offset 0x%x\n",
pMGADRIServer->textureSize/1024,
pMGADRIServer->textureOffset );
}
else
#endif
{
AvailFBArea.x1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
AvailFBArea.y1 = 0;
AvailFBArea.y2 = maxlines;
if (pMga->SecondCrtc)
AvailFBArea.x2 = pScrn->virtualX;
xf86InitFBManager(pScreen, &AvailFBArea);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d lines for offscreen "
"memory.\n",
maxlines - pScrn->virtualY);
}
{
Bool shared_accel = FALSE;
int i;
for(i = 0; i < pScrn->numEntities; i++) {
if(xf86IsEntityShared(pScrn->entityList[i]))
shared_accel = TRUE;
}
if(shared_accel == TRUE)
infoPtr->RestoreAccelState = MGANAME(RestoreAccelState);
}
#ifdef RENDER
if(doRender && ((pScrn->bitsPerPixel == 32) || (pScrn->bitsPerPixel == 16)))
{
if(pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) {
infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE;
infoPtr->SetupForCPUToScreenAlphaTexture =
MGASetupForCPUToScreenAlphaTexture;
} else {
infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE |
XAA_RENDER_NO_SRC_ALPHA;
infoPtr->SetupForCPUToScreenAlphaTexture =
MGASetupForCPUToScreenAlphaTextureFaked;
}
infoPtr->SubsequentCPUToScreenAlphaTexture =
MGASubsequentCPUToScreenTexture;
infoPtr->CPUToScreenAlphaTextureFormats = MGAAlphaTextureFormats;
infoPtr->SetupForCPUToScreenTexture = MGASetupForCPUToScreenTexture;
infoPtr->SubsequentCPUToScreenTexture = MGASubsequentCPUToScreenTexture;
infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE;
infoPtr->CPUToScreenTextureFormats = MGATextureFormats;
}
#endif
return(XAAInit(pScreen, infoPtr));
}
void
MGANAME(InitSolidFillRectFuncs)(MGAPtr pMga)
{
pMga->SetupForSolidFill = MGANAME(SetupForSolidFill);
pMga->SubsequentSolidFillRect = MGANAME(SubsequentSolidFillRect);
}
void
MGANAME(RestoreAccelState)(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
MGAFBLayout *pLayout = &pMga->CurrentLayout;
CARD32 tmp;
MGAStormSync(pScrn);
WAITFIFO(12);
pMga->SrcOrg = 0;
OUTREG(MGAREG_MACCESS, pMga->MAccess);
OUTREG(MGAREG_PITCH, pLayout->displayWidth);
OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
tmp = pMga->PlaneMask;
pMga->PlaneMask = ~tmp;
SET_PLANEMASK(tmp);
tmp = pMga->BgColor;
pMga->BgColor = ~tmp;
SET_BACKGROUND(tmp);
tmp = pMga->FgColor;
pMga->FgColor = ~tmp;
SET_FOREGROUND(tmp);
OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);
OUTREG(MGAREG_DSTORG, pMga->DstOrg);
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT );
#else
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | 0x10000);
#endif
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
OUTREG(MGAREG_YTOP, 0x00000000);
OUTREG(MGAREG_YBOT, 0x007FFFFF);
pMga->AccelFlags &= ~CLIPPER_ON;
}
#if PSZ == 8
CARD32 MGAAtype[16] = {
MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000,
MGADWG_RSTR | 0x00040000, MGADWG_BLK | 0x000c0000,
MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000,
MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000,
MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000,
MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000,
MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000,
MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000
};
CARD32 MGAAtypeNoBLK[16] = {
MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000,
MGADWG_RSTR | 0x00040000, MGADWG_RPL | 0x000c0000,
MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000,
MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000,
MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000,
MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000,
MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000,
MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000
};
Bool
MGAStormAccelInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
switch( pScrn->bitsPerPixel )
{
case 8:
return Mga8AccelInit(pScreen);
case 16:
return Mga16AccelInit(pScreen);
case 24:
return Mga24AccelInit(pScreen);
case 32:
return Mga32AccelInit(pScreen);
}
return FALSE;
}
void
MGAStormSync(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
CHECK_DMA_QUIESCENT(pMga, pScrn);
if (pMga->Chipset != PCI_CHIP_MGA1064)
while(MGAISBUSY());
OUTREG8(MGAREG_CRTC_INDEX, 0);
if(pMga->AccelFlags & CLIPPER_ON) {
pMga->AccelFlags &= ~CLIPPER_ON;
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
}
}
void
MGAStormEngineInit(ScrnInfoPtr pScrn)
{
long maccess = 0;
MGAPtr pMga = MGAPTR(pScrn);
MGAFBLayout *pLayout = &pMga->CurrentLayout;
CARD32 opmode;
CHECK_DMA_QUIESCENT(pMga, pScrn);
if ((pMga->Chipset == PCI_CHIP_MGAG100)
|| (pMga->Chipset == PCI_CHIP_MGAG100_PCI))
maccess = 1 << 14;
opmode = INREG(MGAREG_OPMODE);
switch( pLayout->bitsPerPixel )
{
case 8:
pMga->RestoreAccelState = Mga8RestoreAccelState;
break;
case 16:
maccess |= 1;
if(pLayout->depth == 15)
maccess |= (1 << 31);
Mga16InitSolidFillRectFuncs(pMga);
pMga->RestoreAccelState = Mga16RestoreAccelState;
opmode |= 0x10000;
break;
case 24:
maccess |= 3;
Mga24InitSolidFillRectFuncs(pMga);
pMga->RestoreAccelState = Mga24RestoreAccelState;
opmode |= 0x20000;
break;
case 32:
maccess |= 2;
Mga32InitSolidFillRectFuncs(pMga);
pMga->RestoreAccelState = Mga32RestoreAccelState;
opmode |= 0x20000;
break;
}
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
opmode &= ~0x30000;
#endif
pMga->fifoCount = 0;
while(MGAISBUSY());
if(!pMga->FifoSize) {
pMga->FifoSize = INREG8(MGAREG_FIFOSTATUS);
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%i DWORD fifo\n",
pMga->FifoSize);
}
OUTREG(MGAREG_PITCH, pLayout->displayWidth);
OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
OUTREG(MGAREG_MACCESS, maccess);
pMga->MAccess = maccess;
pMga->PlaneMask = ~0;
if ((pMga->Chipset != PCI_CHIP_MGAG100)
&& (pMga->Chipset != PCI_CHIP_MGAG100_PCI))
OUTREG(MGAREG_PLNWT, pMga->PlaneMask);
pMga->FgColor = 0;
OUTREG(MGAREG_FCOL, pMga->FgColor);
pMga->BgColor = 0;
OUTREG(MGAREG_BCOL, pMga->BgColor);
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | opmode);
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
OUTREG(MGAREG_YTOP, 0x00000000);
OUTREG(MGAREG_YBOT, 0x007FFFFF);
pMga->AccelFlags &= ~CLIPPER_ON;
switch(pMga->Chipset) {
case PCI_CHIP_MGAG550:
case PCI_CHIP_MGAG400:
case PCI_CHIP_MGAG200:
case PCI_CHIP_MGAG200_PCI:
pMga->SrcOrg = 0;
OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);
OUTREG(MGAREG_DSTORG, pMga->DstOrg);
break;
default:
break;
}
xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex);
}
void MGASetClippingRectangle(
ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2
){
MGAPtr pMga = MGAPTR(pScrn);
CHECK_DMA_QUIESCENT(pMga, pScrn);
WAITFIFO(3);
OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1);
OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg);
OUTREG(MGAREG_YBOT, (y2 * pScrn->displayWidth) + pMga->YDstOrg);
pMga->AccelFlags |= CLIPPER_ON;
}
void MGADisableClipping(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
CHECK_DMA_QUIESCENT(pMga, pScrn);
WAITFIFO(3);
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
OUTREG(MGAREG_YTOP, 0x00000000);
OUTREG(MGAREG_YBOT, 0x007FFFFF);
pMga->AccelFlags &= ~CLIPPER_ON;
}
#endif
#define BLIT_LEFT 1
#define BLIT_UP 4
void
MGANAME(SetupForScreenToScreenCopy)(
ScrnInfoPtr pScrn,
int xdir, int ydir,
int rop,
unsigned int planemask,
int trans
){
MGAPtr pMga = MGAPTR(pScrn);
CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO |
MGADWG_BITBLT | MGADWG_BFCOL;
CHECK_DMA_QUIESCENT(pMga, pScrn);
pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
MGANAME(SubsequentScreenToScreenCopy);
pMga->BltScanDirection = 0;
if(ydir == -1) pMga->BltScanDirection |= BLIT_UP;
if(xdir == -1)
pMga->BltScanDirection |= BLIT_LEFT;
else if(pMga->HasFBitBlt && (rop == GXcopy) && !pMga->DrawTransparent)
pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
MGANAME(SubsequentScreenToScreenCopy_FastBlit);
if(pMga->DrawTransparent) {
dwgctl |= MGADWG_TRANSC;
WAITFIFO(2);
SET_FOREGROUND(trans);
trans = ~0;
SET_BACKGROUND(trans);
}
WAITFIFO(4);
OUTREG(MGAREG_DWGCTL, dwgctl);
OUTREG(MGAREG_SGN, pMga->BltScanDirection);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_AR5, ydir * pMga->CurrentLayout.displayWidth);
}
static void
MGANAME(SubsequentScreenToScreenCopy)(
ScrnInfoPtr pScrn,
int srcX, int srcY, int dstX, int dstY, int w, int h
){
int start, end, SrcOrg = 0, DstOrg = 0;
MGAPtr pMga = MGAPTR(pScrn);
if (pMga->AccelFlags & LARGE_ADDRESSES) {
SrcOrg = ((srcY & ~1023) * pMga->CurrentLayout.displayWidth * PSZ) >> 9;
DstOrg = ((dstY & ~1023) * pMga->CurrentLayout.displayWidth * PSZ) >> 9;
dstY &= 1023;
}
if(pMga->BltScanDirection & BLIT_UP) {
srcY += h - 1;
dstY += h - 1;
}
w--;
start = end = XYADDRESS(srcX, srcY);
if(pMga->BltScanDirection & BLIT_LEFT) start += w;
else end += w;
if (pMga->AccelFlags & LARGE_ADDRESSES) {
WAITFIFO(7);
if(DstOrg)
OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg);
if(SrcOrg != pMga->SrcOrg) {
pMga->SrcOrg = SrcOrg;
OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg);
}
if(SrcOrg) {
SrcOrg = (SrcOrg << 9) / PSZ;
end -= SrcOrg;
start -= SrcOrg;
}
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
if(DstOrg)
OUTREG(MGAREG_DSTORG, pMga->DstOrg);
} else {
WAITFIFO(4);
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
}
}
static void
MGANAME(SubsequentScreenToScreenCopy_FastBlit)(
ScrnInfoPtr pScrn,
int srcX, int srcY, int dstX, int dstY, int w, int h
)
{
int start, end;
MGAPtr pMga = MGAPTR(pScrn);
if(pMga->BltScanDirection & BLIT_UP) {
srcY += h - 1;
dstY += h - 1;
}
w--;
start = XYADDRESS(srcX, srcY);
end = start + w;
if(
#if PSZ == 32
!((srcX ^ dstX) & 31)
#elif PSZ == 16
!((srcX ^ dstX) & 63)
#else
!((srcX ^ dstX) & 127)
#endif
) {
if(pMga->MaxFastBlitY) {
if(pMga->BltScanDirection & BLIT_UP) {
if((srcY >= pMga->MaxFastBlitY) ||
(dstY >= pMga->MaxFastBlitY))
goto FASTBLIT_BAILOUT;
} else {
if(((srcY + h) > pMga->MaxFastBlitY) ||
((dstY + h) > pMga->MaxFastBlitY))
goto FASTBLIT_BAILOUT;
}
}
if(pMga->AccelFlags & FASTBLT_BUG) {
int fxright = dstX + w;
#if PSZ == 8
if((dstX & (1 << 6)) && (((fxright >> 6) - (dstX >> 6)) & 7) == 7) {
fxright |= 1 << 6;
#elif PSZ == 16
if((dstX & (1 << 5)) && (((fxright >> 5) - (dstX >> 5)) & 7) == 7) {
fxright |= 1 << 5;
#elif PSZ == 24
if(((dstX * 3) & (1 << 6)) &&
((((fxright * 3 + 2) >> 6) - ((dstX * 3) >> 6)) & 7) == 7) {
fxright = ((fxright * 3 + 2) | (1 << 6)) / 3;
#elif PSZ == 32
if((dstX & (1 << 4)) && (((fxright >> 4) - (dstX >> 4)) & 7) == 7) {
fxright |= 1 << 4;
#endif
WAITFIFO(8);
OUTREG(MGAREG_CXRIGHT, dstX + w);
OUTREG(MGAREG_DWGCTL, 0x040A400C);
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_FXBNDRY, (fxright << 16) | (dstX & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] |
MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL);
OUTREG(MGAREG_CXRIGHT, 0xFFFF);
return;
}
}
WAITFIFO(6);
OUTREG(MGAREG_DWGCTL, 0x040A400C);
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO |
MGADWG_BITBLT | MGADWG_BFCOL);
return;
}
FASTBLIT_BAILOUT:
WAITFIFO(4);
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
}
void
MGANAME(SetupForSolidFill)(
ScrnInfoPtr pScrn,
int color,
int rop,
unsigned int planemask )
{
MGAPtr pMga = MGAPTR(pScrn);
CHECK_DMA_QUIESCENT(pMga, pScrn);
#if PSZ == 24
if(!RGBEQUAL(color))
pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
MGADWG_SGNZERO | MGADWG_SHIFTZERO |
MGADWG_BMONOLEF | pMga->AtypeNoBLK[rop];
else
#endif
pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
MGADWG_SGNZERO | MGADWG_SHIFTZERO |
MGADWG_BMONOLEF | pMga->Atype[rop];
pMga->SolidLineCMD = MGADWG_SOLID | MGADWG_SHIFTZERO | MGADWG_BFCOL |
pMga->AtypeNoBLK[rop];
if(pMga->AccelFlags & TRANSC_SOLID_FILL)
pMga->FilledRectCMD |= MGADWG_TRANSC;
WAITFIFO(3);
SET_FOREGROUND(color);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
}
static void
MGANAME(SubsequentSolidFillRect)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h )
{
MGAPtr pMga = MGAPTR(pScrn);
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
}
static void
MGANAME(SubsequentSolidFillTrap)(ScrnInfoPtr pScrn, int y, int h,
int left, int dxL, int dyL, int eL,
int right, int dxR, int dyR, int eR )
{
MGAPtr pMga = MGAPTR(pScrn);
int sdxl = (dxL < 0);
int ar2 = sdxl? dxL : -dxL;
int sdxr = (dxR < 0);
int ar5 = sdxr? dxR : -dxR;
WAITFIFO(11);
OUTREG(MGAREG_DWGCTL,
pMga->FilledRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO));
OUTREG(MGAREG_AR0, dyL);
OUTREG(MGAREG_AR1, ar2 - eL);
OUTREG(MGAREG_AR2, ar2);
OUTREG(MGAREG_AR4, ar5 - eR);
OUTREG(MGAREG_AR5, ar5);
OUTREG(MGAREG_AR6, dyR);
OUTREG(MGAREG_SGN, (sdxl << 1) | (sdxr << 5));
OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
}
static void
MGANAME(SubsequentSolidHorVertLine) (
ScrnInfoPtr pScrn,
int x, int y,
int len, int dir
){
MGAPtr pMga = MGAPTR(pScrn);
if(dir == DEGREES_0) {
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((x + len) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1);
} else if(pMga->AccelFlags & USE_RECTS_FOR_LINES) {
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | len);
} else {
WAITFIFO(4);
OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | MGADWG_AUTOLINE_OPEN);
OUTREG(MGAREG_XYSTRT, (y << 16) | (x & 0xffff));
OUTREG(MGAREG_XYEND + MGAREG_EXEC, ((y + len) << 16) | (x & 0xffff));
OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
}
}
static void
MGANAME(SubsequentSolidTwoPointLine)(
ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2, int flags
){
MGAPtr pMga = MGAPTR(pScrn);
WAITFIFO(4);
OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD |
((flags & OMIT_LAST) ? MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE));
OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF));
OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF));
OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
}
static void
MGANAME(SetupForMono8x8PatternFill)(
ScrnInfoPtr pScrn,
int patx, int paty,
int fg, int bg,
int rop,
unsigned int planemask )
{
MGAPtr pMga = MGAPTR(pScrn);
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
CHECK_DMA_QUIESCENT(pMga, pScrn);
pMga->PatternRectCMD = MGADWG_TRAP | MGADWG_ARZERO | MGADWG_SGNZERO |
MGADWG_BMONOLEF;
infoRec->SubsequentMono8x8PatternFillRect =
MGANAME(SubsequentMono8x8PatternFillRect);
if(bg == -1) {
#if PSZ == 24
if(!RGBEQUAL(fg))
pMga->PatternRectCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
else
#endif
pMga->PatternRectCMD |= MGADWG_TRANSC | pMga->Atype[rop];
WAITFIFO(5);
} else {
#if PSZ == 24
if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) && RGBEQUAL(fg) && RGBEQUAL(bg))
#else
if(pMga->AccelFlags & BLK_OPAQUE_EXPANSION)
#endif
pMga->PatternRectCMD |= pMga->Atype[rop];
else
pMga->PatternRectCMD |= pMga->AtypeNoBLK[rop];
WAITFIFO(6);
SET_BACKGROUND(bg);
}
SET_FOREGROUND(fg);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD);
OUTREG(MGAREG_PAT0, patx);
OUTREG(MGAREG_PAT1, paty);
}
static void
MGANAME(SubsequentMono8x8PatternFillRect)(
ScrnInfoPtr pScrn,
int patx, int paty,
int x, int y, int w, int h )
{
MGAPtr pMga = MGAPTR(pScrn);
WAITFIFO(3);
OUTREG(MGAREG_SHIFT, (paty << 4) | patx);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
pMga->AccelInfoRec->SubsequentMono8x8PatternFillRect =
MGANAME(SubsequentMono8x8PatternFillRect_Additional);
}
static void
MGANAME(SubsequentMono8x8PatternFillRect_Additional)(
ScrnInfoPtr pScrn,
int patx, int paty,
int x, int y, int w, int h )
{
MGAPtr pMga = MGAPTR(pScrn);
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
}
static void
MGANAME(SubsequentMono8x8PatternFillTrap)(
ScrnInfoPtr pScrn,
int patx, int paty,
int y, int h,
int left, int dxL, int dyL, int eL,
int right, int dxR, int dyR, int eR
){
MGAPtr pMga = MGAPTR(pScrn);
int sdxl = (dxL < 0) ? (1<<1) : 0;
int ar2 = sdxl? dxL : -dxL;
int sdxr = (dxR < 0) ? (1<<5) : 0;
int ar5 = sdxr? dxR : -dxR;
WAITFIFO(12);
OUTREG(MGAREG_SHIFT, (paty << 4) | patx);
OUTREG(MGAREG_DWGCTL,
pMga->PatternRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO));
OUTREG(MGAREG_AR0, dyL);
OUTREG(MGAREG_AR1, ar2 - eL);
OUTREG(MGAREG_AR2, ar2);
OUTREG(MGAREG_AR4, ar5 - eR);
OUTREG(MGAREG_AR5, ar5);
OUTREG(MGAREG_AR6, dyR);
OUTREG(MGAREG_SGN, sdxl | sdxr);
OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD);
}
static void
MGANAME(SetupForScanlineCPUToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int planemask )
{
MGAPtr pMga = MGAPTR(pScrn);
CARD32 mgaCMD = MGADWG_ILOAD | MGADWG_LINEAR | MGADWG_SGNZERO |
MGADWG_SHIFTZERO | MGADWG_BMONOLEF;
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(bg == -1) {
#if PSZ == 24
if(!RGBEQUAL(fg))
mgaCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
else
#endif
mgaCMD |= MGADWG_TRANSC | pMga->Atype[rop];
WAITFIFO(3);
} else {
#if PSZ == 24
if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) &&
RGBEQUAL(fg) && RGBEQUAL(bg))
#else
if(pMga->AccelFlags & BLK_OPAQUE_EXPANSION)
#endif
mgaCMD |= pMga->Atype[rop];
else
mgaCMD |= pMga->AtypeNoBLK[rop];
WAITFIFO(4);
SET_BACKGROUND(bg);
}
SET_FOREGROUND(fg);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_DWGCTL, mgaCMD);
}
static void
MGANAME(SubsequentScanlineCPUToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft
){
MGAPtr pMga = MGAPTR(pScrn);
pMga->AccelFlags |= CLIPPER_ON;
pMga->expandDWORDs = (w + 31) >> 5;
if((pMga->expandDWORDs * h) > pMga->MaxBlitDWORDS) {
pMga->expandHeight = pMga->MaxBlitDWORDS / pMga->expandDWORDs;
pMga->expandRemaining = h / pMga->expandHeight;
if(!(h = h % pMga->expandHeight)) {
pMga->expandRemaining--;
h = pMga->expandHeight;
}
pMga->expandY = y + h;
} else
pMga->expandRemaining = 0;
pMga->expandRows = h;
WAITFIFO(5);
OUTREG(MGAREG_CXBNDRY, ((x + w - 1) << 16) | ((x + skipleft) & 0xFFFF));
w = pMga->expandDWORDs << 5;
OUTREG(MGAREG_AR0, (w * h) - 1);
OUTREG(MGAREG_AR3, 0);
OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
#if defined(__alpha__)
if(1)
#else
if(pMga->expandDWORDs > pMga->FifoSize)
#endif
{
pMga->AccelInfoRec->SubsequentColorExpandScanline =
MGANAME(SubsequentColorExpandScanlineIndirect);
pMga->AccelInfoRec->ScanlineColorExpandBuffers =
(unsigned char**)(&pMga->ScratchBuffer);
} else {
pMga->AccelInfoRec->SubsequentColorExpandScanline =
MGANAME(SubsequentColorExpandScanline);
pMga->AccelInfoRec->ScanlineColorExpandBuffers =
(unsigned char**)(&pMga->ColorExpandBase);
WAITFIFO(pMga->expandDWORDs);
}
}
static void
MGANAME(SubsequentColorExpandScanlineIndirect)(
ScrnInfoPtr pScrn,
int bufno
){
MGAPtr pMga = MGAPTR(pScrn);
int dwords = pMga->expandDWORDs;
CARD32 *src = (CARD32*)(pMga->ScratchBuffer);
while(dwords > pMga->FifoSize) {
WAITFIFO(pMga->FifoSize);
MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize);
src += pMga->FifoSize;
dwords -= pMga->FifoSize;
}
WAITFIFO(dwords);
MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords);
if(!(--pMga->expandRows)) {
if(pMga->expandRemaining) {
WAITFIFO(3);
OUTREG(MGAREG_AR0,((pMga->expandDWORDs<< 5)*pMga->expandHeight)-1);
OUTREG(MGAREG_AR3, 0);
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) |
pMga->expandHeight);
pMga->expandY += pMga->expandHeight;
pMga->expandRows = pMga->expandHeight;
pMga->expandRemaining--;
} else {
DISABLE_CLIP();
}
}
}
static void
MGANAME(SubsequentColorExpandScanline)(
ScrnInfoPtr pScrn,
int bufno
){
MGAPtr pMga = MGAPTR(pScrn);
if(--pMga->expandRows) {
WAITFIFO(pMga->expandDWORDs);
} else if(pMga->expandRemaining) {
WAITFIFO(3);
OUTREG(MGAREG_AR0,((pMga->expandDWORDs<<5)*pMga->expandHeight)-1);
OUTREG(MGAREG_AR3, 0);
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) |
pMga->expandHeight);
pMga->expandY += pMga->expandHeight;
pMga->expandRows = pMga->expandHeight;
pMga->expandRemaining--;
WAITFIFO(pMga->expandDWORDs);
} else {
DISABLE_CLIP();
}
}
static void MGANAME(SetupForScanlineImageWrite)(
ScrnInfoPtr pScrn,
int rop,
unsigned int planemask,
int transparency_color,
int bpp, int depth
){
MGAPtr pMga = MGAPTR(pScrn);
CHECK_DMA_QUIESCENT(pMga, pScrn);
WAITFIFO(3);
OUTREG(MGAREG_AR5, 0);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BFCOL | MGADWG_SHIFTZERO |
MGADWG_SGNZERO | pMga->AtypeNoBLK[rop]);
}
static void MGANAME(SubsequentScanlineImageWriteRect)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft
){
MGAPtr pMga = MGAPTR(pScrn);
pMga->AccelFlags |= CLIPPER_ON;
pMga->expandRows = h;
pMga->expandDWORDs = ((w * PSZ) + 31) >> 5;
WAITFIFO(5);
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000 | ((x + skipleft) & 0xFFFF));
OUTREG(MGAREG_AR0, w - 1);
OUTREG(MGAREG_AR3, 0);
OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
}
static void MGANAME(SubsequentImageWriteScanline)(
ScrnInfoPtr pScrn,
int bufno
){
MGAPtr pMga = MGAPTR(pScrn);
int dwords = pMga->expandDWORDs;
CARD32 *src = (CARD32*)(pMga->ScratchBuffer);
while(dwords > pMga->FifoSize) {
WAITFIFO(pMga->FifoSize);
MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize);
src += pMga->FifoSize;
dwords -= pMga->FifoSize;
}
WAITFIFO(dwords);
MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords);
if(!(--pMga->expandRows)) {
DISABLE_CLIP();
}
}
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
void
MGANAME(SetupForDashedLine)(
ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask,
int length,
unsigned char *pattern
){
MGAPtr pMga = MGAPTR(pScrn);
CARD32 *DashPattern = (CARD32*)pattern;
CARD32 NiceDashPattern = DashPattern[0];
int dwords = (length + 31) >> 5;
CHECK_DMA_QUIESCENT(pMga, pScrn);
pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop];
pMga->StyleLen = length - 1;
if(bg == -1) {
pMga->DashCMD |= MGADWG_TRANSC;
WAITFIFO(dwords + 2);
} else {
WAITFIFO(dwords + 3);
SET_BACKGROUND(bg);
}
SET_PLANEMASK(planemask);
SET_FOREGROUND(fg);
switch(length) {
case 2: NiceDashPattern |= NiceDashPattern << 2;
case 4: NiceDashPattern |= NiceDashPattern << 4;
case 8: NiceDashPattern |= byte_reversed[NiceDashPattern] << 16;
NiceDashPattern |= NiceDashPattern << 8;
pMga->NiceDashCMD = MGADWG_TRAP | MGADWG_ARZERO |
MGADWG_SGNZERO | MGADWG_BMONOLEF;
pMga->AccelFlags |= NICE_DASH_PATTERN;
if(bg == -1) {
#if PSZ == 24
if(!RGBEQUAL(fg))
pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
else
#endif
pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->Atype[rop];
} else {
#if PSZ == 24
if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) &&
RGBEQUAL(fg) && RGBEQUAL(bg))
#else
if(pMga->AccelFlags & BLK_OPAQUE_EXPANSION)
#endif
pMga->NiceDashCMD |= pMga->Atype[rop];
else
pMga->NiceDashCMD |= pMga->AtypeNoBLK[rop];
}
OUTREG(MGAREG_SRC0, NiceDashPattern);
break;
default: pMga->AccelFlags &= ~NICE_DASH_PATTERN;
switch (dwords) {
case 4: OUTREG(MGAREG_SRC3, DashPattern[3]);
case 3: OUTREG(MGAREG_SRC2, DashPattern[2]);
case 2: OUTREG(MGAREG_SRC1, DashPattern[1]);
default: OUTREG(MGAREG_SRC0, DashPattern[0]);
}
}
}
void
MGANAME(SubsequentDashedTwoPointLine)(
ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2,
int flags, int phase
){
MGAPtr pMga = MGAPTR(pScrn);
WAITFIFO(4);
if((pMga->AccelFlags & NICE_DASH_PATTERN) && (y1 == y2)) {
OUTREG(MGAREG_DWGCTL, pMga->NiceDashCMD);
if(x2 < x1) {
if(flags & OMIT_LAST) x2++;
OUTREG(MGAREG_SHIFT, ((-y1 & 0x07) << 4) |
((7 - phase - x1) & 0x07));
OUTREG(MGAREG_FXBNDRY, ((x1 + 1) << 16) | (x2 & 0xffff));
} else {
if(!flags) x2++;
OUTREG(MGAREG_SHIFT, (((1 - y1) & 0x07) << 4) |
((phase - x1) & 0x07));
OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff));
}
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | 1);
} else {
OUTREG(MGAREG_SHIFT, (pMga->StyleLen << 16 ) |
(pMga->StyleLen - phase));
OUTREG(MGAREG_DWGCTL, pMga->DashCMD | ((flags & OMIT_LAST) ?
MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE));
OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF));
OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF));
}
}
#endif
#if PSZ != 24
static void
MGANAME(SetupForPlanarScreenToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int planemask
){
MGAPtr pMga = MGAPTR(pScrn);
CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT |
MGADWG_SGNZERO | MGADWG_BPLAN;
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(bg == -1) {
mgaCMD |= MGADWG_TRANSC;
WAITFIFO(4);
} else {
WAITFIFO(5);
SET_BACKGROUND(bg);
}
SET_FOREGROUND(fg);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_AR5, pScrn->displayWidth);
OUTREG(MGAREG_DWGCTL, mgaCMD);
}
static void
MGANAME(SubsequentPlanarScreenToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int srcx, int srcy,
int skipleft
){
MGAPtr pMga = MGAPTR(pScrn);
int start, end;
w--;
start = XYADDRESS(srcx, srcy) + skipleft;
end = start + w;
WAITFIFO(4);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
}
#endif
static void
MGANAME(SetupForScreenToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int planemask
){
MGAPtr pMga = MGAPTR(pScrn);
CARD32 mgaCMD = MGADWG_BITBLT | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(bg == -1) {
#if PSZ == 24
if(!RGBEQUAL(fg))
mgaCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
else
#endif
mgaCMD |= MGADWG_TRANSC | pMga->Atype[rop];
WAITFIFO(4);
} else {
#if PSZ == 24
if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) &&
RGBEQUAL(fg) && RGBEQUAL(bg))
#else
if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION))
#endif
mgaCMD |= pMga->Atype[rop];
else
mgaCMD |= pMga->AtypeNoBLK[rop];
WAITFIFO(5);
SET_BACKGROUND(bg);
}
SET_FOREGROUND(fg);
SET_PLANEMASK(planemask);
OUTREG(MGAREG_AR5, pScrn->displayWidth * PSZ);
OUTREG(MGAREG_DWGCTL, mgaCMD);
}
static void
MGANAME(SubsequentScreenToScreenColorExpandFill)(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int srcx, int srcy,
int skipleft
){
MGAPtr pMga = MGAPTR(pScrn);
int pitch = pScrn->displayWidth * PSZ;
int start, end, next, num;
Bool resetDstOrg = FALSE;
if (pMga->AccelFlags & LARGE_ADDRESSES) {
int DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9;
int SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9;
y &= 1023;
srcy &= 1023;
WAITFIFO(2);
if(DstOrg) {
OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg);
resetDstOrg = TRUE;
}
if(SrcOrg != pMga->SrcOrg) {
pMga->SrcOrg = SrcOrg;
OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg);
}
}
w--;
start = (XYADDRESS(srcx, srcy) * PSZ) + skipleft;
end = start + w + (pitch * (h - 1));
if(!((start ^ end) & 0xff000000)) {
WAITFIFO(4);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_AR0, start + w);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
} else {
while(h) {
next = (start + 0x00ffffff) & 0xff000000;
if(next <= (start + w)) {
num = next - start - 1;
WAITFIFO(7);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_AR0, start + num);
OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1);
OUTREG(MGAREG_AR3, next);
OUTREG(MGAREG_AR0, start + w );
OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) |
((x + num + 1) & 0xffff));
start += pitch;
h--; y++;
} else {
num = ((next - start - w)/pitch) + 1;
if(num > h) num = h;
WAITFIFO(4);
OUTREG(MGAREG_AR3, start);
OUTREG(MGAREG_AR0, start + w);
OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num);
start += num * pitch;
h -= num; y += num;
}
}
}
if(resetDstOrg) {
WAITFIFO(1);
OUTREG(MGAREG_DSTORG, pMga->DstOrg);
}
}
#if PSZ == 8
void
MGAFillSolidRectsDMA(
ScrnInfoPtr pScrn,
int fg, int rop,
unsigned int planemask,
int nBox,
BoxPtr pBox
){
MGAPtr pMga = MGAPTR(pScrn);
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
CARD32 *base = (CARD32*)pMga->ILOADBase;
CHECK_DMA_QUIESCENT(pMga, pScrn);
SET_SYNC_FLAG(infoRec);
(*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
if(nBox & 1) {
OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC,
(pBox->y1 << 16) | (pBox->y2 - pBox->y1));
nBox--; pBox++;
}
if(!nBox) return;
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL);
while(nBox) {
base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC,
MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC);
base[1] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff);
base[2] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1);
pBox++;
base[3] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff);
base[4] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1);
pBox++;
base += 5; nBox -= 2;
}
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
}
void
MGAFillSolidSpansDMA(
ScrnInfoPtr pScrn,
int fg, int rop,
unsigned int planemask,
int n,
DDXPointPtr ppt,
int *pwidth, int fSorted
){
MGAPtr pMga = MGAPTR(pScrn);
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
CARD32 *base = (CARD32*)pMga->ILOADBase;
CHECK_DMA_QUIESCENT(pMga, pScrn);
SET_SYNC_FLAG(infoRec);
if(infoRec->ClipBox) {
OUTREG(MGAREG_CXBNDRY,
((infoRec->ClipBox->x2 - 1) << 16) | infoRec->ClipBox->x1);
OUTREG(MGAREG_YTOP,
(infoRec->ClipBox->y1 * pScrn->displayWidth) + pMga->YDstOrg);
OUTREG(MGAREG_YBOT,
((infoRec->ClipBox->y2 - 1) * pScrn->displayWidth) + pMga->YDstOrg);
}
(*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
if(n & 1) {
OUTREG(MGAREG_FXBNDRY, ((ppt->x + *pwidth) << 16) | (ppt->x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (ppt->y << 16) | 1);
ppt++; pwidth++; n--;
}
if(n) {
if(n > 838860) n = 838860;
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL);
while(n) {
base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC,
MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC);
base[1] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff);
base[2] = (ppt->y << 16) | 1;
ppt++;
base[3] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff);
base[4] = (ppt->y << 16) | 1;
ppt++;
base += 5; n -= 2;
}
OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
}
if(infoRec->ClipBox) {
OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
OUTREG(MGAREG_YTOP, 0x00000000);
OUTREG(MGAREG_YBOT, 0x007FFFFF);
}
}
void
MGAFillMono8x8PatternRectsTwoPass(
ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask,
int nBoxInit,
BoxPtr pBoxInit,
int pattern0, int pattern1,
int xorg, int yorg
){
MGAPtr pMga = MGAPTR(pScrn);
XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
int nBox, SecondPassColor;
BoxPtr pBox;
CHECK_DMA_QUIESCENT(pMga, pScrn);
if((rop == GXcopy) && (bg != -1)) {
SecondPassColor = bg;
bg = -1;
} else SecondPassColor = -1;
WAITFIFO(1);
OUTREG(MGAREG_SHIFT, (((-yorg) & 0x07) << 4) | ((-xorg) & 0x07));
SECOND_PASS:
nBox = nBoxInit;
pBox = pBoxInit;
(*infoRec->SetupForMono8x8PatternFill)(pScrn, pattern0, pattern1,
fg, bg, rop, planemask);
while(nBox--) {
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC,
(pBox->y1 << 16) | (pBox->y2 - pBox->y1));
pBox++;
}
if(SecondPassColor != -1) {
fg = SecondPassColor;
SecondPassColor = -1;
pattern0 = ~pattern0;
pattern1 = ~pattern1;
goto SECOND_PASS;
}
SET_SYNC_FLAG(infoRec);
}
void
MGAValidatePolyArc(
GCPtr pGC,
unsigned long changes,
DrawablePtr pDraw
){
ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum];
MGAPtr pMga = MGAPTR(pScrn);
Bool fullPlanemask = TRUE;
if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) !=
pMga->AccelInfoRec->FullPlanemask)
{
if(pMga->AccelFlags & MGA_NO_PLANEMASK) return;
fullPlanemask = FALSE;
}
if(!pGC->lineWidth &&
(pGC->fillStyle == FillSolid) &&
(pGC->lineStyle == LineSolid) &&
((pGC->alu != GXcopy) || !fullPlanemask))
{
pGC->ops->PolyArc = MGAPolyArcThinSolid;
}
}
static void
MGAPolyPoint (
DrawablePtr pDraw,
GCPtr pGC,
int mode,
int npt,
xPoint *ppt
){
int numRects = REGION_NUM_RECTS(pGC->pCompositeClip);
XAAInfoRecPtr infoRec;
BoxPtr pbox;
MGAPtr pMga;
int xorg, yorg;
ScrnInfoPtr pScrn;
if(!numRects) return;
if(numRects != 1) {
XAAFallbackOps.PolyPoint(pDraw, pGC, mode, npt, ppt);
return;
}
infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
pScrn = infoRec->pScrn;
pMga = MGAPTR(pScrn);
xorg = pDraw->x;
yorg = pDraw->y;
pbox = REGION_RECTS(pGC->pCompositeClip);
(*infoRec->SetClippingRectangle)(infoRec->pScrn,
pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
(*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
pGC->planemask);
if(mode == CoordModePrevious) {
while(npt--) {
xorg += ppt->x;
yorg += ppt->y;
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((xorg + 1) << 16) | (xorg & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (yorg << 16) | 1);
ppt++;
}
} else {
int x;
while(npt--) {
x = ppt->x + xorg;
WAITFIFO(2);
OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff));
OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((ppt->y + yorg) << 16) | 1);
ppt++;
}
}
(*infoRec->DisableClipping)(infoRec->pScrn);
SET_SYNC_FLAG(infoRec);
}
void
MGAValidatePolyPoint(
GCPtr pGC,
unsigned long changes,
DrawablePtr pDraw
){
ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum];
MGAPtr pMga = MGAPTR(pScrn);
Bool fullPlanemask = TRUE;
pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint;
if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) !=
pMga->AccelInfoRec->FullPlanemask)
{
if(pMga->AccelFlags & MGA_NO_PLANEMASK) return;
fullPlanemask = FALSE;
}
if((pGC->alu != GXcopy) || !fullPlanemask)
pGC->ops->PolyPoint = MGAPolyPoint;
}
void
MGAFillCacheBltRects(
ScrnInfoPtr pScrn,
int rop,
unsigned int planemask,
int nBox,
BoxPtr pBox,
int xorg, int yorg,
XAACacheInfoPtr pCache
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start;
CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
(*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
pCache->trans_color);
while(nBox--) {
y = pBox->y1;
phaseY = (y - yorg) % pCache->orig_h;
if(phaseY < 0) phaseY += pCache->orig_h;
phaseX = (pBox->x1 - xorg) % pCache->orig_w;
if(phaseX < 0) phaseX += pCache->orig_w;
height = pBox->y2 - y;
width = pBox->x2 - pBox->x1;
start = phaseY ? (pCache->orig_h - phaseY) : 0;
if ((rop == GXcopy) && (height >= (pCache->orig_h + start))) {
w = width; skipleft = phaseX; x = pBox->x1;
blit_h = pCache->orig_h;
while(1) {
blit_w = pCache->w - skipleft;
if(blit_w > w) blit_w = w;
(*infoRec->SubsequentScreenToScreenCopy)(pScrn,
pCache->x + skipleft, pCache->y,
x, y + start, blit_w, blit_h);
w -= blit_w;
if(!w) break;
x += blit_w;
skipleft = (skipleft + blit_w) % pCache->orig_w;
}
height -= blit_h;
if(start) {
(*infoRec->SubsequentScreenToScreenCopy)(pScrn,
pBox->x1, y + blit_h, pBox->x1, y, width, start);
height -= start;
y += start;
}
start = blit_h;
while(height) {
if(blit_h > height) blit_h = height;
(*infoRec->SubsequentScreenToScreenCopy)(pScrn,
pBox->x1, y,
pBox->x1, y + start, width, blit_h);
height -= blit_h;
start += blit_h;
blit_h <<= 1;
}
} else {
while(1) {
w = width; skipleft = phaseX; x = pBox->x1;
blit_h = pCache->h - phaseY;
if(blit_h > height) blit_h = height;
while(1) {
blit_w = pCache->w - skipleft;
if(blit_w > w) blit_w = w;
(*infoRec->SubsequentScreenToScreenCopy)(pScrn,
pCache->x + skipleft, pCache->y + phaseY,
x, y, blit_w, blit_h);
w -= blit_w;
if(!w) break;
x += blit_w;
skipleft = (skipleft + blit_w) % pCache->orig_w;
}
height -= blit_h;
if(!height) break;
y += blit_h;
phaseY = (phaseY + blit_h) % pCache->orig_h;
}
}
pBox++;
}
SET_SYNC_FLAG(infoRec);
}
#endif
#ifdef XF86DRI
void
MGANAME(DRIInitBuffers)(WindowPtr pWin, RegionPtr prgn, CARD32 index)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
MGAPtr pMga = MGAPTR(pScrn);
BoxPtr pbox = REGION_RECTS(prgn);
int nbox = REGION_NUM_RECTS(prgn);
CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
MGANAME(SetupForSolidFill)(pScrn, 0, GXcopy, -1);
while (nbox--) {
MGASelectBuffer(pScrn, MGA_BACK);
MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1,
pbox->x2-pbox->x1, pbox->y2-pbox->y1);
MGASelectBuffer(pScrn, MGA_DEPTH);
MGANAME(SubsequentSolidFillRect)(pScrn, pbox->x1, pbox->y1,
pbox->x2-pbox->x1, pbox->y2-pbox->y1);
pbox++;
}
MGASelectBuffer(pScrn, MGA_FRONT);
pMga->AccelInfoRec->NeedToSync = TRUE;
}
void
MGANAME(DRIMoveBuffers)(WindowPtr pParent, DDXPointRec ptOldOrg,
RegionPtr prgnSrc, CARD32 index)
{
ScreenPtr pScreen = pParent->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
MGAPtr pMga = MGAPTR(pScrn);
int nbox;
BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
DDXPointPtr pptTmp, pptNew1, pptNew2;
int xdir, ydir;
int dx, dy;
DDXPointPtr pptSrc;
int screenwidth = pScrn->virtualX;
int screenheight = pScrn->virtualY;
CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
pbox = REGION_RECTS(prgnSrc);
nbox = REGION_NUM_RECTS(prgnSrc);
pboxNew1 = 0;
pptNew1 = 0;
pboxNew2 = 0;
pboxNew2 = 0;
pptSrc = &ptOldOrg;
dx = pParent->drawable.x - ptOldOrg.x;
dy = pParent->drawable.y - ptOldOrg.y;
if (dy>0) {
ydir = -1;
if (nbox>1) {
pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
if (!pboxNew1) return;
pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
if (!pptNew1) {
DEALLOCATE_LOCAL(pboxNew1);
return;
}
pboxBase = pboxNext = pbox+nbox-1;
while (pboxBase >= pbox) {
while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
pboxNext--;
pboxTmp = pboxNext+1;
pptTmp = pptSrc + (pboxTmp - pbox);
while (pboxTmp <= pboxBase) {
*pboxNew1++ = *pboxTmp++;
*pptNew1++ = *pptTmp++;
}
pboxBase = pboxNext;
}
pboxNew1 -= nbox;
pbox = pboxNew1;
pptNew1 -= nbox;
pptSrc = pptNew1;
}
} else {
ydir = 1;
}
if (dx>0) {
xdir = -1;
if (nbox > 1) {
pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
if (!pboxNew2 || !pptNew2) {
if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
if (pboxNew1) {
DEALLOCATE_LOCAL(pptNew1);
DEALLOCATE_LOCAL(pboxNew1);
}
return;
}
pboxBase = pboxNext = pbox;
while (pboxBase < pbox+nbox) {
while ((pboxNext < pbox+nbox) &&
(pboxNext->y1 == pboxBase->y1))
pboxNext++;
pboxTmp = pboxNext;
pptTmp = pptSrc + (pboxTmp - pbox);
while (pboxTmp != pboxBase) {
*pboxNew2++ = *--pboxTmp;
*pptNew2++ = *--pptTmp;
}
pboxBase = pboxNext;
}
pboxNew2 -= nbox;
pbox = pboxNew2;
pptNew2 -= nbox;
pptSrc = pptNew2;
}
} else {
xdir = 1;
}
MGANAME(SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, -1, -1);
for ( ; nbox-- ; pbox++)
{
int x1 = pbox->x1;
int y1 = pbox->y1;
int destx = x1 + dx;
int desty = y1 + dy;
int w = pbox->x2 - x1 + 1;
int h = pbox->y2 - y1 + 1;
if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
if ( destx + w > screenwidth ) w = screenwidth - destx;
if ( desty + h > screenheight ) h = screenheight - desty;
if ( w <= 0 ) continue;
if ( h <= 0 ) continue;
MGASelectBuffer(pScrn, MGA_BACK);
MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1, y1,
destx,desty, w, h);
MGASelectBuffer(pScrn, MGA_DEPTH);
MGANAME(SubsequentScreenToScreenCopy)(pScrn, x1,y1,
destx,desty, w, h);
}
MGASelectBuffer(pScrn, MGA_FRONT);
if (pboxNew2) {
DEALLOCATE_LOCAL(pptNew2);
DEALLOCATE_LOCAL(pboxNew2);
}
if (pboxNew1) {
DEALLOCATE_LOCAL(pptNew1);
DEALLOCATE_LOCAL(pboxNew1);
}
pMga->AccelInfoRec->NeedToSync = TRUE;
}
#endif