#define NO_OPTIMIZE
#undef ET6K_TRANSPARENCY
#include "tseng.h"
#include "tseng_acl.h"
#include "tseng_inline.h"
#include "miline.h"
void TsengSync(ScrnInfoPtr pScrn);
void TsengSetupForSolidFill(ScrnInfoPtr pScrn,
int color, int rop, unsigned int planemask);
void TsengW32iSubsequentSolidFillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h);
void TsengW32pSubsequentSolidFillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h);
void Tseng6KSubsequentSolidFillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h);
void TsengSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
int xdir, int ydir, int rop,
unsigned int planemask, int trans_color);
void TsengSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2, int w, int h);
void TsengSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
int patx, int paty, int rop, unsigned int planemask, int trans_color);
void TsengSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
int patx, int paty, int x, int y, int w, int h);
void TsengSetupForScanlineImageWrite(ScrnInfoPtr pScrn,
int rop, unsigned int planemask, int trans_color, int bpp, int depth);
void TsengSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft);
void TsengSubsequentImageWriteScanline(ScrnInfoPtr pScrn,
int bufno);
#if 0
void TsengSetupForSolidLine(ScrnInfoPtr pScrn,
int color, int rop, unsigned int planemask);
#endif
void TsengSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
int x, int y, int major, int minor, int err, int len, int octant);
Bool
TsengXAAInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
TsengPtr pTseng = TsengPTR(pScrn);
XAAInfoRecPtr pXAAinfo;
BoxRec AvailFBArea;
PDEBUG(" TsengXAAInit\n");
pTseng->AccelInfoRec = pXAAinfo = XAACreateInfoRec();
if (!pXAAinfo)
return FALSE;
pXAAinfo->Flags = PIXMAP_CACHE;
#ifdef TODO
if (Tseng_bus != T_BUS_PCI)
pXAAinfo->Flags |= COP_FRAMEBUFFER_CONCURRENCY;
#endif
pXAAinfo->Sync = TsengSync;
pTseng->need_wait_acl = (Is_W32_W32i || Is_W32p);
pTseng->line_width = pScrn->displayWidth * pTseng->Bytesperpixel;
#if 1
#ifdef OBSOLETE
pXAAinfo->SolidFillFlags |= NO_PLANEMASK;
#endif
if (!(Is_W32_W32i && (pScrn->bitsPerPixel == 24))) {
pXAAinfo->SetupForSolidFill = TsengSetupForSolidFill;
if (Is_ET6K) {
pXAAinfo->SubsequentSolidFillRect = Tseng6KSubsequentSolidFillRect;
} else if (Is_W32p)
pXAAinfo->SubsequentSolidFillRect = TsengW32pSubsequentSolidFillRect;
else
pXAAinfo->SubsequentSolidFillRect = TsengW32iSubsequentSolidFillRect;
}
#ifdef TSENG_TRAPEZOIDS
if (Is_ET6K) {
pXAAinfo->SubsequentFillTrapezoidSolid = TsengSubsequentFillTrapezoidSolid;
}
#endif
#endif
#if 1
#ifdef ET6K_TRANSPARENCY
pXAAinfo->CopyAreaFlags = NO_PLANEMASK;
if (!Is_ET6K) {
pXAAinfo->CopyAreaFlags |= NO_TRANSPARENCY;
}
#else
pXAAinfo->CopyAreaFlags = NO_TRANSPARENCY;
#endif
pXAAinfo->SetupForScreenToScreenCopy =
TsengSetupForScreenToScreenCopy;
pXAAinfo->SubsequentScreenToScreenCopy =
TsengSubsequentScreenToScreenCopy;
#endif
#if 0
if (pTseng->AccelImageWriteBufferOffsets[0]) {
pXAAinfo->ScanlineImageWriteFlags =
pXAAinfo->CopyAreaFlags | LEFT_EDGE_CLIPPING ;
pXAAinfo->NumScanlineImageWriteBuffers = 2;
pXAAinfo->SetupForScanlineImageWrite =
TsengSetupForScanlineImageWrite;
pXAAinfo->SubsequentScanlineImageWriteRect =
TsengSubsequentScanlineImageWriteRect;
pXAAinfo->SubsequentImageWriteScanline =
TsengSubsequentImageWriteScanline;
for (i = 0; i < pXAAinfo->NumScanlineImageWriteBuffers; i++) {
pTseng->XAAScanlineImageWriteBuffers[i] =
pTseng->FbBase + pTseng->AccelImageWriteBufferOffsets[i];
}
if (!pTseng->UseLinMem) {
for (i = 0; i < pXAAinfo->NumScanlineImageWriteBuffers; i++) {
pTseng->XAAScanlineImageWriteBuffers[i] =
pTseng->XAAScanlineImageWriteBuffers[i]
- pTseng->AccelImageWriteBufferOffsets[0]
+ 0x1A000;
}
}
pXAAinfo->ScanlineImageWriteBuffers = pTseng->XAAScanlineImageWriteBuffers;
}
#endif
pXAAinfo->Color8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
pXAAinfo->CachePixelGranularity = 8 * 8;
#ifdef ET6K_TRANSPARENCY
pXAAinfo->PatternFlags |= HARDWARE_PATTERN_NO_PLANEMASK;
if (Is_ET6K) {
pXAAinfo->PatternFlags |= HARDWARE_PATTERN_TRANSPARENCY;
}
#endif
#if 0
if ((pScrn->bitsPerPixel != 24) && (Is_W32p || Is_ET6K)) {
pXAAinfo->SetupForColor8x8PatternFill =
TsengSetupForColor8x8PatternFill;
pXAAinfo->SubsequentColor8x8PatternFillRect =
TsengSubsequentColor8x8PatternFillRect;
}
#endif
#if 0
if (Is_W32p || Is_ET6K) {
pTseng->BresenhamTable = xnfalloc(8);
if (pTseng->BresenhamTable == NULL) {
xf86Msg(X_ERROR, "Could not malloc Bresenham Table.\n");
return FALSE;
}
for (i=0; i<8; i++) {
unsigned char zerolinebias = miGetZeroLineBias(pScreen);
pTseng->BresenhamTable[i] = 0xA0;
if (i & XDECREASING) pTseng->BresenhamTable[i] |= 0x01;
if (i & YDECREASING) pTseng->BresenhamTable[i] |= 0x02;
if (!(i & YMAJOR)) pTseng->BresenhamTable[i] |= 0x04;
if ((1 << i) & zerolinebias) pTseng->BresenhamTable[i] |= 0x10;
}
pXAAinfo->SolidLineFlags = 0;
pXAAinfo->SetupForSolidLine = TsengSetupForSolidFill;
pXAAinfo->SubsequentSolidBresenhamLine =
TsengSubsequentSolidBresenhamLine;
pXAAinfo->SolidBresenhamLineErrorTermBits = 13;
}
#endif
#if 1
if (!TsengXAAInit_Colexp(pScrn))
return FALSE;
#endif
switch (pTseng->Bytesperpixel) {
case 1:
pTseng->powerPerPixel = 0;
pTseng->planemask_mask = 0x000000FF;
pTseng->neg_x_pixel_offset = 0;
break;
case 2:
pTseng->powerPerPixel = 1;
pTseng->planemask_mask = 0x0000FFFF;
pTseng->neg_x_pixel_offset = 1;
break;
case 3:
pTseng->powerPerPixel = 1;
pTseng->planemask_mask = 0x00FFFFFF;
pTseng->neg_x_pixel_offset = 2;
break;
case 4:
pTseng->powerPerPixel = 2;
pTseng->planemask_mask = 0xFFFFFFFF;
pTseng->neg_x_pixel_offset = 3;
break;
}
pTseng->tsengFg = 0;
pTseng->tsengBg = 16;
pTseng->tsengPat = 32;
pTseng->tseng_old_dir = -1;
pTseng->old_x = 0;
pTseng->old_y = 0;
AvailFBArea.x1 = 0;
AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
AvailFBArea.y2 = (pScrn->videoRam * 1024) /
(pScrn->displayWidth * pTseng->Bytesperpixel);
xf86InitFBManager(pScreen, &AvailFBArea);
return (XAAInit(pScreen, pXAAinfo));
}
void
TsengSync(ScrnInfoPtr pScrn)
{
TsengPtr pTseng = TsengPTR(pScrn);
WAIT_ACL;
}
void
TsengSetupForSolidFill(ScrnInfoPtr pScrn,
int color, int rop, unsigned int planemask)
{
TsengPtr pTseng = TsengPTR(pScrn);
PINGPONG(pTseng);
wait_acl_queue(pTseng);
if ((planemask & pTseng->planemask_mask) != pTseng->planemask_mask) {
SET_FG_ROP_PLANEMASK(rop);
SET_BG_COLOR(pTseng, planemask);
} else {
SET_FG_ROP(rop);
}
SET_FG_COLOR(pTseng, color);
SET_FUNCTION_BLT;
}
void
TsengW32pSubsequentSolidFillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
wait_acl_queue(pTseng);
ACL_SOURCE_ADDRESS(pTseng->AccelColorBufferOffset + pTseng->tsengFg);
SET_XYDIR(0);
SET_XY_4(pTseng, w, h);
START_ACL(pTseng, destaddr);
}
void
TsengW32iSubsequentSolidFillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
wait_acl_queue(pTseng);
SET_XYDIR(0);
SET_XY_6(pTseng, w, h);
START_ACL(pTseng, destaddr);
}
void
Tseng6KSubsequentSolidFillRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
wait_acl_queue(pTseng);
ACL_SOURCE_ADDRESS(pTseng->AccelColorBufferOffset + pTseng->tsengFg);
SET_XYDIR(0);
SET_XY_6(pTseng, w, h);
START_ACL_6(destaddr);
}
static __inline__ void
Tseng_setup_screencopy(TsengPtr pTseng,
int rop, unsigned int planemask,
int trans_color, int blit_dir)
{
wait_acl_queue(pTseng);
#ifdef ET6K_TRANSPARENCY
if (Is_ET6K && (trans_color != -1)) {
SET_BG_COLOR(trans_color);
SET_FUNCTION_BLT_TR;
} else
SET_FUNCTION_BLT;
SET_FG_ROP(rop);
#else
if ((planemask & pTseng->planemask_mask) != pTseng->planemask_mask) {
SET_FG_ROP_PLANEMASK(rop);
SET_BG_COLOR(pTseng, planemask);
} else {
SET_FG_ROP(rop);
}
SET_FUNCTION_BLT;
#endif
SET_XYDIR(blit_dir);
}
void
TsengSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
int xdir, int ydir, int rop,
unsigned int planemask, int trans_color)
{
TsengPtr pTseng = TsengPTR(pScrn);
int blit_dir = 0;
pTseng->acl_blitxdir = xdir;
pTseng->acl_blitydir = ydir;
if (xdir == -1)
blit_dir |= 0x1;
if (ydir == -1)
blit_dir |= 0x2;
Tseng_setup_screencopy(pTseng, rop, planemask, trans_color, blit_dir);
ACL_SOURCE_WRAP(0x77);
ACL_SOURCE_Y_OFFSET(pTseng->line_width - 1);
}
void
TsengSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
int x1, int y1, int x2, int y2,
int w, int h)
{
TsengPtr pTseng = TsengPTR(pScrn);
int srcaddr, destaddr;
x1 = MULBPP(pTseng, x1);
x2 = MULBPP(pTseng, x2);
if (pTseng->acl_blitydir == -1) {
srcaddr = (y1 + h - 1) * pTseng->line_width;
destaddr = (y2 + h - 1) * pTseng->line_width;
} else {
srcaddr = y1 * pTseng->line_width;
destaddr = y2 * pTseng->line_width;
}
if (pTseng->acl_blitxdir == -1) {
int eol = MULBPP(pTseng, w);
srcaddr += x1 + eol - 1;
destaddr += x2 + eol - 1;
} else {
srcaddr += x1;
destaddr += x2;
}
wait_acl_queue(pTseng);
SET_XY(pTseng, w, h);
ACL_SOURCE_ADDRESS(srcaddr);
START_ACL(pTseng, destaddr);
}
static int pat_src_addr;
void
TsengSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
int patx, int paty, int rop, unsigned int planemask, int trans_color)
{
TsengPtr pTseng = TsengPTR(pScrn);
pat_src_addr = FBADDR(pTseng, patx, paty);
ErrorF("P");
Tseng_setup_screencopy(pTseng, rop, planemask, trans_color, 0);
switch (pTseng->Bytesperpixel) {
case 1:
ACL_SOURCE_WRAP(0x33);
ACL_SOURCE_Y_OFFSET(8 - 1);
break;
case 2:
ACL_SOURCE_WRAP(0x34);
ACL_SOURCE_Y_OFFSET(16 - 1);
break;
case 3:
ACL_SOURCE_WRAP(0x3D);
ACL_SOURCE_Y_OFFSET(32 - 1);
break;
case 4:
ACL_SOURCE_WRAP(0x35);
ACL_SOURCE_Y_OFFSET(32 - 1);
}
}
void
TsengSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
int patx, int paty, int x, int y, int w, int h)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
int srcaddr = pat_src_addr + MULBPP(pTseng, paty * 8 + patx);
wait_acl_queue(pTseng);
ACL_SOURCE_ADDRESS(srcaddr);
SET_XY(pTseng, w, h);
START_ACL(pTseng, destaddr);
}
void
TsengSetupForScanlineImageWrite(ScrnInfoPtr pScrn,
int rop, unsigned int planemask, int trans_color, int bpp, int depth)
{
TsengPtr pTseng = TsengPTR(pScrn);
Tseng_setup_screencopy(pTseng, rop, planemask, trans_color, 0);
ACL_SOURCE_WRAP(0x77);
ACL_SOURCE_Y_OFFSET(pTseng->line_width - 1);
}
void
TsengSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft)
{
TsengPtr pTseng = TsengPTR(pScrn);
pTseng->acl_iw_dest = y * pTseng->line_width + MULBPP(pTseng, x);
pTseng->acl_skipleft = MULBPP(pTseng, skipleft);
wait_acl_queue(pTseng);
SET_XY(pTseng, w, 1);
}
void
TsengSubsequentImageWriteScanline(ScrnInfoPtr pScrn,
int bufno)
{
TsengPtr pTseng = TsengPTR(pScrn);
wait_acl_queue(pTseng);
ACL_SOURCE_ADDRESS(pTseng->AccelImageWriteBufferOffsets[bufno]
+ pTseng->acl_skipleft);
START_ACL(pTseng, pTseng->acl_iw_dest);
pTseng->acl_iw_dest += pTseng->line_width;
}
void
TsengSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
int x, int y, int major, int minor, int err, int len, int octant)
{
TsengPtr pTseng = TsengPTR(pScrn);
int destaddr = FBADDR(pTseng, x, y);
int xydir = pTseng->BresenhamTable[octant];
minor >>= 1;
major >>= 1;
wait_acl_queue(pTseng);
if (!(octant & YMAJOR)) {
SET_X_YRAW(pTseng, len, 0xFFF);
} else {
SET_XY_RAW(pTseng,0xFFF, len - 1);
}
SET_DELTA(minor, major);
ACL_ERROR_TERM(-err);
if (octant & XDECREASING) {
destaddr += pTseng->Bytesperpixel - 1;
ACL_SOURCE_ADDRESS(pTseng->AccelColorBufferOffset
+ pTseng->tsengFg + pTseng->neg_x_pixel_offset);
} else
ACL_SOURCE_ADDRESS(pTseng->AccelColorBufferOffset + pTseng->tsengFg);
SET_XYDIR(xydir);
START_ACL(pTseng, destaddr);
}
#ifdef TODO
#undef DEBUG_TRAP
#ifdef TSENG_TRAPEZOIDS
void
TsengSubsequentFillTrapezoidSolid(ytop, height, left, dxL, dyL, eL, right, dxR, dyR, eR)
int ytop;
int height;
int left;
int dxL, dyL;
int eL;
int right;
int dxR, dyR;
int eR;
{
unsigned int tseng_bias_compensate = 0xd8;
int destaddr, algrthm;
int xcount = right - left + 1;
int dir_reg = 0x60;
int sec_dir_reg = 0x20;
int octant = 0;
int destaddr, algrthm;
int xcount = right - left + 1;
#ifdef USE_ERROR_TERM
int dir_reg = 0x60;
int sec_dir_reg = 0x20;
#else
int dir_reg = 0x40;
int sec_dir_reg = 0x00;
#endif
int octant = 0;
int bias = 0x00;
#ifdef DEBUG_TRAP
ErrorF("ytop=%d, height=%d, left=%d, dxL=%d, dyL=%d, eL=%d, right=%d, dxR=%d, dyR=%d, eR=%d ",
ytop, height, left, dxL, dyL, eL, right, dxR, dyR, eR);
#endif
if ((dyL < 0) || (dyR < 0))
ErrorF("Tseng Trapezoids: Wrong assumption: dyL/R < 0\n");
destaddr = FBADDR(pTseng, left, ytop);
if (dxL < 0) {
dir_reg |= 1;
octant |= XDECREASING;
dxL = -dxL;
}
wait_acl_queue(pTseng);
if (dxL >= dyL) {
dir_reg |= 4;
SET_DELTA(dyL, dxL);
if (dir_reg & 1) {
destaddr += pTseng->Bytesperpixel;
sec_dir_reg |= 0x80;
xcount--;
}
} else {
SetYMajorOctant(octant);
SET_DELTA(dxL, dyL);
}
ACL_ERROR_TERM(eL);
algrthm = ((tseng_bias_compensate >> octant) & 1) ^ 1;
dir_reg |= algrthm << 4;
SET_XYDIR(dir_reg);
if (dxR < 0) {
sec_dir_reg |= 1;
dxR = -dxR;
}
if (dxR >= dyR) {
sec_dir_reg |= 4;
SET_SECONDARY_DELTA(dyR, dxR);
if (dir_reg & 1) {
sec_dir_reg |= 0x40;
xcount++;
}
} else {
SET_SECONDARY_DELTA(dxR, dyR);
}
ACL_SECONDARY_ERROR_TERM(eR);
SET_SECONDARY_XYDIR(sec_dir_reg);
SET_XY_6(pTseng, xcount, height);
#ifdef DEBUG_TRAP
ErrorF("-> %d,%d\n", xcount, height);
#endif
START_ACL_6(destaddr);
}
#endif
#endif