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 "codeflinger/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 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 160 private: 161 RegisterFile mRegs; 162 }; 163 164 // ---------------------------------------------------------------------------- 165 166 class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator 167 { 168 public: 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 280 private: 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 void add( component_t& dest, 367 const component_t& incoming, 368 const pixel_t& texel, int component); 369 370 // load/store stuff 371 void store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0); 372 void load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0); 373 void extract(integer_t& d, const pixel_t& s, int component); 374 void extract(component_t& d, const pixel_t& s, int component); 375 void extract(integer_t& d, int s, int h, int l, int bits=32); 376 void expand(integer_t& d, const integer_t& s, int dbits); 377 void expand(integer_t& d, const component_t& s, int dbits); 378 void expand(component_t& d, const component_t& s, int dbits); 379 void downshift(pixel_t& d, int component, component_t s, const reg_t& dither); 380 381 382 void mul_factor( component_t& d, 383 const integer_t& v, 384 const integer_t& f); 385 386 void mul_factor_add( component_t& d, 387 const integer_t& v, 388 const integer_t& f, 389 const component_t& a); 390 391 void component_add( component_t& d, 392 const integer_t& dst, 393 const integer_t& src); 394 395 void component_sat( const component_t& v); 396 397 398 void build_scanline_prolog( fragment_parts_t& parts, 399 const needs_t& needs); 400 401 void build_smooth_shade(const fragment_parts_t& parts); 402 403 void build_component( pixel_t& pixel, 404 const fragment_parts_t& parts, 405 int component, 406 Scratch& global_scratches); 407 408 void build_incoming_component( 409 component_t& temp, 410 int dst_size, 411 const fragment_parts_t& parts, 412 int component, 413 Scratch& scratches, 414 Scratch& global_scratches); 415 416 void init_iterated_color(fragment_parts_t& parts, const reg_t& x); 417 418 void build_iterated_color( component_t& fragment, 419 const fragment_parts_t& parts, 420 int component, 421 Scratch& regs); 422 423 void decodeLogicOpNeeds(const needs_t& needs); 424 425 void decodeTMUNeeds(const needs_t& needs, context_t const* c); 426 427 void init_textures( tex_coord_t* coords, 428 const reg_t& x, 429 const reg_t& y); 430 431 void build_textures( fragment_parts_t& parts, 432 Scratch& regs); 433 434 void filter8( const fragment_parts_t& parts, 435 pixel_t& texel, const texture_unit_t& tmu, 436 int U, int V, pointer_t& txPtr, 437 int FRAC_BITS); 438 439 void filter16( const fragment_parts_t& parts, 440 pixel_t& texel, const texture_unit_t& tmu, 441 int U, int V, pointer_t& txPtr, 442 int FRAC_BITS); 443 444 void filter24( 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 filter32( 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 build_texture_environment( component_t& fragment, 455 const fragment_parts_t& parts, 456 int component, 457 Scratch& regs); 458 459 void wrapping( int d, 460 int coord, int size, 461 int tx_wrap, int tx_linear); 462 463 void build_fog( component_t& temp, 464 int component, 465 Scratch& parent_scratches); 466 467 void build_blending( component_t& in_out, 468 const pixel_t& pixel, 469 int component, 470 Scratch& parent_scratches); 471 472 void build_blend_factor( 473 integer_t& factor, int f, int component, 474 const pixel_t& dst_pixel, 475 integer_t& fragment, 476 integer_t& fb, 477 Scratch& scratches); 478 479 void build_blendFOneMinusF( component_t& temp, 480 const integer_t& factor, 481 const integer_t& fragment, 482 const integer_t& fb); 483 484 void build_blendOneMinusFF( component_t& temp, 485 const integer_t& factor, 486 const integer_t& fragment, 487 const integer_t& fb); 488 489 void build_coverage_application(component_t& fragment, 490 const fragment_parts_t& parts, 491 Scratch& regs); 492 493 void build_alpha_test(component_t& fragment, const fragment_parts_t& parts); 494 495 enum { Z_TEST=1, Z_WRITE=2 }; 496 void build_depth_test(const fragment_parts_t& parts, uint32_t mask); 497 void build_iterate_z(const fragment_parts_t& parts); 498 void build_iterate_f(const fragment_parts_t& parts); 499 void build_iterate_texture_coordinates(const fragment_parts_t& parts); 500 501 void build_logic_op(pixel_t& pixel, Scratch& regs); 502 503 void build_masking(pixel_t& pixel, Scratch& regs); 504 505 void build_and_immediate(int d, int s, uint32_t mask, int bits); 506 507 bool isAlphaSourceNeeded() const; 508 509 enum { 510 FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8 511 }; 512 513 enum { 514 LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4 515 }; 516 517 static int blending_codes(int fs, int fd); 518 519 builder_context_t mBuilderContext; 520 texture_machine_t mTextureMachine; 521 component_info_t mInfo[4]; 522 int mBlending; 523 int mMasking; 524 int mAllMasked; 525 int mLogicOp; 526 int mAlphaTest; 527 int mAA; 528 int mDithering; 529 int mDepthTest; 530 531 int mSmooth; 532 int mFog; 533 pixel_t mDstPixel; 534 535 GGLFormat mCbFormat; 536 537 int mBlendFactorCached; 538 integer_t mAlphaSource; 539 540 int mBaseRegister; 541 542 int mBlendSrc; 543 int mBlendDst; 544 int mBlendSrcA; 545 int mBlendDstA; 546 547 int mOptLevel; 548 }; 549 550 // ---------------------------------------------------------------------------- 551 552 }; // namespace android 553 554 #endif // ANDROID_GGLASSEMBLER_H 555