hkSseIntVector.inl
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:10k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. //
  9. // Clearing, loading, and storing
  10. //
  11. inline void hkIntVector::setZero()
  12. {
  13. m_quad = _mm_setzero_si128();
  14. }
  15. inline void hkIntVector::loadUnaligned4(const hkUint32* p)
  16. {
  17. HK_ASSERT2(0x217c2b3b, ((hkUlong)p & 3) == 0, "pointer for hkIntVector::loadUnaligned4 must be 4-byte aligned");
  18. m_quad = _mm_loadu_si128((hkQuadUint*) p);
  19. }
  20. //
  21. // Logical operations
  22. //
  23. inline void hkIntVector::setNot(hkIntVectorParameter a)
  24. {
  25. hkQuadUint allBits = _mm_set1_epi32(-1);
  26. m_quad = _mm_andnot_si128( a.m_quad, allBits); 
  27. }
  28. inline void hkIntVector::setOr(hkIntVectorParameter a, hkIntVectorParameter b)
  29. {
  30. m_quad = _mm_or_si128(a.m_quad, b.m_quad);
  31. }
  32. inline void hkIntVector::setAnd(hkIntVectorParameter a, hkIntVectorParameter b)
  33. {
  34. m_quad = _mm_and_si128(a.m_quad, b.m_quad);
  35. }
  36. inline void hkIntVector::setXor(hkIntVectorParameter a, hkIntVectorParameter b)
  37. {
  38. m_quad = _mm_xor_si128(a.m_quad, b.m_quad);
  39. }
  40. inline void hkIntVector::setAndC(hkIntVectorParameter a, hkIntVectorParameter b)
  41. {
  42. m_quad = _mm_andnot_si128(b.m_quad, a.m_quad);
  43. }
  44. //
  45. // Arithmetic operations
  46. //
  47. inline void hkIntVector::setAddSaturateU32( hkIntVectorParameter a, hkIntVectorParameter b )
  48. {
  49. hkQuadUintUnion qu, qa, qb;
  50. qa.q = a; qb.q = b;
  51. const hkUint32 max = hkUint32(-1);
  52. qu.u[0] = (qa.u[0] < max - qb.u[0]) ? (qa.u[0] + qb.u[0]) : max; 
  53. qu.u[1] = (qa.u[1] < max - qb.u[1]) ? (qa.u[1] + qb.u[1]) : max; 
  54. qu.u[2] = (qa.u[2] < max - qb.u[2]) ? (qa.u[2] + qb.u[2]) : max; 
  55. qu.u[3] = (qa.u[3] < max - qb.u[3]) ? (qa.u[3] + qb.u[3]) : max; 
  56. m_quad = qu.q;
  57. }
  58. inline void hkIntVector::setAddSaturateU16( hkIntVectorParameter a, hkIntVectorParameter b )
  59. {
  60. m_quad = _mm_adds_epu16(a.m_quad, b.m_quad);
  61. }
  62. //inline void hkIntVector::setAddS32( hkIntVectorParameter a, hkIntVectorParameter b )
  63. //{
  64. // m_quad = _mm_add_epi32(a.m_quad, b.m_quad);
  65. //}
  66. inline void hkIntVector::setSubSaturateU32( hkIntVectorParameter a, hkIntVectorParameter b )
  67. {
  68. // There are no unsigned 32-bit compare, min/max, or add/subtract instructions (with or without saturation) in SSE2.
  69. hkQuadUintUnion qu, qa, qb;
  70. qa.q = a; qb.q = b;
  71. qu.u[0] = (qa.u[0] > qb.u[0]) ? (qa.u[0] - qb.u[0]) : 0; 
  72. qu.u[1] = (qa.u[1] > qb.u[1]) ? (qa.u[1] - qb.u[1]) : 0; 
  73. qu.u[2] = (qa.u[2] > qb.u[2]) ? (qa.u[2] - qb.u[2]) : 0; 
  74. qu.u[3] = (qa.u[3] > qb.u[3]) ? (qa.u[3] - qb.u[3]) : 0; 
  75. m_quad = qu.q;
  76. }
  77. inline void hkIntVector::setSubSaturateU16( hkIntVectorParameter a, hkIntVectorParameter b )
  78. {
  79. m_quad = _mm_subs_epu16(a.m_quad, b.m_quad);
  80. }
  81. //inline void hkIntVector::setSubS32( hkIntVectorParameter a, hkIntVectorParameter b )
  82. //{
  83. // m_quad = _mm_sub_epi32(a.m_quad, b.m_quad);
  84. //}
  85. //
  86. // Shift operations
  87. //
  88. template<int shift> inline void hkIntVector::setShiftLeft32( hkIntVectorParameter a)
  89. {
  90. m_quad =  _mm_slli_epi32( a.m_quad, shift);
  91. }
  92. template<int shift> inline void hkIntVector::setShiftRight32( hkIntVectorParameter a)
  93. {
  94. m_quad =  _mm_srli_epi32( a.m_quad, shift);
  95. }
  96. inline void hkIntVector::setShiftLeft32( hkIntVectorParameter a, hkIntVectorParameter shift )
  97. {
  98. // Not sure if it's faster to do this in scalar, or do a bunch of shuffles and 4 shifts
  99. hkQuadUintUnion qu, qa, qshift;
  100. qa.q = a;
  101. qshift.q = shift;
  102. qu.u[0] = qa.u[0] << qshift.u[0];
  103. qu.u[1] = qa.u[1] << qshift.u[1];
  104. qu.u[2] = qa.u[2] << qshift.u[2];
  105. qu.u[3] = qa.u[3] << qshift.u[3];
  106. m_quad = qu.q;
  107. /*m_quad = _mm_sll_epi32(a.m_quad, shift.m_quad);*/
  108. }
  109. inline void hkIntVector::setShiftRight32( hkIntVectorParameter a, hkIntVectorParameter shift )
  110. {
  111. hkQuadUintUnion qu, qa, qshift;
  112. qa.q = a;
  113. qshift.q = shift;
  114. qu.u[0] = qa.u[0] >> qshift.u[0];
  115. qu.u[1] = qa.u[1] >> qshift.u[1];
  116. qu.u[2] = qa.u[2] >> qshift.u[2];
  117. qu.u[3] = qa.u[3] >> qshift.u[3];
  118. m_quad = qu.q;
  119. //m_quad = _mm_srl_epi32(a.m_quad, shift.m_quad);
  120. }
  121. //
  122. // Merge operations
  123. // Stick to the convention that "high" means x,y, "low" means z,w
  124. //
  125. inline void hkIntVector::setMergeHigh32(hkIntVectorParameter a, hkIntVectorParameter b)
  126. {
  127. m_quad = _mm_unpacklo_epi32(a.m_quad, b.m_quad);
  128. }
  129. inline void hkIntVector::setMergeLow32(hkIntVectorParameter a, hkIntVectorParameter b)
  130. {
  131. m_quad = _mm_unpackhi_epi32(a.m_quad, b.m_quad);
  132. }
  133. inline void hkIntVector::setMergeHigh16(hkIntVectorParameter a, hkIntVectorParameter b)
  134. {
  135. m_quad = _mm_unpacklo_epi16(a.m_quad, b.m_quad);
  136. }
  137. inline void hkIntVector::setMergeLow16(hkIntVectorParameter a, hkIntVectorParameter b)
  138. {
  139. m_quad = _mm_unpackhi_epi16(a.m_quad, b.m_quad);
  140. }
  141. inline void hkIntVector::setMergeHigh8(hkIntVectorParameter a, hkIntVectorParameter b)
  142. {
  143. m_quad = _mm_unpacklo_epi8(a.m_quad, b.m_quad);
  144. }
  145. inline void hkIntVector::setMergeLow8(hkIntVectorParameter a, hkIntVectorParameter b)
  146. {
  147. m_quad = _mm_unpackhi_epi8(a.m_quad, b.m_quad);
  148. }
  149. //
  150. // Pack operations
  151. //
  152. inline void hkIntVector::setPackModuloU32( hkIntVectorParameter a, hkIntVectorParameter b )
  153. {
  154. hkQuadShortUnion qu, qa, qb;
  155. qa.q = a; qb.q = b;
  156. qu.u[0] = qa.u[1];
  157. qu.u[1] = qa.u[3];
  158. qu.u[2] = qa.u[5];
  159. qu.u[3] = qa.u[7];
  160. qu.u[4] = qb.u[1];
  161. qu.u[5] = qb.u[3];
  162. qu.u[6] = qb.u[5];
  163. qu.u[7] = qb.u[7];
  164. m_quad = qu.q;
  165. //m_quad = _mm_packs_epi32(a.m_quad, b.m_quad); // This does a signed saturate. NOT WHAT WE WANT!
  166. }
  167. //
  168. // Shuffle
  169. //
  170. template<int A, int B, int C, int D> HK_FORCE_INLINE void hkIntVector::setShuffle( hkIntVectorParameter a )
  171. {
  172. // Shuffle order is backwards of what one might expect!
  173. m_quad = _mm_shuffle_epi32( a.m_quad, _MM_SHUFFLE(D,C,B,A) );
  174. }
  175. //
  176. // Splat
  177. //
  178. template<int val> inline void hkIntVector::splatImmediate32()
  179. {
  180. // We don't need these for SSE, but they're to make sure that PPC code is compatible
  181. HK_COMPILE_TIME_ASSERT( val <=  15 );
  182. HK_COMPILE_TIME_ASSERT( val >= -16 );
  183. m_quad = _mm_set1_epi32(val);
  184. }
  185. template<int val> inline void hkIntVector::splatImmediate16()
  186. {
  187. HK_COMPILE_TIME_ASSERT( val <=  15 );
  188. HK_COMPILE_TIME_ASSERT( val >= -16 );
  189. m_quad = _mm_set1_epi16(val);
  190. }
  191. template<int val> inline void hkIntVector::splatImmediate8()
  192. {
  193. HK_ASSERT2(0x3be5dcf3, val >= -16 && val <= 15, "Invalid value for hkIntVector::splatImmediate8.");
  194. m_quad = _mm_set1_epi8(val);
  195. }
  196. template<int idx> inline void hkIntVector::setBroadcast(hkIntVectorParameter a)
  197. {
  198. m_quad = _mm_shuffle_epi32( a.m_quad, _MM_SHUFFLE(idx, idx, idx, idx) );
  199. }
  200. //
  201. // int <-> float conversion
  202. //
  203. // from Apple's Introduction to AltiVec/SSE Migration Guide
  204. // http://developer.apple.com/documentation/Performance/Conceptual/Accelerate_sse_migration/
  205. inline void hkIntVector::convertToF32fromU32(hkVector4& vOut) const
  206. {
  207. const hkQuadReal two16 = HK_QUADREAL_CONSTANT(1.0e16f, 1.0e16f, 1.0e16f, 1.0e16f);
  208. //Convert vUInt32 to vFloat according to the current rounding mode
  209. hkQuadUint v = m_quad;
  210. {
  211. // Avoid double rounding by doing two exact conversions
  212. // of high and low 16-bit segments
  213. hkQuadUint hi = _mm_srli_epi32( v, 16 );
  214. hkQuadUint lo = _mm_srli_epi32( _mm_slli_epi32(  v, 16 ), 16 );
  215. hkQuadReal fHi = _mm_mul_ps( _mm_cvtepi32_ps( hi ), two16);
  216. hkQuadReal fLo = _mm_cvtepi32_ps( lo );
  217. // do single rounding according to current rounding mode
  218. // note that AltiVec always uses round to nearest. We use current
  219. // rounding mode here, which is round to nearest by default.
  220. vOut.getQuad() =  _mm_add_ps( fHi, fLo );
  221. }
  222. }
  223. inline void hkIntVector::convertToF32fromS32(hkVector4& vOut) const
  224. {
  225. vOut.getQuad() = _mm_cvtepi32_ps(m_quad);
  226. }
  227. inline void hkIntVector::convertFromF32toU32(hkVector4Parameter vIn)
  228. {
  229. hkQuadUintUnion qu;
  230. qu.u[0] = (hkUint32) vIn(0);
  231. qu.u[1] = (hkUint32) vIn(1);
  232. qu.u[2] = (hkUint32) vIn(2);
  233. qu.u[3] = (hkUint32) vIn(3);
  234. m_quad = qu.q;
  235. }
  236. // The following functions are valid for all platforms (there wont' be many of these)
  237. inline void hkIntVector::loadAligned(const hkUint32* p)
  238. {
  239. HK_ASSERT2(0x70aae483, ((hkUlong)p & 0xf) == 0, "pointer for hkIntVector::loadAligned must be 16-byte aligned");
  240. m_quad = *reinterpret_cast<const hkQuadUint*>(p);
  241. }
  242. inline hkQuadUint& hkIntVector::getQuad()
  243. {
  244. return m_quad;
  245. }
  246. inline const hkQuadUint& hkIntVector::getQuad() const
  247. {
  248. return m_quad;
  249. }
  250. inline void hkIntVector::select32(hkIntVectorParameter a, hkIntVectorParameter b, hkVector4ComparisonParameter selectMask)
  251. {
  252. ((hkVector4*)(this))->select32( *(hkVector4*)(&a), *(hkVector4*)(&b), selectMask );
  253. }
  254. //
  255. /*
  256. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  257. * Confidential Information of Havok.  (C) Copyright 1999-2009
  258. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  259. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  260. * rights, and intellectual property rights in the Havok software remain in
  261. * Havok and/or its suppliers.
  262. * Use of this software for evaluation purposes is subject to and indicates
  263. * acceptance of the End User licence Agreement for this product. A copy of
  264. * the license is included with this software and is also available at www.havok.com/tryhavok.
  265. */