GGLAssembler.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  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. #ifndef ANDROID_GGLASSEMBLER_H
  18. #define ANDROID_GGLASSEMBLER_H
  19. #include <stdint.h>
  20. #include <sys/types.h>
  21. #include <private/pixelflinger/ggl_context.h>
  22. #include "ARMAssemblerProxy.h"
  23. namespace android {
  24. // ----------------------------------------------------------------------------
  25. #define CONTEXT_ADDR_LOAD(REG, FIELD) \
  26. ADDR_LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
  27. #define CONTEXT_ADDR_STORE(REG, FIELD) \
  28. ADDR_STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
  29. #define CONTEXT_LOAD(REG, FIELD) \
  30. LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
  31. #define CONTEXT_STORE(REG, FIELD) \
  32. STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD)))
  33. class RegisterAllocator
  34. {
  35. public:
  36. class RegisterFile;
  37. RegisterAllocator(int arch); // NOLINT, implicit
  38. RegisterFile& registerFile();
  39. int reserveReg(int reg);
  40. int obtainReg();
  41. void recycleReg(int reg);
  42. void reset();
  43. class RegisterFile
  44. {
  45. public:
  46. RegisterFile(int arch); // NOLINT, implicit
  47. RegisterFile(const RegisterFile& rhs, int arch);
  48. ~RegisterFile();
  49. void reset();
  50. bool operator == (const RegisterFile& rhs) const;
  51. bool operator != (const RegisterFile& rhs) const {
  52. return !operator == (rhs);
  53. }
  54. int reserve(int reg);
  55. void reserveSeveral(uint32_t regMask);
  56. void recycle(int reg);
  57. void recycleSeveral(uint32_t regMask);
  58. int obtain();
  59. inline int isUsed(int reg) const;
  60. bool hasFreeRegs() const;
  61. int countFreeRegs() const;
  62. uint32_t touched() const;
  63. inline uint32_t status() const { return mStatus; }
  64. enum {
  65. OUT_OF_REGISTERS = 0x1
  66. };
  67. private:
  68. uint32_t mRegs;
  69. uint32_t mTouched;
  70. uint32_t mStatus;
  71. int mArch;
  72. uint32_t mRegisterOffset; // lets reg alloc use 2..17 for mips
  73. // while arm uses 0..15
  74. };
  75. class Scratch
  76. {
  77. public:
  78. explicit Scratch(RegisterFile& regFile)
  79. : mRegFile(regFile), mScratch(0) {
  80. }
  81. ~Scratch() {
  82. mRegFile.recycleSeveral(mScratch);
  83. }
  84. int obtain() {
  85. int reg = mRegFile.obtain();
  86. mScratch |= 1<<reg;
  87. return reg;
  88. }
  89. void recycle(int reg) {
  90. mRegFile.recycle(reg);
  91. mScratch &= ~(1<<reg);
  92. }
  93. bool isUsed(int reg) {
  94. return (mScratch & (1<<reg));
  95. }
  96. int countFreeRegs() {
  97. return mRegFile.countFreeRegs();
  98. }
  99. private:
  100. RegisterFile& mRegFile;
  101. uint32_t mScratch;
  102. };
  103. class Spill
  104. {
  105. public:
  106. Spill(RegisterFile& regFile, ARMAssemblerInterface& gen, uint32_t reglist)
  107. : mRegFile(regFile), mGen(gen), mRegList(reglist), mCount(0)
  108. {
  109. if (reglist) {
  110. int count = 0;
  111. while (reglist) {
  112. count++;
  113. reglist &= ~(1 << (31 - __builtin_clz(reglist)));
  114. }
  115. if (count == 1) {
  116. int reg = 31 - __builtin_clz(mRegList);
  117. mGen.STR(mGen.AL, reg, mGen.SP, mGen.immed12_pre(-4, 1));
  118. } else {
  119. mGen.STM(mGen.AL, mGen.DB, mGen.SP, 1, mRegList);
  120. }
  121. mRegFile.recycleSeveral(mRegList);
  122. mCount = count;
  123. }
  124. }
  125. ~Spill() {
  126. if (mRegList) {
  127. if (mCount == 1) {
  128. int reg = 31 - __builtin_clz(mRegList);
  129. mGen.LDR(mGen.AL, reg, mGen.SP, mGen.immed12_post(4));
  130. } else {
  131. mGen.LDM(mGen.AL, mGen.IA, mGen.SP, 1, mRegList);
  132. }
  133. mRegFile.reserveSeveral(mRegList);
  134. }
  135. }
  136. private:
  137. RegisterFile& mRegFile;
  138. ARMAssemblerInterface& mGen;
  139. uint32_t mRegList;
  140. int mCount;
  141. };
  142. private:
  143. RegisterFile mRegs;
  144. };
  145. // ----------------------------------------------------------------------------
  146. class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator
  147. {
  148. public:
  149. explicit GGLAssembler(ARMAssemblerInterface* target);
  150. virtual ~GGLAssembler();
  151. uint32_t* base() const { return 0; } // XXX
  152. uint32_t* pc() const { return 0; } // XXX
  153. void reset(int opt_level);
  154. virtual void prolog();
  155. virtual void epilog(uint32_t touched);
  156. // generate scanline code for given needs
  157. int scanline(const needs_t& needs, context_t const* c);
  158. int scanline_core(const needs_t& needs, context_t const* c);
  159. enum {
  160. CLEAR_LO = 0x0001,
  161. CLEAR_HI = 0x0002,
  162. CORRUPTIBLE = 0x0004,
  163. FIRST = 0x0008
  164. };
  165. enum { //load/store flags
  166. WRITE_BACK = 0x0001
  167. };
  168. struct reg_t {
  169. reg_t() : reg(-1), flags(0) {
  170. }
  171. reg_t(int r, int f=0) // NOLINT, implicit
  172. : reg(r), flags(f) {
  173. }
  174. void setTo(int r, int f=0) {
  175. reg=r; flags=f;
  176. }
  177. int reg;
  178. uint16_t flags;
  179. };
  180. struct integer_t : public reg_t {
  181. integer_t() : reg_t(), s(0) {
  182. }
  183. integer_t(int r, int sz=32, int f=0) // NOLINT, implicit
  184. : reg_t(r, f), s(sz) {
  185. }
  186. void setTo(int r, int sz=32, int f=0) {
  187. reg_t::setTo(r, f); s=sz;
  188. }
  189. int8_t s;
  190. inline int size() const { return s; }
  191. };
  192. struct pixel_t : public reg_t {
  193. pixel_t() : reg_t() {
  194. memset(&format, 0, sizeof(GGLFormat));
  195. }
  196. pixel_t(int r, const GGLFormat* fmt, int f=0)
  197. : reg_t(r, f), format(*fmt) {
  198. }
  199. void setTo(int r, const GGLFormat* fmt, int f=0) {
  200. reg_t::setTo(r, f); format = *fmt;
  201. }
  202. GGLFormat format;
  203. inline int hi(int c) const { return format.c[c].h; }
  204. inline int low(int c) const { return format.c[c].l; }
  205. inline int mask(int c) const { return ((1<<size(c))-1) << low(c); }
  206. inline int size() const { return format.size*8; }
  207. inline int size(int c) const { return component_size(c); }
  208. inline int component_size(int c) const { return hi(c) - low(c); }
  209. };
  210. struct component_t : public reg_t {
  211. component_t() : reg_t(), h(0), l(0) {
  212. }
  213. component_t(int r, int f=0) // NOLINT, implicit
  214. : reg_t(r, f), h(0), l(0) {
  215. }
  216. component_t(int r, int lo, int hi, int f=0)
  217. : reg_t(r, f), h(hi), l(lo) {
  218. }
  219. explicit component_t(const integer_t& rhs)
  220. : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) {
  221. }
  222. explicit component_t(const pixel_t& rhs, int component) {
  223. setTo( rhs.reg,
  224. rhs.format.c[component].l,
  225. rhs.format.c[component].h,
  226. rhs.flags|CLEAR_LO|CLEAR_HI);
  227. }
  228. void setTo(int r, int lo=0, int hi=0, int f=0) {
  229. reg_t::setTo(r, f); h=hi; l=lo;
  230. }
  231. int8_t h;
  232. int8_t l;
  233. inline int size() const { return h-l; }
  234. };
  235. struct pointer_t : public reg_t {
  236. pointer_t() : reg_t(), size(0) {
  237. }
  238. pointer_t(int r, int s, int f=0)
  239. : reg_t(r, f), size(s) {
  240. }
  241. void setTo(int r, int s, int f=0) {
  242. reg_t::setTo(r, f); size=s;
  243. }
  244. int8_t size;
  245. };
  246. private:
  247. // GGLAssembler hides RegisterAllocator's and ARMAssemblerProxy's reset
  248. // methods by providing a reset method with a different parameter set. The
  249. // intent of GGLAssembler's reset method is to wrap the inherited reset
  250. // methods, so make these methods private in order to prevent direct calls
  251. // to these methods from clients.
  252. using RegisterAllocator::reset;
  253. using ARMAssemblerProxy::reset;
  254. struct tex_coord_t {
  255. reg_t s;
  256. reg_t t;
  257. pointer_t ptr;
  258. };
  259. struct fragment_parts_t {
  260. uint32_t packed : 1;
  261. uint32_t reload : 2;
  262. uint32_t iterated_packed : 1;
  263. pixel_t iterated;
  264. pointer_t cbPtr;
  265. pointer_t covPtr;
  266. reg_t count;
  267. reg_t argb[4];
  268. reg_t argb_dx[4];
  269. reg_t z;
  270. reg_t dither;
  271. pixel_t texel[GGL_TEXTURE_UNIT_COUNT];
  272. tex_coord_t coords[GGL_TEXTURE_UNIT_COUNT];
  273. };
  274. struct texture_unit_t {
  275. int format_idx;
  276. GGLFormat format;
  277. int bits;
  278. int swrap;
  279. int twrap;
  280. int env;
  281. int pot;
  282. int linear;
  283. uint8_t mask;
  284. uint8_t replaced;
  285. };
  286. struct texture_machine_t {
  287. texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT];
  288. uint8_t mask;
  289. uint8_t replaced;
  290. uint8_t directTexture;
  291. uint8_t activeUnits;
  292. };
  293. struct component_info_t {
  294. bool masked : 1;
  295. bool inDest : 1;
  296. bool needed : 1;
  297. bool replaced : 1;
  298. bool iterated : 1;
  299. bool smooth : 1;
  300. bool blend : 1;
  301. bool fog : 1;
  302. };
  303. struct builder_context_t {
  304. context_t const* c;
  305. needs_t needs;
  306. int Rctx;
  307. };
  308. template <typename T>
  309. void modify(T& r, Scratch& regs)
  310. {
  311. if (!(r.flags & CORRUPTIBLE)) {
  312. r.reg = regs.obtain();
  313. r.flags |= CORRUPTIBLE;
  314. }
  315. }
  316. // helpers
  317. void base_offset(const pointer_t& d, const pointer_t& b, const reg_t& o);
  318. // texture environement
  319. void modulate( component_t& dest,
  320. const component_t& incoming,
  321. const pixel_t& texel, int component);
  322. void decal( component_t& dest,
  323. const component_t& incoming,
  324. const pixel_t& texel, int component);
  325. void blend( component_t& dest,
  326. const component_t& incoming,
  327. const pixel_t& texel, int component, int tmu);
  328. void add( component_t& dest,
  329. const component_t& incoming,
  330. const pixel_t& texel, int component);
  331. // load/store stuff
  332. void store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0);
  333. void load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0);
  334. void extract(integer_t& d, const pixel_t& s, int component);
  335. void extract(component_t& d, const pixel_t& s, int component);
  336. void extract(integer_t& d, int s, int h, int l, int bits=32);
  337. void expand(integer_t& d, const integer_t& s, int dbits);
  338. void expand(integer_t& d, const component_t& s, int dbits);
  339. void expand(component_t& d, const component_t& s, int dbits);
  340. void downshift(pixel_t& d, int component, component_t s, const reg_t& dither);
  341. void mul_factor( component_t& d,
  342. const integer_t& v,
  343. const integer_t& f);
  344. void mul_factor_add( component_t& d,
  345. const integer_t& v,
  346. const integer_t& f,
  347. const component_t& a);
  348. void component_add( component_t& d,
  349. const integer_t& dst,
  350. const integer_t& src);
  351. void component_sat( const component_t& v);
  352. void build_scanline_prolog( fragment_parts_t& parts,
  353. const needs_t& needs);
  354. void build_smooth_shade(const fragment_parts_t& parts);
  355. void build_component( pixel_t& pixel,
  356. const fragment_parts_t& parts,
  357. int component,
  358. Scratch& global_scratches);
  359. void build_incoming_component(
  360. component_t& temp,
  361. int dst_size,
  362. const fragment_parts_t& parts,
  363. int component,
  364. Scratch& scratches,
  365. Scratch& global_scratches);
  366. void init_iterated_color(fragment_parts_t& parts, const reg_t& x);
  367. void build_iterated_color( component_t& fragment,
  368. const fragment_parts_t& parts,
  369. int component,
  370. Scratch& regs);
  371. void decodeLogicOpNeeds(const needs_t& needs);
  372. void decodeTMUNeeds(const needs_t& needs, context_t const* c);
  373. void init_textures( tex_coord_t* coords,
  374. const reg_t& x,
  375. const reg_t& y);
  376. void build_textures( fragment_parts_t& parts,
  377. Scratch& regs);
  378. void filter8( const fragment_parts_t& parts,
  379. pixel_t& texel, const texture_unit_t& tmu,
  380. int U, int V, pointer_t& txPtr,
  381. int FRAC_BITS);
  382. void filter16( const fragment_parts_t& parts,
  383. pixel_t& texel, const texture_unit_t& tmu,
  384. int U, int V, pointer_t& txPtr,
  385. int FRAC_BITS);
  386. void filter24( const fragment_parts_t& parts,
  387. pixel_t& texel, const texture_unit_t& tmu,
  388. int U, int V, pointer_t& txPtr,
  389. int FRAC_BITS);
  390. void filter32( const fragment_parts_t& parts,
  391. pixel_t& texel, const texture_unit_t& tmu,
  392. int U, int V, pointer_t& txPtr,
  393. int FRAC_BITS);
  394. void build_texture_environment( component_t& fragment,
  395. const fragment_parts_t& parts,
  396. int component,
  397. Scratch& regs);
  398. void wrapping( int d,
  399. int coord, int size,
  400. int tx_wrap, int tx_linear);
  401. void build_fog( component_t& temp,
  402. int component,
  403. Scratch& parent_scratches);
  404. void build_blending( component_t& in_out,
  405. const pixel_t& pixel,
  406. int component,
  407. Scratch& parent_scratches);
  408. void build_blend_factor(
  409. integer_t& factor, int f, int component,
  410. const pixel_t& dst_pixel,
  411. integer_t& fragment,
  412. integer_t& fb,
  413. Scratch& scratches);
  414. void build_blendFOneMinusF( component_t& temp,
  415. const integer_t& factor,
  416. const integer_t& fragment,
  417. const integer_t& fb);
  418. void build_blendOneMinusFF( component_t& temp,
  419. const integer_t& factor,
  420. const integer_t& fragment,
  421. const integer_t& fb);
  422. void build_coverage_application(component_t& fragment,
  423. const fragment_parts_t& parts,
  424. Scratch& regs);
  425. void build_alpha_test(component_t& fragment, const fragment_parts_t& parts);
  426. enum { Z_TEST=1, Z_WRITE=2 };
  427. void build_depth_test(const fragment_parts_t& parts, uint32_t mask);
  428. void build_iterate_z(const fragment_parts_t& parts);
  429. void build_iterate_f(const fragment_parts_t& parts);
  430. void build_iterate_texture_coordinates(const fragment_parts_t& parts);
  431. void build_logic_op(pixel_t& pixel, Scratch& regs);
  432. void build_masking(pixel_t& pixel, Scratch& regs);
  433. void build_and_immediate(int d, int s, uint32_t mask, int bits);
  434. bool isAlphaSourceNeeded() const;
  435. enum {
  436. FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8
  437. };
  438. enum {
  439. LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4
  440. };
  441. static int blending_codes(int fs, int fd);
  442. builder_context_t mBuilderContext;
  443. texture_machine_t mTextureMachine;
  444. component_info_t mInfo[4];
  445. int mBlending;
  446. int mMasking;
  447. int mAllMasked;
  448. int mLogicOp;
  449. int mAlphaTest;
  450. int mAA;
  451. int mDithering;
  452. int mDepthTest;
  453. int mSmooth;
  454. int mFog;
  455. pixel_t mDstPixel;
  456. GGLFormat mCbFormat;
  457. int mBlendFactorCached;
  458. integer_t mAlphaSource;
  459. int mBaseRegister;
  460. int mBlendSrc;
  461. int mBlendDst;
  462. int mBlendSrcA;
  463. int mBlendDstA;
  464. int mOptLevel;
  465. };
  466. // ----------------------------------------------------------------------------
  467. }; // namespace android
  468. #endif // ANDROID_GGLASSEMBLER_H