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

📄 gglassembler.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    SMLABB(AL, Rs, Ry, Rs, Rx);  // Rs = Rx + Ry*Rs    base_offset(parts.cbPtr, parts.cbPtr, Rs);    scratches.recycle(Rs);        // init fog    const int need_fog = GGL_READ_NEEDS(P_FOG, needs.p);    if (need_fog) {        comment("compute initial fog coordinate");        Scratch scratches(registerFile());        int dfdx = scratches.obtain();        int ydfdy = scratches.obtain();        int f = ydfdy;        CONTEXT_LOAD(dfdx,  generated_vars.dfdx);        CONTEXT_LOAD(ydfdy, iterators.ydfdy);        MLA(AL, 0, f, Rx, dfdx, ydfdy);        CONTEXT_STORE(f, generated_vars.f);    }    // init Z coordinate    if ((mDepthTest != GGL_ALWAYS) || GGL_READ_NEEDS(P_MASK_Z, needs.p)) {        parts.z = reg_t(obtainReg());        comment("compute initial Z coordinate");        Scratch scratches(registerFile());        int dzdx = scratches.obtain();        int ydzdy = parts.z.reg;        CONTEXT_LOAD(dzdx,  generated_vars.dzdx);   // 1.31 fixed-point        CONTEXT_LOAD(ydzdy, iterators.ydzdy);       // 1.31 fixed-point        MLA(AL, 0, parts.z.reg, Rx, dzdx, ydzdy);        // we're going to index zbase of parts.count        // zbase = base + (xl-count + stride*y)*2        int Rs = dzdx;        int zbase = scratches.obtain();        CONTEXT_LOAD(Rs, state.buffers.depth.stride);        CONTEXT_LOAD(zbase, state.buffers.depth.data);        SMLABB(AL, Rs, Ry, Rs, Rx);        ADD(AL, 0, Rs, Rs, reg_imm(parts.count.reg, LSR, 16));        ADD(AL, 0, zbase, zbase, reg_imm(Rs, LSL, 1));        CONTEXT_STORE(zbase, generated_vars.zbase);    }    // init texture coordinates    init_textures(parts.coords, reg_t(Rx), reg_t(Ry));    scratches.recycle(Ry);    // iterated color    init_iterated_color(parts, reg_t(Rx));    // init coverage factor application (anti-aliasing)    if (mAA) {        parts.covPtr.setTo(obtainReg(), 16);        CONTEXT_LOAD(parts.covPtr.reg, state.buffers.coverage);        ADD(AL, 0, parts.covPtr.reg, parts.covPtr.reg, reg_imm(Rx, LSL, 1));    }}// ---------------------------------------------------------------------------void GGLAssembler::build_component( pixel_t& pixel,                                    const fragment_parts_t& parts,                                    int component,                                    Scratch& regs){    static char const * comments[] = {"alpha", "red", "green", "blue"};    comment(comments[component]);    // local register file    Scratch scratches(registerFile());    const int dst_component_size = pixel.component_size(component);    component_t temp(-1);    build_incoming_component( temp, dst_component_size,            parts, component, scratches, regs);    if (mInfo[component].inDest) {        // blending...        build_blending( temp, mDstPixel, component, scratches );        // downshift component and rebuild pixel...        downshift(pixel, component, temp, parts.dither);    }}void GGLAssembler::build_incoming_component(                                    component_t& temp,                                    int dst_size,                                    const fragment_parts_t& parts,                                    int component,                                    Scratch& scratches,                                    Scratch& global_regs){    const uint32_t component_mask = 1<<component;    // Figure out what we need for the blending stage...    int fs = component==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc;    int fd = component==GGLFormat::ALPHA ? mBlendDstA : mBlendDst;    if (fs==GGL_SRC_ALPHA_SATURATE && component==GGLFormat::ALPHA) {        fs = GGL_ONE;    }    // Figure out what we need to extract and for what reason    const int blending = blending_codes(fs, fd);    // Are we actually going to blend?    const int need_blending = (fs != int(GGL_ONE)) || (fd > int(GGL_ZERO));        // expand the source if the destination has more bits    int need_expander = false;    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT-1 ; i++) {        texture_unit_t& tmu = mTextureMachine.tmu[i];        if ((tmu.format_idx) &&            (parts.texel[i].component_size(component) < dst_size)) {            need_expander = true;        }    }    // do we need to extract this component?    const bool multiTexture = mTextureMachine.activeUnits > 1;    const int blend_needs_alpha_source = (component==GGLFormat::ALPHA) &&                                        (isAlphaSourceNeeded());    int need_extract = mInfo[component].needed;    if (mInfo[component].inDest)    {        need_extract |= ((need_blending ?                (blending & (BLEND_SRC|FACTOR_SRC)) : need_expander));        need_extract |= (mTextureMachine.mask != mTextureMachine.replaced);        need_extract |= mInfo[component].smooth;        need_extract |= mInfo[component].fog;        need_extract |= mDithering;        need_extract |= multiTexture;    }    if (need_extract) {        Scratch& regs = blend_needs_alpha_source ? global_regs : scratches;        component_t fragment;        // iterated color        build_iterated_color(fragment, parts, component, regs);        // texture environement (decal, modulate, replace)        build_texture_environment(fragment, parts, component, regs);        // expand the source if the destination has more bits        if (need_expander && (fragment.size() < dst_size)) {            // we're here only if we fetched a texel            // (so we know for sure fragment is CORRUPTIBLE)            expand(fragment, fragment, dst_size);        }        // We have a few specific things to do for the alpha-channel        if ((component==GGLFormat::ALPHA) &&            (mInfo[component].needed || fragment.size()<dst_size))        {            // convert to integer_t first and make sure            // we don't corrupt a needed register            if (fragment.l) {                component_t incoming(fragment);                modify(fragment, regs);                MOV(AL, 0, fragment.reg, reg_imm(incoming.reg, LSR, incoming.l));                fragment.h -= fragment.l;                fragment.l = 0;            }            // coverage factor application            build_coverage_application(fragment, parts, regs);            // alpha-test            build_alpha_test(fragment, parts);            if (blend_needs_alpha_source) {                // We keep only 8 bits for the blending stage                const int shift = fragment.h <= 8 ? 0 : fragment.h-8;                if (fragment.flags & CORRUPTIBLE) {                    fragment.flags &= ~CORRUPTIBLE;                    mAlphaSource.setTo(fragment.reg,                            fragment.size(), fragment.flags);                    if (shift) {                        MOV(AL, 0, mAlphaSource.reg,                            reg_imm(mAlphaSource.reg, LSR, shift));                    }                } else {                    // XXX: it would better to do this in build_blend_factor()                    // so we can avoid the extra MOV below.                    mAlphaSource.setTo(regs.obtain(),                            fragment.size(), CORRUPTIBLE);                    if (shift) {                        MOV(AL, 0, mAlphaSource.reg,                            reg_imm(fragment.reg, LSR, shift));                    } else {                        MOV(AL, 0, mAlphaSource.reg, fragment.reg);                    }                }                mAlphaSource.s -= shift;            }        }        // fog...        build_fog( fragment, component, regs );        temp = fragment;    } else {        if (mInfo[component].inDest) {            // extraction not needed and replace            // we just select the right component            if ((mTextureMachine.replaced & component_mask) == 0) {                // component wasn't replaced, so use it!                temp = component_t(parts.iterated, component);            }            for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {                const texture_unit_t& tmu = mTextureMachine.tmu[i];                if ((tmu.mask & component_mask) &&                    ((tmu.replaced & component_mask) == 0)) {                    temp = component_t(parts.texel[i], component);                }            }        }    }}bool GGLAssembler::isAlphaSourceNeeded() const{    // XXX: also needed for alpha-test    const int bs = mBlendSrc;    const int bd = mBlendDst;    return  bs==GGL_SRC_ALPHA_SATURATE ||            bs==GGL_SRC_ALPHA || bs==GGL_ONE_MINUS_SRC_ALPHA ||            bd==GGL_SRC_ALPHA || bd==GGL_ONE_MINUS_SRC_ALPHA ; }// ---------------------------------------------------------------------------void GGLAssembler::build_smooth_shade(const fragment_parts_t& parts){    if (mSmooth && !parts.iterated_packed) {        // update the iterated color in a pipelined way...        comment("update iterated color");        Scratch scratches(registerFile());        const int reload = parts.reload;        for (int i=0 ; i<4 ; i++) {            if (!mInfo[i].iterated)                 continue;                            int c = parts.argb[i].reg;            int dx = parts.argb_dx[i].reg;                        if (reload & 1) {                c = scratches.obtain();                CONTEXT_LOAD(c, generated_vars.argb[i].c);            }            if (reload & 2) {                dx = scratches.obtain();                CONTEXT_LOAD(dx, generated_vars.argb[i].dx);            }                        if (mSmooth) {                ADD(AL, 0, c, c, dx);            }                        if (reload & 1) {                CONTEXT_STORE(c, generated_vars.argb[i].c);                scratches.recycle(c);            }            if (reload & 2) {                scratches.recycle(dx);            }        }    }}// ---------------------------------------------------------------------------void GGLAssembler::build_coverage_application(component_t& fragment,        const fragment_parts_t& parts, Scratch& regs){    // here fragment.l is guarenteed to be 0    if (mAA) {        // coverages are 1.15 fixed-point numbers        comment("coverage application");        component_t incoming(fragment);        modify(fragment, regs);        Scratch scratches(registerFile());        int cf = scratches.obtain();        LDRH(AL, cf, parts.covPtr.reg, immed8_post(2));        if (fragment.h > 31) {            fragment.h--;            SMULWB(AL, fragment.reg, incoming.reg, cf);        } else {            MOV(AL, 0, fragment.reg, reg_imm(incoming.reg, LSL, 1));            SMULWB(AL, fragment.reg, fragment.reg, cf);        }    }}// ---------------------------------------------------------------------------void GGLAssembler::build_alpha_test(component_t& fragment,                                    const fragment_parts_t& parts){    if (mAlphaTest != GGL_ALWAYS) {        comment("Alpha Test");        Scratch scratches(registerFile());        int ref = scratches.obtain();        const int shift = GGL_COLOR_BITS-fragment.size();        CONTEXT_LOAD(ref, state.alpha_test.ref);        if (shift) CMP(AL, fragment.reg, reg_imm(ref, LSR, shift));        else       CMP(AL, fragment.reg, ref);        int cc = NV;        switch (mAlphaTest) {        case GGL_NEVER:     cc = NV;    break;        case GGL_LESS:      cc = LT;    break;        case GGL_EQUAL:     cc = EQ;    break;        case GGL_LEQUAL:    cc = LS;    break;        case GGL_GREATER:   cc = HI;    break;        case GGL_NOTEQUAL:  cc = NE;    break;        case GGL_GEQUAL:    cc = HS;    break;        }        B(cc^1, "discard_after_textures");    }}// ---------------------------------------------------------------------------            void GGLAssembler::build_depth_test(        const fragment_parts_t& parts, uint32_t mask){    mask &= Z_TEST|Z_WRITE;    const needs_t& needs = mBuilderContext.needs;    const int zmask = GGL_READ_NEEDS(P_MASK_Z, needs.p);    Scratch scratches(registerFile());    if (mDepthTest != GGL_ALWAYS || zmask) {        int cc=AL, ic=AL;        switch (mDepthTest) {        case GGL_LESS:      ic = HI;    break;        case GGL_EQUAL:     ic = EQ;    break;        case GGL_LEQUAL:    ic = HS;    break;        case GGL_GREATER:   ic = LT;    break;        case GGL_NOTEQUAL:  ic = NE;    break;        case GGL_GEQUAL:    ic = LS;    break;        case GGL_NEVER:            // this never happens, because it's taken care of when             // computing the needs. but we keep it for completness.            comment("Depth Test (NEVER)");            B(AL, "discard_before_textures");            return;        case GGL_ALWAYS:            // we're here because zmask is enabled            mask &= ~Z_TEST;    // test always passes.            break;        }                // inverse the condition        cc = ic^1;                if ((mask & Z_WRITE) && !zmask) {            mask &= ~Z_WRITE;        }                if (!mask)            return;        comment("Depth Test");        int zbase = scratches.obtain();        int depth = scratches.obtain();        int z = parts.z.reg;                CONTEXT_LOAD(zbase, generated_vars.zbase);  // stall        SUB(AL, 0, zbase, zbase, reg_imm(parts.count.reg, LSR, 15));            // above does zbase = zbase + ((count >> 16) << 1)        if (mask & Z_TEST) {            LDRH(AL, depth, zbase);  // stall            CMP(AL, depth, reg_imm(z, LSR, 16));            B(cc, "discard_before_textures");

⌨️ 快捷键说明

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