⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atimach64render.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -