GGLAssembler.h revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
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
30namespace 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
41class RegisterAllocator
42{
43public:
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
160private:
161    RegisterFile    mRegs;
162};
163
164// ----------------------------------------------------------------------------
165
166class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
167{
168public:
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
280private:
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    // load/store stuff
367    void    store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
368    void    load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
369    void    extract(integer_t& d, const pixel_t& s, int component);
370    void    extract(component_t& d, const pixel_t& s, int component);
371    void    extract(integer_t& d, int s, int h, int l, int bits=32);
372    void    expand(integer_t& d, const integer_t& s, int dbits);
373    void    expand(integer_t& d, const component_t& s, int dbits);
374    void    expand(component_t& d, const component_t& s, int dbits);
375    void    downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
376
377
378    void    mul_factor( component_t& d,
379                        const integer_t& v,
380                        const integer_t& f);
381
382    void    mul_factor_add( component_t& d,
383                            const integer_t& v,
384                            const integer_t& f,
385                            const component_t& a);
386
387    void    component_add(  component_t& d,
388                            const integer_t& dst,
389                            const integer_t& src);
390
391    void    component_sat(  const component_t& v);
392
393
394    void    build_scanline_prolog(  fragment_parts_t& parts,
395                                    const needs_t& needs);
396
397    void    build_smooth_shade(const fragment_parts_t& parts);
398
399    void    build_component(    pixel_t& pixel,
400                                const fragment_parts_t& parts,
401                                int component,
402                                Scratch& global_scratches);
403
404    void    build_incoming_component(
405                                component_t& temp,
406                                int dst_size,
407                                const fragment_parts_t& parts,
408                                int component,
409                                Scratch& scratches,
410                                Scratch& global_scratches);
411
412    void    init_iterated_color(fragment_parts_t& parts, const reg_t& x);
413
414    void    build_iterated_color(   component_t& fragment,
415                                    const fragment_parts_t& parts,
416                                    int component,
417                                    Scratch& regs);
418
419    void    decodeLogicOpNeeds(const needs_t& needs);
420
421    void    decodeTMUNeeds(const needs_t& needs, context_t const* c);
422
423    void    init_textures(  tex_coord_t* coords,
424                            const reg_t& x,
425                            const reg_t& y);
426
427    void    build_textures( fragment_parts_t& parts,
428                            Scratch& regs);
429
430    void    filter8(   const fragment_parts_t& parts,
431                        pixel_t& texel, const texture_unit_t& tmu,
432                        int U, int V, pointer_t& txPtr,
433                        int FRAC_BITS);
434
435    void    filter16(   const fragment_parts_t& parts,
436                        pixel_t& texel, const texture_unit_t& tmu,
437                        int U, int V, pointer_t& txPtr,
438                        int FRAC_BITS);
439
440    void    filter24(   const fragment_parts_t& parts,
441                        pixel_t& texel, const texture_unit_t& tmu,
442                        int U, int V, pointer_t& txPtr,
443                        int FRAC_BITS);
444
445    void    filter32(   const fragment_parts_t& parts,
446                        pixel_t& texel, const texture_unit_t& tmu,
447                        int U, int V, pointer_t& txPtr,
448                        int FRAC_BITS);
449
450    void    build_texture_environment(  component_t& fragment,
451                                        const fragment_parts_t& parts,
452                                        int component,
453                                        Scratch& regs);
454
455    void    wrapping(   int d,
456                        int coord, int size,
457                        int tx_wrap, int tx_linear);
458
459    void    build_fog(  component_t& temp,
460                        int component,
461                        Scratch& parent_scratches);
462
463    void    build_blending(     component_t& in_out,
464                                const pixel_t& pixel,
465                                int component,
466                                Scratch& parent_scratches);
467
468    void    build_blend_factor(
469                integer_t& factor, int f, int component,
470                const pixel_t& dst_pixel,
471                integer_t& fragment,
472                integer_t& fb,
473                Scratch& scratches);
474
475    void    build_blendFOneMinusF(  component_t& temp,
476                                    const integer_t& factor,
477                                    const integer_t& fragment,
478                                    const integer_t& fb);
479
480    void    build_blendOneMinusFF(  component_t& temp,
481                                    const integer_t& factor,
482                                    const integer_t& fragment,
483                                    const integer_t& fb);
484
485    void build_coverage_application(component_t& fragment,
486                                    const fragment_parts_t& parts,
487                                    Scratch& regs);
488
489    void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
490
491    enum { Z_TEST=1, Z_WRITE=2 };
492    void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
493    void build_iterate_z(const fragment_parts_t& parts);
494    void build_iterate_f(const fragment_parts_t& parts);
495    void build_iterate_texture_coordinates(const fragment_parts_t& parts);
496
497    void build_logic_op(pixel_t& pixel, Scratch& regs);
498
499    void build_masking(pixel_t& pixel, Scratch& regs);
500
501    void build_and_immediate(int d, int s, uint32_t mask, int bits);
502
503    bool    isAlphaSourceNeeded() const;
504
505    enum {
506        FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
507    };
508
509    enum {
510        LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
511    };
512
513    static int blending_codes(int fs, int fd);
514
515    builder_context_t   mBuilderContext;
516    texture_machine_t   mTextureMachine;
517    component_info_t    mInfo[4];
518    int                 mBlending;
519    int                 mMasking;
520    int                 mLogicOp;
521    int                 mAlphaTest;
522    int                 mAA;
523    int                 mDithering;
524    int                 mDepthTest;
525
526    int             mSmooth;
527    int             mFog;
528    pixel_t         mDstPixel;
529
530    GGLFormat       mCbFormat;
531
532    int             mBlendFactorCached;
533    integer_t       mAlphaSource;
534
535    int             mBaseRegister;
536
537    int             mBlendSrc;
538    int             mBlendDst;
539    int             mBlendSrcA;
540    int             mBlendDstA;
541
542    int             mOptLevel;
543};
544
545// ----------------------------------------------------------------------------
546
547}; // namespace android
548
549#endif // ANDROID_GGLASSEMBLER_H
550