• 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