aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/neomagic/neo_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/neomagic/neo_draw.c')
-rw-r--r--xorg-server/hw/kdrive/neomagic/neo_draw.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/neomagic/neo_draw.c b/xorg-server/hw/kdrive/neomagic/neo_draw.c
new file mode 100644
index 000000000..89452b3d8
--- /dev/null
+++ b/xorg-server/hw/kdrive/neomagic/neo_draw.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright © 2004 Franco Catrin
+ *
+ * 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 Franco Catrin not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Franco Catrin makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FRANCO CATRIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FRANCO CATRIN 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "neomagic.h"
+
+#include <X11/Xmd.h>
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "mistruct.h"
+#include "dixfontstr.h"
+#include "fb.h"
+#include "migc.h"
+#include "miline.h"
+#include "picturestr.h"
+
+NeoMMIO *mmio;
+NeoScreenInfo *screen;
+NeoCardInfo *card;
+CARD32 fgColor;
+CARD32 rop;
+
+CARD32 neoRop[16] = {
+ 0x000000, /* GXclear */
+ 0x080000, /* GXand */
+ 0x040000, /* GXandReverse */
+ 0x0c0000, /* GXcopy */
+ 0x020000, /* GXandInvert */
+ 0x0a0000, /* GXnoop */
+ 0x060000, /* GXxor */
+ 0x0e0000, /* GXor */
+ 0x010000, /* GXnor */
+ 0x090000, /* GXequiv */
+ 0x050000, /* GXinvert */
+ 0x0d0000, /* GXorReverse */
+ 0x030000, /* GXcopyInvert */
+ 0x0b0000, /* GXorInverted */
+ 0x070000, /* GXnand */
+ 0x0f0000 /* GXset */
+};
+
+static void neoWaitIdle(NeoCardInfo *neoc)
+{
+ // if MMIO is not working it may halt the machine
+ unsigned int i = 0;
+ while ((mmio->bltStat & 1) && ++i<100000);
+}
+
+static void neoWaitMarker (ScreenPtr pScreen, int marker)
+{
+ KdScreenPriv(pScreen);
+ neoCardInfo(pScreenPriv);
+
+ neoWaitIdle(neoc);
+}
+
+
+static Bool neoPrepareSolid(PixmapPtr pPixmap,
+ int alu,
+ Pixel pm,
+ Pixel fg)
+{
+ FbBits depthMask = FbFullMask(pPixmap->drawable.depth);
+ if ((pm & depthMask) != depthMask) {
+ return FALSE;
+ } else {
+ fgColor = fg;
+ if (alu!=3) DBGOUT("used ROP %i\n", alu);
+ rop = neoRop[alu];
+ return TRUE;
+ }
+}
+
+static void neoSolid (int x1, int y1, int x2, int y2)
+{
+ int x, y, w, h;
+ x = x1;
+ y = y1;
+ w = x2-x1;
+ h = y2-y1;
+ neoWaitIdle(card);
+ mmio->fgColor = fgColor;
+ mmio->bltCntl =
+ NEO_BC3_FIFO_EN |
+ NEO_BC0_SRC_IS_FG |
+ NEO_BC3_SKIP_MAPPING | rop;
+ mmio->dstStart = y * screen->pitch + x * screen->depth;
+
+ mmio->xyExt = (unsigned long)(h << 16) | (w & 0xffff);
+
+}
+
+
+static void neoDoneSolid(void)
+{
+}
+
+static Bool neoPrepareCopy (PixmapPtr pSrcPixpam, PixmapPtr pDstPixmap,
+ int dx, int dy, int alu, Pixel pm)
+{
+ rop = neoRop[alu];
+ return TRUE;
+}
+
+static void neoCopy (int srcX, int srcY, int dstX, int dstY, int w, int h)
+{
+ neoWaitIdle(card);
+
+ if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
+ mmio->bltCntl =
+ NEO_BC3_FIFO_EN |
+ NEO_BC3_SKIP_MAPPING | rop;
+ mmio->srcStart = srcY * screen->pitch + srcX * screen->depth;
+ mmio->dstStart = dstY * screen->pitch + dstX * screen->depth;
+
+ mmio->xyExt = (unsigned long)(h << 16) | (w & 0xffff);
+ } else {
+ mmio->bltCntl = NEO_BC0_X_DEC |
+ NEO_BC0_DST_Y_DEC |
+ NEO_BC0_SRC_Y_DEC |
+ NEO_BC3_FIFO_EN |
+ NEO_BC3_SKIP_MAPPING | rop;
+ srcX+=w-1;
+ dstX+=w-1;
+ srcY+=h-1;
+ dstY+=h-1;
+ mmio->srcStart = srcY * screen->pitch + srcX * screen->depth;
+ mmio->dstStart = dstY * screen->pitch + dstX * screen->depth;
+ mmio->xyExt = (unsigned long)(h << 16) | (w & 0xffff);
+ }
+
+}
+
+static void neoDoneCopy (void)
+{
+}
+
+
+Bool neoDrawInit (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ neoScreenInfo(pScreenPriv);
+
+ ENTER();
+
+ memset(&neos->kaa, 0, sizeof(KaaScreenInfoRec));
+ neos->kaa.waitMarker = neoWaitMarker;
+ neos->kaa.PrepareSolid = neoPrepareSolid;
+ neos->kaa.Solid = neoSolid;
+ neos->kaa.DoneSolid = neoDoneSolid;
+ neos->kaa.PrepareCopy = neoPrepareCopy;
+ neos->kaa.Copy = neoCopy;
+ neos->kaa.DoneCopy = neoDoneCopy;
+
+ if (!kaaDrawInit (pScreen, &neos->kaa)) {
+ return FALSE;
+ }
+ LEAVE();
+ return TRUE;
+}
+
+void neoDrawEnable (ScreenPtr pScreen)
+{
+ ENTER();
+ SetupNeo(pScreen);
+ screen = neos;
+ card = neoc;
+ mmio = neoc->mmio;
+ screen->depth = (screen->backendScreen.mode.BitsPerPixel+7)/8;
+ screen->pitch = screen->backendScreen.mode.BytesPerScanLine;
+ DBGOUT("NEO depth=%x, pitch=%x\n", screen->depth, screen->pitch);
+ LEAVE();
+}
+
+void neoDrawDisable (ScreenPtr pScreen)
+{
+ ENTER();
+ LEAVE();
+}
+
+void neoDrawFini (ScreenPtr pScreen)
+{
+ ENTER();
+ LEAVE();
+}
+