diff --git a/src/atimach64exa.c b/src/atimach64exa.c index 8ba3e09..5b48261 100644 --- a/src/atimach64exa.c +++ b/src/atimach64exa.c @@ -384,6 +384,62 @@ ( static void Mach64DoneSolid(PixmapPtr pPixmap) { } +/* + * Memcpy-base UTS. + */ +static Bool +Mach64UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + char *dst = pDst->devPrivate.ptr; + int dst_pitch = exaGetPixmapPitch(pDst); + + int bpp = pDst->drawable.bitsPerPixel; + int cpp = (bpp + 7) / 8; + int wBytes = w * cpp; + + exaWaitSync(pDst->drawable.pScreen); + + dst += (x * cpp) + (y * dst_pitch); + + while (h--) { + memcpy(dst, src, wBytes); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +/* + * Memcpy-base DFS. + */ +static Bool +Mach64DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + char *src = pSrc->devPrivate.ptr; + int src_pitch = exaGetPixmapPitch(pSrc); + + int bpp = pSrc->drawable.bitsPerPixel; + int cpp = (bpp + 7) / 8; + int wBytes = w * cpp; + + exaWaitSync(pSrc->drawable.pScreen); + + src += (x * cpp) + (y * src_pitch); + + while (h--) { + memcpy(dst, src, wBytes); + src += src_pitch; + dst += dst_pitch; + } + + return TRUE; +} + +#include "atimach64render.c" + /* Compute log base 2 of val. */ static __inline__ int Mach64Log2(int val) { @@ -571,8 +627,10 @@ #ifdef XF86DRI_DEVEL } #endif /* XF86DRI_DEVEL */ - /* FIXME: set to 64 if that helps for hostdata blits or textures */ - /* FIXME: must be multiple of 8 pixels; 32 is ok for 16bpp, 32bpp */ + /* FIXME: + * Pitch must be multiple of 8 pixels, 32 is ok for 16bpp, 32bpp. + * What is the requirement for textures ? + */ pExa->pixmapOffsetAlign = 32; pExa->pixmapPitchAlign = 32; @@ -589,8 +647,7 @@ Bool ATIMach64ExaInit(ScreenPtr pScreen) ExaDriverPtr pExa; /* FIXME: which chips support EXA ? */ - if (pATI->Chip < ATI_CHIP_264CT) - { + if (pATI->Chip < ATI_CHIP_264CT) { xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, "EXA is not supported for ATI chips earlier than " "the ATI Mach64.\n"); @@ -617,6 +674,21 @@ Bool ATIMach64ExaInit(ScreenPtr pScreen) pExa->PrepareCopy = Mach64PrepareCopy; pExa->Copy = Mach64Copy; pExa->DoneCopy = Mach64DoneCopy; + + /* UTS/DFS hooks are beneficial for EXA, even memcpy-based */ + pExa->UploadToScreen = Mach64UploadToScreen; + pExa->DownloadFromScreen = Mach64DownloadFromScreen; + + /* FIXME: which chips support RENDER ? */ + if (pATI->Chip >= ATI_CHIP_264GTPRO) { + /* 3D Rage Pro does not support NPOT (non_power_of_two) textures */ + pExa->flags |= EXA_OFFSCREEN_ALIGN_POT; + + pExa->CheckComposite = Mach64CheckComposite; + pExa->PrepareComposite = Mach64PrepareComposite; + pExa->Composite = Mach64Composite; + pExa->DoneComposite = Mach64DoneComposite; + } if (!exaDriverInit(pScreen, pATI->pExa)) { xfree(pATI->pExa); diff --git a/src/atimach64render.c b/src/atimach64render.c new file mode 100644 index 0000000..749614a --- /dev/null +++ b/src/atimach64render.c @@ -0,0 +1,627 @@ + +/* + * Based on: + * the mach64 DRI and DRM drivers (Gareth Hughes, Leif Delgass) + * the ati/r128 kdrive driver (Eric Anholt, Anders Carlsson) + * the via xfree86 driver (Thomas Hellstrom) + * + * Author: + * George Fufutos + */ + +/* + * Interesting cases for RENDER acceleration: + * + * cursor : ARGB8888 (24x24) Over + * RGB565 + * + * glyph : A8 (9x10) Add + * A8 (420x13) + * glyph set : ARGB8888 (1x1 R) In + * A8 (420x13) Over + * RGB565 + * + * shadow : ARGB8888 (1x1 R) In + * A8 (670x362) Over + * RGB565 + * translucent : RGB565 (652x344) In + * A8 (1x1 R) Over + * RGB565 + */ + +#include +#include + +#include "atiregs3d.h" + +/* FIXME: move to pATI. */ +typedef struct { + CARD32 dp_mix; + CARD32 dp_src; + CARD32 dp_write_mask; + CARD32 dp_pix_width; + CARD32 dst_pitch_offset; + + CARD32 scale_3d_cntl; + CARD32 tex_cntl; + CARD32 tex_size_pitch; + CARD32 tex_offset; + CARD32 secondary_tex_offset; + + int width[2]; /* src/mask texture widths */ + int height[2]; /* src/mask texture heights */ +} Mach64TexState; + +static Mach64TexState _m3d; +static Mach64TexState *m3d = &_m3d; + +typedef struct { + Bool supported; + CARD32 scale_3d_cntl; +} Mach64BlendOp; + +static Mach64BlendOp Mach64BlendOps[] = { + /* Clear */ + {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_ZERO}, + /* Src */ + {1, MACH64_ALPHA_BLEND_SRC_ONE | MACH64_ALPHA_BLEND_DST_ZERO}, + /* Dst */ + {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_ONE}, + /* Over */ + {1, MACH64_ALPHA_BLEND_SRC_ONE | MACH64_ALPHA_BLEND_DST_INVSRCALPHA}, + /* OverReverse */ + {1, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_ONE}, + /* In */ + {1, MACH64_ALPHA_BLEND_SRC_DSTALPHA | MACH64_ALPHA_BLEND_DST_ZERO}, + /* InReverse */ + {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_SRCALPHA}, + /* Out */ + {1, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_ZERO}, + /* OutReverse */ + {1, MACH64_ALPHA_BLEND_SRC_ZERO | MACH64_ALPHA_BLEND_DST_INVSRCALPHA}, + /* Atop */ + {0, MACH64_ALPHA_BLEND_SRC_DSTALPHA | MACH64_ALPHA_BLEND_DST_INVSRCALPHA}, + /* AtopReverse */ + {0, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_SRCALPHA}, + /* Xor */ + {1, MACH64_ALPHA_BLEND_SRC_INVDSTALPHA | MACH64_ALPHA_BLEND_DST_INVSRCALPHA}, + /* Add */ + {1, MACH64_ALPHA_BLEND_SRC_ONE | MACH64_ALPHA_BLEND_DST_ONE} +}; + +#define MACH64_NR_BLEND_OPS \ + (sizeof(Mach64BlendOps) / sizeof(Mach64BlendOps[0])) + +typedef struct { + CARD32 pictFormat; + CARD32 dstFormat; + CARD32 texFormat; +} Mach64TexFormat; + +static Mach64TexFormat Mach64TexFormats[] = { + {PICT_a8r8g8b8, MACH64_DATATYPE_ARGB8888, MACH64_DATATYPE_ARGB8888 }, + {PICT_x8r8g8b8, MACH64_DATATYPE_ARGB8888, MACH64_DATATYPE_ARGB8888 }, + {PICT_a1r5g5b5, MACH64_DATATYPE_ARGB1555, MACH64_DATATYPE_ARGB1555 }, + {PICT_x1r5g5b5, MACH64_DATATYPE_ARGB1555, MACH64_DATATYPE_ARGB1555 }, + {PICT_r5g6b5, MACH64_DATATYPE_RGB565, MACH64_DATATYPE_RGB565 }, + {PICT_a8, MACH64_DATATYPE_RGB8, MACH64_DATATYPE_RGB8 } +}; + +#define MACH64_NR_TEX_FORMATS \ + (sizeof(Mach64TexFormats) / sizeof(Mach64TexFormats[0])) + +static void +Mach64ExaCompositePictDesc(PicturePtr pict, char *string, int n) +{ + char format[20]; + char size[20]; + + if (!pict) { + snprintf(string, n, "None"); + return; + } + + switch (pict->format) { + case PICT_x8r8g8b8: + snprintf(format, 20, "RGB8888 "); + break; + case PICT_x8b8g8r8: + snprintf(format, 20, "BGR8888 "); + break; + case PICT_a8r8g8b8: + snprintf(format, 20, "ARGB8888"); + break; + case PICT_a8b8g8r8: + snprintf(format, 20, "ABGR8888"); + 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; + } + + snprintf(size, 20, "%dx%d%s", + pict->pDrawable->width, + pict->pDrawable->height, + pict->repeat ? " R" : "" + ); + + snprintf(string, n, "%-10p: fmt %s (%s)", (void *)pict->pDrawable, format, size); +} + +static void +Mach64ExaPrintComposite(CARD8 op, + PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, char *string) +{ + char sop[20]; + char srcdesc[40], maskdesc[40], dstdesc[40]; + + switch (op) { + case PictOpSrc: + sprintf(sop, "Src"); + break; + case PictOpOver: + sprintf(sop, "Over"); + break; + case PictOpAdd: + sprintf(sop, "Add"); + break; + default: + sprintf(sop, "0x%x", (int)op); + break; + } + + Mach64ExaCompositePictDesc(pSrc, srcdesc, 40); + Mach64ExaCompositePictDesc(pMask, maskdesc, 40); + Mach64ExaCompositePictDesc(pDst, dstdesc, 40); + + sprintf(string, "op %s, \n" + " src %s\n" + " mask %s\n" + " dst %s\n", sop, srcdesc, maskdesc, dstdesc); +} + +static Bool +Mach64GetOrder(int val, int *shift) +{ + *shift = 0; + + while (val > (1 << *shift)) + (*shift)++; + + return (val == (1 << *shift)); +} + +static Bool +Mach64CheckTexture(PicturePtr pPict) +{ + int w = pPict->pDrawable->width; + int h = pPict->pDrawable->height; + int l2w, l2h, level, i; + + for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) { + if (Mach64TexFormats[i].pictFormat == pPict->format) + break; + } + + if (i == MACH64_NR_TEX_FORMATS) + MACH64_FALLBACK(("Unsupported picture format 0x%x\n", + (int)pPict->format)); + + /* l2w equals l2p (pitch) for all interesting cases (w >= 32) */ + Mach64GetOrder(w, &l2w); + Mach64GetOrder(h, &l2h); + + level = (l2w > l2h) ? l2w : l2h; + + if (level > 10) + MACH64_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h)); + + return TRUE; +} + +Bool +Mach64CheckComposite +( + int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture +) +{ + char compdesc[240]; + + if (op >= MACH64_NR_BLEND_OPS || !Mach64BlendOps[op].supported) + return FALSE; + + if (!Mach64CheckTexture(pSrcPicture)) + return FALSE; + + if (pMaskPicture && !Mach64CheckTexture(pMaskPicture)) + return FALSE; + + if (!Mach64CheckTexture(pDstPicture)) + return FALSE; + + /* It seems that none of the mach64 formats for 8bpp expands to 32bpp + * with the alpha value set. MACH64_DATATYPE_RGB8 appears to expand to + * (I,I,I,0). However, "A8 op A8" which is used in font rendering passes + * rendercheck for unknown reasons. So, let this case accelerated. + */ + if (pSrcPicture->format == PICT_a8 && pDstPicture->format != PICT_a8) + MACH64_FALLBACK(("Unsupported blending of A8 src with non-A8 dst\n")); + +#if 1 + /* FIXME: add support for masks. + * + * The current status is that enabling masks does not lock the card engine + * and does not cause artifacts outside where I expect them ... + */ + if (pMaskPicture) + return FALSE; +#endif + + if (pSrcPicture->transform) + MACH64_FALLBACK(("Unsupported transform\n")); + + if (pMaskPicture && pMaskPicture->transform) + MACH64_FALLBACK(("Unsupported transform\n")); + + if (pMaskPicture && pMaskPicture->componentAlpha) + MACH64_FALLBACK(("Unsupported componentAlpha\n")); + + if (pDstPicture->componentAlpha) + MACH64_FALLBACK(("Unsupported componentAlpha\n")); + + return TRUE; +} + +static void __inline__ Mach64BlendCntl(int op) +{ + m3d->scale_3d_cntl |= MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE | + MACH64_SCALE_DITHER_2D_TABLE | + MACH64_DITHER_INIT_RESET; + + m3d->scale_3d_cntl |= Mach64BlendOps[op].scale_3d_cntl; + + /* Can't color mask and blend at the same time */ + m3d->dp_write_mask = 0xffffffff; + + /* Can't fog and blend at the same time */ + m3d->scale_3d_cntl |= MACH64_ALPHA_FOG_EN_ALPHA; + + /* Enable texture mapping mode */ + m3d->scale_3d_cntl |= MACH64_SCALE_3D_FCN_TEXTURE; + + m3d->scale_3d_cntl |= MACH64_MIP_MAP_DISABLE; + + m3d->tex_cntl |= MACH64_TEX_ST_DIRECT | + MACH64_TEX_SRC_LOCAL | + MACH64_TEX_UNCOMPRESSED | + MACH64_TEX_CACHE_FLUSH | + MACH64_TEX_CACHE_SIZE_4K; + + m3d->scale_3d_cntl |= MACH64_TEX_LIGHT_FCN_REPLACE; +} + +static void __inline__ Mach64CompositeCntl() +{ + m3d->tex_cntl |= MACH64_TEXTURE_COMPOSITE | + MACH64_SECONDARY_STW; + + /* LOCK: + * The engine locks if I enable multitexturing with: + * MACH64_TEX_BLEND_FCN different than TRILINEAR, or + * MACH64_DATATYPE_CI8 for PICT_a8 src/mask. + */ + m3d->scale_3d_cntl |= MACH64_TEX_BLEND_FCN_TRILINEAR; + m3d->scale_3d_cntl |= MACH64_TEX_CACHE_SPLIT; + + m3d->tex_cntl |= MACH64_COMP_COMBINE_BLEND; +} + +static Bool +Mach64PrepareTexture(PicturePtr pPict, PixmapPtr pPix, int unit) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pPix->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + CARD32 texFormat; + + int w = pPict->pDrawable->width; + int h = pPict->pDrawable->height; + int l2w, l2h, l2p, level, pitch, pitchAlign, cpp, i; + + /* Prepare picture format */ + for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) { + if (Mach64TexFormats[i].pictFormat == pPict->format) + break; + } + texFormat = Mach64TexFormats[i].texFormat; + + /* Prepare picture size */ + cpp = PICT_FORMAT_BPP(pPict->format) / 8; + pitch = exaGetPixmapPitch(pPix) / cpp; + pitchAlign = pATI->pExa->pixmapPitchAlign; + + Mach64GetOrder(w, &l2w); + Mach64GetOrder(h, &l2h); + Mach64GetOrder(pitch, &l2p); + + if ((pitch & (pitch - 1)) != 0) + MACH64_FALLBACK(("Error: NPOT pitch 0x%x unsupported\n", pitch)); + + if (w >= pitchAlign && l2w != l2p) + MACH64_FALLBACK(("Error: width 0x%x != pitch 0x%x\n", w, pitch)); + + if (pPict->repeat && w == 1 && h == 1) + l2p = 0; + else if (pPict->repeat && l2p != l2w) + MACH64_FALLBACK(("Repeat not supported for pitch != width\n")); + + l2w = l2p; + + level = (l2w > l2h) ? l2w : l2h; + + m3d->width[unit] = (1 << l2w); + m3d->height[unit] = (1 << l2h); + + /* Update hw state */ + if (unit == 0) { + m3d->dp_pix_width |= SetBits(texFormat, DP_SCALE_PIX_WIDTH); + + if (PICT_FORMAT_A(pPict->format)) + m3d->scale_3d_cntl |= MACH64_TEX_MAP_AEN; + + m3d->tex_size_pitch = (l2w << 0) | + (level << 4) | + (l2h << 8); + + m3d->tex_offset = exaGetPixmapOffset(pPix); + } + else { + m3d->dp_pix_width |= SetBits(texFormat, COMPOSITE_PIX_WIDTH); + +#if 1 + if (PICT_FORMAT_A(pPict->format)) + m3d->tex_cntl |= MACH64_COMP_ALPHA; +#endif + + m3d->tex_size_pitch |= (l2w << 16) | + (level << 20) | + (l2h << 24); + + m3d->secondary_tex_offset = exaGetPixmapOffset(pPix); + } + + /* FIXME: handle filter */ + /* FIXME: handle transform */ + + return TRUE; +} + +Bool +Mach64PrepareComposite +( + int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture, + PixmapPtr pSrc, + PixmapPtr pMask, + PixmapPtr pDst +) +{ + char compdesc[240]; + ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + CARD32 dstFormat; + int offset, i; + + ATIDRISync(pScreenInfo); + +#if 0 + Mach64ExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture, compdesc); + ErrorF("Prep : %s", compdesc); +#endif + + m3d->dp_mix = SetBits(MIX_SRC, DP_BKGD_MIX) | + SetBits(MIX_SRC, DP_FRGD_MIX); + + m3d->dp_src = SetBits(SRC_SCALER_3D, DP_BKGD_SRC) | + SetBits(SRC_SCALER_3D, DP_FRGD_SRC) | + DP_MONO_SRC_ALLONES; + + Mach64GetPixmapOffsetPitch(pDst, &m3d->dst_pitch_offset); + + m3d->scale_3d_cntl = 0; + m3d->tex_cntl = 0; + + Mach64BlendCntl(op); + + if (pMaskPicture) + Mach64CompositeCntl(); + + for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) { + if (Mach64TexFormats[i].pictFormat == pDstPicture->format) + break; + } + dstFormat = Mach64TexFormats[i].dstFormat; + + m3d->dp_pix_width = SetBits(dstFormat, DP_DST_PIX_WIDTH) | + SetBits(dstFormat, DP_SRC_PIX_WIDTH) | + SetBits(dstFormat, DP_HOST_PIX_WIDTH); + + if (!Mach64PrepareTexture(pSrcPicture, pSrc, 0)) + return FALSE; + + if (pMaskPicture && !Mach64PrepareTexture(pMaskPicture, pMask, 1)) + return FALSE; + + if (!pMaskPicture) { + m3d->width[1] = 1; + m3d->height[1] = 1; + m3d->secondary_tex_offset = 0x00000000; + } + +#if 0 + ErrorF("DP_MIX %08x\n", (unsigned)m3d->dp_mix); + ErrorF("DP_SRC %08x\n", (unsigned)m3d->dp_src); + ErrorF("DP_PIX_WIDTH %08x\n", (unsigned)m3d->dp_pix_width); + ErrorF("DST_OFF_PITCH %08x\n", (unsigned)m3d->dst_pitch_offset); + + ErrorF("SCALE_3D_CNTL %08x\n", (unsigned)m3d->scale_3d_cntl); + ErrorF("TEX_SIZE_PITCH %08x\n", (unsigned)m3d->tex_size_pitch); + ErrorF("TEX_CNTL %08x\n", (unsigned)m3d->tex_cntl); + ErrorF("SEC_TEX_OFF %08x\n", (unsigned)m3d->secondary_tex_offset); + ErrorF("TEX_0_OFF %08x\n", (unsigned)m3d->tex_offset); +#endif + + /* Extract texture level from TEX_SIZE_PITCH and shift appropriately for + * addition to TEX_0_OFF. + */ + offset = (m3d->tex_size_pitch & 0xf0) >> 2; + + /* Emit hw state */ + ATIMach64WaitForFIFO(pATI, 12); + outf(DP_SRC, m3d->dp_src); + outf(DP_MIX, m3d->dp_mix); + + outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); + outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); + outf(DST_OFF_PITCH, m3d->dst_pitch_offset); + + outf(SCALE_3D_CNTL, m3d->scale_3d_cntl); + outf(DP_WRITE_MASK, m3d->dp_write_mask); + outf(DP_PIX_WIDTH, m3d->dp_pix_width); + + outf(SETUP_CNTL, 0); + + outf(TEX_SIZE_PITCH, m3d->tex_size_pitch); + outf(TEX_CNTL, m3d->tex_cntl); + outf(SECONDARY_TEX_OFFSET, m3d->secondary_tex_offset); + outf(TEX_0_OFF + offset, m3d->tex_offset); + + return TRUE; +} + +typedef struct { + float s1; + float t1; + float s0; + float t0; + float x; + float y; +} Mach64Vertex; + +#define VTX_SET(v, _dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \ +do { \ + v.s1 = ((float)(_maskX) + 0.0) / m3d->width[1]; \ + v.t1 = ((float)(_maskY) + 0.0) / m3d->height[1]; \ + v.s0 = ((float)(_srcX) + 0.0) / m3d->width[0]; \ + v.t0 = ((float)(_srcY) + 0.0) / m3d->height[0]; \ + v.x = ((float)(_dstX) * 4.0); \ + v.y = ((float)(_dstY) * 4.0); \ +} while (0) + +#define FVAL(_fval) (*(CARD32 *)&(_fval)) + +#define VTX_OUT(v, n) \ +do { \ + float w = 1.0; \ + CARD32 z = 0xffff << 15; \ + CARD32 x_y = ((CARD16)v.x << 16) | \ + ((CARD16)v.y & 0xffff); \ + \ + ATIMach64WaitForFIFO(pATI, 8); \ + outf(VERTEX_##n##_SECONDARY_S, FVAL(v.s1)); \ + outf(VERTEX_##n##_SECONDARY_T, FVAL(v.t1)); \ + outf(VERTEX_##n##_SECONDARY_W, FVAL(w)); \ + \ + outf(VERTEX_##n##_S, FVAL(v.s0)); \ + outf(VERTEX_##n##_T, FVAL(v.t0)); \ + outf(VERTEX_##n##_W, FVAL(w)); \ + \ + outf(VERTEX_##n##_Z, z); \ + outf(VERTEX_##n##_X_Y, x_y); \ +} while (0) + +void +Mach64Composite +( + PixmapPtr pDst, + int srcX, + int srcY, + int maskX, + int maskY, + int dstX, + int dstY, + int w, + int h +) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + Mach64Vertex v0, v1, v2, v3; + float ooa; + + ATIDRISync(pScreenInfo); + +#if 0 + ErrorF("dst (%3d,%3d) (%3d,%3d)\n", dstX, dstY, w, h); + ErrorF("src (%3d,%3d) (%3d,%3d)\n", srcX, srcY, w, h); + if (m3d->secondary_tex_offset) { + ErrorF("mask (%3d,%3d) (%3d,%3d)\n", maskX, maskY, w, h); + } +#endif + + /* Disable clipping if it gets in the way */ + ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1); + + VTX_SET(v0, dstX, dstY, srcX, srcY, maskX, maskY); + VTX_SET(v1, dstX + w, dstY, srcX + w, srcY, maskX + w, maskY); + VTX_SET(v2, dstX + w, dstY + h, srcX + w, srcY + h, maskX + w, maskY + h); + VTX_SET(v3, dstX, dstY + h, srcX, srcY + h, maskX, maskY + h); + + /* Setup upper triangle (v0, v1, v3) */ + VTX_OUT(v0, 1); + VTX_OUT(v1, 2); + VTX_OUT(v3, 3); + + ooa = 1.0 / (w * h); + outf(ONE_OVER_AREA, *(CARD32 *)&ooa); + + /* Setup lower triangle (v2, v1, v3) */ + VTX_OUT(v2, 1); + + ooa = -ooa; + outf(ONE_OVER_AREA, *(CARD32 *)&ooa); +} + +void +Mach64DoneComposite(PixmapPtr pDst) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + ATIDRISync(pScreenInfo); + + /* FIXME: add these registers to ATIHWRec and ATIMach64Sync. */ + ATIMach64WaitForFIFO(pATI, 3); + outf( ALPHA_TST_CNTL, 0 ); + outf( Z_CNTL, 0 ); + outf( SCALE_3D_CNTL, 0 ); +} diff --git a/src/atiregs3d.h b/src/atiregs3d.h new file mode 100644 index 0000000..e8279d3 --- /dev/null +++ b/src/atiregs3d.h @@ -0,0 +1,162 @@ + +/* + * Register values (from Mach64 DRI driver). + */ + +/* SCALE_3D_CNTL */ + +#define MACH64_SCALE_PIX_EXPAND_ZERO_EXTEND (0 << 0) +#define MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE (1 << 0) +#define MACH64_SCALE_DITHER_ERROR_DIFFUSE (0 << 1) +#define MACH64_SCALE_DITHER_2D_TABLE (1 << 1) +#define MACH64_DITHER_EN (1 << 2) +#define MACH64_DITHER_INIT_CURRENT (O << 3) +#define MACH64_DITHER_INIT_RESET (1 << 3) +#define MACH64_ROUND_EN (1 << 4) + +#define MACH64_TEX_CACHE_DIS (1 << 5) + +#define MACH64_SCALE_3D_FCN_MASK (3 << 6) +#define MACH64_SCALE_3D_FCN_NOP (0 << 6) +#define MACH64_SCALE_3D_FCN_SCALE (1 << 6) +#define MACH64_SCALE_3D_FCN_TEXTURE (2 << 6) +#define MACH64_SCALE_3D_FCN_SHADE (3 << 6) +#define MACH64_TEXTURE_DISABLE (1 << 6) + +#define MACH64_EDGE_ANTI_ALIAS (1 << 8) +#define MACH64_TEX_CACHE_SPLIT (1 << 9) +#define MACH64_APPLE_YUV_MODE (1 << 10) + +#define MACH64_ALPHA_FOG_EN_MASK (3 << 11) +#define MACH64_ALPHA_FOG_DIS (0 << 11) +#define MACH64_ALPHA_FOG_EN_ALPHA (1 << 11) +#define MACH64_ALPHA_FOG_EN_FOG (2 << 11) + +#define MACH64_ALPHA_BLEND_SAT (1 << 13) +#define MACH64_RED_DITHER_MAX (1 << 14) +#define MACH64_SIGNED_DST_CLAMP (1 << 15) + +#define MACH64_ALPHA_BLEND_SRC_MASK (7 << 16) +#define MACH64_ALPHA_BLEND_SRC_ZERO (0 << 16) +#define MACH64_ALPHA_BLEND_SRC_ONE (1 << 16) +#define MACH64_ALPHA_BLEND_SRC_DSTCOLOR (2 << 16) +#define MACH64_ALPHA_BLEND_SRC_INVDSTCOLOR (3 << 16) +#define MACH64_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +#define MACH64_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +#define MACH64_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) +#define MACH64_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) +#define MACH64_ALPHA_BLEND_DST_MASK (7 << 19) +#define MACH64_ALPHA_BLEND_DST_ZERO (0 << 19) +#define MACH64_ALPHA_BLEND_DST_ONE (1 << 19) +#define MACH64_ALPHA_BLEND_DST_SRCCOLOR (2 << 19) +#define MACH64_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 19) +#define MACH64_ALPHA_BLEND_DST_SRCALPHA (4 << 19) +#define MACH64_ALPHA_BLEND_DST_INVSRCALPHA (5 << 19) +#define MACH64_ALPHA_BLEND_DST_DSTALPHA (6 << 19) +#define MACH64_ALPHA_BLEND_DST_INVDSTALPHA (7 << 19) + +#define MACH64_TEX_LIGHT_FCN_MASK (3 << 22) +#define MACH64_TEX_LIGHT_FCN_REPLACE (0 << 22) +#define MACH64_TEX_LIGHT_FCN_MODULATE (1 << 22) +#define MACH64_TEX_LIGHT_FCN_ALPHA_DECAL (2 << 22) + +#define MACH64_MIP_MAP_DISABLE (1 << 24) +#define MACH64_BILINEAR_TEX_EN (1 << 25) + +#define MACH64_TEX_BLEND_FCN_MASK (3 << 26) +#define MACH64_TEX_BLEND_FCN_NEAREST (0 << 26) +#define MACH64_TEX_BLEND_FCN_LINEAR (2 << 26) +#define MACH64_TEX_BLEND_FCN_TRILINEAR (3 << 26) + +#define MACH64_TEX_AMASK_AEN (1 << 28) +#define MACH64_TEX_AMASK_BLEND_EDGE (1 << 29) +#define MACH64_TEX_MAP_AEN (1 << 30) +#define MACH64_SRC_3D_HOST_FIFO (1 << 31) + +/* TEX_CNTL */ + +#define MACH64_LOD_BIAS_SHIFT 0 +#define MACH64_LOD_BIAS_MASK (0xf << 0) +#define MACH64_COMP_FACTOR_SHIFT 4 +#define MACH64_COMP_FACTOR_MASK (0xf << 4) + +#define MACH64_TEXTURE_COMPOSITE (1 << 8) + +#define MACH64_COMP_COMBINE_BLEND (0 << 9) +#define MACH64_COMP_COMBINE_MODULATE (1 << 9) +#define MACH64_COMP_BLEND_NEAREST (0 << 11) +#define MACH64_COMP_BLEND_BILINEAR (1 << 11) +#define MACH64_COMP_FILTER_NEAREST (0 << 12) +#define MACH64_COMP_FILTER_BILINEAR (1 << 12) +#define MACH64_COMP_ALPHA (1 << 13) + +#define MACH64_TEXTURE_TILING (1 << 14) +#define MACH64_COMPOSITE_TEX_TILING (1 << 15) +#define MACH64_TEX_COLLISION_DISABLE (1 << 16) + +#define MACH64_TEXTURE_CLAMP_S (1 << 17) +#define MACH64_TEXTURE_CLAMP_T (1 << 18) +#define MACH64_TEX_ST_MULT_W (0 << 19) +#define MACH64_TEX_ST_DIRECT (1 << 19) +#define MACH64_TEX_SRC_LOCAL (0 << 20) +#define MACH64_TEX_SRC_AGP (1 << 20) +#define MACH64_TEX_UNCOMPRESSED (0 << 21) +#define MACH64_TEX_VQ_COMPRESSED (1 << 21) +#define MACH64_COMP_TEX_UNCOMPRESSED (0 << 22) +#define MACH64_COMP_TEX_VQ_COMPRESSED (1 << 22) +#define MACH64_TEX_CACHE_FLUSH (1 << 23) +#define MACH64_SEC_TEX_CLAMP_S (1 << 24) +#define MACH64_SEC_TEX_CLAMP_T (1 << 25) +#define MACH64_TEX_WRAP_S (1 << 28) +#define MACH64_TEX_WRAP_T (1 << 29) +#define MACH64_TEX_CACHE_SIZE_4K (1 << 30) +#define MACH64_TEX_CACHE_SIZE_2K (1 << 30) +#define MACH64_SECONDARY_STW (1 << 31) + +/* MACH64_ALPHA_TST_CNTL */ + +#define MACH64_ALPHA_TEST_EN (1 << 0) +#define MACH64_ALPHA_TEST_MASK (7 << 4) +#define MACH64_ALPHA_TEST_NEVER (0 << 4) +#define MACH64_ALPHA_TEST_LESS (1 << 4) +#define MACH64_ALPHA_TEST_LEQUAL (2 << 4) +#define MACH64_ALPHA_TEST_EQUAL (3 << 4) +#define MACH64_ALPHA_TEST_GEQUAL (4 << 4) +#define MACH64_ALPHA_TEST_GREATER (5 << 4) +#define MACH64_ALPHA_TEST_NOTEQUAL (6 << 4) +#define MACH64_ALPHA_TEST_ALWAYS (7 << 4) + +#define MACH64_ALPHA_MOD_MSB (1 << 7) + +#define MACH64_ALPHA_DST_MASK (7 << 8) +#define MACH64_ALPHA_DST_ZERO (0 << 8) +#define MACH64_ALPHA_DST_ONE (1 << 8) +#define MACH64_ALPHA_DST_SRCALPHA (4 << 8) +#define MACH64_ALPHA_DST_INVSRCALPHA (5 << 8) +#define MACH64_ALPHA_DST_DSTALPHA (6 << 8) +#define MACH64_ALPHA_DST_INVDSTALPHA (7 << 8) + +#define MACH64_ALPHA_TST_SRC_TEXEL (0 << 12) +#define MACH64_ALPHA_TST_SRC_SRCALPHA (1 << 12) + +#define MACH64_REF_ALPHA_MASK (0xff << 16) +#define MACH64_REF_ALPHA_SHIFT 16 +#define MACH64_COMPOSITE_SHADOW (1 << 30) +#define MACH64_SPECULAR_LIGHT_EN (1 << 31) + +/* FIXME: these must be added as PIX_WIDTH_XXX */ + +/* DP_PIX_WIDTH */ + +#define MACH64_DATATYPE_CI8 2 +#define MACH64_DATATYPE_ARGB1555 3 +#define MACH64_DATATYPE_RGB565 4 +#define MACH64_DATATYPE_ARGB8888 6 +#define MACH64_DATATYPE_RGB332 7 +#define MACH64_DATATYPE_Y8 8 +#define MACH64_DATATYPE_RGB8 9 +#define MACH64_DATATYPE_VYUY422 11 +#define MACH64_DATATYPE_YVYU422 12 +#define MACH64_DATATYPE_AYUV444 14 +#define MACH64_DATATYPE_ARGB4444 15 +