x86.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:22k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include "GSTables.h"
  23. #include "x86.h"
  24. // unswizzling
  25. void __fastcall unSwizzleBlock32_c(BYTE* src, BYTE* dst, int dstpitch)
  26. {
  27. DWORD* s = &columnTable32[0][0];
  28. for(int j = 0; j < 8; j++, s += 8, dst += dstpitch)
  29. for(int i = 0; i < 8; i++)
  30. ((DWORD*)dst)[i] = ((DWORD*)src)[s[i]];
  31. }
  32. void __fastcall unSwizzleBlock16_c(BYTE* src, BYTE* dst, int dstpitch)
  33. {
  34. DWORD* s = &columnTable16[0][0];
  35. for(int j = 0; j < 8; j++, s += 16, dst += dstpitch)
  36. for(int i = 0; i < 16; i++)
  37. ((WORD*)dst)[i] = ((WORD*)src)[s[i]];
  38. }
  39. void __fastcall unSwizzleBlock8_c(BYTE* src, BYTE* dst, int dstpitch)
  40. {
  41. DWORD* s = &columnTable8[0][0];
  42. for(int j = 0; j < 16; j++, s += 16, dst += dstpitch)
  43. for(int i = 0; i < 16; i++)
  44. dst[i] = src[s[i]];
  45. }
  46. void __fastcall unSwizzleBlock4_c(BYTE* src, BYTE* dst, int dstpitch)
  47. {
  48. DWORD* s = &columnTable4[0][0];
  49. for(int j = 0; j < 16; j++, s += 32, dst += dstpitch)
  50. {
  51. for(int i = 0; i < 32; i++)
  52. {
  53. DWORD addr = s[i];
  54. BYTE c = (src[addr>>1] >> ((addr&1) << 2)) & 0x0f;
  55. int shift = (i&1) << 2;
  56. dst[i >> 1] = (dst[i >> 1] & (0xf0 >> shift)) | (c << shift);
  57. }
  58. }
  59. }
  60. void __fastcall unSwizzleBlock8HP_c(BYTE* src, BYTE* dst, int dstpitch)
  61. {
  62. DWORD* s = &columnTable32[0][0];
  63. for(int j = 0; j < 8; j++, s += 8, dst += dstpitch)
  64. for(int i = 0; i < 8; i++)
  65. dst[i] = (BYTE)(((DWORD*)src)[s[i]]>>24);
  66. }
  67. void __fastcall unSwizzleBlock4HLP_c(BYTE* src, BYTE* dst, int dstpitch)
  68. {
  69. DWORD* s = &columnTable32[0][0];
  70. for(int j = 0; j < 8; j++, s += 8, dst += dstpitch)
  71. for(int i = 0; i < 8; i++)
  72. dst[i] = (BYTE)(((DWORD*)src)[s[i]]>>24)&0xf;
  73. }
  74. void __fastcall unSwizzleBlock4HHP_c(BYTE* src, BYTE* dst, int dstpitch)
  75. {
  76. DWORD* s = &columnTable32[0][0];
  77. for(int j = 0; j < 8; j++, s += 8, dst += dstpitch)
  78. for(int i = 0; i < 8; i++)
  79. dst[i] = (BYTE)(((DWORD*)src)[s[i]]>>28);
  80. }
  81. void __fastcall unSwizzleBlock4P_c(BYTE* src, BYTE* dst, int dstpitch)
  82. {
  83. DWORD* s = &columnTable4[0][0];
  84. for(int j = 0; j < 16; j++, s += 32, dst += dstpitch)
  85. {
  86. for(int i = 0; i < 32; i++)
  87. {
  88. DWORD addr = s[i];
  89. dst[i] = (src[addr>>1] >> ((addr&1) << 2)) & 0x0f;
  90. }
  91. }
  92. }
  93. // swizzling
  94. void __fastcall SwizzleBlock32_c(BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask)
  95. {
  96. DWORD* d = &columnTable32[0][0];
  97. if(WriteMask == 0xffffffff)
  98. {
  99. for(int j = 0; j < 8; j++, d += 8, src += srcpitch)
  100. for(int i = 0; i < 8; i++)
  101. ((DWORD*)dst)[d[i]] = ((DWORD*)src)[i];
  102. }
  103. else
  104. {
  105. for(int j = 0; j < 8; j++, d += 8, src += srcpitch)
  106. for(int i = 0; i < 8; i++)
  107. ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~WriteMask) | (((DWORD*)src)[i] & WriteMask);
  108. }
  109. }
  110. void __fastcall SwizzleBlock16_c(BYTE* dst, BYTE* src, int srcpitch)
  111. {
  112. DWORD* d = &columnTable16[0][0];
  113. for(int j = 0; j < 8; j++, d += 16, src += srcpitch)
  114. for(int i = 0; i < 16; i++)
  115. ((WORD*)dst)[d[i]] = ((WORD*)src)[i];
  116. }
  117. void __fastcall SwizzleBlock8_c(BYTE* dst, BYTE* src, int srcpitch)
  118. {
  119. DWORD* d = &columnTable8[0][0];
  120. for(int j = 0; j < 16; j++, d += 16, src += srcpitch)
  121. for(int i = 0; i < 16; i++)
  122. dst[d[i]] = src[i];
  123. }
  124. void __fastcall SwizzleBlock4_c(BYTE* dst, BYTE* src, int srcpitch)
  125. {
  126. DWORD* d = &columnTable4[0][0];
  127. for(int j = 0; j < 16; j++, d += 32, src += srcpitch)
  128. {
  129. for(int i = 0; i < 32; i++)
  130. {
  131. DWORD addr = d[i];
  132. BYTE c = (src[i>>1] >> ((i&1) << 2)) & 0x0f;
  133. DWORD shift = (addr&1) << 2;
  134. dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift);
  135. }
  136. }
  137. }
  138. // column swizzling (TODO: sse2)
  139. void __fastcall SwizzleColumn32_c(int y, BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask)
  140. {
  141. DWORD* d = &columnTable32[((y/2)&3)*2][0];
  142. if(WriteMask == 0xffffffff)
  143. {
  144. for(int j = 0; j < 2; j++, d += 8, src += srcpitch)
  145. for(int i = 0; i < 8; i++)
  146. ((DWORD*)dst)[d[i]] = ((DWORD*)src)[i];
  147. }
  148. else
  149. {
  150. for(int j = 0; j < 2; j++, d += 8, src += srcpitch)
  151. for(int i = 0; i < 8; i++)
  152. ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~WriteMask) | (((DWORD*)src)[i] & WriteMask);
  153. }
  154. }
  155. void __fastcall SwizzleColumn16_c(int y, BYTE* dst, BYTE* src, int srcpitch)
  156. {
  157. DWORD* d = &columnTable16[((y/2)&3)*2][0];
  158. for(int j = 0; j < 2; j++, d += 16, src += srcpitch)
  159. for(int i = 0; i < 16; i++)
  160. ((WORD*)dst)[d[i]] = ((WORD*)src)[i];
  161. }
  162. void __fastcall SwizzleColumn8_c(int y, BYTE* dst, BYTE* src, int srcpitch)
  163. {
  164. DWORD* d = &columnTable8[((y/4)&3)*4][0];
  165. for(int j = 0; j < 4; j++, d += 16, src += srcpitch)
  166. for(int i = 0; i < 16; i++)
  167. dst[d[i]] = src[i];
  168. }
  169. void __fastcall SwizzleColumn4_c(int y, BYTE* dst, BYTE* src, int srcpitch)
  170. {
  171. DWORD* d = &columnTable4[y&(3<<2)][0]; // ((y/4)&3)*4
  172. for(int j = 0; j < 4; j++, d += 32, src += srcpitch)
  173. {
  174. for(int i = 0; i < 32; i++)
  175. {
  176. DWORD addr = d[i];
  177. BYTE c = (src[i>>1] >> ((i&1) << 2)) & 0x0f;
  178. DWORD shift = (addr&1) << 2;
  179. dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift);
  180. }
  181. }
  182. }
  183. //
  184. #if defined(_M_AMD64) || _M_IX86_FP >= 2
  185. static __m128i s_zero = _mm_setzero_si128();
  186. static __m128i s_bgrm = _mm_set1_epi32(0x00ffffff);
  187. static __m128i s_am = _mm_set1_epi32(0x00008000);
  188. static __m128i s_bm = _mm_set1_epi32(0x00007c00);
  189. static __m128i s_gm = _mm_set1_epi32(0x000003e0);
  190. static __m128i s_rm = _mm_set1_epi32(0x0000001f);
  191. void __fastcall ExpandBlock24_sse2(DWORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA)
  192. {
  193. __m128i TA0 = _mm_set1_epi32((DWORD)pTEXA->TA0 << 24);
  194. if(!pTEXA->AEM)
  195. {
  196. for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2)
  197. {
  198. for(int i = 0; i < 8; i += 4)
  199. {
  200. __m128i c = _mm_load_si128((__m128i*)&src[i]);
  201. c = _mm_and_si128(c, s_bgrm);
  202. c = _mm_or_si128(c, TA0);
  203. _mm_store_si128((__m128i*)&dst[i], c);
  204. }
  205. }
  206. }
  207. else
  208. {
  209. for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2)
  210. {
  211. for(int i = 0; i < 8; i += 4)
  212. {
  213. __m128i c = _mm_load_si128((__m128i*)&src[i]);
  214. c = _mm_and_si128(c, s_bgrm);
  215. __m128i a = _mm_andnot_si128(_mm_cmpeq_epi32(c, s_zero), TA0);
  216. c = _mm_or_si128(c, a);
  217. _mm_store_si128((__m128i*)&dst[i], c);
  218. }
  219. }
  220. }
  221. }
  222. void __fastcall ExpandBlock16_sse2(WORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA)
  223. {
  224. __m128i TA0 = _mm_set1_epi32((DWORD)pTEXA->TA0 << 24);
  225. __m128i TA1 = _mm_set1_epi32((DWORD)pTEXA->TA1 << 24);
  226. __m128i a, b, g, r;
  227. if(!pTEXA->AEM)
  228. {
  229. for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2)
  230. {
  231. for(int i = 0; i < 16; i += 8)
  232. {
  233. __m128i c = _mm_load_si128((__m128i*)&src[i]);
  234. __m128i cl = _mm_unpacklo_epi16(c, s_zero);
  235. __m128i ch = _mm_unpackhi_epi16(c, s_zero);
  236. __m128i alm = _mm_cmplt_epi32(cl, s_am);
  237. __m128i ahm = _mm_cmplt_epi32(ch, s_am);
  238. // lo
  239. b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9);
  240. g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6);
  241. r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3);
  242. a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1));
  243. cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  244. _mm_store_si128((__m128i*)&dst[i], cl);
  245. // hi
  246. b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9);
  247. g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6);
  248. r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3);
  249. a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1));
  250. ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  251. _mm_store_si128((__m128i*)&dst[i+4], ch);
  252. }
  253. }
  254. }
  255. else
  256. {
  257. for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2)
  258. {
  259. for(int i = 0; i < 16; i += 8)
  260. {
  261. __m128i c = _mm_load_si128((__m128i*)&src[i]);
  262. __m128i cl = _mm_unpacklo_epi16(c, s_zero);
  263. __m128i ch = _mm_unpackhi_epi16(c, s_zero);
  264. __m128i alm = _mm_cmplt_epi32(cl, s_am);
  265. __m128i ahm = _mm_cmplt_epi32(ch, s_am);
  266. __m128i trm = _mm_cmpeq_epi16(c, s_zero);
  267. __m128i trlm = _mm_unpacklo_epi16(trm, trm);
  268. __m128i trhm = _mm_unpackhi_epi16(trm, trm);
  269. // lo
  270. b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9);
  271. g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6);
  272. r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3);
  273. a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1));
  274. a = _mm_andnot_si128(trlm, a);
  275. cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  276. _mm_store_si128((__m128i*)&dst[i], cl);
  277. // hi
  278. b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9);
  279. g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6);
  280. r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3);
  281. a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1));
  282. a = _mm_andnot_si128(trhm, a);
  283. ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  284. _mm_store_si128((__m128i*)&dst[i+4], ch);
  285. }
  286. }
  287. }
  288. }
  289. void __fastcall Expand16_sse2(WORD* src, DWORD* dst, int w, GIFRegTEXA* pTEXA)
  290. {
  291. ASSERT(!(w&7));
  292. __m128i TA0 = _mm_set1_epi32((DWORD)pTEXA->TA0 << 24);
  293. __m128i TA1 = _mm_set1_epi32((DWORD)pTEXA->TA1 << 24);
  294. __m128i a, b, g, r;
  295. if(!pTEXA->AEM)
  296. {
  297. for(int i = 0; i < w; i += 8)
  298. {
  299. __m128i c = _mm_load_si128((__m128i*)&src[i]);
  300. __m128i cl = _mm_unpacklo_epi16(c, s_zero);
  301. __m128i ch = _mm_unpackhi_epi16(c, s_zero);
  302. __m128i alm = _mm_cmplt_epi32(cl, s_am);
  303. __m128i ahm = _mm_cmplt_epi32(ch, s_am);
  304. // lo
  305. b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9);
  306. g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6);
  307. r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3);
  308. a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1));
  309. cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  310. _mm_store_si128((__m128i*)&dst[i], cl);
  311. // hi
  312. b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9);
  313. g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6);
  314. r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3);
  315. a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1));
  316. ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  317. _mm_store_si128((__m128i*)&dst[i+4], ch);
  318. }
  319. }
  320. else
  321. {
  322. for(int i = 0; i < w; i += 8)
  323. {
  324. __m128i c = _mm_load_si128((__m128i*)&src[i]);
  325. __m128i cl = _mm_unpacklo_epi16(c, s_zero);
  326. __m128i ch = _mm_unpackhi_epi16(c, s_zero);
  327. __m128i alm = _mm_cmplt_epi32(cl, s_am);
  328. __m128i ahm = _mm_cmplt_epi32(ch, s_am);
  329. __m128i trm = _mm_cmpeq_epi16(c, s_zero);
  330. __m128i trlm = _mm_unpacklo_epi16(trm, trm);
  331. __m128i trhm = _mm_unpackhi_epi16(trm, trm);
  332. // lo
  333. b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9);
  334. g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6);
  335. r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3);
  336. a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1));
  337. a = _mm_andnot_si128(trlm, a);
  338. cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  339. _mm_store_si128((__m128i*)&dst[i], cl);
  340. // hi
  341. b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9);
  342. g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6);
  343. r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3);
  344. a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1));
  345. a = _mm_andnot_si128(trhm, a);
  346. ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r));
  347. _mm_store_si128((__m128i*)&dst[i+4], ch);
  348. }
  349. }
  350. }
  351. #endif
  352. void __fastcall ExpandBlock24_c(DWORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA)
  353. {
  354. DWORD TA0 = (DWORD)pTEXA->TA0 << 24;
  355. if(!pTEXA->AEM)
  356. {
  357. for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2)
  358. for(int i = 0; i < 8; i++)
  359. dst[i] = TA0 | (src[i]&0xffffff);
  360. }
  361. else
  362. {
  363. for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2)
  364. for(int i = 0; i < 8; i++)
  365. dst[i] = ((src[i]&0xffffff) ? TA0 : 0) | (src[i]&0xffffff);
  366. }
  367. }
  368. void __fastcall ExpandBlock16_c(WORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA)
  369. {
  370. DWORD TA0 = (DWORD)pTEXA->TA0 << 24;
  371. DWORD TA1 = (DWORD)pTEXA->TA1 << 24;
  372. if(!pTEXA->AEM)
  373. {
  374. for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2)
  375. for(int i = 0; i < 16; i++)
  376. dst[i] = ((src[i]&0x8000) ? TA1 : TA0)
  377. | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3);
  378. }
  379. else
  380. {
  381. for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2)
  382. for(int i = 0; i < 16; i++)
  383. dst[i] = ((src[i]&0x8000) ? TA1 : src[i] ? TA0 : 0)
  384. | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3);
  385. }
  386. }
  387. void __fastcall Expand16_c(WORD* src, DWORD* dst, int w, GIFRegTEXA* pTEXA)
  388. {
  389. DWORD TA0 = (DWORD)pTEXA->TA0 << 24;
  390. DWORD TA1 = (DWORD)pTEXA->TA1 << 24;
  391. if(!pTEXA->AEM)
  392. {
  393. for(int i = 0; i < w; i++)
  394. dst[i] = ((src[i]&0x8000) ? TA1 : TA0)
  395. | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3);
  396. }
  397. else
  398. {
  399. for(int i = 0; i < w; i++)
  400. dst[i] = ((src[i]&0x8000) ? TA1 : src[i] ? TA0 : 0)
  401. | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3);
  402. }
  403. }
  404. //
  405. #if defined(_M_AMD64) || _M_IX86_FP >= 2
  406. static __m128 s_uvmin = _mm_set1_ps(+1e10);
  407. static __m128 s_uvmax = _mm_set1_ps(-1e10);
  408. void __fastcall UVMinMax_sse2(int nVertices, vertex_t* pVertices, uvmm_t* uv)
  409. {
  410. __m128 uvmin = s_uvmin;
  411. __m128 uvmax = s_uvmax;
  412. __m128* p = (__m128*)pVertices + 1;
  413. int i = 0;
  414. nVertices -= 5;
  415. for(; i < nVertices; i += 6) // 6 regs for loading, 2 regs for min/max
  416. {
  417. uvmin = _mm_min_ps(uvmin, p[(i+0)*2]);
  418. uvmax = _mm_max_ps(uvmax, p[(i+0)*2]);
  419. uvmin = _mm_min_ps(uvmin, p[(i+1)*2]);
  420. uvmax = _mm_max_ps(uvmax, p[(i+1)*2]);
  421. uvmin = _mm_min_ps(uvmin, p[(i+2)*2]);
  422. uvmax = _mm_max_ps(uvmax, p[(i+2)*2]);
  423. uvmin = _mm_min_ps(uvmin, p[(i+3)*2]);
  424. uvmax = _mm_max_ps(uvmax, p[(i+3)*2]);
  425. uvmin = _mm_min_ps(uvmin, p[(i+4)*2]);
  426. uvmax = _mm_max_ps(uvmax, p[(i+4)*2]);
  427. uvmin = _mm_min_ps(uvmin, p[(i+5)*2]);
  428. uvmax = _mm_max_ps(uvmax, p[(i+5)*2]);
  429. }
  430. nVertices += 5;
  431. for(; i < nVertices; i++)
  432. {
  433. uvmin = _mm_min_ps(uvmin, p[i*2]);
  434. uvmax = _mm_max_ps(uvmax, p[i*2]);
  435. }
  436. _mm_storeh_pi((__m64*)uv, uvmin);
  437. _mm_storeh_pi((__m64*)uv + 1, uvmax);
  438. }
  439. #endif
  440. void __fastcall UVMinMax_c(int nVertices, vertex_t* pVertices, uvmm_t* uv)
  441. {
  442. uv->umin = uv->vmin = +1e10;
  443. uv->umax = uv->vmax = -1e10;
  444. for(; nVertices-- > 0; pVertices++)
  445. {
  446. float u = pVertices->u;
  447. if(uv->umax < u) uv->umax = u;
  448. if(uv->umin > u) uv->umin = u;
  449. float v = pVertices->v;
  450. if(uv->vmax < v) uv->vmax = v;
  451. if(uv->vmin > v) uv->vmin = v;
  452. }
  453. }
  454. #if defined(_M_AMD64) || _M_IX86_FP >= 2
  455. static __m128i s_clut[64];
  456. void __fastcall WriteCLUT_T16_I8_CSM1_sse2(WORD* vm, WORD* clut)
  457. {
  458. __m128i* src = (__m128i*)vm;
  459. __m128i* dst = (__m128i*)clut;
  460. for(int i = 0; i < 32; i += 4)
  461. {
  462. __m128i r0 = _mm_load_si128(&src[i+0]);
  463. __m128i r1 = _mm_load_si128(&src[i+1]);
  464. __m128i r2 = _mm_load_si128(&src[i+2]);
  465. __m128i r3 = _mm_load_si128(&src[i+3]);
  466. __m128i r4 = _mm_unpacklo_epi16(r0, r1);
  467. __m128i r5 = _mm_unpackhi_epi16(r0, r1);
  468. __m128i r6 = _mm_unpacklo_epi16(r2, r3);
  469. __m128i r7 = _mm_unpackhi_epi16(r2, r3);
  470. r0 = _mm_unpacklo_epi32(r4, r6);
  471. r1 = _mm_unpackhi_epi32(r4, r6);
  472. r2 = _mm_unpacklo_epi32(r5, r7);
  473. r3 = _mm_unpackhi_epi32(r5, r7);
  474. r4 = _mm_unpacklo_epi16(r0, r1);
  475. r5 = _mm_unpackhi_epi16(r0, r1);
  476. r6 = _mm_unpacklo_epi16(r2, r3);
  477. r7 = _mm_unpackhi_epi16(r2, r3);
  478. _mm_store_si128(&dst[i+0], r4);
  479. _mm_store_si128(&dst[i+1], r6);
  480. _mm_store_si128(&dst[i+2], r5);
  481. _mm_store_si128(&dst[i+3], r7);
  482. }
  483. }
  484. void __fastcall WriteCLUT_T32_I8_CSM1_sse2(DWORD* vm, WORD* clut)
  485. {
  486. __m128i* src = (__m128i*)vm;
  487. __m128i* dst = s_clut;
  488. for(int j = 0; j < 64; j += 32, src += 32, dst += 32)
  489. {
  490. for(int i = 0; i < 16; i += 4)
  491. {
  492. __m128i r0 = _mm_load_si128(&src[i+0]);
  493. __m128i r1 = _mm_load_si128(&src[i+1]);
  494. __m128i r2 = _mm_load_si128(&src[i+2]);
  495. __m128i r3 = _mm_load_si128(&src[i+3]);
  496. _mm_store_si128(&dst[i*2+0], _mm_unpacklo_epi64(r0, r1));
  497. _mm_store_si128(&dst[i*2+1], _mm_unpacklo_epi64(r2, r3));
  498. _mm_store_si128(&dst[i*2+2], _mm_unpackhi_epi64(r0, r1));
  499. _mm_store_si128(&dst[i*2+3], _mm_unpackhi_epi64(r2, r3));
  500. __m128i r4 = _mm_load_si128(&src[i+0+16]);
  501. __m128i r5 = _mm_load_si128(&src[i+1+16]);
  502. __m128i r6 = _mm_load_si128(&src[i+2+16]);
  503. __m128i r7 = _mm_load_si128(&src[i+3+16]);
  504. _mm_store_si128(&dst[i*2+4], _mm_unpacklo_epi64(r4, r5));
  505. _mm_store_si128(&dst[i*2+5], _mm_unpacklo_epi64(r6, r7));
  506. _mm_store_si128(&dst[i*2+6], _mm_unpackhi_epi64(r4, r5));
  507. _mm_store_si128(&dst[i*2+7], _mm_unpackhi_epi64(r6, r7));
  508. }
  509. }
  510. for(int i = 0; i < 32; i++)
  511. {
  512. __m128i r0 = s_clut[i*2];
  513. __m128i r1 = s_clut[i*2+1];
  514. __m128i r2 = _mm_unpacklo_epi16(r0, r1);
  515. __m128i r3 = _mm_unpackhi_epi16(r0, r1);
  516. r0 = _mm_unpacklo_epi16(r2, r3);
  517. r1 = _mm_unpackhi_epi16(r2, r3);
  518. r2 = _mm_unpacklo_epi16(r0, r1);
  519. r3 = _mm_unpackhi_epi16(r0, r1);
  520. _mm_store_si128(&((__m128i*)clut)[i], r2);
  521. _mm_store_si128(&((__m128i*)clut)[i+32], r3);
  522. }
  523. }
  524. void __fastcall WriteCLUT_T16_I4_CSM1_sse2(WORD* vm, WORD* clut)
  525. {
  526. // TODO (probably not worth, _c is going to be just as fast)
  527. WriteCLUT_T16_I4_CSM1_c(vm, clut);
  528. }
  529. void __fastcall WriteCLUT_T32_I4_CSM1_sse2(DWORD* vm, WORD* clut)
  530. {
  531. __m128i* src = (__m128i*)vm;
  532. __m128i* dst = s_clut;
  533. __m128i r0 = _mm_load_si128(&src[0]);
  534. __m128i r1 = _mm_load_si128(&src[1]);
  535. __m128i r2 = _mm_load_si128(&src[2]);
  536. __m128i r3 = _mm_load_si128(&src[3]);
  537. _mm_store_si128(&dst[0], _mm_unpacklo_epi64(r0, r1));
  538. _mm_store_si128(&dst[1], _mm_unpacklo_epi64(r2, r3));
  539. _mm_store_si128(&dst[2], _mm_unpackhi_epi64(r0, r1));
  540. _mm_store_si128(&dst[3], _mm_unpackhi_epi64(r2, r3));
  541. for(int i = 0; i < 2; i++)
  542. {
  543. __m128i r0 = s_clut[i*2];
  544. __m128i r1 = s_clut[i*2+1];
  545. __m128i r2 = _mm_unpacklo_epi16(r0, r1);
  546. __m128i r3 = _mm_unpackhi_epi16(r0, r1);
  547. r0 = _mm_unpacklo_epi16(r2, r3);
  548. r1 = _mm_unpackhi_epi16(r2, r3);
  549. r2 = _mm_unpacklo_epi16(r0, r1);
  550. r3 = _mm_unpackhi_epi16(r0, r1);
  551. _mm_store_si128(&((__m128i*)clut)[i], r2);
  552. _mm_store_si128(&((__m128i*)clut)[i+32], r3);
  553. }
  554. }
  555. #endif
  556. void __fastcall WriteCLUT_T16_I8_CSM1_c(WORD* vm, WORD* clut)
  557. {
  558. const static DWORD map[] = 
  559. {
  560. 0, 2, 8, 10, 16, 18, 24, 26,
  561. 4, 6, 12, 14, 20, 22, 28, 30,
  562. 1, 3, 9, 11, 17, 19, 25, 27, 
  563. 5, 7, 13, 15, 21, 23, 29, 31
  564. };
  565. for(int j = 0; j < 8; j++, vm += 32, clut += 32) 
  566. {
  567. for(int i = 0; i < 32; i++)
  568. {
  569. clut[i] = vm[map[i]];
  570. }
  571. }
  572. }
  573. void __fastcall WriteCLUT_T32_I8_CSM1_c(DWORD* vm, WORD* clut)
  574. {
  575. const static DWORD map[] = 
  576. {
  577. 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15, 
  578. 64, 65, 68, 69, 72, 73, 76, 77, 66, 67, 70, 71, 74, 75, 78, 79, 
  579. 16, 17, 20, 21, 24, 25, 28, 29, 18, 19, 22, 23, 26, 27, 30, 31, 
  580. 80, 81, 84, 85, 88, 89, 92, 93, 82, 83, 86, 87, 90, 91, 94, 95, 
  581. 32, 33, 36, 37, 40, 41, 44, 45, 34, 35, 38, 39, 42, 43, 46, 47, 
  582. 96, 97, 100, 101, 104, 105, 108, 109, 98, 99, 102, 103, 106, 107, 110, 111, 
  583. 48, 49, 52, 53, 56, 57, 60, 61, 50, 51, 54, 55, 58, 59, 62, 63, 
  584. 112, 113, 116, 117, 120, 121, 124, 125, 114, 115, 118, 119, 122, 123, 126, 127
  585. };
  586. for(int j = 0; j < 2; j++, vm += 128, clut += 128)
  587. {
  588. for(int i = 0; i < 128; i++) 
  589. {
  590. DWORD dw = vm[map[i]];
  591. clut[i] = (WORD)(dw & 0xffff);
  592. clut[i+256] = (WORD)(dw >> 16);
  593. }
  594. }
  595. }
  596. void __fastcall WriteCLUT_T16_I4_CSM1_c(WORD* vm, WORD* clut)
  597. {
  598. const static DWORD map[] = 
  599. {
  600. 0, 2, 8, 10, 16, 18, 24, 26,
  601. 4, 6, 12, 14, 20, 22, 28, 30
  602. };
  603. for(int i = 0; i < 16; i++) 
  604. {
  605. clut[i] = vm[map[i]];
  606. }
  607. }
  608. void __fastcall WriteCLUT_T32_I4_CSM1_c(DWORD* vm, WORD* clut)
  609. {
  610. const static DWORD map[] = 
  611. {
  612. 0, 1, 4, 5, 8, 9, 12, 13,
  613. 2, 3, 6, 7, 10, 11, 14, 15
  614. };
  615. for(int i = 0; i < 16; i++) 
  616. {
  617. DWORD dw = vm[map[i]];
  618. clut[i] = (WORD)(dw & 0xffff);
  619. clut[i+256] = (WORD)(dw >> 16);
  620. }
  621. }
  622. //
  623. #if defined(_M_AMD64) || _M_IX86_FP >= 2
  624. extern "C" void __fastcall ReadCLUT32_T32_I8_sse2(WORD* src, DWORD* dst)
  625. {
  626. for(int i = 0; i < 256; i += 16)
  627. {
  628. ReadCLUT32_T32_I4_sse2(&src[i], &dst[i]); // going to be inlined nicely
  629. }
  630. }
  631. extern "C" void __fastcall ReadCLUT32_T32_I4_sse2(WORD* src, DWORD* dst)
  632. {
  633. __m128i r0 = ((__m128i*)src)[0];
  634. __m128i r1 = ((__m128i*)src)[1];
  635. __m128i r2 = ((__m128i*)src)[0+32];
  636. __m128i r3 = ((__m128i*)src)[1+32];
  637. _mm_store_si128(&((__m128i*)dst)[0], _mm_unpacklo_epi16(r0, r2));
  638. _mm_store_si128(&((__m128i*)dst)[1], _mm_unpackhi_epi16(r0, r2));
  639. _mm_store_si128(&((__m128i*)dst)[2], _mm_unpacklo_epi16(r1, r3));
  640. _mm_store_si128(&((__m128i*)dst)[3], _mm_unpackhi_epi16(r1, r3));
  641. }
  642. extern "C" void __fastcall ReadCLUT32_T16_I8_sse2(WORD* src, DWORD* dst)
  643. {
  644. for(int i = 0; i < 256; i += 16)
  645. {
  646. ReadCLUT32_T16_I4_sse2(&src[i], &dst[i]);
  647. }
  648. }
  649. extern "C" void __fastcall ReadCLUT32_T16_I4_sse2(WORD* src, DWORD* dst)
  650. {
  651. __m128i r0 = ((__m128i*)src)[0];
  652. __m128i r1 = ((__m128i*)src)[1];
  653. _mm_store_si128(&((__m128i*)dst)[0], _mm_unpacklo_epi16(r0, s_zero));
  654. _mm_store_si128(&((__m128i*)dst)[1], _mm_unpackhi_epi16(r0, s_zero));
  655. _mm_store_si128(&((__m128i*)dst)[2], _mm_unpacklo_epi16(r1, s_zero));
  656. _mm_store_si128(&((__m128i*)dst)[3], _mm_unpackhi_epi16(r1, s_zero));
  657. }
  658. #endif
  659. void __fastcall ReadCLUT32_T32_I8_c(WORD* src, DWORD* dst)
  660. {
  661. for(int i = 0; i < 256; i++)
  662. {
  663. dst[i] = ((DWORD)src[i+256] << 16) | src[i];
  664. }
  665. }
  666. void __fastcall ReadCLUT32_T32_I4_c(WORD* src, DWORD* dst)
  667. {
  668. for(int i = 0; i < 16; i++)
  669. {
  670. dst[i] = ((DWORD)src[i+256] << 16) | src[i];
  671. }
  672. }
  673. void __fastcall ReadCLUT32_T16_I8_c(WORD* src, DWORD* dst)
  674. {
  675. for(int i = 0; i < 256; i++)
  676. {
  677. dst[i] = (DWORD)src[i];
  678. }
  679. }
  680. void __fastcall ReadCLUT32_T16_I4_c(WORD* src, DWORD* dst)
  681. {
  682. for(int i = 0; i < 16; i++)
  683. {
  684. dst[i] = (DWORD)src[i];
  685. }
  686. }
  687. //