123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- /* libs/pixelflinger/codeflinger/GGLAssembler.h
- **
- ** Copyright 2006, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
- #ifndef ANDROID_GGLASSEMBLER_H
- #define ANDROID_GGLASSEMBLER_H
- #include <stdint.h>
- #include <sys/types.h>
- #include <private/pixelflinger/ggl_context.h>
- #include "ARMAssemblerProxy.h"
- namespace android {
- // ----------------------------------------------------------------------------
- #define CONTEXT_ADDR_LOAD(REG, FIELD) \
- ADDR_LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
- #define CONTEXT_ADDR_STORE(REG, FIELD) \
- ADDR_STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
- #define CONTEXT_LOAD(REG, FIELD) \
- LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
- #define CONTEXT_STORE(REG, FIELD) \
- STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
- class RegisterAllocator
- {
- public:
- class RegisterFile;
-
- RegisterAllocator(int arch); // NOLINT, implicit
- RegisterFile& registerFile();
- int reserveReg(int reg);
- int obtainReg();
- void recycleReg(int reg);
- void reset();
- class RegisterFile
- {
- public:
- RegisterFile(int arch); // NOLINT, implicit
- RegisterFile(const RegisterFile& rhs, int arch);
- ~RegisterFile();
- void reset();
- bool operator == (const RegisterFile& rhs) const;
- bool operator != (const RegisterFile& rhs) const {
- return !operator == (rhs);
- }
- int reserve(int reg);
- void reserveSeveral(uint32_t regMask);
- void recycle(int reg);
- void recycleSeveral(uint32_t regMask);
- int obtain();
- inline int isUsed(int reg) const;
- bool hasFreeRegs() const;
- int countFreeRegs() const;
- uint32_t touched() const;
- inline uint32_t status() const { return mStatus; }
-
- enum {
- OUT_OF_REGISTERS = 0x1
- };
- private:
- uint32_t mRegs;
- uint32_t mTouched;
- uint32_t mStatus;
- int mArch;
- uint32_t mRegisterOffset; // lets reg alloc use 2..17 for mips
- // while arm uses 0..15
- };
-
- class Scratch
- {
- public:
- explicit Scratch(RegisterFile& regFile)
- : mRegFile(regFile), mScratch(0) {
- }
- ~Scratch() {
- mRegFile.recycleSeveral(mScratch);
- }
- int obtain() {
- int reg = mRegFile.obtain();
- mScratch |= 1<<reg;
- return reg;
- }
- void recycle(int reg) {
- mRegFile.recycle(reg);
- mScratch &= ~(1<<reg);
- }
- bool isUsed(int reg) {
- return (mScratch & (1<<reg));
- }
- int countFreeRegs() {
- return mRegFile.countFreeRegs();
- }
- private:
- RegisterFile& mRegFile;
- uint32_t mScratch;
- };
- class Spill
- {
- public:
- Spill(RegisterFile& regFile, ARMAssemblerInterface& gen, uint32_t reglist)
- : mRegFile(regFile), mGen(gen), mRegList(reglist), mCount(0)
- {
- if (reglist) {
- int count = 0;
- while (reglist) {
- count++;
- reglist &= ~(1 << (31 - __builtin_clz(reglist)));
- }
- if (count == 1) {
- int reg = 31 - __builtin_clz(mRegList);
- mGen.STR(mGen.AL, reg, mGen.SP, mGen.immed12_pre(-4, 1));
- } else {
- mGen.STM(mGen.AL, mGen.DB, mGen.SP, 1, mRegList);
- }
- mRegFile.recycleSeveral(mRegList);
- mCount = count;
- }
- }
- ~Spill() {
- if (mRegList) {
- if (mCount == 1) {
- int reg = 31 - __builtin_clz(mRegList);
- mGen.LDR(mGen.AL, reg, mGen.SP, mGen.immed12_post(4));
- } else {
- mGen.LDM(mGen.AL, mGen.IA, mGen.SP, 1, mRegList);
- }
- mRegFile.reserveSeveral(mRegList);
- }
- }
- private:
- RegisterFile& mRegFile;
- ARMAssemblerInterface& mGen;
- uint32_t mRegList;
- int mCount;
- };
-
- private:
- RegisterFile mRegs;
- };
- // ----------------------------------------------------------------------------
- class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
- {
- public:
- explicit GGLAssembler(ARMAssemblerInterface* target);
- virtual ~GGLAssembler();
- uint32_t* base() const { return 0; } // XXX
- uint32_t* pc() const { return 0; } // XXX
- void reset(int opt_level);
- virtual void prolog();
- virtual void epilog(uint32_t touched);
- // generate scanline code for given needs
- int scanline(const needs_t& needs, context_t const* c);
- int scanline_core(const needs_t& needs, context_t const* c);
- enum {
- CLEAR_LO = 0x0001,
- CLEAR_HI = 0x0002,
- CORRUPTIBLE = 0x0004,
- FIRST = 0x0008
- };
- enum { //load/store flags
- WRITE_BACK = 0x0001
- };
- struct reg_t {
- reg_t() : reg(-1), flags(0) {
- }
- reg_t(int r, int f=0) // NOLINT, implicit
- : reg(r), flags(f) {
- }
- void setTo(int r, int f=0) {
- reg=r; flags=f;
- }
- int reg;
- uint16_t flags;
- };
- struct integer_t : public reg_t {
- integer_t() : reg_t(), s(0) {
- }
- integer_t(int r, int sz=32, int f=0) // NOLINT, implicit
- : reg_t(r, f), s(sz) {
- }
- void setTo(int r, int sz=32, int f=0) {
- reg_t::setTo(r, f); s=sz;
- }
- int8_t s;
- inline int size() const { return s; }
- };
-
- struct pixel_t : public reg_t {
- pixel_t() : reg_t() {
- memset(&format, 0, sizeof(GGLFormat));
- }
- pixel_t(int r, const GGLFormat* fmt, int f=0)
- : reg_t(r, f), format(*fmt) {
- }
- void setTo(int r, const GGLFormat* fmt, int f=0) {
- reg_t::setTo(r, f); format = *fmt;
- }
- GGLFormat format;
- inline int hi(int c) const { return format.c[c].h; }
- inline int low(int c) const { return format.c[c].l; }
- inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
- inline int size() const { return format.size*8; }
- inline int size(int c) const { return component_size(c); }
- inline int component_size(int c) const { return hi(c) - low(c); }
- };
- struct component_t : public reg_t {
- component_t() : reg_t(), h(0), l(0) {
- }
- component_t(int r, int f=0) // NOLINT, implicit
- : reg_t(r, f), h(0), l(0) {
- }
- component_t(int r, int lo, int hi, int f=0)
- : reg_t(r, f), h(hi), l(lo) {
- }
- explicit component_t(const integer_t& rhs)
- : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
- }
- explicit component_t(const pixel_t& rhs, int component) {
- setTo( rhs.reg,
- rhs.format.c[component].l,
- rhs.format.c[component].h,
- rhs.flags|CLEAR_LO|CLEAR_HI);
- }
- void setTo(int r, int lo=0, int hi=0, int f=0) {
- reg_t::setTo(r, f); h=hi; l=lo;
- }
- int8_t h;
- int8_t l;
- inline int size() const { return h-l; }
- };
- struct pointer_t : public reg_t {
- pointer_t() : reg_t(), size(0) {
- }
- pointer_t(int r, int s, int f=0)
- : reg_t(r, f), size(s) {
- }
- void setTo(int r, int s, int f=0) {
- reg_t::setTo(r, f); size=s;
- }
- int8_t size;
- };
- private:
- // GGLAssembler hides RegisterAllocator's and ARMAssemblerProxy's reset
- // methods by providing a reset method with a different parameter set. The
- // intent of GGLAssembler's reset method is to wrap the inherited reset
- // methods, so make these methods private in order to prevent direct calls
- // to these methods from clients.
- using RegisterAllocator::reset;
- using ARMAssemblerProxy::reset;
- struct tex_coord_t {
- reg_t s;
- reg_t t;
- pointer_t ptr;
- };
- struct fragment_parts_t {
- uint32_t packed : 1;
- uint32_t reload : 2;
- uint32_t iterated_packed : 1;
- pixel_t iterated;
- pointer_t cbPtr;
- pointer_t covPtr;
- reg_t count;
- reg_t argb[4];
- reg_t argb_dx[4];
- reg_t z;
- reg_t dither;
- pixel_t texel[GGL_TEXTURE_UNIT_COUNT];
- tex_coord_t coords[GGL_TEXTURE_UNIT_COUNT];
- };
-
- struct texture_unit_t {
- int format_idx;
- GGLFormat format;
- int bits;
- int swrap;
- int twrap;
- int env;
- int pot;
- int linear;
- uint8_t mask;
- uint8_t replaced;
- };
- struct texture_machine_t {
- texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT];
- uint8_t mask;
- uint8_t replaced;
- uint8_t directTexture;
- uint8_t activeUnits;
- };
- struct component_info_t {
- bool masked : 1;
- bool inDest : 1;
- bool needed : 1;
- bool replaced : 1;
- bool iterated : 1;
- bool smooth : 1;
- bool blend : 1;
- bool fog : 1;
- };
- struct builder_context_t {
- context_t const* c;
- needs_t needs;
- int Rctx;
- };
- template <typename T>
- void modify(T& r, Scratch& regs)
- {
- if (!(r.flags & CORRUPTIBLE)) {
- r.reg = regs.obtain();
- r.flags |= CORRUPTIBLE;
- }
- }
- // helpers
- void base_offset(const pointer_t& d, const pointer_t& b, const reg_t& o);
- // texture environement
- void modulate( component_t& dest,
- const component_t& incoming,
- const pixel_t& texel, int component);
- void decal( component_t& dest,
- const component_t& incoming,
- const pixel_t& texel, int component);
- void blend( component_t& dest,
- const component_t& incoming,
- const pixel_t& texel, int component, int tmu);
- void add( component_t& dest,
- const component_t& incoming,
- const pixel_t& texel, int component);
- // load/store stuff
- void store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
- void load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
- void extract(integer_t& d, const pixel_t& s, int component);
- void extract(component_t& d, const pixel_t& s, int component);
- void extract(integer_t& d, int s, int h, int l, int bits=32);
- void expand(integer_t& d, const integer_t& s, int dbits);
- void expand(integer_t& d, const component_t& s, int dbits);
- void expand(component_t& d, const component_t& s, int dbits);
- void downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
- void mul_factor( component_t& d,
- const integer_t& v,
- const integer_t& f);
- void mul_factor_add( component_t& d,
- const integer_t& v,
- const integer_t& f,
- const component_t& a);
- void component_add( component_t& d,
- const integer_t& dst,
- const integer_t& src);
- void component_sat( const component_t& v);
- void build_scanline_prolog( fragment_parts_t& parts,
- const needs_t& needs);
- void build_smooth_shade(const fragment_parts_t& parts);
- void build_component( pixel_t& pixel,
- const fragment_parts_t& parts,
- int component,
- Scratch& global_scratches);
-
- void build_incoming_component(
- component_t& temp,
- int dst_size,
- const fragment_parts_t& parts,
- int component,
- Scratch& scratches,
- Scratch& global_scratches);
- void init_iterated_color(fragment_parts_t& parts, const reg_t& x);
- void build_iterated_color( component_t& fragment,
- const fragment_parts_t& parts,
- int component,
- Scratch& regs);
- void decodeLogicOpNeeds(const needs_t& needs);
-
- void decodeTMUNeeds(const needs_t& needs, context_t const* c);
- void init_textures( tex_coord_t* coords,
- const reg_t& x,
- const reg_t& y);
- void build_textures( fragment_parts_t& parts,
- Scratch& regs);
- void filter8( const fragment_parts_t& parts,
- pixel_t& texel, const texture_unit_t& tmu,
- int U, int V, pointer_t& txPtr,
- int FRAC_BITS);
- void filter16( const fragment_parts_t& parts,
- pixel_t& texel, const texture_unit_t& tmu,
- int U, int V, pointer_t& txPtr,
- int FRAC_BITS);
- void filter24( const fragment_parts_t& parts,
- pixel_t& texel, const texture_unit_t& tmu,
- int U, int V, pointer_t& txPtr,
- int FRAC_BITS);
- void filter32( const fragment_parts_t& parts,
- pixel_t& texel, const texture_unit_t& tmu,
- int U, int V, pointer_t& txPtr,
- int FRAC_BITS);
- void build_texture_environment( component_t& fragment,
- const fragment_parts_t& parts,
- int component,
- Scratch& regs);
- void wrapping( int d,
- int coord, int size,
- int tx_wrap, int tx_linear);
- void build_fog( component_t& temp,
- int component,
- Scratch& parent_scratches);
- void build_blending( component_t& in_out,
- const pixel_t& pixel,
- int component,
- Scratch& parent_scratches);
- void build_blend_factor(
- integer_t& factor, int f, int component,
- const pixel_t& dst_pixel,
- integer_t& fragment,
- integer_t& fb,
- Scratch& scratches);
- void build_blendFOneMinusF( component_t& temp,
- const integer_t& factor,
- const integer_t& fragment,
- const integer_t& fb);
- void build_blendOneMinusFF( component_t& temp,
- const integer_t& factor,
- const integer_t& fragment,
- const integer_t& fb);
- void build_coverage_application(component_t& fragment,
- const fragment_parts_t& parts,
- Scratch& regs);
- void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
- enum { Z_TEST=1, Z_WRITE=2 };
- void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
- void build_iterate_z(const fragment_parts_t& parts);
- void build_iterate_f(const fragment_parts_t& parts);
- void build_iterate_texture_coordinates(const fragment_parts_t& parts);
- void build_logic_op(pixel_t& pixel, Scratch& regs);
- void build_masking(pixel_t& pixel, Scratch& regs);
- void build_and_immediate(int d, int s, uint32_t mask, int bits);
- bool isAlphaSourceNeeded() const;
- enum {
- FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
- };
-
- enum {
- LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
- };
- static int blending_codes(int fs, int fd);
- builder_context_t mBuilderContext;
- texture_machine_t mTextureMachine;
- component_info_t mInfo[4];
- int mBlending;
- int mMasking;
- int mAllMasked;
- int mLogicOp;
- int mAlphaTest;
- int mAA;
- int mDithering;
- int mDepthTest;
- int mSmooth;
- int mFog;
- pixel_t mDstPixel;
-
- GGLFormat mCbFormat;
-
- int mBlendFactorCached;
- integer_t mAlphaSource;
-
- int mBaseRegister;
-
- int mBlendSrc;
- int mBlendDst;
- int mBlendSrcA;
- int mBlendDstA;
-
- int mOptLevel;
- };
- // ----------------------------------------------------------------------------
- }; // namespace android
- #endif // ANDROID_GGLASSEMBLER_H
|