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