blob: d993684048c7544cdab3d6834647091c43d8442a [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
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
41class RegisterAllocator
42{
43public:
44 class RegisterFile;
45
Paul Lind2bc2b792012-02-01 10:54:19 -080046 RegisterAllocator(int arch);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080047 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:
Paul Lind2bc2b792012-02-01 10:54:19 -080056 RegisterFile(int arch);
57 RegisterFile(const RegisterFile& rhs, int arch);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080058 ~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;
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;
Paul Lind2bc2b792012-02-01 10:54:19 -080090 int mArch;
91 uint32_t mRegisterOffset; // lets reg alloc use 2..17 for mips
92 // while arm uses 0..15
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080093 };
94
95 class Scratch
96 {
97 public:
98 Scratch(RegisterFile& regFile)
99 : mRegFile(regFile), mScratch(0) {
100 }
101 ~Scratch() {
102 mRegFile.recycleSeveral(mScratch);
103 }
104 int obtain() {
105 int reg = mRegFile.obtain();
106 mScratch |= 1<<reg;
107 return reg;
108 }
109 void recycle(int reg) {
110 mRegFile.recycle(reg);
111 mScratch &= ~(1<<reg);
112 }
113 bool isUsed(int reg) {
114 return (mScratch & (1<<reg));
115 }
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:
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 }
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
164private:
165 RegisterFile mRegs;
166};
167
168// ----------------------------------------------------------------------------
169
170class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
171{
172public:
173
174 GGLAssembler(ARMAssemblerInterface* target);
175 virtual ~GGLAssembler();
176
177 uint32_t* base() const { return 0; } // XXX
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 {
201 reg_t() : reg(-1), flags(0) {
202 }
203 reg_t(int r, int f=0)
204 : 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 {
214 integer_t() : reg_t(), s(0) {
215 }
216 integer_t(int r, int sz=32, int f=0)
217 : 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;
223 inline int size() const { return s; }
224 };
225
226 struct pixel_t : public reg_t {
227 pixel_t() : reg_t() {
228 memset(&format, 0, sizeof(GGLFormat));
229 }
230 pixel_t(int r, const GGLFormat* fmt, int f=0)
231 : 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;
237 inline int hi(int c) const { return format.c[c].h; }
238 inline int low(int c) const { return format.c[c].l; }
239 inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
240 inline int size() const { return format.size*8; }
241 inline int size(int c) const { return component_size(c); }
242 inline int component_size(int c) const { return hi(c) - low(c); }
243 };
244
245 struct component_t : public reg_t {
246 component_t() : reg_t(), h(0), l(0) {
247 }
248 component_t(int r, int f=0)
249 : reg_t(r, f), h(0), l(0) {
250 }
251 component_t(int r, int lo, int hi, int f=0)
252 : reg_t(r, f), h(hi), l(lo) {
253 }
254 explicit component_t(const integer_t& rhs)
255 : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
256 }
257 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;
268 inline int size() const { return h-l; }
269 };
270
271 struct pointer_t : public reg_t {
272 pointer_t() : reg_t(), size(0) {
273 }
274 pointer_t(int r, int s, int f=0)
275 : 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
284private:
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>
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