#include "Xarch.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "miline.h"
#include "fb.h"
#include "glint_regs.h"
#include "pm3_regs.h"
#include "glint.h"
#include "xaalocal.h"
#define DEBUG 0
#if DEBUG
# define TRACE_ENTER(str) ErrorF("pm3_accel: " str " %d\n",pScrn->scrnIndex)
# define TRACE_EXIT(str) ErrorF("pm3_accel: " str " done\n")
# define TRACE(str) ErrorF("pm3_accel trace: " str "\n")
#else
# define TRACE_ENTER(str)
# define TRACE_EXIT(str)
# define TRACE(str)
#endif
#define PM3_WRITEMASK \
(pGlint->PM3_UsingSGRAM ? PM3FBHardwareWriteMask : PM3FBSoftwareWriteMask )
#define PM3_OTHERWRITEMASK \
(pGlint->PM3_UsingSGRAM ? PM3FBSoftwareWriteMask : PM3FBHardwareWriteMask )
#ifndef XF86DRI
#define PM3_PLANEMASK(planemask) \
{ \
if (planemask != pGlint->planemask) { \
pGlint->planemask = planemask; \
REPLICATE(planemask); \
GLINT_WRITE_REG(planemask, PM3_WRITEMASK); \
} \
}
#else
#define PM3_PLANEMASK(planemask) \
{ \
pGlint->planemask = planemask; \
REPLICATE(planemask); \
GLINT_WRITE_REG(planemask, PM3_WRITEMASK); \
}
#endif
static void Permedia3SetClippingRectangle(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
static void Permedia3DisableClipping(ScrnInfoPtr pScrn);
static void Permedia3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
int x1, int y1, int x2,
int y2, int w, int h);
static void Permedia3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
int xdir, int ydir, int rop,
unsigned int planemask,
int transparency_color);
static void Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
int rop, unsigned int planemask);
static void Permedia3SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
int y, int w, int h);
static void Permedia3SubsequentFillRectSolid32bpp(ScrnInfoPtr pScrn, int x,
int y, int w, int h);
static void Permedia3SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int patternx, int patterny, int fg, int bg,
int rop, unsigned int planemask);
static void Permedia3SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int x_offset, int y_offset, int x, int y,
int w, int h);
static void Permedia3SetupForScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask);
static void Permedia3SubsequentScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn, int x,
int y, int w, int h, int skipleft);
static void Permedia3SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
static void Permedia3SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
unsigned int planemask, int trans_color,
int bpp, int depth);
static void Permedia3SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft);
static void Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
static void Permedia3RestoreAccelState(ScrnInfoPtr pScrn);
static void Permedia3WritePixmap(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 Permedia3WriteBitmap(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);
void
Permedia3InitializeEngine(ScrnInfoPtr pScrn)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
int colorformat = 0;
TRACE_ENTER("Permedia3InitializeEngine");
if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) {
GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask);
}
if (pGlint->MultiAperture) {
ErrorF("pm3_accel: SVEN : multiAperture set\n");
GLINT_SLOW_WRITE_REG(1, BroadcastMask);
GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership);
GLINT_SLOW_WRITE_REG(2, BroadcastMask);
GLINT_SLOW_WRITE_REG(0x00000005, ScanLineOwnership);
GLINT_SLOW_WRITE_REG(3, BroadcastMask);
}
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadEnables);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBSourceReadMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBWriteMode);
GLINT_SLOW_WRITE_REG(0x400, FilterMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3DeltaMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3GIDMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureCoordMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureIndexMode0);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureIndexMode1);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LUTMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureFilterMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureCompositeMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureApplicationMode);
GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeColorMode1);
GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeAlphaMode1);
GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeColorMode0);
GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeAlphaMode0);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ChromaTestMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaTestMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaBlendColorMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaBlendAlphaMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3Window);
GLINT_SLOW_WRITE_REG(0, PM3Config2D);
GLINT_SLOW_WRITE_REG(0xffffffff, PM3SpanColorMask);
GLINT_SLOW_WRITE_REG(0, PM3XBias);
GLINT_SLOW_WRITE_REG(0, PM3YBias);
GLINT_SLOW_WRITE_REG(0, PM3DeltaControl);
GLINT_SLOW_WRITE_REG(0xffffffff, BitMaskPattern);
pGlint->ClippingOn = FALSE;
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
GLINT_SLOW_WRITE_REG(0, PM3Window);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
GLINT_SLOW_WRITE_REG(0, StencilData);
TRACE("Permedia3InitializeEngine : only syncs upto now");
GLINT_SLOW_WRITE_REG(
PM3FBDestReadEnables_E(0xff) |
PM3FBDestReadEnables_R(0xff) |
PM3FBDestReadEnables_ReferenceAlpha(0xff),
PM3FBDestReadEnables);
GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr0);
GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset0);
GLINT_SLOW_WRITE_REG(
PM3FBDestReadBufferWidth_Width(pScrn->displayWidth),
PM3FBDestReadBufferWidth0);
GLINT_SLOW_WRITE_REG(
PM3FBDestReadMode_ReadEnable |
PM3FBDestReadMode_Enable0,
PM3FBDestReadMode);
TRACE("Permedia3InitializeEngine : DestRead");
GLINT_SLOW_WRITE_REG(0, PM3FBSourceReadBufferAddr);
GLINT_SLOW_WRITE_REG(0, PM3FBSourceReadBufferOffset);
GLINT_SLOW_WRITE_REG(
PM3FBSourceReadBufferWidth_Width(pScrn->displayWidth),
PM3FBSourceReadBufferWidth);
GLINT_SLOW_WRITE_REG(
PM3FBSourceReadMode_Blocking |
PM3FBSourceReadMode_ReadEnable,
PM3FBSourceReadMode);
TRACE("Permedia3InitializeEngine : SourceRead");
switch (pScrn->bitsPerPixel) {
case 8:
pGlint->PM3_PixelSize = 2;
#if X_BYTE_ORDER == X_BIG_ENDIAN
pGlint->RasterizerSwap = 3<<15;
#endif
break;
case 16:
pGlint->PM3_PixelSize = 1;
#if X_BYTE_ORDER == X_BIG_ENDIAN
pGlint->RasterizerSwap = 2<<15;
#endif
break;
case 32:
pGlint->PM3_PixelSize = 0;
break;
}
GLINT_SLOW_WRITE_REG(pGlint->PM3_PixelSize, PixelSize);
#if X_BYTE_ORDER == X_BIG_ENDIAN
GLINT_SLOW_WRITE_REG(1 | pGlint->RasterizerSwap, RasterizerMode);
#endif
TRACE("Permedia3InitializeEngine : PixelSize");
GLINT_SLOW_WRITE_REG(0xffffffff, PM3_OTHERWRITEMASK);
GLINT_SLOW_WRITE_REG(
PM3FBWriteMode_WriteEnable|
PM3FBWriteMode_OpaqueSpan|
PM3FBWriteMode_Enable0,
PM3FBWriteMode);
GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr0);
GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset0);
GLINT_SLOW_WRITE_REG(
PM3FBWriteBufferWidth_Width(pScrn->displayWidth),
PM3FBWriteBufferWidth0);
TRACE("Permedia3InitializeEngine : FBWrite");
GLINT_SLOW_WRITE_REG(
pScrn->displayWidth *
(8 * pGlint->FbMapSize / (pScrn->bitsPerPixel * pScrn->displayWidth)
>4095?4095: 8 * pGlint->FbMapSize /
(pScrn->bitsPerPixel * pScrn->displayWidth)),
PM3SizeOfFramebuffer);
GLINT_SLOW_WRITE_REG(0xffffffff, PM3_WRITEMASK);
TRACE("Permedia3InitializeEngine : FBHardwareWriteMask & SizeOfFramebuffer");
switch (pScrn->depth) {
case 8:
colorformat = 4;
break;
case 15:
colorformat = 2;
break;
case 16:
colorformat = 3;
break;
case 24:
case 32:
colorformat = 0;
break;
}
GLINT_SLOW_WRITE_REG(UNIT_DISABLE|
((colorformat&0xf)<<2)|(1<<10),
DitherMode);
pGlint->startxdom = 0;
pGlint->startxsub = 0;
pGlint->starty = 0;
pGlint->count = 0;
pGlint->dy = 1<<16;
pGlint->dxdom = 0;
pGlint->x = 0;
pGlint->y = 0;
pGlint->h = 0;
pGlint->w = 0;
pGlint->ROP = 0xFF;
GLINT_SLOW_WRITE_REG(0, dXDom);
GLINT_SLOW_WRITE_REG(0, dXSub);
GLINT_SLOW_WRITE_REG(1<<16, dY);
GLINT_SLOW_WRITE_REG(0, StartXDom);
GLINT_SLOW_WRITE_REG(0, StartXSub);
GLINT_SLOW_WRITE_REG(0, StartY);
GLINT_SLOW_WRITE_REG(0, GLINTCount);
if (*pGlint->AccelInfoRec->Sync)
(*pGlint->AccelInfoRec->Sync)(pScrn);
TRACE_EXIT("Permedia3InitializeEngine");
}
Bool
Permedia3AccelInit(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
GLINTPtr pGlint = GLINTPTR(pScrn);
pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
if (!infoPtr) return FALSE;
infoPtr->Flags = PIXMAP_CACHE |
OFFSCREEN_PIXMAPS |
LINEAR_FRAMEBUFFER;
if (pGlint->MultiAperture)
infoPtr->Sync = DualPermedia3Sync;
else
infoPtr->Sync = Permedia3Sync;
Permedia3InitializeEngine(pScrn);
infoPtr->ClippingFlags = 0;
infoPtr->SetClippingRectangle = Permedia3SetClippingRectangle;
infoPtr->DisableClipping = Permedia3DisableClipping;
infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
infoPtr->SetupForScreenToScreenCopy =
Permedia3SetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy =
Permedia3SubsequentScreenToScreenCopy;
infoPtr->SolidFillFlags = 0;
infoPtr->SetupForSolidFill = Permedia3SetupForFillRectSolid;
infoPtr->SubsequentSolidFillRect = Permedia3SubsequentFillRectSolid;
infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS |
HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
HARDWARE_PATTERN_SCREEN_ORIGIN |
BIT_ORDER_IN_BYTE_LSBFIRST;
infoPtr->SetupForMono8x8PatternFill =
Permedia3SetupForMono8x8PatternFill;
infoPtr->SubsequentMono8x8PatternFillRect =
Permedia3SubsequentMono8x8PatternFillRect;
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
LEFT_EDGE_CLIPPING |
LEFT_EDGE_CLIPPING_NEGATIVE_X |
BIT_ORDER_IN_BYTE_LSBFIRST |
CPU_TRANSFER_PAD_DWORD;
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 =
Permedia3SetupForScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
Permedia3SubsequentScanlineCPUToScreenColorExpandFill;
infoPtr->SubsequentColorExpandScanline =
Permedia3SubsequentColorExpandScanline;
infoPtr->ScanlineImageWriteFlags = NO_GXCOPY |
LEFT_EDGE_CLIPPING |
LEFT_EDGE_CLIPPING_NEGATIVE_X |
BIT_ORDER_IN_BYTE_LSBFIRST |
CPU_TRANSFER_PAD_DWORD;
infoPtr->NumScanlineImageWriteBuffers = 1;
infoPtr->ScanlineImageWriteBuffers =
pGlint->XAAScanlineColorExpandBuffers;
infoPtr->SetupForScanlineImageWrite =
Permedia3SetupForScanlineImageWrite;
infoPtr->SubsequentScanlineImageWriteRect =
Permedia3SubsequentScanlineImageWriteRect;
infoPtr->SubsequentImageWriteScanline =
Permedia3SubsequentImageWriteScanline;
infoPtr->WriteBitmap = Permedia3WriteBitmap;
infoPtr->WriteBitmapFlags = 0;
infoPtr->WritePixmap = Permedia3WritePixmap;
infoPtr->WritePixmapFlags = 0;
{
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 = Permedia3RestoreAccelState;
}
Permedia3EnableOffscreen(pScreen);
return(XAAInit(pScreen, infoPtr));
}
void
Permedia3EnableOffscreen (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
GLINTPtr pGlint = GLINTPTR(pScrn);
BoxRec AvailFBArea;
AvailFBArea.x1 = 0;
AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
AvailFBArea.y2 = ((pGlint->FbMapSize > 16384*1024) ? 16384*1024 :
pGlint->FbMapSize) / (pScrn->displayWidth *
pScrn->bitsPerPixel / 8);
if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095;
xf86InitFBManager(pScreen, &AvailFBArea);
}
#define CHECKCLIPPING \
{ \
if (pGlint->ClippingOn) { \
pGlint->ClippingOn = FALSE; \
GLINT_WAIT(1); \
GLINT_WRITE_REG(0, ScissorMode); \
} \
}
void
Permedia3Sync(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);
}
void
DualPermedia3Sync(
ScrnInfoPtr pScrn
){
GLINTPtr pGlint = GLINTPTR(pScrn);
CHECKCLIPPING;
while (GLINT_READ_REG(DMACount) != 0);
GLINT_WAIT(3);
GLINT_WRITE_REG(3, BroadcastMask);
GLINT_WRITE_REG(0x400, FilterMode);
GLINT_WRITE_REG(0, GlintSync);
ACCESSCHIP1();
do {
while(GLINT_READ_REG(OutFIFOWords) == 0);
} while (GLINT_READ_REG(OutputFIFO) != Sync_tag);
ACCESSCHIP2();
do {
while(GLINT_READ_REG(OutFIFOWords) == 0);
} while (GLINT_READ_REG(OutputFIFO) != Sync_tag);
ACCESSCHIP1();
}
static void
Permedia3SetClippingRectangle(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
Permedia3DisableClipping(ScrnInfoPtr pScrn)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
CHECKCLIPPING;
}
static void
Permedia3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
int xdir, int ydir, int rop,
unsigned int planemask, int transparency_color)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SetupForScreenToScreenCopy");
pGlint->PM3_Render2D =
PM3Render2D_SpanOperation |
PM3Render2D_Operation_Normal;
pGlint->ClippingOn = TRUE;
pGlint->PM3_Config2D =
PM3Config2D_UserScissorEnable |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
if (xdir == 1) pGlint->PM3_Render2D |= PM3Render2D_XPositive;
if (ydir == 1) pGlint->PM3_Render2D |= PM3Render2D_YPositive;
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXnoop)&&(rop!=GXinvert)) {
pGlint->PM3_Render2D |= PM3Render2D_FBSourceReadEnable;
pGlint->PM3_Config2D |= PM3Config2D_Blocking;
}
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
GLINT_WAIT(2);
PM3_PLANEMASK(planemask);
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
TRACE_EXIT("Permedia3SetupForScreenToScreenCopy");
}
static void
Permedia3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2, int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
int x_align = x1 & 0x1f;
TRACE_ENTER("Permedia3SubsequentScreenToScreenCopy");
GLINT_WAIT(5);
GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMinXY);
GLINT_WRITE_REG((((y2+h)&0x0fff)<<16)|((x2+w)&0x0fff), ScissorMaxXY);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x2-x_align) |
PM3RectanglePosition_YOffset(y2),
PM3RectanglePosition);
GLINT_WRITE_REG(
PM3FBSourceReadBufferOffset_XOffset(x1-x2)|
PM3FBSourceReadBufferOffset_YOffset(y1-y2),
PM3FBSourceReadBufferOffset);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w+x_align)|
PM3Render2D_Height(h),
PM3Render2D);
TRACE_EXIT("Permedia3SubsequentScreenToScreenCopy");
}
static void
Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
int rop, unsigned int planemask)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SetupForFillRectSolid");
pGlint->PM3_Render2D =
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_Normal;
pGlint->PM3_Config2D =
PM3Config2D_UseConstantSource |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
GLINT_WAIT(3);
REPLICATE(color);
if ((rop == GXcopy) && (pScrn->bitsPerPixel == 32) &&
(pScrn->displayWidth <= 1600)) {
pGlint->AccelInfoRec->SubsequentSolidFillRect =
Permedia3SubsequentFillRectSolid32bpp;
if (pGlint->PM3_UsingSGRAM) {
GLINT_WRITE_REG(color, PM3FBBlockColor);
} else {
pGlint->PM3_Render2D |= PM3Render2D_SpanOperation;
GLINT_WRITE_REG(color, PM3ForegroundColor);
}
} else {
pGlint->AccelInfoRec->SubsequentSolidFillRect =
Permedia3SubsequentFillRectSolid;
if ((rop == GXcopy) && (pScrn->bitsPerPixel == 16)) {
if (pGlint->PM3_UsingSGRAM) {
GLINT_WRITE_REG(color, PM3FBBlockColor);
} else {
pGlint->PM3_Render2D |= PM3Render2D_SpanOperation;
GLINT_WRITE_REG(color, PM3ForegroundColor);
}
} else {
pGlint->PM3_Render2D |= PM3Render2D_SpanOperation;
GLINT_WRITE_REG(color, PM3ForegroundColor);
}
}
PM3_PLANEMASK(planemask);
if (((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
|| ((planemask != 0xffffffff) && !(pGlint->PM3_UsingSGRAM)))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
TRACE_EXIT("Permedia3SetupForFillRectSolid");
}
static void
Permedia3SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SubsequentFillRectSolid");
GLINT_WAIT(2);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w) | PM3Render2D_Height(h),
PM3Render2D);
TRACE_EXIT("Permedia3SubsequentFillRectSolid");
}
static void
Permedia3SubsequentFillRectSolid32bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SubsequentFillRectSolid32bpp");
GLINT_WAIT(6);
GLINT_WRITE_REG(1, PixelSize);
GLINT_WRITE_REG(
PM3FBWriteBufferWidth_Width(pScrn->displayWidth<<1),
PM3FBWriteBufferWidth0);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x<<1) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w<<1) | PM3Render2D_Height(h),
PM3Render2D);
GLINT_WRITE_REG(
PM3FBWriteBufferWidth_Width(pScrn->displayWidth),
PM3FBWriteBufferWidth0);
GLINT_WRITE_REG(0, PixelSize);
TRACE_EXIT("Permedia3SubsequentFillRectSolid32bpp");
}
static void
Permedia3SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int patternx, int patterny,
int fg, int bg, int rop,
unsigned int planemask)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SetupForMono8x8PatternFill");
REPLICATE(fg);
pGlint->PM3_Render2D =
PM3Render2D_AreaStippleEnable |
PM3Render2D_SpanOperation |
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_Normal;
pGlint->PM3_Config2D =
PM3Config2D_UseConstantSource |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
pGlint->PM3_AreaStippleMode = 1;
#if X_BYTE_ORDER == X_BIG_ENDIAN
pGlint->PM3_AreaStippleMode |= (1<<18);
#endif
pGlint->PM3_AreaStippleMode |= (2<<1);
pGlint->PM3_AreaStippleMode |= (2<<4);
if (bg != -1) {
REPLICATE(bg);
pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan;
pGlint->PM3_AreaStippleMode |= 1<<20;
GLINT_WAIT(12);
GLINT_WRITE_REG(bg, BackgroundColor);
}
else GLINT_WAIT(11);
GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0);
GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1);
GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2);
GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4);
GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5);
GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6);
GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
GLINT_WRITE_REG(fg, PM3ForegroundColor);
PM3_PLANEMASK(planemask);
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
TRACE_EXIT("Permedia3SetupForMono8x8PatternFill");
}
static void
Permedia3SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int x_offset, int y_offset,
int x, int y, int w, int h)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SubsequentMono8x8PatternFillRect");
GLINT_WAIT(3);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(
(x_offset&0x7)<<7 | (y_offset&0x7)<<12 |
pGlint->PM3_AreaStippleMode,
AreaStippleMode);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w) | PM3Render2D_Height(h),
PM3Render2D);
TRACE_EXIT("Permedia3SubsequentMono8x8PatternFillRect");
}
static void
Permedia3SetupForScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn,
int fg, int bg,
int rop,
unsigned int planemask
){
GLINTPtr pGlint = GLINTPTR(pScrn);
REPLICATE(fg);
pGlint->PM3_Render2D =
PM3Render2D_SpanOperation |
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_SyncOnBitMask;
pGlint->PM3_Config2D =
PM3Config2D_UserScissorEnable |
PM3Config2D_UseConstantSource |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
if (bg != -1) {
REPLICATE(bg);
pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan;
GLINT_WAIT(4);
GLINT_WRITE_REG(bg, BackgroundColor);
}
else GLINT_WAIT(3);
GLINT_WRITE_REG(fg, PM3ForegroundColor);
PM3_PLANEMASK(planemask);
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
}
static void
Permedia3SubsequentScanlineCPUToScreenColorExpandFill(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft
){
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia2SubsequentScanlineCPUToScreenColorExpandFill");
pGlint->dwords = ((w + 31) >> 5);
pGlint->cpucount = h;
GLINT_WAIT(5);
GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY);
GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w) | PM3Render2D_Height(h),
PM3Render2D);
#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
Permedia3SubsequentColorExpandScanline(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 Permedia3SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
unsigned int planemask, int trans_color, int bpp, int depth)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SetupForScanlineImageWrite");
pGlint->PM3_Render2D =
PM3Render2D_SpanOperation |
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_SyncOnHostData;
pGlint->PM3_Config2D =
PM3Config2D_UserScissorEnable |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
GLINT_WAIT(2);
PM3_PLANEMASK(planemask);
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
TRACE_EXIT("Permedia3SetupForScanlineImageWrite");
}
static void Permedia3SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int x, int y, int w, int h, int skipleft)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3SubsequentScanlineImageWrite");
pGlint->dwords = (((w * pScrn->bitsPerPixel) + 3) >> 2);
pGlint->cpucount = h;
GLINT_WAIT(5);
GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY);
GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w) | PM3Render2D_Height(h),
PM3Render2D);
#if defined(__alpha__)
if (0)
#else
if (pGlint->dwords < pGlint->FIFOSize)
#endif
{
pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4;
pGlint->ScanlineDirect = 1;
GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | (0x15<<4) | 0x05,
OutputFIFO);
GLINT_WAIT(pGlint->dwords);
} else {
pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer;
pGlint->ScanlineDirect = 0;
}
pGlint->cpucount--;
TRACE_EXIT("Permedia3SubsequentScanlineImageWrite");
}
static void
Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
int dwords = pGlint->dwords;
if (pGlint->ScanlineDirect) {
if (pGlint->cpucount--)
GLINT_WAIT(dwords);
return;
} else {
while(dwords >= pGlint->FIFOSize) {
GLINT_WAIT(pGlint->FIFOSize);
GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) |
0x05, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno],
pGlint->FIFOSize - 1);
dwords -= pGlint->FIFOSize - 1;
}
if(dwords) {
GLINT_WAIT(dwords + 1);
GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) |
0x05, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno],
dwords);
}
}
}
static void
Permedia3RestoreAccelState(ScrnInfoPtr pScrn)
{
GLINTPtr pGlint = GLINTPTR(pScrn);
if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) {
GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask);
}
Permedia3Sync(pScrn);
}
static void
Permedia3WritePixmap(
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
unsigned char *src,
int srcwidth,
int rop,
unsigned int planemask,
int trans,
int bpp, int depth
)
{
int dwords;
int count;
int skipleft = (long)src & 0x03L;
int Bpp = bpp >> 3;
CARD32 *srcp;
GLINTPtr pGlint = GLINTPTR(pScrn);
TRACE_ENTER("Permedia3WritePixmap");
if (skipleft) {
skipleft /= Bpp;
x -= skipleft;
w += skipleft;
src = (unsigned char*)((long)src & ~0x03L);
}
pGlint->PM3_Render2D =
PM3Render2D_SpanOperation |
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_SyncOnHostData;
pGlint->PM3_Config2D =
PM3Config2D_UserScissorEnable |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
GLINT_WAIT(6);
PM3_PLANEMASK(planemask);
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY);
GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w) | PM3Render2D_Height(h),
PM3Render2D);
dwords = ((w * Bpp) + 3) >> 2;
while(h--) {
count = dwords;
srcp = (CARD32*)src;
while(count >= pGlint->FIFOSize) {
GLINT_WAIT(pGlint->FIFOSize);
GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) |
0x05, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, pGlint->FIFOSize - 1);
count -= pGlint->FIFOSize - 1;
srcp += pGlint->FIFOSize - 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;
}
Permedia3DisableClipping(pScrn);
Permedia3Sync(pScrn);
}
static void
Permedia3WriteBitmap(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
)
{
int dwords;
GLINTPtr pGlint = GLINTPTR(pScrn);
int count;
CARD32 *srcp;
TRACE_ENTER("Permedia3WriteBitmap");
w += skipleft;
x -= skipleft;
dwords = (w + 31) >>5;
REPLICATE(fg);
pGlint->PM3_Render2D =
PM3Render2D_SpanOperation |
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_SyncOnBitMask;
pGlint->PM3_Config2D =
PM3Config2D_UserScissorEnable |
PM3Config2D_UseConstantSource |
PM3Config2D_ForegroundROPEnable |
PM3Config2D_ForegroundROP(rop) |
PM3Config2D_FBWriteEnable;
if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted))
pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable;
if (bg != -1) {
REPLICATE(bg);
pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan;
GLINT_WAIT(8);
GLINT_WRITE_REG(bg, BackgroundColor);
}
else GLINT_WAIT(7);
GLINT_WRITE_REG(fg, PM3ForegroundColor);
PM3_PLANEMASK(planemask);
GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D);
GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY);
GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY);
GLINT_WRITE_REG(
PM3RectanglePosition_XOffset(x) |
PM3RectanglePosition_YOffset(y),
PM3RectanglePosition);
GLINT_WRITE_REG(pGlint->PM3_Render2D |
PM3Render2D_Width(w) | PM3Render2D_Height(h),
PM3Render2D);
while(h--) {
count = dwords;
srcp = (CARD32*)src;
while(count >= 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);
count -= pGlint->FIFOSize - 1;
srcp += pGlint->FIFOSize - 1;
}
if(count) {
GLINT_WAIT(count + 1);
GLINT_WRITE_REG(((count - 1) << 16) | 0x0D, OutputFIFO);
GLINT_MoveDWORDS(
(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
(CARD32*)srcp, count);
}
src += srcwidth;
}
Permedia3DisableClipping(pScrn);
Permedia3Sync(pScrn);
}