PageRenderTime 70ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/opengles/src/arm/GenFragment.cpp

http://ftk.googlecode.com/
C++ | 1978 lines | 1288 code | 377 blank | 313 comment | 87 complexity | d22088b30f83520be38c8b2b8402e417 MD5 | raw file
Possible License(s): LGPL-3.0
  1. // ==========================================================================
  2. //
  3. // GenFragment.cpp JIT Class for 3D Rendering Library
  4. //
  5. // This file contains the rasterizer functions that
  6. // implement the runtime code generation support
  7. // for optimized scan line rasterization routines.
  8. //
  9. // --------------------------------------------------------------------------
  10. //
  11. // 12-29-2003 Hans-Martin Will initial version
  12. //
  13. // --------------------------------------------------------------------------
  14. //
  15. // Copyright (c) 2004, Hans-Martin Will. All rights reserved.
  16. //
  17. // Redistribution and use in source and binary forms, with or without
  18. // modification, are permitted provided that the following conditions are
  19. // met:
  20. //
  21. // * Redistributions of source code must retain the above copyright
  22. // notice, this list of conditions and the following disclaimer.
  23. // * Redistributions in binary form must reproduce the above copyright
  24. // notice, this list of conditions and the following disclaimer in the
  25. // documentation and/or other materials provided with the distribution.
  26. //
  27. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  32. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  37. // THE POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. // ==========================================================================
  40. #include "stdafx.h"
  41. #include "CodeGenerator.h"
  42. #include "Rasterizer.h"
  43. #include "FunctionCache.h"
  44. #include "Surface.h"
  45. #include "Texture.h"
  46. #include "codegen.h"
  47. #include "instruction.h"
  48. #include "emit.h"
  49. #include "arm-dis.h"
  50. using namespace EGL;
  51. namespace {
  52. inline cg_virtual_reg_t * LOAD_DATA(cg_block_t * block, cg_virtual_reg_t * base, I32 constant) {
  53. cg_virtual_reg_t * offset = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  54. cg_virtual_reg_t * addr = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  55. cg_virtual_reg_t * value = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  56. LDI(offset, constant);
  57. ADD(addr, base, offset);
  58. LDW(value, addr);
  59. return value;
  60. }
  61. #define ALLOC_REG(reg) reg = cg_virtual_reg_create(procedure, cg_reg_type_general)
  62. #define ALLOC_FLAGS(reg) reg = cg_virtual_reg_create(procedure, cg_reg_type_flags)
  63. #define DECL_REG(reg) cg_virtual_reg_t * reg = cg_virtual_reg_create(procedure, cg_reg_type_general)
  64. #define DECL_FLAGS(reg) cg_virtual_reg_t * reg = cg_virtual_reg_create(procedure, cg_reg_type_flags)
  65. #define DECL_CONST_REG(reg, value) cg_virtual_reg_t * reg = cg_virtual_reg_create(procedure, cg_reg_type_general); LDI(reg, value)
  66. }
  67. void CodeGenerator :: FetchTexColor(cg_proc_t * procedure, cg_block_t * currentBlock,
  68. const RasterizerState::TextureState * textureState,
  69. cg_virtual_reg_t * regTextureData,
  70. cg_virtual_reg_t * regTexOffset,
  71. cg_virtual_reg_t *& regTexColorR,
  72. cg_virtual_reg_t *& regTexColorG,
  73. cg_virtual_reg_t *& regTexColorB,
  74. cg_virtual_reg_t *& regTexColorA,
  75. cg_virtual_reg_t *& regTexColor565) {
  76. cg_block_t * block = currentBlock;
  77. switch (textureState->InternalFormat) {
  78. case RasterizerState::TextureFormatAlpha: // 8
  79. {
  80. //texColor = Color(0, 0, 0, reinterpret_cast<const U8 *>(data)[texOffset]);
  81. regTexColorR = regTexColorG = regTexColorB = cg_virtual_reg_create(procedure, cg_reg_type_general);
  82. regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  83. regTexColor565 = cg_virtual_reg_create(procedure, cg_reg_type_general);
  84. DECL_REG (regTexAddr);
  85. ADD (regTexAddr, regTexOffset, regTextureData);
  86. LDB (regTexColorA, regTexAddr);
  87. LDI (regTexColorR, 0);
  88. LDI (regTexColor565, 0);
  89. }
  90. break;
  91. case RasterizerState::TextureFormatLuminance: // 8
  92. {
  93. //U8 luminance = reinterpret_cast<const U8 *>(data)[texOffset];
  94. //texColor = Color (luminance, luminance, luminance, 0xff);
  95. regTexColorR = regTexColorB = regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
  96. regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  97. DECL_REG (regTexAddr);
  98. ADD (regTexAddr, regTexOffset, regTextureData);
  99. LDB (regTexColorR, regTexAddr);
  100. LDI (regTexColorA, 0xff);
  101. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  102. }
  103. break;
  104. case RasterizerState::TextureFormatLuminanceAlpha: // 8-8
  105. {
  106. //U8 luminance = reinterpret_cast<const U8 *>(data)[texOffset * 2];
  107. //U8 alpha = reinterpret_cast<const U8 *>(data)[texOffset * 2 + 1];
  108. //texColor = Color (luminance, luminance, luminance, alpha);
  109. regTexColorR = regTexColorB = regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
  110. regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  111. DECL_REG (regScaledOffset);
  112. DECL_REG (regTexAddr);
  113. DECL_REG (regTexAddr1);
  114. DECL_CONST_REG (regConstantOne, 1);
  115. LSL (regScaledOffset, regTexOffset, regConstantOne);
  116. ADD (regTexAddr, regScaledOffset, regTextureData);
  117. LDB (regTexColorR, regTexAddr);
  118. ADD (regTexAddr1, regTexAddr, regConstantOne);
  119. LDB (regTexColorA, regTexAddr1);
  120. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  121. }
  122. break;
  123. case RasterizerState::TextureFormatRGB565: // 5-6-5
  124. //texColor = Color::From565(reinterpret_cast<const U16 *>(data)[texOffset]);
  125. {
  126. regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  127. regTexColor565 = cg_virtual_reg_create(procedure, cg_reg_type_general);
  128. DECL_REG (regScaledOffset);
  129. DECL_REG (regConstantOne);
  130. DECL_REG (regTexAddr);
  131. LDI (regConstantOne, 1);
  132. LSL (regScaledOffset, regTexOffset, regConstantOne);
  133. ADD (regTexAddr, regScaledOffset, regTextureData);
  134. LDH (regTexColor565, regTexAddr);
  135. LDI (regTexColorA, 0xff);
  136. regTexColorR = ExtractBitFieldTo255(block, regTexColor565, 11, 15);
  137. regTexColorG = ExtractBitFieldTo255(block, regTexColor565, 5, 10);
  138. regTexColorB = ExtractBitFieldTo255(block, regTexColor565, 0, 4);
  139. }
  140. break;
  141. case RasterizerState::TextureFormatRGB8: // 8-8-8
  142. {
  143. regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  144. regTexColorR = cg_virtual_reg_create(procedure, cg_reg_type_general);
  145. regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
  146. regTexColorB = cg_virtual_reg_create(procedure, cg_reg_type_general);
  147. DECL_REG (regConstant1);
  148. DECL_REG (regConstant2);
  149. DECL_REG (regConstant3);
  150. DECL_REG (regShiftedOffset);
  151. DECL_REG (regScaledOffset);
  152. DECL_REG (regTexAddr0);
  153. DECL_REG (regTexAddr1);
  154. DECL_REG (regTexAddr2);
  155. LDI (regTexColorA, 0xff);
  156. LDI (regConstant1, 1);
  157. LDI (regConstant2, 2);
  158. LDI (regConstant3, 3);
  159. LSL (regShiftedOffset, regTexOffset, regConstant1);
  160. ADD (regScaledOffset, regTexOffset, regShiftedOffset);
  161. ADD (regTexAddr0, regTextureData, regScaledOffset);
  162. LDB (regTexColorR, regTexAddr0);
  163. ADD (regTexAddr1, regTexAddr0, regConstant1);
  164. LDB (regTexColorG, regTexAddr1);
  165. ADD (regTexAddr2, regTexAddr0, regConstant2);
  166. LDB (regTexColorB, regTexAddr2);
  167. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  168. }
  169. break;
  170. case RasterizerState::TextureFormatRGBA4444: // 4-4-4-4
  171. {
  172. DECL_REG (regScaledOffset);
  173. DECL_REG (regConstantOne);
  174. DECL_REG (regTexAddr);
  175. DECL_REG (regTexColor4444);
  176. LDI (regConstantOne, 1);
  177. LSL (regScaledOffset, regTexOffset, regConstantOne);
  178. ADD (regTexAddr, regScaledOffset, regTextureData);
  179. LDH (regTexColor4444, regTexAddr);
  180. regTexColorR = ExtractBitFieldTo255(block, regTexColor4444, 12, 15);
  181. regTexColorG = ExtractBitFieldTo255(block, regTexColor4444, 8, 11);
  182. regTexColorB = ExtractBitFieldTo255(block, regTexColor4444, 4, 7);
  183. regTexColorA = ExtractBitFieldTo255(block, regTexColor4444, 0, 3);
  184. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  185. }
  186. break;
  187. case RasterizerState::TextureFormatRGBA8: // 8-8-8-8
  188. {
  189. regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  190. regTexColorR = cg_virtual_reg_create(procedure, cg_reg_type_general);
  191. regTexColorG = cg_virtual_reg_create(procedure, cg_reg_type_general);
  192. regTexColorB = cg_virtual_reg_create(procedure, cg_reg_type_general);
  193. DECL_REG (regConstant1);
  194. DECL_REG (regConstant2);
  195. DECL_REG (regConstant3);
  196. DECL_REG (regConstant7);
  197. DECL_REG (regScaledOffset);
  198. DECL_REG (regTexAddr0);
  199. DECL_REG (regTexAddr1);
  200. DECL_REG (regTexAddr2);
  201. DECL_REG (regTexAddr3);
  202. LDI (regConstant1, 1);
  203. LDI (regConstant2, 2);
  204. LDI (regConstant3, 3);
  205. LDI (regConstant7, 7);
  206. LSL (regScaledOffset, regTexOffset, regConstant2);
  207. ADD (regTexAddr0, regTextureData, regScaledOffset);
  208. LDB (regTexColorR, regTexAddr0);
  209. ADD (regTexAddr1, regTexAddr0, regConstant1);
  210. LDB (regTexColorG, regTexAddr1);
  211. ADD (regTexAddr2, regTexAddr0, regConstant2);
  212. LDB (regTexColorB, regTexAddr2);
  213. ADD (regTexAddr3, regTexAddr0, regConstant3);
  214. LDB (regTexColorA, regTexAddr3);
  215. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  216. }
  217. break;
  218. case RasterizerState::TextureFormatRGBA5551: // 5-5-5-1
  219. //texColor = Color::From5551(reinterpret_cast<const U16 *>(data)[texOffset]);
  220. {
  221. DECL_REG (regScaledOffset);
  222. DECL_REG (regConstantOne);
  223. DECL_REG (regTexAddr);
  224. DECL_REG (regTexColor5551);
  225. LDI (regConstantOne, 1);
  226. LSL (regScaledOffset, regTexOffset, regConstantOne);
  227. ADD (regTexAddr, regScaledOffset, regTextureData);
  228. LDH (regTexColor5551, regTexAddr);
  229. regTexColorR = ExtractBitFieldTo255(block, regTexColor5551, 11, 15);
  230. regTexColorG = ExtractBitFieldTo255(block, regTexColor5551, 7, 10);
  231. regTexColorB = ExtractBitFieldTo255(block, regTexColor5551, 1, 5);
  232. regTexColorA = ExtractBitFieldTo255(block, regTexColor5551, 0, 0);
  233. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  234. }
  235. break;
  236. default:
  237. //texColor = Color(0xff, 0xff, 0xff, 0xff);
  238. {
  239. regTexColorR = regTexColorB = regTexColorG = regTexColorA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  240. regTexColor565 = cg_virtual_reg_create(procedure, cg_reg_type_general);
  241. LDI (regTexColorR, 0xff);
  242. LDI (regTexColor565, 0xffff);
  243. }
  244. break;
  245. }
  246. }
  247. namespace {
  248. void WrapOrClamp(cg_proc_t * procedure, cg_block_t * block,
  249. cg_virtual_reg_t * regIn,
  250. cg_virtual_reg_t * regOut,
  251. cg_virtual_reg_t * regMask,
  252. RasterizerState::WrappingMode mode) {
  253. switch (mode) {
  254. case RasterizerState::WrappingModeClampToEdge:
  255. //tu0 = EGL_CLAMP(tu, 0, EGL_ONE);
  256. {
  257. DECL_REG (regConstantZero);
  258. DECL_REG (regTemp);
  259. LDI (regConstantZero, EGL_FixedFromInt(0));
  260. MIN (regTemp, regIn, regMask);
  261. MAX (regOut, regTemp, regConstantZero);
  262. }
  263. break;
  264. default:
  265. case RasterizerState::WrappingModeRepeat:
  266. //tu0 = tu & 0xffff;
  267. {
  268. AND (regOut, regIn, regMask);
  269. }
  270. break;
  271. }
  272. }
  273. cg_virtual_reg_t * BlendComponent(cg_proc_t * procedure, cg_block_t * block,
  274. cg_virtual_reg_t *regA, cg_virtual_reg_t *regB,
  275. cg_virtual_reg_t * regAlpha) {
  276. DECL_REG (regDiff);
  277. DECL_REG (regProduct);
  278. DECL_REG (regConstant8);
  279. DECL_REG (regShifted);
  280. DECL_REG (regResult);
  281. SUB (regDiff, regB, regA);
  282. MUL (regProduct, regDiff, regAlpha);
  283. LDI (regConstant8, 8);
  284. ASR (regShifted, regProduct, regConstant8);
  285. ADD (regResult, regA, regShifted);
  286. return regResult;
  287. }
  288. }
  289. void CodeGenerator :: GenerateFetchTexColor(cg_proc_t * procedure, cg_block_t * currentBlock,
  290. size_t unit,
  291. FragmentGenerationInfo & fragmentInfo,
  292. cg_virtual_reg_t *& regTexColorR,
  293. cg_virtual_reg_t *& regTexColorG,
  294. cg_virtual_reg_t *& regTexColorB,
  295. cg_virtual_reg_t *& regTexColorA,
  296. cg_virtual_reg_t *& regTexColor565) {
  297. cg_block_t * block = currentBlock;
  298. cg_virtual_reg_t * regU = fragmentInfo.regU[unit];
  299. cg_virtual_reg_t * regV = fragmentInfo.regV[unit];
  300. //EGL_Fixed tu0;
  301. //EGL_Fixed tv0;
  302. if (m_State->GetMinFilterMode(unit) == RasterizerState::FilterModeNearest) {
  303. DECL_REG (regU0);
  304. DECL_REG (regV0);
  305. DECL_REG (regMask);
  306. LDI (regMask, 0xffff);
  307. WrapOrClamp(procedure, block, regU, regU0, regMask, m_State->m_Texture[unit].WrappingModeS);
  308. WrapOrClamp(procedure, block, regV, regV0, regMask, m_State->m_Texture[unit].WrappingModeT);
  309. // get the pixel color
  310. //Texture * texture = m_Texture->GetTexture(m_MipMapLevel);
  311. //cg_virtual_reg_t * texX = EGL_IntFromFixed(texture->GetWidth() * tu0);
  312. //cg_virtual_reg_t * texY = EGL_IntFromFixed(texture->GetHeight() * tv0);
  313. //cg_virtual_reg_t * texOffset = texX + (texY << texture->GetExponent());
  314. //void * data = texture->GetData();
  315. DECL_REG (regScaledU);
  316. DECL_REG (regTexX);
  317. DECL_REG (regScaledV);
  318. DECL_REG (regTexY);
  319. DECL_REG (regScaledTexY);
  320. DECL_REG (regTexOffset);
  321. DECL_REG (regConstant16);
  322. cg_virtual_reg_t * regTextureLogWidth = LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_WIDTH);
  323. cg_virtual_reg_t * regTextureLogHeight = LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_HEIGHT);
  324. cg_virtual_reg_t * regTextureData = LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_DATA);
  325. LSL (regScaledU, regU0, regTextureLogWidth);
  326. LSL (regScaledV, regV0, regTextureLogHeight);
  327. LDI (regConstant16, 16);
  328. ASR (regTexX, regScaledU, regConstant16);
  329. ASR (regTexY, regScaledV, regConstant16);
  330. LSL (regScaledTexY, regTexY, regTextureLogWidth);
  331. ADD (regTexOffset, regScaledTexY, regTexX);
  332. FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset,
  333. regTexColorR, regTexColorG, regTexColorB, regTexColorA, regTexColor565);
  334. } else {
  335. assert(m_State->GetMinFilterMode(unit) == RasterizerState::FilterModeLinear);
  336. cg_virtual_reg_t * regTextureLogWidth = LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_WIDTH);
  337. DECL_REG (regHalf);
  338. DECL_REG (regHalfU);
  339. DECL_REG (regHalfV);
  340. LDI (regHalf, 0x8000);
  341. cg_virtual_reg_t * regTextureLogHeight = LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_LOG_HEIGHT);
  342. ASR (regHalfU, regHalf, regTextureLogWidth);
  343. ASR (regHalfV, regHalf, regTextureLogHeight);
  344. DECL_REG (regRoundedU);
  345. DECL_REG (regRoundedV);
  346. SUB (regRoundedU, regU, regHalfU);
  347. SUB (regRoundedV, regV, regHalfV);
  348. DECL_REG (regScaledU);
  349. DECL_REG (regScaledV);
  350. DECL_REG (regFixedOne);
  351. DECL_REG (regFracU);
  352. DECL_REG (regFracV);
  353. DECL_REG (regMask);
  354. LDI (regMask, 0xffff);
  355. LSL (regScaledU, regRoundedU, regTextureLogWidth);
  356. LSL (regScaledV, regRoundedV, regTextureLogHeight);
  357. AND (regFracU, regScaledU, regMask);
  358. AND (regFracV, regScaledV, regMask);
  359. DECL_REG (regTexX);
  360. DECL_REG (regTexY);
  361. DECL_REG (regConstant16);
  362. LDI (regConstant16, 16);
  363. ASR (regTexX, regScaledU, regConstant16);
  364. ASR (regTexY, regScaledV, regConstant16);
  365. DECL_REG (regConstant1);
  366. DECL_REG (regIntMaskU0);
  367. DECL_REG (regIntMaskU);
  368. DECL_REG (regIntMaskV0);
  369. DECL_REG (regIntMaskV);
  370. LDI (regConstant1, 1);
  371. LSL (regIntMaskU0, regConstant1, regTextureLogWidth);
  372. LSL (regIntMaskV0, regConstant1, regTextureLogHeight);
  373. SUB (regIntMaskU, regIntMaskU0, regConstant1);
  374. SUB (regIntMaskV, regIntMaskV0, regConstant1);
  375. DECL_REG (regI0);
  376. DECL_REG (regI1);
  377. DECL_REG (regJ0);
  378. DECL_REG (regJ1);
  379. DECL_REG (regTexX1);
  380. DECL_REG (regTexY1);
  381. ADD (regTexX1, regTexX, regConstant1);
  382. ADD (regTexY1, regTexY, regConstant1);
  383. WrapOrClamp(procedure, block, regTexX, regI0, regIntMaskU, m_State->m_Texture[unit].WrappingModeS);
  384. WrapOrClamp(procedure, block, regTexX1, regI1, regIntMaskU, m_State->m_Texture[unit].WrappingModeS);
  385. WrapOrClamp(procedure, block, regTexY, regJ0, regIntMaskV, m_State->m_Texture[unit].WrappingModeT);
  386. WrapOrClamp(procedure, block, regTexY1, regJ1, regIntMaskV, m_State->m_Texture[unit].WrappingModeT);
  387. DECL_REG (regScaledJ0);
  388. DECL_REG (regScaledJ1);
  389. LSL (regScaledJ0, regJ0, regTextureLogWidth);
  390. LSL (regScaledJ1, regJ1, regTextureLogWidth);
  391. DECL_REG (regTexOffset00);
  392. DECL_REG (regTexOffset01);
  393. DECL_REG (regTexOffset10);
  394. DECL_REG (regTexOffset11);
  395. ADD (regTexOffset00, regI0, regScaledJ0);
  396. ADD (regTexOffset01, regI1, regScaledJ0);
  397. ADD (regTexOffset10, regI0, regScaledJ1);
  398. ADD (regTexOffset11, regI1, regScaledJ1);
  399. cg_virtual_reg_t * regColorR00, * regColorR01, *regColorR10, * regColorR11;
  400. cg_virtual_reg_t * regColorG00, * regColorG01, *regColorG10, * regColorG11;
  401. cg_virtual_reg_t * regColorB00, * regColorB01, *regColorB10, * regColorB11;
  402. cg_virtual_reg_t * regColorA00, * regColorA01, *regColorA10, * regColorA11;
  403. cg_virtual_reg_t * regColor56500, * regColor56501, *regColor56510, * regColor56511;
  404. cg_virtual_reg_t * regTextureData = LOAD_DATA(block, fragmentInfo.regTexture[unit], OFFSET_TEXTURE_DATA);
  405. FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset00,
  406. regColorR00, regColorG00, regColorB00, regColorA00, regColor56500);
  407. FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset01,
  408. regColorR01, regColorG01, regColorB01, regColorA01, regColor56501);
  409. FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset10,
  410. regColorR10, regColorG10, regColorB10, regColorA10, regColor56510);
  411. FetchTexColor(procedure, block, m_State->m_Texture + unit, regTextureData, regTexOffset11,
  412. regColorR11, regColorG11, regColorB11, regColorA11, regColor56511);
  413. cg_virtual_reg_t * regColorR0, * regColorR1;
  414. cg_virtual_reg_t * regColorG0, * regColorG1;
  415. cg_virtual_reg_t * regColorB0, * regColorB1;
  416. cg_virtual_reg_t * regColorA0, * regColorA1;
  417. // blend into 0 and 1 colors
  418. DECL_REG (regConstant8);
  419. DECL_REG (regAdjustedFracU);
  420. DECL_REG (regAdjustedFracV);
  421. LDI (regConstant8, 8);
  422. ASR (regAdjustedFracU, regFracU, regConstant8);
  423. ASR (regAdjustedFracV, regFracV, regConstant8);
  424. regColorR0 = BlendComponent(procedure, block, regColorR00, regColorR01, regAdjustedFracU);
  425. regColorR1 = BlendComponent(procedure, block, regColorR10, regColorR11, regAdjustedFracU);
  426. regTexColorR = BlendComponent(procedure, block, regColorR0, regColorR1, regAdjustedFracV);
  427. regColorG0 = BlendComponent(procedure, block, regColorG00, regColorG01, regAdjustedFracU);
  428. regColorG1 = BlendComponent(procedure, block, regColorG10, regColorG11, regAdjustedFracU);
  429. regTexColorG = BlendComponent(procedure, block, regColorG0, regColorG1, regAdjustedFracV);
  430. regColorB0 = BlendComponent(procedure, block, regColorB00, regColorB01, regAdjustedFracU);
  431. regColorB1 = BlendComponent(procedure, block, regColorB10, regColorB11, regAdjustedFracU);
  432. regTexColorB = BlendComponent(procedure, block, regColorB0, regColorB1, regAdjustedFracV);
  433. regColorA0 = BlendComponent(procedure, block, regColorA00, regColorA01, regAdjustedFracU);
  434. regColorA1 = BlendComponent(procedure, block, regColorA10, regColorA11, regAdjustedFracU);
  435. regTexColorA = BlendComponent(procedure, block, regColorA0, regColorA1, regAdjustedFracV);
  436. // create composite color
  437. regTexColor565 = Color565FromRGB(block, regTexColorR, regTexColorG, regTexColorB);
  438. }
  439. }
  440. // Actually, we could extract the scaling of the texture coordinates into the outer driving loop,
  441. // and have the adjusted clipping range for tu and tv be stored in the rasterizer.
  442. void CodeGenerator :: GenerateFragment(cg_proc_t * procedure, cg_block_t * currentBlock,
  443. cg_block_ref_t * continuation, FragmentGenerationInfo & fragmentInfo,
  444. int weight, bool forceScissor) {
  445. cg_block_t * block = currentBlock;
  446. // Signature of generated function is:
  447. // (I32 x, I32 y, EGL_Fixed depth, EGL_Fixed tu, EGL_Fixed tv, EGL_Fixed fogDensity, const Color& baseColor);
  448. // fragment level clipping (for now)
  449. //if (m_Surface->GetWidth() <= x || x < 0 ||
  450. // m_Surface->GetHeight() <= y || y < 0) {
  451. // return;
  452. //}
  453. if (forceScissor || m_State->m_ScissorTest.Enabled) {
  454. DECL_REG (regConstXStart);
  455. DECL_REG (regConstXEnd);
  456. DECL_FLAGS (regXStartTest);
  457. DECL_FLAGS (regXEndTest);
  458. LDI (regConstXStart, m_State->m_ScissorTest.X);
  459. LDI (regConstXEnd, m_State->m_ScissorTest.X + m_State->m_ScissorTest.Width);
  460. CMP (regXStartTest, fragmentInfo.regX, regConstXStart);
  461. BLT (regXStartTest, continuation);
  462. CMP (regXEndTest, fragmentInfo.regX, regConstXEnd);
  463. BGE (regXEndTest, continuation);
  464. if (fragmentInfo.regY) {
  465. DECL_REG (regConstYStart);
  466. DECL_REG (regConstYEnd);
  467. DECL_FLAGS (regYStartTest);
  468. DECL_FLAGS (regYEndTest);
  469. LDI (regConstYStart, m_State->m_ScissorTest.Y);
  470. LDI (regConstYEnd, m_State->m_ScissorTest.Y + m_State->m_ScissorTest.Height);
  471. CMP (regYStartTest, fragmentInfo.regY, regConstYStart);
  472. BLT (regYStartTest, continuation);
  473. CMP (regYEndTest, fragmentInfo.regY, regConstYEnd);
  474. BGE (regYEndTest, continuation);
  475. }
  476. }
  477. //bool depthTest;
  478. //U32 offset = x + y * m_Surface->GetWidth();
  479. //I32 zBufferValue = m_Surface->GetDepthBuffer()[offset];
  480. cg_virtual_reg_t * regOffset;
  481. if (fragmentInfo.regY) {
  482. regOffset = cg_virtual_reg_create(procedure, cg_reg_type_general);
  483. cg_virtual_reg_t * regWidth = LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_WIDTH);
  484. DECL_REG (regScaledY);
  485. MUL (regScaledY, fragmentInfo.regY, regWidth);
  486. ADD (regOffset, regScaledY, fragmentInfo.regX);
  487. } else {
  488. regOffset = fragmentInfo.regX;
  489. }
  490. cg_virtual_reg_t * regDepthBuffer = LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_DEPTH_BUFFER);
  491. DECL_FLAGS (regDepthTest);
  492. DECL_REG (regScaledY);
  493. DECL_REG (regConstant1);
  494. DECL_REG (regConstant2);
  495. DECL_REG (regOffset4);
  496. DECL_REG (regOffset2);
  497. DECL_REG (regZBufferAddr);
  498. DECL_REG (regZBufferValue);
  499. LDI (regConstant1, 1);
  500. LDI (regConstant2, 2);
  501. LSL (regOffset2, regOffset, regConstant1);
  502. LSL (regOffset4, regOffset, regConstant2);
  503. ADD (regZBufferAddr, regDepthBuffer, regOffset2);
  504. LDH (regZBufferValue, regZBufferAddr);
  505. /*
  506. * Enable this piece if we want to clamp the depth value to 0 .. 0xffff
  507. {
  508. DECL_CONST_REG (regConstant0, 0);
  509. DECL_CONST_REG (regConstant1, 0xffff);
  510. DECL_REG (regNewDepth);
  511. DECL_REG (regTempDepth);
  512. MIN (regTempDepth, fragmentInfo.regDepth, regConstant1);
  513. MAX (regNewDepth, regTempDepth, regConstant0);
  514. fragmentInfo.regDepth = regNewDepth;
  515. }*/
  516. CMP (regDepthTest, fragmentInfo.regDepth, regZBufferValue);
  517. cg_opcode_t branchOnDepthTestPassed, branchOnDepthTestFailed;
  518. switch (m_State->m_DepthTest.Func) {
  519. default:
  520. case RasterizerState::CompFuncNever:
  521. //depthTest = false;
  522. branchOnDepthTestPassed = cg_op_nop;
  523. branchOnDepthTestFailed = cg_op_bra;
  524. break;
  525. case RasterizerState::CompFuncLess:
  526. //depthTest = depth < zBufferValue;
  527. branchOnDepthTestPassed = cg_op_blt;
  528. branchOnDepthTestFailed = cg_op_bge;
  529. break;
  530. case RasterizerState::CompFuncEqual:
  531. //depthTest = depth == zBufferValue;
  532. branchOnDepthTestPassed = cg_op_beq;
  533. branchOnDepthTestFailed = cg_op_bne;
  534. break;
  535. case RasterizerState::CompFuncLEqual:
  536. //depthTest = depth <= zBufferValue;
  537. branchOnDepthTestPassed = cg_op_ble;
  538. branchOnDepthTestFailed = cg_op_bgt;
  539. break;
  540. case RasterizerState::CompFuncGreater:
  541. //depthTest = depth > zBufferValue;
  542. branchOnDepthTestPassed = cg_op_bgt;
  543. branchOnDepthTestFailed = cg_op_ble;
  544. break;
  545. case RasterizerState::CompFuncNotEqual:
  546. //depthTest = depth != zBufferValue;
  547. branchOnDepthTestPassed = cg_op_bne;
  548. branchOnDepthTestFailed = cg_op_beq;
  549. break;
  550. case RasterizerState::CompFuncGEqual:
  551. //depthTest = depth >= zBufferValue;
  552. branchOnDepthTestPassed = cg_op_bge;
  553. branchOnDepthTestFailed = cg_op_blt;
  554. break;
  555. case RasterizerState::CompFuncAlways:
  556. //depthTest = true;
  557. branchOnDepthTestPassed = cg_op_bra;
  558. branchOnDepthTestFailed = cg_op_nop;
  559. break;
  560. }
  561. if (!m_State->m_Stencil.Enabled && m_State->m_DepthTest.Enabled) {
  562. //if (!depthTest)
  563. // return;
  564. if (branchOnDepthTestFailed == cg_op_nop) {
  565. // nothing
  566. } else if (branchOnDepthTestFailed == cg_op_bra) {
  567. BRA (continuation);
  568. } else {
  569. cg_create_inst_branch_cond(block, branchOnDepthTestFailed, regDepthTest, continuation CG_INST_DEBUG_ARGS);
  570. }
  571. }
  572. //Color color = baseColor;
  573. cg_virtual_reg_t * regColorR = ClampTo255(block, fragmentInfo.regR);
  574. cg_virtual_reg_t * regColorG = ClampTo255(block, fragmentInfo.regG);
  575. cg_virtual_reg_t * regColorB = ClampTo255(block, fragmentInfo.regB);
  576. cg_virtual_reg_t * regColorA = ClampTo255(block, fragmentInfo.regA);
  577. cg_virtual_reg_t * regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  578. cg_virtual_reg_t * regBaseColorR = regColorR;
  579. cg_virtual_reg_t * regBaseColorG = regColorG;
  580. cg_virtual_reg_t * regBaseColorB = regColorB;
  581. cg_virtual_reg_t * regBaseColorA = regColorA;
  582. cg_virtual_reg_t * regBaseColor565 = regColor565;
  583. for (size_t unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  584. if (m_State->m_Texture[unit].Enabled) {
  585. //Color texColor;
  586. cg_virtual_reg_t * regTexColorR;
  587. cg_virtual_reg_t * regTexColorG;
  588. cg_virtual_reg_t * regTexColorB;
  589. cg_virtual_reg_t * regTexColorA;
  590. cg_virtual_reg_t * regTexColor565;
  591. GenerateFetchTexColor(procedure, block, unit, fragmentInfo,
  592. regTexColorR, regTexColorG, regTexColorB, regTexColorA, regTexColor565);
  593. if (m_State->m_Texture[unit].Mode == RasterizerState::TextureModeCombine) {
  594. //Color arg[3];
  595. cg_virtual_reg_t * regArgR[3];
  596. cg_virtual_reg_t * regArgG[3];
  597. cg_virtual_reg_t * regArgB[3];
  598. cg_virtual_reg_t * regArgA[3];
  599. cg_virtual_reg_t * regArg565[3];
  600. for (size_t idx = 0; idx < 3; ++idx) {
  601. //Color rgbIn;
  602. cg_virtual_reg_t * regRgbInR;
  603. cg_virtual_reg_t * regRgbInG;
  604. cg_virtual_reg_t * regRgbInB;
  605. cg_virtual_reg_t * regRgbInA;
  606. cg_virtual_reg_t * regRgbIn565;
  607. //U8 alphaIn;
  608. cg_virtual_reg_t * regAlphaIn;
  609. switch (m_State->m_Texture[unit].CombineSrcRGB[idx]) {
  610. case RasterizerState::TextureCombineSrcTexture:
  611. //rgbIn = texColor;
  612. {
  613. regRgbInR = regTexColorR;
  614. regRgbInG = regTexColorG;
  615. regRgbInB = regTexColorB;
  616. regRgbInA = regTexColorA;
  617. regRgbIn565 = regTexColor565;
  618. }
  619. break;
  620. case RasterizerState::TextureCombineSrcConstant:
  621. //rgbIn = m_State->m_Texture[unit].EnvColor;
  622. {
  623. regRgbInR = cg_virtual_reg_create(procedure, cg_reg_type_general);
  624. regRgbInG = cg_virtual_reg_create(procedure, cg_reg_type_general);
  625. regRgbInB = cg_virtual_reg_create(procedure, cg_reg_type_general);
  626. regRgbInA = cg_virtual_reg_create(procedure, cg_reg_type_general);
  627. LDI (regRgbInR, m_State->m_Texture[unit].EnvColor.r);
  628. LDI (regRgbInG, m_State->m_Texture[unit].EnvColor.g);
  629. LDI (regRgbInB, m_State->m_Texture[unit].EnvColor.b);
  630. LDI (regRgbInA, m_State->m_Texture[unit].EnvColor.a);
  631. regRgbIn565 = Color565FromRGB(block, regRgbInR, regRgbInG, regRgbInB);
  632. }
  633. break;
  634. case RasterizerState::TextureCombineSrcPrimaryColor:
  635. //rgbIn = baseColor;
  636. {
  637. regRgbInR = regBaseColorR;
  638. regRgbInG = regBaseColorG;
  639. regRgbInB = regBaseColorB;
  640. regRgbInA = regBaseColorA;
  641. regRgbIn565 = regBaseColor565;
  642. }
  643. break;
  644. case RasterizerState::TextureCombineSrcPrevious:
  645. //rgbIn = color;
  646. {
  647. regRgbInR = regColorR;
  648. regRgbInG = regColorG;
  649. regRgbInB = regColorB;
  650. regRgbInA = regColorA;
  651. regRgbIn565 = regColor565;
  652. }
  653. break;
  654. }
  655. switch (m_State->m_Texture[unit].CombineSrcAlpha[idx]) {
  656. case RasterizerState::TextureCombineSrcTexture:
  657. //alphaIn = texColor.a;
  658. regAlphaIn = regTexColorA;
  659. break;
  660. case RasterizerState::TextureCombineSrcConstant:
  661. //alphaIn = m_State->m_Texture[unit].EnvColor.a;
  662. {
  663. regAlphaIn = cg_virtual_reg_create(procedure, cg_reg_type_general);
  664. LDI (regAlphaIn, m_State->m_Texture[unit].EnvColor.a);
  665. }
  666. break;
  667. case RasterizerState::TextureCombineSrcPrimaryColor:
  668. //alphaIn = baseColor.a;
  669. regAlphaIn = regBaseColorA;
  670. break;
  671. case RasterizerState::TextureCombineSrcPrevious:
  672. //alphaIn = color.a;
  673. regAlphaIn = regColorA;
  674. break;
  675. }
  676. //U8 alphaOut;
  677. cg_virtual_reg_t * regAlphaOut;
  678. if (m_State->m_Texture[unit].CombineOpAlpha[idx] == RasterizerState::TextureCombineOpSrcAlpha) {
  679. //alphaOut = alphaIn;
  680. regAlphaOut = regAlphaIn;
  681. } else {
  682. //alphaOut = 0xFF - alphaIn;
  683. DECL_CONST_REG (constantMaxColor, 0xff);
  684. regAlphaOut = Sub(block, constantMaxColor, regAlphaIn);
  685. }
  686. switch (m_State->m_Texture[unit].CombineOpRGB[idx]) {
  687. case RasterizerState::TextureCombineOpSrcColor:
  688. //arg[idx] = Color(rgbIn.r, rgbIn.g, rgbIn.b, alphaOut);
  689. {
  690. regArgR[idx] = regRgbInR;
  691. regArgG[idx] = regRgbInG;
  692. regArgB[idx] = regRgbInB;
  693. regArg565[idx] = regRgbIn565;
  694. regArgA[idx] = regAlphaOut;
  695. }
  696. break;
  697. case RasterizerState::TextureCombineOpOneMinusSrcColor:
  698. //arg[idx] = Color(0xFF - rgbIn.r, 0xFF - rgbIn.g, 0xFF - rgbIn.b, alphaOut);
  699. {
  700. DECL_CONST_REG (constantMaxColor, 0xff);
  701. regArgR[idx] = Sub(block, constantMaxColor, regRgbInR);
  702. regArgG[idx] = Sub(block, constantMaxColor, regRgbInG);
  703. regArgB[idx] = Sub(block, constantMaxColor, regRgbInB);
  704. regArg565[idx] = Color565FromRGB(block, regArgR[idx], regArgG[idx], regArgB[idx]);
  705. regArgA[idx] = regAlphaOut;
  706. }
  707. break;
  708. case RasterizerState::TextureCombineOpSrcAlpha:
  709. //arg[idx] = Color(rgbIn.a, rgbIn.a, rgbIn.a, alphaOut);
  710. {
  711. regArgR[idx] = regArgG[idx] = regArgB[idx] = regRgbInA;
  712. regArg565[idx] = Color565FromRGB(block, regArgR[idx], regArgG[idx], regArgB[idx]);
  713. regArgA[idx] = regAlphaOut;
  714. }
  715. break;
  716. case RasterizerState::TextureCombineOpOneMinusSrcAlpha:
  717. //arg[idx] = Color(0xFF - rgbIn.a, 0xFF - rgbIn.a, 0xFF - rgbIn.a, alphaOut);
  718. {
  719. DECL_CONST_REG (constantMaxColor, 0xff);
  720. regArgR[idx] = regArgG[idx] = regArgB[idx] = Sub(block, constantMaxColor, regRgbInA);
  721. regArg565[idx] = Color565FromRGB(block, regArgR[idx], regArgG[idx], regArgB[idx]);
  722. regArgA[idx] = regAlphaOut;
  723. }
  724. break;
  725. }
  726. }
  727. //U8 combineAlpha;
  728. cg_virtual_reg_t * regCombineAlpha;
  729. switch (m_State->m_Texture[unit].CombineFuncAlpha) {
  730. case RasterizerState::TextureModeCombineReplace:
  731. {
  732. //combineAlpha = MulU8(arg[0].a, 0xFF, scaleAlpha);
  733. regCombineAlpha = regArgA[0];
  734. }
  735. break;
  736. case RasterizerState::TextureModeCombineModulate:
  737. //combineAlpha = MulU8(arg[0].a, arg[1].a, scaleAlpha);
  738. regCombineAlpha = Mul255(block, regArgA[0], regArgA[1]);
  739. break;
  740. case RasterizerState::TextureModeCombineAdd:
  741. //combineAlpha = AddU8(arg[0].a, arg[1].a, scaleAlpha);
  742. regCombineAlpha = Add(block, regArgA[0], regArgA[1]);
  743. break;
  744. case RasterizerState::TextureModeCombineAddSigned:
  745. //combineAlpha = AddSignedU8(arg[0].a, arg[1].a, scaleAlpha);
  746. regCombineAlpha = AddSigned(block, regArgA[0], regArgA[1]);
  747. break;
  748. case RasterizerState::TextureModeCombineInterpolate:
  749. //combineAlpha = InterpolateU8(arg[0].a, arg[1].a, arg[2].a, scaleAlpha);
  750. //regCombineAlpha = Blend255(block, regArgA[0], regArgA[1], regArgA[2]);
  751. regCombineAlpha = Blend255(block, regArgA[1], regArgA[0], regArgA[2]);
  752. break;
  753. case RasterizerState::TextureModeCombineSubtract:
  754. //combineAlpha = SubU8(arg[0].a, arg[1].a, scaleAlpha);
  755. regCombineAlpha = Sub(block, regArgA[0], regArgA[1]);
  756. break;
  757. }
  758. switch (m_State->m_Texture[unit].CombineFuncRGB) {
  759. case RasterizerState::TextureModeCombineReplace:
  760. //color = Color(
  761. // MulU8(arg[0].r, 0xFF, scaleRGB),
  762. // MulU8(arg[0].g, 0xFF, scaleRGB),
  763. // MulU8(arg[0].b, 0xFF, scaleRGB),
  764. // combineAlpha);
  765. regColorR = regArgR[0];
  766. regColorG = regArgG[0];
  767. regColorB = regArgB[0];
  768. regColorA = regCombineAlpha;
  769. break;
  770. case RasterizerState::TextureModeCombineModulate:
  771. //color =
  772. // Color(
  773. // MulU8(arg[0].r, arg[1].r, scaleRGB),
  774. // MulU8(arg[0].g, arg[1].g, scaleRGB),
  775. // MulU8(arg[0].b, arg[1].b, scaleRGB),
  776. // combineAlpha);
  777. regColorR = Mul255(block, regArgR[0], regArgR[1]);
  778. regColorG = Mul255(block, regArgG[0], regArgG[1]);
  779. regColorB = Mul255(block, regArgB[0], regArgB[1]);
  780. regColorA = regCombineAlpha;
  781. break;
  782. case RasterizerState::TextureModeCombineAdd:
  783. //color =
  784. // Color(
  785. // AddU8(arg[0].r, arg[1].r, scaleRGB),
  786. // AddU8(arg[0].g, arg[1].g, scaleRGB),
  787. // AddU8(arg[0].b, arg[1].b, scaleRGB),
  788. // combineAlpha);
  789. regColorR = Add(block, regArgR[0], regArgR[1]);
  790. regColorG = Add(block, regArgG[0], regArgG[1]);
  791. regColorB = Add(block, regArgB[0], regArgB[1]);
  792. regColorA = regCombineAlpha;
  793. break;
  794. case RasterizerState::TextureModeCombineAddSigned:
  795. //color =
  796. // Color(
  797. // AddSignedU8(arg[0].r, arg[1].r, scaleRGB),
  798. // AddSignedU8(arg[0].g, arg[1].g, scaleRGB),
  799. // AddSignedU8(arg[0].b, arg[1].b, scaleRGB),
  800. // combineAlpha);
  801. regColorR = AddSigned(block, regArgR[0], regArgR[1]);
  802. regColorG = AddSigned(block, regArgG[0], regArgG[1]);
  803. regColorB = AddSigned(block, regArgB[0], regArgB[1]);
  804. regColorA = regCombineAlpha;
  805. break;
  806. case RasterizerState::TextureModeCombineInterpolate:
  807. //color =
  808. // Color(
  809. // InterpolateU8(arg[0].r, arg[1].r, arg[2].r, scaleRGB),
  810. // InterpolateU8(arg[0].g, arg[1].g, arg[2].g, scaleRGB),
  811. // InterpolateU8(arg[0].b, arg[1].b, arg[2].b, scaleRGB),
  812. // combineAlpha);
  813. //regColorR = Blend255(block, regArgR[0], regArgR[1], regArgR[2]);
  814. //regColorG = Blend255(block, regArgG[0], regArgG[1], regArgG[2]);
  815. //regColorB = Blend255(block, regArgB[0], regArgB[1], regArgB[2]);
  816. regColorR = Blend255(block, regArgR[1], regArgR[0], regArgR[2]);
  817. regColorG = Blend255(block, regArgG[1], regArgG[0], regArgG[2]);
  818. regColorB = Blend255(block, regArgB[1], regArgB[0], regArgB[2]);
  819. regColorA = regCombineAlpha;
  820. break;
  821. case RasterizerState::TextureModeCombineSubtract:
  822. //color =
  823. // Color(
  824. // SubU8(arg[0].r, arg[1].r, scaleRGB),
  825. // SubU8(arg[0].g, arg[1].g, scaleRGB),
  826. // SubU8(arg[0].b, arg[1].b, scaleRGB),
  827. // combineAlpha);
  828. regColorR = Sub(block, regArgR[0], regArgR[1]);
  829. regColorG = Sub(block, regArgG[0], regArgG[1]);
  830. regColorB = Sub(block, regArgB[0], regArgB[1]);
  831. regColorA = regCombineAlpha;
  832. break;
  833. case RasterizerState::TextureModeCombineDot3RGB:
  834. case RasterizerState::TextureModeCombineDot3RGBA:
  835. //{
  836. // U8 dotRGB = Dot3U8(arg[0], arg[1], scaleRGB);
  837. // color = Color(dotRGB, dotRGB, dotRGB, combineAlpha);
  838. //}
  839. //{
  840. // U8 dotRGB = Dot3U8(arg[0], arg[1], scaleRGB);
  841. // U8 dotAlpha = Dot3U8(arg[0], arg[1], scaleAlpha);
  842. // color = Color(dotRGB, dotRGB, dotRGB, dotAlpha);
  843. //}
  844. regColorR = Dot3(block, regArgR, regArgG, regArgB);
  845. regColorG = regColorB = regColorR;
  846. if (m_State->m_Texture[unit].CombineFuncRGB == RasterizerState::TextureModeCombineDot3RGBA)
  847. regColorA = regColorR;
  848. else
  849. regColorA = regCombineAlpha;
  850. break;
  851. }
  852. EGL_Fixed scaleAlpha = m_State->m_Texture[unit].ScaleAlpha;
  853. if (scaleAlpha != EGL_ONE) {
  854. DECL_REG (regResultA);
  855. DECL_CONST_REG (regScaleAlpha, scaleAlpha);
  856. FMUL (regResultA, regColorA, regScaleAlpha);
  857. regColorA = regResultA;
  858. }
  859. // Clamp to 0 .. 0xff
  860. {
  861. DECL_REG (regClampLow);
  862. DECL_REG (regClampHigh);
  863. DECL_CONST_REG (constantMaxColor, 0xff);
  864. DECL_CONST_REG (constant0, 0);
  865. MAX (regClampLow, regColorA, constant0);
  866. MIN (regClampHigh, regClampLow, constantMaxColor);
  867. regColorA = regClampHigh;
  868. }
  869. EGL_Fixed scaleRGB = m_State->m_Texture[unit].ScaleRGB;
  870. if (scaleRGB != EGL_ONE) {
  871. DECL_REG (regResultR);
  872. DECL_REG (regResultG);
  873. DECL_REG (regResultB);
  874. DECL_CONST_REG (regScaleRGB, scaleRGB);
  875. FMUL (regResultR, regColorR, regScaleRGB);
  876. FMUL (regResultG, regColorG, regScaleRGB);
  877. FMUL (regResultB, regColorB, regScaleRGB);
  878. regColorR = regResultR;
  879. regColorG = regResultG;
  880. regColorB = regResultB;
  881. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  882. }
  883. // Clamp to 0 .. 0xff
  884. {
  885. DECL_REG (regClampLowR);
  886. DECL_REG (regClampHighR);
  887. DECL_REG (regClampLowG);
  888. DECL_REG (regClampHighG);
  889. DECL_REG (regClampLowB);
  890. DECL_REG (regClampHighB);
  891. DECL_CONST_REG (constantMaxColor, 0xff);
  892. DECL_CONST_REG (constant0, 0);
  893. MAX (regClampLowR, regColorR, constant0);
  894. MIN (regClampHighR, regClampLowR, constantMaxColor);
  895. MAX (regClampLowG, regColorG, constant0);
  896. MIN (regClampHighG, regClampLowG, constantMaxColor);
  897. MAX (regClampLowB, regColorB, constant0);
  898. MIN (regClampHighB, regClampLowB, constantMaxColor);
  899. regColorR = regClampHighR;
  900. regColorG = regClampHighG;
  901. regColorB = regClampHighB;
  902. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  903. }
  904. } else {
  905. switch (m_State->m_Texture[unit].InternalFormat) {
  906. default:
  907. case RasterizerState::TextureFormatAlpha:
  908. switch (m_State->m_Texture[unit].Mode) {
  909. case RasterizerState::TextureModeReplace:
  910. {
  911. //color = Color(color.r, color.g, color.b, texColor.a);
  912. regColorA = regTexColorA;
  913. }
  914. break;
  915. case RasterizerState::TextureModeModulate:
  916. case RasterizerState::TextureModeBlend:
  917. case RasterizerState::TextureModeAdd:
  918. {
  919. //color = Color(color.r, color.g, color.b, MulU8(color.a, texColor.a));
  920. regColorA = Mul255(block, regColorA, regTexColorA);
  921. }
  922. break;
  923. }
  924. break;
  925. case RasterizerState::TextureFormatLuminance:
  926. case RasterizerState::TextureFormatRGB565:
  927. case RasterizerState::TextureFormatRGB8:
  928. switch (m_State->m_Texture[unit].Mode) {
  929. case RasterizerState::TextureModeDecal:
  930. case RasterizerState::TextureModeReplace:
  931. {
  932. //color = Color(texColor.r, texColor.g, texColor.b, color.a);
  933. regColorR = regTexColorR;
  934. regColorG = regTexColorG;
  935. regColorB = regTexColorB;
  936. regColor565 = regTexColor565;
  937. }
  938. break;
  939. case RasterizerState::TextureModeModulate:
  940. {
  941. //color = Color(MulU8(color.r, texColor.r),
  942. // MulU8(color.g, texColor.g), MulU8(color.b, texColor.b), color.a);
  943. regColorR = Mul255(block, regColorR, regTexColorR);
  944. regColorG = Mul255(block, regColorG, regTexColorG);
  945. regColorB = Mul255(block, regColorB, regTexColorB);
  946. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  947. }
  948. break;
  949. case RasterizerState::TextureModeBlend:
  950. {
  951. //color =
  952. // Color(
  953. // MulU8(color.r, 0xff - texColor.r) + MulU8(m_State->m_TexEnvColor.r, texColor.r),
  954. // MulU8(color.g, 0xff - texColor.g) + MulU8(m_State->m_TexEnvColor.g, texColor.g),
  955. // MulU8(color.b, 0xff - texColor.b) + MulU8(m_State->m_TexEnvColor.b, texColor.b),
  956. // color.a);
  957. regColorR = Blend255(block, m_State->m_Texture[unit].EnvColor.r, regColorR, regTexColorR);
  958. regColorG = Blend255(block, m_State->m_Texture[unit].EnvColor.g, regColorG, regTexColorG);
  959. regColorB = Blend255(block, m_State->m_Texture[unit].EnvColor.b, regColorB, regTexColorB);
  960. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  961. }
  962. break;
  963. case RasterizerState::TextureModeAdd:
  964. {
  965. //color =
  966. // Color(
  967. // ClampU8(color.r + texColor.r),
  968. // ClampU8(color.g + texColor.g),
  969. // ClampU8(color.b + texColor.b),
  970. // color.a);
  971. regColorR = AddSaturate255(block, regColorR, regTexColorR);
  972. regColorG = AddSaturate255(block, regColorG, regTexColorG);
  973. regColorB = AddSaturate255(block, regColorB, regTexColorB);
  974. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  975. }
  976. break;
  977. }
  978. break;
  979. case RasterizerState::TextureFormatLuminanceAlpha:
  980. case RasterizerState::TextureFormatRGBA5551:
  981. case RasterizerState::TextureFormatRGBA4444:
  982. case RasterizerState::TextureFormatRGBA8:
  983. switch (m_State->m_Texture[unit].Mode) {
  984. case RasterizerState::TextureModeReplace:
  985. {
  986. //color = texColor;
  987. regColorR = regTexColorR;
  988. regColorG = regTexColorG;
  989. regColorB = regTexColorB;
  990. regColorA = regTexColorA;
  991. regColor565 = regTexColor565;
  992. }
  993. break;
  994. case RasterizerState::TextureModeModulate:
  995. {
  996. //color = color * texColor;
  997. regColorR = Mul255(block, regColorR, regTexColorR);
  998. regColorG = Mul255(block, regColorG, regTexColorG);
  999. regColorB = Mul255(block, regColorB, regTexColorB);
  1000. regColorA = Mul255(block, regColorA, regTexColorA);
  1001. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  1002. }
  1003. break;
  1004. case RasterizerState::TextureModeDecal:
  1005. {
  1006. //color =
  1007. // Color(
  1008. // MulU8(color.r, 0xff - texColor.a) + MulU8(texColor.r, texColor.a),
  1009. // MulU8(color.g, 0xff - texColor.a) + MulU8(texColor.g, texColor.a),
  1010. // MulU8(color.b, 0xff - texColor.a) + MulU8(texColor.b, texColor.a),
  1011. // color.a);
  1012. regColorR = Blend255(block, regColorR, regTexColorR, regTexColorA);
  1013. regColorG = Blend255(block, regColorG, regTexColorG, regTexColorA);
  1014. regColorB = Blend255(block, regColorB, regTexColorB, regTexColorA);
  1015. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  1016. }
  1017. break;
  1018. case RasterizerState::TextureModeBlend:
  1019. {
  1020. //color =
  1021. // Color(
  1022. // MulU8(color.r, 0xff - texColor.r) + MulU8(m_State->m_TexEnvColor.r, texColor.r),
  1023. // MulU8(color.g, 0xff - texColor.g) + MulU8(m_State->m_TexEnvColor.g, texColor.g),
  1024. // MulU8(color.b, 0xff - texColor.b) + MulU8(m_State->m_TexEnvColor.b, texColor.b),
  1025. // MulU8(color.a, texColor.a));
  1026. regColorR = Blend255(block, m_State->m_Texture[unit].EnvColor.r, regColorR, regTexColorR);
  1027. regColorG = Blend255(block, m_State->m_Texture[unit].EnvColor.g, regColorG, regTexColorG);
  1028. regColorB = Blend255(block, m_State->m_Texture[unit].EnvColor.b, regColorB, regTexColorB);
  1029. regColorA = Mul255(block, regColorA, regTexColorA);
  1030. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  1031. }
  1032. break;
  1033. case RasterizerState::TextureModeAdd:
  1034. {
  1035. //color =
  1036. // Color(
  1037. // ClampU8(color.r + texColor.r),
  1038. // ClampU8(color.g + texColor.g),
  1039. // ClampU8(color.b + texColor.b),
  1040. // MulU8(color.a, texColor.a));
  1041. regColorR = AddSaturate255(block, regColorR, regTexColorR);
  1042. regColorG = AddSaturate255(block, regColorG, regTexColorG);
  1043. regColorB = AddSaturate255(block, regColorB, regTexColorB);
  1044. regColorA = Mul255(block, regColorA, regTexColorA);
  1045. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  1046. }
  1047. break;
  1048. }
  1049. break;
  1050. }
  1051. }
  1052. }
  1053. }
  1054. // fog
  1055. if (m_State->m_Fog.Enabled) {
  1056. //color = Color::Blend(color, m_State->m_FogColor, fogDensity);
  1057. DECL_REG (regFogColorR);
  1058. DECL_REG (regFogColorG);
  1059. DECL_REG (regFogColorB);
  1060. LDI (regFogColorR, m_State->m_Fog.Color.r);
  1061. LDI (regFogColorG, m_State->m_Fog.Color.g);
  1062. LDI (regFogColorB, m_State->m_Fog.Color.b);
  1063. cg_virtual_reg_t * regFog = ClampTo255(block, fragmentInfo.regFog);
  1064. regColorR = Blend255(block, regFogColorR, regColorR, regFog);
  1065. regColorG = Blend255(block, regFogColorG, regColorG, regFog);
  1066. regColorB = Blend255(block, regFogColorB, regColorB, regFog);
  1067. // create RGB 565 representation
  1068. regColor565 = Color565FromRGB(block, regColorR, regColorG, regColorB);
  1069. }
  1070. if (m_State->m_Alpha.Enabled) {
  1071. //bool alphaTest;
  1072. //U8 alpha = color.A();
  1073. //U8 alphaRef = EGL_IntFromFixed(m_State->m_AlphaReference * 255);
  1074. DECL_REG (regAlphaRef);
  1075. DECL_FLAGS (regAlphaTest);
  1076. LDI (regAlphaRef, EGL_IntFromFixed(m_State->m_Alpha.Reference * 255));
  1077. CMP (regAlphaTest, regColorA, regAlphaRef);
  1078. cg_opcode_t failedTest;
  1079. switch (m_State->m_Alpha.Func) {
  1080. default:
  1081. case RasterizerState::CompFuncNever:
  1082. //alphaTest = false;
  1083. failedTest = cg_op_bra;
  1084. break;
  1085. case RasterizerState::CompFuncLess:
  1086. //alphaTest = alpha < alphaRef;
  1087. failedTest = cg_op_bge;
  1088. break;
  1089. case RasterizerState::CompFuncEqual:
  1090. //alphaTest = alpha == alphaRef;
  1091. failedTest = cg_op_bne;
  1092. break;
  1093. case RasterizerState::CompFuncLEqual:
  1094. //alphaTest = alpha <= alphaRef;
  1095. failedTest = cg_op_bgt;
  1096. break;
  1097. case RasterizerState::CompFuncGreater:
  1098. //alphaTest = alpha > alphaRef;
  1099. failedTest = cg_op_ble;
  1100. break;
  1101. case RasterizerState::CompFuncNotEqual:
  1102. //alphaTest = alpha != alphaRef;
  1103. failedTest = cg_op_beq;
  1104. break;
  1105. case RasterizerState::CompFuncGEqual:
  1106. //alphaTest = alpha >= alphaRef;
  1107. failedTest = cg_op_blt;
  1108. break;
  1109. case RasterizerState::CompFuncAlways:
  1110. //alphaTest = true;
  1111. failedTest = cg_op_nop;
  1112. break;
  1113. }
  1114. //if (!alphaTest) {
  1115. // return;
  1116. //}
  1117. if (failedTest != cg_op_nop) {
  1118. if (failedTest == cg_op_bra) {
  1119. BRA (continuation);
  1120. } else {
  1121. cg_create_inst_branch_cond(block, failedTest, regAlphaTest, continuation CG_INST_DEBUG_ARGS);
  1122. }
  1123. }
  1124. }
  1125. if (m_State->m_Stencil.Enabled) {
  1126. //bool stencilTest;
  1127. //U32 stencilRef = m_State->m_Stencil.Reference & m_State->ComparisonMask;
  1128. //U32 stencilValue = m_Surface->GetStencilBuffer()[offset];
  1129. //U32 stencil = stencilValue & m_State->m_Stencil.ComparisonMask;
  1130. DECL_REG (regStencilRef);
  1131. DECL_REG (regStencilMask);
  1132. DECL_REG (regStencilAddr);
  1133. DECL_REG (regStencilValue);
  1134. DECL_REG (regStencil);
  1135. DECL_FLAGS (regStencilTest);
  1136. cg_virtual_reg_t * regStencilBuffer = LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_STENCIL_BUFFER);
  1137. LDI (regStencilRef, m_State->m_Stencil.Reference & m_State->m_Stencil.ComparisonMask);
  1138. LDI (regStencilMask, m_State->m_Stencil.ComparisonMask);
  1139. ADD (regStencilAddr, regStencilBuffer, regOffset4);
  1140. LDW (regStencilValue, regStencilAddr);
  1141. AND (regStencil, regStencilValue, regStencilMask);
  1142. CMP (regStencilTest, regStencil, regStencilRef);
  1143. cg_opcode_t passedTest;
  1144. switch (m_State->m_Stencil.Func) {
  1145. default:
  1146. case RasterizerState::CompFuncNever:
  1147. //stencilTest = false;
  1148. passedTest = cg_op_nop;
  1149. break;
  1150. case RasterizerState::CompFuncLess:
  1151. //stencilTest = stencilRef < stencil;
  1152. passedTest = cg_op_bgt;
  1153. break;
  1154. case RasterizerState::CompFuncEqual:
  1155. //stencilTest = stencilRef == stencil;
  1156. passedTest = cg_op_beq;
  1157. break;
  1158. case RasterizerState::CompFuncLEqual:
  1159. //stencilTest = stencilRef <= stencil;
  1160. passedTest = cg_op_bge;
  1161. break;
  1162. case RasterizerState::CompFuncGreater:
  1163. //stencilTest = stencilRef > stencil;
  1164. passedTest = cg_op_blt;
  1165. break;
  1166. case RasterizerState::CompFuncNotEqual:
  1167. //stencilTest = stencilRef != stencil;
  1168. passedTest = cg_op_bne;
  1169. break;
  1170. case RasterizerState::CompFuncGEqual:
  1171. //stencilTest = stencilRef >= stencil;
  1172. passedTest = cg_op_ble;
  1173. break;
  1174. case RasterizerState::CompFuncAlways:
  1175. //stencilTest = true;
  1176. passedTest = cg_op_bra;
  1177. break;
  1178. }
  1179. // branch on stencil test
  1180. cg_block_ref_t * labelStencilPassed = cg_block_ref_create(procedure);
  1181. cg_block_ref_t * labelStencilBypassed = cg_block_ref_create(procedure);
  1182. if (passedTest != cg_op_nop) {
  1183. cg_create_inst_branch_cond(block, passedTest, regStencilTest, labelStencilPassed CG_INST_DEBUG_ARGS);
  1184. }
  1185. //if (!stencilTest) {
  1186. {
  1187. cg_virtual_reg_t * regNewStencilValue;
  1188. switch (m_State->m_Stencil.Fail) {
  1189. default:
  1190. case RasterizerState::StencilOpKeep:
  1191. goto no_write;
  1192. case RasterizerState::StencilOpZero:
  1193. //stencilValue = 0;
  1194. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1195. LDI (regNewStencilValue, 0);
  1196. break;
  1197. case RasterizerState::StencilOpReplace:
  1198. //stencilValue = m_State->m_StencilReference;
  1199. regNewStencilValue = regStencilRef;
  1200. break;
  1201. case RasterizerState::StencilOpIncr:
  1202. //if (stencilValue != 0xffffffff) {
  1203. // stencilValue++;
  1204. //}
  1205. {
  1206. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1207. DECL_REG (regConstant1);
  1208. DECL_FLAGS (regFlag);
  1209. LDI (regConstant1, 1);
  1210. ADD_S (regNewStencilValue, regFlag, regStencilValue, regConstant1);
  1211. BEQ (regFlag, continuation);
  1212. }
  1213. break;
  1214. case RasterizerState::StencilOpDecr:
  1215. //if (stencilValue != 0) {
  1216. // stencilValue--;
  1217. //}
  1218. {
  1219. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1220. DECL_REG (regConstant0);
  1221. DECL_REG (regConstant1);
  1222. DECL_FLAGS (regFlag);
  1223. LDI (regConstant0, 0);
  1224. CMP (regFlag, regStencilValue, regConstant0);
  1225. BEQ (regFlag, continuation);
  1226. LDI (regConstant1, 1);
  1227. SUB (regNewStencilValue, regStencilValue, regConstant1);
  1228. }
  1229. break;
  1230. case RasterizerState::StencilOpInvert:
  1231. //stencilValue = ~stencilValue;
  1232. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1233. NOT (regNewStencilValue, regStencilValue);
  1234. break;
  1235. }
  1236. if (m_State->m_Stencil.Mask == ~0) {
  1237. STW (regNewStencilValue, regStencilAddr);
  1238. } else {
  1239. DECL_REG (regMaskedOriginal);
  1240. DECL_REG (regMaskedNewValue);
  1241. DECL_REG (regWriteValue);
  1242. DECL_CONST_REG (regStencilWriteMask, m_State->m_Stencil.Mask);
  1243. DECL_REG (regInverseWriteMask);
  1244. AND (regMaskedNewValue, regNewStencilValue, regStencilWriteMask);
  1245. NOT (regInverseWriteMask, regStencilWriteMask);
  1246. AND (regMaskedOriginal, regStencilValue, regInverseWriteMask);
  1247. OR (regWriteValue, regMaskedOriginal, regMaskedNewValue);
  1248. STW (regWriteValue, regStencilAddr);
  1249. }
  1250. no_write:
  1251. if (passedTest == cg_op_nop) {
  1252. return;
  1253. } else {
  1254. BRA (continuation);
  1255. }
  1256. //}
  1257. }
  1258. cg_block_ref_t * labelStencilZTestPassed = cg_block_ref_create(procedure);
  1259. // stencil test passed
  1260. block = cg_block_create(procedure, weight);
  1261. labelStencilPassed->block = block;
  1262. //if (!depthTest) {
  1263. if (branchOnDepthTestPassed == cg_op_nop) {
  1264. // nothing
  1265. } else if (branchOnDepthTestPassed == cg_op_bra) {
  1266. BRA (labelStencilZTestPassed);
  1267. } else {
  1268. DECL_FLAGS(regDepthTest1);
  1269. CMP (regDepthTest1, fragmentInfo.regDepth, regZBufferValue);
  1270. cg_create_inst_branch_cond(block, branchOnDepthTestPassed, regDepthTest1, labelStencilZTestPassed CG_INST_DEBUG_ARGS);
  1271. }
  1272. {
  1273. cg_virtual_reg_t * regNewStencilValue;
  1274. switch (m_State->m_Stencil.ZFail) {
  1275. default:
  1276. case RasterizerState::StencilOpKeep:
  1277. regNewStencilValue = regStencilValue;
  1278. break;
  1279. case RasterizerState::StencilOpZero:
  1280. //stencilValue = 0;
  1281. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1282. LDI (regNewStencilValue, 0);
  1283. break;
  1284. case RasterizerState::StencilOpReplace:
  1285. //stencilValue = m_State->m_StencilReference;
  1286. regNewStencilValue = regStencilRef;
  1287. break;
  1288. case RasterizerState::StencilOpIncr:
  1289. //if (stencilValue != 0xffffffff) {
  1290. // stencilValue++;
  1291. //}
  1292. {
  1293. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1294. DECL_REG (regConstant1);
  1295. DECL_FLAGS (regFlag);
  1296. LDI (regConstant1, 1);
  1297. ADD_S (regNewStencilValue, regFlag, regStencilValue, regConstant1);
  1298. if (m_State->m_DepthTest.Enabled) {
  1299. BEQ (regFlag, continuation);
  1300. } else {
  1301. BEQ (regFlag, labelStencilBypassed);
  1302. }
  1303. }
  1304. break;
  1305. case RasterizerState::StencilOpDecr:
  1306. //if (stencilValue != 0) {
  1307. // stencilValue--;
  1308. //}
  1309. {
  1310. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1311. DECL_REG (regConstant0);
  1312. DECL_REG (regConstant1);
  1313. DECL_FLAGS (regFlag);
  1314. LDI (regConstant0, 0);
  1315. CMP (regFlag, regStencilValue, regConstant0);
  1316. if (m_State->m_DepthTest.Enabled) {
  1317. BEQ (regFlag, continuation);
  1318. } else {
  1319. BEQ (regFlag, labelStencilBypassed);
  1320. }
  1321. LDI (regConstant1, 1);
  1322. SUB (regNewStencilValue, regStencilValue, regConstant1);
  1323. }
  1324. break;
  1325. case RasterizerState::StencilOpInvert:
  1326. //stencilValue = ~stencilValue;
  1327. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1328. NOT (regNewStencilValue, regStencilValue);
  1329. break;
  1330. }
  1331. //m_Surface->GetStencilBuffer()[offset] = stencilValue;
  1332. //STW (regNewStencilValue, regStencilAddr);
  1333. //}
  1334. if (m_State->m_Stencil.Mask == ~0) {
  1335. STW (regNewStencilValue, regStencilAddr);
  1336. } else {
  1337. DECL_REG (regMaskedOriginal);
  1338. DECL_REG (regMaskedNewValue);
  1339. DECL_REG (regWriteValue);
  1340. DECL_CONST_REG (regStencilWriteMask, m_State->m_Stencil.Mask);
  1341. DECL_REG (regInverseWriteMask);
  1342. AND (regMaskedNewValue, regNewStencilValue, regStencilWriteMask);
  1343. NOT (regInverseWriteMask, regStencilWriteMask);
  1344. AND (regMaskedOriginal, regStencilValue, regInverseWriteMask);
  1345. OR (regWriteValue, regMaskedOriginal, regMaskedNewValue);
  1346. STW (regWriteValue, regStencilAddr);
  1347. }
  1348. }
  1349. if (m_State->m_DepthTest.Enabled) {
  1350. // return;
  1351. BRA (continuation);
  1352. } else {
  1353. BRA (labelStencilBypassed);
  1354. }
  1355. //} else {
  1356. // stencil nad z-test passed
  1357. block = cg_block_create(procedure, weight);
  1358. labelStencilZTestPassed->block = block;
  1359. {
  1360. cg_virtual_reg_t * regNewStencilValue;
  1361. switch (m_State->m_Stencil.ZPass) {
  1362. default:
  1363. case RasterizerState::StencilOpKeep:
  1364. regNewStencilValue = regStencilValue;
  1365. break;
  1366. case RasterizerState::StencilOpZero:
  1367. //stencilValue = 0;
  1368. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1369. LDI (regNewStencilValue, 0);
  1370. break;
  1371. case RasterizerState::StencilOpReplace:
  1372. //stencilValue = m_State->m_StencilReference;
  1373. regNewStencilValue = regStencilRef;
  1374. break;
  1375. case RasterizerState::StencilOpIncr:
  1376. //if (stencilValue != 0xffffffff) {
  1377. // stencilValue++;
  1378. //}
  1379. {
  1380. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1381. DECL_REG (regConstant1);
  1382. DECL_FLAGS (regFlag);
  1383. LDI (regConstant1, 1);
  1384. ADD_S (regNewStencilValue, regFlag, regStencilValue, regConstant1);
  1385. BEQ (regFlag, labelStencilBypassed);
  1386. }
  1387. break;
  1388. case RasterizerState::StencilOpDecr:
  1389. //if (stencilValue != 0) {
  1390. // stencilValue--;
  1391. //}
  1392. {
  1393. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1394. DECL_REG (regConstant0);
  1395. DECL_REG (regConstant1);
  1396. DECL_FLAGS (regFlag);
  1397. LDI (regConstant0, 0);
  1398. CMP (regFlag, regStencilValue, regConstant0);
  1399. BEQ (regFlag, labelStencilBypassed);
  1400. LDI (regConstant1, 1);
  1401. SUB (regNewStencilValue, regStencilValue, regConstant1);
  1402. }
  1403. break;
  1404. case RasterizerState::StencilOpInvert:
  1405. //stencilValue = ~stencilValue;
  1406. regNewStencilValue = cg_virtual_reg_create(procedure, cg_reg_type_general);
  1407. NOT (regNewStencilValue, regStencilValue);
  1408. break;
  1409. }
  1410. //m_Surface->GetStencilBuffer()[offset] = stencilValue;
  1411. //STW (regNewStencilValue, regStencilAddr);
  1412. //}
  1413. if (m_State->m_Stencil.Mask == ~0) {
  1414. STW (regNewStencilValue, regStencilAddr);
  1415. } else {
  1416. DECL_REG (regMaskedOriginal);
  1417. DECL_REG (regMaskedNewValue);
  1418. DECL_REG (regWriteValue);
  1419. DECL_CONST_REG (regStencilWriteMask, m_State->m_Stencil.Mask);
  1420. DECL_REG (regInverseWriteMask);
  1421. AND (regMaskedNewValue, regNewStencilValue, regStencilWriteMask);
  1422. NOT (regInverseWriteMask, regStencilWriteMask);
  1423. AND (regMaskedOriginal, regStencilValue, regInverseWriteMask);
  1424. OR (regWriteValue, regMaskedOriginal, regMaskedNewValue);
  1425. STW (regWriteValue, regStencilAddr);
  1426. }
  1427. }
  1428. // stencil test bypassed
  1429. block = cg_block_create(procedure, weight);
  1430. labelStencilBypassed->block = block;
  1431. }
  1432. // surface color buffer, depth buffer, alpha buffer, stencil buffer
  1433. cg_virtual_reg_t * regColorBuffer = LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_COLOR_BUFFER);
  1434. cg_virtual_reg_t * regAlphaBuffer = LOAD_DATA(block, fragmentInfo.regInfo, OFFSET_SURFACE_ALPHA_BUFFER);
  1435. //U16 dstValue = m_Surface->GetColorBuffer()[offset];
  1436. //U8 dstAlpha = m_Surface->GetAlphaBuffer()[offset];
  1437. DECL_REG (regDstValue);
  1438. DECL_REG (regDstAlpha);
  1439. DECL_REG (regColorAddr);
  1440. DECL_REG (regAlphaAddr);
  1441. ADD (regColorAddr, regColorBuffer, regOffset2);
  1442. ADD (regAlphaAddr, regAlphaBuffer, regOffset);
  1443. LDH (regDstValue, regColorAddr);
  1444. LDB (regDstAlpha, regAlphaAddr);
  1445. cg_virtual_reg_t * regDstR = ExtractBitFieldTo255(block, regDstValue, 11, 15);
  1446. cg_virtual_reg_t * regDstG = ExtractBitFieldTo255(block, regDstValue, 5, 10);
  1447. cg_virtual_reg_t * regDstB = ExtractBitFieldTo255(block, regDstValue, 0, 4);
  1448. // Blending
  1449. if (m_State->m_Blend.Enabled) {
  1450. cg_virtual_reg_t * regSrcBlendR = 0;
  1451. cg_virtual_reg_t * regSrcBlendG = 0;
  1452. cg_virtual_reg_t * regSrcBlendB = 0;
  1453. cg_virtual_reg_t * regSrcBlendA = 0;
  1454. cg_virtual_reg_t * regDstBlendR = 0;
  1455. cg_virtual_reg_t * regDstBlendG = 0;
  1456. cg_virtual_reg_t * regDstBlendB = 0;
  1457. cg_virtual_reg_t * regDstBlendA = 0;
  1458. bool noSource = false;
  1459. bool noTarget = false;
  1460. //Color dstColor = Color::From565A(dstValue, dstAlpha);
  1461. //Color srcCoeff, dstCoeff;
  1462. // ------------------------------------------------------------------
  1463. // In all the blending code, the assumption is that the blending
  1464. // coefficients are in the range 0x00 - 0x100, while the color to
  1465. // be modulated is R:5, G:6, B:5, A:8 bits format
  1466. // ------------------------------------------------------------------
  1467. switch (m_State->m_Blend.FuncSrc) {
  1468. default:
  1469. case RasterizerState::BlendFuncSrcZero:
  1470. //srcCoeff = Color(0, 0, 0, 0);
  1471. regSrcBlendR = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  1472. LDI (regSrcBlendR, 0);
  1473. regSrcBlendG = regSrcBlendB = regSrcBlendA = regSrcBlendR;
  1474. noSource = true;
  1475. break;
  1476. case RasterizerState::BlendFuncSrcOne:
  1477. {
  1478. //srcCoeff = Color(Color::MAX, Color::MAX, Color::MAX, Color::MAX);
  1479. regSrcBlendR = regColorR;
  1480. regSrcBlendG = regColorG;
  1481. regSrcBlendB = regColorB;
  1482. regSrcBlendA = regColorA;
  1483. }
  1484. break;
  1485. case RasterizerState::BlendFuncSrcDstColor:
  1486. {
  1487. //srcCoeff = color; // adjust scaling of R, G, B
  1488. regSrcBlendR = Mul255(block, regColorR, regDstR);
  1489. regSrcBlendG = Mul255(block, regColorG, regDstG);
  1490. regSrcBlendB = Mul255(block, regColorB, regDstB);
  1491. regSrcBlendA = Mul255(block, regColorA, regDstAlpha);
  1492. }
  1493. break;
  1494. case RasterizerState::BlendFuncSrcOneMinusDstColor:
  1495. {
  1496. //srcCoeff = Color(Color::MAX - color.R(), Color::MAX - color.G(), Color::MAX - color.B(), Color::MAX - color.A());
  1497. DECL_CONST_REG (constantMaxColor, 0xff);
  1498. regSrcBlendR = Mul255(block, regColorR, Sub(block, constantMaxColor, regDstR));
  1499. regSrcBlendG = Mul255(block, regColorG, Sub(block, constantMaxColor, regDstG));
  1500. regSrcBlendB = Mul255(block, regColorB, Sub(block, constantMaxColor, regDstB));
  1501. regSrcBlendA = Mul255(block, regColorA, Sub(block, constantMaxColor, regDstAlpha));
  1502. }
  1503. break;
  1504. case RasterizerState::BlendFuncSrcSrcAlpha:
  1505. //srcCoeff = Color(color.A(), color.A(), color.A(), color.A());
  1506. //srcCoeff * color
  1507. {
  1508. regSrcBlendR = Mul255(block, regColorR, regColorA);
  1509. regSrcBlendG = Mul255(block, regColorG, regColorA);
  1510. regSrcBlendB = Mul255(block, regColorB, regColorA);
  1511. regSrcBlendA = Mul255(block, regColorA, regColorA);
  1512. }
  1513. break;
  1514. case RasterizerState::BlendFuncSrcOneMinusSrcAlpha:
  1515. {
  1516. //srcCoeff = Color(Color::MAX - color.A(), Color::MAX - color.A(), Color::MAX - color.A(), Color::MAX - color.A());
  1517. DECL_CONST_REG (constantMaxColor, 0xff);
  1518. cg_virtual_reg_t * regOneMinusSrcAlpha = Sub(block, constantMaxColor, regColorA);
  1519. regSrcBlendR = Mul255(block, regColorR, regOneMinusSrcAlpha);
  1520. regSrcBlendG = Mul255(block, regColorG, regOneMinusSrcAlpha);
  1521. regSrcBlendB = Mul255(block, regColorB, regOneMinusSrcAlpha);
  1522. regSrcBlendA = Mul255(block, regColorA, regOneMinusSrcAlpha);
  1523. }
  1524. break;
  1525. case RasterizerState::BlendFuncSrcDstAlpha:
  1526. //srcCoeff = Color(dstAlpha, dstAlpha, dstAlpha, dstAlpha);
  1527. //srcCoeff * color
  1528. {
  1529. regSrcBlendR = Mul255(block, regColorR, regDstAlpha);
  1530. regSrcBlendG = Mul255(block, regColorG, regDstAlpha);
  1531. regSrcBlendB = Mul255(block, regColorB, regDstAlpha);
  1532. regSrcBlendA = Mul255(block, regColorA, regDstAlpha);
  1533. }
  1534. break;
  1535. case RasterizerState::BlendFuncSrcOneMinusDstAlpha:
  1536. //srcCoeff = Color(Color::MAX - dstAlpha, Color::MAX - dstAlpha, Color::MAX - dstAlpha, Color::MAX - dstAlpha);
  1537. {
  1538. DECL_CONST_REG (constantMaxColor, 0xff);
  1539. cg_virtual_reg_t * regOneMinusDstAlpha = Sub(block, constantMaxColor, regDstAlpha);
  1540. regSrcBlendR = Mul255(block, regColorR, regOneMinusDstAlpha);
  1541. regSrcBlendG = Mul255(block, regColorG, regOneMinusDstAlpha);
  1542. regSrcBlendB = Mul255(block, regColorB, regOneMinusDstAlpha);
  1543. regSrcBlendA = Mul255(block, regColorA, regOneMinusDstAlpha);
  1544. }
  1545. break;
  1546. case RasterizerState::BlendFuncSrcSrcAlphaSaturate:
  1547. {
  1548. DECL_CONST_REG (constantMaxColor, 0xff);
  1549. // U8 rev = Color::MAX - dstAlpha;
  1550. cg_virtual_reg_t * regRev = Sub(block, constantMaxColor, regDstAlpha);
  1551. // U8 f = (rev < color.A() ? rev : color.A());
  1552. DECL_REG(regF);
  1553. MIN (regF, regRev, regColorA);
  1554. // dstCoeff = Color(f, f, f, Color::MAX);
  1555. //dstCoeff * dstColor
  1556. regSrcBlendR = Mul255(block, regColorR, regF);
  1557. regSrcBlendG = Mul255(block, regColorG, regF);
  1558. regSrcBlendB = Mul255(block, regColorB, regF);
  1559. regSrcBlendA = regColorA;
  1560. }
  1561. break;
  1562. }
  1563. switch (m_State->m_Blend.FuncDst) {
  1564. default:
  1565. case RasterizerState::BlendFuncDstZero:
  1566. //dstCoeff = Color(0, 0, 0, 0);
  1567. regDstBlendR = cg_virtual_reg_create(block->proc, cg_reg_type_general);
  1568. LDI (regDstBlendR, 0);
  1569. regDstBlendG = regDstBlendB = regDstBlendA = regDstBlendR;
  1570. noTarget = true;
  1571. break;
  1572. case RasterizerState::BlendFuncDstOne:
  1573. {
  1574. //dstCoeff = Color(Color::MAX, Color::MAX, Color::MAX, Color::MAX);
  1575. regDstBlendR = regDstR;
  1576. regDstBlendG = regDstG;
  1577. regDstBlendB = regDstB;
  1578. regDstBlendA = regDstAlpha;
  1579. }
  1580. break;
  1581. case RasterizerState::BlendFuncDstSrcColor:
  1582. {
  1583. //dstCoeff = color;
  1584. //dstCoeff * dstColor
  1585. regDstBlendR = Mul255(block, regDstR, regColorR);
  1586. regDstBlendG = Mul255(block, regDstG, regColorG);
  1587. regDstBlendB = Mul255(block, regDstB, regColorB);
  1588. regDstBlendA = Mul255(block, regDstAlpha, regColorA);
  1589. }
  1590. break;
  1591. case RasterizerState::BlendFuncDstOneMinusSrcColor:
  1592. {
  1593. //dstCoeff = Color(Color::MAX - color.R(), Color::MAX - color.G(), Color::MAX - color.B(), Color::MAX - color.A());
  1594. //dstCoeff * dstColor
  1595. DECL_CONST_REG (constantMaxColor, 0xff);
  1596. regDstBlendR = Mul255(block, regDstR, Sub(block, constantMaxColor, regColorR));
  1597. regDstBlendG = Mul255(block, regDstG, Sub(block, constantMaxColor, regColorG));
  1598. regDstBlendB = Mul255(block, regDstB, Sub(block, constantMaxColor, regColorB));
  1599. regDstBlendA = Mul255(block, regDstAlpha, Sub(block