DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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 }