BVB Source Codes

CRYENGINE Show VMath_SSE.hpp Source code

Return Download CRYENGINE: download VMath_SSE.hpp Source code - Download CRYENGINE Source code - Type:.hpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  Version:     v1.00
  5. //  Created:     Michael Kopietz
  6. //  Description: unified vector math lib
  7. // -------------------------------------------------------------------------
  8. //  History:            - created 1999  for Katmai and K3
  9. //                                                      -       ...
  10. //                                                      -       integrated into cryengine
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY
  15.  
  16. namespace NVMath
  17. {
  18.  
  19. typedef __m128 vec4;
  20.  
  21. #include "VMath_Prototypes.hpp"
  22.  
  23. #define SWIZZLEMASK4(N, X, Y, Z) N ## x = _MM_SHUFFLE(0, Z, Y, X), \
  24.   N ## y = _MM_SHUFFLE(1, Z, Y, X),                                \
  25.   N ## z = _MM_SHUFFLE(2, Z, Y, X),                                \
  26.   N ## w = _MM_SHUFFLE(3, Z, Y, X),
  27. #define SWIZZLEMASK3(N, X, Y)    SWIZZLEMASK4(N ## x, X, Y, 0) \
  28.   SWIZZLEMASK4(N ## y, X, Y, 1)                                \
  29.   SWIZZLEMASK4(N ## z, X, Y, 2)                                \
  30.   SWIZZLEMASK4(N ## w, X, Y, 3)
  31. #define SWIZZLEMASK2(N, X)       SWIZZLEMASK3(N ## x, X, 0) \
  32.   SWIZZLEMASK3(N ## y, X, 1)                                \
  33.   SWIZZLEMASK3(N ## z, X, 2)                                \
  34.   SWIZZLEMASK3(N ## w, X, 3)
  35. #define SWIZZLEMASK1 SWIZZLEMASK2(x, 0) \
  36.   SWIZZLEMASK2(y, 1)                    \
  37.   SWIZZLEMASK2(z, 2)                    \
  38.   SWIZZLEMASK2(w, 3)
  39.  
  40. enum ESwizzleMask
  41. {
  42.         SWIZZLEMASK1
  43. };
  44. enum ECacheLvl
  45. {
  46.         ECL_LVL1 = _MM_HINT_T0,
  47.         ECL_LVL2 = _MM_HINT_T1,
  48.         ECL_LVL3 = _MM_HINT_T2,
  49. };
  50. #define BitX 1
  51. #define BitY 2
  52. #define BitZ 4
  53. #define BitW 8
  54.  
  55. ILINE vec4 Vec4(float x)
  56. {
  57.         return _mm_set1_ps(x);
  58. }
  59. ILINE vec4 Vec4(float x, float y, float z, float w)
  60. {
  61.         return _mm_set_ps(w, z, y, x);
  62. }
  63. ILINE vec4 Vec4(uint32 x, uint32 y, uint32 z, uint32 w)
  64. {
  65.         return _mm_set_ps(*reinterpret_cast<float*>(&w),
  66.                           *reinterpret_cast<float*>(&z),
  67.                           *reinterpret_cast<float*>(&y),
  68.                           *reinterpret_cast<float*>(&x));
  69. }
  70. ILINE float Vec4float(vec4 V, uint32 Idx)
  71. {
  72.         union
  73.         {
  74.                 vec4  Tmp;
  75.                 float V4[4];
  76.         } T;
  77.         T.Tmp = V;
  78.         return T.V4[Idx];
  79. }
  80. template<int Idx>
  81. ILINE float Vec4float(vec4 V)
  82. {
  83. #if defined(VEC4_SSE4)
  84.         float f;
  85.         _MM_EXTRACT_FLOAT(f, V, Idx);
  86.         return f;
  87. #else
  88.         return Vec4float(V, Idx);
  89. #endif
  90. }
  91. template<int Idx>
  92. ILINE int32 Vec4int32(vec4 V)
  93. {
  94. #if defined(VEC4_SSE4)
  95.         return _mm_extract_ps(V, Idx);
  96. #else
  97.         return Vec4int32(V, Idx);
  98. #endif
  99. }
  100. ILINE int32 Vec4int32(vec4 V, uint32 Idx)
  101. {
  102.         union
  103.         {
  104.                 vec4  Tmp;
  105.                 int32 V4[4];
  106.         } T;
  107.         T.Tmp = V;
  108.         return T.V4[Idx];
  109. }
  110. ILINE vec4 Vec4Zero()
  111. {
  112.         return _mm_setzero_ps();
  113. }
  114.  
  115. ILINE vec4 Vec4One()
  116. {
  117.         return _mm_set_ps(1.f, 1.f, 1.f, 1.f);
  118. }
  119. ILINE vec4 Vec4Four()
  120. {
  121.         return _mm_set_ps(4.f, 4.f, 4.f, 4.f);
  122. }
  123. ILINE vec4 Vec4ZeroOneTwoThree()
  124. {
  125.         return _mm_set_ps(3.f, 2.f, 1.f, 0.f);
  126. }
  127. ILINE vec4 Vec4FFFFFFFF()
  128. {
  129.         __m128 a = _mm_setzero_ps();
  130.         return _mm_cmpeq_ps(a, a);
  131. }
  132. ILINE vec4 Vec4Epsilon()
  133. {
  134.         return _mm_set_ps(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON, FLT_EPSILON);
  135. }
  136. template<ECacheLvl L>
  137. ILINE void Prefetch(const void* pData)
  138. {
  139. #if (CRY_PLATFORM_LINUX || CRY_PLATFORM_ANDROID) && !defined(__clang__)
  140.         _mm_prefetch(reinterpret_cast<const char*>(pData), (_mm_hint)L);
  141. #else
  142.         _mm_prefetch(reinterpret_cast<const char*>(pData), (int)L);
  143. #endif
  144. }
  145. template<ESwizzleMask M>
  146. ILINE vec4 Shuffle(vec4 V0, vec4 V1)
  147. {
  148.         return _mm_shuffle_ps(V0, V1, M);
  149. }
  150. template<ESwizzleMask M>
  151. ILINE vec4 Swizzle(vec4 V)
  152. {
  153.         return Shuffle<M>(V, V);
  154. }
  155. ILINE void ExtractByteToFloat(vec4& rVOut0, vec4& rVOut1, vec4& rVOut2, vec4& rVOut3, vec4 VIn)
  156. {
  157.         const vec4 Zf = Vec4Zero();
  158.         const __m128i Z = *reinterpret_cast<const __m128i*>(&Zf);
  159.         __m128i V0 = _mm_unpacklo_epi8(*reinterpret_cast<const __m128i*>(&VIn), Z);
  160.         __m128i V1 = _mm_unpackhi_epi8(*reinterpret_cast<const __m128i*>(&VIn), Z);
  161.         __m128i V00 = _mm_unpacklo_epi8(V0, Z);
  162.         __m128i V01 = _mm_unpackhi_epi8(V0, Z);
  163.         __m128i V10 = _mm_unpacklo_epi8(V1, Z);
  164.         __m128i V11 = _mm_unpackhi_epi8(V1, Z);
  165.         V00 = _mm_srai_epi32(_mm_slli_epi32(V00, 24), 24);
  166.         V01 = _mm_srai_epi32(_mm_slli_epi32(V01, 24), 24);
  167.         V10 = _mm_srai_epi32(_mm_slli_epi32(V10, 24), 24);
  168.         V11 = _mm_srai_epi32(_mm_slli_epi32(V11, 24), 24);
  169.         rVOut0 = int32Tofloat(*reinterpret_cast<const vec4*>(&V00));
  170.         rVOut1 = int32Tofloat(*reinterpret_cast<const vec4*>(&V01));
  171.         rVOut2 = int32Tofloat(*reinterpret_cast<const vec4*>(&V10));
  172.         rVOut3 = int32Tofloat(*reinterpret_cast<const vec4*>(&V11));
  173. }
  174. ILINE vec4 Add(vec4 V0, vec4 V1)
  175. {
  176.         return _mm_add_ps(V0, V1);
  177. }
  178. ILINE vec4 Sub(vec4 V0, vec4 V1)
  179. {
  180.         return _mm_sub_ps(V0, V1);
  181. }
  182. ILINE vec4 Mul(vec4 V0, vec4 V1)
  183. {
  184.         return _mm_mul_ps(V0, V1);
  185. }
  186. ILINE vec4 Div(vec4 V0, vec4 V1)
  187. {
  188.         return _mm_div_ps(V0, V1);
  189. }
  190. ILINE vec4 RcpFAST(vec4 V)
  191. {
  192.         return _mm_rcp_ps(V);
  193. }
  194. ILINE vec4 DivFAST(vec4 V0, vec4 V1)
  195. {
  196.         return Mul(V0, RcpFAST(V1));
  197. }
  198. ILINE vec4 Rcp(vec4 V)
  199. {
  200.         return Div(Vec4One(), V);
  201. }
  202. ILINE vec4 Madd(vec4 V0, vec4 V1, vec4 V2)
  203. {
  204.         return Add(V2, Mul(V0, V1));
  205. }
  206. ILINE vec4 Msub(vec4 V0, vec4 V1, vec4 V2)
  207. {
  208.         return Sub(Mul(V0, V1), V2);
  209. }
  210. ILINE vec4 Min(vec4 V0, vec4 V1)
  211. {
  212.         return _mm_min_ps(V0, V1);
  213. }
  214. ILINE vec4 Max(vec4 V0, vec4 V1)
  215. {
  216.         return _mm_max_ps(V0, V1);
  217. }
  218. ILINE vec4 floatToint32(vec4 V)
  219. {
  220.         const __m128i Tmp = _mm_cvttps_epi32(V);
  221.         return *reinterpret_cast<const vec4*>(&Tmp);
  222. }
  223. ILINE vec4 int32Tofloat(vec4 V)
  224. {
  225.         return _mm_cvtepi32_ps(*reinterpret_cast<__m128i*>(&V));
  226. }
  227. ILINE vec4 CmpLE(vec4 V0, vec4 V1)
  228. {
  229.         return _mm_cmple_ps(V0, V1);
  230. }
  231. ILINE vec4 CmpEq(vec4 V0, vec4 V1)
  232. {
  233.         return _mm_cmpeq_ps(V0, V1);
  234. }
  235. ILINE uint32 SignMask(vec4 V)
  236. {
  237.         return _mm_movemask_ps(V);
  238. }
  239. ILINE vec4 And(vec4 V0, vec4 V1)
  240. {
  241.         const __m128i Tmp = _mm_and_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1));
  242.         return *reinterpret_cast<const vec4*>(&Tmp);
  243. }
  244. ILINE vec4 AndNot(vec4 V0, vec4 V1)
  245. {
  246.         const __m128i Tmp = _mm_andnot_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1));
  247.         return *reinterpret_cast<const vec4*>(&Tmp);
  248. }
  249. ILINE vec4 Or(vec4 V0, vec4 V1)
  250. {
  251.         const __m128i Tmp = _mm_or_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1));
  252.         return *reinterpret_cast<const vec4*>(&Tmp);
  253. }
  254. ILINE vec4 Xor(vec4 V0, vec4 V1)
  255. {
  256.         const __m128i Tmp = _mm_xor_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1));
  257.         return *reinterpret_cast<const vec4*>(&Tmp);
  258. }
  259. ILINE vec4 ShiftAR(vec4 V, uint32 Count)
  260. {
  261.         const __m128i Tmp = _mm_srai_epi32(*reinterpret_cast<__m128i*>(&V), Count);
  262.         return *reinterpret_cast<const vec4*>(&Tmp);
  263. }
  264. template<int INDEX>
  265. ILINE vec4 Splat(vec4 V)
  266. {
  267.         CRY_ASSERT_MESSAGE(0, "Should not be reached!");
  268.         return Vec4FFFFFFFF();
  269. }
  270. template<>
  271. ILINE vec4 Splat<0>(vec4 V)
  272. {
  273.         return Shuffle<xxxx>(V, V);
  274. }
  275. template<>
  276. ILINE vec4 Splat<1>(vec4 V)
  277. {
  278.         return Shuffle<yyyy>(V, V);
  279. }
  280. template<>
  281. ILINE vec4 Splat<2>(vec4 V)
  282. {
  283.         return Shuffle<zzzz>(V, V);
  284. }
  285. template<>
  286. ILINE vec4 Splat<3>(vec4 V)
  287. {
  288.         return Shuffle<wwww>(V, V);
  289. }
  290. ILINE vec4 SelectBits(vec4 V0, vec4 V1, vec4 M)
  291. {
  292. #if defined(VEC4_SSE4)
  293.         return _mm_blendv_ps(V0, V1, M);
  294. #else
  295.         return Or(AndNot(M, V0), And(M, V1));
  296. #endif
  297. }
  298. ILINE vec4 Select(vec4 V0, vec4 V1, vec4 M)
  299. {
  300. #if !defined(VEC4_SSE4)
  301.         M = ShiftAR(M, 31);
  302. #endif
  303.         return SelectBits(V0, V1, M);
  304. }
  305. ILINE vec4 SelectSign(vec4 V0, vec4 V1, vec4 M)
  306. {
  307. #if defined(VEC4_SSE4)
  308.         return Select(V0, V1, M);
  309. #else
  310.         return Select(V0, V1, ShiftAR(M, 31));
  311. #endif
  312. }
  313. template<int M>
  314. ILINE vec4 SelectStatic(vec4 V0, vec4 V1)
  315. {
  316. #if defined(VEC4_SSE4)
  317.         return _mm_blend_ps(V0, V1, M);
  318. #else
  319.         const vec4 mask = Vec4(M & 0x1 ? ~0x0u : 0x0u, M & 0x2 ? ~0x0u : 0x0u, M & 0x4 ? ~0x0u : 0x0u, M & 0x8 ? ~0x0u : 0x0u);
  320.         return Select(V0, V1, mask);
  321. #endif
  322. }
  323.  
  324. }
  325.  
downloadVMath_SSE.hpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top