Index: tdfx.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h,v retrieving revision 1.2 diff -u -r1.2 tdfx.h --- tdfx.h 23 Apr 2004 19:49:53 -0000 1.2 +++ tdfx.h 27 Sep 2004 17:14:42 -0000 @@ -227,6 +227,24 @@ XF86VideoAdaptorPtr textureAdaptor; ScreenBlockHandlerProcPtr BlockHandler; OptionInfoPtr Options; + CARD32 lfbMode; /* Cached lfbMode value */ +#ifdef RENDER + /* Render accel support variables, from voodoo(4) */ + CARD32 alpha; /* Cached alpha reg for sw blit */ + CARD32 alphaPitch; /* Software render blit state */ + CARD32 alphaSrc; + CARD32 alphaDst; + CARD8 *alphaPtr; + CARD32 alphaC; + CARD32 alphaW; + CARD32 alphaH; + CARD32 texPitch; + CARD32 texSrc; + CARD32 texDst; + CARD8 *texPtr; + CARD32 texW; + CARD32 texH; +#endif } TDFXRec; typedef struct { Index: tdfx_accel.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c,v retrieving revision 1.2 diff -u -r1.2 tdfx_accel.c --- tdfx_accel.c 23 Apr 2004 19:49:53 -0000 1.2 +++ tdfx_accel.c 27 Sep 2004 17:14:43 -0000 @@ -163,15 +163,14 @@ TDFXSetLFBConfig(TDFXPtr pTDFX) { if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) { #if X_BYTE_ORDER == X_BIG_ENDIAN - unsigned int lfbmode; - lfbmode=TDFXReadLongMMIO(pTDFX, SST_3D_LFBMODE); + pTDFX->lfbMode=TDFXReadLongMMIO(pTDFX, SST_3D_LFBMODE); - lfbmode&=~BIT(12); /* 0 bit 12 is byte swizzle */ - lfbmode|=BIT(11); /* 1 bit 11 is word swizzle */ - lfbmode&=~BIT(10); /* 0 bit 10 ARGB or ABGR */ - lfbmode&=~BIT(9); /* 0 bit 9 if bit10 = 0: ARGB else ABGR */ + pTDFX->lfbMode&=~BIT(12); /* 0 bit 12 is byte swizzle */ + pTDFX->lfbMode|=BIT(11); /* 1 bit 11 is word swizzle */ + pTDFX->lfbMode&=~BIT(10); /* 0 bit 10 ARGB or ABGR */ + pTDFX->lfbMode&=~BIT(9); /* 0 bit 9 if bit10 = 0: ARGB else ABGR */ - TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, lfbmode); + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, pTDFX->lfbMode); #endif TDFXWriteLongMMIO(pTDFX, LFBMEMORYCONFIG, (pTDFX->backOffset>>12) | SST_RAW_LFB_ADDR_STRIDE_4K | @@ -201,6 +200,262 @@ } } +#if defined(RENDER) +/* + * Render acceleration lifted pretty much wholesale from Alan Cox' voodoo(4) + * driver. All Voodoo chips support CPU-driven alpha composite to the frame + * buffer. This is presumably meant for software fallbacks on rendering 3D + * but happens to be very useful to avoid some Render operations reading + * from the frame buffer as much. + * + * We could use the 3D engine more to accelerate trapezoids. However, this + * driver would have to cooperate with glide to do so, and voodoo(4) lacks + * any DRI support atm. + * + * The server takes the DRI lock, so we don't have to worry about contention. + * Since we dirty 3D state we need to clean up, but we don't have an epilogue + * function, so we need to set the appropriate bits in the SAREA. Currently + * this is not done. + */ + +#define RENDER_DEBUG 0 + +static int TDFXBlendMode[] = { + /* Clear */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ZERO), + /* Src */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ONE) | AM_DST(AM_BLEND_ZERO), + /* Dst */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ONE), + /* Over */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ONE) | AM_DST(AM_BLEND_OMSRCA), + /* OverReverse */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_OMDSTA) | AM_DST(AM_BLEND_ONE), + /* In */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_DSTA) | AM_DST(AM_BLEND_ZERO), + /* InReverse */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_SRCA), + /* Out */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_OMDSTA) | AM_DST(AM_BLEND_ZERO), + /* OutReverse */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_OMSRCA), + /* Atop */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_DSTA) | AM_DST(AM_BLEND_OMSRCA), + /* AtopReverse */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_OMDSTA) | AM_DST(AM_BLEND_SRCA), + /* Xor */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_OMDSTA) | AM_DST(AM_BLEND_OMSRCA), + /* Add */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ONE) | AM_SRC(AM_BLEND_ONE), + /* no other base ops supported */ + 0, 0, 0, + /* DisjointClear */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ZERO), + /* DisjointSrc */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ONE) | AM_DST(AM_BLEND_ZERO), + /* DisjointDst */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ONE), + /* no other Disjoint ops supported */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* ConjointClear */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ZERO), + /* ConjointSrc */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ONE) | AM_DST(AM_BLEND_ZERO), + /* ConjointDst */ + AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ONE), + /* no other Conjoint ops supported */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static Bool +TDFXSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, int op, CARD16 red, + CARD16 green, CARD16 blue, CARD16 alpha, CARD32 maskFormat, + CARD32 dstFormat, CARD8 *alphaPtr, int alphaPitch, int width, int height, + int flags) +{ + TDFXPtr pTDFX = TDFXPTR(pScrn); + + if (RENDER_DEBUG) ErrorF("Alpha setup: %d %d %d %d %d %d %d %d\n", op, + red, green, blue, alpha, maskFormat, dstFormat, + flags); + + pTDFX->alphaSrc = maskFormat; + pTDFX->alphaDst = dstFormat; + pTDFX->alphaPitch = alphaPitch; + pTDFX->alphaPtr = alphaPtr; + pTDFX->alphaW = width; + pTDFX->alphaH = height; + pTDFX->alphaC = (alpha & 0xFF00) << 16 | (red & 0xFF00) << 8 | + (green & 0xFF00) | blue >> 8; + + if (!(pTDFX->alpha = TDFXBlendMode[op])) return FALSE; + + pTDFX->sync(pScrn); + + return TRUE; +} + +static void +TDFXSubsequentCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, int dstx, int dsty, + int srcx, int srcy, int width, int height) +{ + TDFXPtr pTDFX = TDFXPTR(pScrn); + /* 32bit LFB write mode */ + CARD32 *fb = (CARD32 *)(pTDFX->FbBase + pTDFX->fbOffset + + pScrn->displayWidth * 4 * dsty + + 4 * dstx); + CARD8 *db = pTDFX->alphaPtr + pTDFX->alphaW * srcy + srcx; + int x, y; + CARD32 *fdb; + CARD8 *cdb; + CARD32 colour = pTDFX->alphaC; + int dw, dh; + int w, h; + + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, pTDFX->alpha); + TDFXWriteLongMMIO(pTDFX, SST_3D_FBZMODE, FBZ_ENABLE_RGB_WRITE); + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, + LFB_WRITE_FORMAT(LFB_ARGB8888) | LFB_ENABLE_PIXEL_PIPE); + + dh = srcy; + w = pTDFX->alphaW; + h = pTDFX->alphaH; + + for (y = 0; y < height; y++) + { + cdb = db; + fdb = fb; + + dw = srcx; + for (x = 0; x < width; x++) + { + *fdb++ = (*cdb++<< 24) | colour; + if (++dw == w) + { + dw = 0; + cdb -= pTDFX->alphaW; + } + } + db += pTDFX->alphaW; + fb += pScrn->displayWidth; + if (++dh == h) + { + db = pTDFX->alphaPtr + srcx; + dh = 0; + } + } + + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, pTDFX->lfbMode); + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, AM_DISABLE); +} + +static Bool +TDFXSetupForCPUToScreenTexture(ScrnInfoPtr pScrn, int op, CARD32 srcFormat, + CARD32 dstFormat, CARD8 *texPtr, int texPitch, int width, int height, + int flags) +{ + TDFXPtr pTDFX = TDFXPTR(pScrn); + + if (RENDER_DEBUG) ErrorF("Setup: %d %x %x %d\n", op, srcFormat, dstFormat, + flags); + + pTDFX->texSrc = srcFormat; + pTDFX->texDst = dstFormat; + pTDFX->texPitch = texPitch; + pTDFX->texPtr = texPtr; + pTDFX->texW = width; + pTDFX->texH = height; + + pTDFX->sync(pScrn); + if (!(pTDFX->alpha = TDFXBlendMode[op])) return FALSE; + + return TRUE; +} + +static void +TDFXSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, int dstx, int dsty, + int srcx, int srcy, int width, int height) +{ + TDFXPtr pTDFX = TDFXPTR(pScrn); + /* 32bit LFB write mode */ + CARD32 *fb = (CARD32 *)(pTDFX->FbBase + pTDFX->fbOffset + + pScrn->displayWidth * 4 * dsty + + 4 * dstx); + CARD32 *db = ((CARD32 *)(pTDFX->texPtr)) + pTDFX->texW * srcy + srcx; + int x, y; + CARD32 *cdb, *fdb; + int dw, dh; + int w, h; + + /* cheat on Dst ops */ + if (pTDFX->alpha == + (AM_BLEND_ENABLE | AM_SRC(AM_BLEND_ZERO) | AM_DST(AM_BLEND_ONE))) + return; + + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, pTDFX->alpha); + TDFXWriteLongMMIO(pTDFX, SST_3D_FBZMODE, FBZ_ENABLE_RGB_WRITE); + + if (pTDFX->texSrc == PICT_a8r8g8b8) + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, + LFB_WRITE_FORMAT(LFB_ARGB8888) | LFB_ENABLE_PIXEL_PIPE); + else if (pTDFX->texSrc == PICT_x8r8g8b8) + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, + LFB_WRITE_FORMAT(LFB_XRGB8888) | LFB_ENABLE_PIXEL_PIPE); + else if (RENDER_DEBUG) ErrorF("BOGOFORMAT\n"); + + dh = srcy; + w = pTDFX->texW; + h = pTDFX->texH; + + /* + * Tiled software render letting hardware do the read merge + * that we don't want the CPU to do. + */ + + for (y = 0; y < height; y++) + { + cdb = db; + fdb = fb; + dw = srcx; + for (x = 0; x < width; x++) + { + *fdb++ = *cdb++; + + if (++dw == w) + { + dw = 0; + cdb -= pTDFX->texW; + } + } + db += pTDFX->texW; + fb += pScrn->displayWidth; + dh ++; + if (dh == h) + { + db = ((CARD32 *)pTDFX->texPtr) + srcx; + dh = 0; + } + } + + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, pTDFX->lfbMode); + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, AM_DISABLE); +} + +/* XXX we can add more here */ +static CARD32 TDFXTextureFormats[4] = { + PICT_a8r8g8b8, + PICT_x8r8g8b8, +/* PICT_a8, */ + 0, +}; +static CARD32 TDFXTextureDstFormats[3] = { + PICT_a8r8g8b8, + PICT_x8r8g8b8, + 0, +}; + +#endif + Bool TDFXAccelInit(ScreenPtr pScreen) { @@ -287,6 +542,26 @@ infoPtr->ScreenToScreenColorExpandFillFlags = commonFlags; #endif +#if defined(RENDER) + infoPtr->CPUToScreenAlphaTextureFlags = 0; + infoPtr->SetupForCPUToScreenAlphaTexture2 = + TDFXSetupForCPUToScreenAlphaTexture; + infoPtr->SubsequentCPUToScreenAlphaTexture = + TDFXSubsequentCPUToScreenAlphaTexture; + + infoPtr->CPUToScreenTextureFlags = 0; + infoPtr->SetupForCPUToScreenTexture2 = TDFXSetupForCPUToScreenTexture; + infoPtr->SubsequentCPUToScreenTexture = TDFXSubsequentCPUToScreenTexture; + + /* the src and dst format lists should probably be split */ + infoPtr->CPUToScreenTextureFormats = TDFXTextureFormats; + infoPtr->CPUToScreenTextureDstFormats = TDFXTextureDstFormats; + infoPtr->CPUToScreenAlphaTextureFormats = TDFXTextureFormats; + infoPtr->CPUToScreenAlphaTextureDstFormats = TDFXTextureDstFormats; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration enabled\n"); +#endif + pTDFX->PciCnt=TDFXReadLongMMIO(pTDFX, 0)&0x1F; pTDFX->PrevDrawState=pTDFX->DrawState=0; Index: tdfxdefs.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h,v retrieving revision 1.2 diff -u -r1.2 tdfxdefs.h --- tdfxdefs.h 23 Apr 2004 19:49:53 -0000 1.2 +++ tdfxdefs.h 27 Sep 2004 17:14:43 -0000 @@ -199,6 +199,8 @@ /* 3D Registers */ #define SST_3D_OFFSET 0x200000 #define SST_3D_STATUS SST_3D_OFFSET+0 +#define SST_3D_ALPHAMODE SST_3D_OFFSET+0x10C +#define SST_3D_FBZMODE SST_3D_OFFSET+0x110 #define SST_3D_LFBMODE SST_3D_OFFSET+0x114 #define SST_3D_COMMAND SST_3D_OFFSET+0x120 #define SST_3D_SWAPBUFFERCMD SST_3D_OFFSET+0x128 @@ -209,6 +211,88 @@ #define SST_3D_RIGHTOVERLAYBUF SST_3D_OFFSET+0x254 #define SST_3D_FBISWAPHISTORY SST_3D_OFFSET+0x258 +/* depth and alpha functions use the following table */ +#define SST_FUNC_NEVER 0 +#define SST_FUNC_LT 1 +#define SST_FUNC_EQ 2 +#define SST_FUNC_LE 3 +#define SST_FUNC_GT 4 +#define SST_FUNC_NE 5 +#define SST_FUNC_GE 6 +#define SST_FUNC_ALWAYS 7 + +/* SST_3D_ALPHAMODE bits */ +#define AM_DISABLE 0 +#define AM_FUNC_ENABLE (1 << 0) +#define AM_FUNC(x) (x << 1) +#define AM_BLEND_ENABLE (1 << 4) +#define AM_BLEND_ZERO 0 +#define AM_BLEND_SRCA 1 +#define AM_BLEND_COLOR 2 +#define AM_BLEND_DSTA 3 +#define AM_BLEND_ONE 4 +#define AM_BLEND_OMSRCA 5 +#define AM_BLEND_OMCOLOR 6 +#define AM_BLEND_OMDSTA 7 +#define AM_BLEND_SATURATE 0xf +#define AM_BLEND_BEFOREFOG 0xf +#define AM_SRC(x) (x << 8) +#define AM_DST(x) (x << 12) +#define AM_SRCA(x) (x << 16) +#define AM_DSTA(x) (x << 20) +#define AM_REFERENCE_ALPHA (x << 24) + +/* SST_3D_FBZMODE bits */ +#define FBZ_ENABLE_CLIPRECT (1 << 0) +#define FBZ_ENABLE_CHROMAKEY (1 << 1) +#define FBZ_ENABLE_STIPPLE_REG_MASK (1 << 2) +#define FBZ_ENABLE_W_BUFFER_SELECT (1 << 3) +#define FBZ_ENABLE_DEPTH_BUFFERING (1 << 4) +#define FBZ_DEPTH_FUNC(x) (x << 5) +#define FBZ_ENABLE_DITHERING (1 << 8) +#define FBZ_ENABLE_RGB_WRITE (1 << 9) +#define FBZ_ENABLE_ALPHA_WRITE (1 << 10) +#define FBZ_4x4_ORDERED 0 +#define FBZ_2x2_ORDERED 1 +#define FBZ_DITHER_MODE(x) (1 << 11) +#define FBZ_ENABLE_STIPPLE_MASK (1 << 12) +#define FBZ_ENABLE_ALPHA_MASK (1 << 13) +#define FBZ_ENABLE_DEPTH_BIAS (1 << 16) +#define FBZ_TOP 0 +#define FBZ_BOTTOM 1 +#define FBZ_Y_ORIGIN(x) (x << 17) +#define FBZ_ENABLE_ALPHA_PLANES (1 << 18) +#define FBZ_ENABLE_ABLEND_DITHER_SUB (1 << 19) +#define FBZ_NORMAL 0 +#define FBZ_ZACOLOR 1 +#define FBZ_DEPTH_SOURCE(x) (x << 20) +#define FBZ_ITER_W 0 +#define FBZ_ITER_Z 1 +#define FBZ_DEPTH_FLOAT_SELECT(x) (x << 21) + +/* SST_3D_LFBMODE bits */ +#define LFB_RGB565 0 +#define LFB_XRGB1555 1 +#define LFB_ARGB1555 2 +#define LFB_XRGB8888 4 +#define LFB_ARGB8888 5 +#define LFB_Z16_RGB565 12 +#define LFB_Z16_XRGB1555 13 +#define LFB_Z16_ARGB1555 14 +#define LFB_Z16_Z16 15 +#define LFB_WRITE_FORMAT(x) (x << 0) +#define LFB_ENABLE_PIXEL_PIPE (1 << 8) +#define LFB_ARGB 0 +#define LFB_ABGR 1 +#define LFB_RGBA 2 +#define LFB_BGRA 3 +#define LFB_RGBA_LANE(x) (x << 9) +#define LFB_ENABLE_WORD_SWAP (1 << 11) +#define LFB_ENABLE_BYTE_SWIZZLE (1 << 12) +#define LFB_TOP 0 +#define LFB_BOTTOM 1 +#define LFB_Y_ORIGIN(x) (x << 13) + /* NAPALM REGISTERS */ #define CFG_PCI_COMMAND 4 #define CFG_MEM0BASE 16