#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "fb.h"
#include "glint_regs.h"
#include "glint.h"
#include "miline.h"
#include "xaalocal.h"
static void PermediaSync(ScrnInfoPtr pScrn);
static void PermediaSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask);
static void PermediaSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
static void PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color,
int rop, unsigned int planemask);
static void PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn, int x, int y,
int len, int dir);
static void PermediaSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
int x, int y, int dmaj, int dmin, int e,
int len, int octant);
static void PermediaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1,
int y1, int x2, int y2, int w, int h);
static void PermediaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
int ydir, int rop, unsigned int planemask,
int transparency_color);
static void PermediaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2);
static void PermediaDisableClipping(ScrnInfoPtr pScrn);
static void PermediaSetupForScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask);
static void PermediaSubsequentScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn, int x,
int y, int w, int h, int skipleft);
static void PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
static void PermediaWriteBitmap(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 PermediaWritePixmap8bpp(ScrnInfoPtr pScrn, int x, int y, int w,
int h, unsigned char *src, int srcwidth,
int rop, unsigned int planemask,
int transparency_color, int bpp, int depth);
static void PermediaWritePixmap16bpp(ScrnInfoPtr pScrn, int x, int y, int w,
int h, unsigned char *src, int srcwidth,
int rop, unsigned int planemask,
int transparency_color, int bpp, int depth);
static void PermediaWritePixmap32bpp(ScrnInfoPtr pScrn, int x, int y, int w,
int h, unsigned char *src, int srcwidth,
int rop, unsigned int planemask,
int transparency_color, int bpp, int depth);
static void PermediaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int patternx, int patterny,
int fg, int bg, int rop,
unsigned planemask);
static void PermediaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int patternx, int patterny, int x, int y,
int w, int h);
static void PermediaLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
int a, int d);
static void PermediaPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
int mode, int npt, DDXPointPtr pPts);
static void PermediaPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
int nseg, xSegment *pSeg);
void
PermediaInitializeEngine(ScrnInfoPtr pScrn)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode);
GLINT_SLOW_WRITE_REG(0, dXSub);
GLINT_SLOW_WRITE_REG(GWIN_DisableLBUpdate, GLINTWindow);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PMTextureReadMode);
GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TexelLUTMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
GLINT_SLOW_WRITE_REG(0x400, FilterMode);
GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask);
GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase);
switch (pScrn->bitsPerPixel) {
case 8:
GLINT_SLOW_WRITE_REG(0x0, FBReadPixel);
GLINT_SLOW_WRITE_REG(pGlint->pprod, PMTextureMapFormat);
break;
case 16:
GLINT_SLOW_WRITE_REG(0x1, FBReadPixel);
GLINT_SLOW_WRITE_REG(pGlint->pprod | 1<<19, PMTextureMapFormat);
break;
case 32:
GLINT_SLOW_WRITE_REG(0x2, FBReadPixel);
GLINT_SLOW_WRITE_REG(pGlint->pprod | 2<<19, PMTextureMapFormat);
break;
}
pGlint->ROP = 0xFF;
pGlint->ClippingOn = FALSE;
pGlint->startxsub = 0;
pGlint->startxdom = 0;
pGlint->starty = 0;
pGlint->count = 0;
pGlint->dxdom = 0;
pGlint->dy = 1<<16;
GLINT_WAIT(6);
GLINT_WRITE_REG(0, StartXSub);
GLINT_WRITE_REG(0,StartXDom);
GLINT_WRITE_REG(0,StartY);
GLINT_WRITE_REG(0,GLINTCount);
GLINT_WRITE_REG(0,dXDom);
GLINT_WRITE_REG(1<<16,dY);
}
Bool
PermediaAccelInit(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
GLINTPtr pGlint = GLINTPTR(pScrn);
BoxRec AvailFBArea;
pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
if (!infoPtr) return FALSE;
PermediaInitializeEngine(pScrn);
infoPtr->Flags = PIXMAP_CACHE |
LINEAR_FRAMEBUFFER |
OFFSCREEN_PIXMAPS;
infoPtr->Sync = PermediaSync;
infoPtr->SetClippingRectangle = PermediaSetClippingRectangle;
infoPtr->DisableClipping = PermediaDisableClipping;
infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL;
infoPtr->SolidFillFlags = 0;
infoPtr->SetupForSolidFill = PermediaSetupForFillRectSolid;
infoPtr->SubsequentSolidFillRect = PermediaSubsequentFillRectSolid;
infoPtr->SolidLineFlags = 0;
infoPtr->PolySegmentThinSolidFlags = 0;
infoPtr->PolylinesThinSolidFlags = 0;
infoPtr->SetupForSolidLine = PermediaSetupForSolidLine;
infoPtr->SubsequentSolidHorVertLine = PermediaSubsequentHorVertLine;
if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR))
{
infoPtr->SubsequentSolidBresenhamLine =
PermediaSubsequentSolidBresenhamLine;
}
infoPtr->PolySegmentThinSolid = PermediaPolySegmentThinSolidWrapper;
infoPtr->PolylinesThinSolid = PermediaPolylinesThinSolidWrapper;
infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
infoPtr->SetupForScreenToScreenCopy = PermediaSetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy = PermediaSubsequentScreenToScreenCopy;
infoPtr->Mono8x8PatternFillFlags =
HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
HARDWARE_PATTERN_PROGRAMMED_BITS |
HARDWARE_PATTERN_SCREEN_ORIGIN;
infoPtr->SetupForMono8x8PatternFill =
PermediaSetupForMono8x8PatternFill;
infoPtr->SubsequentMono8x8PatternFillRect =
PermediaSubsequentMono8x8PatternFillRect;
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
#if 0
LEFT_EDGE_CLIPPING |
LEFT_EDGE_CLIPPING_NEGATIVE_X |
#endif
BIT_ORDER_IN_BYTE_LSBFIRST;
infoPtr->NumScanlineColorExpandBuffers = 1;
pGlint->ScratchBuffer = xalloc(((pScrn->virtualX+62)/32*4)
+ (pScrn->virtualX
* pScrn->bitsPerPixel / 8));
infoPtr->ScanlineColorExpandBuffers =
pGlint->XAAScanlineColorExpandBuffers;
pGlint->XAAScanlineColorExpandBuffers[0] =
pGlint->IOBase + OutputFIFO + 4;
infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
PermediaSetupForScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
PermediaSubsequentScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentColorExpandScanline =
PermediaSubsequentColorExpandScanline;
infoPtr->ColorExpandRange = pGlint->FIFOSize;
infoPtr->WriteBitmap = PermediaWriteBitmap;
if (pScrn->bitsPerPixel == 8)
infoPtr->WritePixmap = PermediaWritePixmap8bpp;
else
if (pScrn->bitsPerPixel == 16)
infoPtr->WritePixmap = PermediaWritePixmap16bpp;
else
if (pScrn->bitsPerPixel == 32)
infoPtr->WritePixmap = PermediaWritePixmap32bpp;
AvailFBArea.x1 = 0;
AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
AvailFBArea.y2 = pGlint->FbMapSize / (pScrn->displayWidth *
pScrn->bitsPerPixel / 8);
if (AvailFBArea.y2 > 1023) AvailFBArea.y2 = 1023;
xf86InitFBManager(pScreen, &AvailFBArea);
return (XAAInit(pScreen, infoPtr));
}
static void PermediaLoadCoord(
ScrnInfoPtr pScrn,
int x, int y,
int w, int h,
int a, int d
){
GLINTPtr pGlint = GLINTPTR(pScrn);
if (w != pGlint->startxsub) {
GLINT_WRITE_REG(w, StartXSub);
pGlint->startxsub = w;
}
if (x != pGlint->startxdom) {
GLINT_WRITE_REG(x,StartXDom);
pGlint->startxdom = x;
}
if (y != pGlint->starty) {
GLINT_WRITE_REG(y,StartY);
pGlint->starty = y;
}
if (h != pGlint->count) {
GLINT_WRITE_REG(h,GLINTCount);
pGlint->count = h;
}
if (a != pGlint->dxdom) {
GLINT_WRITE_REG(a,dXDom);
pGlint->dxdom = a;
}
if (d != pGlint->dy) {
GLINT_WRITE_REG(d,dY);
pGlint->dy = d;
}
}
static void
PermediaSync(ScrnInfoPtr pScrn)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
CHECKCLIPPING;
while (GLINT_READ_REG(DMACount) != 0);
GLINT_WAIT(2);
GLINT_WRITE_REG(0x400, FilterMode);
GLINT_WRITE_REG(0, GlintSync);
do {
while(GLINT_READ_REG(OutFIFOWords) == 0);
} while (GLINT_READ_REG(OutputFIFO) != Sync_tag);
}
static void
PermediaSetClippingRectangle(
ScrnInfoPtr pScrn,
int x1, int y1,
int x2, int y2
){
GLINTPtr pGlint = GLINTPTR(pScrn);
GLINT_WAIT(3);
GLINT_WRITE_REG (((y1&0x0FFF) << 16) | (x1&0x0FFF), ScissorMinXY);
GLINT_WRITE_REG (((y2&0x0FFF) << 16) | (x2&0x0FFF), ScissorMaxXY);
GLINT_WRITE_REG (1, ScissorMode);
pGlint->ClippingOn = TRUE;
}
static void
PermediaDisableClipping(
ScrnInfoPtr pScrn
){
GLINTPtr pGlint = GLINTPTR(pScrn);
CHECKCLIPPING;
}
static void
PermediaSetupForScreenToScreenCopy(
ScrnInfoPtr pScrn,
int xdir, int ydir, int rop,
unsigned int planemask, int transparency_color
){
GLINTPtr pGlint = GLINTPTR(pScrn);
pGlint->BltScanDirection = 0;
if (ydir == 1) pGlint->BltScanDirection |= YPositive;
GLINT_WAIT(4);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(0, RasterizerMode);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
if ((rop == GXset) || (rop == GXclear)) {
pGlint->FrameBufferReadMode = pGlint->pprod;
} else
if ((rop == GXcopy) || (rop == GXcopyInverted)) {
pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable;
} else {
pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable |
FBRM_DstEnable;
}
LOADROP(rop);
}
static void
PermediaSubsequentScreenToScreenCopy(
ScrnInfoPtr pScrn,
int x1, int y1,
int x2, int y2,
int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
int srcaddr;
int dstaddr;
char align;
int direction;
if (!(pGlint->BltScanDirection & YPositive)) {
y1 = y1 + h - 1;
y2 = y2 + h - 1;
direction = -1<<16;
} else {
direction = 1<<16;
}
if ((w < 32) || (pGlint->ROP != GXcopy)) {
GLINT_WAIT(9);
PermediaLoadCoord(pScrn, x2<<16, y2<<16, (x2+w)<<16, h, 0, direction);
srcaddr = x1;
dstaddr = x2;
GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode);
} else {
GLINT_WAIT(10);
PermediaLoadCoord(pScrn, (x2>>pGlint->BppShift)<<16, y2<<16,
((x2+w+7)>>pGlint->BppShift)<<16, h, 0,
direction);
srcaddr = (x1 & ~pGlint->bppalign);
dstaddr = (x2 & ~pGlint->bppalign);
align = (x2 & pGlint->bppalign) - (x1 & pGlint->bppalign);
GLINT_WRITE_REG(pGlint->FrameBufferReadMode | FBRM_Packed |
(align&7)<<20, FBReadMode);
GLINT_WRITE_REG(x2<<16|(x2+w), PackedDataLimits);
}
srcaddr += y1 * pScrn->displayWidth;
dstaddr += y2 * pScrn->displayWidth;
GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
GLINT_WRITE_REG(PrimitiveTrapezoid, Render);
}
static void
PermediaSetupForFillRectSolid(
ScrnInfoPtr pScrn,
int color, int rop,
unsigned int planemask
){
GLINTPtr pGlint = GLINTPTR(pScrn);
REPLICATE(color);
GLINT_WAIT(6);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(0, RasterizerMode);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_WRITE_REG(color, FBBlockColor);
} else {
GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
GLINT_WRITE_REG(color, ConstantColor);
}
LOADROP(rop);
}
static void
PermediaSubsequentFillRectSolid(
ScrnInfoPtr pScrn,
int x, int y,
int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
int speed = 0;
if (pGlint->ROP == GXcopy) {
GLINT_WAIT(7);
PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
speed = FastFillEnable;
} else {
GLINT_WAIT(9);
GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed | FBRM_DstEnable, FBReadMode);
PermediaLoadCoord(pScrn, (x>>pGlint->BppShift)<<16, y<<16,
((x+w+7)>>pGlint->BppShift)<<16, h, 0, 1<<16);
GLINT_WRITE_REG(x<<16|(x+w), PackedDataLimits);
}
GLINT_WRITE_REG(PrimitiveTrapezoid | speed, Render);
}
static void
PermediaSetupForMono8x8PatternFill(
ScrnInfoPtr pScrn,
int patternx, int patterny,
int fg, int bg, int rop,
unsigned int planemask)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
if (bg == -1) pGlint->FrameBufferReadMode = -1;
else pGlint->FrameBufferReadMode = 0;
pGlint->ForeGroundColor = fg;
pGlint->BackGroundColor = bg;
REPLICATE(pGlint->ForeGroundColor);
REPLICATE(pGlint->BackGroundColor);
GLINT_WAIT(8);
GLINT_WRITE_REG ((patternx & 0x000000ff), AreaStipplePattern0);
GLINT_WRITE_REG ((patternx & 0x0000ff00) >> 8, AreaStipplePattern1);
GLINT_WRITE_REG ((patternx & 0x00ff0000) >> 16, AreaStipplePattern2);
GLINT_WRITE_REG ((patternx & 0xff000000) >> 24, AreaStipplePattern3);
GLINT_WRITE_REG ((patterny & 0x000000ff), AreaStipplePattern4);
GLINT_WRITE_REG ((patterny & 0x0000ff00) >> 8, AreaStipplePattern5);
GLINT_WRITE_REG ((patterny & 0x00ff0000) >> 16, AreaStipplePattern6);
GLINT_WRITE_REG ((patterny & 0xff000000) >> 24, AreaStipplePattern7);
GLINT_WAIT(7);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(0, RasterizerMode);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
}
GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor);
GLINT_WRITE_REG(pGlint->BackGroundColor, Texel0);
LOADROP(rop);
}
static void
PermediaSubsequentMono8x8PatternFillRect(
ScrnInfoPtr pScrn,
int patternx, int patterny,
int x, int y,
int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
GLINT_WAIT(8);
PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
if (pGlint->FrameBufferReadMode != -1) {
GLINT_WRITE_REG(1<<20|patternx<<7|patterny<<12|UNIT_ENABLE,
AreaStippleMode);
GLINT_WRITE_REG(AreaStippleEnable | TextureEnable | PrimitiveTrapezoid,
Render);
} else {
GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode);
GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render);
}
}
static void
PermediaWriteBitmap(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
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
GLINTPtr pGlint = GLINTPTR(pScrn);
unsigned char *srcpntr;
int dwords, height;
register int count;
register CARD32* pattern;
int dobackground = 0;
w += skipleft;
x -= skipleft;
dwords = (w + 31) >> 5;
PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h);
GLINT_WAIT(14);
DO_PLANEMASK(planemask);
LOADROP(rop);
if (bg != -1) dobackground = ForceBackgroundColor;
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
}
pGlint->BackGroundColor = bg;
pGlint->ForeGroundColor = fg;
REPLICATE(fg);
REPLICATE(bg);
if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) {
pGlint->FrameBufferReadMode = FastFillEnable;
GLINT_WRITE_REG(0, RasterizerMode);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_WRITE_REG(fg, FBBlockColor);
} else {
GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
GLINT_WRITE_REG(fg, ConstantColor);
if (dobackground) {
GLINT_WRITE_REG(bg, Texel0);
pGlint->FrameBufferReadMode = TextureEnable;
} else {
pGlint->FrameBufferReadMode = 0;
}
}
PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, Render);
height = h;
srcpntr = src;
while(height--) {
count = dwords >> 3;
pattern = (CARD32*)srcpntr;
while(count--) {
GLINT_WAIT(8);
GLINT_WRITE_REG(*(pattern), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
pattern+=8;
}
count = dwords & 0x07;
GLINT_WAIT(count);
while (count--)
GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
srcpntr += srcwidth;
}
PermediaDisableClipping(pScrn);
SET_SYNC_FLAG(infoRec);
}
static void
PermediaSetupForScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int planemask
){
GLINTPtr pGlint = GLINTPTR(pScrn);
int dobackground = 0;
if (bg != -1) dobackground |= ForceBackgroundColor;
pGlint->BackGroundColor = bg;
pGlint->ForeGroundColor = fg;
REPLICATE(fg);
REPLICATE(bg);
GLINT_WAIT(7);
DO_PLANEMASK(planemask);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable, FBReadMode);
}
if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) {
pGlint->FrameBufferReadMode = FastFillEnable;
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_WRITE_REG(fg, FBBlockColor);
GLINT_WRITE_REG(0,RasterizerMode);
} else {
GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
GLINT_WRITE_REG(fg, ConstantColor);
GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
if (dobackground) {
GLINT_WRITE_REG(bg, Texel0);
pGlint->FrameBufferReadMode = TextureEnable;
} else {
pGlint->FrameBufferReadMode = 0;
}
}
LOADROP(rop);
}
static void
PermediaSubsequentScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft
){
GLINTPtr pGlint = GLINTPTR(pScrn);
pGlint->dwords = ((w + 31) >> 5);
#if 0
PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h);
#endif
pGlint->cpucount = h;
GLINT_WAIT(8);
PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask,
Render);
#if defined(__alpha__)
if (0)
#else
if ((pGlint->dwords*h) < pGlint->FIFOSize)
#endif
{
pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4;
pGlint->ScanlineDirect = 1;
GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO);
GLINT_WAIT(pGlint->dwords*h);
} else {
pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer;
pGlint->ScanlineDirect = 0;
}
pGlint->cpucount--;
}
static void
PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno];
int dwords = pGlint->dwords;
if (!pGlint->ScanlineDirect) {
while(dwords >= pGlint->FIFOSize) {
GLINT_WAIT(pGlint->FIFOSize);
GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, pGlint->FIFOSize - 1);
dwords -= pGlint->FIFOSize - 1;
srcp += pGlint->FIFOSize - 1;
}
if(dwords) {
GLINT_WAIT(dwords + 1);
GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, dwords);
}
}
}
static void
PermediaWritePixmap8bpp(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
unsigned char *src,
int srcwidth,
int rop,
unsigned int planemask,
int transparency_color,
int bpp, int depth
)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
GLINTPtr pGlint = GLINTPTR(pScrn);
int dwords, count;
CARD32* srcp;
unsigned char *srcpbyte;
Bool FastTexLoad = FALSE;
GLINT_WAIT(2);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(0, RasterizerMode);
dwords = (w + 3) >> 2;
if((!(x&3)) && (!(w&3))) FastTexLoad = TRUE;
if((rop != GXcopy) || (planemask != ~0))
FastTexLoad = FALSE;
#if 0
if (rop != GXcopy) {
int skipleft;
if((skipleft = (long)src & 0x03)) {
skipleft /= (bpp>>3);
x -= skipleft;
w += skipleft;
src = (unsigned char*)((long)src & ~0x03);
}
}
#endif
if(FastTexLoad) {
int address;
GLINT_WAIT(1);
GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
PermediaSync(pScrn);
while(h--) {
count = dwords;
address = ((y * pScrn->displayWidth) + x) >> 2;
srcp = (CARD32*)src;
GLINT_WAIT(1);
GLINT_WRITE_REG(address, TextureDownloadOffset);
while(count >= infoRec->ColorExpandRange) {
GLINT_WAIT(infoRec->ColorExpandRange);
GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16)
| (0x11 << 4) | 0x0D, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, infoRec->ColorExpandRange - 1);
count -= infoRec->ColorExpandRange - 1;
address += infoRec->ColorExpandRange - 1;
srcp += infoRec->ColorExpandRange - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, count);
}
src += srcwidth;
y++;
}
GLINT_WAIT(1);
GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
} else {
GLINT_WAIT(10);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
}
PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
LOADROP(rop);
GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
{
while(h--) {
count = w;
srcpbyte = (unsigned char *)src;
while(count >= infoRec->ColorExpandRange) {
GLINT_WAIT(infoRec->ColorExpandRange);
GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
(0x15 << 4) | 0x05, OutputFIFO);
GLINT_MoveBYTE(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(unsigned char *)srcpbyte, infoRec->ColorExpandRange-1);
count -= infoRec->ColorExpandRange - 1;
srcpbyte += infoRec->ColorExpandRange - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
0x05, OutputFIFO);
GLINT_MoveBYTE(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(unsigned char *)srcpbyte, count);
}
src += srcwidth;
}
}
}
SET_SYNC_FLAG(infoRec);
}
static void
PermediaWritePixmap16bpp(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
unsigned char *src,
int srcwidth,
int rop,
unsigned int planemask,
int transparency_color,
int bpp, int depth
)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
GLINTPtr pGlint = GLINTPTR(pScrn);
int dwords, count;
CARD32* srcp;
unsigned short* srcpword;
Bool FastTexLoad;
GLINT_WAIT(2);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(0, RasterizerMode);
FastTexLoad = FALSE;
dwords = (w + 1) >> 1;
if((!(x&1)) && (!(w&1))) FastTexLoad = TRUE;
if((rop != GXcopy) || (planemask != ~0))
FastTexLoad = FALSE;
#if 0
if (rop != GXcopy) {
int skipleft;
if((skipleft = (long)src & 0x03L)) {
skipleft /= (bpp>>3);
x -= skipleft;
w += skipleft;
src = (unsigned char*)((long)src & ~0x03L);
}
}
#endif
if(FastTexLoad) {
int address;
GLINT_WAIT(1);
GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
PermediaSync(pScrn);
while(h--) {
count = dwords;
address = ((y * pScrn->displayWidth) + x) >> 1;
srcp = (CARD32*)src;
GLINT_WAIT(1);
GLINT_WRITE_REG(address, TextureDownloadOffset);
while(count >= infoRec->ColorExpandRange) {
GLINT_WAIT(infoRec->ColorExpandRange);
GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
(0x11 << 4) | 0x0D, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, infoRec->ColorExpandRange - 1);
count -= infoRec->ColorExpandRange - 1;
address += infoRec->ColorExpandRange - 1;
srcp += infoRec->ColorExpandRange - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, count);
}
src += srcwidth;
y++;
}
GLINT_WAIT(1);
GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
} else {
GLINT_WAIT(10);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
}
PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
LOADROP(rop);
GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
{
while(h--) {
count = w;
srcpword = (unsigned short *)src;
while(count >= infoRec->ColorExpandRange) {
GLINT_WAIT(infoRec->ColorExpandRange);
GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
(0x15 << 4) | 0x05, OutputFIFO);
GLINT_MoveWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(unsigned short *)srcpword,infoRec->ColorExpandRange-1);
count -= infoRec->ColorExpandRange - 1;
srcpword += infoRec->ColorExpandRange - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
0x05, OutputFIFO);
GLINT_MoveWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(unsigned short *)srcpword, count);
}
src += srcwidth;
}
}
}
SET_SYNC_FLAG(infoRec);
}
static void
PermediaWritePixmap32bpp(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
unsigned char *src,
int srcwidth,
int rop,
unsigned int planemask,
int transparency_color,
int bpp, int depth
)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
GLINTPtr pGlint = GLINTPTR(pScrn);
int dwords, count;
CARD32* srcp;
Bool FastTexLoad;
GLINT_WAIT(3);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(0, RasterizerMode);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
}
FastTexLoad = TRUE;
dwords = w;
if((rop != GXcopy) || (planemask != ~0))
FastTexLoad = FALSE;
#if 0
if (!FastTexLoad) {
int skipleft;
if((skipleft = (long)src & 0x03L)) {
skipleft /= (bpp>>3);
x -= skipleft;
w += skipleft;
src = (unsigned char*)((long)src & ~0x03L);
}
}
#endif
if(FastTexLoad) {
int address;
GLINT_WAIT(1);
GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
PermediaSync(pScrn);
while(h--) {
count = dwords;
address = (y * pScrn->displayWidth) + x;
srcp = (CARD32*)src;
GLINT_WAIT(1);
GLINT_WRITE_REG(address, TextureDownloadOffset);
while(count >= infoRec->ColorExpandRange) {
GLINT_WAIT(infoRec->ColorExpandRange);
GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
(0x11 << 4) | 0x0D, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, infoRec->ColorExpandRange - 1);
count -= infoRec->ColorExpandRange - 1;
address += infoRec->ColorExpandRange - 1;
srcp += infoRec->ColorExpandRange - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, count);
}
src += srcwidth;
y++;
}
GLINT_WAIT(1);
GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
} else {
GLINT_WAIT(9);
PermediaLoadCoord(pScrn, (x&0xFFFF)<<16, y<<16, ((x&0xFFFF)+w)<<16, h, 0, 1<<16);
LOADROP(rop);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
while(h--) {
count = dwords;
srcp = (CARD32*)src;
while(count >= infoRec->ColorExpandRange) {
GLINT_WAIT(infoRec->ColorExpandRange);
GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
(0x15 << 4) | 0x05, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, infoRec->ColorExpandRange - 1);
count -= infoRec->ColorExpandRange - 1;
srcp += infoRec->ColorExpandRange - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
0x05, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, count);
}
src += srcwidth;
}
}
SET_SYNC_FLAG(infoRec);
}
static void
PermediaPolylinesThinSolidWrapper(
DrawablePtr pDraw,
GCPtr pGC,
int mode,
int npt,
DDXPointPtr pPts
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
pGlint->CurrentGC = pGC;
pGlint->CurrentDrawable = pDraw;
if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
XAAPolyLines(pDraw, pGC, mode, npt, pPts);
}
static void
PermediaPolySegmentThinSolidWrapper(
DrawablePtr pDraw,
GCPtr pGC,
int nseg,
xSegment *pSeg
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
pGlint->CurrentGC = pGC;
pGlint->CurrentDrawable = pDraw;
if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
XAAPolySegment(pDraw, pGC, nseg, pSeg);
}
static void
PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color,
int rop, unsigned int planemask)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
GLINT_WAIT(6);
DO_PLANEMASK(planemask);
GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_WRITE_REG(color, GLINTColor);
GLINT_WRITE_REG(0, RasterizerMode);
if (rop == GXcopy) {
GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
} else {
GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
}
LOADROP(rop);
}
static void
PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
GLINT_WAIT(7);
if (dir == DEGREES_0) {
PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 1<<16, 0);
} else {
PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 0, 1<<16);
}
GLINT_WRITE_REG(PrimitiveLine, Render);
}
static void
PermediaSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
int x, int y, int dmaj, int dmin, int e, int len, int octant)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
int dxdom, dy;
if(dmaj == dmin) {
GLINT_WAIT(7);
if(octant & YDECREASING) {
dy = -1<<16;
} else {
dy = 1<<16;
}
if(octant & XDECREASING) {
dxdom = -1<<16;
} else {
dxdom = 1<<16;
}
PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, dxdom, dy);
GLINT_WRITE_REG(PrimitiveLine, Render);
return;
}
fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0,
(octant & XDECREASING) ? -1 : 1,
(octant & YDECREASING) ? -1 : 1,
(octant & YMAJOR) ? Y_AXIS : X_AXIS,
x, y, e, dmin, -dmaj, len);
}