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);  // NOLINT, implicit
     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);  // NOLINT, implicit
     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             explicit 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     explicit    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)  // NOLINT, implicit
    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)  // NOLINT, implicit
    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)  // NOLINT, implicit
    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     // GGLAssembler hides RegisterAllocator's and ARMAssemblerProxy's reset
    292     // methods by providing a reset method with a different parameter set. The
    293     // intent of GGLAssembler's reset method is to wrap the inherited reset
    294     // methods, so make these methods private in order to prevent direct calls
    295     // to these methods from clients.
    296     using RegisterAllocator::reset;
    297     using ARMAssemblerProxy::reset;
    298 
    299     struct tex_coord_t {
    300         reg_t       s;
    301         reg_t       t;
    302         pointer_t   ptr;
    303     };
    304 
    305     struct fragment_parts_t {
    306         uint32_t    packed  : 1;
    307         uint32_t    reload  : 2;
    308         uint32_t    iterated_packed  : 1;
    309         pixel_t     iterated;
    310         pointer_t   cbPtr;
    311         pointer_t   covPtr;
    312         reg_t       count;
    313         reg_t       argb[4];
    314         reg_t       argb_dx[4];
    315         reg_t       z;
    316         reg_t       dither;
    317         pixel_t     texel[GGL_TEXTURE_UNIT_COUNT];
    318         tex_coord_t coords[GGL_TEXTURE_UNIT_COUNT];
    319     };
    320 
    321     struct texture_unit_t {
    322         int         format_idx;
    323         GGLFormat   format;
    324         int         bits;
    325         int         swrap;
    326         int         twrap;
    327         int         env;
    328         int         pot;
    329         int         linear;
    330         uint8_t     mask;
    331         uint8_t     replaced;
    332     };
    333 
    334     struct texture_machine_t {
    335         texture_unit_t  tmu[GGL_TEXTURE_UNIT_COUNT];
    336         uint8_t         mask;
    337         uint8_t         replaced;
    338         uint8_t         directTexture;
    339         uint8_t         activeUnits;
    340     };
    341 
    342     struct component_info_t {
    343         bool    masked      : 1;
    344         bool    inDest      : 1;
    345         bool    needed      : 1;
    346         bool    replaced    : 1;
    347         bool    iterated    : 1;
    348         bool    smooth      : 1;
    349         bool    blend       : 1;
    350         bool    fog         : 1;
    351     };
    352 
    353     struct builder_context_t {
    354         context_t const*    c;
    355         needs_t             needs;
    356         int                 Rctx;
    357     };
    358 
    359     template <typename T>
    360     void modify(T& r, Scratch& regs)
    361     {
    362         if (!(r.flags & CORRUPTIBLE)) {
    363             r.reg = regs.obtain();
    364             r.flags |= CORRUPTIBLE;
    365         }
    366     }
    367 
    368     // helpers
    369     void    base_offset(const pointer_t& d, const pointer_t& b, const reg_t& o);
    370 
    371     // texture environement
    372     void    modulate(   component_t& dest,
    373                         const component_t& incoming,
    374                         const pixel_t& texel, int component);
    375 
    376     void    decal(  component_t& dest,
    377                     const component_t& incoming,
    378                     const pixel_t& texel, int component);
    379 
    380     void    blend(  component_t& dest,
    381                     const component_t& incoming,
    382                     const pixel_t& texel, int component, int tmu);
    383 
    384     void    add(  component_t& dest,
    385                     const component_t& incoming,
    386                     const pixel_t& texel, int component);
    387 
    388     // load/store stuff
    389     void    store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
    390     void    load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
    391     void    extract(integer_t& d, const pixel_t& s, int component);
    392     void    extract(component_t& d, const pixel_t& s, int component);
    393     void    extract(integer_t& d, int s, int h, int l, int bits=32);
    394     void    expand(integer_t& d, const integer_t& s, int dbits);
    395     void    expand(integer_t& d, const component_t& s, int dbits);
    396     void    expand(component_t& d, const component_t& s, int dbits);
    397     void    downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
    398 
    399 
    400     void    mul_factor( component_t& d,
    401                         const integer_t& v,
    402                         const integer_t& f);
    403 
    404     void    mul_factor_add( component_t& d,
    405                             const integer_t& v,
    406                             const integer_t& f,
    407                             const component_t& a);
    408 
    409     void    component_add(  component_t& d,
    410                             const integer_t& dst,
    411                             const integer_t& src);
    412 
    413     void    component_sat(  const component_t& v);
    414 
    415 
    416     void    build_scanline_prolog(  fragment_parts_t& parts,
    417                                     const needs_t& needs);
    418 
    419     void    build_smooth_shade(const fragment_parts_t& parts);
    420 
    421     void    build_component(    pixel_t& pixel,
    422                                 const fragment_parts_t& parts,
    423                                 int component,
    424                                 Scratch& global_scratches);
    425 
    426     void    build_incoming_component(
    427                                 component_t& temp,
    428                                 int dst_size,
    429                                 const fragment_parts_t& parts,
    430                                 int component,
    431                                 Scratch& scratches,
    432                                 Scratch& global_scratches);
    433 
    434     void    init_iterated_color(fragment_parts_t& parts, const reg_t& x);
    435 
    436     void    build_iterated_color(   component_t& fragment,
    437                                     const fragment_parts_t& parts,
    438                                     int component,
    439                                     Scratch& regs);
    440 
    441     void    decodeLogicOpNeeds(const needs_t& needs);
    442 
    443     void    decodeTMUNeeds(const needs_t& needs, context_t const* c);
    444 
    445     void    init_textures(  tex_coord_t* coords,
    446                             const reg_t& x,
    447                             const reg_t& y);
    448 
    449     void    build_textures( fragment_parts_t& parts,
    450                             Scratch& regs);
    451 
    452     void    filter8(   const fragment_parts_t& parts,
    453                         pixel_t& texel, const texture_unit_t& tmu,
    454                         int U, int V, pointer_t& txPtr,
    455                         int FRAC_BITS);
    456 
    457     void    filter16(   const fragment_parts_t& parts,
    458                         pixel_t& texel, const texture_unit_t& tmu,
    459                         int U, int V, pointer_t& txPtr,
    460                         int FRAC_BITS);
    461 
    462     void    filter24(   const fragment_parts_t& parts,
    463                         pixel_t& texel, const texture_unit_t& tmu,
    464                         int U, int V, pointer_t& txPtr,
    465                         int FRAC_BITS);
    466 
    467     void    filter32(   const fragment_parts_t& parts,
    468                         pixel_t& texel, const texture_unit_t& tmu,
    469                         int U, int V, pointer_t& txPtr,
    470                         int FRAC_BITS);
    471 
    472     void    build_texture_environment(  component_t& fragment,
    473                                         const fragment_parts_t& parts,
    474                                         int component,
    475                                         Scratch& regs);
    476 
    477     void    wrapping(   int d,
    478                         int coord, int size,
    479                         int tx_wrap, int tx_linear);
    480 
    481     void    build_fog(  component_t& temp,
    482                         int component,
    483                         Scratch& parent_scratches);
    484 
    485     void    build_blending(     component_t& in_out,
    486                                 const pixel_t& pixel,
    487                                 int component,
    488                                 Scratch& parent_scratches);
    489 
    490     void    build_blend_factor(
    491                 integer_t& factor, int f, int component,
    492                 const pixel_t& dst_pixel,
    493                 integer_t& fragment,
    494                 integer_t& fb,
    495                 Scratch& scratches);
    496 
    497     void    build_blendFOneMinusF(  component_t& temp,
    498                                     const integer_t& factor,
    499                                     const integer_t& fragment,
    500                                     const integer_t& fb);
    501 
    502     void    build_blendOneMinusFF(  component_t& temp,
    503                                     const integer_t& factor,
    504                                     const integer_t& fragment,
    505                                     const integer_t& fb);
    506 
    507     void build_coverage_application(component_t& fragment,
    508                                     const fragment_parts_t& parts,
    509                                     Scratch& regs);
    510 
    511     void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
    512 
    513     enum { Z_TEST=1, Z_WRITE=2 };
    514     void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
    515     void build_iterate_z(const fragment_parts_t& parts);
    516     void build_iterate_f(const fragment_parts_t& parts);
    517     void build_iterate_texture_coordinates(const fragment_parts_t& parts);
    518 
    519     void build_logic_op(pixel_t& pixel, Scratch& regs);
    520 
    521     void build_masking(pixel_t& pixel, Scratch& regs);
    522 
    523     void build_and_immediate(int d, int s, uint32_t mask, int bits);
    524 
    525     bool    isAlphaSourceNeeded() const;
    526 
    527     enum {
    528         FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
    529     };
    530 
    531     enum {
    532         LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
    533     };
    534 
    535     static int blending_codes(int fs, int fd);
    536 
    537     builder_context_t   mBuilderContext;
    538     texture_machine_t   mTextureMachine;
    539     component_info_t    mInfo[4];
    540     int                 mBlending;
    541     int                 mMasking;
    542     int                 mAllMasked;
    543     int                 mLogicOp;
    544     int                 mAlphaTest;
    545     int                 mAA;
    546     int                 mDithering;
    547     int                 mDepthTest;
    548 
    549     int             mSmooth;
    550     int             mFog;
    551     pixel_t         mDstPixel;
    552 
    553     GGLFormat       mCbFormat;
    554 
    555     int             mBlendFactorCached;
    556     integer_t       mAlphaSource;
    557 
    558     int             mBaseRegister;
    559 
    560     int             mBlendSrc;
    561     int             mBlendDst;
    562     int             mBlendSrcA;
    563     int             mBlendDstA;
    564 
    565     int             mOptLevel;
    566 };
    567 
    568 // ----------------------------------------------------------------------------
    569 
    570 }; // namespace android
    571 
    572 #endif // ANDROID_GGLASSEMBLER_H
    573