type_vec4_simd.inl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. #if GLM_ARCH & GLM_ARCH_SSE2_BIT
  2. namespace glm{
  3. namespace detail
  4. {
  5. # if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
  6. template<qualifier Q, int E0, int E1, int E2, int E3>
  7. struct _swizzle_base1<4, float, Q, E0,E1,E2,E3, true> : public _swizzle_base0<float, 4>
  8. {
  9. GLM_FUNC_QUALIFIER vec<4, float, Q> operator ()() const
  10. {
  11. __m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer);
  12. vec<4, float, Q> Result;
  13. # if GLM_ARCH & GLM_ARCH_AVX_BIT
  14. Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0));
  15. # else
  16. Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0));
  17. # endif
  18. return Result;
  19. }
  20. };
  21. template<qualifier Q, int E0, int E1, int E2, int E3>
  22. struct _swizzle_base1<4, int, Q, E0,E1,E2,E3, true> : public _swizzle_base0<int, 4>
  23. {
  24. GLM_FUNC_QUALIFIER vec<4, int, Q> operator ()() const
  25. {
  26. __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer);
  27. vec<4, int, Q> Result;
  28. Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0));
  29. return Result;
  30. }
  31. };
  32. template<qualifier Q, int E0, int E1, int E2, int E3>
  33. struct _swizzle_base1<4, uint, Q, E0,E1,E2,E3, true> : public _swizzle_base0<uint, 4>
  34. {
  35. GLM_FUNC_QUALIFIER vec<4, uint, Q> operator ()() const
  36. {
  37. __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer);
  38. vec<4, uint, Q> Result;
  39. Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0));
  40. return Result;
  41. }
  42. };
  43. # endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
  44. template<qualifier Q>
  45. struct compute_vec4_add<float, Q, true>
  46. {
  47. static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
  48. {
  49. vec<4, float, Q> Result;
  50. Result.data = _mm_add_ps(a.data, b.data);
  51. return Result;
  52. }
  53. };
  54. # if GLM_ARCH & GLM_ARCH_AVX_BIT
  55. template<qualifier Q>
  56. struct compute_vec4_add<double, Q, true>
  57. {
  58. static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
  59. {
  60. vec<4, double, Q> Result;
  61. Result.data = _mm256_add_pd(a.data, b.data);
  62. return Result;
  63. }
  64. };
  65. # endif
  66. template<qualifier Q>
  67. struct compute_vec4_sub<float, Q, true>
  68. {
  69. static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
  70. {
  71. vec<4, float, Q> Result;
  72. Result.data = _mm_sub_ps(a.data, b.data);
  73. return Result;
  74. }
  75. };
  76. # if GLM_ARCH & GLM_ARCH_AVX_BIT
  77. template<qualifier Q>
  78. struct compute_vec4_sub<double, Q, true>
  79. {
  80. static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
  81. {
  82. vec<4, double, Q> Result;
  83. Result.data = _mm256_sub_pd(a.data, b.data);
  84. return Result;
  85. }
  86. };
  87. # endif
  88. template<qualifier Q>
  89. struct compute_vec4_mul<float, Q, true>
  90. {
  91. static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
  92. {
  93. vec<4, float, Q> Result;
  94. Result.data = _mm_mul_ps(a.data, b.data);
  95. return Result;
  96. }
  97. };
  98. # if GLM_ARCH & GLM_ARCH_AVX_BIT
  99. template<qualifier Q>
  100. struct compute_vec4_mul<double, Q, true>
  101. {
  102. static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
  103. {
  104. vec<4, double, Q> Result;
  105. Result.data = _mm256_mul_pd(a.data, b.data);
  106. return Result;
  107. }
  108. };
  109. # endif
  110. template<qualifier Q>
  111. struct compute_vec4_div<float, Q, true>
  112. {
  113. static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
  114. {
  115. vec<4, float, Q> Result;
  116. Result.data = _mm_div_ps(a.data, b.data);
  117. return Result;
  118. }
  119. };
  120. # if GLM_ARCH & GLM_ARCH_AVX_BIT
  121. template<qualifier Q>
  122. struct compute_vec4_div<double, Q, true>
  123. {
  124. static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
  125. {
  126. vec<4, double, Q> Result;
  127. Result.data = _mm256_div_pd(a.data, b.data);
  128. return Result;
  129. }
  130. };
  131. # endif
  132. template<>
  133. struct compute_vec4_div<float, aligned_lowp, true>
  134. {
  135. static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& a, vec<4, float, aligned_lowp> const& b)
  136. {
  137. vec<4, float, aligned_lowp> Result;
  138. Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data));
  139. return Result;
  140. }
  141. };
  142. template<typename T, qualifier Q>
  143. struct compute_vec4_and<T, Q, true, 32, true>
  144. {
  145. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  146. {
  147. vec<4, T, Q> Result;
  148. Result.data = _mm_and_si128(a.data, b.data);
  149. return Result;
  150. }
  151. };
  152. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  153. template<typename T, qualifier Q>
  154. struct compute_vec4_and<T, Q, true, 64, true>
  155. {
  156. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  157. {
  158. vec<4, T, Q> Result;
  159. Result.data = _mm256_and_si256(a.data, b.data);
  160. return Result;
  161. }
  162. };
  163. # endif
  164. template<typename T, qualifier Q>
  165. struct compute_vec4_or<T, Q, true, 32, true>
  166. {
  167. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  168. {
  169. vec<4, T, Q> Result;
  170. Result.data = _mm_or_si128(a.data, b.data);
  171. return Result;
  172. }
  173. };
  174. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  175. template<typename T, qualifier Q>
  176. struct compute_vec4_or<T, Q, true, 64, true>
  177. {
  178. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  179. {
  180. vec<4, T, Q> Result;
  181. Result.data = _mm256_or_si256(a.data, b.data);
  182. return Result;
  183. }
  184. };
  185. # endif
  186. template<typename T, qualifier Q>
  187. struct compute_vec4_xor<T, Q, true, 32, true>
  188. {
  189. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  190. {
  191. vec<4, T, Q> Result;
  192. Result.data = _mm_xor_si128(a.data, b.data);
  193. return Result;
  194. }
  195. };
  196. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  197. template<typename T, qualifier Q>
  198. struct compute_vec4_xor<T, Q, true, 64, true>
  199. {
  200. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  201. {
  202. vec<4, T, Q> Result;
  203. Result.data = _mm256_xor_si256(a.data, b.data);
  204. return Result;
  205. }
  206. };
  207. # endif
  208. template<typename T, qualifier Q>
  209. struct compute_vec4_shift_left<T, Q, true, 32, true>
  210. {
  211. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  212. {
  213. vec<4, T, Q> Result;
  214. Result.data = _mm_sll_epi32(a.data, b.data);
  215. return Result;
  216. }
  217. };
  218. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  219. template<typename T, qualifier Q>
  220. struct compute_vec4_shift_left<T, Q, true, 64, true>
  221. {
  222. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  223. {
  224. vec<4, T, Q> Result;
  225. Result.data = _mm256_sll_epi64(a.data, b.data);
  226. return Result;
  227. }
  228. };
  229. # endif
  230. template<typename T, qualifier Q>
  231. struct compute_vec4_shift_right<T, Q, true, 32, true>
  232. {
  233. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  234. {
  235. vec<4, T, Q> Result;
  236. Result.data = _mm_srl_epi32(a.data, b.data);
  237. return Result;
  238. }
  239. };
  240. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  241. template<typename T, qualifier Q>
  242. struct compute_vec4_shift_right<T, Q, true, 64, true>
  243. {
  244. static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
  245. {
  246. vec<4, T, Q> Result;
  247. Result.data = _mm256_srl_epi64(a.data, b.data);
  248. return Result;
  249. }
  250. };
  251. # endif
  252. template<typename T, qualifier Q>
  253. struct compute_vec4_bitwise_not<T, Q, true, 32, true>
  254. {
  255. static vec<4, T, Q> call(vec<4, T, Q> const& v)
  256. {
  257. vec<4, T, Q> Result;
  258. Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1));
  259. return Result;
  260. }
  261. };
  262. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  263. template<typename T, qualifier Q>
  264. struct compute_vec4_bitwise_not<T, Q, true, 64, true>
  265. {
  266. static vec<4, T, Q> call(vec<4, T, Q> const& v)
  267. {
  268. vec<4, T, Q> Result;
  269. Result.data = _mm256_xor_si256(v.data, _mm_set1_epi32(-1));
  270. return Result;
  271. }
  272. };
  273. # endif
  274. template<qualifier Q>
  275. struct compute_vec4_equal<float, Q, false, 32, true>
  276. {
  277. static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
  278. {
  279. return _mm_movemask_ps(_mm_cmpeq_ps(v1.data, v2.data)) != 0;
  280. }
  281. };
  282. # if GLM_ARCH & GLM_ARCH_SSE41_BIT
  283. template<qualifier Q>
  284. struct compute_vec4_equal<int, Q, true, 32, true>
  285. {
  286. static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
  287. {
  288. //return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0;
  289. __m128i neq = _mm_xor_si128(v1.data, v2.data);
  290. return _mm_test_all_zeros(neq, neq) == 0;
  291. }
  292. };
  293. # endif
  294. template<qualifier Q>
  295. struct compute_vec4_nequal<float, Q, false, 32, true>
  296. {
  297. static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
  298. {
  299. return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0;
  300. }
  301. };
  302. # if GLM_ARCH & GLM_ARCH_SSE41_BIT
  303. template<qualifier Q>
  304. struct compute_vec4_nequal<int, Q, true, 32, true>
  305. {
  306. static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
  307. {
  308. //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0;
  309. __m128i neq = _mm_xor_si128(v1.data, v2.data);
  310. return _mm_test_all_zeros(neq, neq) != 0;
  311. }
  312. };
  313. # endif
  314. }//namespace detail
  315. template<>
  316. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) :
  317. data(_mm_set1_ps(_s))
  318. {}
  319. template<>
  320. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) :
  321. data(_mm_set1_ps(_s))
  322. {}
  323. template<>
  324. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) :
  325. data(_mm_set1_ps(_s))
  326. {}
  327. # if GLM_ARCH & GLM_ARCH_AVX_BIT
  328. template<>
  329. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_lowp>::vec(double _s) :
  330. data(_mm256_set1_pd(_s))
  331. {}
  332. template<>
  333. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_mediump>::vec(double _s) :
  334. data(_mm256_set1_pd(_s))
  335. {}
  336. template<>
  337. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(double _s) :
  338. data(_mm256_set1_pd(_s))
  339. {}
  340. # endif
  341. template<>
  342. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) :
  343. data(_mm_set1_epi32(_s))
  344. {}
  345. template<>
  346. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) :
  347. data(_mm_set1_epi32(_s))
  348. {}
  349. template<>
  350. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) :
  351. data(_mm_set1_epi32(_s))
  352. {}
  353. # if GLM_ARCH & GLM_ARCH_AVX2_BIT
  354. template<>
  355. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_lowp>::vec(detail::int64 _s) :
  356. data(_mm256_set1_epi64x(_s))
  357. {}
  358. template<>
  359. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_mediump>::vec(detail::int64 _s) :
  360. data(_mm256_set1_epi64x(_s))
  361. {}
  362. template<>
  363. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_highp>::vec(detail::int64 _s) :
  364. data(_mm256_set1_epi64x(_s))
  365. {}
  366. # endif
  367. template<>
  368. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _x, float _y, float _z, float _w) :
  369. data(_mm_set_ps(_w, _z, _y, _x))
  370. {}
  371. template<>
  372. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _x, float _y, float _z, float _w) :
  373. data(_mm_set_ps(_w, _z, _y, _x))
  374. {}
  375. template<>
  376. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _x, float _y, float _z, float _w) :
  377. data(_mm_set_ps(_w, _z, _y, _x))
  378. {}
  379. template<>
  380. template<>
  381. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
  382. data(_mm_set_epi32(_w, _z, _y, _x))
  383. {}
  384. template<>
  385. template<>
  386. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
  387. data(_mm_set_epi32(_w, _z, _y, _x))
  388. {}
  389. template<>
  390. template<>
  391. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
  392. data(_mm_set_epi32(_w, _z, _y, _x))
  393. {}
  394. template<>
  395. template<>
  396. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
  397. data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
  398. {}
  399. template<>
  400. template<>
  401. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
  402. data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
  403. {}
  404. template<>
  405. template<>
  406. GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
  407. data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
  408. {}
  409. }//namespace glm
  410. #endif//GLM_ARCH & GLM_ARCH_SSE2_BIT