blob: 9db20dfd3ee48065fbefa7faf2b74c258b704e5d [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/* 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
Mathias Agopian9857d992013-04-01 15:17:55 -070027#include "ARMAssemblerProxy.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080028
29
30namespace android {
31
32// ----------------------------------------------------------------------------
33
Ashok Bhatbfc6dc42013-02-21 10:27:40 +000034#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
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080040#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
47class RegisterAllocator
48{
49public:
50 class RegisterFile;
51
Paul Lind2bc2b792012-02-01 10:54:19 -080052 RegisterAllocator(int arch);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053 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:
Paul Lind2bc2b792012-02-01 10:54:19 -080062 RegisterFile(int arch);
63 RegisterFile(const RegisterFile& rhs, int arch);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080064 ~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;
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;
Paul Lind2bc2b792012-02-01 10:54:19 -080096 int mArch;
97 uint32_t mRegisterOffset; // lets reg alloc use 2..17 for mips
98 // while arm uses 0..15
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080099 };
100
101 class Scratch
102 {
103 public:
104 Scratch(RegisterFile& regFile)
105 : mRegFile(regFile), mScratch(0) {
106 }
107 ~Scratch() {
108 mRegFile.recycleSeveral(mScratch);
109 }
110 int obtain() {
111 int reg = mRegFile.obtain();
112 mScratch |= 1<<reg;
113 return reg;
114 }
115 void recycle(int reg) {
116 mRegFile.recycle(reg);
117 mScratch &= ~(1<<reg);
118 }
119 bool isUsed(int reg) {
120 return (mScratch & (1<<reg));
121 }
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:
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 }
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
170private:
171 RegisterFile mRegs;
172};
173
174// ----------------------------------------------------------------------------
175
176class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
177{
178public:
179
180 GGLAssembler(ARMAssemblerInterface* target);
181 virtual ~GGLAssembler();
182
183 uint32_t* base() const { return 0; } // XXX
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 {
207 reg_t() : reg(-1), flags(0) {
208 }
209 reg_t(int r, int f=0)
210 : 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 {
220 integer_t() : reg_t(), s(0) {
221 }
222 integer_t(int r, int sz=32, int f=0)
223 : 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;
229 inline int size() const { return s; }
230 };
231
232 struct pixel_t : public reg_t {
233 pixel_t() : reg_t() {
234 memset(&format, 0, sizeof(GGLFormat));
235 }
236 pixel_t(int r, const GGLFormat* fmt, int f=0)
237 : 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;
243 inline int hi(int c) const { return format.c[c].h; }
244 inline int low(int c) const { return format.c[c].l; }
245 inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
246 inline int size() const { return format.size*8; }
247 inline int size(int c) const { return component_size(c); }
248 inline int component_size(int c) const { return hi(c) - low(c); }
249 };
250
251 struct component_t : public reg_t {
252 component_t() : reg_t(), h(0), l(0) {
253 }
254 component_t(int r, int f=0)
255 : reg_t(r, f), h(0), l(0) {
256 }
257 component_t(int r, int lo, int hi, int f=0)
258 : reg_t(r, f), h(hi), l(lo) {
259 }
260 explicit component_t(const integer_t& rhs)
261 : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
262 }
263 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;
274 inline int size() const { return h-l; }
275 };
276
277 struct pointer_t : public reg_t {
278 pointer_t() : reg_t(), size(0) {
279 }
280 pointer_t(int r, int s, int f=0)
281 : 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
290private:
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>
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