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 "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 RegisterAllocator(int arch); 47 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: 56 RegisterFile(int arch); 57 RegisterFile(const RegisterFile& rhs, int arch); 58 ~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; 90 int mArch; 91 uint32_t mRegisterOffset; // lets reg alloc use 2..17 for mips 92 // while arm uses 0..15 93 }; 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 164 private: 165 RegisterFile mRegs; 166 }; 167 168 // ---------------------------------------------------------------------------- 169 170 class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator 171 { 172 public: 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 284 private: 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 559