diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:04:21 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 20:04:21 +0000 |
commit | 85b8022e36c5bde7945354cb63ead06f93780c91 (patch) | |
tree | 09a70f61102ceeb32dea5656f65128c5db109c4c /driver/xf86-video-glint/src/pm3_accel.c | |
parent | 825703dbe31e6b96e993914ea7a3ab0d0db77ca1 (diff) |
Importing xf86-video-glint 1.1.1
Diffstat (limited to 'driver/xf86-video-glint/src/pm3_accel.c')
-rw-r--r-- | driver/xf86-video-glint/src/pm3_accel.c | 1227 |
1 files changed, 1227 insertions, 0 deletions
diff --git a/driver/xf86-video-glint/src/pm3_accel.c b/driver/xf86-video-glint/src/pm3_accel.c new file mode 100644 index 000000000..9c96a7453 --- /dev/null +++ b/driver/xf86-video-glint/src/pm3_accel.c @@ -0,0 +1,1227 @@ +/* $XdotOrg: driver/xf86-video-glint/src/pm3_accel.c,v 1.6 2006/04/07 19:07:59 ajax Exp $ */ +/* + * Copyright 2000-2001 by Sven Luther <luther@dpt-info.u-strasbg.fr>. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sven Luther not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sven Luther makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * SVEN LUTHER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SVEN LUTHER BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Sven Luther, <luther@dpt-info.u-strasbg.fr> + * Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * this work is sponsored by Appian Graphics. + * + * Permedia 3 accelerated options. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_accel.c,v 1.30 2002/05/21 14:38:04 alanh Exp $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xarch.h> +#include "xf86.h" +#include "xf86_OSproc.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" /* For replacements */ + +#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 + +/* Clipping */ +static void Permedia3SetClippingRectangle(ScrnInfoPtr pScrn, int x, int y, + int w, int h); +static void Permedia3DisableClipping(ScrnInfoPtr pScrn); +/* ScreenToScreenCopy */ +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); +/* SolidFill */ +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); +/* 8x8 Mono Pattern Fills */ +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; + + /* Initialize the Accelerator Engine to defaults */ + 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"); + /* Only write the following register to the first PM3 */ + GLINT_SLOW_WRITE_REG(1, BroadcastMask); + GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership); + + /* Only write the following register to the second PM3 */ + GLINT_SLOW_WRITE_REG(2, BroadcastMask); + GLINT_SLOW_WRITE_REG(0x00000005, ScanLineOwnership); + + /* Make sure the rest of the register writes go to both PM3's */ + GLINT_SLOW_WRITE_REG(3, BroadcastMask); + } + + /* Disable LocalBuffer. Fixes stripes problems when + * doing screen-to-screen copies */ + 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); + + /* Host out PreInit */ + /* Set filter mode to enable sync tag & data output */ + 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); + /* Not done in P3Lib ??? */ + 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); + + /* ScissorStippleUnit Initialization (is it needed ?) */ + pGlint->ClippingOn = FALSE; + GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); + /* We never use Screen Scissor ... + GLINT_SLOW_WRITE_REG( + (pScrn->virtualX&0xffff)|((pScrn->virtualY&0xffff)<<16), + ScreenSize); + GLINT_SLOW_WRITE_REG( + (0&0xffff)|((0&0xffff)<<16), + WindowOrigin); + */ + + /* StencilDepthUnit Initialization */ + 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); + + /* FBReadUnit Initialization */ + 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(0, PM3FBDestReadBufferAddr1); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset1); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth1); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr2); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset2); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth2); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr3); + GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset3); + GLINT_SLOW_WRITE_REG( + PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), + PM3FBDestReadBufferWidth3); + */ + GLINT_SLOW_WRITE_REG( + PM3FBDestReadMode_ReadEnable | + /* Not needed, since FBDestRead is the same as FBWrite. + PM3FBDestReadMode_Blocking | + */ + 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; /* Swap host data */ +#endif + break; + case 16: + pGlint->PM3_PixelSize = 1; +#if X_BYTE_ORDER == X_BIG_ENDIAN + pGlint->RasterizerSwap = 2<<15; /* Swap host data */ +#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"); + + /* LogicalOpUnit Initialization */ + GLINT_SLOW_WRITE_REG(0xffffffff, PM3_OTHERWRITEMASK); + + /* FBWriteUnit Initialization */ + 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); + /* + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr1); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset1); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth1); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr2); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset2); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth2); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr3); + GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset3); + GLINT_SLOW_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth3); + */ + TRACE("Permedia3InitializeEngine : FBWrite"); + /* SizeOfframebuffer */ + 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"); + /* Color Format */ + 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); + + /* Other stuff */ + 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 != NULL) + (*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; + + /* Generic accel engine flags */ + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + /* Synchronization of the accel engine */ + if (pGlint->MultiAperture) + infoPtr->Sync = DualPermedia3Sync; + else + infoPtr->Sync = Permedia3Sync; + + Permedia3InitializeEngine(pScrn); + + /* Clipping Setup */ + infoPtr->ClippingFlags = 0; + infoPtr->SetClippingRectangle = Permedia3SetClippingRectangle; + infoPtr->DisableClipping = Permedia3DisableClipping; + + /* ScreenToScreenCopy */ + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + infoPtr->SetupForScreenToScreenCopy = + Permedia3SetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + Permedia3SubsequentScreenToScreenCopy; + + /* SolidFill */ + infoPtr->SolidFillFlags = 0; + infoPtr->SetupForSolidFill = Permedia3SetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = Permedia3SubsequentFillRectSolid; + + /* 8x8 Mono Pattern Fills */ + 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; + + /* Available Framebuffer Area for XAA. */ + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + /* X coords are short's so we have to do this to make sure we dont wrap*/ + AvailFBArea.y2 = ((pGlint->FbMapSize > 16384*1024) ? 16384*1024 : + pGlint->FbMapSize) / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + /* Permedia3 has a maximum 4096x4096 framebuffer */ + 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); /* hack! this shouldn't need to be reloaded */ + GLINT_WRITE_REG(0x400, FilterMode); + GLINT_WRITE_REG(0, GlintSync); + + /* Read 1st PM3 until Sync Tag shows */ + ACCESSCHIP1(); + do { + while(GLINT_READ_REG(OutFIFOWords) == 0); + } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); + + ACCESSCHIP2(); + /* Read 2nd PM3 until Sync Tag shows */ + 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; +} + +/* ScreenToScreenCopy definition */ +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); + /* Spans needs to be 32 bit aligned. */ + 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"); +} + +/* Solid Fills */ +static void +Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask) +{ + GLINTPtr pGlint = GLINTPTR(pScrn); + TRACE_ENTER("Permedia3SetupForFillRectSolid"); + /* Prepare Common Render2D & Config2D data */ + 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); + /* We can't do block fills properly at 32bpp, so we can stick the chip + * into 16bpp and double the width and xcoord, but it seems that at + * extremely high resolutions (above 1600) it doesn't fill. + * so, we fall back to the slower span filling method. + */ + 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; + /* Can't do block fills at 8bpp either */ + 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); + + /* Put the chip into 16bpp mode */ + GLINT_WRITE_REG(1, PixelSize); + /* Now double the displayWidth */ + GLINT_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth<<1), + PM3FBWriteBufferWidth0); + + /* and double the x,w coords */ + 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); + + /* Now fixup */ + GLINT_WRITE_REG( + PM3FBWriteBufferWidth_Width(pScrn->displayWidth), + PM3FBWriteBufferWidth0); + GLINT_WRITE_REG(0, PixelSize); + TRACE_EXIT("Permedia3SubsequentFillRectSolid32bpp"); +} + +/* 8x8 Mono Pattern Fills */ +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; +/* Mirror stipple pattern horizontally */ +#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); /* dwords per scanline */ + + 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) /* force Alpha to use indirect always */ +#else + if ((pGlint->dwords*h) < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than 120 dword colour expansion */ + 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 { + /* Use indirect for anything 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); + } + } +} + +/* Images Writes */ +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); /* per scanline */ + + 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) /* force Alpha to use indirect always */ +#else + if (pGlint->dwords < pGlint->FIFOSize) +#endif + { + /* Turn on direct for less than 120 dword colour expansion */ + 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 { + /* Use indirect for anything 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 is either + * - 0, 1, 2 or 3 in 8 bpp + * - 0 or 1 in 16 bpp + * - 0 in 32 bpp + */ + 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); + /* width of the stuff to copy in 32 bit words */ + dwords = ((w * Bpp) + 3) >> 2; + + while(h--) { + count = dwords; + srcp = (CARD32*)src; + while(count >= pGlint->FIFOSize) { + GLINT_WAIT(pGlint->FIFOSize); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + 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); + /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ + 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); +} |