Home | History | Annotate | Download | only in codeflinger
      1 /* libs/pixelflinger/codeflinger/GGLAssembler.h
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 
     19 #ifndef ANDROID_GGLASSEMBLER_H
     20 #define ANDROID_GGLASSEMBLER_H
     21 
     22 #include <stdint.h>
     23 #include <sys/types.h>
     24 
     25 #include <private/pixelflinger/ggl_context.h>
     26 
     27 #include "ARMAssemblerProxy.h"
     28 
     29 
     30 namespace android {
     31 
     32 // ----------------------------------------------------------------------------
     33 
     34 #define CONTEXT_ADDR_LOAD(REG, FIELD) \
     35     ADDR_LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
     36 
     37 #define CONTEXT_ADDR_STORE(REG, FIELD) \
     38     ADDR_STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
     39 
     40 #define CONTEXT_LOAD(REG, FIELD) \
     41     LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
     42 
     43 #define CONTEXT_STORE(REG, FIELD) \
     44     STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
     45 
     46 
     47 class RegisterAllocator
     48 {
     49 public:
     50     class RegisterFile;
     51 
     52                     RegisterAllocator(int arch);
     53     RegisterFile&   registerFile();
     54     int             reserveReg(int reg);
     55     int             obtainReg();
     56     void            recycleReg(int reg);
     57     void            reset();
     58 
     59     class RegisterFile
     60     {
     61     public:
     62                             RegisterFile(int arch);
     63                             RegisterFile(const RegisterFile& rhs, int arch);
     64                             ~RegisterFile();
     65 
     66                 void        reset();
     67 
     68                 bool operator == (const RegisterFile& rhs) const;
     69                 bool operator != (const RegisterFile& rhs) const {
     70                     return !operator == (rhs);
     71                 }
     72 
     73                 int         reserve(int reg);
     74                 void        reserveSeveral(uint32_t regMask);
     75 
     76                 void        recycle(int reg);
     77                 void        recycleSeveral(uint32_t regMask);
     78 
     79                 int         obtain();
     80         inline  int         isUsed(int reg) const;
     81 
     82                 bool        hasFreeRegs() const;
     83                 int         countFreeRegs() const;
     84 
     85                 uint32_t    touched() const;
     86         inline  uint32_t    status() const { return mStatus; }
     87 
     88         enum {
     89             OUT_OF_REGISTERS = 0x1
     90         };
     91 
     92     private:
     93         uint32_t    mRegs;
     94         uint32_t    mTouched;
     95         uint32_t    mStatus;
     96         int         mArch;
     97         uint32_t    mRegisterOffset;    // lets reg alloc use 2..17 for mips
     98                                         // while arm uses 0..15
     99     };
    100 
    101     class Scratch
    102     {
    103     public:
    104             Scratch(RegisterFile& regFile)
    105                 : mRegFile(regFile), mScratch(0) {
    106             }
    107             ~Scratch() {
    108                 mRegFile.recycleSeveral(mScratch);
    109             }
    110         int obtain() {
    111             int reg = mRegFile.obtain();
    112             mScratch |= 1<<reg;
    113             return reg;
    114         }
    115         void recycle(int reg) {
    116             mRegFile.recycle(reg);
    117             mScratch &= ~(1<<reg);
    118         }
    119         bool isUsed(int reg) {
    120             return (mScratch & (1<<reg));
    121         }
    122         int countFreeRegs() {
    123             return mRegFile.countFreeRegs();
    124         }
    125     private:
    126         RegisterFile&   mRegFile;
    127         uint32_t        mScratch;
    128     };
    129 
    130     class Spill
    131     {
    132     public:
    133         Spill(RegisterFile& regFile, ARMAssemblerInterface& gen, uint32_t reglist)
    134             : mRegFile(regFile), mGen(gen), mRegList(reglist), mCount(0)
    135         {
    136             if (reglist) {
    137                 int count = 0;
    138                 while (reglist) {
    139                     count++;
    140                     reglist &= ~(1 << (31 - __builtin_clz(reglist)));
    141                 }
    142                 if (count == 1) {
    143                     int reg = 31 - __builtin_clz(mRegList);
    144                     mGen.STR(mGen.AL, reg, mGen.SP, mGen.immed12_pre(-4, 1));
    145                 } else {
    146                     mGen.STM(mGen.AL, mGen.DB, mGen.SP, 1, mRegList);
    147                 }
    148                 mRegFile.recycleSeveral(mRegList);
    149                 mCount = count;
    150             }
    151         }
    152         ~Spill() {
    153             if (mRegList) {
    154                 if (mCount == 1) {
    155                     int reg = 31 - __builtin_clz(mRegList);
    156                     mGen.LDR(mGen.AL, reg, mGen.SP, mGen.immed12_post(4));
    157                 } else {
    158                     mGen.LDM(mGen.AL, mGen.IA, mGen.SP, 1, mRegList);
    159                 }
    160                 mRegFile.reserveSeveral(mRegList);
    161             }
    162         }
    163     private:
    164         RegisterFile&           mRegFile;
    165         ARMAssemblerInterface&  mGen;
    166         uint32_t                mRegList;
    167         int                     mCount;
    168     };
    169 
    170 private:
    171     RegisterFile    mRegs;
    172 };
    173 
    174 // ----------------------------------------------------------------------------
    175 
    176 class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
    177 {
    178 public:
    179 
    180                     GGLAssembler(ARMAssemblerInterface* target);
    181         virtual     ~GGLAssembler();
    182 
    183     uint32_t*   base() const { return 0; } // XXX
    184     uint32_t*   pc() const { return 0; } // XXX
    185 
    186     void        reset(int opt_level);
    187 
    188     virtual void    prolog();
    189     virtual void    epilog(uint32_t touched);
    190 
    191         // generate scanline code for given needs
    192     int         scanline(const needs_t& needs, context_t const* c);
    193     int         scanline_core(const needs_t& needs, context_t const* c);
    194 
    195         enum {
    196             CLEAR_LO    = 0x0001,
    197             CLEAR_HI    = 0x0002,
    198             CORRUPTIBLE = 0x0004,
    199             FIRST       = 0x0008
    200         };
    201 
    202         enum { //load/store flags
    203             WRITE_BACK  = 0x0001
    204         };
    205 
    206         struct reg_t {
    207             reg_t() : reg(-1), flags(0) {
    208             }
    209             reg_t(int r, int f=0)
    210                 : reg(r), flags(f) {
    211             }
    212             void setTo(int r, int f=0) {
    213                 reg=r; flags=f;
    214             }
    215             int         reg;
    216             uint16_t    flags;
    217         };
    218 
    219         struct integer_t : public reg_t {
    220             integer_t() : reg_t(), s(0) {
    221             }
    222             integer_t(int r, int sz=32, int f=0)
    223                 : reg_t(r, f), s(sz) {
    224             }
    225             void setTo(int r, int sz=32, int f=0) {
    226                 reg_t::setTo(r, f); s=sz;
    227             }
    228             int8_t s;
    229             inline int size() const { return s; }
    230         };
    231 
    232         struct pixel_t : public reg_t {
    233             pixel_t() : reg_t() {
    234                 memset(&format, 0, sizeof(GGLFormat));
    235             }
    236             pixel_t(int r, const GGLFormat* fmt, int f=0)
    237                 : reg_t(r, f), format(*fmt) {
    238             }
    239             void setTo(int r, const GGLFormat* fmt, int f=0) {
    240                 reg_t::setTo(r, f); format = *fmt;
    241             }
    242             GGLFormat format;
    243             inline int hi(int c) const { return format.c[c].h; }
    244             inline int low(int c) const { return format.c[c].l; }
    245             inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
    246             inline int size() const { return format.size*8; }
    247             inline int size(int c) const { return component_size(c); }
    248             inline int component_size(int c) const { return hi(c) - low(c); }
    249         };
    250 
    251         struct component_t : public reg_t {
    252             component_t() : reg_t(), h(0), l(0) {
    253             }
    254             component_t(int r, int f=0)
    255                 : reg_t(r, f), h(0), l(0) {
    256             }
    257             component_t(int r, int lo, int hi, int f=0)
    258                 : reg_t(r, f), h(hi), l(lo) {
    259             }
    260             explicit component_t(const integer_t& rhs)
    261                 : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
    262             }
    263             explicit component_t(const pixel_t& rhs, int component) {
    264                 setTo(  rhs.reg,
    265                         rhs.format.c[component].l,
    266                         rhs.format.c[component].h,
    267                         rhs.flags|CLEAR_LO|CLEAR_HI);
    268             }
    269             void setTo(int r, int lo=0, int hi=0, int f=0) {
    270                 reg_t::setTo(r, f); h=hi; l=lo;
    271             }
    272             int8_t h;
    273             int8_t l;
    274             inline int size() const { return h-l; }
    275         };
    276 
    277         struct pointer_t : public reg_t {
    278             pointer_t() : reg_t(), size(0) {
    279             }
    280             pointer_t(int r, int s, int f=0)
    281                 : reg_t(r, f), size(s) {
    282             }
    283             void setTo(int r, int s, int f=0) {
    284                 reg_t::setTo(r, f); size=s;
    285             }
    286             int8_t size;
    287         };
    288 
    289 
    290 private:
    291     struct tex_coord_t {
    292         reg_t       s;
    293         reg_t       t;
    294         pointer_t   ptr;
    295     };
    296 
    297     struct fragment_parts_t {
    298         uint32_t    packed  : 1;
    299         uint32_t    reload  : 2;
    300         uint32_t    iterated_packed  : 1;
    301         pixel_t     iterated;
    302         pointer_t   cbPtr;
    303         pointer_t   covPtr;
    304         reg_t       count;
    305         reg_t       argb[4];
    306         reg_t       argb_dx[4];
    307         reg_t       z;
    308         reg_t       dither;
    309         pixel_t     texel[GGL_TEXTURE_UNIT_COUNT];
    310         tex_coord_t coords[GGL_TEXTURE_UNIT_COUNT];
    311     };
    312 
    313     struct texture_unit_t {
    314         int         format_idx;
    315         GGLFormat   format;
    316         int         bits;
    317         int         swrap;
    318         int         twrap;
    319         int         env;
    320         int         pot;
    321         int         linear;
    322         uint8_t     mask;
    323         uint8_t     replaced;
    324     };
    325 
    326     struct texture_machine_t {
    327         texture_unit_t  tmu[GGL_TEXTURE_UNIT_COUNT];
    328         uint8_t         mask;
    329         uint8_t         replaced;
    330         uint8_t         directTexture;
    331         uint8_t         activeUnits;
    332     };
    333 
    334     struct component_info_t {
    335         bool    masked      : 1;
    336         bool    inDest      : 1;
    337         bool    needed      : 1;
    338         bool    replaced    : 1;
    339         bool    iterated    : 1;
    340         bool    smooth      : 1;
    341         bool    blend       : 1;
    342         bool    fog         : 1;
    343     };
    344 
    345     struct builder_context_t {
    346         context_t const*    c;
    347         needs_t             needs;
    348         int                 Rctx;
    349     };
    350 
    351     template <typename T>
    352     void modify(T& r, Scratch& regs)
    353     {
    354         if (!(r.flags & CORRUPTIBLE)) {
    355             r.reg = regs.obtain();
    356             r.flags |= CORRUPTIBLE;
    357         }
    358     }
    359 
    360     // helpers
    361     void    base_offset(const pointer_t& d, const pointer_t& b, const reg_t& o);
    362 
    363     // texture environement
    364     void    modulate(   component_t& dest,
    365                         const component_t& incoming,
    366                         const pixel_t& texel, int component);
    367 
    368     void    decal(  component_t& dest,
    369                     const component_t& incoming,
    370                     const pixel_t& texel, int component);
    371 
    372     void    blend(  component_t& dest,
    373                     const component_t& incoming,
    374                     const pixel_t& texel, int component, int tmu);
    375 
    376     void    add(  component_t& dest,
    377                     const component_t& incoming,
    378                     const pixel_t& texel, int component);
    379 
    380     // load/store stuff
    381     void    store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
    382     void    load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
    383     void    extract(integer_t& d, const pixel_t& s, int component);
    384     void    extract(component_t& d, const pixel_t& s, int component);
    385     void    extract(integer_t& d, int s, int h, int l, int bits=32);
    386     void    expand(integer_t& d, const integer_t& s, int dbits);
    387     void    expand(integer_t& d, const component_t& s, int dbits);
    388     void    expand(component_t& d, const component_t& s, int dbits);
    389     void    downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
    390 
    391 
    392     void    mul_factor( component_t& d,
    393                         const integer_t& v,
    394                         const integer_t& f);
    395 
    396     void    mul_factor_add( component_t& d,
    397                             const integer_t& v,
    398                             const integer_t& f,
    399                             const component_t& a);
    400 
    401     void    component_add(  component_t& d,
    402                             const integer_t& dst,
    403                             const integer_t& src);
    404 
    405     void    component_sat(  const component_t& v);
    406 
    407 
    408     void    build_scanline_prolog(  fragment_parts_t& parts,
    409                                     const needs_t& needs);
    410 
    411     void    build_smooth_shade(const fragment_parts_t& parts);
    412 
    413     void    build_component(    pixel_t& pixel,
    414                                 const fragment_parts_t& parts,
    415                                 int component,
    416                                 Scratch& global_scratches);
    417 
    418     void    build_incoming_component(
    419                                 component_t& temp,
    420                                 int dst_size,
    421                                 const fragment_parts_t& parts,
    422                                 int component,
    423                                 Scratch& scratches,
    424                                 Scratch& global_scratches);
    425 
    426     void    init_iterated_color(fragment_parts_t& parts, const reg_t& x);
    427 
    428     void    build_iterated_color(   component_t& fragment,
    429                                     const fragment_parts_t& parts,
    430                                     int component,
    431                                     Scratch& regs);
    432 
    433     void    decodeLogicOpNeeds(const needs_t& needs);
    434 
    435     void    decodeTMUNeeds(const needs_t& needs, context_t const* c);
    436 
    437     void    init_textures(  tex_coord_t* coords,
    438                             const reg_t& x,
    439                             const reg_t& y);
    440 
    441     void    build_textures( fragment_parts_t& parts,
    442                             Scratch& regs);
    443 
    444     void    filter8(   const fragment_parts_t& parts,
    445                         pixel_t& texel, const texture_unit_t& tmu,
    446                         int U, int V, pointer_t& txPtr,
    447                         int FRAC_BITS);
    448 
    449     void    filter16(   const fragment_parts_t& parts,
    450                         pixel_t& texel, const texture_unit_t& tmu,
    451                         int U, int V, pointer_t& txPtr,
    452                         int FRAC_BITS);
    453 
    454     void    filter24(   const fragment_parts_t& parts,
    455                         pixel_t& texel, const texture_unit_t& tmu,
    456                         int U, int V, pointer_t& txPtr,
    457                         int FRAC_BITS);
    458 
    459     void    filter32(   const fragment_parts_t& parts,
    460                         pixel_t& texel, const texture_unit_t& tmu,
    461                         int U, int V, pointer_t& txPtr,
    462                         int FRAC_BITS);
    463 
    464     void    build_texture_environment(  component_t& fragment,
    465                                         const fragment_parts_t& parts,
    466                                         int component,
    467                                         Scratch& regs);
    468 
    469     void    wrapping(   int d,
    470                         int coord, int size,
    471                         int tx_wrap, int tx_linear);
    472 
    473     void    build_fog(  component_t& temp,
    474                         int component,
    475                         Scratch& parent_scratches);
    476 
    477     void    build_blending(     component_t& in_out,
    478                                 const pixel_t& pixel,
    479                                 int component,
    480                                 Scratch& parent_scratches);
    481 
    482     void    build_blend_factor(
    483                 integer_t& factor, int f, int component,
    484                 const pixel_t& dst_pixel,
    485                 integer_t& fragment,
    486                 integer_t& fb,
    487                 Scratch& scratches);
    488 
    489     void    build_blendFOneMinusF(  component_t& temp,
    490                                     const integer_t& factor,
    491                                     const integer_t& fragment,
    492                                     const integer_t& fb);
    493 
    494     void    build_blendOneMinusFF(  component_t& temp,
    495                                     const integer_t& factor,
    496                                     const integer_t& fragment,
    497                                     const integer_t& fb);
    498 
    499     void build_coverage_application(component_t& fragment,
    500                                     const fragment_parts_t& parts,
    501                                     Scratch& regs);
    502 
    503     void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
    504 
    505     enum { Z_TEST=1, Z_WRITE=2 };
    506     void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
    507     void build_iterate_z(const fragment_parts_t& parts);
    508     void build_iterate_f(const fragment_parts_t& parts);
    509     void build_iterate_texture_coordinates(const fragment_parts_t& parts);
    510 
    511     void build_logic_op(pixel_t& pixel, Scratch& regs);
    512 
    513     void build_masking(pixel_t& pixel, Scratch& regs);
    514 
    515     void build_and_immediate(int d, int s, uint32_t mask, int bits);
    516 
    517     bool    isAlphaSourceNeeded() const;
    518 
    519     enum {
    520         FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
    521     };
    522 
    523     enum {
    524         LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
    525     };
    526 
    527     static int blending_codes(int fs, int fd);
    528 
    529     builder_context_t   mBuilderContext;
    530     texture_machine_t   mTextureMachine;
    531     component_info_t    mInfo[4];
    532     int                 mBlending;
    533     int                 mMasking;
    534     int                 mAllMasked;
    535     int                 mLogicOp;
    536     int                 mAlphaTest;
    537     int                 mAA;
    538     int                 mDithering;
    539     int                 mDepthTest;
    540 
    541     int             mSmooth;
    542     int             mFog;
    543     pixel_t         mDstPixel;
    544 
    545     GGLFormat       mCbFormat;
    546 
    547     int             mBlendFactorCached;
    548     integer_t       mAlphaSource;
    549 
    550     int             mBaseRegister;
    551 
    552     int             mBlendSrc;
    553     int             mBlendDst;
    554     int             mBlendSrcA;
    555     int             mBlendDstA;
    556 
    557     int             mOptLevel;
    558 };
    559 
    560 // ----------------------------------------------------------------------------
    561 
    562 }; // namespace android
    563 
    564 #endif // ANDROID_GGLASSEMBLER_H
    565