#include "riva_include.h"
#include "xaalocal.h"
#include "xaarop.h"
#include "miline.h"
static void
RivaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
{
int height = y2-y1 + 1;
int width = x2-x1 + 1;
RivaPtr pRiva = RivaPTR(pScrn);
RIVA_FIFO_FREE(pRiva->riva, Clip, 2);
pRiva->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff);
pRiva->riva.Clip->WidthHeight = (height << 16) | width;
}
static void
RivaDisableClipping(ScrnInfoPtr pScrn)
{
RivaSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
}
static void
RivaSetPattern(RivaPtr pRiva, int clr0, int clr1, int pat0, int pat1)
{
RIVA_FIFO_FREE(pRiva->riva, Patt, 4);
pRiva->riva.Patt->Color0 = clr0;
pRiva->riva.Patt->Color1 = clr1;
pRiva->riva.Patt->Monochrome[0] = pat0;
pRiva->riva.Patt->Monochrome[1] = pat1;
}
static void
RivaSetRopSolid(RivaPtr pRiva, int rop)
{
if (pRiva->currentRop != rop) {
if (pRiva->currentRop >= 16)
RivaSetPattern(pRiva, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
pRiva->currentRop = rop;
RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
pRiva->riva.Rop->Rop3 = XAACopyROP[rop];
}
}
static void
RivaSetRopPattern(RivaPtr pRiva, int rop)
{
if (pRiva->currentRop != (rop + 16)) {
pRiva->currentRop = rop + 16;
RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
pRiva->riva.Rop->Rop3 = XAAPatternROP[rop];
}
}
static
void RivaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned planemask)
{
RivaPtr pRiva = RivaPTR(pScrn);
RivaSetRopSolid(pRiva, rop);
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
pRiva->riva.Bitmap->Color1A = color;
}
static void
RivaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
RivaPtr pRiva = RivaPTR(pScrn);
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
write_mem_barrier();
pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
write_mem_barrier();
}
static void
RivaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
unsigned planemask, int transparency_color)
{
RivaSetRopSolid(RivaPTR(pScrn), rop);
}
static void
RivaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2, int w, int h)
{
RivaPtr pRiva = RivaPTR(pScrn);
RIVA_FIFO_FREE(pRiva->riva, Blt, 3);
pRiva->riva.Blt->TopLeftSrc = (y1 << 16) | x1;
pRiva->riva.Blt->TopLeftDst = (y2 << 16) | x2;
write_mem_barrier();
pRiva->riva.Blt->WidthHeight = (h << 16) | w;
write_mem_barrier();
}
static void
RivaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
int fg, int bg, int rop, unsigned planemask)
{
RivaPtr pRiva = RivaPTR(pScrn);
RivaSetRopPattern(pRiva, rop);
if (pScrn->depth == 16)
{
fg = ((fg & 0x0000F800) << 8)
| ((fg & 0x000007E0) << 5)
| ((fg & 0x0000001F) << 3)
| 0xFF000000;
if (bg != -1)
bg = ((bg & 0x0000F800) << 8)
| ((bg & 0x000007E0) << 5)
| ((bg & 0x0000001F) << 3)
| 0xFF000000;
else
bg = 0;
}
else
{
fg |= pRiva->opaqueMonochrome;
bg = (bg == -1) ? 0 : bg | pRiva->opaqueMonochrome;
};
RivaSetPattern(pRiva, bg, fg, patternx, patterny);
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
pRiva->riva.Bitmap->Color1A = fg;
}
static void
RivaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int patternx, int patterny,
int x, int y, int w, int h)
{
RivaPtr pRiva = RivaPTR(pScrn);
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
write_mem_barrier();
pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
write_mem_barrier();
}
void
RivaResetGraphics(ScrnInfoPtr pScrn)
{
RivaPtr pRiva = RivaPTR(pScrn);
if(pRiva->NoAccel) return;
RIVA_FIFO_FREE(pRiva->riva, Patt, 1);
pRiva->riva.Patt->Shape = 0;
RivaDisableClipping(pScrn);
pRiva->currentRop = 16;
RivaSetRopSolid(pRiva, GXcopy);
}
void RivaSync(ScrnInfoPtr pScrn)
{
RivaPtr pRiva = RivaPTR(pScrn);
RIVA_BUSY(pRiva->riva);
}
static void
RivaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask)
{
RivaPtr pRiva = RivaPTR(pScrn);
RivaSetRopSolid(pRiva, rop);
if ( bg == -1 )
{
bg = 0x80000000;
pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData1C;
}
else
{
pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
if (pScrn->depth == 16)
{
bg = ((bg & 0x0000F800) << 8)
| ((bg & 0x000007E0) << 5)
| ((bg & 0x0000001F) << 3)
| 0xFF000000;
}
else
{
bg |= pRiva->opaqueMonochrome;
};
}
pRiva->FgColor = fg;
pRiva->BgColor = bg;
}
static void
RivaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
RivaPtr pRiva = RivaPTR(pScrn);
int t = pRiva->expandWidth;
CARD32 *pbits = (CARD32*)pRiva->expandBuffer;
CARD32 *d = (CARD32*)pRiva->expandFifo;
while(t >= 16)
{
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 16);
d[0] = pbits[0];
d[1] = pbits[1];
d[2] = pbits[2];
d[3] = pbits[3];
d[4] = pbits[4];
d[5] = pbits[5];
d[6] = pbits[6];
d[7] = pbits[7];
d[8] = pbits[8];
d[9] = pbits[9];
d[10] = pbits[10];
d[11] = pbits[11];
d[12] = pbits[12];
d[13] = pbits[13];
d[14] = pbits[14];
d[15] = pbits[15];
t -= 16; pbits += 16;
}
if(t) {
RIVA_FIFO_FREE(pRiva->riva, Bitmap, t);
while(t >= 4)
{
d[0] = pbits[0];
d[1] = pbits[1];
d[2] = pbits[2];
d[3] = pbits[3];
t -= 4; pbits += 4;
}
while(t--)
*(d++) = *(pbits++);
}
if (!(--pRiva->expandRows)) {
RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
write_mem_barrier();
pRiva->riva.Blt->TopLeftSrc = 0;
}
write_mem_barrier();
}
static void
RivaSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
{
RivaPtr pRiva = RivaPTR(pScrn);
if ( --pRiva->expandRows ) {
RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
} else {
RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
write_mem_barrier();
pRiva->riva.Blt->TopLeftSrc = 0;
}
write_mem_barrier();
}
static void
RivaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
int y, int w, int h,
int skipleft)
{
int bw;
RivaPtr pRiva = RivaPTR(pScrn);
bw = (w + 31) & ~31;
pRiva->expandWidth = bw >> 5;
if ( pRiva->BgColor == 0x80000000 )
{
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 5);
pRiva->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft)
& 0xFFFF);
pRiva->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
pRiva->riva.Bitmap->Color1C = pRiva->FgColor;
pRiva->riva.Bitmap->WidthHeightC = (h << 16) | bw;
write_mem_barrier();
pRiva->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF);
write_mem_barrier();
}
else
{
RIVA_FIFO_FREE(pRiva->riva, Bitmap, 7);
pRiva->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft)
& 0xFFFF);
pRiva->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
pRiva->riva.Bitmap->Color0E = pRiva->BgColor;
pRiva->riva.Bitmap->Color1E = pRiva->FgColor;
pRiva->riva.Bitmap->WidthHeightInE = (h << 16) | bw;
pRiva->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
write_mem_barrier();
pRiva->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF);
write_mem_barrier();
}
pRiva->expandRows = h;
if(pRiva->expandWidth > (pRiva->riva.FifoEmptyCount >> 2)) {
pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
pRiva->AccelInfoRec->SubsequentColorExpandScanline =
RivaSubsequentColorExpandScanline;
} else {
pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandFifo;
pRiva->AccelInfoRec->SubsequentColorExpandScanline =
RivaSubsequentColorExpandScanlineFifo;
RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
}
}
static void
RivaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
{
RivaPtr pRiva = RivaPTR(pScrn);
RivaSetRopSolid(pRiva, rop);
pRiva->FgColor = color;
}
static void
RivaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
{
RivaPtr pRiva = RivaPTR(pScrn);
RIVA_FIFO_FREE(pRiva->riva, Line, 3);
pRiva->riva.Line->Color = pRiva->FgColor;
pRiva->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
write_mem_barrier();
if ( dir ==DEGREES_0 )
pRiva->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
else
pRiva->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
write_mem_barrier();
}
static void
RivaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2, int flags)
{
RivaPtr pRiva = RivaPTR(pScrn);
Bool lastPoint = !(flags & OMIT_LAST);
RIVA_FIFO_FREE(pRiva->riva, Line, lastPoint ? 5 : 3);
pRiva->riva.Line->Color = pRiva->FgColor;
pRiva->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
write_mem_barrier();
pRiva->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
write_mem_barrier();
if (lastPoint)
{
pRiva->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
write_mem_barrier();
pRiva->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
write_mem_barrier();
}
}
static void
RivaValidatePolyArc(
GCPtr pGC,
unsigned long changes,
DrawablePtr pDraw
){
if(pGC->planemask != ~0) return;
if(!pGC->lineWidth &&
((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid)))
{
pGC->ops->PolyArc = miZeroPolyArc;
}
}
static void
RivaValidatePolyPoint(
GCPtr pGC,
unsigned long changes,
DrawablePtr pDraw
){
pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint;
if(pGC->planemask != ~0) return;
if(pGC->alu != GXcopy)
pGC->ops->PolyPoint = miPolyPoint;
}
Bool
RivaAccelInit(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RivaPtr pRiva = RivaPTR(pScrn);
pRiva->AccelInfoRec = infoPtr = XAACreateInfoRec();
if(!infoPtr) return FALSE;
infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
infoPtr->Sync = RivaSync;
infoPtr->SolidFillFlags = NO_PLANEMASK;
infoPtr->SetupForSolidFill = RivaSetupForSolidFill;
infoPtr->SubsequentSolidFillRect = RivaSubsequentSolidFillRect;
infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
infoPtr->SetupForScreenToScreenCopy = RivaSetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy = RivaSubsequentScreenToScreenCopy;
pRiva->opaqueMonochrome = ~((1 << pScrn->depth) - 1);
infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
HARDWARE_PATTERN_PROGRAMMED_BITS |
NO_PLANEMASK;
infoPtr->SetupForMono8x8PatternFill = RivaSetupForMono8x8PatternFill;
infoPtr->SubsequentMono8x8PatternFillRect =
RivaSubsequentMono8x8PatternFillRect;
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
BIT_ORDER_IN_BYTE_LSBFIRST |
NO_PLANEMASK |
CPU_TRANSFER_PAD_DWORD |
LEFT_EDGE_CLIPPING |
LEFT_EDGE_CLIPPING_NEGATIVE_X;
infoPtr->NumScanlineColorExpandBuffers = 1;
infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
RivaSetupForScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
RivaSubsequentScanlineCPUToScreenColorExpandFill;
pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
pRiva->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);
infoPtr->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
infoPtr->SubsequentColorExpandScanline = RivaSubsequentColorExpandScanline;
infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
infoPtr->SetupForSolidLine = RivaSetupForSolidLine;
infoPtr->SubsequentSolidHorVertLine =
RivaSubsequentSolidHorVertLine;
infoPtr->SubsequentSolidTwoPointLine =
RivaSubsequentSolidTwoPointLine;
infoPtr->SetClippingRectangle = RivaSetClippingRectangle;
infoPtr->DisableClipping = RivaDisableClipping;
infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);
infoPtr->ValidatePolyArc = RivaValidatePolyArc;
infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
infoPtr->ValidatePolyPoint = RivaValidatePolyPoint;
infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
RivaResetGraphics(pScrn);
return(XAAInit(pScreen, infoPtr));
}