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