blob: 47dbf3a3342fe3aeddda3d4838b37d1d61851362 [file] [log] [blame]
bigbiff673c7ae2020-12-02 19:44:56 -05001/* 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
30namespace android {
31
32// ----------------------------------------------------------------------------
33
34#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
40#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
52 RegisterAllocator(int arch); // NOLINT, implicit
53 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:
62 RegisterFile(int arch); // NOLINT, implicit
63 RegisterFile(const RegisterFile& rhs, int arch);
64 ~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;
96 int mArch;
97 uint32_t mRegisterOffset; // lets reg alloc use 2..17 for mips
98 // while arm uses 0..15
99 };
100
101 class Scratch
102 {
103 public:
104 explicit 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 explicit 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) // NOLINT, implicit
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) // NOLINT, implicit
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) // NOLINT, implicit
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 // GGLAssembler hides RegisterAllocator's and ARMAssemblerProxy's reset
292 // methods by providing a reset method with a different parameter set. The
293 // intent of GGLAssembler's reset method is to wrap the inherited reset
294 // methods, so make these methods private in order to prevent direct calls
295 // to these methods from clients.
296 using RegisterAllocator::reset;
297 using ARMAssemblerProxy::reset;
298
299 struct tex_coord_t {
300 reg_t s;
301 reg_t t;
302 pointer_t ptr;
303 };
304
305 struct fragment_parts_t {
306 uint32_t packed : 1;
307 uint32_t reload : 2;
308 uint32_t iterated_packed : 1;
309 pixel_t iterated;
310 pointer_t cbPtr;
311 pointer_t covPtr;
312 reg_t count;
313 reg_t argb[4];
314 reg_t argb_dx[4];
315 reg_t z;
316 reg_t dither;
317 pixel_t texel[GGL_TEXTURE_UNIT_COUNT];
318 tex_coord_t coords[GGL_TEXTURE_UNIT_COUNT];
319 };
320
321 struct texture_unit_t {
322 int format_idx;
323 GGLFormat format;
324 int bits;
325 int swrap;
326 int twrap;
327 int env;
328 int pot;
329 int linear;
330 uint8_t mask;
331 uint8_t replaced;
332 };
333
334 struct texture_machine_t {
335 texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT];
336 uint8_t mask;
337 uint8_t replaced;
338 uint8_t directTexture;
339 uint8_t activeUnits;
340 };
341
342 struct component_info_t {
343 bool masked : 1;
344 bool inDest : 1;
345 bool needed : 1;
346 bool replaced : 1;
347 bool iterated : 1;
348 bool smooth : 1;
349 bool blend : 1;
350 bool fog : 1;
351 };
352
353 struct builder_context_t {
354 context_t const* c;
355 needs_t needs;
356 int Rctx;
357 };
358
359 template <typename T>
360 void modify(T& r, Scratch& regs)
361 {
362 if (!(r.flags & CORRUPTIBLE)) {
363 r.reg = regs.obtain();
364 r.flags |= CORRUPTIBLE;
365 }
366 }
367
368 // helpers
369 void base_offset(const pointer_t& d, const pointer_t& b, const reg_t& o);
370
371 // texture environement
372 void modulate( component_t& dest,
373 const component_t& incoming,
374 const pixel_t& texel, int component);
375
376 void decal( component_t& dest,
377 const component_t& incoming,
378 const pixel_t& texel, int component);
379
380 void blend( component_t& dest,
381 const component_t& incoming,
382 const pixel_t& texel, int component, int tmu);
383
384 void add( component_t& dest,
385 const component_t& incoming,
386 const pixel_t& texel, int component);
387
388 // load/store stuff
389 void store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
390 void load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
391 void extract(integer_t& d, const pixel_t& s, int component);
392 void extract(component_t& d, const pixel_t& s, int component);
393 void extract(integer_t& d, int s, int h, int l, int bits=32);
394 void expand(integer_t& d, const integer_t& s, int dbits);
395 void expand(integer_t& d, const component_t& s, int dbits);
396 void expand(component_t& d, const component_t& s, int dbits);
397 void downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
398
399
400 void mul_factor( component_t& d,
401 const integer_t& v,
402 const integer_t& f);
403
404 void mul_factor_add( component_t& d,
405 const integer_t& v,
406 const integer_t& f,
407 const component_t& a);
408
409 void component_add( component_t& d,
410 const integer_t& dst,
411 const integer_t& src);
412
413 void component_sat( const component_t& v);
414
415
416 void build_scanline_prolog( fragment_parts_t& parts,
417 const needs_t& needs);
418
419 void build_smooth_shade(const fragment_parts_t& parts);
420
421 void build_component( pixel_t& pixel,
422 const fragment_parts_t& parts,
423 int component,
424 Scratch& global_scratches);
425
426 void build_incoming_component(
427 component_t& temp,
428 int dst_size,
429 const fragment_parts_t& parts,
430 int component,
431 Scratch& scratches,
432 Scratch& global_scratches);
433
434 void init_iterated_color(fragment_parts_t& parts, const reg_t& x);
435
436 void build_iterated_color( component_t& fragment,
437 const fragment_parts_t& parts,
438 int component,
439 Scratch& regs);
440
441 void decodeLogicOpNeeds(const needs_t& needs);
442
443 void decodeTMUNeeds(const needs_t& needs, context_t const* c);
444
445 void init_textures( tex_coord_t* coords,
446 const reg_t& x,
447 const reg_t& y);
448
449 void build_textures( fragment_parts_t& parts,
450 Scratch& regs);
451
452 void filter8( const fragment_parts_t& parts,
453 pixel_t& texel, const texture_unit_t& tmu,
454 int U, int V, pointer_t& txPtr,
455 int FRAC_BITS);
456
457 void filter16( const fragment_parts_t& parts,
458 pixel_t& texel, const texture_unit_t& tmu,
459 int U, int V, pointer_t& txPtr,
460 int FRAC_BITS);
461
462 void filter24( const fragment_parts_t& parts,
463 pixel_t& texel, const texture_unit_t& tmu,
464 int U, int V, pointer_t& txPtr,
465 int FRAC_BITS);
466
467 void filter32( const fragment_parts_t& parts,
468 pixel_t& texel, const texture_unit_t& tmu,
469 int U, int V, pointer_t& txPtr,
470 int FRAC_BITS);
471
472 void build_texture_environment( component_t& fragment,
473 const fragment_parts_t& parts,
474 int component,
475 Scratch& regs);
476
477 void wrapping( int d,
478 int coord, int size,
479 int tx_wrap, int tx_linear);
480
481 void build_fog( component_t& temp,
482 int component,
483 Scratch& parent_scratches);
484
485 void build_blending( component_t& in_out,
486 const pixel_t& pixel,
487 int component,
488 Scratch& parent_scratches);
489
490 void build_blend_factor(
491 integer_t& factor, int f, int component,
492 const pixel_t& dst_pixel,
493 integer_t& fragment,
494 integer_t& fb,
495 Scratch& scratches);
496
497 void build_blendFOneMinusF( component_t& temp,
498 const integer_t& factor,
499 const integer_t& fragment,
500 const integer_t& fb);
501
502 void build_blendOneMinusFF( component_t& temp,
503 const integer_t& factor,
504 const integer_t& fragment,
505 const integer_t& fb);
506
507 void build_coverage_application(component_t& fragment,
508 const fragment_parts_t& parts,
509 Scratch& regs);
510
511 void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
512
513 enum { Z_TEST=1, Z_WRITE=2 };
514 void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
515 void build_iterate_z(const fragment_parts_t& parts);
516 void build_iterate_f(const fragment_parts_t& parts);
517 void build_iterate_texture_coordinates(const fragment_parts_t& parts);
518
519 void build_logic_op(pixel_t& pixel, Scratch& regs);
520
521 void build_masking(pixel_t& pixel, Scratch& regs);
522
523 void build_and_immediate(int d, int s, uint32_t mask, int bits);
524
525 bool isAlphaSourceNeeded() const;
526
527 enum {
528 FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
529 };
530
531 enum {
532 LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
533 };
534
535 static int blending_codes(int fs, int fd);
536
537 builder_context_t mBuilderContext;
538 texture_machine_t mTextureMachine;
539 component_info_t mInfo[4];
540 int mBlending;
541 int mMasking;
542 int mAllMasked;
543 int mLogicOp;
544 int mAlphaTest;
545 int mAA;
546 int mDithering;
547 int mDepthTest;
548
549 int mSmooth;
550 int mFog;
551 pixel_t mDstPixel;
552
553 GGLFormat mCbFormat;
554
555 int mBlendFactorCached;
556 integer_t mAlphaSource;
557
558 int mBaseRegister;
559
560 int mBlendSrc;
561 int mBlendDst;
562 int mBlendSrcA;
563 int mBlendDstA;
564
565 int mOptLevel;
566};
567
568// ----------------------------------------------------------------------------
569
570}; // namespace android
571
572#endif // ANDROID_GGLASSEMBLER_H