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