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);
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;
status()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:
Scratch(RegisterFile & regFile)104             Scratch(RegisterFile& regFile)
105                 : mRegFile(regFile), mScratch(0) {
106             }
~Scratch()107             ~Scratch() {
108                 mRegFile.recycleSeveral(mScratch);
109             }
obtain()110         int obtain() {
111             int reg = mRegFile.obtain();
112             mScratch |= 1<<reg;
113             return reg;
114         }
recycle(int reg)115         void recycle(int reg) {
116             mRegFile.recycle(reg);
117             mScratch &= ~(1<<reg);
118         }
isUsed(int reg)119         bool isUsed(int reg) {
120             return (mScratch & (1<<reg));
121         }
countFreeRegs()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:
Spill(RegisterFile & regFile,ARMAssemblerInterface & gen,uint32_t reglist)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         }
~Spill()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                     GGLAssembler(ARMAssemblerInterface* target);
181         virtual     ~GGLAssembler();
182 
base()183     uint32_t*   base() const { return 0; } // XXX
pc()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 {
reg_treg_t207             reg_t() : reg(-1), flags(0) {
208             }
209             reg_t(int r, int f=0)
regreg_t210                 : 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 {
integer_tinteger_t220             integer_t() : reg_t(), s(0) {
221             }
222             integer_t(int r, int sz=32, int f=0)
reg_tinteger_t223                 : 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;
sizeinteger_t229             inline int size() const { return s; }
230         };
231 
232         struct pixel_t : public reg_t {
pixel_tpixel_t233             pixel_t() : reg_t() {
234                 memset(&format, 0, sizeof(GGLFormat));
235             }
236             pixel_t(int r, const GGLFormat* fmt, int f=0)
reg_tpixel_t237                 : 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;
hipixel_t243             inline int hi(int c) const { return format.c[c].h; }
lowpixel_t244             inline int low(int c) const { return format.c[c].l; }
maskpixel_t245             inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
sizepixel_t246             inline int size() const { return format.size*8; }
sizepixel_t247             inline int size(int c) const { return component_size(c); }
component_sizepixel_t248             inline int component_size(int c) const { return hi(c) - low(c); }
249         };
250 
251         struct component_t : public reg_t {
component_tcomponent_t252             component_t() : reg_t(), h(0), l(0) {
253             }
254             component_t(int r, int f=0)
reg_tcomponent_t255                 : reg_t(r, f), h(0), l(0) {
256             }
257             component_t(int r, int lo, int hi, int f=0)
reg_tcomponent_t258                 : reg_t(r, f), h(hi), l(lo) {
259             }
component_tcomponent_t260             explicit component_t(const integer_t& rhs)
261                 : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
262             }
component_tcomponent_t263             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;
sizecomponent_t274             inline int size() const { return h-l; }
275         };
276 
277         struct pointer_t : public reg_t {
pointer_tpointer_t278             pointer_t() : reg_t(), size(0) {
279             }
280             pointer_t(int r, int s, int f=0)
reg_tpointer_t281                 : 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     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>
modify(T & r,Scratch & regs)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