/opengles/src/arm/GenLline.cpp

http://ftk.googlecode.com/ · C++ · 1140 lines · 601 code · 295 blank · 244 comment · 13 complexity · f55f5c5fae19ac49ebd0a48591f3334a MD5 · raw file

  1. // ==========================================================================
  2. //
  3. // GenLine.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. U32 Log(U32 value) {
  67. U32 result = 0;
  68. U32 mask = 1;
  69. while ((value & mask) != value) {
  70. ++result;
  71. mask = (mask << 1) | 1;
  72. }
  73. return result;
  74. }
  75. }
  76. void CodeGenerator :: GenerateRasterLine() {
  77. cg_proc_t * procedure = cg_proc_create(m_Module);
  78. // The signature of the generated function is:
  79. // (const RasterInfo * info, const EdgePos& start, const EdgePos& end);
  80. // Do not pass in y coordinate but rather assume that raster info pointers have been
  81. // adjusted to point to current scanline in memory
  82. // In the edge buffers, z, tu and tv are actually divided by w
  83. DECL_REG (regInfo); // virtual register containing info structure pointer
  84. DECL_REG (regFrom); // virtual register containing start RasterPos pointer
  85. DECL_REG (regTo); // virtual register containing end RasterPos pointer
  86. procedure->num_args = 3; // the previous three declarations make up the arguments
  87. cg_block_t * block = cg_block_create(procedure, 1);
  88. cg_block_ref_t * blockRefEndProc = cg_block_ref_create(procedure);
  89. cg_virtual_reg_t * regTexture = LOAD_DATA(block, regInfo, OFFSET_TEXTURES);
  90. FragmentGenerationInfo info;
  91. size_t unit;
  92. info.regInfo = regInfo;
  93. info.regTexture[0] = regTexture;
  94. for (unit = 1; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  95. DECL_CONST_REG (regOffset, unit * 4);
  96. DECL_REG (regTextureN);
  97. ADD (regTextureN, regTexture, regOffset);
  98. info.regTexture[unit] = regTextureN;
  99. }
  100. // EGL_Fixed deltaX = p_to.m_WindowCoords.x - p_from.m_WindowCoords.x;
  101. // EGL_Fixed deltaY = p_to.m_WindowCoords.y - p_from.m_WindowCoords.y;
  102. DECL_REG (regDeltaX);
  103. DECL_REG (regDeltaY);
  104. cg_virtual_reg_t * regToX = LOAD_DATA(block, regTo, OFFSET_RASTER_POS_WINDOW_X);
  105. cg_virtual_reg_t * regFromX = LOAD_DATA(block, regFrom, OFFSET_RASTER_POS_WINDOW_X);
  106. cg_virtual_reg_t * regToY = LOAD_DATA(block, regTo, OFFSET_RASTER_POS_WINDOW_Y);
  107. cg_virtual_reg_t * regFromY = LOAD_DATA(block, regFrom, OFFSET_RASTER_POS_WINDOW_Y);
  108. FSUB (regDeltaX, regToX, regFromX);
  109. FSUB (regDeltaY, regToY, regFromY);
  110. DECL_REG (regAbsDeltaX);
  111. DECL_REG (regAbsDeltaY);
  112. ABS (regAbsDeltaX, regDeltaX);
  113. ABS (regAbsDeltaY, regDeltaY);
  114. // if (EGL_Abs(deltaX) > EGL_Abs(deltaY)) {
  115. DECL_FLAGS (regCompareXY);
  116. FCMP (regCompareXY, regAbsDeltaY, regAbsDeltaX);
  117. cg_block_ref_t * blockRefRasterY = cg_block_ref_create(procedure);
  118. BGT (regCompareXY, blockRefRasterY);
  119. // Bresenham along x-axis
  120. block = cg_block_create(procedure, 1);
  121. {
  122. // const RasterPos *start, *end;
  123. // I32 x;
  124. // I32 endX;
  125. // EGL_Fixed roundedX;
  126. // if (deltaX < 0) {
  127. DECL_FLAGS (regSignX);
  128. DECL_CONST_REG (regZero, 0);
  129. FCMP (regSignX, regDeltaX, regZero);
  130. cg_block_ref_t * blockRefPositiveDeltaX = cg_block_ref_create(procedure);
  131. BGE (regSignX, blockRefPositiveDeltaX);
  132. block = cg_block_create(procedure, 1);
  133. // deltaY = -deltaY;
  134. // deltaX = -deltaX;
  135. DECL_REG (regMinusDeltaX);
  136. DECL_REG (regMinusDeltaY);
  137. FNEG (regMinusDeltaX, regDeltaX);
  138. FNEG (regMinusDeltaY, regDeltaY);
  139. // start = &p_to;
  140. // end = &p_from;
  141. DECL_REG (regStart0);
  142. DECL_REG (regEnd0);
  143. OR (regStart0, regTo, regTo);
  144. OR (regEnd0, regFrom, regFrom);
  145. // roundedX = EGL_NearestInt(p_to.m_WindowCoords.x + 1);
  146. // x = EGL_IntFromFixed(roundedX);
  147. // endX = EGL_IntFromFixed(p_from.m_WindowCoords.x + ((EGL_ONE)/2));
  148. DECL_REG (regX0);
  149. DECL_REG (regEndX0);
  150. DECL_CONST_REG (regHalf, 0x8000);
  151. DECL_REG (regXToPlusHalf0);
  152. DECL_REG (regXFromPlusHalf0);
  153. FADD (regXToPlusHalf0, regToX, regHalf);
  154. TRUNC (regX0, regXToPlusHalf0);
  155. FADD (regXFromPlusHalf0, regFromX, regHalf);
  156. TRUNC (regEndX0, regXFromPlusHalf0);
  157. cg_block_ref_t * blockRefPostDeltaX = cg_block_ref_create(procedure);
  158. BRA (blockRefPostDeltaX);
  159. // } else {
  160. block = cg_block_create(procedure, 1);
  161. blockRefPositiveDeltaX->block = block;
  162. // start = &p_from;
  163. // end = &p_to;
  164. DECL_REG (regStart1);
  165. DECL_REG (regEnd1);
  166. OR (regStart1, regFrom, regFrom);
  167. OR (regEnd1, regTo, regTo);
  168. // roundedX = EGL_NearestInt(p_from.m_WindowCoords.x);
  169. // x = EGL_IntFromFixed(roundedX);
  170. // endX = EGL_IntFromFixed(p_to.m_WindowCoords.x + ((EGL_ONE)/2-1));
  171. DECL_REG (regX1);
  172. DECL_REG (regEndX1);
  173. DECL_CONST_REG (regHalf1, 0x7fff);
  174. DECL_REG (regXToPlusHalf1);
  175. DECL_REG (regXFromPlusHalf1);
  176. FADD (regXToPlusHalf1, regToX, regHalf1);
  177. TRUNC (regEndX1, regXToPlusHalf1);
  178. FADD (regXFromPlusHalf1, regFromX, regHalf1);
  179. TRUNC (regX1, regXFromPlusHalf1);
  180. // }
  181. block = cg_block_create(procedure, 1);
  182. blockRefPostDeltaX->block = block;
  183. DECL_REG (regCommonDeltaX);
  184. DECL_REG (regCommonDeltaY);
  185. PHI (regCommonDeltaX, cg_create_virtual_reg_list(procedure->module->heap, regDeltaX, regMinusDeltaX, NULL));
  186. PHI (regCommonDeltaY, cg_create_virtual_reg_list(procedure->module->heap, regDeltaY, regMinusDeltaY, NULL));
  187. DECL_REG (regCommonX);
  188. DECL_REG (regCommonEndX);
  189. PHI (regCommonX, cg_create_virtual_reg_list(procedure->module->heap, regX0, regX1, NULL));
  190. PHI (regCommonEndX, cg_create_virtual_reg_list(procedure->module->heap, regEndX0, regEndX1, NULL));
  191. // const RasterPos& from = *start;
  192. // const RasterPos& to = *end;
  193. DECL_REG (regCommonFrom);
  194. DECL_REG (regCommonTo);
  195. PHI (regCommonFrom, cg_create_virtual_reg_list(procedure->module->heap, regStart0, regStart1, NULL));
  196. PHI (regCommonTo, cg_create_virtual_reg_list(procedure->module->heap, regEnd0, regEnd1, NULL));
  197. // I32 yIncrement = (deltaY > 0) ? 1 : -1;
  198. DECL_FLAGS (regSignY);
  199. FCMP (regSignY, regCommonDeltaY, regZero);
  200. cg_block_ref_t * blockRefPositiveDeltaY = cg_block_ref_create(procedure);
  201. BGT (regSignY, blockRefPositiveDeltaY);
  202. block = cg_block_create(procedure, 1);
  203. DECL_CONST_REG (regYIncrementNeg, -1);
  204. cg_block_ref_t * blockRefCommonDeltaY = cg_block_ref_create(procedure);
  205. BRA (blockRefCommonDeltaY);
  206. block = cg_block_create(procedure, 1);
  207. blockRefPositiveDeltaY->block = block;
  208. DECL_CONST_REG (regYIncrementPos, 1);
  209. block = cg_block_create(procedure, 1);
  210. blockRefCommonDeltaY->block = block;
  211. DECL_REG (regYIncrement);
  212. PHI (regYIncrement, cg_create_virtual_reg_list(procedure->module->heap, regYIncrementPos, regYIncrementNeg, NULL));
  213. // -- initialize with starting vertex attributes
  214. // FractionalColor baseColor = from.m_Color;
  215. // EGL_Fixed OneOverZ = from.m_WindowCoords.invZ;
  216. // EGL_Fixed tuOverZ = EGL_Mul(from.m_TextureCoords.tu, OneOverZ);
  217. // EGL_Fixed tvOverZ = EGL_Mul(from.m_TextureCoords.tv, OneOverZ);
  218. // EGL_Fixed fogDensity = from.m_FogDensity;
  219. // EGL_Fixed depth = from.m_WindowCoords.depth;
  220. cg_virtual_reg_t * regColorR0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_R);
  221. cg_virtual_reg_t * regColorG0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_G);
  222. cg_virtual_reg_t * regColorB0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_B);
  223. cg_virtual_reg_t * regColorA0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_A);
  224. cg_virtual_reg_t * regInvZ0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_WINDOW_INV_Z);
  225. cg_virtual_reg_t * regFog0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_FOG);
  226. cg_virtual_reg_t * regDepth0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_WINDOW_DEPTH);
  227. cg_virtual_reg_t * regTu0[EGL_NUM_TEXTURE_UNITS];
  228. cg_virtual_reg_t * regTv0[EGL_NUM_TEXTURE_UNITS];
  229. cg_virtual_reg_t * regTuOverZ0[EGL_NUM_TEXTURE_UNITS];
  230. cg_virtual_reg_t * regTvOverZ0[EGL_NUM_TEXTURE_UNITS];
  231. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  232. regTu0[unit] = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_TEX_TU + unit * sizeof(TexCoord));
  233. regTv0[unit] = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_TEX_TV + unit * sizeof(TexCoord));
  234. ALLOC_REG(regTuOverZ0[unit]);
  235. ALLOC_REG(regTvOverZ0[unit]);
  236. FMUL (regTuOverZ0[unit], regTu0[unit], regInvZ0);
  237. FMUL (regTvOverZ0[unit], regTv0[unit], regInvZ0);
  238. }
  239. // -- end initialize
  240. // EGL_Fixed invSpan = EGL_Inverse(deltaX);
  241. // EGL_Fixed slope = EGL_Mul(EGL_Abs(deltaY), invSpan);
  242. // EGL_Fixed OneOverZTo = to.m_WindowCoords.invZ;
  243. DECL_REG (regInvSpan);
  244. DECL_REG (regSlope);
  245. FINV (regInvSpan, regCommonDeltaX);
  246. FMUL (regSlope, regAbsDeltaY, regInvSpan);
  247. cg_virtual_reg_t * regEndColorR0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_R);
  248. cg_virtual_reg_t * regEndColorG0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_G);
  249. cg_virtual_reg_t * regEndColorB0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_B);
  250. cg_virtual_reg_t * regEndColorA0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_A);
  251. cg_virtual_reg_t * regEndInvZ0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_WINDOW_INV_Z);
  252. cg_virtual_reg_t * regEndFog0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_FOG);
  253. cg_virtual_reg_t * regEndDepth0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_WINDOW_DEPTH);
  254. cg_virtual_reg_t * regEndTu0[EGL_NUM_TEXTURE_UNITS];
  255. cg_virtual_reg_t * regEndTv0[EGL_NUM_TEXTURE_UNITS];
  256. cg_virtual_reg_t * regEndTuOverZ0[EGL_NUM_TEXTURE_UNITS];
  257. cg_virtual_reg_t * regEndTvOverZ0[EGL_NUM_TEXTURE_UNITS];
  258. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  259. regEndTu0[unit] = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_TEX_TU + unit * sizeof(TexCoord));
  260. regEndTv0[unit] = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_TEX_TV + unit * sizeof(TexCoord));
  261. ALLOC_REG(regEndTuOverZ0[unit]);
  262. ALLOC_REG(regEndTvOverZ0[unit]);
  263. FMUL (regEndTuOverZ0[unit], regEndTu0[unit], regEndInvZ0);
  264. FMUL (regEndTvOverZ0[unit], regEndTv0[unit], regEndInvZ0);
  265. }
  266. // -- increments(to, from, invSpan)
  267. // FractionalColor colorIncrement = (to.m_Color - from.m_Color) * invSpan;
  268. // EGL_Fixed deltaFog = EGL_Mul(to.m_FogDensity - from.m_FogDensity, invSpan);
  269. // EGL_Fixed deltaZ = EGL_Mul(OneOverZTo - OneOverZ, invSpan);
  270. // EGL_Fixed deltaU = EGL_Mul(EGL_Mul(to.m_TextureCoords.tu, OneOverZTo) -
  271. // EGL_Mul(from.m_TextureCoords.tu, OneOverZ), invSpan);
  272. // EGL_Fixed deltaV = EGL_Mul(EGL_Mul(to.m_TextureCoords.tv, OneOverZTo) -
  273. // EGL_Mul(from.m_TextureCoords.tv, OneOverZ), invSpan);
  274. // EGL_Fixed deltaDepth = EGL_Mul(to.m_WindowCoords.depth - from.m_WindowCoords.depth, invSpan);
  275. DECL_REG (regDiffColorR);
  276. DECL_REG (regDeltaColorR);
  277. DECL_REG (regDiffColorG);
  278. DECL_REG (regDeltaColorG);
  279. DECL_REG (regDiffColorB);
  280. DECL_REG (regDeltaColorB);
  281. DECL_REG (regDiffColorA);
  282. DECL_REG (regDeltaColorA);
  283. DECL_REG (regDiffFog);
  284. DECL_REG (regDeltaFog);
  285. DECL_REG (regDiffDepth);
  286. DECL_REG (regDeltaDepth);
  287. FSUB (regDiffColorR, regEndColorR0, regColorR0);
  288. FMUL (regDeltaColorR, regDiffColorR, regInvSpan);
  289. FSUB (regDiffColorG, regEndColorG0, regColorG0);
  290. FMUL (regDeltaColorG, regDiffColorG, regInvSpan);
  291. FSUB (regDiffColorB, regEndColorB0, regColorB0);
  292. FMUL (regDeltaColorB, regDiffColorB, regInvSpan);
  293. FSUB (regDiffColorA, regEndColorA0, regColorA0);
  294. FMUL (regDeltaColorA, regDiffColorA, regInvSpan);
  295. FSUB (regDiffFog, regEndFog0, regFog0);
  296. FMUL (regDeltaFog, regDiffFog, regInvSpan);
  297. FSUB (regDiffDepth, regEndDepth0, regDepth0);
  298. FMUL (regDeltaDepth, regDiffDepth, regInvSpan);
  299. DECL_REG (regDiffInvZ);
  300. DECL_REG (regDeltaInvZ);
  301. FSUB (regDiffInvZ, regEndInvZ0, regInvZ0);
  302. FMUL (regDeltaInvZ, regDiffInvZ, regInvSpan);
  303. cg_virtual_reg_t * regDiffTuOverZ[EGL_NUM_TEXTURE_UNITS];
  304. cg_virtual_reg_t * regDeltaTuOverZ[EGL_NUM_TEXTURE_UNITS];
  305. cg_virtual_reg_t * regDiffTvOverZ[EGL_NUM_TEXTURE_UNITS];
  306. cg_virtual_reg_t * regDeltaTvOverZ[EGL_NUM_TEXTURE_UNITS];
  307. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  308. ALLOC_REG (regDiffTuOverZ[unit]);
  309. ALLOC_REG (regDeltaTuOverZ[unit]);
  310. ALLOC_REG (regDiffTvOverZ[unit]);
  311. ALLOC_REG (regDeltaTvOverZ[unit]);
  312. FSUB (regDiffTuOverZ[unit], regEndTuOverZ0[unit], regTuOverZ0[unit]);
  313. FMUL (regDeltaTuOverZ[unit], regDiffTuOverZ[unit], regInvSpan);
  314. FSUB (regDiffTvOverZ[unit], regEndTvOverZ0[unit], regTvOverZ0[unit]);
  315. FMUL (regDeltaTvOverZ[unit], regDiffTvOverZ[unit], regInvSpan);
  316. }
  317. // -- end increments
  318. // I32 y = EGL_IntFromFixed(from.m_WindowCoords.y + ((EGL_ONE)/2-1));
  319. cg_virtual_reg_t * regFromY0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_WINDOW_Y);
  320. DECL_CONST_REG (regHalf2, 0x7fff);
  321. DECL_REG (regFromY0PlusHalf);
  322. DECL_REG (regY0);
  323. FADD (regFromY0PlusHalf, regFromY0, regHalf2);
  324. TRUNC (regY0, regFromY0PlusHalf);
  325. // EGL_Fixed error = 0;
  326. DECL_CONST_REG (regError0, 0);
  327. block = cg_block_create(procedure, 4);
  328. cg_block_ref_t * blockRefBeginLoop = cg_block_ref_create(procedure);
  329. blockRefBeginLoop->block = block;
  330. // for (; x < endX; ++x) {
  331. // --- variables for loop entry
  332. DECL_REG (regLoopX);
  333. DECL_REG (regLoopY);
  334. DECL_REG (regLoopError);
  335. DECL_REG (regLoopOneOverZ);
  336. DECL_REG (regLoopColorR);
  337. DECL_REG (regLoopColorG);
  338. DECL_REG (regLoopColorB);
  339. DECL_REG (regLoopColorA);
  340. DECL_REG (regLoopDepth);
  341. DECL_REG (regLoopFog);
  342. // --- variables for loop exit
  343. DECL_REG (regEndLoopX);
  344. DECL_REG (regEndLoopY);
  345. DECL_REG (regEndLoopError);
  346. DECL_REG (regEndLoopOneOverZ);
  347. DECL_REG (regEndLoopColorR);
  348. DECL_REG (regEndLoopColorG);
  349. DECL_REG (regEndLoopColorB);
  350. DECL_REG (regEndLoopColorA);
  351. DECL_REG (regEndLoopDepth);
  352. DECL_REG (regEndLoopFog);
  353. PHI (regLoopX, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopX, regCommonX, NULL));
  354. PHI (regLoopY, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopY, regY0, NULL));
  355. PHI (regLoopError, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopError, regError0, NULL));
  356. PHI (regLoopOneOverZ, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopOneOverZ, regInvZ0, NULL));
  357. PHI (regLoopColorR, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorR, regColorR0, NULL));
  358. PHI (regLoopColorG, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorG, regColorG0, NULL));
  359. PHI (regLoopColorB, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorB, regColorB0, NULL));
  360. PHI (regLoopColorA, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorA, regColorA0, NULL));
  361. PHI (regLoopDepth, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopDepth, regDepth0, NULL));
  362. PHI (regLoopFog, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopFog, regFog0, NULL));
  363. cg_virtual_reg_t * regLoopTuOverZ[EGL_NUM_TEXTURE_UNITS];
  364. cg_virtual_reg_t * regLoopTvOverZ[EGL_NUM_TEXTURE_UNITS];
  365. cg_virtual_reg_t * regEndLoopTuOverZ[EGL_NUM_TEXTURE_UNITS];
  366. cg_virtual_reg_t * regEndLoopTvOverZ[EGL_NUM_TEXTURE_UNITS];
  367. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  368. ALLOC_REG (regLoopTuOverZ[unit]);
  369. ALLOC_REG (regLoopTvOverZ[unit]);
  370. ALLOC_REG (regEndLoopTuOverZ[unit]);
  371. ALLOC_REG (regEndLoopTvOverZ[unit]);
  372. PHI (regLoopTuOverZ[unit], cg_create_virtual_reg_list(procedure->module->heap, regEndLoopTuOverZ[unit], regTuOverZ0[unit], NULL));
  373. PHI (regLoopTvOverZ[unit], cg_create_virtual_reg_list(procedure->module->heap, regEndLoopTvOverZ[unit], regTvOverZ0[unit], NULL));
  374. }
  375. // EGL_Fixed z = EGL_Inverse(OneOverZ);
  376. // OneOverZ += deltaZ;
  377. DECL_REG (regLoopZ);
  378. FINV (regLoopZ, regLoopOneOverZ);
  379. FADD (regEndLoopOneOverZ, regLoopOneOverZ, regDeltaInvZ);
  380. cg_virtual_reg_t * regLoopTu[EGL_NUM_TEXTURE_UNITS];
  381. cg_virtual_reg_t * regLoopTv[EGL_NUM_TEXTURE_UNITS];
  382. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  383. ALLOC_REG (regLoopTu[unit]);
  384. ALLOC_REG (regLoopTv[unit]);
  385. // EGL_Fixed tu = EGL_Mul(tuOverZ, z);
  386. // EGL_Fixed tv = EGL_Mul(tvOverZ, z);
  387. // tuOverZ += deltaU;
  388. // tvOverZ += deltaV;
  389. FMUL (regLoopTu[unit], regLoopTuOverZ[unit], regLoopZ);
  390. FADD (regEndLoopTuOverZ[unit], regLoopTuOverZ[unit], regDeltaTuOverZ[unit]);
  391. FMUL (regLoopTv[unit], regLoopTvOverZ[unit], regLoopZ);
  392. FADD (regEndLoopTvOverZ[unit], regLoopTvOverZ[unit], regDeltaTvOverZ[unit]);
  393. info.regU[unit] = regLoopTu[unit];
  394. info.regV[unit] = regLoopTv[unit];
  395. }
  396. // Fragment(x, y, depth, tu, tv, fogDensity, baseColor);
  397. info.regX = regLoopX;
  398. info.regY = regLoopY;
  399. info.regFog = regLoopFog;
  400. info.regDepth = regLoopDepth;
  401. info.regR = regLoopColorR;
  402. info.regG = regLoopColorG;
  403. info.regB = regLoopColorB;
  404. info.regA = regLoopColorA;
  405. cg_block_ref_t * postFragment = cg_block_ref_create(procedure);
  406. GenerateFragment(procedure, block, postFragment, info, 5, true);
  407. block = cg_block_create(procedure, 5);
  408. postFragment->block = block;
  409. // error += slope;
  410. DECL_REG (regIncError);
  411. FADD (regIncError, regLoopError, regSlope);
  412. // if (error > EGL_ONE) {
  413. DECL_CONST_REG (regLoopOne, EGL_ONE);
  414. DECL_FLAGS (regErrorOverflow);
  415. FCMP (regErrorOverflow, regIncError, regLoopOne);
  416. cg_block_ref_t * noOverflow = cg_block_ref_create(procedure);
  417. BLE (regErrorOverflow, noOverflow);
  418. block = cg_block_create(procedure, 5);
  419. // y += yIncrement;
  420. // error -= EGL_ONE;
  421. DECL_REG (regIncY);
  422. DECL_REG (regCorrectedError);
  423. FADD (regIncY, regLoopY, regYIncrement);
  424. FSUB (regCorrectedError, regIncError, regLoopOne);
  425. // }
  426. block = cg_block_create(procedure, 5);
  427. noOverflow->block = block;
  428. PHI (regEndLoopY, cg_create_virtual_reg_list(procedure->module->heap, regLoopY, regIncY, NULL));
  429. PHI (regEndLoopError, cg_create_virtual_reg_list(procedure->module->heap, regIncError, regCorrectedError, NULL));
  430. // baseColor += colorIncrement;
  431. FADD (regEndLoopColorR, regLoopColorR, regDeltaColorR);
  432. FADD (regEndLoopColorG, regLoopColorG, regDeltaColorG);
  433. FADD (regEndLoopColorB, regLoopColorB, regDeltaColorB);
  434. FADD (regEndLoopColorA, regLoopColorA, regDeltaColorA);
  435. // depth += deltaDepth;
  436. // fogDensity += deltaFog;
  437. FADD (regEndLoopDepth, regLoopDepth, regDeltaDepth);
  438. FADD (regEndLoopFog, regLoopFog, regDeltaFog);
  439. DECL_CONST_REG (regConstInt1, 1);
  440. DECL_FLAGS (regCompareX);
  441. FADD (regEndLoopX, regLoopX, regConstInt1);
  442. FCMP (regCompareX, regEndLoopX, regCommonEndX);
  443. BLT (regCompareX, blockRefBeginLoop);
  444. // }
  445. }
  446. BRA (blockRefEndProc);
  447. // } else {
  448. // Bresenham along y-axis
  449. block = cg_block_create(procedure, 1);
  450. blockRefRasterY->block = block;
  451. // const RasterPos *start, *end;
  452. // I32 y;
  453. // I32 endY;
  454. // EGL_Fixed roundedY; //, preStepY;
  455. // if (deltaY < 0) {
  456. // deltaY = -deltaY;
  457. // deltaX = -deltaX;
  458. // start = &p_to;
  459. // end = &p_from;
  460. // roundedY = EGL_NearestInt(p_to.m_WindowCoords.y + 1);
  461. // y = EGL_IntFromFixed(roundedY);
  462. // endY = EGL_IntFromFixed(p_from.m_WindowCoords.y + ((EGL_ONE)/2));
  463. // } else {
  464. // start = &p_from;
  465. // end = &p_to;
  466. // roundedY = EGL_NearestInt(p_from.m_WindowCoords.y);
  467. // y = EGL_IntFromFixed(roundedY);
  468. // endY = EGL_IntFromFixed(p_to.m_WindowCoords.y + ((EGL_ONE)/2-1));
  469. // }
  470. // const RasterPos& from = *start;
  471. // const RasterPos& to = *end;
  472. //-- initialize with from vertex attributes
  473. // FractionalColor baseColor = from.m_Color;
  474. // EGL_Fixed OneOverZ = from.m_WindowCoords.invZ;
  475. // EGL_Fixed tuOverZ = EGL_Mul(from.m_TextureCoords.tu, OneOverZ);
  476. // EGL_Fixed tvOverZ = EGL_Mul(from.m_TextureCoords.tv, OneOverZ);
  477. // EGL_Fixed fogDensity = from.m_FogDensity;
  478. // EGL_Fixed depth = from.m_WindowCoords.depth;
  479. //-- end initialize
  480. // EGL_Fixed invSpan = EGL_Inverse(deltaY);
  481. // EGL_Fixed slope = EGL_Mul(EGL_Abs(deltaX), invSpan);
  482. // EGL_Fixed OneOverZTo = to.m_WindowCoords.invZ;
  483. // -- increments(to, from, invSpan)
  484. // FractionalColor colorIncrement = (to.m_Color - from.m_Color) * invSpan;
  485. // EGL_Fixed deltaFog = EGL_Mul(to.m_FogDensity - from.m_FogDensity, invSpan);
  486. // EGL_Fixed deltaZ = EGL_Mul(OneOverZTo - OneOverZ, invSpan);
  487. // EGL_Fixed deltaU = EGL_Mul(EGL_Mul(to.m_TextureCoords.tu, OneOverZTo) -
  488. // EGL_Mul(from.m_TextureCoords.tu, OneOverZ), invSpan);
  489. // EGL_Fixed deltaV = EGL_Mul(EGL_Mul(to.m_TextureCoords.tv, OneOverZTo) -
  490. // EGL_Mul(from.m_TextureCoords.tv, OneOverZ), invSpan);
  491. // EGL_Fixed deltaDepth = EGL_Mul(to.m_WindowCoords.depth - from.m_WindowCoords.depth, invSpan);
  492. // -- end increments
  493. // I32 x = EGL_IntFromFixed(from.m_WindowCoords.x + ((EGL_ONE)/2-1));
  494. // I32 xIncrement = (deltaX > 0) ? 1 : -1;
  495. // EGL_Fixed error = 0;
  496. // can have xIncrement; yIncrement; xBaseIncrement, yBaseIncrement
  497. // then both x/y loops become the same
  498. // question: how to add correct mipmap selection?
  499. // for (; y < endY; ++y) {
  500. // EGL_Fixed z = EGL_Inverse(OneOverZ);
  501. // EGL_Fixed tu = EGL_Mul(tuOverZ, z);
  502. // EGL_Fixed tv = EGL_Mul(tvOverZ, z);
  503. // Fragment(x, y, depth, tu, tv, fogDensity, baseColor);
  504. // error += slope;
  505. // if (error > EGL_ONE) {
  506. // x += xIncrement;
  507. // error -= EGL_ONE;
  508. // }
  509. // baseColor += colorIncrement;
  510. // depth += deltaDepth;
  511. // OneOverZ += deltaZ;
  512. // tuOverZ += deltaU;
  513. // tvOverZ += deltaV;
  514. // fogDensity += deltaFog;
  515. // }
  516. // }
  517. {
  518. // const RasterPos *start, *end;
  519. // I32 x;
  520. // I32 endX;
  521. // EGL_Fixed roundedX;
  522. // if (deltaX < 0) {
  523. DECL_FLAGS (regSignY);
  524. DECL_CONST_REG (regZero, 0);
  525. FCMP (regSignY, regDeltaY, regZero);
  526. cg_block_ref_t * blockRefPositiveDeltaY = cg_block_ref_create(procedure);
  527. BGE (regSignY, blockRefPositiveDeltaY);
  528. block = cg_block_create(procedure, 1);
  529. // deltaY = -deltaY;
  530. // deltaX = -deltaX;
  531. DECL_REG (regMinusDeltaX);
  532. DECL_REG (regMinusDeltaY);
  533. FNEG (regMinusDeltaX, regDeltaX);
  534. FNEG (regMinusDeltaY, regDeltaY);
  535. // start = &p_to;
  536. // end = &p_from;
  537. DECL_REG (regStart0);
  538. DECL_REG (regEnd0);
  539. OR (regStart0, regTo, regTo);
  540. OR (regEnd0, regFrom, regFrom);
  541. // roundedX = EGL_NearestInt(p_to.m_WindowCoords.x + 1);
  542. // x = EGL_IntFromFixed(roundedX);
  543. // endX = EGL_IntFromFixed(p_from.m_WindowCoords.x + ((EGL_ONE)/2));
  544. DECL_REG (regY0);
  545. DECL_REG (regEndY0);
  546. DECL_CONST_REG (regHalf, 0x8000);
  547. DECL_REG (regYToPlusHalf0);
  548. DECL_REG (regYFromPlusHalf0);
  549. FADD (regYToPlusHalf0, regToY, regHalf);
  550. TRUNC (regY0, regYToPlusHalf0);
  551. FADD (regYFromPlusHalf0, regFromY, regHalf);
  552. TRUNC (regEndY0, regYFromPlusHalf0);
  553. cg_block_ref_t * blockRefPostDeltaY = cg_block_ref_create(procedure);
  554. BRA (blockRefPostDeltaY);
  555. // } else {
  556. block = cg_block_create(procedure, 1);
  557. blockRefPositiveDeltaY->block = block;
  558. // start = &p_from;
  559. // end = &p_to;
  560. DECL_REG (regStart1);
  561. DECL_REG (regEnd1);
  562. OR (regStart1, regFrom, regFrom);
  563. OR (regEnd1, regTo, regTo);
  564. // roundedX = EGL_NearestInt(p_from.m_WindowCoords.x);
  565. // x = EGL_IntFromFixed(roundedX);
  566. // endX = EGL_IntFromFixed(p_to.m_WindowCoords.x + ((EGL_ONE)/2-1));
  567. DECL_REG (regY1);
  568. DECL_REG (regEndY1);
  569. DECL_CONST_REG (regHalf1, 0x7fff);
  570. DECL_REG (regYToPlusHalf1);
  571. DECL_REG (regYFromPlusHalf1);
  572. FADD (regYToPlusHalf1, regToY, regHalf1);
  573. TRUNC (regEndY1, regYToPlusHalf1);
  574. FADD (regYFromPlusHalf1, regFromY, regHalf1);
  575. TRUNC (regY1, regYFromPlusHalf1);
  576. // }
  577. block = cg_block_create(procedure, 1);
  578. blockRefPostDeltaY->block = block;
  579. DECL_REG (regCommonDeltaX);
  580. DECL_REG (regCommonDeltaY);
  581. PHI (regCommonDeltaX, cg_create_virtual_reg_list(procedure->module->heap, regDeltaX, regMinusDeltaX, NULL));
  582. PHI (regCommonDeltaY, cg_create_virtual_reg_list(procedure->module->heap, regDeltaY, regMinusDeltaY, NULL));
  583. DECL_REG (regCommonY);
  584. DECL_REG (regCommonEndY);
  585. PHI (regCommonY, cg_create_virtual_reg_list(procedure->module->heap, regY0, regY1, NULL));
  586. PHI (regCommonEndY, cg_create_virtual_reg_list(procedure->module->heap, regEndY0, regEndY1, NULL));
  587. // const RasterPos& from = *start;
  588. // const RasterPos& to = *end;
  589. DECL_REG (regCommonFrom);
  590. DECL_REG (regCommonTo);
  591. PHI (regCommonFrom, cg_create_virtual_reg_list(procedure->module->heap, regStart0, regStart1, NULL));
  592. PHI (regCommonTo, cg_create_virtual_reg_list(procedure->module->heap, regEnd0, regEnd1, NULL));
  593. // I32 yIncrement = (deltaY > 0) ? 1 : -1;
  594. DECL_FLAGS (regSignX);
  595. FCMP (regSignX, regCommonDeltaX, regZero);
  596. cg_block_ref_t * blockRefPositiveDeltaX = cg_block_ref_create(procedure);
  597. BGT (regSignX, blockRefPositiveDeltaX);
  598. block = cg_block_create(procedure, 1);
  599. DECL_CONST_REG (regXIncrementNeg, -1);
  600. cg_block_ref_t * blockRefCommonDeltaX = cg_block_ref_create(procedure);
  601. BRA (blockRefCommonDeltaX);
  602. block = cg_block_create(procedure, 1);
  603. blockRefPositiveDeltaX->block = block;
  604. DECL_CONST_REG (regXIncrementPos, 1);
  605. block = cg_block_create(procedure, 1);
  606. blockRefCommonDeltaX->block = block;
  607. DECL_REG (regXIncrement);
  608. PHI (regXIncrement, cg_create_virtual_reg_list(procedure->module->heap, regXIncrementPos, regXIncrementNeg, NULL));
  609. // -- initialize with starting vertex attributes
  610. // FractionalColor baseColor = from.m_Color;
  611. // EGL_Fixed OneOverZ = from.m_WindowCoords.invZ;
  612. // EGL_Fixed tuOverZ = EGL_Mul(from.m_TextureCoords.tu, OneOverZ);
  613. // EGL_Fixed tvOverZ = EGL_Mul(from.m_TextureCoords.tv, OneOverZ);
  614. // EGL_Fixed fogDensity = from.m_FogDensity;
  615. // EGL_Fixed depth = from.m_WindowCoords.depth;
  616. cg_virtual_reg_t * regColorR0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_R);
  617. cg_virtual_reg_t * regColorG0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_G);
  618. cg_virtual_reg_t * regColorB0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_B);
  619. cg_virtual_reg_t * regColorA0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_COLOR_A);
  620. cg_virtual_reg_t * regInvZ0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_WINDOW_INV_Z);
  621. cg_virtual_reg_t * regFog0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_FOG);
  622. cg_virtual_reg_t * regDepth0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_WINDOW_DEPTH);
  623. cg_virtual_reg_t * regTu0[EGL_NUM_TEXTURE_UNITS];
  624. cg_virtual_reg_t * regTv0[EGL_NUM_TEXTURE_UNITS];
  625. cg_virtual_reg_t * regTuOverZ0[EGL_NUM_TEXTURE_UNITS];
  626. cg_virtual_reg_t * regTvOverZ0[EGL_NUM_TEXTURE_UNITS];
  627. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  628. regTu0[unit] = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_TEX_TU + unit * sizeof(TexCoord));
  629. regTv0[unit] = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_TEX_TV + unit * sizeof(TexCoord));
  630. ALLOC_REG (regTuOverZ0[unit]);
  631. ALLOC_REG (regTvOverZ0[unit]);
  632. FMUL (regTuOverZ0[unit], regTu0[unit], regInvZ0);
  633. FMUL (regTvOverZ0[unit], regTv0[unit], regInvZ0);
  634. }
  635. // -- end initialize
  636. // EGL_Fixed invSpan = EGL_Inverse(deltaX);
  637. // EGL_Fixed slope = EGL_Mul(EGL_Abs(deltaY), invSpan);
  638. // EGL_Fixed OneOverZTo = to.m_WindowCoords.invZ;
  639. DECL_REG (regInvSpan);
  640. DECL_REG (regSlope);
  641. FINV (regInvSpan, regCommonDeltaY);
  642. FMUL (regSlope, regAbsDeltaX, regInvSpan);
  643. cg_virtual_reg_t * regEndColorR0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_R);
  644. cg_virtual_reg_t * regEndColorG0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_G);
  645. cg_virtual_reg_t * regEndColorB0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_B);
  646. cg_virtual_reg_t * regEndColorA0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_COLOR_A);
  647. cg_virtual_reg_t * regEndFog0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_FOG);
  648. cg_virtual_reg_t * regEndDepth0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_WINDOW_DEPTH);
  649. cg_virtual_reg_t * regEndInvZ0 = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_WINDOW_INV_Z);
  650. cg_virtual_reg_t * regEndTu0[EGL_NUM_TEXTURE_UNITS];
  651. cg_virtual_reg_t * regEndTv0[EGL_NUM_TEXTURE_UNITS];
  652. cg_virtual_reg_t * regEndTuOverZ0[EGL_NUM_TEXTURE_UNITS];
  653. cg_virtual_reg_t * regEndTvOverZ0[EGL_NUM_TEXTURE_UNITS];
  654. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  655. regEndTu0[unit] = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_TEX_TU + unit * sizeof(TexCoord));
  656. regEndTv0[unit] = LOAD_DATA(block, regCommonTo, OFFSET_RASTER_POS_TEX_TV + unit * sizeof(TexCoord));
  657. ALLOC_REG (regEndTuOverZ0[unit]);
  658. ALLOC_REG (regEndTvOverZ0[unit]);
  659. FMUL (regEndTuOverZ0[unit], regEndTu0[unit], regEndInvZ0);
  660. FMUL (regEndTvOverZ0[unit], regEndTv0[unit], regEndInvZ0);
  661. }
  662. // -- increments(to, from, invSpan)
  663. // FractionalColor colorIncrement = (to.m_Color - from.m_Color) * invSpan;
  664. // EGL_Fixed deltaFog = EGL_Mul(to.m_FogDensity - from.m_FogDensity, invSpan);
  665. // EGL_Fixed deltaZ = EGL_Mul(OneOverZTo - OneOverZ, invSpan);
  666. // EGL_Fixed deltaU = EGL_Mul(EGL_Mul(to.m_TextureCoords.tu, OneOverZTo) -
  667. // EGL_Mul(from.m_TextureCoords.tu, OneOverZ), invSpan);
  668. // EGL_Fixed deltaV = EGL_Mul(EGL_Mul(to.m_TextureCoords.tv, OneOverZTo) -
  669. // EGL_Mul(from.m_TextureCoords.tv, OneOverZ), invSpan);
  670. // EGL_Fixed deltaDepth = EGL_Mul(to.m_WindowCoords.depth - from.m_WindowCoords.depth, invSpan);
  671. DECL_REG (regDiffColorR);
  672. DECL_REG (regDeltaColorR);
  673. DECL_REG (regDiffColorG);
  674. DECL_REG (regDeltaColorG);
  675. DECL_REG (regDiffColorB);
  676. DECL_REG (regDeltaColorB);
  677. DECL_REG (regDiffColorA);
  678. DECL_REG (regDeltaColorA);
  679. DECL_REG (regDiffFog);
  680. DECL_REG (regDeltaFog);
  681. DECL_REG (regDiffDepth);
  682. DECL_REG (regDeltaDepth);
  683. FSUB (regDiffColorR, regEndColorR0, regColorR0);
  684. FMUL (regDeltaColorR, regDiffColorR, regInvSpan);
  685. FSUB (regDiffColorG, regEndColorG0, regColorG0);
  686. FMUL (regDeltaColorG, regDiffColorG, regInvSpan);
  687. FSUB (regDiffColorB, regEndColorB0, regColorB0);
  688. FMUL (regDeltaColorB, regDiffColorB, regInvSpan);
  689. FSUB (regDiffColorA, regEndColorA0, regColorA0);
  690. FMUL (regDeltaColorA, regDiffColorA, regInvSpan);
  691. FSUB (regDiffFog, regEndFog0, regFog0);
  692. FMUL (regDeltaFog, regDiffFog, regInvSpan);
  693. FSUB (regDiffDepth, regEndDepth0, regDepth0);
  694. FMUL (regDeltaDepth, regDiffDepth, regInvSpan);
  695. DECL_REG (regDiffInvZ);
  696. DECL_REG (regDeltaInvZ);
  697. FSUB (regDiffInvZ, regEndInvZ0, regInvZ0);
  698. FMUL (regDeltaInvZ, regDiffInvZ, regInvSpan);
  699. cg_virtual_reg_t * regDiffTuOverZ[EGL_NUM_TEXTURE_UNITS];
  700. cg_virtual_reg_t * regDeltaTuOverZ[EGL_NUM_TEXTURE_UNITS];
  701. cg_virtual_reg_t * regDiffTvOverZ[EGL_NUM_TEXTURE_UNITS];
  702. cg_virtual_reg_t * regDeltaTvOverZ[EGL_NUM_TEXTURE_UNITS];
  703. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  704. ALLOC_REG (regDiffTuOverZ[unit]);
  705. ALLOC_REG (regDeltaTuOverZ[unit]);
  706. ALLOC_REG (regDiffTvOverZ[unit]);
  707. ALLOC_REG (regDeltaTvOverZ[unit]);
  708. FSUB (regDiffTuOverZ[unit], regEndTuOverZ0[unit], regTuOverZ0[unit]);
  709. FMUL (regDeltaTuOverZ[unit], regDiffTuOverZ[unit], regInvSpan);
  710. FSUB (regDiffTvOverZ[unit], regEndTvOverZ0[unit], regTvOverZ0[unit]);
  711. FMUL (regDeltaTvOverZ[unit], regDiffTvOverZ[unit], regInvSpan);
  712. }
  713. // -- end increments
  714. // I32 y = EGL_IntFromFixed(from.m_WindowCoords.y + ((EGL_ONE)/2-1));
  715. cg_virtual_reg_t * regFromX0 = LOAD_DATA(block, regCommonFrom, OFFSET_RASTER_POS_WINDOW_X);
  716. DECL_CONST_REG (regHalf2, 0x7fff);
  717. DECL_REG (regFromX0PlusHalf);
  718. DECL_REG (regX0);
  719. FADD (regFromX0PlusHalf, regFromX0, regHalf2);
  720. TRUNC (regX0, regFromX0PlusHalf);
  721. // EGL_Fixed error = 0;
  722. DECL_CONST_REG (regError0, 0);
  723. block = cg_block_create(procedure, 4);
  724. cg_block_ref_t * blockRefBeginLoop = cg_block_ref_create(procedure);
  725. blockRefBeginLoop->block = block;
  726. // for (; x < endX; ++x) {
  727. // --- variables for loop entry
  728. DECL_REG (regLoopX);
  729. DECL_REG (regLoopY);
  730. DECL_REG (regLoopError);
  731. DECL_REG (regLoopOneOverZ);
  732. DECL_REG (regLoopColorR);
  733. DECL_REG (regLoopColorG);
  734. DECL_REG (regLoopColorB);
  735. DECL_REG (regLoopColorA);
  736. DECL_REG (regLoopDepth);
  737. DECL_REG (regLoopFog);
  738. // --- variables for loop exit
  739. DECL_REG (regEndLoopX);
  740. DECL_REG (regEndLoopY);
  741. DECL_REG (regEndLoopError);
  742. DECL_REG (regEndLoopOneOverZ);
  743. DECL_REG (regEndLoopColorR);
  744. DECL_REG (regEndLoopColorG);
  745. DECL_REG (regEndLoopColorB);
  746. DECL_REG (regEndLoopColorA);
  747. DECL_REG (regEndLoopDepth);
  748. DECL_REG (regEndLoopFog);
  749. PHI (regLoopX, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopX, regX0, NULL));
  750. PHI (regLoopY, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopY, regCommonY, NULL));
  751. PHI (regLoopError, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopError, regError0, NULL));
  752. PHI (regLoopOneOverZ, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopOneOverZ, regInvZ0, NULL));
  753. PHI (regLoopColorR, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorR, regColorR0, NULL));
  754. PHI (regLoopColorG, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorG, regColorG0, NULL));
  755. PHI (regLoopColorB, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorB, regColorB0, NULL));
  756. PHI (regLoopColorA, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopColorA, regColorA0, NULL));
  757. PHI (regLoopDepth, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopDepth, regDepth0, NULL));
  758. PHI (regLoopFog, cg_create_virtual_reg_list(procedure->module->heap, regEndLoopFog, regFog0, NULL));
  759. cg_virtual_reg_t * regLoopTuOverZ[EGL_NUM_TEXTURE_UNITS];
  760. cg_virtual_reg_t * regLoopTvOverZ[EGL_NUM_TEXTURE_UNITS];
  761. cg_virtual_reg_t * regEndLoopTuOverZ[EGL_NUM_TEXTURE_UNITS];
  762. cg_virtual_reg_t * regEndLoopTvOverZ[EGL_NUM_TEXTURE_UNITS];
  763. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  764. ALLOC_REG (regLoopTuOverZ[unit]);
  765. ALLOC_REG (regLoopTvOverZ[unit]);
  766. ALLOC_REG (regEndLoopTuOverZ[unit]);
  767. ALLOC_REG (regEndLoopTvOverZ[unit]);
  768. PHI (regLoopTuOverZ[unit], cg_create_virtual_reg_list(procedure->module->heap, regEndLoopTuOverZ[unit], regTuOverZ0[unit], NULL));
  769. PHI (regLoopTvOverZ[unit], cg_create_virtual_reg_list(procedure->module->heap, regEndLoopTvOverZ[unit], regTvOverZ0[unit], NULL));
  770. }
  771. // EGL_Fixed z = EGL_Inverse(OneOverZ);
  772. // OneOverZ += deltaZ;
  773. DECL_REG (regLoopZ);
  774. FINV (regLoopZ, regLoopOneOverZ);
  775. FADD (regEndLoopOneOverZ, regLoopOneOverZ, regDeltaInvZ);
  776. cg_virtual_reg_t * regLoopTu[EGL_NUM_TEXTURE_UNITS];
  777. cg_virtual_reg_t * regLoopTv[EGL_NUM_TEXTURE_UNITS];
  778. for (unit = 0; unit < EGL_NUM_TEXTURE_UNITS; ++unit) {
  779. ALLOC_REG (regLoopTu[unit]);
  780. ALLOC_REG (regLoopTv[unit]);
  781. // EGL_Fixed tu = EGL_Mul(tuOverZ, z);
  782. // EGL_Fixed tv = EGL_Mul(tvOverZ, z);
  783. // tuOverZ += deltaU;
  784. // tvOverZ += deltaV;
  785. FMUL (regLoopTu[unit], regLoopTuOverZ[unit], regLoopZ);
  786. FADD (regEndLoopTuOverZ[unit], regLoopTuOverZ[unit], regDeltaTuOverZ[unit]);
  787. FMUL (regLoopTv[unit], regLoopTvOverZ[unit], regLoopZ);
  788. FADD (regEndLoopTvOverZ[unit], regLoopTvOverZ[unit], regDeltaTvOverZ[unit]);
  789. info.regU[unit] = regLoopTu[unit];
  790. info.regV[unit] = regLoopTv[unit];
  791. }
  792. // Fragment(x, y, depth, tu, tv, fogDensity, baseColor);
  793. info.regX = regLoopX;
  794. info.regY = regLoopY;
  795. info.regFog = regLoopFog;
  796. info.regDepth = regLoopDepth;
  797. info.regR = regLoopColorR;
  798. info.regG = regLoopColorG;
  799. info.regB = regLoopColorB;
  800. info.regA = regLoopColorA;
  801. cg_block_ref_t * postFragment = cg_block_ref_create(procedure);
  802. GenerateFragment(procedure, block, postFragment, info, 5, true);
  803. block = cg_block_create(procedure, 5);
  804. postFragment->block = block;
  805. // error += slope;
  806. DECL_REG (regIncError);
  807. FADD (regIncError, regLoopError, regSlope);
  808. // if (error > EGL_ONE) {
  809. DECL_CONST_REG (regLoopOne, EGL_ONE);
  810. DECL_FLAGS (regErrorOverflow);
  811. FCMP (regErrorOverflow, regIncError, regLoopOne);
  812. cg_block_ref_t * noOverflow = cg_block_ref_create(procedure);
  813. BLE (regErrorOverflow, noOverflow);
  814. block = cg_block_create(procedure, 5);
  815. // y += yIncrement;
  816. // error -= EGL_ONE;
  817. DECL_REG (regIncX);
  818. DECL_REG (regCorrectedError);
  819. FADD (regIncX, regLoopX, regXIncrement);
  820. FSUB (regCorrectedError, regIncError, regLoopOne);
  821. // }
  822. block = cg_block_create(procedure, 5);
  823. noOverflow->block = block;
  824. PHI (regEndLoopX, cg_create_virtual_reg_list(procedure->module->heap, regLoopX, regIncX, NULL));
  825. PHI (regEndLoopError, cg_create_virtual_reg_list(procedure->module->heap, regIncError, regCorrectedError, NULL));
  826. // baseColor += colorIncrement;
  827. FADD (regEndLoopColorR, regLoopColorR, regDeltaColorR);
  828. FADD (regEndLoopColorG, regLoopColorG, regDeltaColorG);
  829. FADD (regEndLoopColorB, regLoopColorB, regDeltaColorB);
  830. FADD (regEndLoopColorA, regLoopColorA, regDeltaColorA);
  831. // depth += deltaDepth;
  832. // fogDensity += deltaFog;
  833. FADD (regEndLoopDepth, regLoopDepth, regDeltaDepth);
  834. FADD (regEndLoopFog, regLoopFog, regDeltaFog);
  835. DECL_CONST_REG (regConstInt1, 1);
  836. DECL_FLAGS (regCompareY);
  837. FADD (regEndLoopY, regLoopY, regConstInt1);
  838. FCMP (regCompareY, regEndLoopY, regCommonEndY);
  839. BLT (regCompareY, blockRefBeginLoop);
  840. // }
  841. }
  842. block = cg_block_create(procedure, 1);
  843. blockRefEndProc->block = block;
  844. RET();
  845. }