Simd_Generic.cpp (7741B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 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. 23 24 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. 25 26 =========================================================================== 27 */ 28 29 #pragma hdrstop 30 #include "../precompiled.h" 31 #include "Simd_Generic.h" 32 33 //=============================================================== 34 // 35 // Generic implementation of idSIMDProcessor 36 // 37 //=============================================================== 38 39 #define UNROLL1(Y) { int _IX; for (_IX=0;_IX<count;_IX++) {Y(_IX);} } 40 #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);}} 41 #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);}} 42 #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);} } 43 44 #ifdef _DEBUG 45 #define NODEFAULT default: assert( 0 ) 46 #else 47 #define NODEFAULT default: __assume( 0 ) 48 #endif 49 50 51 /* 52 ============ 53 idSIMD_Generic::GetName 54 ============ 55 */ 56 const char * idSIMD_Generic::GetName() const { 57 return "generic code"; 58 } 59 60 /* 61 ============ 62 idSIMD_Generic::MinMax 63 ============ 64 */ 65 void VPCALL idSIMD_Generic::MinMax( float &min, float &max, const float *src, const int count ) { 66 min = idMath::INFINITY; max = -idMath::INFINITY; 67 #define OPER(X) if ( src[(X)] < min ) {min = src[(X)];} if ( src[(X)] > max ) {max = src[(X)];} 68 UNROLL1(OPER) 69 #undef OPER 70 } 71 72 /* 73 ============ 74 idSIMD_Generic::MinMax 75 ============ 76 */ 77 void VPCALL idSIMD_Generic::MinMax( idVec2 &min, idVec2 &max, const idVec2 *src, const int count ) { 78 min[0] = min[1] = idMath::INFINITY; max[0] = max[1] = -idMath::INFINITY; 79 #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]; } 80 UNROLL1(OPER) 81 #undef OPER 82 } 83 84 /* 85 ============ 86 idSIMD_Generic::MinMax 87 ============ 88 */ 89 void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idVec3 *src, const int count ) { 90 min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; 91 #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]; } 92 UNROLL1(OPER) 93 #undef OPER 94 } 95 96 /* 97 ============ 98 idSIMD_Generic::MinMax 99 ============ 100 */ 101 void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const int count ) { 102 min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; 103 #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]; } 104 UNROLL1(OPER) 105 #undef OPER 106 } 107 108 /* 109 ============ 110 idSIMD_Generic::MinMax 111 ============ 112 */ 113 void VPCALL idSIMD_Generic::MinMax( idVec3 &min, idVec3 &max, const idDrawVert *src, const triIndex_t *indexes, const int count ) { 114 min[0] = min[1] = min[2] = idMath::INFINITY; max[0] = max[1] = max[2] = -idMath::INFINITY; 115 #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]; } 116 UNROLL1(OPER) 117 #undef OPER 118 } 119 120 /* 121 ================ 122 idSIMD_Generic::Memcpy 123 ================ 124 */ 125 void VPCALL idSIMD_Generic::Memcpy( void *dst, const void *src, const int count ) { 126 memcpy( dst, src, count ); 127 } 128 129 /* 130 ================ 131 idSIMD_Generic::Memset 132 ================ 133 */ 134 void VPCALL idSIMD_Generic::Memset( void *dst, const int val, const int count ) { 135 memset( dst, val, count ); 136 } 137 138 /* 139 ============ 140 idSIMD_Generic::BlendJoints 141 ============ 142 */ 143 void VPCALL idSIMD_Generic::BlendJoints( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { 144 for ( int i = 0; i < numJoints; i++ ) { 145 int j = index[i]; 146 joints[j].q.Slerp( joints[j].q, blendJoints[j].q, lerp ); 147 joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp ); 148 joints[j].w = 0.0f; 149 } 150 } 151 152 /* 153 ============ 154 idSIMD_Generic::BlendJointsFast 155 ============ 156 */ 157 void VPCALL idSIMD_Generic::BlendJointsFast( idJointQuat *joints, const idJointQuat *blendJoints, const float lerp, const int *index, const int numJoints ) { 158 for ( int i = 0; i < numJoints; i++ ) { 159 int j = index[i]; 160 joints[j].q.Lerp( joints[j].q, blendJoints[j].q, lerp ); 161 joints[j].t.Lerp( joints[j].t, blendJoints[j].t, lerp ); 162 joints[j].w = 0.0f; 163 } 164 } 165 166 /* 167 ============ 168 idSIMD_Generic::ConvertJointQuatsToJointMats 169 ============ 170 */ 171 void VPCALL idSIMD_Generic::ConvertJointQuatsToJointMats( idJointMat *jointMats, const idJointQuat *jointQuats, const int numJoints ) { 172 for ( int i = 0; i < numJoints; i++ ) { 173 jointMats[i].SetRotation( jointQuats[i].q.ToMat3() ); 174 jointMats[i].SetTranslation( jointQuats[i].t ); 175 } 176 } 177 178 /* 179 ============ 180 idSIMD_Generic::ConvertJointMatsToJointQuats 181 ============ 182 */ 183 void VPCALL idSIMD_Generic::ConvertJointMatsToJointQuats( idJointQuat *jointQuats, const idJointMat *jointMats, const int numJoints ) { 184 for ( int i = 0; i < numJoints; i++ ) { 185 jointQuats[i] = jointMats[i].ToJointQuat(); 186 } 187 } 188 189 /* 190 ============ 191 idSIMD_Generic::TransformJoints 192 ============ 193 */ 194 void VPCALL idSIMD_Generic::TransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { 195 for ( int i = firstJoint; i <= lastJoint; i++ ) { 196 assert( parents[i] < i ); 197 jointMats[i] *= jointMats[parents[i]]; 198 } 199 } 200 201 /* 202 ============ 203 idSIMD_Generic::UntransformJoints 204 ============ 205 */ 206 void VPCALL idSIMD_Generic::UntransformJoints( idJointMat *jointMats, const int *parents, const int firstJoint, const int lastJoint ) { 207 for ( int i = lastJoint; i >= firstJoint; i-- ) { 208 assert( parents[i] < i ); 209 jointMats[i] /= jointMats[parents[i]]; 210 } 211 }