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 2 Sep 2004 04:40:03 -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 2 Sep 2004 04:40:04 -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,196 @@ } } +#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. + * + * Unlike voodoo(4), we don't have a magic 1024-wide framebuffer. + * + * XXX this is broken under DRI, we don't take a lock or dirty any state. + * it may be entirely broken anyway, i haven't done anything special for + * >16bpp and the use of ->sync() is a total guess. + */ + +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); + + pTDFX->alphaSrc = maskFormat; + pTDFX->alphaDst = dstFormat; + pTDFX->alphaPitch = alphaPitch; + pTDFX->alphaPtr = alphaPtr; + pTDFX->alphaW = width; + pTDFX->alphaH = height; + pTDFX->alphaC = (red & 0xFF00) << 8 | (green & 0xFF00) | blue >> 8; + + if(op != PictOpOver && op != PictOpSrc) + return FALSE; + + pTDFX->sync(pScrn); + if (op == PictOpSrc) + pTDFX->alpha = 0; + else + /* dst = src * srcalpha + (1-a) * dst */ + pTDFX->alpha = (1<<4) | (1<<8) | (5<<12); /* wrong for 24? */ + + return TRUE; +} + +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, 1 | (1 << 9)); + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, (1<<8) | 5); /* ARGB 888 */ + + 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 += 1024; + if (++dh == h) + { + db = pTDFX->alphaPtr + srcx; + dh = 0; + } + } + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, pTDFX->lfbMode); + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, 0); +} + +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(op != PictOpOver && op != PictOpSrc) + return FALSE; /* For now */ + + pTDFX->texSrc = srcFormat; + pTDFX->texDst = dstFormat; + pTDFX->texPitch = texPitch; + pTDFX->texPtr = texPtr; + pTDFX->texW = width; + pTDFX->texH = height; + + pTDFX->sync(pScrn); + if (op == PictOpSrc || dstFormat == PICT_x8r8g8b8) /* XXX not srcFormat? */ + pTDFX->alpha = 0; + else + pTDFX->alpha = (1<<4) | (1<<8) | (5<<12); /* wrong for 24? */ + + return TRUE; +} + +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; + + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, pTDFX->alpha); + TDFXWriteLongMMIO(pTDFX, SST_3D_FBZMODE, 1 | (1<<9)); + + if(pTDFX->texDst == PICT_a8r8g8b8) + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, (1<<8) | 5); /* ARGB888 */ + else if(pTDFX->texDst == PICT_x8r8g8b8) + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, (1<<8) | 4); /* xRGB888 */ + else 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 += 1024; + dh ++; + if (dh == h) + { + db = ((CARD32 *)pTDFX->texPtr) + srcx; + dh = 0; + } + } + TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, pTDFX->lfbMode); + TDFXWriteLongMMIO(pTDFX, SST_3D_ALPHAMODE, 0); +} + +/* XXX can we add more here? 16-bit formats, autoswizzling... */ +CARD32 TDFXAlphaTextureFormats[2] = {PICT_a8, 0}; +CARD32 TDFXTextureFormats[3] = {PICT_a8r8g8b8, PICT_x8r8g8b8, 0}; + +#endif + Bool TDFXAccelInit(ScreenPtr pScreen) { @@ -287,6 +476,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 = TDFXTextureFormats; + infoPtr->CPUToScreenAlphaTextureFormats = TDFXAlphaTextureFormats; + infoPtr->CPUToScreenAlphaTextureDstFormats = TDFXAlphaTextureFormats; + + 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 2 Sep 2004 04:40:04 -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