aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/via/viadraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/via/viadraw.c')
-rw-r--r--xorg-server/hw/kdrive/via/viadraw.c499
1 files changed, 499 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/via/viadraw.c b/xorg-server/hw/kdrive/via/viadraw.c
new file mode 100644
index 000000000..a6544ee36
--- /dev/null
+++ b/xorg-server/hw/kdrive/via/viadraw.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright © 2004 Ralph Thomas
+ *
+ * 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 Ralph Thomas not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Ralph Thomas makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * RALPH THOMAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL RALPH THOMAS 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.
+ */
+/*
+** VIA CLE266 driver
+** Copyright 2004 (C) Ralph Thomas <ralpht@gmail.com>
+**
+** http://www.viatech.com.tw/
+**
+** This code is for accelerated drawing of solids and accelerated
+** copies. Note that there is currently no software FIFO implemented,
+** and no documentation on any hardware FIFO.
+*/
+
+#include "via.h"
+#include "viadraw.h"
+#include "via_regs.h"
+#include <sched.h>
+#include "kdrive.h"
+#include "kaa.h"
+
+/*
+** A global to contain card information between calls into this file.
+** XXX: This is totally brain-damaged. Why don't I get the information
+** I want in viaSolid/viaCopy/viaDoneXXX?
+*/
+static ViaCardInfo* card;
+
+/*
+** Translation table from GC raster operation values into ROP3 values
+** that the VIA chip understands.
+**
+** viaPatternRop is used by viaPrepareSolid.
+** viaCopyRop is used by viaPrepareCopy.
+*/
+CARD8 viaPatternRop[16] = {
+ /* GXclear */ 0x00, /* ROP_0 0 */
+ /* GXand */ 0xA0, /* ROP_DPa src AND dst */
+ /* GXandReverse */ 0x50, /* ROP_PDna src AND NOT dst */
+ /* GXcopy */ 0xF0, /* ROP_P src */
+ /* GXandInverted*/ 0x0A, /* ROP_DPna NOT src AND dst */
+ /* GXnoop */ 0xAA, /* ROP_D dst */
+ /* GXxor */ 0x5A, /* ROP_DPx src XOR dst */
+ /* GXor */ 0xFA, /* ROP_DPo src OR dst */
+ /* GXnor */ 0x05, /* ROP_DPon NOT src AND NOT dst */
+ /* GXequiv */ 0xA5, /* ROP_PDxn NOT src XOR dst */
+ /* GXinvert */ 0x55, /* ROP_Dn NOT dst */
+ /* GXorReverse */ 0xF5, /* ROP_PDno src OR NOT dst */
+ /* GXcopyInverted*/ 0x0F, /* ROP_Pn NOT src */
+ /* GXorInverted */ 0xAF, /* ROP_DPno NOT src OR dst */
+ /* GXnand */ 0x5F, /* ROP_DPan NOT src OR NOT dst */
+ /* GXset */ 0xFF, /* ROP_1 1 */
+};
+
+CARD8 viaCopyRop[16] = {
+ /* GXclear */ 0x00, /* ROP_0 0 */
+ /* GXand */ 0x88, /* ROP_DSa src AND dst */
+ /* GXandReverse */ 0x44, /* ROP_SDna src AND NOT dst */
+ /* GXcopy */ 0xCC, /* ROP_S src */
+ /* GXandInverted*/ 0x22, /* ROP_DSna NOT src AND dst */
+ /* GXnoop */ 0xAA, /* ROP_D dst */
+ /* GXxor */ 0x66, /* ROP_DSx src XOR dst */
+ /* GXor */ 0xEE, /* ROP_DSo src OR dst */
+ /* GXnor */ 0x11, /* ROP_DSon NOT src AND NOT dst */
+ /* GXequiv */ 0x99, /* ROP_DSxn NOT src XOR dst */
+ /* GXinvert */ 0x55, /* ROP_Dn NOT dst */
+ /* GXorReverse */ 0xDD, /* ROP_SDno src OR NOT dst */
+ /* GXcopyInverted*/ 0x33, /* ROP_Sn NOT src */
+ /* GXorInverted */ 0xBB, /* ROP_DSno NOT src OR dst */
+ /* GXnand */ 0x77, /* ROP_DSan NOT src OR NOT dst */
+ /* GXset */ 0xFF, /* ROP_1 1 */
+};
+
+/*
+** void viaWaitIdle( ViaCardInfo* viac )
+**
+** Description:
+** Block up the CPU while waiting for the last command sent to
+** the chip to complete. As an experiment I'm going to try to
+** yield my process to others instead of just tight looping.
+**
+** Arguments:
+** viac VIA-driver specific chip information
+**
+** Return:
+** None.
+*/
+void
+viaWaitIdle( ViaCardInfo* viac ) {
+ while( INREG32( VIA_REG_STATUS ) & VIA_BUSY )
+ sched_yield();
+}
+
+/*
+** void viaDrawSync( ScreenPtr pScreen, int marker )
+**
+** Description:
+** Block until the graphics chip has finished all outstanding drawing
+** operations and the framebuffer contents is static.
+**
+** Arguments:
+** pScreen Pointer to screen strucutre for the screen we're
+** waiting for drawing to end on.
+**
+** Return:
+** None.
+*/
+static void
+viaWaitMarker( ScreenPtr pScreen, int marker ) {
+ KdScreenPriv( pScreen );
+ ViaCardInfo* viac = pScreenPriv->card->driver;
+
+ viaWaitIdle( viac );
+}
+
+
+/*
+** Bool viaPrepareSolid( PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg )
+**
+** Description:
+** Decide if the specified solid fill operation can be accelerated or not,
+** and if the fill can be accelerated, prepare the hardware for doing it.
+**
+** Arguments:
+** pPixmap Pixmap to draw solid into.
+** alu Raster operation to draw using, these are the same
+** values which get set by XSetFunction(3X). See the
+** Xlib PM p. 140 for a list of raster operations as
+** well as descriptions.
+** planemask This is the GC plane mask. We only copy bits which
+** match the plane mask.
+** fg The foreground pixel of the GC, the pixel to draw in.
+**
+** Return:
+** TRUE This operation can be accelerated, call viaSolid to actually
+** have it drawn.
+** FALSE This operation cannot be accelerated, fall back to software.
+**
+** See Also:
+** viaSolid - the function which actually draws the solid.
+*/
+static Bool
+viaPrepareSolid( PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg ) {
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ KdScreenPriv( pScreen );
+ ViaCardInfo* viac = pScreenPriv->card->driver;
+
+ /*
+ ** We don't accelerate when the plane mask is not everything.
+ */
+ if( ~planeMask & FbFullMask( pPixmap->drawable.depth ) ) return FALSE;
+
+ /*
+ ** Compose the command, then store the composed command and color
+ ** in the viac structure so that when viaSolid gets called we can
+ ** write them out.
+ */
+ viac->savedCommand = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT |
+ (viaPatternRop[alu] << 24);
+ viac->savedFgColor = fg;
+
+ /*
+ ** Store pointer to chip information, due to brain-damaged KAA.
+ */
+ card = viac;
+
+ return TRUE;
+}
+
+/*
+** void viaSolid( int x1, int y1, int x2, int y2 )
+**
+** Description:
+** Perform a solid fill, using the data that was stored by viaPrepareSolid.
+**
+** Arguments:
+** x1 x-coordinate of fill origin
+** y1 y-coordinate of fill origin
+** x2 x-coordinate of fill end point
+** y2 y-coordinate of fill end point
+**
+** Return:
+** None.
+**
+** See Also:
+** viaPrepareSolid - the function that composes the GE command and saves
+** the color for us.
+*/
+static void
+viaSolid( int x1, int y1, int x2, int y2 ) {
+ ViaCardInfo* viac = card;
+ int w = x2 - x1; int h = y2 - y1;
+
+ if( !viac ) return;
+ if( !w || !h ) return;
+
+ /*
+ ** Wait for the card to finish the current draw.
+ */
+ viaWaitIdle( viac );
+
+ /*
+ ** Do the draw.
+ */
+ OUTREG32( VIA_REG_DSTPOS, ((y1 << 16) | x1) );
+ OUTREG32( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)) );
+ OUTREG32( VIA_REG_FGCOLOR, viac->savedFgColor );
+ OUTREG32( VIA_REG_GECMD, viac->savedCommand );
+}
+
+/*
+** void viaDoneSolid
+**
+** Description:
+** Finish up drawing of the solid.
+**
+** Arguments:
+** None.
+**
+** Return:
+** None.
+*/
+static void
+viaDoneSolid(void) {
+}
+
+/*
+** Bool viaPrepareCopy( PixmapPtr pSrcPixmap, PixmapPtr pDestPixmap, int dx,
+** int dy, int alu, Pixel planeMask )
+**
+** Description:
+** Set up the VIA chip for a BitBlt.
+**
+** Arguments:
+** pSrcPixmap the source pixmap to copy from
+** pDestPixmap the destination pixmap to copy to
+** dx direction of copy in x
+** dy direction of copy in y
+** alu Raster operation to draw using, these are the same
+** values which get set by XSetFunction(3X). See the
+** Xlib PM p. 140 for a list of raster operations as
+** well as descriptions.
+** planeMask This is the GC plane mask. We only copy bits which
+** match the plane mask.
+**
+** Return:
+** TRUE the requested copy operation can be accelerated using hardware,
+** call viaCopy next.
+** FALSE the requested copy operation cannot be accelerated using
+** hardware - fallback to software.
+**
+** See Also:
+** viaCopy - the function which does the actual copy.
+*/
+static Bool
+viaPrepareCopy( PixmapPtr pSrcPixmap, PixmapPtr pDestPixmap, int dx, int dy,
+ int alu, Pixel planeMask ) {
+ ScreenPtr pScreen = pDestPixmap->drawable.pScreen;
+ KdScreenPriv( pScreen );
+ ViaCardInfo* viac = pScreenPriv->card->driver;
+
+ /*
+ ** Don't accelerate when the plane mask is set.
+ */
+ if( ~planeMask & FbFullMask( pDestPixmap->drawable.depth ) ) return FALSE;
+
+ viac->savedCommand = VIA_GEC_BLT | (viaCopyRop[alu] << 24);
+
+ if( dx < 0 ) viac->savedCommand |= VIA_GEC_DECX;
+ if( dy < 0 ) viac->savedCommand |= VIA_GEC_DECY;
+
+ /*
+ ** Store pointer to chip structure, due to brain-damaged KAA.
+ */
+ card = viac;
+
+ return TRUE;
+}
+
+/*
+** void viaCopy( int srcX, int srcY, int dstX, int dstY, int w, int h )
+**
+** Description:
+** Perform a BitBlt from one screen area to another.
+**
+** Arguments:
+** srcX source x-coordinate
+** srcY source y-coordinate
+** dstX destination x-coordinate
+** dstY destination y-coordinate
+** w width of area to copy (pixels)
+** h height of area to copy (pixels)
+**
+** Return:
+** None.
+**
+** See Also:
+** viaPrepareCopy - the function which sets up for the copy.
+*/
+static void
+viaCopy( int srcX, int srcY, int dstX, int dstY, int w, int h ) {
+ ViaCardInfo* viac = card;
+
+ if( !viac ) return;
+ if( !w | !h ) return;
+
+ /*
+ ** XXX: Check these two "if"s out.
+ */
+ if( viac->savedCommand & VIA_GEC_DECX ) {
+ srcX += ( w - 1 );
+ dstX += ( w - 1 );
+ }
+
+ if( viac->savedCommand & VIA_GEC_DECY ) {
+ srcY += ( h - 1 );
+ dstY += ( h - 1 );
+ }
+
+ OUTREG32( VIA_REG_SRCPOS, ((srcY << 16) | srcX) );
+ OUTREG32( VIA_REG_DSTPOS, ((dstY << 16) | dstX) );
+ OUTREG32( VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)) );
+ OUTREG32( VIA_REG_GECMD, viac->savedCommand );
+}
+
+/*
+** void viaDoneCopy()
+**
+** Description:
+** Finish up the copy.
+**
+** Arguments:
+** None.
+**
+** Return:
+** None.
+*/
+static void
+viaDoneCopy(void) {
+}
+
+
+/*
+** Bool viaDrawInit( ScreenPtr pScreen )
+**
+** Description:
+** Initialize the 2D acceleration hardware and register the KAA
+** acceleration layer with the VIA acceleration functions (above).
+**
+** Arguments:
+** pScreen Pointer to screen structure for the screen we're
+** enabling acceleration on.
+**
+** Return:
+** TRUE initialization and setup of KAA acceleration was successful.
+** FALSE initialization and setup of KAA acceleration failed.
+*/
+Bool
+viaDrawInit( ScreenPtr pScreen ) {
+ KdScreenPriv( pScreen );
+ ViaCardInfo* viac = pScreenPriv->card->driver;
+ ViaScreenInfo* vias = pScreenPriv->card->driver;
+ CARD32 geMode = 0;
+
+ if( !viac ) return FALSE;
+ DebugF( "viac->mapBase = 0x%x\n", viac->mapBase );
+
+ /*
+ ** We reset the 2D engine to a known state by setting all of it's
+ ** registers to zero.
+ */
+ OUTREG32( VIA_REG_GEMODE, 0x0 );
+ OUTREG32( VIA_REG_SRCPOS, 0x0 );
+ OUTREG32( VIA_REG_DSTPOS, 0x0 );
+ OUTREG32( VIA_REG_DIMENSION, 0x0 );
+ OUTREG32( VIA_REG_PATADDR, 0x0 );
+ OUTREG32( VIA_REG_FGCOLOR, 0x0 );
+ OUTREG32( VIA_REG_BGCOLOR, 0x0 );
+ OUTREG32( VIA_REG_CLIPTL, 0x0 );
+ OUTREG32( VIA_REG_CLIPBR, 0x0 );
+ OUTREG32( VIA_REG_OFFSET, 0x0 );
+ OUTREG32( VIA_REG_KEYCONTROL, 0x0 );
+ OUTREG32( VIA_REG_SRCBASE, 0x0 );
+ OUTREG32( VIA_REG_DSTBASE, 0x0 );
+ OUTREG32( VIA_REG_PITCH, 0x0 );
+ OUTREG32( VIA_REG_MONOPAT0, 0x0 );
+ OUTREG32( VIA_REG_MONOPAT1, 0x0 );
+
+ /*
+ ** Set the GE mode up.
+ ** XXX: What happens in 24bpp mode?
+ */
+ switch( pScreenPriv->screen->fb[0].bitsPerPixel ) {
+ case 16:
+ geMode = VIA_GEM_16bpp;
+ break;
+ case 32:
+ geMode = VIA_GEM_32bpp;
+ break;
+ default:
+ geMode = VIA_GEM_8bpp;
+ break;
+ }
+
+ OUTREG32( VIA_REG_GEMODE, geMode );
+
+ /*
+ ** Set the source and destination base addresses, and set pitch.
+ */
+ OUTREG32( VIA_REG_SRCBASE, 0x0 );
+ OUTREG32( VIA_REG_DSTBASE, 0x0 );
+ OUTREG32( VIA_REG_PITCH, VIA_PITCH_ENABLE |
+ ((pScreen->width * pScreenPriv->screen->fb[0].bitsPerPixel >> 3) >> 3) |
+ (((pScreen->width * pScreenPriv->screen->fb[0].bitsPerPixel >> 3) >> 3) << 16));
+
+ DebugF( "Initialized 2D engine!\n" );
+
+ memset(&vias->kaa, 0, sizeof(KaaScreenInfoRec));
+ vias->kaa.waitMarker = viaWaitMarker;
+ vias->kaa.PrepareSolid = viaPrepareSolid;
+ vias->kaa.Solid = viaSolid;
+ vias->kaa.DoneSolid = viaDoneSolid;
+ vias->kaa.PrepareCopy = viaPrepareCopy;
+ vias->kaa.Copy = viaCopy;
+ vias->kaa.DoneCopy = viaDoneCopy;
+
+ return kaaDrawInit( pScreen, &vias->kaa );
+}
+
+/*
+** void viaDrawEnable( ScreenPtr pScreen )
+**
+** Description:
+** Enable accelerated drawing on the specified screen.
+**
+** Arguments:
+** pScreen Pointer to screen structure for the screen we're
+** enabling acceleration on.
+**
+** Return:
+** None.
+*/
+void
+viaDrawEnable( ScreenPtr pScreen ) {
+ kaaMarkSync( pScreen );
+}
+
+/*
+** void viaDrawDisable( ScreenPtr pScreen )
+**
+** Description:
+** Disable accelerated drawing to the specified screen.
+**
+** Arguments:
+** pScreen Pointer to screen structure for the screen we're
+** disabling acceleration on.
+**
+** Return:
+** None
+*/
+void
+viaDrawDisable( ScreenPtr pScreen ) {
+}
+
+/*
+** void viaDrawFini( ScreenPtr pScreen )
+**
+** Description:
+** Shutdown accelerated drawing and free associated strucures and
+** resources.
+**
+** Arguments:
+** pScreen Pointer to screen structure for the screen we're
+** disabling acceleration on.
+**
+** Return:
+** None.
+*/
+void
+viaDrawFini( ScreenPtr pScreen ) {
+}