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

📄 atimach64render.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2006 George Sapountzis * All Rights Reserved. * * Based on the mach64 DRI and DRM drivers: * Copyright 2000 Gareth Hughes * Copyright 2002-2003 Leif Delgass * All Rights Reserved. * * Based on the ati hw/kdrive driver: * Copyright 2003 Eric Anholt, Anders Carlsson * * Based on the via hw/xfree86 driver: * Copyright 2006 Thomas Hellstrom. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: *    George Sapountzis <gsap7@yahoo.gr> *//* * 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 * * In all interesting cases one of src/mask is "1x1 R". *//* * Assumptions and limitations of mach64 RENDER acceleration: * * RENDER acceleration is supported for GTPRO and later chips using the 3D * triangle setup, i.e. the VERTEX_? registers (see the dri driver). According * to atiregs.h, SCALE_3D_CNTL and TEX_?_OFF appear in GT, thus chips as old * as GT should be capable of RENDER acceleration, using the S_?_INC, T_?_INC * registers for texture mapping (see the directfb driver). * * GTPRO added a triangle setup engine and multitexturing. However, it seems * that none of the 8bpp mach64 formats expands the 8bit value to the alpha * channel in texture mapping, RGB8 appears to expand to (I,I,I,0). This makes * GTPRO multitexturing unsuitable for emulating the IN operation. Moreover, * it seems that GT/GTPRO has a muxltiplexer instead of a blender for computing * the final alpha channel which forbids destinations with an alpha channel and * generic two-pass compositing. * * A texture unit combines the fragment color (VERTEX_?_ARGB) coming in from * triangle rasterization with the texel from the texture according to the * texture environment (TEX_LIGHT_FCN_). "1x1 R" textures may come in as frag- * ment colors, eliminating the need for multitexturing in all interesting * cases (via also uses this optimization). * * Texture registers are saved/restored and cached (see atimach64.c). TEX_CNTL * cannot be cached because it flushes the texture cache. TEX_?_OFF are also * not cached because I am not sure whether writing at some offset register * affects the value at another offset. * * Vertex registers are not saved/restored. This shouldn't be a problem though * either for DRI or VT switch because vertex registers are set and used within * a signle acceleration hook. Synchronization between the DDX and DRI is based * on calling ATIDRISync() at the beginning of each DDX acceleration hook, * which suggests the assumption that individual acceleration hooks are not * interrupted. */#include <string.h>#include <stdio.h>/* * Helper functions copied from exa and via. */#if 0static voidMach64ExaCompositePictDesc(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%s",        pict->pDrawable->width,        pict->pDrawable->height,        pict->repeat ? " R" : "",        pict->componentAlpha ? " C" : ""    );    snprintf(string, n, "%-10p: fmt %s (%s)", (void *)pict->pDrawable, format, size);}static voidMach64ExaPrintComposite(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 PictOpInReverse:        sprintf(sop, "InR");        break;    case PictOpOutReverse:        sprintf(sop, "OutR");        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);}#endifstatic __inline__ CARD32viaBitExpandHelper(CARD32 component, CARD32 bits){    CARD32 tmp, mask;    mask = (1 << (8 - bits)) - 1;    tmp = component << (8 - bits);    return ((component & 1) ? tmp | mask : tmp);}static __inline__ voidMach64PixelARGB(PixmapPtr pPixmap, CARD32 format, CARD32 *argb){    CARD32 pixel;    CARD8  comp;    int    bits, shift;    /* Ensure that texture drawing has completed. */    exaWaitSync(pPixmap->drawable.pScreen);    /* exaGetPixmapFirstPixel() */    switch (pPixmap->drawable.bitsPerPixel) {    case 32:        pixel = *(CARD32 *)(pPixmap->devPrivate.ptr);        break;    case 16:        pixel = *(CARD16 *)(pPixmap->devPrivate.ptr);        break;    default:        pixel = *(CARD8 *)(pPixmap->devPrivate.ptr);        break;    }    /* exaGetRGBAFromPixel()/viaPixelARGB8888() */    switch (PICT_FORMAT_TYPE(format)) {    case PICT_TYPE_A:        shift = 0;        bits = PICT_FORMAT_A(format);        comp = (pixel >> shift) & ((1 << bits) - 1);        comp = viaBitExpandHelper(comp, bits);        *argb = comp << 24;        break;    case PICT_TYPE_ARGB:        shift = 0;        bits = PICT_FORMAT_B(format);        comp = (pixel >> shift) & ((1 << bits) - 1);        comp = viaBitExpandHelper(comp, bits);        *argb = comp;        shift += bits;        bits = PICT_FORMAT_G(format);        comp = (pixel >> shift) & ((1 << bits) - 1);        comp = viaBitExpandHelper(comp, bits);        *argb |= comp << 8;        shift += bits;        bits = PICT_FORMAT_R(format);        comp = (pixel >> shift) & ((1 << bits) - 1);        comp = viaBitExpandHelper(comp, bits);        *argb |= comp << 16;        shift += bits;        bits = PICT_FORMAT_A(format);        if (bits) {            comp = (pixel >> shift) & ((1 << bits) - 1);            comp = viaBitExpandHelper(comp, bits);        } else {            comp = 0xff;        }        *argb |= comp << 24;        break;    case PICT_TYPE_ABGR:        break;    default:        break;    }}/* * RENDER acceleration for mach64 */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, -1,                       MACH64_DATATYPE_ARGB8888},    {PICT_x8r8g8b8, MACH64_DATATYPE_ARGB8888, MACH64_DATATYPE_ARGB8888},    {PICT_a1r5g5b5, -1,                       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]))#define MACH64_PICT_IS_1x1R(_pPict)      \    ((_pPict) &&                         \     (_pPict)->pDrawable->width == 1 &&  \     (_pPict)->pDrawable->height == 1 && \     (_pPict)->repeat)/* * CheckComposite hook helper functions. */static __inline__ BoolMach64GetOrder(int val, int *shift){    *shift = 0;    while (val > (1 << *shift))        (*shift)++;    return (val == (1 << *shift));}static BoolMach64CheckTexture(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 >= 64) */    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;}/* * CheckComposite acceleration hook. */BoolMach64CheckComposite(    int        op,    PicturePtr pSrcPicture,    PicturePtr pMaskPicture,    PicturePtr pDstPicture){    Bool src_solid, mask_solid, mask_comp, op_comp;    int i;    if (op >= MACH64_NR_BLEND_OPS || !Mach64BlendOps[op].supported)        return FALSE;    if (!Mach64CheckTexture(pSrcPicture))        return FALSE;    if (pMaskPicture && !Mach64CheckTexture(pMaskPicture))        return FALSE;    /* Check destination format */    for (i = 0; i < MACH64_NR_TEX_FORMATS; i++) {        if (Mach64TexFormats[i].pictFormat == pDstPicture->format)            break;    }    if (i == MACH64_NR_TEX_FORMATS || Mach64TexFormats[i].dstFormat == -1)        MACH64_FALLBACK(("Unsupported dst format 0x%x\n",                        (int)pDstPicture->format));    /* Check that A8 src/dst appears only as "A8 ADD A8" */    if (pDstPicture->format == PICT_a8) {        if (pMaskPicture || pSrcPicture->format != PICT_a8 || op != PictOpAdd)            MACH64_FALLBACK(("A8 dst with mask or non-A8 src.\n"));    }    if (pDstPicture->format != PICT_a8) {        if (pSrcPicture->format == PICT_a8)            MACH64_FALLBACK(("A8 src with non-A8 dst.\n"));    }    /* Check that one of src/mask can come in as the fragment color. */    src_solid = MACH64_PICT_IS_1x1R(pSrcPicture);    mask_solid = MACH64_PICT_IS_1x1R(pMaskPicture);    mask_comp = pMaskPicture && pMaskPicture->componentAlpha;    op_comp = op == PictOpAdd ||              op == PictOpInReverse ||              op == PictOpOutReverse;    if (mask_solid && src_solid)        MACH64_FALLBACK(("Bad one-pixel IN composite operation.\n"));    if (pMaskPicture) {        if (!mask_solid && !src_solid)            MACH64_FALLBACK(("Multitexturing required.\n"));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -