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