summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <unichrome@shipmail.org>2006-02-22 17:35:33 +0000
committerThomas Hellstrom <unichrome@shipmail.org>2006-02-22 17:35:33 +0000
commit58fdf3195122dacd4535377d6fdd55de48dfeb01 (patch)
tree52ec572427b8079bf22eeb4300cbd8121fed3a21
parent6611b34cd5b56b4ad786e6cada872ceaf2b7b6c4 (diff)
Bugzilla #5180 <https://bugs.freedesktop.org/show_bug.cgi?id=5180> XAA
rework and EXA support including render / composite accel.
-rw-r--r--ChangeLog55
-rw-r--r--src/Makefile.am2
-rw-r--r--src/via_3d.c584
-rw-r--r--src/via_3d.h120
-rw-r--r--src/via_accel.c3174
-rw-r--r--src/via_cursor.c2
-rw-r--r--src/via_dga.c42
-rw-r--r--src/via_dri.c58
-rw-r--r--src/via_driver.c184
-rw-r--r--src/via_driver.h114
-rw-r--r--src/via_memcpy.c1
-rw-r--r--src/via_memory.c82
-rw-r--r--src/via_priv.h8
-rw-r--r--src/via_vbe.c2
14 files changed, 3184 insertions, 1244 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b56f59..5b42356 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,60 @@
2006-02-22 Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ * src/Makefile.am:
+ * src/via_3d.c: (via3DDstFormat), (via3DTexFormat),
+ (via3DDstSupported), (via3DTexSupported), (viaSet3DDestination),
+ (viaSet3DDrawing), (viaSet3DFlags), (viaOrder), (viaSet3DTexture),
+ (viaSet3DTexBlendCol), (viaSet3DCompositeOperator),
+ (via3DOpSupported), (via3DEmitQuad), (via3DEmitState),
+ (via3DEmitClipRect), (viaInit3DState):
+ * src/via_3d.h:
+ * src/via_accel.c: (viaDumpDMA), (viaFlushPCI),
+ (viaFlushDRIEnabled), (viaSetupCBuffer), (viaTearDownCBuffer),
+ (viaInitAgp), (viaEnableVQ), (viaDisableVQ), (viaAccelSetMode),
+ (viaInitialize2DEngine), (viaAccelSync), (viaSetClippingRectangle),
+ (viaDisableClipping), (viaAccelClippingHelper),
+ (viaAccelSolidHelper), (viaAccelPlaneMaskHelper),
+ (viaAccelTransparentHelper), (viaAccelCopyHelper),
+ (viaSetupForScreenToScreenCopy), (viaSubsequentScreenToScreenCopy),
+ (viaSetupForSolidFill), (viaSubsequentSolidFillRect),
+ (viaSetupForMono8x8PatternFill),
+ (viaSubsequentMono8x8PatternFillRect),
+ (viaSetupForColor8x8PatternFill),
+ (viaSubsequentColor8x8PatternFillRect),
+ (viaSetupForCPUToScreenColorExpandFill),
+ (viaSubsequentScanlineCPUToScreenColorExpandFill),
+ (viaSetupForImageWrite), (viaSubsequentImageWriteRect),
+ (viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine),
+ (viaSubsequentSolidHorVertLine), (viaSetupForDashedLine),
+ (viaSubsequentDashedTwoPointLine), (viaInitXAA),
+ (viaAccelMarkSync), (viaAccelWaitMarker), (viaExaPrepareSolid),
+ (viaExaSolid), (viaExaDoneSolidCopy), (viaExaPrepareCopy),
+ (viaExaCopy), (viaExaCompositePictDesc), (viaExaPrintComposite),
+ (viaBitExpandHelper), (viaPixelARGB8888), (viaExpandablePixel),
+ (viaCheckUpload), (viaOrder), (viaExaDownloadFromScreen),
+ (viaExaTexUploadToScreen), (viaExaUploadToScreen),
+ (viaExaUploadToScratch), (viaExaCheckComposite), (viaIsAGP),
+ (viaIsOffscreen), (viaExaPrepareComposite), (viaExaComposite),
+ (viaInitExa), (viaInitAccel), (viaExitAccel), (viaFinishInitAccel),
+ (viaAccelBlitRect), (viaAccelFillRect), (viaAccelSyncMarker):
+ * src/via_cursor.c: (VIALoadCursorImage):
+ * src/via_dga.c:
+ * src/via_dri.c: (VIADRIRingBufferInit), (VIADRIFBInit),
+ (VIADRIScreenInit), (VIADRICloseScreen):
+ * src/via_driver.c: (VIASetup), (VIAPreInit), (VIALeaveVT),
+ (VIAScreenInit), (VIAInternalScreenInit), (VIAWriteMode),
+ (VIACloseScreen), (VIASwitchMode):
+ * src/via_driver.h:
+ * src/via_memcpy.c: (viaVidCopyInit):
+ * src/via_memory.c: (VIAFreeLinear), (offScreenLinear),
+ (VIAAllocLinear), (VIAInitLinear):
+ * src/via_priv.h:
+ * src/via_vbe.c: (ViaVbeSetMode):
+ Bugzilla #5180 <https://bugs.freedesktop.org/show_bug.cgi?id=5180>
+ XAA rework and EXA support including render / composite accel.
+
+2006-02-22 Thomas Hellstrom <thomas-at-tungstengraphics.com>
+
* src/via_mode.c: (ViaModePrimary):
Import Luc's fix for sometimes-blanking CRTs. (Luc Verhaegen)
diff --git a/src/Makefile.am b/src/Makefile.am
index be33590..228b115 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,8 @@ via_drv_la_LDFLAGS = -module -avoid-version
via_drv_ladir = @moduledir@/drivers
via_drv_la_SOURCES = \
+ via_3d.h \
+ via_3d.c \
via_accel.c \
via_bandwidth.c \
via_bios.h \
diff --git a/src/via_3d.c b/src/via_3d.c
new file mode 100644
index 0000000..54fb360
--- /dev/null
+++ b/src/via_3d.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2006 Thomas Hellstrom. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "via_3d.h"
+#include "via_3d_reg.h"
+#include <picturestr.h>
+
+typedef struct
+{
+ Bool supported;
+ CARD32 col0;
+ CARD32 col1;
+ CARD32 al0;
+ CARD32 al1;
+} ViaCompositeOperator;
+
+typedef struct
+{
+ CARD32 pictFormat;
+ Bool dstSupported;
+ Bool texSupported;
+ CARD32 dstFormat;
+ CARD32 texFormat;
+} Via3DFormat;
+
+static ViaCompositeOperator viaOperatorModes[256];
+static Via3DFormat via3DFormats[256];
+
+#define VIA_NUM_3D_OPCODES 19
+#define VIA_NUM_3D_FORMATS 15
+#define VIA_FMT_HASH(arg) (((((arg) >> 1) + (arg)) >> 8) & 0xFF)
+
+static const CARD32 viaOpCodes[VIA_NUM_3D_OPCODES][5] = {
+ {PictOpClear, 0x05, 0x45, 0x40, 0x80},
+ {PictOpSrc, 0x15, 0x45, 0x50, 0x80},
+ {PictOpDst, 0x05, 0x55, 0x40, 0x90},
+ {PictOpOver, 0x15, 0x52, 0x50, 0x91},
+ {PictOpOverReverse, 0x13, 0x45, 0x52, 0x90},
+ {PictOpIn, 0x03, 0x45, 0x42, 0x80},
+ {PictOpInReverse, 0x05, 0x42, 0x40, 0x81},
+ {PictOpOut, 0x13, 0x45, 0x52, 0x80},
+ {PictOpOutReverse, 0x05, 0x52, 0x40, 0x91},
+ {PictOpAtop, 0x03, 0x52, 0x42, 0x91},
+ {PictOpAtopReverse, 0x13, 0x42, 0x52, 0x81},
+ {PictOpXor, 0x15, 0x52, 0x52, 0x91},
+ {PictOpAdd, 0x15, 0x55, 0x50, 0x90},
+ {PictOpDisjointClear, 0x05, 0x45, 0x40, 0x80},
+ {PictOpDisjointSrc, 0x15, 0x45, 0x50, 0x80},
+ {PictOpDisjointDst, 0x05, 0x55, 0x40, 0x90},
+ {PictOpConjointClear, 0x05, 0x45, 0x40, 0x80},
+ {PictOpConjointSrc, 0x15, 0x45, 0x50, 0x80},
+ {PictOpConjointDst, 0x05, 0x55, 0x40, 0x90}
+};
+
+static const CARD32 viaFormats[VIA_NUM_3D_FORMATS][5] = {
+ {PICT_x1r5g5b5, HC_HDBFM_RGB555, HC_HTXnFM_RGB555, 1, 1},
+ {PICT_r5g6b5, HC_HDBFM_RGB565, HC_HTXnFM_RGB565, 1, 1},
+ {PICT_a4r4g4b4, HC_HDBFM_ARGB4444, HC_HTXnFM_ARGB4444, 1, 1},
+ {PICT_a1r5g5b5, HC_HDBFM_ARGB1555, HC_HTXnFM_ARGB1555, 1, 1},
+ {PICT_x1b5g5r5, HC_HDBFM_BGR555, HC_HTXnFM_BGR555, 1, 1},
+ {PICT_b5g6r5, HC_HDBFM_BGR565, HC_HTXnFM_BGR565, 1, 1},
+ {PICT_a4b4g4r4, HC_HDBFM_ABGR4444, HC_HTXnFM_ABGR4444, 1, 1},
+ {PICT_a1b5g5r5, HC_HDBFM_ABGR1555, HC_HTXnFM_ABGR1555, 1, 1},
+ {PICT_x8r8g8b8, HC_HDBFM_ARGB0888, HC_HTXnFM_ARGB0888, 1, 1},
+ {PICT_a8r8g8b8, HC_HDBFM_ARGB8888, HC_HTXnFM_ARGB8888, 1, 1},
+ {PICT_x8b8g8r8, HC_HDBFM_ABGR0888, HC_HTXnFM_ABGR0888, 1, 1},
+ {PICT_a8b8g8r8, HC_HDBFM_ABGR8888, HC_HTXnFM_ABGR8888, 1, 1},
+ {PICT_a8, 0x00, HC_HTXnFM_A8, 0, 1},
+ {PICT_a4, 0x00, HC_HTXnFM_A4, 0, 1},
+ {PICT_a1, 0x00, HC_HTXnFM_A1, 0, 1}
+};
+
+static CARD32
+via3DDstFormat(int format)
+{
+ return via3DFormats[VIA_FMT_HASH(format)].dstFormat;
+}
+
+static CARD32
+via3DTexFormat(int format)
+{
+ return via3DFormats[VIA_FMT_HASH(format)].texFormat;
+}
+
+static Bool
+via3DDstSupported(int format)
+{
+ Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format);
+
+ if (fm->pictFormat != format)
+ return FALSE;
+ return fm->dstSupported;
+}
+
+static Bool
+via3DTexSupported(int format)
+{
+ Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format);
+
+ if (fm->pictFormat != format)
+ return FALSE;
+ return fm->texSupported;
+}
+
+static void
+viaSet3DDestination(Via3DState * v3d, CARD32 offset, CARD32 pitch, int format)
+{
+ v3d->drawingDirty = TRUE; /* Affects planemask format. */
+ v3d->destDirty = TRUE;
+ v3d->destOffset = offset;
+ v3d->destPitch = pitch;
+ v3d->destFormat = via3DDstFormat(format);
+ v3d->destDepth = (v3d->destFormat < HC_HDBFM_ARGB0888) ? 16 : 32;
+}
+
+static void
+viaSet3DDrawing(Via3DState * v3d, int rop,
+ CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha)
+{
+ v3d->drawingDirty = TRUE;
+ v3d->rop = rop;
+ v3d->planeMask = planeMask;
+ v3d->solidColor = solidColor;
+ v3d->solidAlpha = solidAlpha;
+}
+
+static void
+viaSet3DFlags(Via3DState * v3d, int numTextures,
+ Bool writeAlpha, Bool writeColor, Bool blend)
+{
+ v3d->enableDirty = TRUE;
+ v3d->blendDirty = TRUE;
+ v3d->numTextures = numTextures;
+ v3d->writeAlpha = writeAlpha;
+ v3d->writeColor = writeColor;
+ v3d->blend = blend;
+}
+
+static Bool
+viaOrder(CARD32 val, CARD32 * shift)
+{
+ *shift = 0;
+
+ while (val > (1 << *shift))
+ (*shift)++;
+ return (val == (1 << *shift));
+}
+
+static Bool
+viaSet3DTexture(Via3DState * v3d, int tex, CARD32 offset,
+ CARD32 pitch, CARD32 width, CARD32 height, int format,
+ ViaTextureModes sMode, ViaTextureModes tMode,
+ ViaTexBlendingModes blendingMode, Bool agpTexture)
+{
+ ViaTextureUnit *vTex = v3d->tex + tex;
+
+ vTex->textureLevel0Offset = offset;
+ if (!viaOrder(pitch, &vTex->textureLevel0Exp))
+ return FALSE;
+ vTex->textureLevel0Pitch = pitch;
+ if (!viaOrder(width, &vTex->textureLevel0WExp))
+ return FALSE;
+ if (!viaOrder(height, &vTex->textureLevel0HExp))
+ return FALSE;
+
+ if (pitch <= 4) {
+ ErrorF("Warning! texture pitch is leq 4\n");
+ }
+
+ vTex->textureFormat = via3DTexFormat(format);
+
+ switch (blendingMode) {
+ case via_src:
+ vTex->texCsat = (0x01 << 23) | (0x10 << 14) | (0x03 << 7) | 0x00;
+ vTex->texAsat =
+ (0x0B << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) |
+ 0x03;
+ vTex->texRCa = 0x00000000;
+ vTex->texRAa = 0x00000000;
+ vTex->texBColDirty = TRUE;
+ break;
+ case via_src_onepix_mask:
+ vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00;
+ vTex->texAsat =
+ (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) |
+ 0x03;
+ break;
+ case via_src_onepix_comp_mask:
+ vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00;
+ vTex->texAsat =
+ (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) |
+ 0x03;
+ break;
+ case via_mask:
+ vTex->texCsat = (0x01 << 23) | (0x07 << 14) | (0x04 << 7) | 0x00;
+ vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03;
+ break;
+ case via_comp_mask:
+ vTex->texCsat = (0x01 << 23) | (0x03 << 14) | (0x04 << 7) | 0x00;
+ vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03;
+ break;
+ default:
+ return FALSE;
+ }
+
+ vTex->textureDirty = TRUE;
+ vTex->textureModesS = sMode - via_single;
+ vTex->textureModesT = tMode - via_single;
+
+ vTex->agpTexture = agpTexture;
+ return TRUE;
+}
+
+static void
+viaSet3DTexBlendCol(Via3DState * v3d, int tex, Bool component, CARD32 color)
+{
+ CARD32 alpha;
+ ViaTextureUnit *vTex = v3d->tex + tex;
+
+ vTex->texRAa = (color >> 8) & 0x00FF0000;
+ if (component) {
+ vTex->texRCa = (color & 0x00FFFFFF);
+ } else {
+ alpha = color >> 24;
+ vTex->texRCa = alpha | (alpha << 8) | (alpha << 16) | (alpha << 24);
+ }
+ vTex->texBColDirty = TRUE;
+}
+
+/*
+ * Check if compositing operator is supported and return corresponding register setting.
+ */
+
+static void
+viaSet3DCompositeOperator(Via3DState * v3d, CARD8 op)
+{
+ ViaCompositeOperator *vOp = viaOperatorModes + op;
+
+ v3d->blendDirty = TRUE;
+ if (v3d && vOp->supported) {
+ v3d->blendCol0 = vOp->col0 << 4;
+ v3d->blendCol1 = vOp->col1 << 2;
+ v3d->blendAl0 = vOp->al0 << 4;
+ v3d->blendAl1 = vOp->al1 << 2;
+ }
+}
+
+static Bool
+via3DOpSupported(CARD8 op)
+{
+ return viaOperatorModes[op].supported;
+}
+
+static void
+via3DEmitQuad(Via3DState * v3d, ViaCommandBuffer * cb, int dstX, int dstY,
+ int src0X, int src0Y, int src1X, int src1Y, int w, int h)
+{
+ CARD32 acmd;
+ float dx1, dx2, dy1, dy2, sx1[2], sx2[2], sy1[2], sy2[2], wf;
+ double scalex, scaley;
+ int i, numTex;
+ ViaTextureUnit *vTex;
+
+ numTex = v3d->numTextures;
+ dx1 = dstX;
+ dx2 = dstX + w;
+ dy1 = dstY;
+ dy2 = dstY + h;
+
+ if (numTex) {
+ sx1[0] = src0X;
+ sx1[1] = src1X;
+ sy1[0] = src0Y;
+ sy1[1] = src1Y;
+ for (i = 0; i < numTex; ++i) {
+ vTex = v3d->tex + i;
+ scalex = 1. / (double)((1 << vTex->textureLevel0WExp));
+ scaley = 1. / (double)((1 << vTex->textureLevel0HExp));
+ sx2[i] = sx1[i] + w;
+ sy2[i] = sy1[i] + h;
+ sx1[i] *= scalex;
+ sy1[i] *= scaley;
+ sx2[i] *= scalex;
+ sy2[i] *= scaley;
+ }
+ }
+
+ wf = 0.05;
+
+ /*
+ * Vertex buffer. Emit two 3-point triangles. The W or Z coordinate
+ * is needed for AGP DMA, and the W coordinate is for some obscure
+ * reason needed for texture mapping to be done correctly. So emit
+ * a w value after the x and y coordinates.
+ */
+
+ BEGIN_H2(HC_ParaType_CmdVdata, 22 + numTex * 6);
+ acmd = ((1 << 14) | (1 << 13) | (1 << 11));
+ if (numTex)
+ acmd |= ((1 << 7) | (1 << 8));
+ OUT_RING_SubA(0xEC, acmd);
+
+ acmd = 2 << 16;
+ OUT_RING_SubA(0xEE, acmd);
+
+ OUT_RING(*((CARD32 *) (&dx1)));
+ OUT_RING(*((CARD32 *) (&dy1)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx1 + i)));
+ OUT_RING(*((CARD32 *) (sy1 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx2)));
+ OUT_RING(*((CARD32 *) (&dy1)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx2 + i)));
+ OUT_RING(*((CARD32 *) (sy1 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx1)));
+ OUT_RING(*((CARD32 *) (&dy2)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx1 + i)));
+ OUT_RING(*((CARD32 *) (sy2 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx1)));
+ OUT_RING(*((CARD32 *) (&dy2)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx1 + i)));
+ OUT_RING(*((CARD32 *) (sy2 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx2)));
+ OUT_RING(*((CARD32 *) (&dy1)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx2 + i)));
+ OUT_RING(*((CARD32 *) (sy1 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx2)));
+ OUT_RING(*((CARD32 *) (&dy2)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx2 + i)));
+ OUT_RING(*((CARD32 *) (sy2 + i)));
+ }
+ OUT_RING_SubA(0xEE,
+ acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK);
+ OUT_RING_SubA(0xEE,
+ acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK);
+
+ ADVANCE_RING;
+}
+
+static void
+via3DEmitState(Via3DState * v3d, ViaCommandBuffer * cb, Bool forceUpload)
+{
+ int i;
+ Bool saveHas3dState;
+ ViaTextureUnit *vTex;
+
+ /*
+ * Destination buffer location, format and pitch.
+ */
+
+ if (forceUpload || v3d->destDirty) {
+ v3d->destDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 3);
+
+ OUT_RING_SubA(HC_SubA_HDBBasL, v3d->destOffset & 0x00FFFFFF);
+ OUT_RING_SubA(HC_SubA_HDBBasH, v3d->destOffset >> 24);
+ OUT_RING_SubA(HC_SubA_HDBFM, v3d->destFormat |
+ (v3d->destPitch & HC_HDBPit_MASK) | HC_HDBLoc_Local);
+ }
+
+ if (forceUpload || v3d->blendDirty) {
+ v3d->blendDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 6);
+ OUT_RING_SubA(HC_SubA_HABLRFCa, 0x00);
+ OUT_RING_SubA(HC_SubA_HABLRFCb, 0x00);
+ OUT_RING_SubA(HC_SubA_HABLCsat, v3d->blendCol0);
+ OUT_RING_SubA(HC_SubA_HABLCop, v3d->blendCol1);
+ OUT_RING_SubA(HC_SubA_HABLAsat, v3d->blendAl0);
+ OUT_RING_SubA(HC_SubA_HABLAop, v3d->blendAl1);
+ }
+
+ if (forceUpload || v3d->drawingDirty) {
+
+ CARD32 planeMaskLo, planeMaskHi;
+
+ v3d->drawingDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 4);
+
+ /*
+ * Raster operation and Planemask.
+ */
+
+ if ( /* v3d->destDepth == 16 Bad Docs? */ FALSE) {
+ planeMaskLo = (v3d->planeMask & 0x000000FF) << 16;
+ planeMaskHi = (v3d->planeMask & 0x0000FF00) >> 8;
+ } else {
+ planeMaskLo = v3d->planeMask & 0x00FFFFFF;
+ planeMaskHi = v3d->planeMask >> 24;
+ }
+
+ OUT_RING_SubA(HC_SubA_HROP, ((v3d->rop & 0x0F) << 8) | planeMaskHi);
+ OUT_RING_SubA(HC_SubA_HFBBMSKL, planeMaskLo);
+
+ /*
+ * Solid shading color and alpha. Pixel center at
+ * floating coordinates (X.5,Y.5).
+ */
+
+ OUT_RING_SubA(HC_SubA_HSolidCL,
+ (v3d->solidColor & 0x00FFFFFF) | (0 << 23));
+ OUT_RING_SubA(HC_SubA_HPixGC,
+ ((v3d->solidColor & 0xFF000000) >> 16) | (0 << 23) | (v3d->
+ solidAlpha & 0xFF));
+ }
+
+ if (forceUpload || v3d->enableDirty) {
+ v3d->enableDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 1);
+
+ OUT_RING_SubA(HC_SubA_HEnable,
+ ((v3d->writeColor) ? HC_HenCW_MASK : 0) |
+ ((v3d->blend) ? HC_HenABL_MASK : 0) |
+ ((v3d->numTextures) ? HC_HenTXMP_MASK : 0) |
+ ((v3d->writeAlpha) ? HC_HenAW_MASK : 0));
+
+ if (v3d->numTextures) {
+ BEGIN_H2((HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)), 2);
+ OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) |
+ (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 1);
+ OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) |
+ (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 0);
+ }
+ }
+
+ for (i = 0; i < v3d->numTextures; ++i) {
+ vTex = v3d->tex + i;
+
+ if (forceUpload || vTex->textureDirty) {
+ vTex->textureDirty = FALSE;
+
+ BEGIN_H2((HC_ParaType_Tex |
+ (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)),
+ 13);
+
+ OUT_RING_SubA(HC_SubA_HTXnFM, (vTex->textureFormat |
+ (vTex->agpTexture ? HC_HTXnLoc_AGP : HC_HTXnLoc_Local)));
+ OUT_RING_SubA(HC_SubA_HTXnL0BasL,
+ vTex->textureLevel0Offset & 0x00FFFFFF);
+ OUT_RING_SubA(HC_SubA_HTXnL012BasH,
+ vTex->textureLevel0Offset >> 24);
+ OUT_RING_SubA(HC_SubA_HTXnL0Pit, vTex->textureLevel0Exp << 20);
+ OUT_RING_SubA(HC_SubA_HTXnL0_5WE, vTex->textureLevel0WExp);
+ OUT_RING_SubA(HC_SubA_HTXnL0_5HE, vTex->textureLevel0HExp);
+ OUT_RING_SubA(HC_SubA_HTXnL0OS, 0x00);
+ OUT_RING_SubA(HC_SubA_HTXnTB, 0x00);
+ OUT_RING_SubA(HC_SubA_HTXnMPMD,
+ (((unsigned)vTex->textureModesT) << 19) | (((unsigned)vTex->
+ textureModesS) << 16));
+
+ OUT_RING_SubA(HC_SubA_HTXnTBLCsat, vTex->texCsat);
+ OUT_RING_SubA(HC_SubA_HTXnTBLCop, (0x00 << 22) | (0x00 << 19) |
+ (0x00 << 14) | (0x02 << 11) |
+ (0x00 << 7) | (0x03 << 3) | 0x02);
+ OUT_RING_SubA(HC_SubA_HTXnTBLAsat, vTex->texAsat);
+ OUT_RING_SubA(HC_SubA_HTXnTBLRFog, 0x00);
+ }
+ }
+
+ for (i = 0; i < v3d->numTextures; ++i) {
+ vTex = v3d->tex + i;
+
+ if (forceUpload || vTex->texBColDirty) {
+ saveHas3dState = cb->has3dState;
+ vTex->texBColDirty = FALSE;
+ BEGIN_H2((HC_ParaType_Tex |
+ (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)),
+ 2);
+ OUT_RING_SubA(HC_SubA_HTXnTBLRAa, vTex->texRAa);
+ OUT_RING_SubA(HC_SubA_HTXnTBLRCa, vTex->texRCa);
+ cb->has3dState = saveHas3dState;
+ }
+ }
+}
+
+/*
+ * Cliprect. Considered not important for the DRM 3D State, so restore the
+ * has3dState flag afterwards.
+ */
+
+static void
+via3DEmitClipRect(Via3DState * v3d, ViaCommandBuffer * cb, int x, int y,
+ int w, int h)
+{
+ Bool saveHas3dState;
+
+ saveHas3dState = cb->has3dState;
+ BEGIN_H2(HC_ParaType_NotTex, 4);
+ OUT_RING_SubA(HC_SubA_HClipTB, (y << 12) | (y + h));
+ OUT_RING_SubA(HC_SubA_HClipLR, (x << 12) | (x + w));
+ cb->has3dState = saveHas3dState;
+}
+
+void
+viaInit3DState(Via3DState * v3d)
+{
+ ViaCompositeOperator *op;
+ int i;
+ CARD32 tmp, hash;
+ Via3DFormat *format;
+
+ v3d->setDestination = viaSet3DDestination;
+ v3d->setDrawing = viaSet3DDrawing;
+ v3d->setFlags = viaSet3DFlags;
+ v3d->setTexture = viaSet3DTexture;
+ v3d->setTexBlendCol = viaSet3DTexBlendCol;
+ v3d->opSupported = via3DOpSupported;
+ v3d->setCompositeOperator = viaSet3DCompositeOperator;
+ v3d->emitQuad = via3DEmitQuad;
+ v3d->emitState = via3DEmitState;
+ v3d->emitClipRect = via3DEmitClipRect;
+ v3d->dstSupported = via3DDstSupported;
+ v3d->texSupported = via3DTexSupported;
+
+ for (i = 0; i < 256; ++i) {
+ viaOperatorModes[i].supported = FALSE;
+ }
+
+ for (i = 0; i < VIA_NUM_3D_OPCODES; ++i) {
+ op = viaOperatorModes + viaOpCodes[i][0];
+ op->supported = TRUE;
+ op->col0 = viaOpCodes[i][1];
+ op->col1 = viaOpCodes[i][2];
+ op->al0 = viaOpCodes[i][3];
+ op->al1 = viaOpCodes[i][4];
+ }
+
+ for (i = 0; i < 256; ++i) {
+ via3DFormats[i].pictFormat = 0x00;
+ }
+ for (i = 0; i < VIA_NUM_3D_FORMATS; ++i) {
+ tmp = viaFormats[i][0];
+ hash = VIA_FMT_HASH(tmp);
+ format = via3DFormats + hash;
+ if (format->pictFormat) {
+ ErrorF("BUG: Bad hash function\n");
+ }
+ format->pictFormat = tmp;
+ format->dstSupported = (viaFormats[i][3] != 0x00);
+ format->texSupported = (viaFormats[i][4] != 0x00);
+ format->dstFormat = viaFormats[i][1];
+ format->texFormat = viaFormats[i][2];
+ }
+}
diff --git a/src/via_3d.h b/src/via_3d.h
new file mode 100644
index 0000000..118b6c9
--- /dev/null
+++ b/src/via_3d.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2006 Thomas Hellstrom. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef VIA_3D_H
+#define VIA_3D_H
+
+#include "xf86.h"
+#include "via_dmabuffer.h"
+
+#define VIA_NUM_TEXUNITS 2
+
+typedef enum
+{
+ via_single,
+ via_clamp,
+ via_repeat,
+ via_mirror,
+ via_warp
+} ViaTextureModes;
+
+typedef enum
+{
+ via_src,
+ via_src_onepix_mask,
+ via_src_onepix_comp_mask,
+ via_mask,
+ via_comp_mask
+} ViaTexBlendingModes;
+
+typedef struct _ViaTextureUnit
+{
+ CARD32 textureLevel0Offset;
+ CARD32 textureLevel0Pitch;
+ CARD32 textureLevel0Exp;
+ CARD32 textureLevel0WExp;
+ CARD32 textureLevel0HExp;
+ CARD32 textureFormat;
+ CARD32 textureModesT;
+ CARD32 textureModesS;
+ CARD32 texCsat;
+ CARD32 texRCa;
+ CARD32 texAsat;
+ CARD32 texRAa;
+ Bool agpTexture;
+ Bool textureDirty;
+ Bool texBColDirty;
+} ViaTextureUnit;
+
+typedef struct _Via3DState
+{
+ Bool destDirty;
+ Bool blendDirty;
+ Bool enableDirty;
+ Bool drawingDirty;
+ CARD32 rop;
+ CARD32 planeMask;
+ CARD32 solidColor;
+ CARD32 solidAlpha;
+ CARD32 destOffset;
+ CARD32 destPitch;
+ CARD32 destFormat;
+ int destDepth;
+ int numTextures;
+ Bool blend;
+ CARD32 blendCol0;
+ CARD32 blendCol1;
+ CARD32 blendAl0;
+ CARD32 blendAl1;
+ Bool writeAlpha;
+ Bool writeColor;
+ Bool useDestAlpha;
+ ViaTextureUnit tex[VIA_NUM_TEXUNITS];
+ void (*setDestination) (struct _Via3DState * v3d, CARD32 offset,
+ CARD32 pitch, int format);
+ void (*setDrawing) (struct _Via3DState * v3d, int rop,
+ CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha);
+ void (*setFlags) (struct _Via3DState * v3d, int numTextures,
+ Bool writeAlpha, Bool writeColor, Bool blend);
+ Bool(*setTexture) (struct _Via3DState * v3d, int tex, CARD32 offset,
+ CARD32 pitch, CARD32 width, CARD32 height, int format,
+ ViaTextureModes sMode, ViaTextureModes tMode,
+ ViaTexBlendingModes blendingMode, Bool agpTexture);
+ void (*setTexBlendCol) (struct _Via3DState * v3d, int tex, Bool component,
+ CARD32 color);
+ void (*setCompositeOperator) (struct _Via3DState * v3d, CARD8 op);
+ Bool(*opSupported) (CARD8 op);
+ void (*emitQuad) (struct _Via3DState * v3d, ViaCommandBuffer * cb,
+ int dstX, int dstY, int src0X, int src0Y, int src1X, int src1Y, int w,
+ int h);
+ void (*emitState) (struct _Via3DState * v3d, ViaCommandBuffer * cb,
+ Bool forceUpload);
+ void (*emitClipRect) (struct _Via3DState * v3d, ViaCommandBuffer * cb,
+ int x, int y, int w, int h);
+ Bool(*dstSupported) (int format);
+ Bool(*texSupported) (int format);
+} Via3DState;
+
+void viaInit3DState(Via3DState * v3d);
+
+#endif
diff --git a/src/via_accel.c b/src/via_accel.c
index 7467f6a..0960746 100644
--- a/src/via_accel.c
+++ b/src/via_accel.c
@@ -1,6 +1,7 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2006 Thomas Hellstrom. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,14 +21,9 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- */
-
-/*************************************************************************
*
- * File: via_accel.c
- * Content: 2D acceleration function for VIA/S3G UniChrome
- *
- ************************************************************************/
+ * Mostly rewritten and modified for EXA support by Thomas Hellstrom 2005.
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -41,1387 +37,2419 @@
#include "via_driver.h"
#include "via_regs.h"
#include "via_id.h"
+#include "via_dmabuffer.h"
-/* Forward declaration of functions used in the driver */
-
-static void VIASetupForScreenToScreenCopy(
- ScrnInfoPtr pScrn,
- int xdir,
- int ydir,
- int rop,
- unsigned planemask,
- int trans_color);
-
-static void VIASubsequentScreenToScreenCopy(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int w,
- int h);
-
-static void VIASetupForSolidFill(
- ScrnInfoPtr pScrn,
- int color,
- int rop,
- unsigned planemask);
-
-static void VIASubsequentSolidFillRect(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h);
-
-static void VIASetupForMono8x8PatternFill(
- ScrnInfoPtr pScrn,
- int pattern0,
- int pattern1,
- int fg,
- int bg,
- int rop,
- unsigned planemask);
-
-static void VIASubsequentMono8x8PatternFillRect(
- ScrnInfoPtr pScrn,
- int patOffx,
- int patOffy,
- int x,
- int y,
- int w,
- int h);
-
-static void VIASetupForColor8x8PatternFill(
- ScrnInfoPtr pScrn,
- int patternx,
- int patterny,
- int rop,
- unsigned planemask,
- int trans_color);
-
-static void VIASubsequentColor8x8PatternFillRect(
- ScrnInfoPtr pScrn,
- int patOffx,
- int patOffy,
- int x,
- int y,
- int w,
- int h);
-
-static void VIASetupForCPUToScreenColorExpandFill(
- ScrnInfoPtr pScrn,
- int fg,
- int bg,
- int rop,
- unsigned planemask);
-
-static void VIASubsequentScanlineCPUToScreenColorExpandFill(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int skipleft);
-
-#if 0 /* Buggy. Temporarily disabled 2005-01-23 */
-static void VIASetupForScreenToScreenColorExpand(
- ScrnInfoPtr pScrn,
- int bg,
- int fg,
- int rop,
- unsigned planemask);
-
-static void VIASubsequentScreenToScreenColorExpand(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int srcx,
- int srcy,
- int offset);
-#endif
+#define VIAACCELPATTERNROP(vRop) (XAAGetPatternROP(vRop) << 24)
+#define VIAACCELCOPYROP(vRop) (XAAGetCopyROP(vRop) << 24)
+/*
+ * Use PCI MMIO to flush the command buffer. When AGP DMA is not available.
+ */
-static void VIASetupForImageWrite(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned planemask,
- int trans_color,
- int bpp,
- int depth);
+static void
+viaDumpDMA(ViaCommandBuffer * buf)
+{
+ register CARD32 *bp = buf->buf;
+ CARD32 *endp = bp + buf->pos;
-static void VIASubsequentImageWriteRect(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int skipleft);
+ while (bp != endp) {
+ if (((bp - buf->buf) & 3) == 0) {
+ ErrorF("\n %04lx: ", (unsigned long)(bp - buf->buf));
+ }
+ ErrorF("0x%08x ", (unsigned)*bp++);
+ }
+ ErrorF("\n");
+}
-static void
-VIASetupForSolidLine(
- ScrnInfoPtr pScrn,
- int color,
- int rop,
- unsigned int planemask);
+void
+viaFlushPCI(ViaCommandBuffer * buf)
+{
+ register CARD32 *bp = buf->buf;
+ CARD32 transSetting;
+ CARD32 *endp = bp + buf->pos;
+ unsigned loop = 0;
+ register CARD32 offset = 0;
+ register CARD32 value;
+ VIAPtr pVia = VIAPTR(buf->pScrn);
+
+ while (bp < endp) {
+ if (*bp == HALCYON_HEADER2) {
+ if (++bp == endp)
+ return;
+ VIASETREG(VIA_REG_TRANSET, transSetting = *bp++);
+ while (bp < endp) {
+ if ((transSetting != HC_ParaType_CmdVdata) &&
+ ((*bp == HALCYON_HEADER2)
+ || (*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1))
+ break;
+ VIASETREG(VIA_REG_TRANSPACE, *bp++);
+ }
+ } else if ((*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1) {
+
+ while (bp < endp) {
+ if (*bp == HALCYON_HEADER2)
+ break;
+ if (offset == 0) {
+ /*
+ * Not doing this wait will probably stall the processor
+ * for an unacceptable amount of time in VIASETREG while other high
+ * priority interrupts may be pending.
+ */
+ while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
+ && (loop++ < MAXLOOP)) ;
+ while ((VIAGETREG(VIA_REG_STATUS) & (VIA_CMD_RGTR_BUSY |
+ VIA_2D_ENG_BUSY))
+ && (loop++ < MAXLOOP)) ;
+ }
+ offset = (*bp++ & 0x0FFFFFFF) << 2;
+ value = *bp++;
+ VIASETREG(offset, value);
+ }
+ } else {
+ ErrorF("Command stream parser error.\n");
+ }
+ }
+ buf->pos = 0;
+ buf->mode = 0;
+ buf->has3dState = FALSE;
+}
-static void
-VIASubsequentSolidTwoPointLine(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int flags);
+/*
+ * Flush the command buffer using DRM. If in PCI mode, we can bypass DRM,
+ * but not for command buffers that contains 3D engine state, since then
+ * the DRM command verifier will lose track of the 3D engine state.
+ */
+#ifdef XF86DRI
static void
-VIASubsequentSolidHorVertLine(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int len,
- int dir);
+viaFlushDRIEnabled(ViaCommandBuffer * cb)
+{
+ ScrnInfoPtr pScrn = cb->pScrn;
+ VIAPtr pVia = VIAPTR(pScrn);
+ char *tmp = (char *)cb->buf;
+ int tmpSize;
+ drm_via_cmdbuffer_t b;
+
+ /*
+ * Align command buffer end for AGP DMA.
+ */
+
+ if (pVia->agpDMA && cb->mode == 2 && cb->rindex != HC_ParaType_CmdVdata
+ && (cb->pos & 1)) {
+ OUT_RING(HC_DUMMY);
+ }
+
+ tmpSize = cb->pos * sizeof(CARD32);
+ if (pVia->agpDMA || (pVia->directRenderingEnabled && cb->has3dState)) {
+ cb->mode = 0;
+ cb->has3dState = FALSE;
+ while (tmpSize > 0) {
+ b.size = (tmpSize > VIA_DMASIZE) ? VIA_DMASIZE : tmpSize;
+ tmpSize -= b.size;
+ b.buf = tmp;
+ tmp += b.size;
+ if (drmCommandWrite(pVia->drmFD,
+ ((pVia->agpDMA) ? DRM_VIA_CMDBUFFER : DRM_VIA_PCICMD), &b,
+ sizeof(b))) {
+ ErrorF("DRM command buffer submission failed.\n");
+ viaDumpDMA(cb);
+ return;
+ }
+ }
+ cb->pos = 0;
+ } else {
+ viaFlushPCI(cb);
+ }
+}
+#endif
+
+/*
+ * Initialize a command buffer. Some fields are currently not used since they
+ * are intended for Unichrome Pro group A video commands.
+ */
+
+int
+viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf, unsigned size)
+{
+#ifdef XF86DRI
+ VIAPtr pVia = VIAPTR(pScrn);
+#endif
+
+ buf->pScrn = pScrn;
+ buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2;
+ buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32));
+ if (!buf->buf)
+ return BadAlloc;
+ buf->waitFlags = 0;
+ buf->pos = 0;
+ buf->mode = 0;
+ buf->header_start = 0;
+ buf->rindex = 0;
+ buf->has3dState = FALSE;
+ buf->flushFunc = viaFlushPCI;
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ buf->flushFunc = viaFlushDRIEnabled;
+ }
+#endif
+ return Success;
+}
+
+/*
+ * Free resources associated with a command buffer.
+ */
+
+void
+viaTearDownCBuffer(ViaCommandBuffer * buf)
+{
+ if (buf && buf->buf)
+ xfree(buf->buf);
+ buf->buf = NULL;
+}
+
+/*
+ * Leftover from VIAs code.
+ */
static void
-VIASetupForDashedLine(
- ScrnInfoPtr pScrn,
- int fg,
- int bg,
- int rop,
- unsigned int planemask,
- int length,
- unsigned char *pattern);
+viaInitAgp(VIAPtr pVia)
+{
+ VIASETREG(VIA_REG_TRANSET, 0x00100000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
+ VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x7D000000);
+
+ VIASETREG(VIA_REG_TRANSET, 0xfe020000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
+}
+
+/*
+ * Initialize the virtual command queue. Header 2 commands can be put
+ * in this queue for buffering. AFAIK it doesn't handle Header 1
+ * commands, which is really a pity, since it has to be idled before
+ * issuing a H1 command.
+ */
static void
-VIASubsequentDashedTwoPointLine(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int flags,
- int phase);
-
-static void VIASetClippingRectangle(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2);
-
-static void VIADisableClipping( ScrnInfoPtr );
+viaEnableVQ(VIAPtr pVia)
+{
+ CARD32
+ vqStartAddr = pVia->VQStart,
+ vqEndAddr = pVia->VQEnd,
+ vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF),
+ vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF),
+ vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) |
+ ((vqEndAddr & 0xFF000000) >> 16),
+ vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
+
+ VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x080003fe);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0b000260);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0c000274);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0d000264);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0e000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0f000020);
+ VIASETREG(VIA_REG_TRANSPACE, 0x1000027e);
+ VIASETREG(VIA_REG_TRANSPACE, 0x110002fe);
+ VIASETREG(VIA_REG_TRANSPACE, 0x200f0060);
+
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000006);
+ VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
+ VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
+ VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
+
+ VIASETREG(VIA_REG_TRANSPACE, vqStartEndH);
+ VIASETREG(VIA_REG_TRANSPACE, vqStartL);
+ VIASETREG(VIA_REG_TRANSPACE, vqEndL);
+ VIASETREG(VIA_REG_TRANSPACE, vqLen);
+}
+
+/*
+ * Disable the virtual command queue.
+ */
void
-VIAInitialize2DEngine(ScrnInfoPtr pScrn)
+viaDisableVQ(ScrnInfoPtr pScrn)
{
- VIAPtr pVia = VIAPTR(pScrn);
- CARD32 dwVQStartAddr, dwVQEndAddr;
- CARD32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
- CARD32 dwGEMode;
- ViaTwodContext *tdc = &pVia->td;
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
+ VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
+ VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
+ VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
+}
- /* init 2D engine regs to reset 2D engine */
- VIASETREG(0x04, 0x0);
- VIASETREG(0x08, 0x0);
- VIASETREG(0x0c, 0x0);
- VIASETREG(0x10, 0x0);
- VIASETREG(0x14, 0x0);
- VIASETREG(0x18, 0x0);
- VIASETREG(0x1c, 0x0);
- VIASETREG(0x20, 0x0);
- VIASETREG(0x24, 0x0);
- VIASETREG(0x28, 0x0);
- VIASETREG(0x2c, 0x0);
- VIASETREG(0x30, 0x0);
- VIASETREG(0x34, 0x0);
- VIASETREG(0x38, 0x0);
- VIASETREG(0x3c, 0x0);
- VIASETREG(0x40, 0x0);
-
- /* Init AGP and VQ regs */
- VIASETREG(0x43c, 0x00100000);
- VIASETREG(0x440, 0x00000000);
- VIASETREG(0x440, 0x00333004);
- VIASETREG(0x440, 0x60000000);
- VIASETREG(0x440, 0x61000000);
- VIASETREG(0x440, 0x62000000);
- VIASETREG(0x440, 0x63000000);
- VIASETREG(0x440, 0x64000000);
- VIASETREG(0x440, 0x7D000000);
-
- VIASETREG(0x43c, 0xfe020000);
- VIASETREG(0x440, 0x00000000);
+/*
+ * Update our 2D state (TwoDContext) with a new mode.
+ */
- if (pVia->VQStart != 0) {
- /* Enable VQ */
- dwVQStartAddr = pVia->VQStart;
- dwVQEndAddr = pVia->VQEnd;
- dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
- dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
- dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) |
- ((dwVQEndAddr & 0xFF000000) >> 16);
- dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
-
- VIASETREG(0x43c, 0x00fe0000);
- VIASETREG(0x440, 0x080003fe);
- VIASETREG(0x440, 0x0a00027c);
- VIASETREG(0x440, 0x0b000260);
- VIASETREG(0x440, 0x0c000274);
- VIASETREG(0x440, 0x0d000264);
- VIASETREG(0x440, 0x0e000000);
- VIASETREG(0x440, 0x0f000020);
- VIASETREG(0x440, 0x1000027e);
- VIASETREG(0x440, 0x110002fe);
- VIASETREG(0x440, 0x200f0060);
-
- VIASETREG(0x440, 0x00000006);
- VIASETREG(0x440, 0x40008c0f);
- VIASETREG(0x440, 0x44000000);
- VIASETREG(0x440, 0x45080c04);
- VIASETREG(0x440, 0x46800408);
-
- VIASETREG(0x440, dwVQStartEndH);
- VIASETREG(0x440, dwVQStartL);
- VIASETREG(0x440, dwVQEndL);
- VIASETREG(0x440, dwVQLen);
- }
- else {
- /* Diable VQ */
- VIASETREG(0x43c, 0x00fe0000);
- VIASETREG(0x440, 0x00000004);
- VIASETREG(0x440, 0x40008c0f);
- VIASETREG(0x440, 0x44000000);
- VIASETREG(0x440, 0x45080c04);
- VIASETREG(0x440, 0x46800408);
- }
-
- dwGEMode = 0;
-
- switch (pScrn->bitsPerPixel) {
+static Bool
+viaAccelSetMode(int bpp, ViaTwodContext * tdc)
+{
+ switch (bpp) {
case 16:
- dwGEMode |= VIA_GEM_16bpp;
- break;
+ tdc->mode = VIA_GEM_16bpp;
+ tdc->bytesPPShift = 1;
+ return TRUE;
case 32:
- dwGEMode |= VIA_GEM_32bpp;
- break;
+ tdc->mode = VIA_GEM_32bpp;
+ tdc->bytesPPShift = 2;
+ return TRUE;
+ case 8:
+ tdc->mode = VIA_GEM_8bpp;
+ tdc->bytesPPShift = 0;
+ return TRUE;
default:
- dwGEMode |= VIA_GEM_8bpp;
- break;
+ tdc->bytesPPShift = 0;
+ return FALSE;
}
-
- /* Set BPP and Pitch */
- tdc->mode = dwGEMode;
}
+/*
+ * Initialize the 2D engine and set the 2D context mode to the
+ * current screen depth. Also enable the virtual queue.
+ */
+
+void
+viaInitialize2DEngine(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int i;
+
+ /*
+ * init 2D engine regs to reset 2D engine
+ */
+
+ for (i = 0x04; i < 0x44; i += 4) {
+ VIASETREG(i, 0x0);
+ }
-#define CLEAR_CBUFFER(buf, pVia) \
- (buf)->curPos = 0; \
- (pVia)->justSetup = 1;
+ viaInitAgp(pVia);
-#define COND_CLEAR_CBUFFER(buf, pVia) \
- if ((pVia)->justSetup == 1) { \
- (pVia)->justSetup = 0; \
- } else { \
- (buf)->curPos = 0; \
+ if (pVia->VQStart != 0) {
+ viaEnableVQ(pVia);
+ } else {
+ viaDisableVQ(pScrn);
}
-#define CBUFFER(buf,offset,value) \
- (buf)->buffer[(buf)->curPos++] = ((offset) >> 2) | 0xF0000000; \
- (buf)->buffer[(buf)->curPos++] = (value); \
-
+ viaAccelSetMode(pScrn->bitsPerPixel, tdc);
+}
+
+/*
+ * Wait for acceleration engines idle. An expensive way to sync.
+ */
-static void dispatchCBuffer(VIAPtr pVia, ViaCBuffer *buf)
+void
+viaAccelSync(ScrnInfoPtr pScrn)
{
- unsigned size = buf->curPos >> 1;
- int i;
- register CARD32 *bp = buf->buffer;
- unsigned loop = 0;
- register unsigned offset;
- register unsigned value;
-
- /*
- * Not doing this wait will probably stall the processor
- * for an unacceptable amount of time in VIASETREG while other high
- * priority interrupts may be pending.
- */
-
+ VIAPtr pVia = VIAPTR(pScrn);
+ int loop = 0;
+
mem_barrier();
- while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP));
+ while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
+ && (loop++ < MAXLOOP)) ;
+
while ((VIAGETREG(VIA_REG_STATUS) &
- (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY )) &&
- (loop++ < MAXLOOP));
-
- for(i=0; i<size; ++i) {
- offset = (*bp++ & 0x0FFFFFFF) << 2;
- value = *bp++;
- VIASETREG( offset , value);
+ (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+ (loop++ < MAXLOOP)) ;
+}
+
+/*
+ * Set 2D state clipping on.
+ */
+
+static void
+viaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ tdc->clipping = TRUE;
+ tdc->clipX1 = x1;
+ tdc->clipY1 = y1;
+ tdc->clipX2 = x2;
+ tdc->clipY2 = y2;
+}
+
+/*
+ * Set 2D state clipping off.
+ */
+
+static void
+viaDisableClipping(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ tdc->clipping = FALSE;
+}
+
+/*
+ * Emit clipping borders to the command buffer and update the 2D context
+ * current command with clipping info.
+ */
+
+static int
+viaAccelClippingHelper(ViaCommandBuffer * cb, int refY, ViaTwodContext * tdc)
+{
+ if (tdc->clipping) {
+ refY = (refY < tdc->clipY1) ? refY : tdc->clipY1;
+ tdc->cmd |= VIA_GEC_CLIP_ENABLE;
+ BEGIN_RING(4);
+ OUT_RING_H1(VIA_REG_CLIPTL,
+ ((tdc->clipY1 - refY) << 16) | tdc->clipX1);
+ OUT_RING_H1(VIA_REG_CLIPBR,
+ ((tdc->clipY2 - refY) << 16) | tdc->clipX2);
+ } else {
+ tdc->cmd &= ~VIA_GEC_CLIP_ENABLE;
}
+ return refY;
+
+}
+
+/*
+ * Emit a solid blit operation to the command buffer.
+ */
+
+static void
+viaAccelSolidHelper(ViaCommandBuffer * cb, int x, int y, int w, int h,
+ unsigned fbBase, CARD32 mode, unsigned pitch, CARD32 fg, CARD32 cmd)
+{
+ BEGIN_RING(14);
+ OUT_RING_H1(VIA_REG_GEMODE, mode);
+ OUT_RING_H1(VIA_REG_DSTBASE, fbBase >> 3);
+ OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (pitch >> 3) << 16);
+ OUT_RING_H1(VIA_REG_DSTPOS, (y << 16) | x);
+ OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1));
+ OUT_RING_H1(VIA_REG_FGCOLOR, fg);
+ OUT_RING_H1(VIA_REG_GECMD, cmd);
}
-static void dispatchCBufferAGP(VIAPtr pVia, ViaCBuffer *buf)
+/*
+ * Check if we can use a planeMask and update the 2D context accordingly.
+ */
+
+static Bool
+viaAccelPlaneMaskHelper(ViaTwodContext * tdc, CARD32 planeMask)
{
-#ifdef XF86DRI
- drm_via_cmdbuffer_t b;
-
- b.buf = (char *)(buf->buffer);
- b.size = buf->curPos*sizeof(CARD32);
-
- if (pVia->directRenderingEnabled && pVia->agpEnable && pVia->dma2d) {
- VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
- if (pVIADRI->ringBufActive) {
- if (drmCommandWrite(pVia->drmFD,DRM_VIA_CMDBUFFER,&b,sizeof(b)))
- dispatchCBuffer(pVia,buf); /* No success using AGP. Try PCI instead. */
- return;
+ CARD32 modeMask = (1 << ((1 << tdc->bytesPPShift) << 3)) - 1;
+ CARD32 curMask = 0x00000000;
+ CARD32 curByteMask;
+ int i;
+
+ if ((planeMask & modeMask) != modeMask) {
+
+ /*
+ * Masking doesn't work in 8bpp.
+ */
+
+ if (modeMask == 0xFF) {
+ tdc->keyControl &= 0x0FFFFFFF;
+ return FALSE;
}
+
+ /*
+ * Translate the bit planemask to a byte planemask.
+ */
+
+ for (i = 0; i < (1 << tdc->bytesPPShift); ++i) {
+ curByteMask = (0xFF << (i << 3));
+
+ if ((planeMask & curByteMask) == 0) {
+ curMask |= (1 << i);
+ } else if ((planeMask & curByteMask) != curByteMask) {
+ tdc->keyControl &= 0x0FFFFFFF;
+ return FALSE;
+ }
+ }
+
+ tdc->keyControl = (tdc->keyControl & 0x0FFFFFFF) | (curMask << 28);
}
-#endif
- /*
- * No AGP ringbuffer or no DRI.
- */
- dispatchCBuffer(pVia,buf);
+ return TRUE;
}
+/*
+ * Emit transparency state and color to the command buffer.
+ */
-/* Acceleration init function, sets up pointers to our accelerated functions */
-Bool
-VIAInitAccel(ScreenPtr pScreen)
+static void
+viaAccelTransparentHelper(ViaTwodContext * tdc, ViaCommandBuffer * cb,
+ CARD32 keyControl, CARD32 transColor, Bool usePlaneMask)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- VIAPtr pVia = VIAPTR(pScrn);
- XAAInfoRecPtr xaaptr;
- BoxRec AvailFBArea;
- unsigned long cacheEnd;
- unsigned long cacheEndTmp;
-
+ tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000);
+ tdc->keyControl |= (keyControl & 0x0FFFFFFF);
+ BEGIN_RING(4);
+ OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl);
+ if (keyControl) {
+ OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor);
+ }
+}
- pVia->VQStart = 0;
- if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) &&
- pVia->VQEnable) {
- /* Reserved space for VQ */
- pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE;
- pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1;
- pVia->FBFreeEnd -= VIA_VQ_SIZE;
+/*
+ * Emit a copy blit operation to the command buffer.
+ */
+
+static void
+viaAccelCopyHelper(ViaCommandBuffer * cb, int xs, int ys, int xd, int yd,
+ int w, int h, unsigned srcFbBase, unsigned dstFbBase, CARD32 mode,
+ unsigned srcPitch, unsigned dstPitch, CARD32 cmd)
+{
+ if (cmd & VIA_GEC_DECY) {
+ ys += h - 1;
+ yd += h - 1;
}
- if (pVia->hwcursor) {
- pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
- pVia->CursorStart = pVia->FBFreeEnd;
+
+ if (cmd & VIA_GEC_DECX) {
+ xs += w - 1;
+ xd += w - 1;
+ }
+
+ BEGIN_RING(16);
+ OUT_RING_H1(VIA_REG_GEMODE, mode);
+ OUT_RING_H1(VIA_REG_SRCBASE, srcFbBase >> 3);
+ OUT_RING_H1(VIA_REG_DSTBASE, dstFbBase >> 3);
+ OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE |
+ ((dstPitch >> 3) << 16) | (srcPitch >> 3));
+ OUT_RING_H1(VIA_REG_SRCPOS, (ys << 16) | xs);
+ OUT_RING_H1(VIA_REG_DSTPOS, (yd << 16) | xd);
+ OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1));
+ OUT_RING_H1(VIA_REG_GECMD, cmd);
+}
+
+/*
+ * XAA functions. Note that the 2047 line blitter limit has been worked around by adding
+ * min(y1, y2, clipping y) * stride to the offset (which is recommended by VIA docs).
+ * The y values (including clipping) must be subtracted accordingly.
+ */
+
+static void
+viaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned planemask, int trans_color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 cmd;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ cmd = VIA_GEC_BLT | VIAACCELCOPYROP(rop);
+
+ if (xdir < 0)
+ cmd |= VIA_GEC_DECX;
+
+ if (ydir < 0)
+ cmd |= VIA_GEC_DECY;
+
+ tdc->cmd = cmd;
+ viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+ trans_color, FALSE);
+}
+
+static void
+viaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ sub = viaAccelClippingHelper(cb, y2, tdc);
+ viaAccelCopyHelper(cb, x1, 0, x2, y2 - sub, w, h,
+ pScrn->fbOffset + pVia->Bpl * y1, pScrn->fbOffset + pVia->Bpl * sub,
+ tdc->mode, pVia->Bpl, pVia->Bpl, tdc->cmd);
+ ADVANCE_RING;
+}
+
+/*
+ * SetupForSolidFill is also called to set up for lines.
+ */
+
+static void
+viaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
+ tdc->fgColor = color;
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+}
+
+static void
+viaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ viaAccelSolidHelper(cb, x, y - sub, w, h,
+ pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, tdc->fgColor,
+ tdc->cmd);
+ ADVANCE_RING;
+}
+
+/*
+ * Original VIA comment:
+ * The meaning of the two pattern paremeters to Setup & Subsequent for
+ * Mono8x8Patterns varies depending on the flag bits. We specify
+ * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns
+ * without caching in the frame buffer. Thus, Setup gets the pattern bits.
+ * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify
+ * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated
+ * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN,
+ * then Setup would get the unrotated pattern, and Subsequent gets the
+ * origin values.
+ */
+
+static void
+viaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattern0, int pattern1,
+ int fg, int bg, int rop, unsigned planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int cmd;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO |
+ VIAACCELPATTERNROP(rop);
+
+ if (bg == -1) {
+ cmd |= VIA_GEC_MPAT_TRANS;
}
- VIAInitialize2DEngine(pScrn);
+ tdc->cmd = cmd;
+ tdc->fgColor = fg;
+ tdc->bgColor = bg;
+ tdc->pattern0 = pattern0;
+ tdc->pattern1 = pattern1;
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+
+}
+
+static void
+viaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx,
+ int patOffy, int x, int y, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 patOffset;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ patOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ dstBase = pScrn->fbOffset + sub * pVia->Bpl;
+
+ BEGIN_RING(22);
+ OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
+ OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
+ OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
+ OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | x);
+ OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
+ OUT_RING_H1(VIA_REG_PATADDR, patOffset);
+ OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
+ OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor);
+ OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0);
+ OUT_RING_H1(VIA_REG_MONOPAT1, tdc->pattern1);
+ OUT_RING_H1(VIA_REG_GECMD, tdc->cmd);
+ ADVANCE_RING;
+}
+
+static void
+viaSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int rop, unsigned planemask, int trans_color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ tdc->cmd = VIA_GEC_BLT | VIAACCELPATTERNROP(rop);
+ tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl);
+ viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+ trans_color, FALSE);
+}
+
+static void
+viaSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx,
+ int patOffy, int x, int y, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 patAddr;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
- if (pScrn->depth == 8) {
- pVia->PlaneMask = 0xFF;
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ patAddr = (tdc->patternAddr >> 3) |
+ ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ dstBase = pScrn->fbOffset + sub * pVia->Bpl;
+
+ BEGIN_RING(14);
+ OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
+ OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
+ OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
+ OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | x);
+ OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
+ OUT_RING_H1(VIA_REG_PATADDR, patAddr);
+ OUT_RING_H1(VIA_REG_GECMD, tdc->cmd);
+ ADVANCE_RING;
+}
+
+/*
+ * CPU to screen functions cannot use AGP due to complicated syncing. Therefore the
+ * command buffer is flushed before new command emissions and viaFluchPCI is called
+ * explicitly instead of cb->flushFunc() at the end of each CPU to screen function.
+ * Should the buffer get completely filled again by a CPU to screen command emission,
+ * a horrible error will occur.
+ */
+
+static void
+viaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int cmd;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO |
+ VIAACCELCOPYROP(rop);
+
+ if (bg == -1) {
+ cmd |= VIA_GEC_MSRC_TRANS;
}
- else if (pScrn->depth == 15) {
- pVia->PlaneMask = 0x7FFF;
+
+ tdc->cmd = cmd;
+ tdc->fgColor = fg;
+ tdc->bgColor = bg;
+
+ ADVANCE_RING;
+
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+}
+
+static void
+viaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (skipleft) {
+ viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1),
+ (y + h - 1));
+ }
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ BEGIN_RING(4);
+ OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor);
+ OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
+ viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0,
+ pScrn->fbOffset + sub * pVia->Bpl, tdc->mode, pVia->Bpl, pVia->Bpl,
+ tdc->cmd);
+
+ viaFlushPCI(cb);
+ viaDisableClipping(pScrn);
+}
+
+static void
+viaSetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned planemask,
+ int trans_color, int bpp, int depth)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop);
+ ADVANCE_RING;
+ viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+ trans_color, FALSE);
+}
+
+static void
+viaSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (skipleft) {
+ viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1),
+ (y + h - 1));
+ }
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0,
+ pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, pVia->Bpl,
+ tdc->cmd);
+
+ viaFlushPCI(cb);
+ viaDisableClipping(pScrn);
+}
+
+static void
+viaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+ tdc->cmd = VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
+ tdc->fgColor = color;
+
+ BEGIN_RING(6);
+ OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
+ OUT_RING_H1(VIA_REG_MONOPAT0, 0xFF);
+ OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
+}
+
+static void
+viaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int flags)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int dx, dy, cmd, tmp, error = 1;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ cmd = tdc->cmd | VIA_GEC_LINE;
+
+ dx = x2 - x1;
+ if (dx < 0) {
+ dx = -dx;
+ cmd |= VIA_GEC_DECX; /* line will be drawn from right */
+ error = 0;
}
- else if (pScrn->depth == 16) {
- pVia->PlaneMask = 0xFFFF;
+
+ dy = y2 - y1;
+ if (dy < 0) {
+ dy = -dy;
+ cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */
}
- else if (pScrn->depth == 24) {
- pVia->PlaneMask = 0xFFFFFF;
+
+ if (dy > dx) {
+ tmp = dy;
+ dy = dx;
+ dx = tmp; /* Swap 'dx' and 'dy' */
+ cmd |= VIA_GEC_Y_MAJOR; /* Y major line */
}
- /* General acceleration flags */
+ if (flags & OMIT_LAST) {
+ cmd |= VIA_GEC_LASTPIXEL_OFF;
+ }
+
+ sub = viaAccelClippingHelper(cb, (y1 < y2) ? y1 : y2, tdc);
+
+ dstBase = pScrn->fbOffset + sub * pVia->Bpl;
+ y1 -= sub;
+ y2 -= sub;
+
+ BEGIN_RING(14);
+ OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
+ OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
+
+ /*
+ * major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1)
+ * K1 = 2*dmin K2 = 2*(dmin - dmax)
+ * Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax))
+ */
+
+ OUT_RING_H1(VIA_REG_LINE_K1K2,
+ ((((dy << 1) & 0x3fff) << 16) | (((dy - dx) << 1) & 0x3fff)));
+ OUT_RING_H1(VIA_REG_LINE_XY, ((y1 << 16) | x1));
+ OUT_RING_H1(VIA_REG_DIMENSION, dx);
+ OUT_RING_H1(VIA_REG_LINE_ERROR,
+ (((dy << 1) - dx - error) & 0x3fff) | 0xFF0000);
+ OUT_RING_H1(VIA_REG_GECMD, cmd);
+ ADVANCE_RING;
+
+}
+
+static void
+viaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ dstBase = pScrn->fbOffset + sub * pVia->Bpl;
+
+ BEGIN_RING(10);
+ OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
+ OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
+
+ if (dir == DEGREES_0) {
+ OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | x);
+ OUT_RING_H1(VIA_REG_DIMENSION, (len - 1));
+ OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT);
+ } else {
+ OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | x);
+ OUT_RING_H1(VIA_REG_DIMENSION, ((len - 1) << 16));
+ OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT);
+ }
+ ADVANCE_RING;
+}
+
+static void
+viaSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length, unsigned char *pattern)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int cmd;
+ CARD32 pat = *(CARD32 *) pattern;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+ cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
+
+ if (bg == -1) {
+ cmd |= VIA_GEC_MPAT_TRANS;
+ }
+
+ tdc->cmd = cmd;
+ tdc->fgColor = fg;
+ tdc->bgColor = bg;
+
+ switch (length) {
+ case 2:
+ pat |= pat << 2; /* fall through */
+ case 4:
+ pat |= pat << 4; /* fall through */
+ case 8:
+ pat |= pat << 8; /* fall through */
+ case 16:
+ pat |= pat << 16;
+ }
+
+ tdc->pattern0 = pat;
+
+ BEGIN_RING(8);
+ OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
+ OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
+ OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor);
+ OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0);
+}
+
+static void
+viaSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int flags, int phase)
+{
+ viaSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags);
+}
+
+static int
+viaInitXAA(ScreenPtr pScreen)
+{
+
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ XAAInfoRecPtr xaaptr;
+
+ /*
+ * General acceleration flags
+ */
+
if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec()))
- return FALSE;
+ return FALSE;
xaaptr->Flags = PIXMAP_CACHE |
- OFFSCREEN_PIXMAPS |
- LINEAR_FRAMEBUFFER |
- MICROSOFT_ZERO_LINE_BIAS |
- 0;
+ OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER | MICROSOFT_ZERO_LINE_BIAS | 0;
if (pScrn->bitsPerPixel == 8)
- xaaptr->CachePixelGranularity = 128;
+ xaaptr->CachePixelGranularity = 128;
- /* Clipping */
- xaaptr->SetClippingRectangle = VIASetClippingRectangle;
- xaaptr->DisableClipping = VIADisableClipping;
+ xaaptr->SetClippingRectangle = viaSetClippingRectangle;
+ xaaptr->DisableClipping = viaDisableClipping;
xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL |
HARDWARE_CLIP_SOLID_LINE |
HARDWARE_CLIP_DASHED_LINE |
HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
HARDWARE_CLIP_MONO_8x8_FILL |
HARDWARE_CLIP_COLOR_8x8_FILL |
- HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND |
- 0;
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0;
- xaaptr->Sync = VIAAccelSync;
+ xaaptr->Sync = viaAccelSync;
- /* ScreenToScreen copies */
- xaaptr->SetupForScreenToScreenCopy = VIASetupForScreenToScreenCopy;
- xaaptr->SubsequentScreenToScreenCopy = VIASubsequentScreenToScreenCopy;
+ xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy;
+ xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy;
xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
- /* Solid filled rectangles */
- xaaptr->SetupForSolidFill = VIASetupForSolidFill;
- xaaptr->SubsequentSolidFillRect = VIASubsequentSolidFillRect;
+ xaaptr->SetupForSolidFill = viaSetupForSolidFill;
+ xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect;
xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
- /* Mono 8x8 pattern fills */
- xaaptr->SetupForMono8x8PatternFill = VIASetupForMono8x8PatternFill;
+ xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill;
xaaptr->SubsequentMono8x8PatternFillRect =
- VIASubsequentMono8x8PatternFillRect;
+ viaSubsequentMono8x8PatternFillRect;
xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK |
HARDWARE_PATTERN_PROGRAMMED_BITS |
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
- BIT_ORDER_IN_BYTE_MSBFIRST |
- 0;
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST | 0;
- /* Color 8x8 pattern fills */
- xaaptr->SetupForColor8x8PatternFill = VIASetupForColor8x8PatternFill;
+ xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill;
xaaptr->SubsequentColor8x8PatternFillRect =
- VIASubsequentColor8x8PatternFillRect;
+ viaSubsequentColor8x8PatternFillRect;
xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK |
NO_TRANSPARENCY |
HARDWARE_PATTERN_PROGRAMMED_BITS |
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
- 0;
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0;
-#if 0 /* Buggy. Temporarily disabled 2005-01-23 */
-
- /* Screen to Screen color expansion. */
- xaaptr->SetupForScreenToScreenColorExpandFill =
- VIASetupForScreenToScreenColorExpand;
- xaaptr->SubsequentScreenToScreenColorExpandFill =
- VIASubsequentScreenToScreenColorExpand;
- xaaptr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
- BIT_ORDER_IN_BYTE_MSBFIRST |
- ROP_NEEDS_SOURCE |
- 0;
-#endif
-
- /* Solid lines */
- xaaptr->SetupForSolidLine = VIASetupForSolidLine;
- xaaptr->SubsequentSolidTwoPointLine = VIASubsequentSolidTwoPointLine;
- xaaptr->SubsequentSolidHorVertLine = VIASubsequentSolidHorVertLine;
+ xaaptr->SetupForSolidLine = viaSetupForSolidLine;
+ xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine;
+ xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine;
xaaptr->SolidBresenhamLineErrorTermBits = 14;
xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
- /* dashed line */
- xaaptr->SetupForDashedLine = VIASetupForDashedLine;
- xaaptr->SubsequentDashedTwoPointLine = VIASubsequentDashedTwoPointLine;
+ xaaptr->SetupForDashedLine = viaSetupForDashedLine;
+ xaaptr->SubsequentDashedTwoPointLine = viaSubsequentDashedTwoPointLine;
xaaptr->DashPatternMaxLength = 8;
xaaptr->DashedLineFlags = NO_PLANEMASK |
ROP_NEEDS_SOURCE |
- LINE_PATTERN_POWER_OF_2_ONLY |
- LINE_PATTERN_MSBFIRST_LSBJUSTIFIED |
- 0;
+ LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0;
- /* CPU to Screen color expansion */
xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
CPU_TRANSFER_PAD_DWORD |
SCANLINE_PAD_DWORD |
BIT_ORDER_IN_BYTE_MSBFIRST |
- LEFT_EDGE_CLIPPING |
- ROP_NEEDS_SOURCE |
- 0;
+ LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0;
xaaptr->SetupForScanlineCPUToScreenColorExpandFill =
- VIASetupForCPUToScreenColorExpandFill;
+ viaSetupForCPUToScreenColorExpandFill;
xaaptr->SubsequentScanlineCPUToScreenColorExpandFill =
- VIASubsequentScanlineCPUToScreenColorExpandFill;
+ viaSubsequentScanlineCPUToScreenColorExpandFill;
xaaptr->ColorExpandBase = pVia->BltBase;
xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE;
- /* ImageWrite */
xaaptr->ImageWriteFlags = NO_PLANEMASK |
CPU_TRANSFER_PAD_DWORD |
SCANLINE_PAD_DWORD |
BIT_ORDER_IN_BYTE_MSBFIRST |
- LEFT_EDGE_CLIPPING |
- ROP_NEEDS_SOURCE |
- SYNC_AFTER_IMAGE_WRITE |
- 0;
-
+ LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | SYNC_AFTER_IMAGE_WRITE | 0;
+
/*
- * CLE266 has fast direct processor access to the framebuffer.
- * Therefore, disable the PCI GXcopy.
+ * Most Unichromes are much faster using processor to
+ * framebuffer writes than using the 2D engine for this.
+ * test with x11perf -shmput500!
*/
-
- if (pVia->Chipset == VIA_CLE266)
- xaaptr->ImageWriteFlags |= NO_GXCOPY;
- xaaptr->SetupForImageWrite = VIASetupForImageWrite;
- xaaptr->SubsequentImageWriteRect = VIASubsequentImageWriteRect;
+ if (pVia->Chipset != VIA_K8M800)
+ xaaptr->ImageWriteFlags |= NO_GXCOPY;
+
+ xaaptr->SetupForImageWrite = viaSetupForImageWrite;
+ xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect;
xaaptr->ImageWriteBase = pVia->BltBase;
xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE;
- /* We reserve space for pixel cache */
-
- cacheEnd = pVia->FBFreeEnd / pVia->Bpl;
- cacheEndTmp = (pVia->FBFreeStart + VIA_PIXMAP_CACHE_SIZE + pVia->Bpl-1)
- / pVia->Bpl;
-
- /*
- * Use only requested pixmap size if it is less than available
- * offscreen memory.
- */
+ return XAAInit(pScreen, xaaptr);
- if(cacheEnd > cacheEndTmp)
- cacheEnd = cacheEndTmp;
- /*
- * Clip to the blitter limit
- */
+}
- if (cacheEnd > VIA_MAX_ACCEL_Y)
- cacheEnd = VIA_MAX_ACCEL_Y;
+/*
+ * Mark Sync using the 2D blitter for AGP. NoOp for PCI.
+ * In the future one could even launch a NULL PCI DMA command
+ * to have an interrupt generated, provided it is possible to
+ * write to the PCI DMA engines from the AGP command stream.
+ */
- pVia->FBFreeStart = (cacheEnd + 1) *pVia->Bpl;
+int
+viaAccelMarkSync(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ RING_VARS;
+
+ ++pVia->curMarker;
/*
- * Finally, we set up the video memory space available to the pixmap
- * cache
+ * Wrap around without possibly affecting the int sign bit.
*/
- AvailFBArea.x1 = 0;
- AvailFBArea.y1 = 0;
- AvailFBArea.x2 = pScrn->displayWidth;
- AvailFBArea.y2 = cacheEnd;
-
- xf86InitFBManager(pScreen, &AvailFBArea);
- DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d lines for offscreen memory.\n",
- AvailFBArea.y2 - pScrn->virtualY ));
+ pVia->curMarker &= 0x7FFFFFFF;
- pVia->justSetup = 0;
- return XAAInit(pScreen, xaaptr);
+ if (pVia->agpDMA) {
+ BEGIN_RING(2);
+ OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00);
+ viaAccelSolidHelper(cb, 0, 0, 1, 1, pVia->markerOffset,
+ VIA_GEM_32bpp, 4, pVia->curMarker,
+ (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT);
+ ADVANCE_RING;
+ }
+ return pVia->curMarker;
}
/*
- * The sync function for the GE
+ * Wait for the value to get blitted, or in the PCI case for engine idle.
*/
-void
-VIAAccelSync(ScrnInfoPtr pScrn)
+
+void
+viaAccelWaitMarker(ScreenPtr pScreen, int marker)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- int loop = 0;
-
- mem_barrier();
-
- while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
- ;
-
- while ((VIAGETREG(VIA_REG_STATUS) &
- (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
- (loop++ < MAXLOOP))
- ;
+ CARD32 uMarker = marker;
+
+ if (pVia->agpDMA) {
+ while ((pVia->lastMarkerRead - uMarker) > (1 << 24))
+ pVia->lastMarkerRead = *pVia->markerBuf;
+ } else {
+ viaAccelSync(pScrn);
+ }
}
-/* These are the ScreenToScreen bitblt functions. We support all ROPs, all
- * directions.
- *
+#ifdef VIA_HAVE_EXA
+
+/*
+ * Exa functions. It is assumed that EXA does not exceed the blitter limits.
*/
-static void
-VIASetupForScreenToScreenCopy(
- ScrnInfoPtr pScrn,
- int xdir,
- int ydir,
- int rop,
- unsigned planemask,
- int trans_color)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
- ViaCBuffer *buf = &pVia->cBuf;
+static Bool
+viaExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
ViaTwodContext *tdc = &pVia->td;
- cmd = VIA_GEC_BLT | (XAAGetCopyROP(rop) << 24);
+ RING_VARS;
- if (xdir < 0)
- cmd |= VIA_GEC_DECX;
+ if (exaGetPixmapPitch(pPixmap) & 7)
+ return FALSE;
- if (ydir < 0)
- cmd |= VIA_GEC_DECY;
+ if (!viaAccelSetMode(pPixmap->drawable.depth, tdc))
+ return FALSE;
- pVia->SavedCmd = cmd;
+ if (!viaAccelPlaneMaskHelper(tdc, planeMask))
+ return FALSE;
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE);
- CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- if (trans_color != -1) {
- /* Transparent Bitblt */
- CBUFFER(buf,VIA_REG_SRCCOLORKEY, trans_color);
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x4000);
- }
- else {
- /* Disable Transparent Bitblt */
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0);
- }
+ tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu);
+
+ tdc->fgColor = fg;
+
+ return TRUE;
}
static void
-VIASubsequentScreenToScreenCopy(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int w,
- int h)
+viaExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
ViaTwodContext *tdc = &pVia->td;
- CARD32 srcBase, dstBase;
+ CARD32 dstPitch, dstOffset;
- if (!w || !h)
- return;
+ RING_VARS;
- srcBase = y1*pVia->Bpl + x1*pVia->Bpp;
- dstBase = y2*pVia->Bpl + x2*pVia->Bpp;
+ int w = x2 - x1, h = y2 - y1;
- x1 = (srcBase & 31);
- x2 = (dstBase & 31);
+ dstPitch = exaGetPixmapPitch(pPixmap);
+ dstOffset = exaGetPixmapOffset(pPixmap);
- switch (pScrn->bitsPerPixel) {
- case 16:
- x1 >>= 1;
- x2 >>= 1;
- break;
- case 32:
- x1 >>= 2;
- x2 >>= 2;
- break;
- default:
- break;
- }
+ viaAccelSolidHelper(cb, x1, y1, w, h, dstOffset,
+ tdc->mode, dstPitch, tdc->fgColor, tdc->cmd);
+ ADVANCE_RING;
+}
- y1 = 0;
- y2 = 0;
+static void
+viaExaDoneSolidCopy(PixmapPtr pPixmap)
+{
+}
- if (pVia->SavedCmd & VIA_GEC_DECX) {
- x1 += (w - 1);
- x2 += (w - 1);
- }
+static Bool
+viaExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
+ int ydir, int alu, Pixel planeMask)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
- if (pVia->SavedCmd & VIA_GEC_DECY) {
- y1 += (h - 1);
- y2 += (h - 1);
- }
+ RING_VARS;
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode );
- /* Set Src and Dst base address and pitch, pitch is qword */
- CBUFFER(buf,VIA_REG_SRCBASE, (srcBase & ~31) >> 3);
- CBUFFER(buf,VIA_REG_DSTBASE, (dstBase & ~31) >> 3);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- (pVia->Bpl >> 3) | ((pVia->Bpl >> 3) << 16));
- CBUFFER(buf,VIA_REG_SRCPOS, ((y1 << 16) | x1));
- CBUFFER(buf,VIA_REG_DSTPOS, ((y2 << 16) | x2));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
- dispatchCBufferAGP(pVia, buf);
-}
+ if (pSrcPixmap->drawable.bitsPerPixel !=
+ pDstPixmap->drawable.bitsPerPixel)
+ return FALSE;
+ if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3)
+ return FALSE;
-/*
- * SetupForSolidFill is also called to set up for lines.
- */
+ if (exaGetPixmapPitch(pDstPixmap) & 7)
+ return FALSE;
-static void
-VIASetupForSolidFill(
- ScrnInfoPtr pScrn,
- int color,
- int rop,
- unsigned planemask)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
+ tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap);
- cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT |
- (XAAGetPatternROP(rop) << 24);
+ tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu);
+ if (xdir < 0)
+ tdc->cmd |= VIA_GEC_DECX;
+ if (ydir < 0)
+ tdc->cmd |= VIA_GEC_DECY;
- pVia->SavedCmd = cmd;
- pVia->SavedFgColor = color;
-}
+ if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc))
+ return FALSE;
+ if (!viaAccelPlaneMaskHelper(tdc, planeMask))
+ return FALSE;
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE);
+
+ return TRUE;
+}
static void
-VIASubsequentSolidFillRect(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h)
+viaExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
+ int width, int height)
{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
ViaTwodContext *tdc = &pVia->td;
+ CARD32 srcOffset = tdc->srcOffset;
+ CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap);
- if (!w || !h)
- return;
-
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- /* Set Src and Dst base address and pitch, pitch is qword */
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ RING_VARS;
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
- dispatchCBufferAGP(pVia, buf);
+ if (!width || !height)
+ return;
+ viaAccelCopyHelper(cb, srcX, srcY, dstX, dstY, width, height,
+ srcOffset, dstOffset, tdc->mode, tdc->srcPitch,
+ exaGetPixmapPitch(pDstPixmap), tdc->cmd);
+ ADVANCE_RING;
}
-
-/*
- * The meaning of the two pattern paremeters to Setup & Subsequent for
- * Mono8x8Patterns varies depending on the flag bits. We specify
- * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns
- * without caching in the frame buffer. Thus, Setup gets the pattern bits.
- * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify
- * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated
- * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN,
- * then Setup would get the unrotated pattern, and Subsequent gets the
- * origin values.
- */
-
+#ifdef VIA_DEBUG_COMPOSITE
static void
-VIASetupForMono8x8PatternFill(
- ScrnInfoPtr pScrn,
- int pattern0,
- int pattern1,
- int fg,
- int bg,
- int rop,
- unsigned planemask)
+viaExaCompositePictDesc(PicturePtr pict, char *string, int n)
{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
+ char format[20];
+ char size[20];
- cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO |
- (XAAGetPatternROP(rop) << 24);
+ if (!pict) {
+ snprintf(string, n, "None");
+ return;
+ }
- if (bg == -1) {
- /* transparent mono pattern */
- cmd |= VIA_GEC_MPAT_TRANS;
+ switch (pict->format) {
+ case PICT_x8r8g8b8:
+ snprintf(format, 20, "RGB8888");
+ break;
+ case PICT_a8r8g8b8:
+ snprintf(format, 20, "ARGB8888");
+ break;
+ case PICT_r5g6b5:
+ snprintf(format, 20, "RGB565 ");
+ break;
+ case PICT_x1r5g5b5:
+ snprintf(format, 20, "RGB555 ");
+ break;
+ case PICT_a8:
+ snprintf(format, 20, "A8 ");
+ break;
+ case PICT_a1:
+ snprintf(format, 20, "A1 ");
+ break;
+ default:
+ snprintf(format, 20, "0x%x", (int)pict->format);
+ break;
}
- pVia->SavedCmd = cmd;
- pVia->SavedFgColor = fg;
- pVia->SavedBgColor = bg;
- pVia->SavedPattern0 = pattern0;
- pVia->SavedPattern1 = pattern1;
-}
+ snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
+ pict->pDrawable->height, pict->repeat ? " R" : "");
+ snprintf(string, n, "0x%lx: fmt %s (%s)", (long)pict->pDrawable, format,
+ size);
+}
static void
-VIASubsequentMono8x8PatternFillRect(
- ScrnInfoPtr pScrn,
- int patOffx,
- int patOffy,
- int x,
- int y,
- int w,
- int h)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- CARD32 dwPatOffset;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
-
- if (!w || !h)
- return;
-
- dwPatOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
+viaExaPrintComposite(CARD8 op,
+ PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
+{
+ char sop[20];
+ char srcdesc[40], maskdesc[40], dstdesc[40];
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- /* Set Src and Dst base address and pitch, pitch is qword */
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ switch (op) {
+ case PictOpSrc:
+ sprintf(sop, "Src");
+ break;
+ case PictOpOver:
+ sprintf(sop, "Over");
+ break;
+ default:
+ sprintf(sop, "0x%x", (int)op);
+ break;
+ }
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_PATADDR, dwPatOffset);
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor);
- CBUFFER(buf,VIA_REG_MONOPAT0, pVia->SavedPattern0);
- CBUFFER(buf,VIA_REG_MONOPAT1, pVia->SavedPattern1);
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
- dispatchCBufferAGP(pVia, buf);
+ viaExaCompositePictDesc(pSrc, srcdesc, 40);
+ viaExaCompositePictDesc(pMask, maskdesc, 40);
+ viaExaCompositePictDesc(pDst, dstdesc, 40);
+ ErrorF("Composite fallback: op %s, \n"
+ " src %s, \n"
+ " mask %s, \n"
+ " dst %s, \n", sop, srcdesc, maskdesc, dstdesc);
}
+#endif
-static void
-VIASetupForColor8x8PatternFill(
- ScrnInfoPtr pScrn,
- int patternx,
- int patterny,
- int rop,
- unsigned planemask,
- int trans_color)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
+/*
+ * Helper for bitdepth expansion.
+ */
- cmd = VIA_GEC_BLT | (XAAGetPatternROP(rop) << 24);
+static CARD32
+viaBitExpandHelper(CARD32 component, CARD32 bits)
+{
+ CARD32 tmp, mask;
- pVia->SavedCmd = cmd;
- pVia->SavedPatternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl);
+ mask = (1 << (8 - bits)) - 1;
+ tmp = component << (8 - bits);
+ return ((component & 1) ? tmp | mask : tmp);
}
+/*
+ * Extract the components from a pixel of format "format" to an
+ * argb8888 pixel. This is used to extract data from one-pixel repeat pixmaps.
+ * Assumes little endian.
+ */
static void
-VIASubsequentColor8x8PatternFillRect(
- ScrnInfoPtr pScrn,
- int patOffx,
- int patOffy,
- int x,
- int y,
- int w,
- int h)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- CARD32 dwPatAddr;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
+viaPixelARGB8888(unsigned format, void *pixelP, CARD32 * argb8888)
+{
+ CARD32 bits, shift, pixel, bpp;
- if (!w || !h)
- return;
+ bpp = PICT_FORMAT_BPP(format);
- dwPatAddr = (pVia->SavedPatternAddr >> 3) |
- ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
+ if (bpp <= 8) {
+ pixel = *((CARD8 *) pixelP);
+ } else if (bpp <= 16) {
+ pixel = *((CARD16 *) pixelP);
+ } else {
+ pixel = *((CARD32 *) pixelP);
+ }
+
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_A:
+ bits = PICT_FORMAT_A(format);
+ *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 24;
+ return;
+ case PICT_TYPE_ARGB:
+ shift = 0;
+ bits = PICT_FORMAT_B(format);
+ *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits);
+ shift += bits;
+ bits = PICT_FORMAT_G(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) << 8;
+ shift += bits;
+ bits = PICT_FORMAT_R(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) << 16;
+ shift += bits;
+ bits = PICT_FORMAT_A(format);
+ *argb8888 |= ((bits) ?
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) : 0xFF) << 24;
+ return;
+ case PICT_TYPE_ABGR:
+ shift = 0;
+ bits = PICT_FORMAT_B(format);
+ *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 16;
+ shift += bits;
+ bits = PICT_FORMAT_G(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) << 8;
+ shift += bits;
+ bits = PICT_FORMAT_R(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), bits);
+ shift += bits;
+ bits = PICT_FORMAT_A(format);
+ *argb8888 |= ((bits) ?
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) : 0xFF) << 24;
+ return;
+ default:
+ break;
+ }
+ return;
+}
- /* Set Src and Dst base address and pitch, pitch is qword */
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+/*
+ * Check if the above function will work.
+ */
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_PATADDR, dwPatAddr);
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
- dispatchCBufferAGP(pVia, buf);
+static Bool
+viaExpandablePixel(int format)
+{
+ int formatType = PICT_FORMAT_TYPE(format);
+ return (formatType == PICT_TYPE_A ||
+ formatType == PICT_TYPE_ABGR || formatType == PICT_TYPE_ARGB);
}
-static void
-VIASetupForCPUToScreenColorExpandFill(
- ScrnInfoPtr pScrn,
- int fg,
- int bg,
- int rop,
- unsigned planemask)
+/*
+ * Check if we need to force upload of the whole 3D state (if other clients or)
+ * subsystems have touched the 3D engine). Also tell DRI clients and subsystems * that we have touched the 3D engine.
+ */
+
+static Bool
+viaCheckUpload(ScrnInfoPtr pScrn, Via3DState * v3d)
{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
+ VIAPtr pVia = VIAPTR(pScrn);
+ Bool forceUpload;
- cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO |
- (XAAGetCopyROP(rop) << 24);
+ forceUpload = (pVia->lastToUpload != v3d);
+ pVia->lastToUpload = v3d;
- if (bg == -1) {
- cmd |= VIA_GEC_MSRC_TRANS;
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ volatile drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
+ DRIGetSAREAPrivate(pScrn->pScreen);
+ int myContext = DRIGetContext(pScrn->pScreen);
+
+ forceUpload = forceUpload || (saPriv->ctxOwner != myContext);
+ saPriv->ctxOwner = myContext;
}
+#endif
+ return forceUpload;
+}
- pVia->SavedCmd = cmd;
- pVia->SavedFgColor = fg;
- pVia->SavedBgColor = bg;
+static Bool
+viaOrder(CARD32 val, CARD32 * shift)
+{
+ *shift = 0;
- /* Disable Transparent Bitblt */
- CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0);
+ while (val > (1 << *shift))
+ (*shift)++;
+ return (val == (1 << *shift));
}
+#ifdef XF86DRI
-static void
-VIASubsequentScanlineCPUToScreenColorExpandFill(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int skipleft)
+/*
+ * Use PCI DMA if we can. If the system alignments don't match we're using
+ * an aligned bounce buffer for pipelined PCI DMA and memcpy.
+ * throughput for large transfers is around 65 MB/s.
+ */
+
+static Bool
+viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+ char *dst, int dst_pitch)
{
+ ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
-
- /* XAA will be sending bitmap data next. */
- /* We should probably wait for empty/idle here. */
+ drm_via_dmablit_t blit[2], *curBlit;
+ unsigned srcPitch = exaGetPixmapPitch(pSrc);
+ unsigned wBytes = (pSrc->drawable.bitsPerPixel * w + 7) >> 3;
+ unsigned srcOffset;
+ int err, buf, height, i;
+ char *bounceAligned = NULL;
+ unsigned bouncePitch = 0;
+ Bool sync[2], useBounceBuffer;
+ unsigned totSize;
- if (skipleft) {
- VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1));
+ if (!w || !h)
+ return TRUE;
+
+ srcOffset = x * pSrc->drawable.bitsPerPixel;
+ if (srcOffset & 3)
+ return FALSE;
+ srcOffset = exaGetPixmapOffset(pSrc) + y * srcPitch + (srcOffset >> 3);
+
+ totSize = wBytes * h;
+
+ exaWaitSync(pScrn->pScreen);
+ if (totSize < VIA_MIN_DOWNLOAD) {
+ bounceAligned = (char *)pVia->FBBase + srcOffset;
+ while (h--) {
+ memcpy(dst, bounceAligned, wBytes);
+ dst += dst_pitch;
+ bounceAligned += srcPitch;
+ }
+ return TRUE;
}
- /* Set Src and Dst base address and pitch, pitch is qword */
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ if (!pVia->directRenderingEnabled)
+ return FALSE;
- CBUFFER(buf,VIA_REG_SRCPOS, 0);
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor);
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
- dispatchCBuffer(pVia, buf);
+ if ((srcPitch & 3) || (srcOffset & 3)) {
+ ErrorF("VIA EXA download src_pitch misaligned\n");
+ return FALSE;
+ }
-}
+ useBounceBuffer = (((unsigned long)dst & 15) || (dst_pitch & 15));
-#if 0 /* Buggy. Temporarily disabled 2005-01-23 */
-static void
-VIASetupForScreenToScreenColorExpand(
- ScrnInfoPtr pScrn,
- int fg,
- int bg,
- int rop,
- unsigned int planemask)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
- ViaCBuffer *buf = &pVia->cBuf;
+ height = h;
+
+ if (useBounceBuffer) {
+ bounceAligned = (char *)(((unsigned long)pVia->dBounce + 15) & ~15);
+ bouncePitch = (dst_pitch + 15) & ~15;
+ height = VIA_DMA_DL_SIZE / bouncePitch;
+ }
- cmd = VIA_GEC_BLT | VIA_GEC_SRC_MONO | (XAAGetCopyROP(rop) << 24);
+ sync[0] = FALSE;
+ sync[1] = FALSE;
+ buf = 0;
+ err = 0;
+
+ while (h && !err) {
+ curBlit = blit + buf;
+
+ curBlit->num_lines = (h > height) ? height : h;
+ h -= curBlit->num_lines;
+ curBlit->line_length = wBytes;
+ curBlit->fb_addr = srcOffset;
+ curBlit->fb_stride = srcPitch;
+ curBlit->mem_addr = (unsigned char *)
+ ((useBounceBuffer) ? bounceAligned + VIA_DMA_DL_SIZE * buf : dst);
+ curBlit->mem_stride = (useBounceBuffer) ? bouncePitch : dst_pitch;
+ curBlit->to_fb = 0;
+#if (VIA_DRM_VERSION >= ((2 << 16) | 9))
+ curBlit->flags = 0;
+#endif
- if (bg == -1) {
- cmd |= VIA_GEC_MSRC_TRANS;
+ while (-EAGAIN == (err =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, curBlit,
+ sizeof(*curBlit)))) ;
+ sync[buf] = TRUE;
+ buf = (buf) ? 0 : 1;
+ curBlit = blit + buf;
+
+ if (sync[buf] && !err) {
+ while (-EAGAIN == (err =
+ drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC,
+ &curBlit->sync, sizeof(curBlit->sync)))) ;
+ sync[buf] = FALSE;
+ if (!err && useBounceBuffer) {
+ for (i = 0; i < curBlit->num_lines; ++i) {
+ memcpy(dst, curBlit->mem_addr, curBlit->line_length);
+ dst += dst_pitch;
+ curBlit->mem_addr += curBlit->mem_stride;
+ }
+ }
+ }
+ srcOffset += height * srcPitch;
}
- pVia->SavedCmd = cmd;
- pVia->SavedFgColor = fg;
- pVia->SavedBgColor = bg;
+ buf = (buf) ? 0 : 1;
+ curBlit = blit + buf;
+
+ if (sync[buf] && !err) {
+ while (-EAGAIN == (err =
+ drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC,
+ &curBlit->sync, sizeof(curBlit->sync)))) ;
+ if (!err && useBounceBuffer) {
+ for (i = 0; i < curBlit->num_lines; ++i) {
+ memcpy(dst, curBlit->mem_addr, curBlit->line_length);
+ dst += dst_pitch;
+ curBlit->mem_addr += curBlit->mem_stride;
+ }
+ }
+ }
- /* Disable Transparent Bitblt */
- CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0);
+ return (err == 0);
}
+/*
+ * Upload to framebuffer memory using memcpy to AGP pipelined with a
+ * 3D engine texture operation from AGP to framebuffer. The AGP buffers (2)
+ * should be kept rather small for optimal pipelining.
+ */
-static void
-VIASubsequentScreenToScreenColorExpand(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int srcx,
- int srcy,
- int offset)
+static Bool
+viaExaTexUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
- CARD32 srcBase,dstBase;
+ unsigned dstPitch = exaGetPixmapPitch(pDst);
+ unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3;
+ unsigned dstOffset;
+ CARD32 texWidth, texHeight, texPitch;
+ int format;
+ char *dst;
+ int i, sync[2], yOffs, bufH, bufOffs, height;
+ Bool buf;
+ Via3DState *v3d = &pVia->v3d;
- srcBase = srcy*pVia->Bpl + srcx*pVia->Bpp;
- dstBase = y*pVia->Bpl + x*pVia->Bpp;
+ if (!w || !h)
+ return TRUE;
+
+
+ if (wBytes * h < VIA_MIN_TEX_UPLOAD) {
+ dstOffset = x * pDst->drawable.bitsPerPixel;
+ if (dstOffset & 3)
+ return FALSE;
+ dst =
+ (char *)pVia->FBBase + (exaGetPixmapOffset(pDst) + y * dstPitch +
+ (dstOffset >> 3));
+ exaWaitSync(pScrn->pScreen);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ dst += dstPitch;
+ src += src_pitch;
+ }
+ return TRUE;
+ }
- x = (dstBase & 31);
- srcx = srcBase & 7;
+ if (!pVia->texAddr)
+ return FALSE;
- switch (pScrn->bitsPerPixel) {
- case 16:
- x >>= 1;
- break;
+ switch (pDst->drawable.bitsPerPixel) {
case 32:
- x >>= 2;
+ format = PICT_a8r8g8b8;
+ break;
+ case 16:
+ format = PICT_r5g6b5;
break;
default:
- break;
+ return FALSE;
}
- srcy = 0;
- y = 0;
+ dstOffset = exaGetPixmapOffset(pDst);
+ viaOrder(wBytes, &texPitch);
+ if (texPitch < 3)
+ texPitch = 3;
+ height = VIA_AGP_UPL_SIZE >> texPitch;
+ if (height > 1024)
+ height = 1024;
+ texPitch = 1 << texPitch;
+ viaOrder(w, &texWidth);
+ texWidth = 1 << texWidth;
+
+ texHeight = height << 1;
+ bufOffs = texPitch * height;
+
+ v3d->setDestination(v3d, dstOffset, dstPitch, format);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00);
+ v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE);
+ if (!v3d->setTexture(v3d, 0, pVia->texOffset + pVia->agpAddr, texPitch,
+ texWidth, texHeight, format, via_single, via_single, via_src,
+ TRUE))
+ return FALSE;
+
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+ v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width,
+ pDst->drawable.height);
+
+ buf = 1;
+ yOffs = 0;
+ sync[0] = -1;
+ sync[1] = -1;
+
+ while (h) {
+ buf = (buf) ? 0 : 1;
+ bufH = (h > height) ? height : h;
+ dst = pVia->texAddr + ((buf) ? bufOffs : 0);
+
+ if (sync[buf] >= 0)
+ viaAccelWaitMarker(pScrn->pScreen, sync[buf]);
+
+ for (i = 0; i < bufH; ++i) {
+ memcpy(dst, src, wBytes);
+ dst += texPitch;
+ src += src_pitch;
+ }
+
+ v3d->emitQuad(v3d, &pVia->cb, x, y + yOffs, 0, (buf) ? height : 0, 0,
+ 0, w, bufH);
+
+ sync[buf] = viaAccelMarkSync(pScrn->pScreen);
+
+ h -= bufH;
+ yOffs += bufH;
+ }
- /* Set Src and Dst base address and pitch, pitch is qword */
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0);
- CBUFFER(buf,VIA_REG_SRCBASE, (srcBase & ~7) >> 3);
- CBUFFER(buf,VIA_REG_DSTBASE, (dstBase & ~31) >> 3);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
- CBUFFER(buf,VIA_REG_SRCPOS, (srcx << 6) | offset);
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor);
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
+ if (sync[buf] >= 0)
+ viaAccelWaitMarker(pScrn->pScreen, sync[buf]);
- dispatchCBufferAGP(pVia, buf);
+ return TRUE;
}
+/*
+ * I'm not sure PCI DMA upload is necessary. Seems buggy for widths below 65, and I'd guess that in
+ * most situations, CPU direct writes are faster. Use DMA only when alignments match. At least
+ * it saves some CPU cycles.
+ */
+
+static Bool
+viaExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ drm_via_dmablit_t blit;
+ unsigned dstPitch = exaGetPixmapPitch(pDst);
+ unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3;
+ unsigned dstOffset;
+ char *dst;
+ int err;
+
+ dstOffset = x * pDst->drawable.bitsPerPixel;
+ if (dstOffset & 3)
+ return FALSE;
+ dstOffset = exaGetPixmapOffset(pDst) + y * dstPitch + (dstOffset >> 3);
+
+ if (wBytes * h < VIA_MIN_UPLOAD || wBytes < 65) {
+ dst = (char *)pVia->FBBase + dstOffset;
+
+ exaWaitSync(pScrn->pScreen);
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ dst += dstPitch;
+ src += src_pitch;
+ }
+ return TRUE;
+ }
+
+ if (!pVia->directRenderingEnabled)
+ return FALSE;
+
+ if (((unsigned long)src & 15) || (src_pitch & 15))
+ return FALSE;
+
+ if ((dstPitch & 3) || (dstOffset & 3))
+ return FALSE;
+
+ blit.line_length = wBytes;
+ blit.num_lines = h;
+ blit.fb_addr = dstOffset;
+ blit.fb_stride = dstPitch;
+ blit.mem_addr = (unsigned char *) src;
+ blit.mem_stride = src_pitch;
+ blit.to_fb = 1;
+#if (VIA_DRM_VERSION >= ((2 << 16) | 9))
+ blit.flags = 0;
#endif
-static void
-VIASetupForImageWrite(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned planemask,
- int trans_color,
- int bpp,
- int depth)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
+ exaWaitSync(pScrn->pScreen);
+ while (-EAGAIN == (err =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit,
+ sizeof(blit)))) ;
+ if (err < 0)
+ return FALSE;
- /* We don't record bpp and depth because we assume bpp is equal to
- bpp of screen. Is this assume correct ? */
+ while (-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC,
+ &blit.sync, sizeof(blit.sync)))) ;
+ return (err == 0);
+}
- cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | (XAAGetCopyROP(rop) << 24);
+#endif
- pVia->SavedCmd = cmd;
+static Bool
+viaExaUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst)
+{
- CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- if (trans_color != -1) {
- /* Transparent Bitblt */
- CBUFFER(buf,VIA_REG_SRCCOLORKEY, trans_color);
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x4000);
+ ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ char *src, *dst;
+ unsigned w, wBytes, srcPitch, h;
+ CARD32 dstPitch;
+
+ if (!pVia->scratchAddr)
+ return FALSE;
+
+ *pDst = *pSrc;
+ w = pSrc->drawable.width;
+ h = pSrc->drawable.height;
+ wBytes = (w * pSrc->drawable.bitsPerPixel + 7) >> 3;
+
+ viaOrder(wBytes, &dstPitch);
+ dstPitch = 1 << dstPitch;
+ if (dstPitch < 8)
+ dstPitch = 8;
+ if (dstPitch * h > VIA_SCRATCH_SIZE) {
+ ErrorF("EXA UploadToScratch Failed\n");
+ return FALSE;
}
- else {
- /* Disable Transparent Bitblt */
- CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0);
+
+ pDst->devKind = dstPitch;
+ pDst->devPrivate.ptr = dst = pVia->scratchAddr;
+ src = pSrc->devPrivate.ptr;
+ srcPitch = exaGetPixmapPitch(pSrc);
+
+ /*
+ * Copying to AGP needs not be HW accelerated.
+ * and if scratch is in FB, we are without DRI and hw accel.
+ */
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ dst += dstPitch;
+ src += srcPitch;
}
-}
+ return TRUE;
+}
-static void
-VIASubsequentImageWriteRect(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int w,
- int h,
- int skipleft)
+static Bool
+viaExaCheckComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture)
{
- VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
- if (skipleft) {
- VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1));
+ ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Via3DState *v3d = &pVia->v3d;
+
+ /*
+ * Reject small composites early. They are done much faster in software.
+ */
+
+ if (!pSrcPicture->repeat &&
+ pSrcPicture->pDrawable->width *
+ pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE)
+ return FALSE;
+
+ if (pMaskPicture &&
+ !pMaskPicture->repeat &&
+ pMaskPicture->pDrawable->width *
+ pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE)
+ return FALSE;
+
+ if (pMaskPicture && pMaskPicture->componentAlpha)
+ return FALSE;
+
+ if (!v3d->opSupported(op)) {
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Operator not supported\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
}
- /* Set Src and Dst base address and pitch, pitch is qword */
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ /*
+ * FIXME: A8 destination formats are currently not supported and does
+ * not seem supported by the hardware, althought there are some left-over
+ * register settings apparent in the via_3d_reg.h file. We need to fix this
+ * (if important), by using component ARGB8888 operations with bitmask.
+ */
- CBUFFER(buf,VIA_REG_SRCPOS, 0);
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd);
- dispatchCBuffer(pVia, buf);
+ if (!v3d->dstSupported(pDstPicture->format)) {
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Destination format not supported:\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+ }
-}
+ if (v3d->texSupported(pSrcPicture->format)) {
+ if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 ||
+ !v3d->texSupported(pMaskPicture->format))) {
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Mask format not supported:\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+ }
+ return TRUE;
+ }
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Src format not supported:\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+}
-/* Setup for XAA solid lines. */
-static void
-VIASetupForSolidLine(
- ScrnInfoPtr pScrn,
- int color,
- int rop,
- unsigned int planemask)
+static Bool
+viaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset)
{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
-
- CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- /* we move VIA_GEC_LINE from here to the place firing command */
- cmd = VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24);
+#ifdef XF86DRI
+ unsigned long offs;
- pVia->SavedCmd = cmd;
- pVia->SavedFgColor = color;
+ if (pVia->directRenderingEnabled && !pVia->IsPCI) {
+ offs = (unsigned long)pPix->devPrivate.ptr -
+ (unsigned long)pVia->agpMappedAddr;
- /* set solid line pattern */
- CBUFFER(buf,VIA_REG_MONOPAT0, 0xFF);
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
+ if ((offs - pVia->scratchOffset) < VIA_SCRATCH_SIZE) {
+ *offset = offs + pVia->agpAddr;
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+static Bool
+viaIsOffscreen(VIAPtr pVia, PixmapPtr pPix)
+{
+ return ((unsigned long)pPix->devPrivate.ptr -
+ (unsigned long)pVia->FBBase) < pVia->videoRambytes;
}
+static Bool
+viaExaPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+ CARD32 height, width;
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Via3DState *v3d = &pVia->v3d;
+ int curTex = 0;
+ ViaTexBlendingModes srcMode;
+ Bool isAGP;
+ unsigned long offset;
-static void
-VIASubsequentSolidTwoPointLine(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int flags)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int dx, dy, cmd, tmp, error = 1;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
+ v3d->setDestination(v3d, exaGetPixmapOffset(pDst),
+ exaGetPixmapPitch(pDst), pDstPicture->format);
+ v3d->setCompositeOperator(v3d, op);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF);
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- cmd = pVia->SavedCmd | VIA_GEC_LINE;
+ viaOrder(pSrc->drawable.width, &width);
+ viaOrder(pSrc->drawable.height, &height);
- dx = x2 - x1;
- if (dx < 0) {
- dx = -dx;
- cmd |= VIA_GEC_DECX; /* line will be drawn from right */
- error = 0;
+ /*
+ * For One-pixel repeat mask pictures we avoid using multitexturing by
+ * modifying the src's texture blending equation and feed the pixel
+ * value as a constant alpha for the src's texture. Multitexturing on the
+ * unichromes seem somewhat slow, so this speeds up translucent windows.
+ */
+
+ srcMode = via_src;
+ pVia->maskP = NULL;
+ if (pMaskPicture &&
+ (pMaskPicture->pDrawable->height == 1) &&
+ (pMaskPicture->pDrawable->width == 1) &&
+ pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) {
+ pVia->maskP = pMask->devPrivate.ptr;
+ pVia->maskFormat = pMaskPicture->format;
+ pVia->componentAlpha = pMaskPicture->componentAlpha;
+ srcMode =
+ (pMaskPicture->
+ componentAlpha) ? via_src_onepix_comp_mask : via_src_onepix_mask;
}
- dy = y2 - y1;
- if (dy < 0) {
- dy = -dy;
- cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */
+ /*
+ * One-Pixel repeat src pictures go as solid color instead of textures.
+ * Speeds up window shadows.
+ */
+
+ pVia->srcP = NULL;
+ if (pSrcPicture &&
+ (pSrcPicture->pDrawable->height == 1) &&
+ (pSrcPicture->pDrawable->width == 1) &&
+ pSrcPicture->repeat && viaExpandablePixel(pSrcPicture->format)) {
+ pVia->srcP = pSrc->devPrivate.ptr;
+ pVia->srcFormat = pSrcPicture->format;
}
- if (dy > dx) {
- tmp = dy;
- dy = dx;
- dx = tmp; /* Swap 'dx' and 'dy' */
- cmd |= VIA_GEC_Y_MAJOR; /* Y major line */
+ /*
+ * Exa should be smart enough to eliminate this IN operation.
+ */
+
+ if (pVia->srcP && pVia->maskP) {
+ ErrorF
+ ("Bad one-pixel IN composite operation. EXA needs to be smarter.\n");
+ return FALSE;
}
- if (flags & OMIT_LAST) {
- cmd |= VIA_GEC_LASTPIXEL_OFF;
+ if (!pVia->srcP) {
+ offset = exaGetPixmapOffset(pSrc);
+ isAGP = viaIsAGP(pVia, pSrc, &offset);
+ if (!isAGP && !viaIsOffscreen(pVia, pSrc))
+ return FALSE;
+ if (!v3d->setTexture(v3d, curTex++, offset,
+ exaGetPixmapPitch(pSrc), 1 << width, 1 << height,
+ pSrcPicture->format, via_repeat, via_repeat,
+ srcMode, isAGP))
+ return FALSE;
}
- /* Set Src and Dst base address and pitch, pitch is qword */
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ if (pMaskPicture && !pVia->maskP) {
+ offset = exaGetPixmapOffset(pMask);
+ isAGP = viaIsAGP(pVia, pMask, &offset);
+ if (!isAGP && !viaIsOffscreen(pVia, pMask))
+ return FALSE;
+ viaOrder(pMask->drawable.width, &width);
+ viaOrder(pMask->drawable.height, &height);
+ if (!v3d->setTexture(v3d, curTex++, offset,
+ exaGetPixmapPitch(pMask), 1 << width, 1 << height,
+ pMaskPicture->format, via_repeat, via_repeat,
+ (pMaskPicture->componentAlpha) ? via_comp_mask : via_mask,
+ isAGP))
+ return FALSE;
+ }
- /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */
- /* K1 = 2*dmin K2 = 2*(dmin - dmax) */
- /* Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax)) */
- CBUFFER(buf,VIA_REG_LINE_K1K2, ((((dy << 1) & 0x3fff) << 16)|
- (((dy - dx) << 1) & 0x3fff)));
- CBUFFER(buf,VIA_REG_LINE_XY, ((y1 << 16) | x1));
- CBUFFER(buf,VIA_REG_DIMENSION, dx);
- CBUFFER(buf,VIA_REG_LINE_ERROR, (((dy << 1) - dx - error) & 0x3fff));
- CBUFFER(buf,VIA_REG_GECMD, cmd);
- dispatchCBufferAGP(pVia, buf);
+ v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE);
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+ v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width,
+ pDst->drawable.height);
+ return TRUE;
}
-
-/* Subsequent XAA solid horizontal and vertical lines */
static void
-VIASubsequentSolidHorVertLine(
- ScrnInfoPtr pScrn,
- int x,
- int y,
- int len,
- int dir)
+viaExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int width, int height)
{
- VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
-
- /* Set Src and Dst base address and pitch, pitch is qword */
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Via3DState *v3d = &pVia->v3d;
+ CARD32 col;
- if (dir == DEGREES_0) {
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, (len - 1));
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT);
+ if (pVia->maskP) {
+ viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col);
+ v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col);
}
- else {
- CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x));
- CBUFFER(buf,VIA_REG_DIMENSION, ((len - 1) << 16));
- CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT);
+ if (pVia->srcP) {
+ viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24);
+ srcX = maskX;
+ srcY = maskY;
}
- dispatchCBufferAGP(pVia, buf);
+
+ if (pVia->maskP || pVia->srcP)
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+
+ v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY, width,
+ height);
}
-static void
-VIASetupForDashedLine(
- ScrnInfoPtr pScrn,
- int fg,
- int bg,
- int rop,
- unsigned int planemask,
- int length,
- unsigned char *pattern)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int cmd;
- CARD32 pat = *(CARD32 *)pattern;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
+/*
+ * Init EXA. Alignments are 2D engine constraints.
+ */
- cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24);
+static ExaDriverPtr
+viaInitExa(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ExaDriverPtr pExa = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1);
+
+ if (!pExa)
+ return NULL;
+
+ pExa->card.memoryBase = pVia->FBBase;
+ pExa->card.memorySize = pVia->FBFreeEnd;
+ pExa->card.offScreenBase = pScrn->virtualY * pVia->Bpl;
+ pExa->card.pixmapOffsetAlign = 32;
+ pExa->card.pixmapPitchAlign = 16;
+ pExa->card.flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT;
+ pExa->card.maxX = 2047;
+ pExa->card.maxY = 2047;
+
+ pExa->accel.WaitMarker = viaAccelWaitMarker;
+ pExa->accel.MarkSync = viaAccelMarkSync;
+ pExa->accel.PrepareSolid = viaExaPrepareSolid;
+ pExa->accel.Solid = viaExaSolid;
+ pExa->accel.DoneSolid = viaExaDoneSolidCopy;
+ pExa->accel.PrepareCopy = viaExaPrepareCopy;
+ pExa->accel.Copy = viaExaCopy;
+ pExa->accel.DoneCopy = viaExaDoneSolidCopy;
- if (bg == -1) {
- /* transparent mono pattern */
- cmd |= VIA_GEC_MPAT_TRANS;
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+#ifdef linux
+ if ((pVia->drmVerMajor > 2) ||
+ ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) {
+ if (pVia->Chipset != VIA_K8M800)
+ pExa->accel.UploadToScreen = viaExaUploadToScreen;
+ pExa->accel.DownloadFromScreen = viaExaDownloadFromScreen;
+ }
+#endif
+ if (pVia->Chipset == VIA_K8M800)
+ pExa->accel.UploadToScreen = viaExaTexUploadToScreen;
}
+#endif
- pVia->SavedCmd = cmd;
- pVia->SavedFgColor = fg;
- pVia->SavedBgColor = bg;
+ pExa->accel.UploadToScratch = viaExaUploadToScratch;
- switch (length) {
- case 2: pat |= pat << 2; /* fall through */
- case 4: pat |= pat << 4; /* fall through */
- case 8: pat |= pat << 8; /* fall through */
- case 16: pat |= pat << 16;
+ if (!pVia->noComposite) {
+ pExa->accel.CheckComposite = viaExaCheckComposite;
+ pExa->accel.PrepareComposite = viaExaPrepareComposite;
+ pExa->accel.Composite = viaExaComposite;
+ pExa->accel.DoneComposite = viaExaDoneSolidCopy;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[EXA] Disabling EXA accelerated composite.\n");
}
- pVia->SavedPattern0 = pat;
- CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor);
- CBUFFER(buf,VIA_REG_MONOPAT0, pVia->SavedPattern0);
+ if (!exaDriverInit(pScreen, pExa)) {
+ xfree(pExa);
+ return NULL;
+ }
+ viaInit3DState(&pVia->v3d);
+ return pExa;
}
+#endif /* VIA_HAVE_EXA */
-static void
-VIASubsequentDashedTwoPointLine(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2,
- int flags,
- int phase)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- int dx, dy, cmd, tmp, error = 1;
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
+/*
+ * Acceleration init function. Sets up offscreen memory disposition, initializes engines
+ * and acceleration method.
+ */
- COND_CLEAR_CBUFFER( buf, pVia);
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
- CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor);
- cmd = pVia->SavedCmd;
+Bool
+viaInitAccel(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ BoxRec AvailFBArea;
+ int maxY;
- dx = x2 - x1;
- if (dx < 0) {
- dx = -dx;
- cmd |= VIA_GEC_DECX; /* line will be drawn from right */
- error = 0;
+ pVia->VQStart = 0;
+ if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) &&
+ pVia->VQEnable) {
+ pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE;
+ pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1;
+ pVia->FBFreeEnd -= VIA_VQ_SIZE;
}
- dy = y2 - y1;
- if (dy < 0) {
- dy = -dy;
- cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */
+ viaInitialize2DEngine(pScrn);
+
+ if (pVia->hwcursor) {
+ pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
+ pVia->CursorStart = pVia->FBFreeEnd;
}
- if (dy > dx) {
- tmp = dy;
- dy = dx;
- dx = tmp; /* Swap 'dx' and 'dy' */
- cmd |= VIA_GEC_Y_MAJOR; /* Y major line */
+ /*
+ * Sync marker space.
+ */
+
+ pVia->FBFreeEnd -= 32;
+ pVia->markerOffset = (pVia->FBFreeEnd + 31) & ~31;
+ pVia->markerBuf = (CARD32 *) ((char *)pVia->FBBase + pVia->markerOffset);
+ *pVia->markerBuf = 0;
+ pVia->curMarker = 0;
+ pVia->lastMarkerRead = 0;
+
+#ifdef VIA_HAVE_EXA
+#ifdef XF86DRI
+ pVia->texAddr = NULL;
+ pVia->dBounce = NULL;
+ pVia->scratchAddr = NULL;
+#endif
+ if (pVia->useEXA) {
+ pVia->exaDriverPtr = viaInitExa(pScreen);
+ if (!pVia->exaDriverPtr) {
+
+ /*
+ * Docs recommend turning off also Xv here, but we handle this
+ * case with the old linear offscreen FB manager through
+ * VIAInitLinear.
+ */
+
+ pVia->NoAccel = TRUE;
+ return FALSE;
+ }
+
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2;
+ if (pVia->driSize > (16 * 1024 * 1024))
+ pVia->driSize = 16 * 1024 * 1024;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[EXA] Enabled EXA acceleration.\n");
+ return TRUE;
}
+#endif
- if (flags & OMIT_LAST) {
- cmd |= VIA_GEC_LASTPIXEL_OFF;
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+
+ /*
+ * Memory distribution for XAA is tricky. We'd like to make the
+ * pixmap cache no larger than 3 x visible screen size, otherwise
+ * XAA may get slow for some undetermined reason.
+ */
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2;
+ maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl);
+ } else
+#endif
+ {
+ maxY = pVia->FBFreeEnd / pVia->Bpl;
}
+ if (maxY > 4 * pScrn->virtualY)
+ maxY = 4 * pScrn->virtualY;
+
+ pVia->FBFreeStart = (maxY + 1) * pVia->Bpl;
+
+ AvailFBArea.y2 = maxY;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ VIAInitLinear(pScreen);
+
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl);
- /* Set Src and Dst base address and pitch, pitch is qword */
- CBUFFER(buf,VIA_REG_SRCBASE, 0x0);
- CBUFFER(buf,VIA_REG_DSTBASE, 0x0);
- CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE |
- ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) |
- (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d lines for offscreen memory.\n",
+ AvailFBArea.y2 - pScrn->virtualY));
- /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */
- /* K1 = 2*dmin K2 = 2*(dmin - dmax) */
- /* Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax)) */
- CBUFFER(buf,VIA_REG_LINE_K1K2, ((((dy << 1) & 0x3fff) << 16)|
- (((dy - dx) << 1) & 0x3fff)));
- CBUFFER(buf,VIA_REG_LINE_XY, ((y1 << 16) | x1));
- CBUFFER(buf,VIA_REG_DIMENSION, dx);
- CBUFFER(buf,VIA_REG_LINE_ERROR, (((dy << 1) - dx - error) & 0x3fff) | 0xFF0000);
- CBUFFER(buf,VIA_REG_GECMD, cmd);
- dispatchCBufferAGP(pVia, buf);
+ return viaInitXAA(pScreen);
}
+/*
+ * Free used acceleration resorces.
+ */
-static void
-VIASetClippingRectangle(
- ScrnInfoPtr pScrn,
- int x1,
- int y1,
- int x2,
- int y2)
+void
+viaExitAccel(ScreenPtr pScreen)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- ViaCBuffer *buf = &pVia->cBuf;
- ViaTwodContext *tdc = &pVia->td;
-
- COND_CLEAR_CBUFFER( buf, pVia);
- pVia->justSetup = 0;
- CBUFFER(buf,VIA_REG_GEMODE, tdc->mode);
-#ifdef DEBUG_EXTRA
- ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 );
-#endif
- CBUFFER(buf,VIA_REG_CLIPTL, ((y1 << 16) | x1));
- CBUFFER(buf,VIA_REG_CLIPBR, ((y2 << 16) | x2));
- pVia->SavedCmd |= VIA_GEC_CLIP_ENABLE;
- dispatchCBufferAGP(pVia, buf);
+ viaAccelSync(pScrn);
+ viaTearDownCBuffer(&pVia->cb);
+#ifdef VIA_HAVE_EXA
+ if (pVia->useEXA) {
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ if (pVia->texAddr) {
+ drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM,
+ &pVia->texAGPBuffer, sizeof(drm_via_mem_t));
+ pVia->texAddr = NULL;
+ }
+ if (pVia->scratchAddr && !pVia->IsPCI &&
+ ((unsigned long)pVia->scratchAddr -
+ (unsigned long)pVia->agpMappedAddr == pVia->scratchOffset)) {
+ drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM,
+ &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t));
+ pVia->scratchAddr = NULL;
+ }
+ }
+ if (pVia->dBounce)
+ xfree(pVia->dBounce);
+#endif
+ if (pVia->scratchAddr) {
+ exaOffscreenFree(pScreen, pVia->scratchFBBuffer);
+ pVia->scratchAddr = NULL;
+ }
+ if (pVia->exaDriverPtr) {
+ exaDriverFini(pScreen);
+ }
+ xfree(pVia->exaDriverPtr);
+ pVia->exaDriverPtr = NULL;
+ return;
+ }
+#endif
+ if (pVia->AccelInfoRec) {
+ XAADestroyInfoRec(pVia->AccelInfoRec);
+ pVia->AccelInfoRec = NULL;
+ }
}
-static void VIADisableClipping(ScrnInfoPtr pScrn)
+/*
+ * Allocate command buffer and
+ * buffers for accelerated upload, download and
+ * the EXA scratch area. The Scratch area resides primarily in
+ * AGP memory but reverts to FB if AGP is not available.
+ */
+
+void
+viaFinishInitAccel(ScreenPtr pScreen)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
-#ifdef DEBUG_EXTRA
- ErrorF("Kill ClipRect\n");
+#ifdef VIA_HAVE_EXA
+#ifdef XF86DRI
+ int size, ret;
+
+ if (pVia->directRenderingEnabled && pVia->useEXA) {
+
+ pVia->dBounce = xcalloc(VIA_DMA_DL_SIZE * 2, 1);
+
+ if (!pVia->IsPCI) {
+
+ /*
+ * Allocate upload and scratch space.
+ */
+
+ if (pVia->exaDriverPtr->accel.UploadToScreen ==
+ viaExaTexUploadToScreen) {
+
+ size = VIA_AGP_UPL_SIZE * 2 + 32;
+ pVia->texAGPBuffer.context = 1;
+ pVia->texAGPBuffer.size = size;
+ pVia->texAGPBuffer.type = VIA_MEM_AGP;
+ ret =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM,
+ &pVia->texAGPBuffer, sizeof(drm_via_mem_t));
+
+ if (ret || size != pVia->texAGPBuffer.size) {
+ pVia->texAGPBuffer.size = 0;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated %u kiB of AGP memory for system to frame-buffer transfer.\n",
+ size / 1024);
+ pVia->texOffset = (pVia->texAGPBuffer.offset + 31) & ~31;
+ pVia->texAddr =
+ (char *)pVia->agpMappedAddr + pVia->texOffset;
+ }
+
+ }
+
+ size = VIA_SCRATCH_SIZE + 32;
+ pVia->scratchAGPBuffer.context = 1;
+ pVia->scratchAGPBuffer.size = size;
+ pVia->scratchAGPBuffer.type = VIA_MEM_AGP;
+ ret =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM,
+ &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t));
+ if (ret || size != pVia->scratchAGPBuffer.size) {
+ pVia->scratchAGPBuffer.size = 0;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated %u kiB of AGP memory for EXA scratch area.\n",
+ size / 1024);
+ pVia->scratchOffset =
+ (pVia->scratchAGPBuffer.offset + 31) & ~31;
+ pVia->scratchAddr =
+ (char *)pVia->agpMappedAddr + pVia->scratchOffset;
+ }
+
+ }
+ }
#endif
+ if (!pVia->scratchAddr && pVia->useEXA) {
+
+ pVia->scratchFBBuffer =
+ exaOffscreenAlloc(pScreen, VIA_SCRATCH_SIZE, 32, TRUE, NULL,
+ NULL);
+ if (pVia->scratchFBBuffer) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated %u kiB of framebuffer memory for EXA scratch area.\n",
+ VIA_SCRATCH_SIZE / 1024);
+ pVia->scratchOffset = pVia->scratchFBBuffer->offset;
+ pVia->scratchAddr = (char *)pVia->FBBase + pVia->scratchOffset;
+ }
- pVia->SavedCmd &= ~VIA_GEC_CLIP_ENABLE;
+ }
+#endif
+ if (Success != viaSetupCBuffer(pScrn, &pVia->cb, 0)) {
+ pVia->NoAccel = TRUE;
+ viaExitAccel(pScreen);
+ return;
+ }
}
/*
- *
+ * DGA accelerated functions go here and let them be independent of acceleration
+ * method.
*/
-void
-ViaVQDisable(ScrnInfoPtr pScrn)
+
+void
+viaAccelBlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
{
VIAPtr pVia = VIAPTR(pScrn);
- VIASETREG(VIA_REG_TRANSET, 0x00FE0000);
- VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
+ ViaTwodContext *tdc = &pVia->td;
+ unsigned dstOffset = pScrn->fbOffset + dsty * pVia->Bpl;
+ unsigned srcOffset = pScrn->fbOffset + srcy * pVia->Bpl;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ if (!pVia->NoAccel) {
+
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+ CARD32 cmd = VIA_GEC_BLT | VIAACCELCOPYROP(GXcopy);
+
+ if (xdir < 0)
+ cmd |= VIA_GEC_DECX;
+ if (ydir < 0)
+ cmd |= VIA_GEC_DECY;
+
+ viaAccelSetMode(pScrn->bitsPerPixel, tdc);
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+ viaAccelCopyHelper(cb, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset,
+ tdc->mode, pVia->Bpl, pVia->Bpl, cmd);
+ pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
+ ADVANCE_RING;
+ }
+}
+
+void
+viaAccelFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned long color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ unsigned dstBase = pScrn->fbOffset + y * pVia->Bpl;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT |
+ VIAACCELPATTERNROP(GXcopy);
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ if (!pVia->NoAccel) {
+ viaAccelSetMode(pScrn->bitsPerPixel, tdc);
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+ viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode,
+ pVia->Bpl, color, cmd);
+ pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
+ ADVANCE_RING;
+ }
+}
+
+void
+viaAccelSyncMarker(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ viaAccelWaitMarker(pScrn->pScreen, pVia->accelMarker);
}
diff --git a/src/via_cursor.c b/src/via_cursor.c
index 29c3f4b..1ab1133 100644
--- a/src/via_cursor.c
+++ b/src/via_cursor.c
@@ -115,7 +115,7 @@ VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char* src)
VIAPtr pVia = VIAPTR(pScrn);
CARD32 dwCursorMode;
- VIAAccelSync(pScrn);
+ viaAccelSync(pScrn);
dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
diff --git a/src/via_dga.c b/src/via_dga.c
index 2331915..3c13674 100644
--- a/src/via_dga.c
+++ b/src/via_dga.c
@@ -36,9 +36,6 @@ static Bool VIADGAOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
static Bool VIADGASetMode(ScrnInfoPtr, DGAModePtr);
static int VIADGAGetViewport(ScrnInfoPtr);
static void VIADGASetViewport(ScrnInfoPtr, int, int, int);
-static void VIADGAFillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
-static void VIADGABlitRect(ScrnInfoPtr, int, int, int, int, int, int);
-
static
DGAFunctionRec VIADGAFuncs = {
@@ -47,9 +44,9 @@ DGAFunctionRec VIADGAFuncs = {
VIADGASetMode,
VIADGASetViewport,
VIADGAGetViewport,
- VIAAccelSync,
- VIADGAFillRect,
- VIADGABlitRect,
+ viaAccelSyncMarker,
+ viaAccelFillRect,
+ viaAccelBlitRect,
NULL /* BlitTransRect */
};
@@ -303,39 +300,6 @@ VIADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
pVia->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */
}
-
-static void
-VIADGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color)
-{
- VIAPtr pVia = VIAPTR(pScrn);
-
- if (pVia->AccelInfoRec) {
- (*pVia->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
- (*pVia->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
- SET_SYNC_FLAG(pVia->AccelInfoRec);
- }
-}
-
-
-static void
-VIADGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
- int dstx, int dsty)
-{
- VIAPtr pVia = VIAPTR(pScrn);
-
- if (pVia->AccelInfoRec) {
- int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
- int ydir = (srcy < dsty) ? -1 : 1;
-
- (*pVia->AccelInfoRec->SetupForScreenToScreenCopy)(
- pScrn, xdir, ydir, GXcopy, ~0, -1);
- (*pVia->AccelInfoRec->SubsequentScreenToScreenCopy)(
- pScrn, srcx, srcy, dstx, dsty, w, h);
- SET_SYNC_FLAG(pVia->AccelInfoRec);
- }
-}
-
-
static Bool
VIADGAOpenFramebuffer(
ScrnInfoPtr pScrn,
diff --git a/src/via_dri.c b/src/via_dri.c
index 7f64d21..2caf4d0 100644
--- a/src/via_dri.c
+++ b/src/via_dri.c
@@ -160,13 +160,8 @@ VIADRIRingBufferInit(ScrnInfoPtr pScrn)
if (pVia->agpEnable) {
drm_via_dma_init_t ringBufInit;
- drmVersionPtr drmVer;
- if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {
- return FALSE;
- }
-
- if (((drmVer->version_major <= 1) && (drmVer->version_minor <= 3))) {
+ if (((pVia->drmVerMajor <= 1) && (pVia->drmVerMinor <= 3))) {
return FALSE;
}
@@ -333,11 +328,40 @@ static Bool VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia)
}
static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia)
{
- int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart;
- int FBOffset = pVia->FBFreeStart;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int FBSize = pVia->driSize;
+ int FBOffset;
VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ if (FBSize < pVia->Bpl) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] No DRM framebuffer heap available.\n");
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Please increase the frame buffer\n");
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] memory area in BIOS. Disabling DRI.\n");
+ return FALSE;
+ }
+ if (FBSize < 3*(pScrn->virtualY * pVia->Bpl)) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] The DRM Heap and Pixmap cache memory could be too small\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] for optimal performance. Please increase the frame buffer\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] memory area in BIOS.\n");
+ }
+
+ pVia->driOffScreenMem.pool = 0;
+ if (Success != VIAAllocLinear(&pVia->driOffScreenMem, pScrn, FBSize)) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to allocate offscreen frame buffer area\n");
+ return FALSE;
+ }
+
+ FBOffset = pVia->driOffScreenMem.base;
+
pVIADRI->fbOffset = FBOffset;
- pVIADRI->fbSize = pVia->videoRambytes;
+ pVIADRI->fbSize = FBSize;
{
drm_via_fb_t fb;
@@ -351,9 +375,7 @@ static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia)
return FALSE;
} else {
xf86DrvMsg(pScreen->myNum, X_INFO,
- "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "
- "FBSize= 0x%08x\n",
- pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);
+ "[drm] Using %d bytes for DRM memory heap.\n", FBSize);
return TRUE;
}
}
@@ -594,6 +616,7 @@ Bool VIADRIScreenInit(ScreenPtr pScreen)
VIAPtr pVia = VIAPTR(pScrn);
DRIInfoPtr pDRIInfo;
VIADRIPtr pVIADRI;
+ drmVersionPtr drmVer;
/* if symbols or version check fails, we still want this to be NULL */
pVia->pDRIInfo = NULL;
@@ -697,6 +720,15 @@ Bool VIADRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
+ if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {
+ VIADRICloseScreen(pScreen);
+ return FALSE;
+ }
+ pVia->drmVerMajor = drmVer->version_major;
+ pVia->drmVerMinor = drmVer->version_minor;
+ pVia->drmVerPL = drmVer->version_patchlevel;
+ drmFreeVersion(drmVer);
+
if (!(VIAInitVisualConfigs(pScreen))) {
VIADRICloseScreen(pScreen);
@@ -739,8 +771,8 @@ VIADRICloseScreen(ScreenPtr pScreen)
drmAgpRelease(pVia->drmFD);
}
-
DRICloseScreen(pScreen);
+ VIAFreeLinear(&pVia->driOffScreenMem);
if (pVia->pDRIInfo) {
if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) {
diff --git a/src/via_driver.c b/src/via_driver.c
index 4cd5958..90bee5c 100644
--- a/src/via_driver.c
+++ b/src/via_driver.c
@@ -124,6 +124,9 @@ typedef enum {
OPTION_PCI_BURST,
OPTION_PCI_RETRY,
OPTION_NOACCEL,
+#ifdef VIA_HAVE_EXA
+ OPTION_ACCELMETHOD,
+#endif
OPTION_SWCURSOR,
OPTION_HWCURSOR,
OPTION_SHADOW_FB,
@@ -143,7 +146,8 @@ typedef enum {
OPTION_DISABLEIRQ,
OPTION_TVDEFLICKER,
OPTION_AGP_DMA,
- OPTION_2D_DMA
+ OPTION_2D_DMA,
+ OPTION_EXA_NOCOMPOSITE
} VIAOpts;
@@ -156,6 +160,9 @@ static OptionInfoRec VIAOptions[] =
#endif /* HAVE_DEBUG */
{OPTION_VBEMODES, "VBEModes", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE},
+#ifdef VIA_HAVE_EXA
+ {OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
+#endif /* VIA_HAVE_EXA */
{OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
@@ -176,6 +183,7 @@ static OptionInfoRec VIAOptions[] =
{OPTION_DISABLEIRQ, "DisableIRQ", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_AGP_DMA, "EnableAGPDMA", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_DMA, "NoAGPFor2D", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_EXA_NOCOMPOSITE, "ExaNoComposite", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -262,6 +270,20 @@ static const char *xaaSymbols[] = {
NULL
};
+#ifdef VIA_HAVE_EXA
+static const char *exaSymbols[] = {
+ "exaGetVersion",
+ "exaDriverInit",
+ "exaDriverFini",
+ "exaOffscreenAlloc",
+ "exaOffscreenFree",
+ "exaGetPixmapPitch",
+ "exaGetPixmapOffset",
+ "exaWaitSync",
+ NULL
+};
+#endif
+
static const char *shadowSymbols[] = {
"ShadowFBInit",
NULL
@@ -355,6 +377,9 @@ static pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin)
fbSymbols,
ramdacSymbols,
xaaSymbols,
+#ifdef VIA_HAVE_EXA
+ exaSymbols,
+#endif
shadowSymbols,
vbeSymbols,
i2cSymbols,
@@ -843,6 +868,35 @@ static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags)
else {
pVia->NoAccel = FALSE;
}
+#ifdef VIA_HAVE_EXA
+ if(!pVia->NoAccel) {
+ from = X_DEFAULT;
+ if((s = (char *)xf86GetOptValString(VIAOptions, OPTION_ACCELMETHOD))) {
+ if(!xf86NameCmp(s,"XAA")) {
+ from = X_CONFIG;
+ pVia->useEXA = FALSE;
+ }
+ else if(!xf86NameCmp(s,"EXA")) {
+ from = X_CONFIG;
+ pVia->useEXA = TRUE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n",
+ pVia->useEXA ? "EXA" : "XAA");
+
+ pVia->noComposite = FALSE;
+ if (pVia->useEXA) {
+ if (xf86ReturnOptValBool(VIAOptions, OPTION_EXA_NOCOMPOSITE, FALSE)) {
+ pVia->noComposite = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option: ExaNoComposite - Disable Composite acceleration for EXA\n");
+ } else {
+ pVia->noComposite = FALSE;
+ }
+ }
+
+ }
+#endif /* VIA_HAVE_EXA */
if (pVia->shadowFB && !pVia->NoAccel) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1351,7 +1405,7 @@ static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags)
NULL, /* list of line pitches */
256, /* mini line pitch */
3344, /* max line pitch */
- 16 * pScrn->bitsPerPixel, /* pitch inc (bits) */
+ 32*8, /* pitch inc (bits) */
128, /* min height */
2508, /* max height */
pScrn->display->virtualX, /* virtual width */
@@ -1398,6 +1452,13 @@ static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
xf86LoaderReqSymLists(xaaSymbols, NULL);
+#ifdef VIA_HAVE_EXA
+ if(!xf86LoadSubModule(pScrn, "exa")) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(exaSymbols, NULL);
+#endif
}
if (pVia->hwcursor) {
@@ -1475,11 +1536,7 @@ static void VIALeaveVT(int scrnIndex, int flags)
DRILock(screenInfo.screens[scrnIndex], 0);
#endif
- VIAAccelSync(pScrn);
-
-
-#ifdef XF86DRI
- if (pVia->directRenderingEnabled) {
+ viaAccelSync(pScrn);
/*
* Next line apparently helps fix 3D hang on VT switch.
@@ -1488,12 +1545,15 @@ static void VIALeaveVT(int scrnIndex, int flags)
hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+
VIADRIRingBufferCleanup(pScrn);
}
#endif
if (pVia->VQEnable)
- ViaVQDisable(pScrn);
+ viaDisableVQ(pScrn);
/* Save video status and turn off all video activities */
@@ -1875,7 +1935,8 @@ VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
vgaHWPtr hwp = VGAHWPTR(pScrn);
VIAPtr pVia = VIAPTR(pScrn);
-
+
+ pScrn->pScreen = pScreen;
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit\n"));
if (!VIAMapFB(pScrn))
@@ -1961,30 +2022,9 @@ VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, 0, 0);
if (!pVia->NoAccel) {
- VIAInitAccel(pScreen);
- } else {
- /*
- * This is needed because xf86InitFBManagerLinear in VIAInitLinear
- * needs xf86InitFBManager to have been initialized, and
- * xf86InitFBManager needs at least one line of free memory to
- * work. This is only for Xv in Noaccel part, and since Xv is in some
- * sense accelerated, it might be a better idea to disable it
- * altogether.
- */
- BoxRec AvailFBArea;
-
- AvailFBArea.x1 = 0;
- AvailFBArea.y1 = 0;
- AvailFBArea.x2 = pScrn->displayWidth;
- AvailFBArea.y2 = pScrn->virtualY + 1;
- /*
- * Update FBFreeStart also for other memory managers, since
- * we steal one line to make xf86InitFBManager work.
- */
- pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl;
- xf86InitFBManager(pScreen, &AvailFBArea);
+ viaInitAccel(pScreen);
}
-
+
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
/*xf86SetSilkenMouse(pScreen);*/
@@ -2017,11 +2057,6 @@ VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n"));
- if (!pVia->IsSecondary)
- memset(pVia->FBBase, 0x00, pVia->videoRambytes);
-
- vgaHWBlankScreen(pScrn, TRUE);
-
pVia->CloseScreen = pScreen->CloseScreen;
pScreen->SaveScreen = VIASaveScreen;
pScreen->CloseScreen = VIACloseScreen;
@@ -2030,20 +2065,61 @@ VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n"));
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n"));
+ pVia->agpDMA = FALSE;
#ifdef XF86DRI
if (pVia->directRenderingEnabled)
pVia->directRenderingEnabled = VIADRIFinishScreenInit(pScreen);
- if (pVia->directRenderingEnabled)
+ if (pVia->directRenderingEnabled) {
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n");
- else {
+ pVia->agpDMA = pVia->dma2d && pVIADRI->ringBufActive;
+ } else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n");
- VIAInitLinear(pScreen);
}
-#else
- VIAInitLinear(pScreen);
#endif
+ if (!pVia->NoAccel)
+ viaFinishInitAccel(pScreen);
+
+ if (pVia->NoAccel) {
+ memset(pVia->FBBase, 0x00, pVia->videoRambytes);
+ } else {
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ DRILock(screenInfo.screens[scrnIndex], 0);
+#endif
+ viaAccelFillRect(pScrn, pScrn->frameX0, pScrn->frameY0,
+ pScrn->displayWidth, pScrn->virtualY,
+ 0x00000000);
+ viaAccelSyncMarker(pScrn);
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+#endif
+ }
+ vgaHWBlankScreen(pScrn, TRUE);
+
+ if (pVia->NoAccel) {
+
+ /*
+ * This is only for Xv in Noaccel path, and since Xv is in some
+ * sense accelerated, it might be a better idea to disable it
+ * altogether.
+ */
+
+ BoxRec AvailFBArea;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pScrn->virtualY + 1;
+ pVia->FBFreeStart=(AvailFBArea.y2 + 1)*pVia->Bpl;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ VIAInitLinear(pScreen);
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl);
+ }
viaInitVideo(pScreen);
@@ -2097,6 +2173,7 @@ static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen)
FBStart = pVia->FBBase;
}
+ ErrorF("fbScreenInit");
return fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi,
pScrn->yDpi, displayWidth, pScrn->bitsPerPixel);
}
@@ -2123,9 +2200,9 @@ VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
/* Enable the graphics engine. */
if (!pVia->NoAccel)
- VIAInitialize2DEngine(pScrn);
+ viaInitialize2DEngine(pScrn);
-#ifdef XF86DRI
+#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
VIAInitialize3DEngine(pScrn);
#endif
@@ -2151,15 +2228,11 @@ static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen)
DRILock(screenInfo.screens[scrnIndex], 0);
#endif
/* Wait Hardware Engine idle to exit graphical mode */
- VIAAccelSync(pScrn);
+ viaAccelSync(pScrn);
-#ifdef XF86DRI
/* Fix 3D Hang after X restart */
-
- if (pVia->directRenderingEnabled)
hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
-#endif
if (!pVia->IsSecondary) {
/* Turn off all video activities */
@@ -2169,16 +2242,13 @@ static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen)
}
if (pVia->VQEnable)
- ViaVQDisable(pScrn);
+ viaDisableVQ(pScrn);
}
#ifdef XF86DRI
if (pVia->directRenderingEnabled)
VIADRICloseScreen(pScreen);
#endif
- if (pVia->AccelInfoRec) {
- XAADestroyInfoRec(pVia->AccelInfoRec);
- pVia->AccelInfoRec = NULL;
- }
+ viaExitAccel(pScreen);
if (pVia->CursorInfoRec) {
xf86DestroyCursorInfoRec(pVia->CursorInfoRec);
pVia->CursorInfoRec = NULL;
@@ -2279,7 +2349,7 @@ VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
DRILock(screenInfo.screens[scrnIndex], 0);
#endif
- VIAAccelSync(pScrn);
+ viaAccelSync(pScrn);
#ifdef XF86DRI
if (pVia->directRenderingEnabled)
@@ -2287,7 +2357,7 @@ VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
#endif
if (pVia->VQEnable)
- ViaVQDisable(pScrn);
+ viaDisableVQ(pScrn);
if (pVia->pVbe)
ret = ViaVbeSetMode(pScrn, mode);
@@ -2355,7 +2425,7 @@ static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags)
return;
}
-#ifdef XF86DRI
+#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
void
VIAInitialize3DEngine(ScrnInfoPtr pScrn)
{
diff --git a/src/via_driver.h b/src/via_driver.h
index 84c8657..fc5a765 100644
--- a/src/via_driver.h
+++ b/src/via_driver.h
@@ -55,6 +55,8 @@
#include "via_bios.h"
#include "via_priv.h"
#include "via_swov.h"
+#include "via_dmabuffer.h"
+#include "via_3d.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -70,12 +72,24 @@
#define PATCHLEVEL 33
#define VIA_VERSION ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL)
-#define VIA_MAX_ACCEL_X (2047)
-#define VIA_MAX_ACCEL_Y (2047)
-#define VIA_PIXMAP_CACHE_SIZE (4 * (VIA_MAX_ACCEL_X + 1) * (VIA_MAX_ACCEL_Y +1))
+#ifdef VIA_HAVE_EXA
+#include "exa.h"
+#define VIA_AGP_UPL_SIZE (1024*128)
+#define VIA_DMA_DL_SIZE (1024*128)
+#define VIA_SCRATCH_SIZE (2048*1024)
+
+ /*
+ * Pixmap sizes below which we don't try to do hw accel.
+ */
+
+#define VIA_MIN_COMPOSITE 1 /*400*/
+#define VIA_MIN_UPLOAD 4000
+#define VIA_MIN_TEX_UPLOAD 400
+#define VIA_MIN_DOWNLOAD 400
+#endif
+
#define VIA_CURSOR_SIZE (4 * 1024)
#define VIA_VQ_SIZE (256 * 1024)
-#define VIA_CBUFFERSIZE 512
typedef struct {
CARD8 SR08, SR0A, SR0F;
@@ -134,15 +148,25 @@ typedef struct {
typedef struct _twodContext {
CARD32 mode;
+ CARD32 cmd;
+ CARD32 fgColor;
+ CARD32 bgColor;
+ CARD32 pattern0;
+ CARD32 pattern1;
+ CARD32 patternAddr;
+ CARD32 keyControl;
+ unsigned srcOffset;
+ unsigned srcPitch;
+ unsigned Bpp;
+ unsigned bytesPPShift;
+ Bool clipping;
+ int clipX1;
+ int clipX2;
+ int clipY1;
+ int clipY2;
} ViaTwodContext;
typedef struct{
- unsigned curPos;
- CARD32 buffer[VIA_CBUFFERSIZE];
- int status;
-} ViaCBuffer;
-
-typedef struct{
/* textMode */
CARD8 *state, *pstate; /* SVGA state */
int statePage, stateSize, stateMode;
@@ -155,13 +179,13 @@ typedef struct _VIA {
VIARegRec SavedReg;
xf86CursorInfoPtr CursorInfoRec;
int Bpp, Bpl;
- unsigned PlaneMask;
Bool FirstInit;
unsigned long videoRambytes;
int videoRamKbytes;
int FBFreeStart;
int FBFreeEnd;
+ int driSize;
int CursorStart;
int VQStart;
int VQEnd;
@@ -179,11 +203,6 @@ typedef struct _VIA {
unsigned char* FBBase;
CARD8 MemClk;
- /* Private memory pool management */
- int SWOVUsed[MEM_BLOCKS]; /* Free map for SWOV pool */
- unsigned long SWOVPool; /* Base of SWOV pool */
- unsigned long SWOVSize; /* Size of SWOV blocks */
-
/* Here are all the Options */
Bool VQEnable;
Bool pci_burst;
@@ -212,16 +231,38 @@ typedef struct _VIA {
/* Support for XAA acceleration */
XAAInfoRecPtr AccelInfoRec;
- xRectangle Rect;
- CARD32 SavedCmd;
- CARD32 SavedFgColor;
- CARD32 SavedBgColor;
- CARD32 SavedPattern0;
- CARD32 SavedPattern1;
- CARD32 SavedPatternAddr;
- int justSetup;
ViaTwodContext td;
- ViaCBuffer cBuf;
+ Via3DState v3d;
+ Via3DState *lastToUpload;
+ ViaCommandBuffer cb;
+ int accelMarker;
+ CARD32 markerOffset;
+ CARD32 *markerBuf;
+ CARD32 curMarker;
+ CARD32 lastMarkerRead;
+ Bool agpDMA;
+#ifdef VIA_HAVE_EXA
+ ExaDriverPtr exaDriverPtr;
+ ExaOffscreenArea *exa_scratch;
+ unsigned int exa_scratch_next;
+ Bool useEXA;
+ void *maskP;
+ CARD32 maskFormat;
+ Bool componentAlpha;
+ void *srcP;
+ CARD32 srcFormat;
+ ExaOffscreenArea *scratchFBBuffer;
+ unsigned scratchOffset;
+ char * scratchAddr;
+ Bool noComposite;
+#ifdef XF86DRI
+ drm_via_mem_t scratchAGPBuffer;
+ drm_via_mem_t texAGPBuffer;
+ unsigned texOffset;
+ char * texAddr;
+ char * dBounce;
+#endif
+#endif
/* BIOS Info Ptr */
VIABIOSInfoPtr pBIOSInfo;
@@ -266,6 +307,10 @@ typedef struct _VIA {
Bool IsPCI;
Bool drixinerama;
ViaXvMC xvmc;
+ int drmVerMajor;
+ int drmVerMinor;
+ int drmVerPL;
+ VIAMem driOffScreenMem;
#endif
Bool DRIIrqEnable;
Bool agpEnable;
@@ -318,7 +363,7 @@ typedef struct
} VIAEntRec, *VIAEntPtr;
/* Prototypes. */
-#ifdef XF86DRI
+#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
void VIAInitialize3DEngine(ScrnInfoPtr pScrn);
#endif
@@ -330,10 +375,19 @@ void ViaCursorStore(ScrnInfoPtr pScrn);
void ViaCursorRestore(ScrnInfoPtr pScrn);
/* In via_accel.c. */
-Bool VIAInitAccel(ScreenPtr);
-void VIAInitialize2DEngine(ScrnInfoPtr);
-void VIAAccelSync(ScrnInfoPtr);
-void ViaVQDisable(ScrnInfoPtr pScrn);
+Bool viaInitAccel(ScreenPtr);
+void viaInitialize2DEngine(ScrnInfoPtr);
+void viaAccelSync(ScrnInfoPtr);
+void viaDisableVQ(ScrnInfoPtr);
+void viaExitAccel(ScreenPtr);
+void viaAccelBlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+void viaAccelFillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+void viaAccelSyncMarker(ScrnInfoPtr);
+void viaFinishInitAccel(ScreenPtr);
+void viaAccelWaitMarker(ScreenPtr, int);
+int viaAccelMarkSync(ScreenPtr);
+
+
/* In via_shadow.c */
void ViaShadowFBInit(ScrnInfoPtr pScrn, ScreenPtr pScreen);
diff --git a/src/via_memcpy.c b/src/via_memcpy.c
index ccf0f07..aa490af 100644
--- a/src/via_memcpy.c
+++ b/src/via_memcpy.c
@@ -546,7 +546,6 @@ vidCopyFunc viaVidCopyInit( char *copyType,
double cpuFreq;
VIAPtr pVia = VIAPTR(pScrn);
- pScrn->pScreen = pScreen;
if (NULL == (cpuInfoFile = fopen("/proc/cpuinfo","r"))) {
return libc_YUV42X;
}
diff --git a/src/via_memory.c b/src/via_memory.c
index 95c9dfb..37fbb84 100644
--- a/src/via_memory.c
+++ b/src/via_memory.c
@@ -43,47 +43,68 @@
#endif
/*
- * Isolate the wonders of X memory allocation, DRI memory allocation
+ * Isolate the wonders of X memory allocation and DRI memory allocation
* and 4.3 or 4.4 differences in once abstraction
*
* The pool code indicates who provided the memory
* 0 - nobody
- * 1 - xf86 linear (Used in 4.4 only - current)
+ * 1 - xf86 linear
* 2 - DRM
- * 3 - Preallocated buffer (Used in 4.3 only - removed)
*/
void VIAFreeLinear(VIAMemPtr mem)
{
DEBUG(ErrorF("Freed %lu (pool %d)\n", mem->base, mem->pool));
- switch(mem->pool)
- {
+ switch(mem->pool) {
+ case 0:
+ return;
case 1:
+#ifdef VIA_HAVE_EXA
+ {
+ VIAPtr pVia = VIAPTR(mem->pScrn);
+ if (pVia->useEXA && !pVia->NoAccel) {
+ exaOffscreenFree(mem->pScrn->pScreen, mem->exa);
+ mem->linear = NULL;
+ mem->pool = 0;
+ return;
+ }
+ }
+#endif
xf86FreeOffscreenLinear(mem->linear);
mem->linear = NULL;
mem->pool = 0;
return;
case 2:
#ifdef XF86DRI
- if(drmCommandWrite(mem->drm_fd, DRM_VIA_FREEMEM,
+ if(drmCommandWriteRead(mem->drm_fd, DRM_VIA_FREEMEM,
&mem->drm, sizeof(drm_via_mem_t)) < 0)
ErrorF("DRM module failed free.\n");
#endif
mem->pool = 0;
return;
- case 0:
- case 3: /* deprecated */
- default:
- return;
}
}
-
static unsigned long offScreenLinear(VIAMemPtr mem, ScrnInfoPtr pScrn,
unsigned long size) {
- int depth = (pScrn->bitsPerPixel + 7) >> 3;
- /* Make sure we don't truncate requested size */
+ int depth = pScrn->bitsPerPixel >> 3;
+
+#ifdef VIA_HAVE_EXA
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ if (pVia->useEXA && !pVia->NoAccel) {
+
+ mem->exa = exaOffscreenAlloc(pScrn->pScreen, size,
+ 32, TRUE, NULL,NULL);
+ if (mem->exa == NULL)
+ return BadAlloc;
+ mem->base = mem->exa->offset;
+ mem->pool = 1;
+ return Success;
+ }
+#endif
+
mem->linear = xf86AllocateOffscreenLinear(pScrn->pScreen,
( size + depth - 1 ) / depth,
32, NULL, NULL, NULL);
@@ -98,15 +119,15 @@ static unsigned long offScreenLinear(VIAMemPtr mem, ScrnInfoPtr pScrn,
unsigned long VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long size)
{
- if(mem->pool)
- ErrorF("VIA Double Alloc.\n");
-
#ifdef XF86DRI
- {
VIAPtr pVia = VIAPTR(pScrn);
int ret;
+ if(mem->pool)
+ ErrorF("VIA Double Alloc.\n");
+
if(pVia->directRenderingEnabled) {
+ mem->pScrn = pScrn;
mem->drm_fd = pVia->drmFD;
mem->drm.context = 1;
mem->drm.size = size;
@@ -114,8 +135,9 @@ unsigned long VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long siz
ret = drmCommandWriteRead(mem->drm_fd, DRM_VIA_ALLOCMEM, &mem->drm,
sizeof(drm_via_mem_t));
if (ret || (size != mem->drm.size)) {
+
/*
- * Try XY Fallback before failing.
+ * Try X Offsceen fallback before failing.
*/
if (Success == offScreenLinear(mem, pScrn, size))
@@ -127,15 +149,17 @@ unsigned long VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long siz
mem->base = mem->drm.offset;
mem->pool = 2;
DEBUG(ErrorF("Fulfilled via DRI at %lu\n", mem->base));
- return 0;
- }
+ return Success;
}
-#endif /* XF86DRI */
-
+#endif
+ {
+ mem->pScrn = pScrn;
if (Success == offScreenLinear(mem, pScrn, size))
return Success;
ErrorF("Linear memory allocation failed\n");
return BadAlloc;
+ }
+ return Success;
}
void VIAInitLinear(ScreenPtr pScreen)
@@ -143,13 +167,15 @@ void VIAInitLinear(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
- /*
- * In the 44 path we must take care not to truncate offset and size so
- * that we get overlaps. If there is available memory below line 2048
- * we use it.
- */
+#ifdef VIA_HAVE_EXA
+ if (pVia->useEXA && !pVia->NoAccel) {
+ return;
+ } else
+#endif
+ {
unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1 ) / pVia->Bpp;
- unsigned long size = pVia->FBFreeEnd / pVia->Bpp - offset;
+ long size = pVia->FBFreeEnd / pVia->Bpp - offset;
if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size);
+ }
}
diff --git a/src/via_priv.h b/src/via_priv.h
index 2f0cf31..325e5f9 100644
--- a/src/via_priv.h
+++ b/src/via_priv.h
@@ -4,6 +4,9 @@
#ifdef XF86DRI
#include "via_drm.h"
#endif
+#ifdef VIA_HAVE_EXA
+#include "exa.h"
+#endif
/*
* Alignment macro functions
@@ -116,9 +119,12 @@ typedef struct {
int drm_fd; /* Fd in DRM mode */
drm_via_mem_t drm; /* DRM management object */
#endif
- int slot; /* Pool 3 slot */
void *pVia; /* VIA driver pointer */
FBLinearPtr linear; /* X linear pool info ptr */
+#ifdef VIA_HAVE_EXA
+ ExaOffscreenArea *exa;
+#endif
+ ScrnInfoPtr pScrn;
} VIAMem;
typedef VIAMem *VIAMemPtr;
diff --git a/src/via_vbe.c b/src/via_vbe.c
index e23b224..e6f484c 100644
--- a/src/via_vbe.c
+++ b/src/via_vbe.c
@@ -158,7 +158,7 @@ ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
pScrn->vtSema = TRUE;
if (!pVia->NoAccel)
- VIAInitialize2DEngine(pScrn);
+ viaInitialize2DEngine(pScrn);
#ifdef XF86DRI
VIAInitialize3DEngine(pScrn);