• 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 "codeflinger/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     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;
status()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:
Scratch(RegisterFile & regFile)94             Scratch(RegisterFile& regFile)
95                 : mRegFile(regFile), mScratch(0) {
96             }
~Scratch()97             ~Scratch() {
98                 mRegFile.recycleSeveral(mScratch);
99             }
obtain()100         int obtain() {
101             int reg = mRegFile.obtain();
102             mScratch |= 1<<reg;
103             return reg;
104         }
recycle(int reg)105         void recycle(int reg) {
106             mRegFile.recycle(reg);
107             mScratch &= ~(1<<reg);
108         }
isUsed(int reg)109         bool isUsed(int reg) {
110             return (mScratch & (1<<reg));
111         }
countFreeRegs()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:
Spill(RegisterFile & regFile,ARMAssemblerInterface & gen,uint32_t reglist)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         }
~Spill()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 
160 private:
161     RegisterFile    mRegs;
162 };
163 
164 // ----------------------------------------------------------------------------
165 
166 class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
167 {
168 public:
169 
170                     GGLAssembler(ARMAssemblerInterface* target);
171         virtual     ~GGLAssembler();
172 
base()173     uint32_t*   base() const { return 0; } // XXX
pc()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 {
reg_treg_t197             reg_t() : reg(-1), flags(0) {
198             }
199             reg_t(int r, int f=0)
regreg_t200                 : 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 {
integer_tinteger_t210             integer_t() : reg_t(), s(0) {
211             }
212             integer_t(int r, int sz=32, int f=0)
reg_tinteger_t213                 : 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;
sizeinteger_t219             inline int size() const { return s; }
220         };
221 
222         struct pixel_t : public reg_t {
pixel_tpixel_t223             pixel_t() : reg_t() {
224                 memset(&format, 0, sizeof(GGLFormat));
225             }
226             pixel_t(int r, const GGLFormat* fmt, int f=0)
reg_tpixel_t227                 : 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;
hipixel_t233             inline int hi(int c) const { return format.c[c].h; }
lowpixel_t234             inline int low(int c) const { return format.c[c].l; }
maskpixel_t235             inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
sizepixel_t236             inline int size() const { return format.size*8; }
sizepixel_t237             inline int size(int c) const { return component_size(c); }
component_sizepixel_t238             inline int component_size(int c) const { return hi(c) - low(c); }
239         };
240 
241         struct component_t : public reg_t {
component_tcomponent_t242             component_t() : reg_t(), h(0), l(0) {
243             }
244             component_t(int r, int f=0)
reg_tcomponent_t245                 : reg_t(r, f), h(0), l(0) {
246             }
247             component_t(int r, int lo, int hi, int f=0)
reg_tcomponent_t248                 : reg_t(r, f), h(hi), l(lo) {
249             }
component_tcomponent_t250             explicit component_t(const integer_t& rhs)
251                 : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
252             }
component_tcomponent_t253             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;
sizecomponent_t264             inline int size() const { return h-l; }
265         };
266 
267         struct pointer_t : public reg_t {
pointer_tpointer_t268             pointer_t() : reg_t(), size(0) {
269             }
270             pointer_t(int r, int s, int f=0)
reg_tpointer_t271                 : 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 
280 private:
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>
modify(T & r,Scratch & regs)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     void    add(  component_t& dest,
367                     const component_t& incoming,
368                     const pixel_t& texel, int component);
369 
370     // load/store stuff
371     void    store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
372     void    load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
373     void    extract(integer_t& d, const pixel_t& s, int component);
374     void    extract(component_t& d, const pixel_t& s, int component);
375     void    extract(integer_t& d, int s, int h, int l, int bits=32);
376     void    expand(integer_t& d, const integer_t& s, int dbits);
377     void    expand(integer_t& d, const component_t& s, int dbits);
378     void    expand(component_t& d, const component_t& s, int dbits);
379     void    downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
380 
381 
382     void    mul_factor( component_t& d,
383                         const integer_t& v,
384                         const integer_t& f);
385 
386     void    mul_factor_add( component_t& d,
387                             const integer_t& v,
388                             const integer_t& f,
389                             const component_t& a);
390 
391     void    component_add(  component_t& d,
392                             const integer_t& dst,
393                             const integer_t& src);
394 
395     void    component_sat(  const component_t& v);
396 
397 
398     void    build_scanline_prolog(  fragment_parts_t& parts,
399                                     const needs_t& needs);
400 
401     void    build_smooth_shade(const fragment_parts_t& parts);
402 
403     void    build_component(    pixel_t& pixel,
404                                 const fragment_parts_t& parts,
405                                 int component,
406                                 Scratch& global_scratches);
407 
408     void    build_incoming_component(
409                                 component_t& temp,
410                                 int dst_size,
411                                 const fragment_parts_t& parts,
412                                 int component,
413                                 Scratch& scratches,
414                                 Scratch& global_scratches);
415 
416     void    init_iterated_color(fragment_parts_t& parts, const reg_t& x);
417 
418     void    build_iterated_color(   component_t& fragment,
419                                     const fragment_parts_t& parts,
420                                     int component,
421                                     Scratch& regs);
422 
423     void    decodeLogicOpNeeds(const needs_t& needs);
424 
425     void    decodeTMUNeeds(const needs_t& needs, context_t const* c);
426 
427     void    init_textures(  tex_coord_t* coords,
428                             const reg_t& x,
429                             const reg_t& y);
430 
431     void    build_textures( fragment_parts_t& parts,
432                             Scratch& regs);
433 
434     void    filter8(   const fragment_parts_t& parts,
435                         pixel_t& texel, const texture_unit_t& tmu,
436                         int U, int V, pointer_t& txPtr,
437                         int FRAC_BITS);
438 
439     void    filter16(   const fragment_parts_t& parts,
440                         pixel_t& texel, const texture_unit_t& tmu,
441                         int U, int V, pointer_t& txPtr,
442                         int FRAC_BITS);
443 
444     void    filter24(   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    filter32(   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    build_texture_environment(  component_t& fragment,
455                                         const fragment_parts_t& parts,
456                                         int component,
457                                         Scratch& regs);
458 
459     void    wrapping(   int d,
460                         int coord, int size,
461                         int tx_wrap, int tx_linear);
462 
463     void    build_fog(  component_t& temp,
464                         int component,
465                         Scratch& parent_scratches);
466 
467     void    build_blending(     component_t& in_out,
468                                 const pixel_t& pixel,
469                                 int component,
470                                 Scratch& parent_scratches);
471 
472     void    build_blend_factor(
473                 integer_t& factor, int f, int component,
474                 const pixel_t& dst_pixel,
475                 integer_t& fragment,
476                 integer_t& fb,
477                 Scratch& scratches);
478 
479     void    build_blendFOneMinusF(  component_t& temp,
480                                     const integer_t& factor,
481                                     const integer_t& fragment,
482                                     const integer_t& fb);
483 
484     void    build_blendOneMinusFF(  component_t& temp,
485                                     const integer_t& factor,
486                                     const integer_t& fragment,
487                                     const integer_t& fb);
488 
489     void build_coverage_application(component_t& fragment,
490                                     const fragment_parts_t& parts,
491                                     Scratch& regs);
492 
493     void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
494 
495     enum { Z_TEST=1, Z_WRITE=2 };
496     void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
497     void build_iterate_z(const fragment_parts_t& parts);
498     void build_iterate_f(const fragment_parts_t& parts);
499     void build_iterate_texture_coordinates(const fragment_parts_t& parts);
500 
501     void build_logic_op(pixel_t& pixel, Scratch& regs);
502 
503     void build_masking(pixel_t& pixel, Scratch& regs);
504 
505     void build_and_immediate(int d, int s, uint32_t mask, int bits);
506 
507     bool    isAlphaSourceNeeded() const;
508 
509     enum {
510         FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
511     };
512 
513     enum {
514         LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
515     };
516 
517     static int blending_codes(int fs, int fd);
518 
519     builder_context_t   mBuilderContext;
520     texture_machine_t   mTextureMachine;
521     component_info_t    mInfo[4];
522     int                 mBlending;
523     int                 mMasking;
524     int                 mAllMasked;
525     int                 mLogicOp;
526     int                 mAlphaTest;
527     int                 mAA;
528     int                 mDithering;
529     int                 mDepthTest;
530 
531     int             mSmooth;
532     int             mFog;
533     pixel_t         mDstPixel;
534 
535     GGLFormat       mCbFormat;
536 
537     int             mBlendFactorCached;
538     integer_t       mAlphaSource;
539 
540     int             mBaseRegister;
541 
542     int             mBlendSrc;
543     int             mBlendDst;
544     int             mBlendSrcA;
545     int             mBlendDstA;
546 
547     int             mOptLevel;
548 };
549 
550 // ----------------------------------------------------------------------------
551 
552 }; // namespace android
553 
554 #endif // ANDROID_GGLASSEMBLER_H
555