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