545c082cf9
in the kaa structure: markSync and waitMarker. The first, if set, returns a hardware-dependent marker number which can then be waited for with waitMarker. If markSync is absent (which is the case on all drivers currently), waitMarker must wait for idle on any given marker number. The intention is to allow for more parallelism when we get downloading from framebuffer, or more fine-grained idling. - Replace the KdMarkSync/KdCheckSync functions with kaaMarkSync and kaaWaitSync. These will need to be refined when KAA starts being smart about using them. Merge kpict.c into kasync.c since kasyn.c has all the rest of these fallback funcs. - Restructure all drivers to initialize a KaaInfo structure by hand rather than statically in dubious order. - Whack the i810 driver into shape in hopes that it'll work after this change (it certainly wouldn't have before this). Doesn't support my i845 though. - Make a new KXV helper to avoid duplicated code to fill the region with the necessary color key. Use it in i810 and mach64 (tested).
496 lines
12 KiB
C
496 lines
12 KiB
C
/*
|
|
* Id: tridentdraw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
|
|
*
|
|
* Copyright © 1999 Keith Packard
|
|
*
|
|
* 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 Keith Packard not be used in
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
* specific, written prior permission. Keith Packard makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL KEITH PACKARD 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.
|
|
*/
|
|
/* $RCSId: xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c,v 1.10 2001/06/03 18:48:19 keithp Exp $ */
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include "chips.h"
|
|
|
|
#include <X11/Xmd.h>
|
|
#include "gcstruct.h"
|
|
#include "scrnintstr.h"
|
|
#include "pixmapstr.h"
|
|
#include "regionstr.h"
|
|
#include "mistruct.h"
|
|
#include "fontstruct.h"
|
|
#include "dixfontstr.h"
|
|
#include "fb.h"
|
|
#include "migc.h"
|
|
#include "miline.h"
|
|
#include "kaa.h"
|
|
|
|
CARD8 chipsBltRop[16] = {
|
|
/* GXclear */ 0x00, /* 0 */
|
|
/* GXand */ 0x88, /* src AND dst */
|
|
/* GXandReverse */ 0x44, /* src AND NOT dst */
|
|
/* GXcopy */ 0xcc, /* src */
|
|
/* GXandInverted*/ 0x22, /* NOT src AND dst */
|
|
/* GXnoop */ 0xaa, /* dst */
|
|
/* GXxor */ 0x66, /* src XOR dst */
|
|
/* GXor */ 0xee, /* src OR dst */
|
|
/* GXnor */ 0x11, /* NOT src AND NOT dst */
|
|
/* GXequiv */ 0x99, /* NOT src XOR dst */
|
|
/* GXinvert */ 0x55, /* NOT dst */
|
|
/* GXorReverse */ 0xdd, /* src OR NOT dst */
|
|
/* GXcopyInverted*/ 0x33, /* NOT src */
|
|
/* GXorInverted */ 0xbb, /* NOT src OR dst */
|
|
/* GXnand */ 0x77, /* NOT src OR NOT dst */
|
|
/* GXset */ 0xff, /* 1 */
|
|
};
|
|
|
|
CARD8 chipsSolidRop[16] = {
|
|
/* GXclear */ 0x00, /* 0 */
|
|
/* GXand */ 0xa0, /* src AND dst */
|
|
/* GXandReverse */ 0x50, /* src AND NOT dst */
|
|
/* GXcopy */ 0xf0, /* src */
|
|
/* GXandInverted*/ 0x0a, /* NOT src AND dst */
|
|
/* GXnoop */ 0xaa, /* dst */
|
|
/* GXxor */ 0x5a, /* src XOR dst */
|
|
/* GXor */ 0xfa, /* src OR dst */
|
|
/* GXnor */ 0x05, /* NOT src AND NOT dst */
|
|
/* GXequiv */ 0xa5, /* NOT src XOR dst */
|
|
/* GXinvert */ 0x55, /* NOT dst */
|
|
/* GXorReverse */ 0xf5, /* src OR NOT dst */
|
|
/* GXcopyInverted*/ 0x0f, /* NOT src */
|
|
/* GXorInverted */ 0xaf, /* NOT src OR dst */
|
|
/* GXnand */ 0x5f, /* NOT src OR NOT dst */
|
|
/* GXset */ 0xff, /* 1 */
|
|
};
|
|
|
|
/* Definitions for the Chips and Technology BitBLT engine communication. */
|
|
/* These are done using Memory Mapped IO, of the registers */
|
|
/* BitBLT modes for register 93D0. */
|
|
|
|
#ifdef HIQV
|
|
#define ctPATCOPY 0xF0
|
|
#define ctLEFT2RIGHT 0x000
|
|
#define ctRIGHT2LEFT 0x100
|
|
#define ctTOP2BOTTOM 0x000
|
|
#define ctBOTTOM2TOP 0x200
|
|
#define ctSRCSYSTEM 0x400
|
|
#define ctDSTSYSTEM 0x800
|
|
#define ctSRCMONO 0x1000
|
|
#define ctBGTRANSPARENT 0x22000
|
|
#define ctCOLORTRANSENABLE 0x4000
|
|
#define ctCOLORTRANSDISABLE 0x0
|
|
#define ctCOLORTRANSDST 0x8000
|
|
#define ctCOLORTRANSROP 0x0
|
|
#define ctCOLORTRANSEQUAL 0x10000L
|
|
#define ctCOLORTRANSNEQUAL 0x0
|
|
#define ctPATMONO 0x40000L
|
|
#define ctPATSOLID 0x80000L
|
|
#define ctPATSTART0 0x000000L
|
|
#define ctPATSTART1 0x100000L
|
|
#define ctPATSTART2 0x200000L
|
|
#define ctPATSTART3 0x300000L
|
|
#define ctPATSTART4 0x400000L
|
|
#define ctPATSTART5 0x500000L
|
|
#define ctPATSTART6 0x600000L
|
|
#define ctPATSTART7 0x700000L
|
|
#define ctSRCFG 0x000000L /* Where is this for the 65550?? */
|
|
#else
|
|
#define ctPATCOPY 0xF0
|
|
#define ctTOP2BOTTOM 0x100
|
|
#define ctBOTTOM2TOP 0x000
|
|
#define ctLEFT2RIGHT 0x200
|
|
#define ctRIGHT2LEFT 0x000
|
|
#define ctSRCFG 0x400
|
|
#define ctSRCMONO 0x800
|
|
#define ctPATMONO 0x1000
|
|
#define ctBGTRANSPARENT 0x2000
|
|
#define ctSRCSYSTEM 0x4000
|
|
#define ctPATSOLID 0x80000L
|
|
#define ctPATSTART0 0x00000L
|
|
#define ctPATSTART1 0x10000L
|
|
#define ctPATSTART2 0x20000L
|
|
#define ctPATSTART3 0x30000L
|
|
#define ctPATSTART4 0x40000L
|
|
#define ctPATSTART5 0x50000L
|
|
#define ctPATSTART6 0x60000L
|
|
#define ctPATSTART7 0x70000L
|
|
#endif
|
|
|
|
#define chipsFillPix(bpp,pixel) {\
|
|
if (bpp == 8) \
|
|
{ \
|
|
pixel = pixel & 0xff; \
|
|
} \
|
|
else if (bpp == 16) \
|
|
{ \
|
|
pixel = pixel & 0xffff; \
|
|
} \
|
|
}
|
|
|
|
static VOL8 *mmio;
|
|
static CARD32 byteStride;
|
|
static CARD32 bytesPerPixel;
|
|
static CARD32 pixelStride;
|
|
|
|
static void
|
|
chipsSet (ScreenPtr pScreen)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
chipsScreenInfo(pScreenPriv);
|
|
|
|
mmio = chipss->mmio_base;
|
|
byteStride = pScreenPriv->screen->fb[0].byteStride;
|
|
bytesPerPixel = pScreenPriv->screen->fb[0].bitsPerPixel >> 3;
|
|
pixelStride = pScreenPriv->screen->fb[0].pixelStride;
|
|
}
|
|
|
|
static void
|
|
chipsWaitMarker (ScreenPtr pScreen, int marker)
|
|
{
|
|
chipsSet (pScreen);
|
|
chipsWaitIdle ();
|
|
}
|
|
|
|
#ifdef HIQV
|
|
#define CHIPS_BR0 0x00 /* offset */
|
|
#define CHIPS_BR1 0x04 /* bg */
|
|
#define CHIPS_BR2 0x08 /* fg */
|
|
#define CHIPS_BR3 0x0c /* monochrome */
|
|
#define CHIPS_BR4 0x10 /* bitblt */
|
|
#define CHIPS_BR5 0x14 /* pattern addr */
|
|
#define CHIPS_BR6 0x18 /* source addr */
|
|
#define CHIPS_BR7 0x1c /* dst addr */
|
|
#define CHIPS_BR8 0x20 /* dst w/h */
|
|
#else
|
|
#define CHIPS_DR0 0x83d0
|
|
#define CHIPS_DR1 0x87d0
|
|
#define CHIPS_DR2 0x8bd0
|
|
#define CHIPS_DR3 0x8fd0
|
|
#define CHIPS_DR4 0x93d0
|
|
#define CHIPS_DR5 0x97d0
|
|
#define CHIPS_DR6 0x9bd0
|
|
#define CHIPS_DR7 0x9fd0
|
|
#endif
|
|
|
|
#define DBG(x)
|
|
|
|
static void
|
|
chipsPitch (int src, int dst)
|
|
{
|
|
CARD32 p;
|
|
|
|
p = ((dst & 0xffff) << 16) | (src & 0xffff);
|
|
DBG(ErrorF ("\tpitch 0x%x\n", p));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR0) = p;
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR0) = p;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsBg (Pixel bg)
|
|
{
|
|
DBG(ErrorF ("\tbg 0x%x\n", bg));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR1) = bg & 0xffff;
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR2) = bg;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsFg (Pixel fg)
|
|
{
|
|
DBG(ErrorF ("\tfg 0x%x\n", fg));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR2) = fg;
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR3) = fg;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsOp (CARD32 op)
|
|
{
|
|
DBG(ErrorF ("\top 0x%x\n", op));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR4) = op;
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR4) = op;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsRopSolid (int rop)
|
|
{
|
|
CARD32 op;
|
|
|
|
op = chipsSolidRop[rop] | ctTOP2BOTTOM | ctLEFT2RIGHT | ctPATSOLID | ctPATMONO;
|
|
chipsOp (op);
|
|
}
|
|
|
|
static void
|
|
chipsSrc (int addr)
|
|
{
|
|
DBG(ErrorF ("\tsrc 0x%x\n", addr));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR6) = addr;
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR5) = addr;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsDst (int addr)
|
|
{
|
|
DBG(ErrorF ("\tdst 0x%x\n", addr));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR7) = addr;
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR6) = addr;
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsWidthHeightGo (int w, int h)
|
|
{
|
|
DBG(ErrorF ("\twidth height %d/%d\n", w, h));
|
|
#ifdef HIQV
|
|
*(VOL32 *) (mmio + CHIPS_BR8) = ((h & 0xffff) << 16) | (w & 0xffff);
|
|
#else
|
|
*(VOL32 *) (mmio + CHIPS_DR7) = ((h & 0xffff) << 16) | (w & 0xffff);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
chipsWaitIdle (void)
|
|
{
|
|
#ifdef HIQV
|
|
int timeout = 0;
|
|
CARD8 tmp;
|
|
VOL32 *br4 = (VOL32 *) (mmio + CHIPS_BR4);
|
|
|
|
DBG(ErrorF ("\tBR4 0x%x 0x%x\n", mmio + CHIPS_BR4, *br4));
|
|
DBG(ErrorF ("\tXR20 0x%x\n", chipsReadXR (0, 0x20)));
|
|
for (;;)
|
|
{
|
|
if ((*br4 & 0x80000000) == 0)
|
|
break;
|
|
tmp = chipsReadXR (0, 0x20);
|
|
if ((tmp & 1) == 0)
|
|
break;
|
|
if (++timeout > 1000000)
|
|
{
|
|
ErrorF ("timeout\n");
|
|
tmp = chipsReadXR (0, 0x20);
|
|
chipsWriteXR (0, 0x20, tmp | 2);
|
|
sleep (1);
|
|
chipsWriteXR (0, 0x20, tmp);
|
|
sleep (1);
|
|
}
|
|
}
|
|
#else
|
|
while (*(VOL32 *) (mmio + CHIPS_DR4) & 0x00100000)
|
|
;
|
|
#endif
|
|
}
|
|
|
|
static Bool
|
|
chipsPrepareSolid (PixmapPtr pPixmap,
|
|
int alu,
|
|
Pixel pm,
|
|
Pixel fg)
|
|
{
|
|
FbBits depthMask;
|
|
|
|
DBG(ErrorF ("PrepareSolid %d 0x%x\n", alu, fg));
|
|
depthMask = FbFullMask(pPixmap->drawable.depth);
|
|
if ((pm & depthMask) != depthMask)
|
|
return FALSE;
|
|
else
|
|
{
|
|
chipsSet (pPixmap->drawable.pScreen);
|
|
chipsWaitIdle ();
|
|
chipsFillPix(pPixmap->drawable.bitsPerPixel,fg);
|
|
chipsFg (fg);
|
|
chipsBg (fg);
|
|
chipsRopSolid (alu);
|
|
chipsPitch (byteStride, byteStride);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
static void
|
|
chipsSolid (int x1, int y1, int x2, int y2)
|
|
{
|
|
CARD32 dst;
|
|
int w, h;
|
|
|
|
DBG(ErrorF (" Solid %dx%d %dx%d\n", x1, y1, x2, y2));
|
|
dst = y1 * byteStride + x1 * bytesPerPixel;
|
|
w = (x2 - x1) * bytesPerPixel;
|
|
h = (y2 - y1);
|
|
chipsWaitIdle ();
|
|
chipsDst (dst);
|
|
chipsWidthHeightGo (w, h);
|
|
}
|
|
|
|
static void
|
|
chipsDoneSolid (void)
|
|
{
|
|
}
|
|
|
|
static CARD32 copyOp;
|
|
|
|
static Bool
|
|
chipsPrepareCopy (PixmapPtr pSrcPixmap,
|
|
PixmapPtr pDstPixmap,
|
|
int dx,
|
|
int dy,
|
|
int alu,
|
|
Pixel pm)
|
|
{
|
|
FbBits depthMask;
|
|
|
|
DBG(ErrorF ("PrepareSolid %d 0x%x\n", alu, fg));
|
|
depthMask = FbFullMask(pDstPixmap->drawable.depth);
|
|
if ((pm & depthMask) != depthMask)
|
|
return FALSE;
|
|
else
|
|
{
|
|
copyOp = chipsBltRop[alu];
|
|
if (dy >= 0)
|
|
copyOp |= ctTOP2BOTTOM;
|
|
else
|
|
copyOp |= ctBOTTOM2TOP;
|
|
if (dx >= 0)
|
|
copyOp |= ctLEFT2RIGHT;
|
|
else
|
|
copyOp |= ctRIGHT2LEFT;
|
|
chipsSet (pDstPixmap->drawable.pScreen);
|
|
chipsWaitIdle ();
|
|
chipsOp (copyOp);
|
|
chipsPitch (byteStride, byteStride);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
static void
|
|
chipsCopy (int srcX,
|
|
int srcY,
|
|
int dstX,
|
|
int dstY,
|
|
int w,
|
|
int h)
|
|
{
|
|
int src, dst;
|
|
if ((copyOp & (ctTOP2BOTTOM|ctBOTTOM2TOP)) == ctBOTTOM2TOP)
|
|
{
|
|
src = (srcY + h - 1) * byteStride;
|
|
dst = (dstY + h - 1) * byteStride;
|
|
}
|
|
else
|
|
{
|
|
src = srcY * byteStride;
|
|
dst = dstY * byteStride;
|
|
}
|
|
if ((copyOp & (ctLEFT2RIGHT|ctRIGHT2LEFT)) == ctRIGHT2LEFT)
|
|
{
|
|
src = src + (srcX + w) * bytesPerPixel - 1;
|
|
dst = dst + (dstX + w) * bytesPerPixel - 1;
|
|
}
|
|
else
|
|
{
|
|
src = src + srcX * bytesPerPixel;
|
|
dst = dst + dstX * bytesPerPixel;
|
|
}
|
|
chipsWaitIdle ();
|
|
chipsSrc (src);
|
|
chipsDst (dst);
|
|
chipsWidthHeightGo (w * bytesPerPixel, h);
|
|
}
|
|
|
|
static void
|
|
chipsDoneCopy (void)
|
|
{
|
|
}
|
|
|
|
Bool
|
|
chipsDrawInit (ScreenPtr pScreen)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
chipsScreenInfo(pScreenPriv);
|
|
|
|
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
|
|
case 8:
|
|
case 16:
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
memset(&chipss->kaa, 0, sizeof(KaaScreenInfoRec));
|
|
chipss->kaa.waitMarker = chipsWaitMarker;
|
|
chipss->kaa.PrepareSolid = chipsPrepareSolid;
|
|
chipss->kaa.Solid = chipsSolid;
|
|
chipss->kaa.DoneSolid = chipsDoneSolid;
|
|
chipss->kaa.PrepareCopy = chipsPrepareCopy;
|
|
chipss->kaa.Copy = chipsCopy;
|
|
chipss->kaa.DoneCopy = chipsDoneCopy;
|
|
|
|
if (!kaaDrawInit (pScreen, &chipss->kaa))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
chipsDrawEnable (ScreenPtr pScreen)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
chipsScreenInfo(pScreenPriv);
|
|
CARD8 mode = 0x00;
|
|
|
|
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
|
|
case 8:
|
|
mode = 0x00;
|
|
break;
|
|
case 16:
|
|
mode = 0x10;
|
|
break;
|
|
}
|
|
chipsSet (pScreen);
|
|
chipsWaitIdle ();
|
|
chipsWriteXR (chipss, 0x20, mode);
|
|
|
|
kaaMarkSync (pScreen);
|
|
}
|
|
|
|
void
|
|
chipsDrawDisable (ScreenPtr pScreen)
|
|
{
|
|
}
|
|
|
|
void
|
|
chipsDrawFini (ScreenPtr pScreen)
|
|
{
|
|
}
|
|
|