diff options
author | Tilman Sauerbeck <tilman@code-monkey.de> | 2006-08-10 19:49:22 +0200 |
---|---|---|
committer | Tilman Sauerbeck <tilman@code-monkey.de> | 2006-08-10 19:49:22 +0200 |
commit | 84ec0db961de3b10ac02ec5ae6adcec5cc439069 (patch) | |
tree | fa2042098a15cf61f8d6044cf143b442931d1e59 /src | |
parent | bde592047cd62194d7ef67520a9fdbaf269a8b90 (diff) |
Initial commit of the Exa bits.
Based on ajax' mga-exa-2.patch with some straight forward fixes
by myself.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 11 | ||||
-rw-r--r-- | src/mga.h | 27 | ||||
-rw-r--r-- | src/mga_dri.c | 33 | ||||
-rw-r--r-- | src/mga_driver.c | 75 | ||||
-rw-r--r-- | src/mga_exa.c | 744 | ||||
-rw-r--r-- | src/mga_reg.h | 100 |
6 files changed, 973 insertions, 17 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0fa8d93..17211bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,7 +54,6 @@ mga_drv_la_SOURCES = \ mga_reg.h \ mga_sarea.h \ mga_shadow.c \ - mga_storm.c \ mga_ucode.h \ mga_vga.c \ mga_video.c @@ -65,3 +64,13 @@ mga_drv_la_SOURCES += \ mga_dri.h \ mga_dripriv.h endif + +if USE_EXA +mga_drv_la_SOURCES += \ + mga_exa.c +endif + +if USE_XAA +mga_drv_la_SOURCES += \ + mga_storm.c +endif @@ -19,6 +19,7 @@ #include "compiler.h" #include "xaa.h" +#include "exa.h" #include "xf86Cursor.h" #include "vgaHW.h" #include "colormapst.h" @@ -80,7 +81,8 @@ typedef enum { OPTION_MONITOR2POS, OPTION_METAMODES, OPTION_OLDDMA, - OPTION_PCIDMA + OPTION_PCIDMA, + OPTION_ACCELMETHOD } MGAOpts; @@ -408,6 +410,8 @@ typedef struct { MGARamdacRec Dac; Bool HasSDRAM; Bool NoAccel; + Bool Exa; + ExaDriverPtr ExaDriver; Bool SyncOnGreen; Bool Dac6Bit; Bool HWCursor; @@ -528,6 +532,18 @@ typedef struct { Bool HALLoaded; #endif OptionInfoPtr Options; + + /* Exa */ + PicturePtr currentSrcPicture; + PicturePtr currentMaskPicture; + PixmapPtr currentSrc; + PixmapPtr currentMask; + int src_w2; + int src_h2; + int mask_w2; + int mask_h2; + CARD32 src_pitch; /* FIXME kill me */ + /* Merged Framebuffer data */ Bool MergedFB; @@ -588,12 +604,19 @@ void MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y); void MGA2064SetupFuncs(ScrnInfoPtr pScrn); void MGAGSetupFuncs(ScrnInfoPtr pScrn); +#ifdef USE_XAA void MGAStormSync(ScrnInfoPtr pScrn); void MGAStormEngineInit(ScrnInfoPtr pScrn); Bool MGAStormAccelInit(ScreenPtr pScreen); +Bool mgaAccelInit(ScreenPtr pScreen); +#endif + +#ifdef USE_EXA +Bool mgaExaInit(ScreenPtr pScreen); +#endif + Bool MGAHWCursorInit(ScreenPtr pScreen); -Bool mgaAccelInit(ScreenPtr pScreen); void MGAPolyArcThinSolid(DrawablePtr, GCPtr, int, xArc*); diff --git a/src/mga_dri.c b/src/mga_dri.c index 6775cff..be646e5 100644 --- a/src/mga_dri.c +++ b/src/mga_dri.c @@ -390,7 +390,11 @@ void MGAGetQuiescence( ScrnInfoPtr pScrn ) OUTREG( MGAREG_YTOP, 0x00000000 ); /* minPixelPointer */ OUTREG( MGAREG_YBOT, 0x007FFFFF ); /* maxPixelPointer */ - pMga->AccelFlags &= ~CLIPPER_ON; + /* FIXME what about EXA? */ +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) + pMga->AccelFlags &= ~CLIPPER_ON; +#endif } } @@ -406,7 +410,12 @@ void MGAGetQuiescenceShared( ScrnInfoPtr pScrn ) if ( pMGAEnt->directRenderingEnabled ) { MGAWaitForIdleDMA( pMGAEnt->pScrn_1 ); - pMga->RestoreAccelState( pScrn ); + + /* FIXME what about EXA? */ +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) + pMga->RestoreAccelState( pScrn ); +#endif xf86SetLastScrnFlag( pScrn->entityList[0], pScrn->scrnIndex ); } } @@ -420,7 +429,12 @@ static void MGASwapContext( ScreenPtr pScreen ) * appropriate. */ pMga->haveQuiescense = 0; - pMga->AccelInfoRec->NeedToSync = TRUE; + + /* FIXME what about EXA? */ +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) + pMga->AccelInfoRec->NeedToSync = TRUE; +#endif } static void MGASwapContextShared( ScreenPtr pScreen ) @@ -432,11 +446,16 @@ static void MGASwapContextShared( ScreenPtr pScreen ) pMga = MGAPTR(pMGAEnt->pScrn_1); - pMga->haveQuiescense = 0; - pMga->AccelInfoRec->NeedToSync = TRUE; + pMga->haveQuiescense = pMGA2->haveQuiescense = 0; - pMGA2->haveQuiescense = 0; - pMGA2->AccelInfoRec->NeedToSync = TRUE; + /* FIXME what about EXA? */ +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) + pMga->AccelInfoRec->NeedToSync = TRUE; + + if (!pMGA2->Exa && pMGA2->AccelInfoRec) + pMGA2->AccelInfoRec->NeedToSync = TRUE; +#endif } /* FIXME: This comment is out of date, since we aren't overriding diff --git a/src/mga_driver.c b/src/mga_driver.c index 6f4909a..a7c6de1 100644 --- a/src/mga_driver.c +++ b/src/mga_driver.c @@ -86,7 +86,10 @@ #include "mga_macros.h" #include "mga_maven.h" +#ifdef USE_XAA #include "xaa.h" +#endif + #include "xf86cmap.h" #include "shadowfb.h" #include "fbdevhw.h" @@ -232,6 +235,7 @@ static const OptionInfoRec MGAOptions[] = { { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, { OPTION_OLDDMA, "OldDmaInit", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCIDMA, "ForcePciDma", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -276,6 +280,17 @@ static const char *xf8_32bppSymbols[] = { NULL }; +#ifdef USE_EXA +static const char *exaSymbols[] = { + "exaDriverInit", + "exaDriverFini", + "exaGetPixmapOffset", + "exaGetVersion", + NULL +}; +#endif + +#ifdef USE_XAA static const char *xaaSymbols[] = { "XAACachePlanarMonoStipple", "XAACreateInfoRec", @@ -286,6 +301,7 @@ static const char *xaaSymbols[] = { "XAA_888_plus_PICT_a8_to_8888", NULL }; +#endif static const char *ramdacSymbols[] = { "xf86CreateCursorInfoRec", @@ -453,7 +469,13 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) * Tell the loader about symbols from other modules that this module * might refer to. */ - LoaderRefSymLists(vgahwSymbols, xaaSymbols, + LoaderRefSymLists(vgahwSymbols, +#ifdef USE_XAA + xaaSymbols, +#endif +#ifdef USE_EXA + exaSymbols, +#endif xf8_32bppSymbols, ramdacSymbols, ddcSymbols, i2cSymbols, shadowSymbols, fbdevHWSymbols, vbeSymbols, @@ -1497,6 +1519,19 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (xf86ReturnOptValBool(pMga->Options, OPTION_NOACCEL, FALSE)) { pMga->NoAccel = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } else { + int from = X_DEFAULT; + char *s = xf86GetOptValString(pMga->Options, OPTION_ACCELMETHOD); + pMga->NoAccel = FALSE; + pMga->Exa = FALSE; +#ifdef USE_EXA + if (!xf86NameCmp(s, "EXA")) { + pMga->Exa = TRUE; + from = X_CONFIG; + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", + pMga->Exa ? "EXA" : "XAA"); } if (xf86ReturnOptValBool(pMga->Options, OPTION_PCI_RETRY, FALSE)) { pMga->UsePCIRetry = TRUE; @@ -2326,11 +2361,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) /* Load XAA if needed */ if (!pMga->NoAccel) { - if (!xf86LoadSubModule(pScrn, "xaa")) { - MGAFreeRec(pScrn); - return FALSE; +#ifdef USE_EXA + if (pMga->Exa) { + if (!xf86LoadSubModule(pScrn, "exa")) { + MGAFreeRec(pScrn); + return FALSE; + } else xf86LoaderReqSymLists(exaSymbols, NULL); + } else { +#endif +#ifdef USE_XAA + if (!xf86LoadSubModule(pScrn, "xaa")) { + MGAFreeRec(pScrn); + return FALSE; + } else xf86LoaderReqSymLists(xaaSymbols, NULL); +#endif } - xf86LoaderReqSymLists(xaaSymbols, NULL); } /* Load ramdac if needed */ @@ -3337,8 +3382,16 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */ MGADGAInit(pScreen); - if (!pMga->NoAccel) - MGAStormAccelInit(pScreen); + if (!pMga->NoAccel) { +#ifdef USE_EXA + if (pMga->Exa) + mgaExaInit(pScreen); + else +#endif +#ifdef USE_XAA + MGAStormAccelInit(pScreen); +#endif + } miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); @@ -3843,8 +3896,16 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) ); /* MGA_HAL */ #endif +#ifdef USE_XAA if (pMga->AccelInfoRec) XAADestroyInfoRec(pMga->AccelInfoRec); +#endif +#ifdef USE_EXA + if (pMga->ExaDriver) { + exaDriverFini(pScreen); + xfree(pMga->ExaDriver); + } +#endif if (pMga->CursorInfoRec) xf86DestroyCursorInfoRec(pMga->CursorInfoRec); if (pMga->ShadowPtr) diff --git a/src/mga_exa.c b/src/mga_exa.c new file mode 100644 index 0000000..ee7aa0b --- /dev/null +++ b/src/mga_exa.c @@ -0,0 +1,744 @@ +/* + * Copyright 2006 Red Hat, Inc. + * + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them 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 MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + * + * Authors: + * Adam Jackson <ajax@nwnk.net> + */ + +/* + * Sources: + * - mga kdrive accel by Anders Carlsson + * - mga g400 Render accel by Damien Ciabrini + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" + +#include "mga.h" +#include "mga_reg.h" +#include "mga_macros.h" + +#include "exa.h" +#ifdef XF86DRI +#include "mga_dri.h" +#endif + +#if 0 +#define DEBUG_MSG(x) ErrorF x +#else +#define DEBUG_MSG(x) +#endif + +#define PMGA(x) \ + MGAPtr pMga = xf86Screens[x->drawable.pScreen->myNum]->driverPrivate; + +/* FIXME: is this correct? */ +#define QUIESCE_DMA(x) \ + CHECK_DMA_QUIESCENT(pMga, xf86Screens[x->drawable.pScreen->myNum]); + +/* stuff stolen from mga_storm.c */ +#define BLIT_LEFT 1 +#define BLIT_UP 4 + +static const CARD32 mgaRop[16] = { + /* GXclear */ MGADWG_RPL | 0x00000000, /* 0 */ + /* GXand */ MGADWG_RSTR | 0x00080000, /* src AND dst */ + /* GXandReverse */ MGADWG_RSTR | 0x00040000, /* src AND NOT dst */ + /* GXcopy */ MGADWG_RSTR | 0x000c0000, /* src */ + /* GXandInverted */ MGADWG_RSTR | 0x00020000, /* NOT src AND dst */ + /* GXnoop */ MGADWG_RSTR | 0x000a0000, /* dst */ + /* GXxor */ MGADWG_RSTR | 0x00060000, /* src XOR dst */ + /* GXor */ MGADWG_RSTR | 0x000e0000, /* src OR dst */ + /* GXnor */ MGADWG_RSTR | 0x00010000, /* NOT src AND NOT dst */ + /* GXequiv */ MGADWG_RSTR | 0x00090000, /* NOT src XOR dst */ + /* GXinvert */ MGADWG_RSTR | 0x00050000, /* NOT dst */ + /* GXorReverse */ MGADWG_RSTR | 0x000d0000, /* src OR NOT dst */ + /* GXcopyInverted */ MGADWG_RPL | 0x00030000, /* NOT src */ + /* GXorInverted */ MGADWG_RSTR | 0x000b0000, /* NOT src OR dst */ + /* GXnand */ MGADWG_RSTR | 0x00070000, /* NOT src OR NOT dst */ + /* GXset */ MGADWG_RPL | 0x000f0000 /* 1 */ +}; + +static const CARD32 atype[16] = { + MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000, + MGADWG_RSTR | 0x00040000, MGADWG_BLK | 0x000c0000, + MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000, + MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000, + MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000, + MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000, + MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000, + MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000 +}; + +static const CARD32 atype_noblk[16] = { + MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000, + MGADWG_RSTR | 0x00040000, MGADWG_RPL | 0x000c0000, + MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000, + MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000, + MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000, + MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000, + MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000, + MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000 +}; + +static const struct { + Bool dst_alpha; + Bool src_alpha; + CARD32 blend_cntl; +} mgaBlendOp[] = { + {0, 0, MGA_SRC_ZERO | MGA_DST_ZERO}, + {0, 0, MGA_SRC_ONE | MGA_DST_ZERO}, + {0, 0, MGA_SRC_ZERO | MGA_DST_ONE}, + {0, 1, MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA}, + {1, 0, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_ONE}, + {1, 0, MGA_SRC_DST_ALPHA | MGA_DST_ZERO}, + {0, 1, MGA_SRC_ZERO | MGA_DST_SRC_ALPHA}, + {1, 0, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_ZERO}, + {0, 1, MGA_SRC_ZERO | MGA_DST_ONE_MINUS_SRC_ALPHA}, + {1, 1, MGA_SRC_DST_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA}, + {1, 1, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_SRC_ALPHA}, + {1, 1, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA}, + {0, 0, MGA_SRC_ONE | MGA_DST_ONE}, +}; + +static const struct { + int fmt; + CARD32 card_fmt; +} texformats[] = { + { PICT_a8r8g8b8, MGA_TW32 }, + { PICT_x8r8g8b8, MGA_TW32 }, + { PICT_r5g6b5, MGA_TW16 }, + { PICT_a1r5g5b5, MGA_TW15 }, + { PICT_x1r5g5b5, MGA_TW15 }, + { PICT_a4r4g4b4, MGA_TW12 }, + { PICT_x4r4g4b4, MGA_TW12 }, + { PICT_a8, MGA_TW8A }, +}; + +static CARD32 +mgaGetPixmapPitch(PixmapPtr pPix) +{ + return exaGetPixmapPitch(pPix) / (pPix->drawable.bitsPerPixel >> 3); +} + +static void +mgaNoopDone(PixmapPtr pPixmap) +{ +} + +static Bool +mgaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + PMGA(pPixmap); + QUIESCE_DMA(pPixmap); + + pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | + MGADWG_SGNZERO | MGADWG_SHIFTZERO | mgaRop[alu]; + + WAITFIFO(5); + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pPixmap)); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pPixmap)); + OUTREG(MGAREG_FCOL, fg); + OUTREG(MGAREG_PLNWT, planemask); + OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); + + return TRUE; +} + +static void +mgaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + PMGA(pPixmap); + + WAITFIFO(2); + OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (y1 << 16) | (y2 - y1)); +} + +static Bool +mgaPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int xdir, int ydir, int alu, + Pixel planemask) +{ + PMGA(pSrc); + int blit_direction = 0; + int dwgctl = 0; + + QUIESCE_DMA(pSrc); + + DEBUG_MSG(("s: %x@%x d: %x@%x xdir %d ydir %d alu %d pm %d\n", + exaGetPixmapOffset(pSrc), exaGetPixmapPitch(pSrc), + exaGetPixmapOffset(pDst), exaGetPixmapPitch(pDst), + xdir, ydir, alu, planemask)); + + if (xdir < 0) + blit_direction |= BLIT_LEFT; + + if (ydir < 0) + blit_direction |= BLIT_UP; + + pMga->BltScanDirection = blit_direction; + + dwgctl = mgaRop[alu] | MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL; + pMga->src_pitch = mgaGetPixmapPitch(pSrc); + + WAITFIFO(7); + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pDst)); + OUTREG(MGAREG_SRCORG, exaGetPixmapOffset(pSrc)); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pDst)); + OUTREG(MGAREG_DWGCTL, dwgctl); + OUTREG(MGAREG_SGN, blit_direction); + OUTREG(MGAREG_PLNWT, planemask); + + /* this is crap */ + OUTREG(MGAREG_AR5, (ydir < -0 ? -1 : 1) * pMga->src_pitch); + + return TRUE; +} + +/* this whole thing is bogus. */ +static void +mgaCopy(PixmapPtr pDst, int srcx, int srcy, int dstx, int dsty, int w, int h) +{ + PMGA(pDst); + int start, end; + + DEBUG_MSG((" %d,%d -> %d,%d %dx%d\n", srcx, srcy, dstx,dsty, w, h)); + + w--; + + if (pMga->BltScanDirection & BLIT_UP) { + srcy += h - 1; + dsty += h - 1; + } + + start = end = srcy * pMga->src_pitch + srcx; + + if (pMga->BltScanDirection & BLIT_LEFT) + start += w; + else + end += w; + + DEBUG_MSG((" end %d start %d dstx %d dsty %d w %d h %d\n", + end, start, dstx, dsty, w, h)); + WAITFIFO(4); + OUTREG(MGAREG_AR0, end); + OUTREG(MGAREG_AR3, start); + OUTREG(MGAREG_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (dsty << 16) | h); +} + +static int +MGA_LOG2(int val) +{ + int ret = 0; + + if (val == 1) + return 0; + + while (val >> ret) + ret++; + + return ((1 << (ret - 1)) == val) ? (ret - 1) : ret; +} + +static Bool +mgaCheckSourceTexture(int tmu, PicturePtr pPict) +{ + int w = pPict->pDrawable->width; + int h = pPict->pDrawable->height; + int i; + CARD32 texctl = 0; + + if ((w > 2047) || (h > 2047)){ + DEBUG_MSG(("Picture w/h too large (%dx%d)\n", w, h)); + return FALSE; + } + + for (i = 0; i < sizeof(texformats) / sizeof(texformats[0]); i++) { + if (texformats[i].fmt == pPict->format) { + texctl = texformats[i].card_fmt; + break; + } + } + + if (texctl == 0) { + DEBUG_MSG(("Unsupported picture format 0x%x\n", pPict->format)); + return FALSE; + } + + if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0)) { + DEBUG_MSG(("NPOT repeat unsupported (%dx%d)\n", w, h)); + return FALSE; + } + + if (pPict->filter != PictFilterNearest && + pPict->filter != PictFilterBilinear) { + DEBUG_MSG(("Unsupported filter 0x%x\n", pPict->filter)); + return FALSE; + } + + return TRUE; +} + +static Bool +mgaCheckComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict, + PicturePtr pDstPict) +{ + if (op >= sizeof(mgaBlendOp) / sizeof(mgaBlendOp[0])) { + DEBUG_MSG(("unsupported op %x", op)); + return FALSE; + } + + if (!mgaCheckSourceTexture(0, pSrcPict)) + return FALSE; + + if (pMaskPict) { + if (PICT_FORMAT_A(pMaskPict->format) == 0) { + DEBUG_MSG(("Mask without alpha unsupported")); + return FALSE; + } + + if (!mgaCheckSourceTexture(1, pMaskPict)) + return FALSE; + + if (pMaskPict->componentAlpha) { + DEBUG_MSG(("Component alpha unsupported")); + return FALSE; + } + } + + switch (pDstPict->format) { + case PICT_a8: + DEBUG_MSG(("render to A8 unsupported")); + return FALSE; + default: + break; + } + + return TRUE; +} + +static Bool +PrepareSourceTexture(int tmu, PicturePtr pSrcPicture, PixmapPtr pSrc) +{ + PMGA(pSrc); + int i; + int pitch = mgaGetPixmapPitch(pSrc); + int w = pSrc->drawable.width; + int h = pSrc->drawable.height; + int w_log2 = MGA_LOG2(w); + int h_log2 = MGA_LOG2(h); + + int texctl = MGA_PITCHLIN | ((pitch & (2048 - 1)) << 9) | + MGA_CLAMPUV | MGA_NOPERSPECTIVE; + int flags = 0; + int texctl2 = MGA_G400_TC2_MAGIC | flags; + + for (i = 0; i < sizeof(texformats) / sizeof(texformats[0]); i++) { + if (texformats[i].fmt == pSrcPicture->format) { + texctl |= texformats[i].card_fmt; + break; + } + } + + if (PICT_FORMAT_A(pSrcPicture->format) != 0) { + texctl |= MGA_TAKEY; + } else { + texctl |= MGA_TAMASK | MGA_TAKEY; + } + + if (pSrcPicture->repeat) { + texctl &= ~MGA_CLAMPUV; + } + + if (tmu == 1) + texctl2 |= MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1 | flags; + + WAITFIFO(6); + OUTREG(MGAREG_TEXCTL2, texctl2); + OUTREG(MGAREG_TEXCTL, texctl); + /* Source (texture) address + pitch */ + OUTREG(MGAREG_TEXORG, exaGetPixmapOffset(pSrc)); + OUTREG(MGAREG_TEXWIDTH, (w-1)<<18 | ((8-w_log2)&63)<<9 | w_log2); + OUTREG(MGAREG_TEXHEIGHT, (h-1)<<18 | ((8-h_log2)&63)<<9 | h_log2); + /* Set blit filtering flags */ + if (pSrcPicture->filter == PictFilterBilinear) + OUTREG(MGAREG_TEXFILTER, (0x10<<21) | MGA_MAG_BILIN | MGA_MIN_BILIN); + else + OUTREG(MGAREG_TEXFILTER, (0x10<<21) | MGA_MAG_NRST | MGA_MIN_NRST); + + if (tmu == 1) { + WAITFIFO(1); + OUTREG(MGAREG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX | flags); + } + + return TRUE; +} + +/* + * The formals params are the elements of the following matrix: + * + * Dest Transform Src + * coords coords + * / Xdst \ / X_incx X_incy X_init \ / Xsrc \ + * | Ydst | = | Y_incx Y_incy Y_init | x | Ysrc | + * \ 1 / \ H_incx H_incy H_init / \ 1 / + * + * matrix elements are 32bits fixed points (16.16) + * mga_fx_* is the size of the fixed point for the TMU + */ +static void +setTMIncrementsRegs(PixmapPtr pPix, int X_incx, int X_incy, int X_init, + int Y_incx, int Y_incy, int Y_init, + int H_incx, int H_incy, int H_init, + int mga_fx_width_size, int mga_fx_height_size) +{ + PMGA(pPix); + + int decalw = mga_fx_width_size - 16; + int decalh = mga_fx_height_size - 16; + + /* Convert 16 bits fixpoint -> MGA variable size fixpoint */ + if (decalw >= 0) { + X_incx = X_incx << decalw; + X_incy = X_incy << decalw; + X_init = X_init << decalw; + } else { + decalw =- decalw; + X_incx = X_incx >> decalw; + X_incy = X_incy >> decalw; + X_init = X_init >> decalw; + } + + /* Convert 16 bits fixpoint -> MGA variable size fixpoint */ + if (decalh >= 0) { + Y_incx = Y_incx << decalh; + Y_incy = Y_incy << decalh; + Y_init = Y_init << decalh; + } else { + decalh =- decalh; + Y_incx = Y_incx >> decalh; + Y_incy = Y_incy >> decalh; + Y_init = Y_init >> decalh; + } + + /* Set TM registers */ + WAITFIFO(9); + OUTREG(MGAREG_TMR0, X_incx); + OUTREG(MGAREG_TMR1, Y_incx); + OUTREG(MGAREG_TMR2, X_incy); + OUTREG(MGAREG_TMR3, Y_incy); + OUTREG(MGAREG_TMR4, H_incx); + OUTREG(MGAREG_TMR5, H_incy); + OUTREG(MGAREG_TMR6, X_init); + OUTREG(MGAREG_TMR7, Y_init); + OUTREG(MGAREG_TMR8, H_init); +} + +/* XXX these look like magic */ +#define C_ARG1_CUR 0x0 +#define C_ARG1_ALPHA MGA_TDS_COLOR_ARG1_REPLICATEALPHA +#define C_ARG2_DIFFUSE MGA_TDS_COLOR_ARG2_DIFFUSE +#define C_ARG2_FCOL MGA_TDS_COLOR_ARG2_FCOL +#define C_ARG2_PREV MGA_TDS_COLOR_ARG2_PREVSTAGE +#define C_ARG1_INV MGA_TDS_COLOR_ARG1_INV +#define C_ARG2_INV MGA_TDS_COLOR_ARG2_INV +#define COLOR_MUL MGA_TDS_COLOR_SEL_MUL +#define COLOR_ARG1 MGA_TDS_COLOR_SEL_ARG1 +#define COLOR_ARG2 MGA_TDS_COLOR_SEL_ARG2 +#define A_ARG1_CUR 0x0 +#define A_ARG2_IGN A_ARG2_DIFFUSE +#define A_ARG2_FCOL MGA_TDS_ALPHA_ARG2_FCOL +#define A_ARG2_DIFFUSE MGA_TDS_ALPHA_ARG2_DIFFUSE +#define A_ARG2_PREV MGA_TDS_ALPHA_ARG2_PREVSTAGE +#define ALPHA_MUL MGA_TDS_ALPHA_SEL_MUL +#define ALPHA_ARG1 MGA_TDS_ALPHA_SEL_ARG1 +#define ALPHA_ARG2 MGA_TDS_ALPHA_SEL_ARG2 + +static Bool +mgaPrepareComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict, + PicturePtr pDstPict, PixmapPtr pSrc, PixmapPtr pMask, + PixmapPtr pDst) +{ + PMGA(pDst); + CARD32 ds0 = 0, ds1 = 0, cmd, blendcntl; + + WAITFIFO(3); + OUTREG(MGAREG_FCOL, 0xff000000); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pDst)); + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pDst)); + + if (!PrepareSourceTexture(0, pSrcPict, pSrc)) + return FALSE; + + if (pMask && !PrepareSourceTexture(1, pMaskPict, pMask)) + return FALSE; + + if (pSrcPict->format == PICT_a8) { + /* C = 0 A = As */ + /* MGA HW: A8 format makes RGB white. We use FCOL for the black + * If FCOL was not 0, it would have been be premultiplied (RENDER) + * color component would have been: + * C_ARG1_ALPHA | C_ARG2_FCOL | COLOR_MUL + */ + ds0 = C_ARG2_FCOL | COLOR_ARG2 | + A_ARG1_CUR | ALPHA_ARG1; + + /* MGA HW: TMU1 must be enabled when DUALSTAGE0 contains something */ + if (!pMask) { + if (!PrepareSourceTexture(1, pSrcPict, pSrc)) + return FALSE; + ds1 = C_ARG2_PREV | COLOR_ARG2 | + A_ARG2_PREV | ALPHA_ARG2; + } + } else { + /* C = Cs A = As */ + ds0 = C_ARG1_CUR | COLOR_ARG1 | + A_ARG1_CUR | ALPHA_ARG1; + } + + if (pMask) { + /* As or Am might be NULL. in this case we don't multiply because, + * the alpha component holds garbage. + */ + int color, alpha; + + if (PICT_FORMAT_A(pMaskPict->format) == 0) { + /* C = Cs */ + color = C_ARG2_PREV | COLOR_ARG2; + } else { + /* C = Am * Cs */ + color = C_ARG1_ALPHA | C_ARG2_PREV | COLOR_MUL; + } + + if (PICT_FORMAT_A(pMaskPict->format) == 0) { + /* A = As */ + alpha = A_ARG2_PREV | ALPHA_ARG2; + } else if (PICT_FORMAT_A(pSrcPict->format) == 0) { + /* A = Am */ + alpha = A_ARG1_CUR | ALPHA_ARG1; + } else { + /* A = Am * As */ + alpha = A_ARG1_CUR | A_ARG2_PREV | ALPHA_MUL; + } + + ds1 = color | alpha; + } + + cmd = MGADWG_TEXTURE_TRAP | MGADWG_I | 0x000c0000 | + MGADWG_SHIFTZERO | MGADWG_SGNZERO | MGADWG_ARZERO; + blendcntl = mgaBlendOp[op].blend_cntl; + + if (PICT_FORMAT_A(pDstPict->format) == 0 && mgaBlendOp[op].dst_alpha) { + if ((blendcntl & MGA_SRC_BLEND_MASK) == MGA_SRC_DST_ALPHA) + blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ONE; + else if ((blendcntl&MGA_SRC_BLEND_MASK) == MGA_SRC_ONE_MINUS_DST_ALPHA) + blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ZERO; + } + + WAITFIFO(4); + OUTREG(MGAREG_TDUALSTAGE0, ds0); + OUTREG(MGAREG_TDUALSTAGE1, ds1); + OUTREG(MGAREG_DWGCTL, cmd); + OUTREG(MGAREG_ALPHACTRL, MGA_ALPHACHANNEL | blendcntl); + + pMga->currentSrcPicture = pSrcPict; + pMga->currentMaskPicture = pMaskPict; + pMga->currentSrc = pSrc; + pMga->currentMask = pMask; + + pMga->src_w2 = MGA_LOG2 (pSrc->drawable.width); + pMga->src_h2 = MGA_LOG2 (pSrc->drawable.height); + + if (pMask) { + pMga->mask_w2 = MGA_LOG2 (pMask->drawable.width); + pMga->mask_h2 = MGA_LOG2 (pMask->drawable.height); + } + + return TRUE; +} + +static void +mgaComposite(PixmapPtr pDst, int srcx, int srcy, int maskx, int masky, + int dstx, int dsty, int w, int h) +{ + PMGA(pDst); + PictTransformPtr t; + + srcx %= pMga->currentSrc->drawable.width; + srcy %= pMga->currentSrc->drawable.height; + + if (pMga->currentMask) { + maskx %= pMga->currentMask->drawable.width; + maskx %= pMga->currentMask->drawable.height; + } + + t = pMga->currentSrcPicture->transform; + + if (t) + setTMIncrementsRegs(pMga->currentSrc, + t->matrix[0][0], + t->matrix[0][1], + t->matrix[0][2] + (srcx << 16), + t->matrix[1][0], + t->matrix[1][1], + t->matrix[1][2] + (srcy << 16), + t->matrix[2][0], + t->matrix[2][1], + t->matrix[2][2], + 20 - pMga->src_w2, + 20 - pMga->src_h2); + else + setTMIncrementsRegs(pMga->currentSrc, + 1 << 16, 0, srcx << 16, + 0, 1 << 16, srcy << 16, + 0, 0, 0x10000, + 20 - pMga->src_w2, + 20 - pMga->src_h2); + + if (pMga->currentMask) { + WAITFIFO(1); + OUTREG(MGAREG_TEXCTL2, + MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1); + + t = pMga->currentMaskPicture->transform; + + if (t) + setTMIncrementsRegs(pMga->currentMask, + t->matrix[0][0], + t->matrix[0][1], + t->matrix[0][2] + (maskx << 16), + t->matrix[1][0], + t->matrix[1][1], + t->matrix[1][2] + (masky << 16), + t->matrix[2][0], + t->matrix[2][1], + t->matrix[2][2], + 20 - pMga->mask_w2, + 20 - pMga->mask_h2); + else + setTMIncrementsRegs(pMga->currentMask, + 1 << 16, 0, maskx << 16, + 0, 1 << 16, masky << 16, + 0, 0, 0x10000, + 20 - pMga->mask_w2, + 20 - pMga->mask_h2); + + WAITFIFO(1); + OUTREG(MGAREG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX); + } + + WAITFIFO(2); + OUTREG(MGAREG_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (dsty << 16) | (h & 0xffff)); +} + +static Bool +mgaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + return FALSE; +} + +static Bool +mgaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, + int dst_pitch) +{ + return FALSE; +} + +static void +mgaWaitMarker(ScreenPtr pScreen, int marker) +{ +} + +Bool +mgaExaInit(ScreenPtr pScreen) +{ + ExaDriverPtr pExa; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = pScrn->driverPrivate; + + pExa = exaDriverAlloc(); + if (!pExa) { + pMga->NoAccel = TRUE; + return FALSE; + } + + pMga->ExaDriver = pExa; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + + pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT; + pExa->memoryBase = pMga->FbStart; + pExa->memorySize = pMga->FbUsableSize - 4096; + pExa->offScreenBase = (pScrn->virtualX * pScrn->virtualY * + pScrn->bitsPerPixel/8) + 4096; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "X %d Y %d bpp %d\n", + pScrn->virtualX, pScrn->virtualY, pScrn->bitsPerPixel); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Start at %p, size %x, osb %x\n", + pExa->memoryBase, pExa->memorySize, pExa->offScreenBase); + + pExa->pixmapOffsetAlign = 64; + pExa->pixmapPitchAlign = 64; + pExa->maxX = 2048; + pExa->maxY = 2048; + + pExa->WaitMarker = mgaWaitMarker; + pExa->PrepareSolid = mgaPrepareSolid; + pExa->Solid = mgaSolid; + pExa->DoneSolid = mgaNoopDone; + pExa->PrepareCopy = mgaPrepareCopy; + pExa->Copy = mgaCopy; + pExa->DoneCopy = mgaNoopDone; + + /* FIXME + * if (pMga->Chipset >= PCI_CHIP_MGAG400) { + */ + if (1) { + pExa->CheckComposite = mgaCheckComposite; + pExa->PrepareComposite = mgaPrepareComposite; + pExa->Composite = mgaComposite; + pExa->DoneComposite = mgaNoopDone; + } + + if (0) { + pExa->DownloadFromScreen = mgaDownloadFromScreen; + pExa->UploadToScreen = mgaUploadToScreen; + } + + /* XXX fill in the XAA setup code here */ +#if 0 + if(pMga->HasSDRAM) { + pMga->Atype = pMga->AtypeNoBLK = atype_noblk; + } else { + pMga->Atype = atype; + pMga->AtypeNoBLK = atype_noblk; + } +#endif + + return exaDriverInit(pScreen, pExa); +} diff --git a/src/mga_reg.h b/src/mga_reg.h index 0d6a20b..7fe729a 100644 --- a/src/mga_reg.h +++ b/src/mga_reg.h @@ -465,14 +465,114 @@ #define MGAREG_TEXWIDTH 0x2c28 #define MGAREG_TEXHEIGHT 0x2c2c #define MGAREG_TEXCTL 0x2c30 +# define MGA_TW4 (0x00000000) +# define MGA_TW8 (0x00000001) +# define MGA_TW15 (0x00000002) +# define MGA_TW16 (0x00000003) +# define MGA_TW12 (0x00000004) +# define MGA_TW32 (0x00000006) +# define MGA_TW8A (0x00000007) +# define MGA_TW8AL (0x00000008) +# define MGA_TW422 (0x0000000A) +# define MGA_TW422UYVY (0x0000000B) +# define MGA_PITCHLIN (0x00000100) +# define MGA_NOPERSPECTIVE (0x00200000) +# define MGA_TAKEY (0x02000000) +# define MGA_TAMASK (0x04000000) +# define MGA_CLAMPUV (0x18000000) #define MGAREG_TEXCTL2 0x2c3c +# define MGA_G400_TC2_MAGIC (0x00008000) +# define MGA_TC2_DECALBLEND (0x00000001) +# define MGA_TC2_IDECAL (0x00000002) +# define MGA_TC2_DECALDIS (0x00000004) +# define MGA_TC2_CKSTRANSDIS (0x00000010) +# define MGA_TC2_BORDEREN (0x00000020) +# define MGA_TC2_SPECEN (0x00000040) +# define MGA_TC2_DUALTEX (0x00000080) +# define MGA_TC2_TABLEFOG (0x00000100) +# define MGA_TC2_BUMPMAP (0x00000200) +# define MGA_TC2_SELECT_TMU1 (0x80000000) #define MGAREG_TEXTRANS 0x2c34 #define MGAREG_TEXTRANSHIGH 0x2c38 #define MGAREG_TEXFILTER 0x2c58 +# define MGA_MIN_NRST (0x00000000) +# define MGA_MIN_BILIN (0x00000002) +# define MGA_MIN_ANISO (0x0000000D) +# define MGA_MAG_NRST (0x00000000) +# define MGA_MAG_BILIN (0x00000020) #define MGAREG_ALPHASTART 0x2c70 #define MGAREG_ALPHAXINC 0x2c74 #define MGAREG_ALPHAYINC 0x2c78 #define MGAREG_ALPHACTRL 0x2c7c +# define MGA_SRC_ZERO (0x00000000) +# define MGA_SRC_ONE (0x00000001) +# define MGA_SRC_DST_COLOR (0x00000002) +# define MGA_SRC_ONE_MINUS_DST_COLOR (0x00000003) +# define MGA_SRC_ALPHA (0x00000004) +# define MGA_SRC_ONE_MINUS_SRC_ALPHA (0x00000005) +# define MGA_SRC_DST_ALPHA (0x00000006) +# define MGA_SRC_ONE_MINUS_DST_ALPHA (0x00000007) +# define MGA_SRC_SRC_ALPHA_SATURATE (0x00000008) +# define MGA_SRC_BLEND_MASK (0x0000000f) +# define MGA_DST_ZERO (0x00000000) +# define MGA_DST_ONE (0x00000010) +# define MGA_DST_SRC_COLOR (0x00000020) +# define MGA_DST_ONE_MINUS_SRC_COLOR (0x00000030) +# define MGA_DST_SRC_ALPHA (0x00000040) +# define MGA_DST_ONE_MINUS_SRC_ALPHA (0x00000050) +# define MGA_DST_DST_ALPHA (0x00000060) +# define MGA_DST_ONE_MINUS_DST_ALPHA (0x00000070) +# define MGA_DST_BLEND_MASK (0x00000070) +# define MGA_ALPHACHANNEL (0x00000100) +# define MGA_VIDEOALPHA (0x00000200) +# define MGA_DIFFUSEDALPHA (0x01000000) +# define MGA_MODULATEDALPHA (0x02000000) +#define MGAREG_TDUALSTAGE0 (0x2CF8) +#define MGAREG_TDUALSTAGE1 (0x2CFC) +# define MGA_TDS_COLOR_ARG2_DIFFUSE (0x00000000) +# define MGA_TDS_COLOR_ARG2_SPECULAR (0x00000001) +# define MGA_TDS_COLOR_ARG2_FCOL (0x00000002) +# define MGA_TDS_COLOR_ARG2_PREVSTAGE (0x00000003) +# define MGA_TDS_COLOR_ALPHA_DIFFUSE (0x00000000) +# define MGA_TDS_COLOR_ALPHA_FCOL (0x00000004) +# define MGA_TDS_COLOR_ALPHA_CURRTEX (0x00000008) +# define MGA_TDS_COLOR_ALPHA_PREVTEX (0x0000000c) +# define MGA_TDS_COLOR_ALPHA_PREVSTAGE (0x00000010) +# define MGA_TDS_COLOR_ARG1_REPLICATEALPHA (0x00000020) +# define MGA_TDS_COLOR_ARG1_INV (0x00000040) +# define MGA_TDS_COLOR_ARG2_REPLICATEALPHA (0x00000080) +# define MGA_TDS_COLOR_ARG2_INV (0x00000100) +# define MGA_TDS_COLOR_ALPHA1INV (0x00000200) +# define MGA_TDS_COLOR_ALPHA2INV (0x00000400) +# define MGA_TDS_COLOR_ARG1MUL_ALPHA1 (0x00000800) +# define MGA_TDS_COLOR_ARG2MUL_ALPHA2 (0x00001000) +# define MGA_TDS_COLOR_ARG1ADD_MULOUT (0x00002000) +# define MGA_TDS_COLOR_ARG2ADD_MULOUT (0x00004000) +# define MGA_TDS_COLOR_MODBRIGHT_2X (0x00008000) +# define MGA_TDS_COLOR_MODBRIGHT_4X (0x00010000) +# define MGA_TDS_COLOR_ADD_SUB (0x00000000) +# define MGA_TDS_COLOR_ADD_ADD (0x00020000) +# define MGA_TDS_COLOR_ADD2X (0x00040000) +# define MGA_TDS_COLOR_ADDBIAS (0x00080000) +# define MGA_TDS_COLOR_BLEND (0x00100000) +# define MGA_TDS_COLOR_SEL_ARG1 (0x00000000) +# define MGA_TDS_COLOR_SEL_ARG2 (0x00200000) +# define MGA_TDS_COLOR_SEL_ADD (0x00400000) +# define MGA_TDS_COLOR_SEL_MUL (0x00600000) +# define MGA_TDS_ALPHA_ARG1_INV (0x00800000) +# define MGA_TDS_ALPHA_ARG2_DIFFUSE (0x00000000) +# define MGA_TDS_ALPHA_ARG2_FCOL (0x01000000) +# define MGA_TDS_ALPHA_ARG2_PREVTEX (0x02000000) +# define MGA_TDS_ALPHA_ARG2_PREVSTAGE (0x03000000) +# define MGA_TDS_ALPHA_ARG2_INV (0x04000000) +# define MGA_TDS_ALPHA_ADD (0x08000000) +# define MGA_TDS_ALPHA_ADDBIAS (0x10000000) +# define MGA_TDS_ALPHA_ADD2X (0x20000000) +# define MGA_TDS_ALPHA_SEL_ARG1 (0x00000000) +# define MGA_TDS_ALPHA_SEL_ARG2 (0x40000000) +# define MGA_TDS_ALPHA_SEL_ADD (0x80000000) +# define MGA_TDS_ALPHA_SEL_MUL (0xc0000000) + #define MGAREG_DWGSYNC 0x2c4c #define MGAREG_AGP_PLL 0x1e4c |