Advertisement
Guest User

Untitled

a guest
Aug 6th, 2017
106
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Pixel UberShader for 0 texgens
  2. int idot(int3 x, int3 y)
  3. {
  4. int3 tmp = x * y;
  5. return tmp.x + tmp.y + tmp.z;
  6. }
  7. int idot(int4 x, int4 y)
  8. {
  9. int4 tmp = x * y;
  10. return tmp.x + tmp.y + tmp.z + tmp.w;
  11. }
  12.  
  13. int iround(float x) { return int (round(x)); }
  14. int2 iround(float2 x) { return int2(round(x)); }
  15. int3 iround(float3 x) { return int3(round(x)); }
  16. int4 iround(float4 x) { return int4(round(x)); }
  17.  
  18. SamplerState samp[8] : register(s0);
  19.  
  20. Texture2DArray Tex[8] : register(t0);
  21.  
  22. cbuffer PSBlock : register(b0) {
  23. int4 color[4];
  24. int4 k[4];
  25. int4 alphaRef;
  26. float4 texdim[8];
  27. int4 czbias[2];
  28. int4 cindscale[2];
  29. int4 cindmtx[6];
  30. int4 cfogcolor;
  31. int4 cfogi;
  32. float4 cfogf[2];
  33. float4 czslope;
  34. float2 cefbscale;
  35. uint bpmem_genmode;
  36. uint bpmem_alphaTest;
  37. uint bpmem_fogParam3;
  38. uint bpmem_fogRangeBase;
  39. uint bpmem_dstalpha;
  40. uint bpmem_ztex_op;
  41. bool bpmem_late_ztest;
  42. bool bpmem_rgba6_format;
  43. bool bpmem_dither;
  44. bool bpmem_bounding_box;
  45. uint4 bpmem_pack1[16];
  46. uint4 bpmem_pack2[8];
  47. int4 konstLookup[32];
  48. };
  49.  
  50. #define bpmem_combiners(i) (bpmem_pack1[(i)].xy)
  51. #define bpmem_tevind(i) (bpmem_pack1[(i)].z)
  52. #define bpmem_iref(i) (bpmem_pack1[(i)].w)
  53. #define bpmem_tevorder(i) (bpmem_pack2[(i)].x)
  54. #define bpmem_tevksel(i) (bpmem_pack2[(i)].y)
  55.  
  56. struct VS_OUTPUT {
  57. float4 pos : POSITION;
  58. float4 colors_0 : COLOR0;
  59. float4 colors_1 : COLOR1;
  60. float4 clipPos : TEXCOORD0;
  61. float clipDist0 : SV_ClipDistance0;
  62. float clipDist1 : SV_ClipDistance1;
  63. };
  64. uint bitfieldExtract(uint val, int off, int size) {
  65. // This built-in function is only support in OpenGL 4.0+ and ES 3.1+
  66. // Microsoft's HLSL compiler automatically optimises this to a bitfield extract instruction.
  67. uint mask = uint((1 << size) - 1);
  68. return uint(val >> off) & mask;
  69. }
  70.  
  71. int4 sampleTexture(uint sampler_num, float2 uv) {
  72. // This is messy, but DirectX, OpenGl 3.3 and Opengl ES 3.0 doesn't support dynamic indexing of the sampler array
  73. // With any luck the shader compiler will optimise this if the hardware supports dynamic indexing.
  74. switch(sampler_num) {
  75. case 0u: return iround(Tex[0].Sample(samp[0], float3(uv, 0.0)) * 255.0);
  76. case 1u: return iround(Tex[1].Sample(samp[1], float3(uv, 0.0)) * 255.0);
  77. case 2u: return iround(Tex[2].Sample(samp[2], float3(uv, 0.0)) * 255.0);
  78. case 3u: return iround(Tex[3].Sample(samp[3], float3(uv, 0.0)) * 255.0);
  79. case 4u: return iround(Tex[4].Sample(samp[4], float3(uv, 0.0)) * 255.0);
  80. case 5u: return iround(Tex[5].Sample(samp[5], float3(uv, 0.0)) * 255.0);
  81. case 6u: return iround(Tex[6].Sample(samp[6], float3(uv, 0.0)) * 255.0);
  82. case 7u: return iround(Tex[7].Sample(samp[7], float3(uv, 0.0)) * 255.0);
  83. }
  84. }
  85.  
  86. int4 Swizzle(uint s, int4 color) {
  87. // AKA: Color Channel Swapping
  88.  
  89. int4 ret;
  90. ret.r = color[bitfieldExtract(bpmem_tevksel(s * 2u), 0, 2)];
  91. ret.g = color[bitfieldExtract(bpmem_tevksel(s * 2u), 2, 2)];
  92. ret.b = color[bitfieldExtract(bpmem_tevksel(s * 2u + 1u), 0, 2)];
  93. ret.a = color[bitfieldExtract(bpmem_tevksel(s * 2u + 1u), 2, 2)];
  94. return ret;
  95. }
  96.  
  97. int Wrap(int coord, uint mode) {
  98. if (mode == 0u) // ITW_OFF
  99. return coord;
  100. else if (mode < 6u) // ITW_256 to ITW_16
  101. return coord & (0xfffe >> mode);
  102. else // ITW_0
  103. return 0;
  104. }
  105.  
  106. // TEV's Linear Interpolate, plus bias, add/subtract and scale
  107. int tevLerp(int A, int B, int C, int D, uint bias, bool op, bool alpha, uint shift) {
  108. // Scale C from 0..255 to 0..256
  109. C += C >> 7;
  110.  
  111. // Add bias to D
  112. if (bias == 1u) D += 128;
  113. else if (bias == 2u) D -= 128;
  114.  
  115. int lerp = (A << 8) + (B - A)*C;
  116. if (shift != 3u) {
  117. lerp = lerp << shift;
  118. D = D << shift;
  119. }
  120.  
  121. if ((shift == 3u) == alpha)
  122. lerp = lerp + (op ? 127 : 128);
  123.  
  124. int result = lerp >> 8;
  125.  
  126. // Add/Subtract D
  127. if(op) // Subtract
  128. result = D - result;
  129. else // Add
  130. result = D + result;
  131.  
  132. // Most of the Shift was moved inside the lerp for improved percision
  133. // But we still do the divide by 2 here
  134. if (shift == 3u)
  135. result = result >> 1;
  136. return result;
  137. }
  138.  
  139. // TEV's Linear Interpolate, plus bias, add/subtract and scale
  140. int3 tevLerp3(int3 A, int3 B, int3 C, int3 D, uint bias, bool op, bool alpha, uint shift) {
  141. // Scale C from 0..255 to 0..256
  142. C += C >> 7;
  143.  
  144. // Add bias to D
  145. if (bias == 1u) D += 128;
  146. else if (bias == 2u) D -= 128;
  147.  
  148. int3 lerp = (A << 8) + (B - A)*C;
  149. if (shift != 3u) {
  150. lerp = lerp << shift;
  151. D = D << shift;
  152. }
  153.  
  154. if ((shift == 3u) == alpha)
  155. lerp = lerp + (op ? 127 : 128);
  156.  
  157. int3 result = lerp >> 8;
  158.  
  159. // Add/Subtract D
  160. if(op) // Subtract
  161. result = D - result;
  162. else // Add
  163. result = D + result;
  164.  
  165. // Most of the Shift was moved inside the lerp for improved percision
  166. // But we still do the divide by 2 here
  167. if (shift == 3u)
  168. result = result >> 1;
  169. return result;
  170. }
  171.  
  172. // Implements operations 0-5 of tev's compare mode,
  173. // which are common to both color and alpha channels
  174. bool tevCompare(uint op, int3 color_A, int3 color_B) {
  175. switch (op) {
  176. case 0u: // TEVCMP_R8_GT
  177. return (color_A.r > color_B.r);
  178. case 1u: // TEVCMP_R8_EQ
  179. return (color_A.r == color_B.r);
  180. case 2u: // TEVCMP_GR16_GT
  181. int A_16 = (color_A.r | (color_A.g << 8));
  182. int B_16 = (color_B.r | (color_B.g << 8));
  183. return A_16 > B_16;
  184. case 3u: // TEVCMP_GR16_EQ
  185. return (color_A.r == color_B.r && color_A.g == color_B.g);
  186. case 4u: // TEVCMP_BGR24_GT
  187. int A_24 = (color_A.r | (color_A.g << 8) | (color_A.b << 16));
  188. int B_24 = (color_B.r | (color_B.g << 8) | (color_B.b << 16));
  189. return A_24 > B_24;
  190. case 5u: // TEVCMP_BGR24_EQ
  191. return (color_A.r == color_B.r && color_A.g == color_B.g && color_A.b == color_B.b);
  192. default:
  193. return false;
  194. }
  195. }
  196.  
  197. // Helper function for Alpha Test
  198. bool alphaCompare(int a, int b, uint compare) {
  199. switch (compare) {
  200. case 0u: // NEVER
  201. return false;
  202. case 1u: // LESS
  203. return a < b;
  204. case 2u: // EQUAL
  205. return a == b;
  206. case 3u: // LEQUAL
  207. return a <= b;
  208. case 4u: // GREATER
  209. return a > b;
  210. case 5u: // NEQUAL;
  211. return a != b;
  212. case 6u: // GEQUAL
  213. return a >= b;
  214. case 7u: // ALWAYS
  215. return true;
  216. }
  217. }
  218.  
  219. struct State {
  220. int4 Reg[4];
  221. int4 TexColor;
  222. int AlphaBump;
  223. };
  224. struct StageState {
  225. uint stage;
  226. uint order;
  227. uint cc;
  228. uint ac;
  229. };
  230.  
  231. int4 getRasColor(State s, StageState ss, float4 colors_0, float4 colors_1);
  232. int4 getKonstColor(State s, StageState ss);
  233.  
  234. int3 selectColorInput(State s, StageState ss, float4 colors_0, float4 colors_1, uint index) {
  235. switch (index) {
  236. case 0u: // prev.rgb
  237. return s.Reg[0].rgb;
  238. case 1u: // prev.aaa
  239. return s.Reg[0].aaa;
  240. case 2u: // c0.rgb
  241. return s.Reg[1].rgb;
  242. case 3u: // c0.aaa
  243. return s.Reg[1].aaa;
  244. case 4u: // c1.rgb
  245. return s.Reg[2].rgb;
  246. case 5u: // c1.aaa
  247. return s.Reg[2].aaa;
  248. case 6u: // c2.rgb
  249. return s.Reg[3].rgb;
  250. case 7u: // c2.aaa
  251. return s.Reg[3].aaa;
  252. case 8u:
  253. return s.TexColor.rgb;
  254. case 9u:
  255. return s.TexColor.aaa;
  256. case 10u:
  257. return getRasColor(s, ss, colors_0, colors_1).rgb;
  258. case 11u:
  259. return getRasColor(s, ss, colors_0, colors_1).aaa;
  260. case 12u: // One
  261. return int3(255, 255, 255);
  262. case 13u: // Half
  263. return int3(128, 128, 128);
  264. case 14u:
  265. return getKonstColor(s, ss).rgb;
  266. case 15u: // Zero
  267. return int3(0, 0, 0);
  268. }
  269. }
  270.  
  271. int selectAlphaInput(State s, StageState ss, float4 colors_0, float4 colors_1, uint index) {
  272. switch (index) {
  273. case 0u: // prev.a
  274. return s.Reg[0].a;
  275. case 1u: // c0.a
  276. return s.Reg[1].a;
  277. case 2u: // c1.a
  278. return s.Reg[2].a;
  279. case 3u: // c2.a
  280. return s.Reg[3].a;
  281. case 4u:
  282. return s.TexColor.a;
  283. case 5u:
  284. return getRasColor(s, ss, colors_0, colors_1).a;
  285. case 6u:
  286. return getKonstColor(s, ss).a;
  287. case 7u: // Zero
  288. return 0;
  289. }
  290. }
  291.  
  292. int4 getTevReg(in State s, uint index) {
  293. switch (index) {
  294. case 0u: // prev
  295. return s.Reg[0];
  296. case 1u: // c0
  297. return s.Reg[1];
  298. case 2u: // c1
  299. return s.Reg[2];
  300. case 3u: // c2
  301. return s.Reg[3];
  302. default: // prev
  303. return s.Reg[0];
  304. }
  305. }
  306.  
  307. void setRegColor(inout State s, uint index, int3 color) {
  308. switch (index) {
  309. case 0u: // prev
  310. s.Reg[0].rgb = color;
  311. break;
  312. case 1u: // c0
  313. s.Reg[1].rgb = color;
  314. break;
  315. case 2u: // c1
  316. s.Reg[2].rgb = color;
  317. break;
  318. case 3u: // c2
  319. s.Reg[3].rgb = color;
  320. break;
  321. }
  322. }
  323.  
  324. void setRegAlpha(inout State s, uint index, int alpha) {
  325. switch (index) {
  326. case 0u: // prev
  327. s.Reg[0].a = alpha;
  328. break;
  329. case 1u: // c0
  330. s.Reg[1].a = alpha;
  331. break;
  332. case 2u: // c1
  333. s.Reg[2].a = alpha;
  334. break;
  335. case 3u: // c2
  336. s.Reg[3].a = alpha;
  337. break;
  338. }
  339. }
  340.  
  341. void main(
  342. out float4 ocol0 : SV_Target0,
  343. out float4 ocol1 : SV_Target1,
  344.  
  345. in float4 rawpos : SV_Position,
  346. in float4 colors_0 : COLOR0,
  347. in float4 colors_1 : COLOR1
  348. ,
  349. in float4 clipPos : TEXCOORD0,
  350. in float clipDist0 : SV_ClipDistance0
  351. ,
  352. in float clipDist1 : SV_ClipDistance1
  353.  
  354. ) {
  355. int3 tevcoord = int3(0, 0, 0);
  356. State s;
  357. s.TexColor = int4(0, 0, 0, 0);
  358. s.AlphaBump = 0;
  359.  
  360. s.Reg[0] = color[0];
  361. s.Reg[1] = color[1];
  362. s.Reg[2] = color[2];
  363. s.Reg[3] = color[3];
  364. uint num_stages = bitfieldExtract(bpmem_genmode, 10, 4);
  365.  
  366. // Main tev loop
  367. [loop]
  368. for(uint stage = 0u; stage <= num_stages; stage++)
  369. {
  370. StageState ss;
  371. ss.stage = stage;
  372. ss.cc = bpmem_combiners(stage).x;
  373. ss.ac = bpmem_combiners(stage).y;
  374. ss.order = bpmem_tevorder(stage>>1);
  375. if ((stage & 1u) == 1u)
  376. ss.order = ss.order >> 12;
  377.  
  378. // This is the Meat of TEV
  379. {
  380. // Color Combiner
  381. uint color_a = bitfieldExtract(ss.cc, 12, 4);
  382. uint color_b = bitfieldExtract(ss.cc, 8, 4);
  383. uint color_c = bitfieldExtract(ss.cc, 4, 4);
  384. uint color_d = bitfieldExtract(ss.cc, 0, 4);
  385. uint color_bias = bitfieldExtract(ss.cc, 16, 2);
  386. bool color_op = bool(bitfieldExtract(ss.cc, 18, 1));
  387. bool color_clamp = bool(bitfieldExtract(ss.cc, 19, 1));
  388. uint color_shift = bitfieldExtract(ss.cc, 20, 2);
  389. uint color_dest = bitfieldExtract(ss.cc, 22, 2);
  390. uint color_compare_op = color_shift << 1 | uint(color_op);
  391.  
  392. int3 color_A = selectColorInput(s, ss, colors_0, colors_1, color_a) & int3(255, 255, 255);
  393. int3 color_B = selectColorInput(s, ss, colors_0, colors_1, color_b) & int3(255, 255, 255);
  394. int3 color_C = selectColorInput(s, ss, colors_0, colors_1, color_c) & int3(255, 255, 255);
  395. int3 color_D = selectColorInput(s, ss, colors_0, colors_1, color_d); // 10 bits + sign
  396.  
  397. int3 color;
  398. if(color_bias != 3u) { // Normal mode
  399. color = tevLerp3(color_A, color_B, color_C, color_D, color_bias, color_op, false, color_shift);
  400. } else { // Compare mode
  401. // op 6 and 7 do a select per color channel
  402. if (color_compare_op == 6u) {
  403. // TEVCMP_RGB8_GT
  404. color.r = (color_A.r > color_B.r) ? color_C.r : 0;
  405. color.g = (color_A.g > color_B.g) ? color_C.g : 0;
  406. color.b = (color_A.b > color_B.b) ? color_C.b : 0;
  407. } else if (color_compare_op == 7u) {
  408. // TEVCMP_RGB8_EQ
  409. color.r = (color_A.r == color_B.r) ? color_C.r : 0;
  410. color.g = (color_A.g == color_B.g) ? color_C.g : 0;
  411. color.b = (color_A.b == color_B.b) ? color_C.b : 0;
  412. } else {
  413. // The remaining ops do one compare which selects all 3 channels
  414. color = tevCompare(color_compare_op, color_A, color_B) ? color_C : int3(0, 0, 0);
  415. }
  416. color = color_D + color;
  417. }
  418.  
  419. // Clamp result
  420. if (color_clamp)
  421. color = clamp(color, 0, 255);
  422. else
  423. color = clamp(color, -1024, 1023);
  424.  
  425. // Write result to the correct input register of the next stage
  426. setRegColor(s, color_dest, color);
  427.  
  428. // Alpha Combiner
  429. uint alpha_a = bitfieldExtract(ss.ac, 13, 3);
  430. uint alpha_b = bitfieldExtract(ss.ac, 10, 3);
  431. uint alpha_c = bitfieldExtract(ss.ac, 7, 3);
  432. uint alpha_d = bitfieldExtract(ss.ac, 4, 3);
  433. uint alpha_bias = bitfieldExtract(ss.ac, 16, 2);
  434. bool alpha_op = bool(bitfieldExtract(ss.ac, 18, 1));
  435. bool alpha_clamp = bool(bitfieldExtract(ss.ac, 19, 1));
  436. uint alpha_shift = bitfieldExtract(ss.ac, 20, 2);
  437. uint alpha_dest = bitfieldExtract(ss.ac, 22, 2);
  438. uint alpha_compare_op = alpha_shift << 1 | uint(alpha_op);
  439.  
  440. int alpha_A;
  441. int alpha_B;
  442. if (alpha_bias != 3u || alpha_compare_op > 5u) {
  443. // Small optimisation here: alpha_A and alpha_B are unused by compare ops 0-5
  444. alpha_A = selectAlphaInput(s, ss, colors_0, colors_1, alpha_a) & 255;
  445. alpha_B = selectAlphaInput(s, ss, colors_0, colors_1, alpha_b) & 255;
  446. };
  447. int alpha_C = selectAlphaInput(s, ss, colors_0, colors_1, alpha_c) & 255;
  448. int alpha_D = selectAlphaInput(s, ss, colors_0, colors_1, alpha_d); // 10 bits + sign
  449.  
  450.  
  451. int alpha;
  452. if(alpha_bias != 3u) { // Normal mode
  453. alpha = tevLerp(alpha_A, alpha_B, alpha_C, alpha_D, alpha_bias, alpha_op, true, alpha_shift);
  454. } else { // Compare mode
  455. if (alpha_compare_op == 6u) {
  456. // TEVCMP_A8_GT
  457. alpha = (alpha_A > alpha_B) ? alpha_C : 0;
  458. } else if (alpha_compare_op == 7u) {
  459. // TEVCMP_A8_EQ
  460. alpha = (alpha_A == alpha_B) ? alpha_C : 0;
  461. } else {
  462. // All remaining alpha compare ops actually compare the color channels
  463. alpha = tevCompare(alpha_compare_op, color_A, color_B) ? alpha_C : 0;
  464. }
  465. alpha = alpha_D + alpha;
  466. }
  467.  
  468. // Clamp result
  469. if (alpha_clamp)
  470. alpha = clamp(alpha, 0, 255);
  471. else
  472. alpha = clamp(alpha, -1024, 1023);
  473.  
  474. // Write result to the correct input register of the next stage
  475. setRegAlpha(s, alpha_dest, alpha);
  476. }
  477. } // Main tev loop
  478.  
  479. int4 TevResult;
  480. TevResult.xyz = getTevReg(s, bitfieldExtract(bpmem_combiners(num_stages).x, 22, 2)).xyz;
  481. TevResult.w = getTevReg(s, bitfieldExtract(bpmem_combiners(num_stages).y, 22, 2)).w;
  482. TevResult &= 255;
  483.  
  484. int zCoord = int((1.0 - rawpos.z) * 16777216.0);
  485. zCoord = clamp(zCoord, 0, 0xFFFFFF);
  486.  
  487. // Depth Texture
  488. int early_zCoord = zCoord;
  489. if (bpmem_ztex_op != 0u) {
  490. int ztex = int(czbias[1].w); // fixed bias
  491.  
  492. // Whatever texture was in our last stage, it's now our depth texture
  493. ztex += idot(s.TexColor.xyzw, czbias[0].xyzw);
  494. ztex += (bpmem_ztex_op == 1u) ? zCoord : 0;
  495. zCoord = ztex & 0xFFFFFF;
  496. }
  497.  
  498. // Alpha Test
  499. if (bpmem_alphaTest != 0u) {
  500. bool comp0 = alphaCompare(TevResult.a, alphaRef.r, bitfieldExtract(bpmem_alphaTest, 16, 3));
  501. bool comp1 = alphaCompare(TevResult.a, alphaRef.g, bitfieldExtract(bpmem_alphaTest, 19, 3));
  502.  
  503. // These if statements are written weirdly to work around intel and qualcom bugs with handling booleans.
  504. switch (bitfieldExtract(bpmem_alphaTest, 22, 2)) {
  505. case 0u: // AND
  506. if (comp0 && comp1) break; else discard; break;
  507. case 1u: // OR
  508. if (comp0 || comp1) break; else discard; break;
  509. case 2u: // XOR
  510. if (comp0 != comp1) break; else discard; break;
  511. case 3u: // XNOR
  512. if (comp0 == comp1) break; else discard; break;
  513. }
  514. }
  515.  
  516. if (bpmem_dither) {
  517. // Flipper uses a standard 2x2 Bayer Matrix for 6 bit dithering
  518. // Here the matrix is encoded into the two factor constants
  519. int2 dither = int2(rawpos.xy) & 1;
  520. TevResult.rgb = (TevResult.rgb - (TevResult.rgb >> 6)) + abs(dither.y * 3 - dither.x * 2);
  521. }
  522.  
  523. // Fog
  524. uint fog_function = bitfieldExtract(bpmem_fogParam3, 21, 3);
  525. if (fog_function != 0u) {
  526. // TODO: This all needs to be converted from float to fixed point
  527. float ze;
  528. if (bitfieldExtract(bpmem_fogParam3, 20, 1) == 0u) {
  529. // perspective
  530. // ze = A/(B - (Zs >> B_SHF)
  531. ze = (cfogf[1].x * 16777216.0) / float(cfogi.y - (zCoord >> cfogi.w));
  532. } else {
  533. // orthographic
  534. // ze = a*Zs (here, no B_SHF)
  535. ze = cfogf[1].x * float(zCoord) / 16777216.0;
  536. }
  537.  
  538. if (bool(bitfieldExtract(bpmem_fogRangeBase, 10, 1))) {
  539. // x_adjust = sqrt((x-center)^2 + k^2)/k
  540. // ze *= x_adjust
  541. // TODO Instead of this theoretical calculation, we should use the
  542. // coefficient table given in the fog range BP registers!
  543. float x_adjust = (2.0 * (rawpos.x / cfogf[0].y)) - 1.0 - cfogf[0].x;
  544. x_adjust = sqrt(x_adjust * x_adjust + cfogf[0].z * cfogf[0].z) / cfogf[0].z;
  545. ze *= x_adjust;
  546. }
  547.  
  548. float fog = clamp(ze - cfogf[1].z, 0.0, 1.0);
  549.  
  550. if (fog_function > 3u) {
  551. switch (fog_function) {
  552. case 4u:
  553. fog = 1.0 - exp2(-8.0 * fog);
  554. break;
  555. case 5u:
  556. fog = 1.0 - exp2(-8.0 * fog * fog);
  557. break;
  558. case 6u:
  559. fog = exp2(-8.0 * (1.0 - fog));
  560. break;
  561. case 7u:
  562. fog = 1.0 - fog;
  563. fog = exp2(-8.0 * fog * fog);
  564. break;
  565. }
  566. }
  567.  
  568. int ifog = iround(fog * 256.0);
  569. TevResult.rgb = (TevResult.rgb * (256 - ifog) + cfogcolor.rgb * ifog) >> 8;
  570. }
  571.  
  572. if (bpmem_rgba6_format)
  573. ocol0.rgb = float3(TevResult.rgb >> 2) / 63.0;
  574. else
  575. ocol0.rgb = float3(TevResult.rgb) / 255.0;
  576.  
  577. if (bpmem_dstalpha != 0u)
  578. ocol0.a = float(bitfieldExtract(bpmem_dstalpha, 0, 8) >> 2) / 63.0;
  579. else
  580. ocol0.a = float(TevResult.a >> 2) / 63.0;
  581.  
  582. // Dest alpha override (dual source blending)
  583. // Colors will be blended against the alpha from ocol1 and
  584. // the alpha from ocol0 will be written to the framebuffer.
  585. ocol1 = float4(0.0, 0.0, 0.0, float(TevResult.a) / 255.0);
  586. }
  587.  
  588. int4 getRasColor(State s, StageState ss, float4 colors_0, float4 colors_1) {
  589. // Select Ras for stage
  590. uint ras = bitfieldExtract(ss.order, 7, 3);
  591. if (ras < 2u) { // Lighting Channel 0 or 1
  592. int4 color = iround(((ras == 0u) ? colors_0 : colors_1) * 255.0);
  593. uint swap = bitfieldExtract(ss.ac, 0, 2);
  594. return Swizzle(swap, color);
  595. } else if (ras == 5u) { // Alpha Bumb
  596. return int4(s.AlphaBump, s.AlphaBump, s.AlphaBump, s.AlphaBump);
  597. } else if (ras == 6u) { // Normalzied Alpha Bump
  598. int normalized = s.AlphaBump | s.AlphaBump >> 5;
  599. return int4(normalized, normalized, normalized, normalized);
  600. } else {
  601. return int4(0, 0, 0, 0);
  602. }
  603. }
  604.  
  605. int4 getKonstColor(State s, StageState ss) {
  606. // Select Konst for stage
  607. // TODO: a switch case might be better here than an dynamically // indexed uniform lookup
  608. uint tevksel = bpmem_tevksel(ss.stage>>1);
  609. if ((ss.stage & 1u) == 0u)
  610. return int4(konstLookup[bitfieldExtract(tevksel, 4, 5)].rgb, konstLookup[bitfieldExtract(tevksel, 9, 5)].a);
  611. else
  612. return int4(konstLookup[bitfieldExtract(tevksel, 14, 5)].rgb, konstLookup[bitfieldExtract(tevksel, 19, 5)].a);
  613. }
Advertisement
RAW Paste Data Copied
Advertisement