GGLAssembler.h revision bfc6dc4ca8d5a1ee498e80a18350b91519a5412c
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
30namespace 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
47class RegisterAllocator
48{
49public:
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
170private:
171    RegisterFile    mRegs;
172};
173
174// ----------------------------------------------------------------------------
175
176class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
177{
178public:
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
290private:
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