GGLAssembler.cpp revision 01dda204cd28fe181691b4a44a51be7e5666d0c8
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/codeflinger/GGLAssembler.cpp
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License.
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_TAG "GGLAssembler"
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdint.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/log.h>
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "codeflinger/GGLAssembler.h"
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLAssembler::GGLAssembler(ARMAssemblerInterface* target)
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    : ARMAssemblerProxy(target), RegisterAllocator(), mOptLevel(7)
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLAssembler::~GGLAssembler()
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::prolog()
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ARMAssemblerProxy::prolog();
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::epilog(uint32_t touched)
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ARMAssemblerProxy::epilog(touched);
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::reset(int opt_level)
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ARMAssemblerProxy::reset();
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    RegisterAllocator::reset();
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mOptLevel = opt_level;
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint GGLAssembler::scanline(const needs_t& needs, context_t const* c)
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int err = 0;
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int opt_level = mOptLevel;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (opt_level >= 0) {
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        reset(opt_level);
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        err = scanline_core(needs, c);
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (err == 0)
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        opt_level--;
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: in theory, pcForLabel is not valid before generate()
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t* fragment_start_pc = pcForLabel("fragment_loop");
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t* fragment_end_pc = pcForLabel("epilog");
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int per_fragment_ops = int(fragment_end_pc - fragment_start_pc);
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // build a name for our pipeline
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char name[64];
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sprintf(name,
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "scanline__%08X:%08X_%08X_%08X [%3d ipp]",
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            needs.p, needs.n, needs.t[0], needs.t[1], per_fragment_ops);
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (err) {
8501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block        ALOGE("Error while generating ""%s""\n", name);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        disassemble(name);
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return generate(name);
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint GGLAssembler::scanline_core(const needs_t& needs, context_t const* c)
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int64_t duration = ggl_system_time();
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBlendFactorCached = 0;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBlending = 0;
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mMasking = 0;
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mAA        = GGL_READ_NEEDS(P_AA, needs.p);
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mDithering = GGL_READ_NEEDS(P_DITHER, needs.p);
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mAlphaTest = GGL_READ_NEEDS(P_ALPHA_TEST, needs.p) + GGL_NEVER;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mDepthTest = GGL_READ_NEEDS(P_DEPTH_TEST, needs.p) + GGL_NEVER;
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mFog       = GGL_READ_NEEDS(P_FOG, needs.p) != 0;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mSmooth    = GGL_READ_NEEDS(SHADE, needs.n) != 0;
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBuilderContext.needs = needs;
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBuilderContext.c = c;
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBuilderContext.Rctx = reserveReg(R0); // context always in R0
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mCbFormat = c->formats[ GGL_READ_NEEDS(CB_FORMAT, needs.n) ];
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // ------------------------------------------------------------------------
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    decodeLogicOpNeeds(needs);
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    decodeTMUNeeds(needs, c);
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBlendSrc  = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_SRC, needs.n));
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBlendDst  = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_DST, needs.n));
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBlendSrcA = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_SRCA, needs.n));
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mBlendDstA = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_DSTA, needs.n));
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!mCbFormat.c[GGLFormat::ALPHA].h) {
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((mBlendSrc == GGL_ONE_MINUS_DST_ALPHA) ||
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (mBlendSrc == GGL_DST_ALPHA)) {
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mBlendSrc = GGL_ONE;
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((mBlendSrcA == GGL_ONE_MINUS_DST_ALPHA) ||
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (mBlendSrcA == GGL_DST_ALPHA)) {
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mBlendSrcA = GGL_ONE;
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((mBlendDst == GGL_ONE_MINUS_DST_ALPHA) ||
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (mBlendDst == GGL_DST_ALPHA)) {
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mBlendDst = GGL_ONE;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((mBlendDstA == GGL_ONE_MINUS_DST_ALPHA) ||
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (mBlendDstA == GGL_DST_ALPHA)) {
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mBlendDstA = GGL_ONE;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // if we need the framebuffer, read it now
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int blending =    blending_codes(mBlendSrc, mBlendDst) |
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            blending_codes(mBlendSrcA, mBlendDstA);
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: handle special cases, destination not modified...
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((mBlendSrc==GGL_ZERO) && (mBlendSrcA==GGL_ZERO) &&
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        (mBlendDst==GGL_ONE) && (mBlendDstA==GGL_ONE)) {
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Destination unmodified (beware of logic ops)
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if ((mBlendSrc==GGL_ZERO) && (mBlendSrcA==GGL_ZERO) &&
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        (mBlendDst==GGL_ZERO) && (mBlendDstA==GGL_ZERO)) {
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Destination is zero (beware of logic ops)
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fbComponents = 0;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int masking = GGL_READ_NEEDS(MASK_ARGB, needs.n);
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<4 ; i++) {
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int mask = 1<<i;
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        component_info_t& info = mInfo[i];
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int fs = i==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int fd = i==GGLFormat::ALPHA ? mBlendDstA : mBlendDst;
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (fs==GGL_SRC_ALPHA_SATURATE && i==GGLFormat::ALPHA)
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fs = GGL_ONE;
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.masked =   !!(masking & mask);
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.inDest =   !info.masked && mCbFormat.c[i].h &&
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        ((mLogicOp & LOGIC_OP_SRC) || (!mLogicOp));
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mCbFormat.components >= GGL_LUMINANCE &&
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (i==GGLFormat::GREEN || i==GGLFormat::BLUE)) {
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            info.inDest = false;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.needed =   (i==GGLFormat::ALPHA) &&
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        (isAlphaSourceNeeded() || mAlphaTest != GGL_ALWAYS);
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.replaced = !!(mTextureMachine.replaced & mask);
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.iterated = (!info.replaced && (info.inDest || info.needed));
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.smooth =   mSmooth && info.iterated;
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.fog =      mFog && info.inDest && (i != GGLFormat::ALPHA);
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.blend =    (fs != int(GGL_ONE)) || (fd > int(GGL_ZERO));
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mBlending |= (info.blend ? mask : 0);
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mMasking |= (mCbFormat.c[i].h && info.masked) ? mask : 0;
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fbComponents |= mCbFormat.c[i].h ? mask : 0;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mAllMasked = (mMasking == fbComponents);
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mAllMasked) {
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mDithering = 0;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fragment_parts_t parts;
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // ------------------------------------------------------------------------
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    prolog();
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // ------------------------------------------------------------------------
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    build_scanline_prolog(parts, needs);
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (registerFile().status())
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return registerFile().status();
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // ------------------------------------------------------------------------
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    label("fragment_loop");
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // ------------------------------------------------------------------------
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch regs(registerFile());
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mDithering) {
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // update the dither index.
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, parts.count.reg,
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    reg_imm(parts.count.reg, ROR, GGL_DITHER_ORDER_SHIFT));
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, parts.count.reg, parts.count.reg,
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    imm( 1 << (32 - GGL_DITHER_ORDER_SHIFT)));
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, parts.count.reg,
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    reg_imm(parts.count.reg, ROR, 32 - GGL_DITHER_ORDER_SHIFT));
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // XXX: could we do an early alpha-test here in some cases?
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // It would probaly be used only with smooth-alpha and no texture
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // (or no alpha component in the texture).
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Early z-test
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mAlphaTest==GGL_ALWAYS) {
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_depth_test(parts, Z_TEST|Z_WRITE);
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // we cannot do the z-write here, because
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // it might be killed by the alpha-test later
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_depth_test(parts, Z_TEST);
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        { // texture coordinates
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            Scratch scratches(registerFile());
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // texel generation
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_textures(parts, regs);
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((blending & (FACTOR_DST|BLEND_DST)) ||
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (mMasking && !mAllMasked) ||
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (mLogicOp & LOGIC_OP_DST))
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        {
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // blending / logic_op / masking need the framebuffer
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mDstPixel.setTo(regs.obtain(), &mCbFormat);
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // load the framebuffer pixel
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            comment("fetch color-buffer");
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            load(parts.cbPtr, mDstPixel);
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (registerFile().status())
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return registerFile().status();
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel_t pixel;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int directTex = mTextureMachine.directTexture;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (directTex | parts.packed) {
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // note: we can't have both here
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // iterated color or direct texture
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pixel = directTex ? parts.texel[directTex-1] : parts.iterated;
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pixel.flags &= ~CORRUPTIBLE;
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (mDithering) {
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const int ctxtReg = mBuilderContext.Rctx;
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const int mask = GGL_DITHER_SIZE-1;
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                parts.dither = reg_t(regs.obtain());
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                AND(AL, 0, parts.dither.reg, parts.count.reg, imm(mask));
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ADD(AL, 0, parts.dither.reg, parts.dither.reg, ctxtReg);
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                LDRB(AL, parts.dither.reg, parts.dither.reg,
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        immed12_pre(GGL_OFFSETOF(ditherMatrix)));
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // allocate a register for the resulting pixel
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pixel.setTo(regs.obtain(), &mCbFormat, FIRST);
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_component(pixel, parts, GGLFormat::ALPHA,    regs);
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (mAlphaTest!=GGL_ALWAYS) {
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // only handle the z-write part here. We know z-test
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // was successful, as well as alpha-test.
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                build_depth_test(parts, Z_WRITE);
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_component(pixel, parts, GGLFormat::RED,      regs);
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_component(pixel, parts, GGLFormat::GREEN,    regs);
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_component(pixel, parts, GGLFormat::BLUE,     regs);
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pixel.flags |= CORRUPTIBLE;
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (registerFile().status())
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return registerFile().status();
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (pixel.reg == -1) {
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // be defensive here. if we're here it's probably
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // that this whole fragment is a no-op.
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pixel = mDstPixel;
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!mAllMasked) {
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // logic operation
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_logic_op(pixel, regs);
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // masking
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_masking(pixel, regs);
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            comment("store");
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            store(parts.cbPtr, pixel, WRITE_BACK);
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (registerFile().status())
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return registerFile().status();
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // update the iterated color...
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (parts.reload != 3) {
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_smooth_shade(parts);
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // update iterated z
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    build_iterate_z(parts);
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // update iterated fog
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    build_iterate_f(parts);
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SUB(AL, S, parts.count.reg, parts.count.reg, imm(1<<16));
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    B(PL, "fragment_loop");
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    label("epilog");
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    epilog(registerFile().touched());
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((mAlphaTest!=GGL_ALWAYS) || (mDepthTest!=GGL_ALWAYS)) {
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mDepthTest!=GGL_ALWAYS) {
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            label("discard_before_textures");
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_iterate_texture_coordinates(parts);
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        label("discard_after_textures");
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_smooth_shade(parts);
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_iterate_z(parts);
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_iterate_f(parts);
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!mAllMasked) {
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, parts.cbPtr.reg, parts.cbPtr.reg, imm(parts.cbPtr.size>>3));
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SUB(AL, S, parts.count.reg, parts.count.reg, imm(1<<16));
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        B(PL, "fragment_loop");
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        epilog(registerFile().touched());
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return registerFile().status();
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_scanline_prolog(
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fragment_parts_t& parts, const needs_t& needs)
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    Scratch scratches(registerFile());
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int Rctx = mBuilderContext.Rctx;
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // compute count
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    comment("compute ct (# of pixels to process)");
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    parts.count.setTo(obtainReg());
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int Rx = scratches.obtain();
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int Ry = scratches.obtain();
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CONTEXT_LOAD(Rx, iterators.xl);
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CONTEXT_LOAD(parts.count.reg, iterators.xr);
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CONTEXT_LOAD(Ry, iterators.y);
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // parts.count = iterators.xr - Rx
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SUB(AL, 0, parts.count.reg, parts.count.reg, Rx);
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SUB(AL, 0, parts.count.reg, parts.count.reg, imm(1));
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mDithering) {
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // parts.count.reg = 0xNNNNXXDD
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // NNNN = count-1
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // DD   = dither offset
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // XX   = 0xxxxxxx (x = garbage)
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int tx = scratches.obtain();
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ty = scratches.obtain();
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        AND(AL, 0, tx, Rx, imm(GGL_DITHER_MASK));
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        AND(AL, 0, ty, Ry, imm(GGL_DITHER_MASK));
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, tx, tx, reg_imm(ty, LSL, GGL_DITHER_ORDER_SHIFT));
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ORR(AL, 0, parts.count.reg, tx, reg_imm(parts.count.reg, LSL, 16));
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // parts.count.reg = 0xNNNN0000
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // NNNN = count-1
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV(AL, 0, parts.count.reg, reg_imm(parts.count.reg, LSL, 16));
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!mAllMasked) {
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // compute dst ptr
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("compute color-buffer pointer");
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int cb_bits = mCbFormat.size*8;
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int Rs = scratches.obtain();
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parts.cbPtr.setTo(obtainReg(), cb_bits);
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(Rs, state.buffers.color.stride);
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(parts.cbPtr.reg, state.buffers.color.data);
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SMLABB(AL, Rs, Ry, Rs, Rx);  // Rs = Rx + Ry*Rs
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        base_offset(parts.cbPtr, parts.cbPtr, Rs);
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        scratches.recycle(Rs);
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // init fog
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int need_fog = GGL_READ_NEEDS(P_FOG, needs.p);
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (need_fog) {
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("compute initial fog coordinate");
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int dfdx = scratches.obtain();
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ydfdy = scratches.obtain();
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int f = ydfdy;
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(dfdx,  generated_vars.dfdx);
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(ydfdy, iterators.ydfdy);
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MLA(AL, 0, f, Rx, dfdx, ydfdy);
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_STORE(f, generated_vars.f);
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // init Z coordinate
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((mDepthTest != GGL_ALWAYS) || GGL_READ_NEEDS(P_MASK_Z, needs.p)) {
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parts.z = reg_t(obtainReg());
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("compute initial Z coordinate");
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int dzdx = scratches.obtain();
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ydzdy = parts.z.reg;
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(dzdx,  generated_vars.dzdx);   // 1.31 fixed-point
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(ydzdy, iterators.ydzdy);       // 1.31 fixed-point
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MLA(AL, 0, parts.z.reg, Rx, dzdx, ydzdy);
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // we're going to index zbase of parts.count
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // zbase = base + (xl-count + stride*y)*2
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int Rs = dzdx;
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int zbase = scratches.obtain();
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(Rs, state.buffers.depth.stride);
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(zbase, state.buffers.depth.data);
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SMLABB(AL, Rs, Ry, Rs, Rx);
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, Rs, Rs, reg_imm(parts.count.reg, LSR, 16));
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, zbase, zbase, reg_imm(Rs, LSL, 1));
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_STORE(zbase, generated_vars.zbase);
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // init texture coordinates
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    init_textures(parts.coords, reg_t(Rx), reg_t(Ry));
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    scratches.recycle(Ry);
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // iterated color
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    init_iterated_color(parts, reg_t(Rx));
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // init coverage factor application (anti-aliasing)
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mAA) {
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        parts.covPtr.setTo(obtainReg(), 16);
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(parts.covPtr.reg, state.buffers.coverage);
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, parts.covPtr.reg, parts.covPtr.reg, reg_imm(Rx, LSL, 1));
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_component( pixel_t& pixel,
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    const fragment_parts_t& parts,
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    int component,
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    Scratch& regs)
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    static char const * comments[] = {"alpha", "red", "green", "blue"};
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    comment(comments[component]);
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // local register file
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    Scratch scratches(registerFile());
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int dst_component_size = pixel.component_size(component);
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    component_t temp(-1);
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    build_incoming_component( temp, dst_component_size,
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            parts, component, scratches, regs);
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mInfo[component].inDest) {
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // blending...
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_blending( temp, mDstPixel, component, scratches );
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // downshift component and rebuild pixel...
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        downshift(pixel, component, temp, parts.dither);
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_incoming_component(
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    component_t& temp,
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    int dst_size,
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    const fragment_parts_t& parts,
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    int component,
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    Scratch& scratches,
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    Scratch& global_regs)
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint32_t component_mask = 1<<component;
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Figure out what we need for the blending stage...
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fs = component==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc;
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd = component==GGLFormat::ALPHA ? mBlendDstA : mBlendDst;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fs==GGL_SRC_ALPHA_SATURATE && component==GGLFormat::ALPHA) {
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fs = GGL_ONE;
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Figure out what we need to extract and for what reason
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int blending = blending_codes(fs, fd);
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Are we actually going to blend?
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int need_blending = (fs != int(GGL_ONE)) || (fd > int(GGL_ZERO));
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // expand the source if the destination has more bits
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int need_expander = false;
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT-1 ; i++) {
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texture_unit_t& tmu = mTextureMachine.tmu[i];
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((tmu.format_idx) &&
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (parts.texel[i].component_size(component) < dst_size)) {
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            need_expander = true;
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // do we need to extract this component?
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const bool multiTexture = mTextureMachine.activeUnits > 1;
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int blend_needs_alpha_source = (component==GGLFormat::ALPHA) &&
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                        (isAlphaSourceNeeded());
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int need_extract = mInfo[component].needed;
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mInfo[component].inDest)
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        need_extract |= ((need_blending ?
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (blending & (BLEND_SRC|FACTOR_SRC)) : need_expander));
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        need_extract |= (mTextureMachine.mask != mTextureMachine.replaced);
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        need_extract |= mInfo[component].smooth;
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        need_extract |= mInfo[component].fog;
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        need_extract |= mDithering;
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        need_extract |= multiTexture;
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (need_extract) {
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch& regs = blend_needs_alpha_source ? global_regs : scratches;
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        component_t fragment;
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // iterated color
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_iterated_color(fragment, parts, component, regs);
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // texture environement (decal, modulate, replace)
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_texture_environment(fragment, parts, component, regs);
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // expand the source if the destination has more bits
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (need_expander && (fragment.size() < dst_size)) {
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // we're here only if we fetched a texel
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // (so we know for sure fragment is CORRUPTIBLE)
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            expand(fragment, fragment, dst_size);
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // We have a few specific things to do for the alpha-channel
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((component==GGLFormat::ALPHA) &&
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            (mInfo[component].needed || fragment.size()<dst_size))
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        {
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // convert to integer_t first and make sure
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // we don't corrupt a needed register
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (fragment.l) {
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                component_t incoming(fragment);
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                modify(fragment, regs);
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                MOV(AL, 0, fragment.reg, reg_imm(incoming.reg, LSR, incoming.l));
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fragment.h -= fragment.l;
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fragment.l = 0;
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // coverage factor application
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_coverage_application(fragment, parts, regs);
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // alpha-test
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_alpha_test(fragment, parts);
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (blend_needs_alpha_source) {
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // We keep only 8 bits for the blending stage
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const int shift = fragment.h <= 8 ? 0 : fragment.h-8;
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (fragment.flags & CORRUPTIBLE) {
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    fragment.flags &= ~CORRUPTIBLE;
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    mAlphaSource.setTo(fragment.reg,
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            fragment.size(), fragment.flags);
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if (shift) {
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        MOV(AL, 0, mAlphaSource.reg,
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            reg_imm(mAlphaSource.reg, LSR, shift));
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } else {
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    // XXX: it would better to do this in build_blend_factor()
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    // so we can avoid the extra MOV below.
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    mAlphaSource.setTo(regs.obtain(),
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            fragment.size(), CORRUPTIBLE);
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if (shift) {
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        MOV(AL, 0, mAlphaSource.reg,
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            reg_imm(fragment.reg, LSR, shift));
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    } else {
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        MOV(AL, 0, mAlphaSource.reg, fragment.reg);
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                mAlphaSource.s -= shift;
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // fog...
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        build_fog( fragment, component, regs );
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        temp = fragment;
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mInfo[component].inDest) {
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // extraction not needed and replace
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // we just select the right component
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if ((mTextureMachine.replaced & component_mask) == 0) {
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // component wasn't replaced, so use it!
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                temp = component_t(parts.iterated, component);
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                const texture_unit_t& tmu = mTextureMachine.tmu[i];
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if ((tmu.mask & component_mask) &&
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    ((tmu.replaced & component_mask) == 0)) {
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    temp = component_t(parts.texel[i], component);
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbool GGLAssembler::isAlphaSourceNeeded() const
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: also needed for alpha-test
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int bs = mBlendSrc;
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int bd = mBlendDst;
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  bs==GGL_SRC_ALPHA_SATURATE ||
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bs==GGL_SRC_ALPHA || bs==GGL_ONE_MINUS_SRC_ALPHA ||
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bd==GGL_SRC_ALPHA || bd==GGL_ONE_MINUS_SRC_ALPHA ;
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_smooth_shade(const fragment_parts_t& parts)
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mSmooth && !parts.iterated_packed) {
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // update the iterated color in a pipelined way...
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("update iterated color");
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int reload = parts.reload;
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (int i=0 ; i<4 ; i++) {
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!mInfo[i].iterated)
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int c = parts.argb[i].reg;
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int dx = parts.argb_dx[i].reg;
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (reload & 1) {
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                c = scratches.obtain();
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                CONTEXT_LOAD(c, generated_vars.argb[i].c);
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (reload & 2) {
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                dx = scratches.obtain();
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                CONTEXT_LOAD(dx, generated_vars.argb[i].dx);
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (mSmooth) {
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ADD(AL, 0, c, c, dx);
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (reload & 1) {
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                CONTEXT_STORE(c, generated_vars.argb[i].c);
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                scratches.recycle(c);
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (reload & 2) {
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                scratches.recycle(dx);
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_coverage_application(component_t& fragment,
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const fragment_parts_t& parts, Scratch& regs)
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // here fragment.l is guarenteed to be 0
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mAA) {
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // coverages are 1.15 fixed-point numbers
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("coverage application");
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        component_t incoming(fragment);
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        modify(fragment, regs);
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int cf = scratches.obtain();
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LDRH(AL, cf, parts.covPtr.reg, immed8_post(2));
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (fragment.h > 31) {
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fragment.h--;
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            SMULWB(AL, fragment.reg, incoming.reg, cf);
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, fragment.reg, reg_imm(incoming.reg, LSL, 1));
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            SMULWB(AL, fragment.reg, fragment.reg, cf);
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_alpha_test(component_t& fragment,
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    const fragment_parts_t& parts)
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mAlphaTest != GGL_ALWAYS) {
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("Alpha Test");
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ref = scratches.obtain();
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int shift = GGL_COLOR_BITS-fragment.size();
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(ref, state.alpha_test.ref);
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (shift) CMP(AL, fragment.reg, reg_imm(ref, LSR, shift));
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else       CMP(AL, fragment.reg, ref);
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int cc = NV;
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (mAlphaTest) {
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_NEVER:     cc = NV;    break;
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_LESS:      cc = LT;    break;
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_EQUAL:     cc = EQ;    break;
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_LEQUAL:    cc = LS;    break;
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_GREATER:   cc = HI;    break;
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_NOTEQUAL:  cc = NE;    break;
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_GEQUAL:    cc = HS;    break;
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        B(cc^1, "discard_after_textures");
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_depth_test(
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const fragment_parts_t& parts, uint32_t mask)
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mask &= Z_TEST|Z_WRITE;
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const needs_t& needs = mBuilderContext.needs;
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int zmask = GGL_READ_NEEDS(P_MASK_Z, needs.p);
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    Scratch scratches(registerFile());
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mDepthTest != GGL_ALWAYS || zmask) {
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int cc=AL, ic=AL;
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (mDepthTest) {
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_LESS:      ic = HI;    break;
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_EQUAL:     ic = EQ;    break;
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_LEQUAL:    ic = HS;    break;
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_GREATER:   ic = LT;    break;
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_NOTEQUAL:  ic = NE;    break;
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_GEQUAL:    ic = LS;    break;
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_NEVER:
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // this never happens, because it's taken care of when
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // computing the needs. but we keep it for completness.
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            comment("Depth Test (NEVER)");
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            B(AL, "discard_before_textures");
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_ALWAYS:
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // we're here because zmask is enabled
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mask &= ~Z_TEST;    // test always passes.
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // inverse the condition
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cc = ic^1;
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((mask & Z_WRITE) && !zmask) {
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mask &= ~Z_WRITE;
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!mask)
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        comment("Depth Test");
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int zbase = scratches.obtain();
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int depth = scratches.obtain();
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int z = parts.z.reg;
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(zbase, generated_vars.zbase);  // stall
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SUB(AL, 0, zbase, zbase, reg_imm(parts.count.reg, LSR, 15));
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // above does zbase = zbase + ((count >> 16) << 1)
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mask & Z_TEST) {
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            LDRH(AL, depth, zbase);  // stall
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            CMP(AL, depth, reg_imm(z, LSR, 16));
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            B(cc, "discard_before_textures");
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mask & Z_WRITE) {
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (mask == Z_WRITE) {
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // only z-write asked, cc is meaningless
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ic = AL;
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, depth, reg_imm(z, LSR, 16));
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            STRH(ic, depth, zbase);
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_iterate_z(const fragment_parts_t& parts)
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const needs_t& needs = mBuilderContext.needs;
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((mDepthTest != GGL_ALWAYS) || GGL_READ_NEEDS(P_MASK_Z, needs.p)) {
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int dzdx = scratches.obtain();
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(dzdx, generated_vars.dzdx);    // stall
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, parts.z.reg, parts.z.reg, dzdx);
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_iterate_f(const fragment_parts_t& parts)
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const needs_t& needs = mBuilderContext.needs;
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (GGL_READ_NEEDS(P_FOG, needs.p)) {
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        Scratch scratches(registerFile());
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int dfdx = scratches.obtain();
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int f = scratches.obtain();
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(f,     generated_vars.f);
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_LOAD(dfdx,  generated_vars.dfdx);   // stall
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, f, f, dfdx);
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        CONTEXT_STORE(f,    generated_vars.f);
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_logic_op(pixel_t& pixel, Scratch& regs)
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const needs_t& needs = mBuilderContext.needs;
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR;
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (opcode == GGL_COPY)
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    comment("logic operation");
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel_t s(pixel);
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!(pixel.flags & CORRUPTIBLE)) {
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel.reg = regs.obtain();
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel.flags |= CORRUPTIBLE;
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel_t d(mDstPixel);
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(opcode) {
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_CLEAR:         MOV(AL, 0, pixel.reg, imm(0));          break;
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_AND:           AND(AL, 0, pixel.reg, s.reg, d.reg);    break;
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_AND_REVERSE:   BIC(AL, 0, pixel.reg, s.reg, d.reg);    break;
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_COPY:                                                  break;
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_AND_INVERTED:  BIC(AL, 0, pixel.reg, d.reg, s.reg);    break;
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_NOOP:          MOV(AL, 0, pixel.reg, d.reg);           break;
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_XOR:           EOR(AL, 0, pixel.reg, s.reg, d.reg);    break;
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_OR:            ORR(AL, 0, pixel.reg, s.reg, d.reg);    break;
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_NOR:           ORR(AL, 0, pixel.reg, s.reg, d.reg);
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            MVN(AL, 0, pixel.reg, pixel.reg);       break;
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_EQUIV:         EOR(AL, 0, pixel.reg, s.reg, d.reg);
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            MVN(AL, 0, pixel.reg, pixel.reg);       break;
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_INVERT:        MVN(AL, 0, pixel.reg, d.reg);           break;
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_OR_REVERSE:    // s | ~d == ~(~s & d)
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            BIC(AL, 0, pixel.reg, d.reg, s.reg);
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            MVN(AL, 0, pixel.reg, pixel.reg);       break;
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_COPY_INVERTED: MVN(AL, 0, pixel.reg, s.reg);           break;
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_OR_INVERTED:   // ~s | d == ~(s & ~d)
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            BIC(AL, 0, pixel.reg, s.reg, d.reg);
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            MVN(AL, 0, pixel.reg, pixel.reg);       break;
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_NAND:          AND(AL, 0, pixel.reg, s.reg, d.reg);
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            MVN(AL, 0, pixel.reg, pixel.reg);       break;
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_SET:           MVN(AL, 0, pixel.reg, imm(0));          break;
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    };
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic uint32_t find_bottom(uint32_t val)
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t i = 0;
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (!(val & (3<<i)))
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        i+= 2;
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return i;
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void normalize(uint32_t& val, uint32_t& rot)
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    rot = 0;
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (!(val&3)  || (val & 0xFC000000)) {
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t newval;
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        newval = val >> 2;
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        newval |= (val&3) << 30;
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        val = newval;
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        rot += 2;
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (rot == 32) {
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            rot = 0;
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_and_immediate(int d, int s, uint32_t mask, int bits)
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t rot;
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t size = ((bits>=32) ? 0 : (1LU << bits)) - 1;
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mask &= size;
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mask == size) {
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (d != s)
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV( AL, 0, d, s);
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int negative_logic = !isValidImmediate(mask);
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (negative_logic) {
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mask = ~mask & size;
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    normalize(mask, rot);
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mask) {
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while (mask) {
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            uint32_t bitpos = find_bottom(mask);
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int shift = rot + bitpos;
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            uint32_t m = mask & (0xff << bitpos);
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mask &= ~m;
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            m >>= bitpos;
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int32_t newMask =  (m<<shift) | (m>>(32-shift));
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!negative_logic) {
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                AND( AL, 0, d, s, imm(newMask) );
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                BIC( AL, 0, d, s, imm(newMask) );
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            s = d;
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MOV( AL, 0, d, imm(0));
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::build_masking(pixel_t& pixel, Scratch& regs)
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!mMasking || mAllMasked) {
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    comment("color mask");
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel_t fb(mDstPixel);
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel_t s(pixel);
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!(pixel.flags & CORRUPTIBLE)) {
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel.reg = regs.obtain();
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel.flags |= CORRUPTIBLE;
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int mask = 0;
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<4 ; i++) {
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int component_mask = 1<<i;
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int h = fb.format.c[i].h;
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int l = fb.format.c[i].l;
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (h && (!(mMasking & component_mask))) {
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mask |= ((1<<(h-l))-1) << l;
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // There is no need to clear the masked components of the source
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // (unless we applied a logic op), because they're already zeroed
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // by construction (masked components are not computed)
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mLogicOp) {
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const needs_t& needs = mBuilderContext.needs;
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR;
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (opcode != GGL_CLEAR) {
952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // clear masked component of source
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            build_and_immediate(pixel.reg, s.reg, mask, fb.size());
954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            s = pixel;
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // clear non masked components of destination
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    build_and_immediate(fb.reg, fb.reg, ~mask, fb.size());
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // or back the channels that were masked
962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (s.reg == fb.reg) {
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         // this is in fact a MOV
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (s.reg == pixel.reg) {
965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // ugh. this in in fact a nop
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            MOV(AL, 0, pixel.reg, fb.reg);
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ORR(AL, 0, pixel.reg, s.reg, fb.reg);
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid GGLAssembler::base_offset(
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const pointer_t& d, const pointer_t& b, const reg_t& o)
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (b.size) {
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 32:
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 2));
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 24:
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (d.reg == b.reg) {
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 1));
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, d.reg, d.reg, o.reg);
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, d.reg, o.reg, reg_imm(o.reg, LSL, 1));
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ADD(AL, 0, d.reg, d.reg, b.reg);
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 16:
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 1));
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 8:
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ADD(AL, 0, d.reg, b.reg, o.reg);
997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// cheezy register allocator...
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid RegisterAllocator::reset()
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs.reset();
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint RegisterAllocator::reserveReg(int reg)
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mRegs.reserve(reg);
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint RegisterAllocator::obtainReg()
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mRegs.obtain();
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid RegisterAllocator::recycleReg(int reg)
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs.recycle(reg);
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectRegisterAllocator::RegisterFile& RegisterAllocator::registerFile()
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mRegs;
1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectRegisterAllocator::RegisterFile::RegisterFile()
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    : mRegs(0), mTouched(0), mStatus(0)
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    reserve(ARMAssemblerInterface::SP);
1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    reserve(ARMAssemblerInterface::PC);
1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectRegisterAllocator::RegisterFile::RegisterFile(const RegisterFile& rhs)
1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    : mRegs(rhs.mRegs), mTouched(rhs.mTouched)
1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectRegisterAllocator::RegisterFile::~RegisterFile()
1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbool RegisterAllocator::RegisterFile::operator == (const RegisterFile& rhs) const
1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (mRegs == rhs.mRegs);
1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid RegisterAllocator::RegisterFile::reset()
1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs = mTouched = mStatus = 0;
1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    reserve(ARMAssemblerInterface::SP);
1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    reserve(ARMAssemblerInterface::PC);
1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint RegisterAllocator::RegisterFile::reserve(int reg)
1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG_ALWAYS_FATAL_IF(isUsed(reg),
1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        "reserving register %d, but already in use",
1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        reg);
1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs |= (1<<reg);
1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mTouched |= mRegs;
1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return reg;
1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid RegisterAllocator::RegisterFile::reserveSeveral(uint32_t regMask)
1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs |= regMask;
1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mTouched |= regMask;
1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint RegisterAllocator::RegisterFile::isUsed(int reg) const
1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG_ALWAYS_FATAL_IF(reg>=16, "invalid register %d", reg);
1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mRegs & (1<<reg);
1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint RegisterAllocator::RegisterFile::obtain()
1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char priorityList[14] = {  0,  1, 2, 3,
1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    12, 14, 4, 5,
1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                     6,  7, 8, 9,
1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    10, 11 };
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int nbreg = sizeof(priorityList);
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int i, r;
1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (i=0 ; i<nbreg ; i++) {
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        r = priorityList[i];
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!isUsed(r)) {
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // this is not an error anymore because, we'll try again with
1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // a lower optimization level.
109801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block    //ALOGE_IF(i >= nbreg, "pixelflinger ran out of registers\n");
1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (i >= nbreg) {
1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mStatus |= OUT_OF_REGISTERS;
1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // we return SP so we can more easily debug things
1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // the code will never be run anyway.
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return ARMAssemblerInterface::SP;
1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    reserve(r);
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return r;
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbool RegisterAllocator::RegisterFile::hasFreeRegs() const
1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ((mRegs & 0xFFFF) == 0xFFFF) ? false : true;
1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint RegisterAllocator::RegisterFile::countFreeRegs() const
1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int f = ~mRegs & 0xFFFF;
1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // now count number of 1
1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project   f = (f & 0x5555) + ((f>>1) & 0x5555);
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project   f = (f & 0x3333) + ((f>>2) & 0x3333);
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project   f = (f & 0x0F0F) + ((f>>4) & 0x0F0F);
1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project   f = (f & 0x00FF) + ((f>>8) & 0x00FF);
1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project   return f;
1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid RegisterAllocator::RegisterFile::recycle(int reg)
1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG_FATAL_IF(!isUsed(reg),
1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "recycling unallocated register %d",
1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            reg);
1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs &= ~(1<<reg);
1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid RegisterAllocator::RegisterFile::recycleSeveral(uint32_t regMask)
1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG_FATAL_IF((mRegs & regMask)!=regMask,
1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "recycling unallocated registers "
1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "(recycle=%08x, allocated=%08x, unallocated=%08x)",
1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            regMask, mRegs, mRegs&regMask);
1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRegs &= ~regMask;
1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t RegisterAllocator::RegisterFile::touched() const
1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mTouched;
1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android
1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1151