Simd_Generic.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code 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. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #pragma hdrstop
  21. #include "../precompiled.h"
  22. #include "Simd_Generic.h"
  23. //===============================================================
  24. //
  25. // Generic implementation of idSIMDProcessor
  26. //
  27. //===============================================================
  28. #define UNROLL1(Y) { int _IX; for (_IX=0;_IX<count;_IX++) {Y(_IX);} }
  29. #define UNROLL2(Y) { int _IX, _NM = count&0xfffffffe; for (_IX=0;_IX<_NM;_IX+=2){Y(_IX+0);Y(_IX+1);} if (_IX < count) {Y(_IX);}}
  30. #define UNROLL4(Y) { int _IX, _NM = count&0xfffffffc; for (_IX=0;_IX<_NM;_IX+=4){Y(_IX+0);Y(_IX+1);Y(_IX+2);Y(_IX+3);}for(;_IX<count;_IX++){Y(_IX);}}
  31. #define UNROLL8(Y) { int _IX, _NM = count&0xfffffff8; for (_IX=0;_IX<_NM;_IX+=8){Y(_IX+0);Y(_IX+1);Y(_IX+2);Y(_IX+3);Y(_IX+4);Y(_IX+5);Y(_IX+6);Y(_IX+7);} _NM = count&0xfffffffe; for(;_IX<_NM;_IX+=2){Y(_IX); Y(_IX+1);} if (_IX < count) {Y(_IX);} }
  32. #ifdef _DEBUG
  33. #define NODEFAULT default: assert( 0 )
  34. #else
  35. #define NODEFAULT default: __assume( 0 )
  36. #endif
  37. /*
  38. ============
  39. idSIMD_Generic::GetName
  40. ============
  41. */
  42. const char * idSIMD_Generic::GetName() const {
  43. return "generic code";
  44. }
  45. /*
  46. ============
  47. idSIMD_Generic::MinMax
  48. ============
  49. */
  50. void VPCALL idSIMD_Generic::MinMax( float &min, float &max, const float *src, const int count ) {
  51. min = idMath::INFINITY; max = -idMath::INFINITY;
  52. #define OPER(X) if ( src[(X)] < min ) {min = src[(X)];} if ( src[(X)] > max ) {max = src[(X)];}
  53. UNROLL1(OPER)
  54. #undef OPER
  55. }
  56. /*
  57. ============
  58. idSIMD_Generic::MinMax
  59. ============
  60. */
  61. void VPCALL idSIMD_Generic::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) {
  62. min[0] = min[1] = idMath::INFINITY; max[0] = max[1] = -idMath::INFINITY;
  63. #define OPER(X) const idVec2 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; }
  64. UNROLL1(OPER)
  65. #undef OPER
  66. }
  67. /*
  68. ============
  69. idSIMD_Generic::MinMax
  70. ============
  71. */
  72. void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) {
  73. min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY;
  74. #define OPER(X) const idVec3 &v = src[(X)]; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; }
  75. UNROLL1(OPER)
  76. #undef OPER
  77. }
  78. /*
  79. ============
  80. idSIMD_Generic::MinMax
  81. ============
  82. */
  83. void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) {
  84. min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY;
  85. #define OPER(X) const idVec3 &v = src[(X)].xyz; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; }
  86. UNROLL1(OPER)
  87. #undef OPER
  88. }
  89. /*
  90. ============
  91. idSIMD_Generic::MinMax
  92. ============
  93. */
  94. void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const triIndex_t *indexes, const int count ) {
  95. min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY;
  96. #define OPER(X) const idVec3 &v = src[indexes[(X)]].xyz; if ( v[0] < min[0] ) { min[0] = v[0]; } if ( v[0] > max[0] ) { max[0] = v[0]; } if ( v[1] < min[1] ) { min[1] = v[1]; } if ( v[1] > max[1] ) { max[1] = v[1]; } if ( v[2] < min[2] ) { min[2] = v[2]; } if ( v[2] > max[2] ) { max[2] = v[2]; }
  97. UNROLL1(OPER)
  98. #undef OPER
  99. }
  100. /*
  101. ================
  102. idSIMD_Generic::Memcpy
  103. ================
  104. */
  105. void VPCALL idSIMD_Generic::Memcpy( void *dst, const void *src, const int count ) {
  106. memcpy( dst, src, count );
  107. }
  108. /*
  109. ================
  110. idSIMD_Generic::Memset
  111. ================
  112. */
  113. void VPCALL idSIMD_Generic::Memset( void *dst, const int val, const int count ) {
  114. memset( dst, val, count );
  115. }
  116. /*
  117. ============
  118. idSIMD_Generic::BlendJoints
  119. ============
  120. */
  121. void VPCALL idSIMD_Generic::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) {
  122. for ( int i = 0; i < numJoints; i++ ) {
  123. int j = index[i];
  124. joints[j].q.Slerp( joints[j].q, blendJoints[j].q, lerp );
  125. joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp );
  126. joints[j].w = 0.0f;
  127. }
  128. }
  129. /*
  130. ============
  131. idSIMD_Generic::BlendJointsFast
  132. ============
  133. */
  134. void VPCALL idSIMD_Generic::BlendJointsFast( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) {
  135. for ( int i = 0; i < numJoints; i++ ) {
  136. int j = index[i];
  137. joints[j].q.Lerp( joints[j].q, blendJoints[j].q, lerp );
  138. joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp );
  139. joints[j].w = 0.0f;
  140. }
  141. }
  142. /*
  143. ============
  144. idSIMD_Generic::ConvertJointQuatsToJointMats
  145. ============
  146. */
  147. void VPCALL idSIMD_Generic::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) {
  148. for ( int i = 0; i < numJoints; i++ ) {
  149. jointMats[i].SetRotation( jointQuats[i].q.ToMat3() );
  150. jointMats[i].SetTranslation( jointQuats[i].t );
  151. }
  152. }
  153. /*
  154. ============
  155. idSIMD_Generic::ConvertJointMatsToJointQuats
  156. ============
  157. */
  158. void VPCALL idSIMD_Generic::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) {
  159. for ( int i = 0; i < numJoints; i++ ) {
  160. jointQuats[i] = jointMats[i].ToJointQuat();
  161. }
  162. }
  163. /*
  164. ============
  165. idSIMD_Generic::TransformJoints
  166. ============
  167. */
  168. void VPCALL idSIMD_Generic::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) {
  169. for ( int i = firstJoint; i <= lastJoint; i++ ) {
  170. assert( parents[i] < i );
  171. jointMats[i] *= jointMats[parents[i]];
  172. }
  173. }
  174. /*
  175. ============
  176. idSIMD_Generic::UntransformJoints
  177. ============
  178. */
  179. void VPCALL idSIMD_Generic::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) {
  180. for ( int i = lastJoint; i >= firstJoint; i-- ) {
  181. assert( parents[i] < i );
  182. jointMats[i] /= jointMats[parents[i]];
  183. }
  184. }