📄 atimach64render.c
字号:
if (!mask_solid && !op_comp) MACH64_FALLBACK(("Non-solid mask.\n")); if (mask_comp && !src_solid) MACH64_FALLBACK(("Component-alpha mask.\n")); if (!mask_comp && pMaskPicture->format != PICT_a8) MACH64_FALLBACK(("Non-A8 mask.\n")); if (mask_comp && pMaskPicture->format != PICT_a8r8g8b8) MACH64_FALLBACK(("Non-ARGB mask.\n")); } return TRUE;}/* * This function setups the fragment color from a solid pixmap in the presence * of a mask. */static __inline__ BoolMach64PrepareMask( Mach64ContextRegs3D *m3d, int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PixmapPtr pSrc, PixmapPtr pMask){ Bool mask_solid, src_solid; CARD32 argb = 0; mask_solid = MACH64_PICT_IS_1x1R(pMaskPicture); src_solid = MACH64_PICT_IS_1x1R(pSrcPicture); if (mask_solid) { Mach64PixelARGB(pMask, pMaskPicture->format, &argb); argb >>= 24; argb &= 0xff; m3d->frag_mask = TRUE; m3d->frag_color = (argb << 24) | (argb << 16) | (argb << 8) | argb; return TRUE; } if (src_solid) { /* We can only handle cases where either the src color (e.g. ADD) or * the src alpha (e.g. IN_REV, OUT_REV) is used but not both. * * (ARGB8888 IN A8) OVER RGB565 is implemented as: * (ARGB8888 IN A8) ADD ((ARGB8888 IN A8) OUT_REV RGB565). */ if (op == PictOpInReverse || op == PictOpOutReverse) { Mach64PixelARGB(pSrc, pSrcPicture->format, &argb); argb >>= 24; argb &= 0xff; m3d->frag_src = TRUE; m3d->frag_color = (argb << 24) | (argb << 16) | (argb << 8) | argb; m3d->color_alpha = TRUE; return TRUE; } if (op == PictOpAdd) { Mach64PixelARGB(pSrc, pSrcPicture->format, &argb); m3d->frag_src = TRUE; m3d->frag_color = argb; return TRUE; } } return FALSE;}/* * This function setups the texturing and blending environments. It also * manipulates blend control for non-solid masks. */static void __inline__Mach64BlendCntl(Mach64ContextRegs3D *m3d, 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; if (m3d->color_alpha) { /* A8 uses RGB8 which expands to (I,I,I,0). Thus, we use the color * channels instead of the alpha channel as the alpha factor. We also * use the color channels for ARGB8888 masks with component-alpha. */ CARD32 Ad = m3d->scale_3d_cntl & MACH64_ALPHA_BLEND_DST_MASK; /* InReverse */ if (Ad == MACH64_ALPHA_BLEND_DST_SRCALPHA) { m3d->scale_3d_cntl &= ~MACH64_ALPHA_BLEND_DST_MASK; m3d->scale_3d_cntl |= MACH64_ALPHA_BLEND_DST_SRCCOLOR; } /* OutReverse */ if (Ad == MACH64_ALPHA_BLEND_DST_INVSRCALPHA) { m3d->scale_3d_cntl &= ~MACH64_ALPHA_BLEND_DST_MASK; m3d->scale_3d_cntl |= MACH64_ALPHA_BLEND_DST_INVSRCCOLOR; } } /* 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; /* Setup the texture environment */ m3d->scale_3d_cntl |= MACH64_TEX_LIGHT_FCN_MODULATE; /* Initialize texture unit */ m3d->tex_cntl |= MACH64_TEX_ST_DIRECT | MACH64_TEX_SRC_LOCAL | MACH64_TEX_UNCOMPRESSED | MACH64_TEX_CACHE_FLUSH | MACH64_TEX_CACHE_SIZE_4K;}/* * This function setups the texture unit. */static BoolMach64PrepareTexture(PicturePtr pPict, PixmapPtr pPix){ ScrnInfoPtr pScreenInfo = xf86Screens[pPix->drawable.pScreen->myNum]; ATIPtr pATI = ATIPTR(pScreenInfo); Mach64ContextRegs3D *m3d = &pATI->m3d; CARD32 texFormat; int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; int l2w, l2h, l2p, level, pitch, 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; Mach64GetOrder(w, &l2w); Mach64GetOrder(h, &l2h); Mach64GetOrder(pitch, &l2p); if (pPict->repeat && w == 1 && h == 1) l2p = 0; else if (pPict->repeat) MACH64_FALLBACK(("Repeat not supported for w,h != 1,1\n")); l2w = l2p; level = (l2w > l2h) ? l2w : l2h; m3d->tex_width = (1 << l2w); m3d->tex_height = (1 << l2h); /* Update hw state */ m3d->dp_pix_width |= SetBits(texFormat, DP_SCALE_PIX_WIDTH); m3d->tex_size_pitch = (l2w << 0) | (level << 4) | (l2h << 8); m3d->tex_offset = exaGetPixmapOffset(pPix); if (PICT_FORMAT_A(pPict->format)) m3d->scale_3d_cntl |= MACH64_TEX_MAP_AEN; switch (pPict->filter) { case PictFilterNearest: m3d->scale_3d_cntl |= MACH64_TEX_BLEND_FCN_NEAREST; break; case PictFilterBilinear: /* FIXME */#if 0 m3d->scale_3d_cntl |= MACH64_TEX_BLEND_FCN_LINEAR; m3d->scale_3d_cntl |= MACH64_BILINEAR_TEX_EN;#endif MACH64_FALLBACK(("Bilinear filter 0x%x\n", pPict->filter)); break; default: MACH64_FALLBACK(("Bad filter 0x%x\n", pPict->filter)); } m3d->transform = pPict->transform; return TRUE;}/* * PrepareComposite acceleration hook. */BoolMach64PrepareComposite( int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst){ ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum]; ATIPtr pATI = ATIPTR(pScreenInfo); Mach64ContextRegs3D *m3d = &pATI->m3d; CARD32 dstFormat; int offset, i; ATIDRISync(pScreenInfo); /* Initialize state */ 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; m3d->frag_src = FALSE; m3d->frag_mask = FALSE; m3d->frag_color = 0xffffffff; m3d->color_alpha = FALSE; m3d->transform = NULL; /* Compute state */ if (pMaskPicture && !Mach64PrepareMask(m3d, op, pSrcPicture, pMaskPicture, pSrc, pMask)) return FALSE; Mach64BlendCntl(m3d, op); 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 (!m3d->frag_src) { if (!Mach64PrepareTexture(pSrcPicture, pSrc)) return FALSE; } if (pMaskPicture && !m3d->frag_mask) { if (!Mach64PrepareTexture(pMaskPicture, pMask)) return FALSE; } offset = TEX_LEVEL(m3d->tex_size_pitch); /* Emit 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(TEX_0_OFF + offset, m3d->tex_offset); return TRUE;}/* * Vertex format, setup and emission. */typedef struct { float s0; /* normalized texture coords */ float t0; float x; /* quarter-pixels */ float y; CARD32 argb; /* fragment color */} Mach64Vertex;#define VTX_SET(_v, _col, _dstX, _dstY, _srcX, _dx, _srcY, _dy) \do { \ _v.s0 = ((float)(_srcX) + _dx) / m3d->tex_width; \ _v.t0 = ((float)(_srcY) + _dy) / m3d->tex_height; \ _v.x = ((float)(_dstX) * 4.0); \ _v.y = ((float)(_dstY) * 4.0); \ _v.argb = _col; \} 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, 6); \ 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##_ARGB, _v.argb); \ outf(VERTEX_##n##_X_Y, x_y); \} while (0)/* * Composite acceleration hook. */voidMach64Composite( 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); Mach64ContextRegs3D *m3d = &pATI->m3d; Mach64Vertex v0, v1, v2, v3; float ooa; CARD32 col; PictVector v; int srcXend, srcYend; float dxy = 0.0, dwh = 0.0; ATIDRISync(pScreenInfo); /* Disable clipping if it gets in the way */ ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1); /* Handle solid textures which come in as fragment color */ col = m3d->frag_color; if (m3d->frag_src) { srcX = maskX; srcY = maskY; } /* Handle transform */ srcXend = srcX + w; srcYend = srcY + h; if (m3d->transform) { v.vector[0] = IntToxFixed(srcX); v.vector[1] = IntToxFixed(srcY); v.vector[2] = xFixed1; PictureTransformPoint(m3d->transform, &v); srcX = xFixedToInt(v.vector[0]); srcY = xFixedToInt(v.vector[1]); v.vector[0] = IntToxFixed(srcXend); v.vector[1] = IntToxFixed(srcYend); v.vector[2] = xFixed1; PictureTransformPoint(m3d->transform, &v); srcXend = xFixedToInt(v.vector[0]); srcYend = xFixedToInt(v.vector[1]);#if 0 /* Bilinear needs manipulation of texture coordinates */ if (m3d->scale_3d_cntl & MACH64_BILINEAR_TEX_EN) { dxy = 0.5; dwh = -1.0; }#endif } /* Create vertices in clock-wise order */ VTX_SET(v0, col, dstX, dstY, srcX, dxy, srcY, dxy); VTX_SET(v1, col, dstX + w, dstY, srcXend, dwh, srcY, dxy); VTX_SET(v2, col, dstX + w, dstY + h, srcXend, dwh, srcYend, dwh); VTX_SET(v3, col, dstX, dstY + h, srcX, dxy, srcYend, dwh); /* 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, FVAL(ooa)); /* Setup lower triangle (v2, v1, v3) */ VTX_OUT(v2, 1); ooa = -ooa; outf(ONE_OVER_AREA, FVAL(ooa));}/* * DoneComposite acceleration hook. */voidMach64DoneComposite(PixmapPtr pDst){ ScrnInfoPtr pScreenInfo = xf86Screens[pDst->drawable.pScreen->myNum]; ATIPtr pATI = ATIPTR(pScreenInfo); ATIDRISync(pScreenInfo); outf(SCALE_3D_CNTL, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -