| ... | ... |
@@ -16,8 +16,7 @@ |
| 16 | 16 |
along with the this software. If not, see <http://www.gnu.org/licenses/>. |
| 17 | 17 |
*/ |
| 18 | 18 |
|
| 19 |
-#ifndef MATRIX_H |
|
| 20 |
-#define MATRIX_H |
|
| 19 |
+#pragma once |
|
| 21 | 20 |
|
| 22 | 21 |
#include <cmath> |
| 23 | 22 |
#include <cstring> |
| ... | ... |
@@ -62,5 +61,3 @@ inline int32_t s32floor(double d) |
| 62 | 61 |
{
|
| 63 | 62 |
return s32floor(static_cast<float>(d)); |
| 64 | 63 |
} |
| 65 |
- |
|
| 66 |
-#endif |
| ... | ... |
@@ -21,319 +21,46 @@ |
| 21 | 21 |
|
| 22 | 22 |
#include <cmath> |
| 23 | 23 |
#include <cstring> |
| 24 |
- |
|
| 25 | 24 |
#include "types.h" |
| 26 | 25 |
#include "mem.h" |
| 27 | 26 |
|
| 28 |
-/*#ifdef __SSE__ |
|
| 29 |
-#include <xmmintrin.h> |
|
| 30 |
-#endif*/ |
|
| 31 |
- |
|
| 32 | 27 |
#ifdef __SSE2__ |
| 33 | 28 |
#include <emmintrin.h> |
| 34 | 29 |
#endif |
| 35 | 30 |
|
| 36 |
-/*struct MatrixStack |
|
| 37 |
-{
|
|
| 38 |
- MatrixStack(int size, int type); |
|
| 39 |
- int32_t *matrix; |
|
| 40 |
- int32_t position; |
|
| 41 |
- int32_t size; |
|
| 42 |
- uint8_t type; |
|
| 43 |
-};*/ |
|
| 44 |
- |
|
| 45 |
-//void MatrixInit(float *matrix); |
|
| 46 |
-//void MatrixInit(int32_t *matrix); |
|
| 47 |
- |
|
| 48 |
-//In order to conditionally use these asm optimized functions in visual studio |
|
| 49 |
-//without having to make new build types to exclude the assembly files. |
|
| 50 |
-//a bit sloppy, but there aint much to it |
|
| 51 |
- |
|
| 52 |
-//float MatrixGetMultipliedIndex (int index, float *matrix, float *rightMatrix); |
|
| 53 |
-//int32_t MatrixGetMultipliedIndex (int index, int32_t *matrix, int32_t *rightMatrix); |
|
| 54 |
-//void MatrixSet (float *matrix, int x, int y, float value); |
|
| 55 |
-//void MatrixCopy (float * matrixDST, const float * matrixSRC); |
|
| 56 |
-//void MatrixCopy (int32_t * matrixDST, const int32_t * matrixSRC); |
|
| 57 |
-//int MatrixCompare (const float * matrixDST, const float * matrixSRC); |
|
| 58 |
-//void MatrixIdentity (float *matrix); |
|
| 59 |
-//void MatrixIdentity (int32_t *matrix); |
|
| 60 |
- |
|
| 61 |
-//void MatrixTranspose (float *matrix); |
|
| 62 |
-//void MatrixStackInit (MatrixStack *stack); |
|
| 63 |
-//void MatrixStackSetMaxSize (MatrixStack *stack, int size); |
|
| 64 |
-//void MatrixStackPushMatrix (MatrixStack *stack, const int32_t *ptr); |
|
| 65 |
-//void MatrixStackPopMatrix (int32_t *mtxCurr, MatrixStack *stack, int size); |
|
| 66 |
-//int32_t* MatrixStackGetPos (MatrixStack *stack, int pos); |
|
| 67 |
-//int32_t* MatrixStackGet (MatrixStack *stack); |
|
| 68 |
-//void MatrixStackLoadMatrix (MatrixStack *stack, int pos, const int32_t *ptr); |
|
| 69 |
- |
|
| 70 |
-//void Vector2Copy(float *dst, const float *src); |
|
| 71 |
-//void Vector2Add(float *dst, const float *src); |
|
| 72 |
-//void Vector2Subtract(float *dst, const float *src); |
|
| 73 |
-//float Vector2Dot(const float *a, const float *b); |
|
| 74 |
-//float Vector2Cross(const float *a, const float *b); |
|
| 75 |
- |
|
| 76 |
-//float Vector3Dot(const float *a, const float *b); |
|
| 77 |
-//void Vector3Cross(float* dst, const float *a, const float *b); |
|
| 78 |
-//float Vector3Length(const float *a); |
|
| 79 |
-//void Vector3Add(float *dst, const float *src); |
|
| 80 |
-//void Vector3Subtract(float *dst, const float *src); |
|
| 81 |
-//void Vector3Scale(float *dst, const float scale); |
|
| 82 |
-//void Vector3Copy(float *dst, const float *src); |
|
| 83 |
-//void Vector3Normalize(float *dst); |
|
| 84 |
- |
|
| 85 |
-//void Vector4Copy(float *dst, const float *src); |
|
| 86 |
- |
|
| 87 |
-//these functions are an unreliable, inaccurate floor. |
|
| 88 |
-//it should only be used for positive numbers |
|
| 89 |
-//this isnt as fast as it could be if we used a visual c++ intrinsic, but those appear not to be universally available |
|
| 31 |
+// these functions are an unreliable, inaccurate floor. |
|
| 32 |
+// it should only be used for positive numbers |
|
| 33 |
+// this isnt as fast as it could be if we used a visual c++ intrinsic, but those appear not to be universally available |
|
| 90 | 34 |
inline uint32_t u32floor(float f) |
| 91 | 35 |
{
|
| 92 | 36 |
#ifdef __SSE2__ |
| 93 |
- return (uint32_t)_mm_cvtt_ss2si(_mm_set_ss(f)); |
|
| 37 |
+ return static_cast<uint32_t>(_mm_cvtt_ss2si(_mm_set_ss(f))); |
|
| 94 | 38 |
#else |
| 95 |
- return (uint32_t)f; |
|
| 39 |
+ return static_cast<uint32_t>(f); |
|
| 96 | 40 |
#endif |
| 97 | 41 |
} |
| 98 | 42 |
inline uint32_t u32floor(double d) |
| 99 | 43 |
{
|
| 100 | 44 |
#ifdef __SSE2__ |
| 101 |
- return (uint32_t)_mm_cvttsd_si32(_mm_set_sd(d)); |
|
| 45 |
+ return static_cast<uint32_t>(_mm_cvttsd_si32(_mm_set_sd(d))); |
|
| 102 | 46 |
#else |
| 103 |
- return (uint32_t)d; |
|
| 47 |
+ return static_cast<uint32_t>(d); |
|
| 104 | 48 |
#endif |
| 105 | 49 |
} |
| 106 | 50 |
|
| 107 |
-//same as above but works for negative values too. |
|
| 108 |
-//be sure that the results are the same thing as floorf! |
|
| 51 |
+// same as above but works for negative values too. |
|
| 52 |
+// be sure that the results are the same thing as floorf! |
|
| 109 | 53 |
inline int32_t s32floor(float f) |
| 110 | 54 |
{
|
| 111 | 55 |
#ifdef __SSE2__ |
| 112 |
- return _mm_cvtss_si32( _mm_add_ss(_mm_set_ss(-0.5f),_mm_add_ss(_mm_set_ss(f), _mm_set_ss(f))) ) >> 1; |
|
| 56 |
+ return _mm_cvtss_si32(_mm_add_ss(_mm_set_ss(-0.5f),_mm_add_ss(_mm_set_ss(f), _mm_set_ss(f)))) >> 1; |
|
| 113 | 57 |
#else |
| 114 |
- return (int32_t)floorf(f); |
|
| 58 |
+ return static_cast<int32_t>(floorf(f)); |
|
| 115 | 59 |
#endif |
| 116 | 60 |
} |
| 117 | 61 |
inline int32_t s32floor(double d) |
| 118 | 62 |
{
|
| 119 |
- return s32floor((float)d); |
|
| 63 |
+ return s32floor(static_cast<float>(d)); |
|
| 120 | 64 |
} |
| 121 | 65 |
|
| 122 |
-//switched SSE2 functions |
|
| 123 |
-//------------- |
|
| 124 |
-#ifdef __SSE2__ |
|
| 125 |
- |
|
| 126 |
-/*template<int NUM> |
|
| 127 |
-inline void memset_u16_le(void* dst, uint16_t val) |
|
| 128 |
-{
|
|
| 129 |
- uint32_t u32val; |
|
| 130 |
- //just for the endian safety |
|
| 131 |
- T1WriteWord((uint8_t*)&u32val,0,val); |
|
| 132 |
- T1WriteWord((uint8_t*)&u32val,2,val); |
|
| 133 |
- ////const __m128i temp = _mm_set_epi32(u32val,u32val,u32val,u32val); |
|
| 134 |
- |
|
| 135 |
-#if defined(__GNUC__) || defined(__INTEL_COMPILER) |
|
| 136 |
- const __m128i temp = _mm_set_epi32(u32val,u32val,u32val,u32val); |
|
| 137 |
- MACRODO_N(NUM/8,_mm_store_si128((__m128i*)((uint8_t*)dst+(X)*16), temp)); |
|
| 138 |
-#else |
|
| 139 |
- __m128 temp; temp.m128_i32[0] = u32val; |
|
| 140 |
- //MACRODO_N(NUM/8,_mm_store_si128((__m128i*)((uint8_t*)dst+(X)*16), temp)); |
|
| 141 |
- MACRODO_N(NUM/8,_mm_store_ps1((float*)((uint8_t*)dst+(X)*16), temp)); |
|
| 142 |
-#endif |
|
| 143 |
-}*/ |
|
| 144 |
- |
|
| 145 |
-#else //no sse2 |
|
| 146 |
- |
|
| 147 |
-/*template<int NUM> |
|
| 148 |
-static inline void memset_u16_le(void* dst, uint16_t val) |
|
| 149 |
-{
|
|
| 150 |
- for(int i=0;i<NUM;i++) |
|
| 151 |
- T1WriteWord((uint8_t*)dst,i<<1,val); |
|
| 152 |
-}*/ |
|
| 153 |
- |
|
| 154 |
-#endif |
|
| 155 |
- |
|
| 156 |
-// NOSSE version always used in gfx3d.cpp |
|
| 157 |
-//void _NOSSE_MatrixMultVec4x4 (const float *matrix, float *vecPtr); |
|
| 158 |
-//void MatrixMultVec3x3_fixed(const int32_t *matrix, int32_t *vecPtr); |
|
| 159 |
- |
|
| 160 |
-//--------------------------- |
|
| 161 |
-//switched SSE functions |
|
| 162 |
-#ifdef __SSE__ |
|
| 163 |
- |
|
| 164 |
-/*struct SSE_MATRIX |
|
| 165 |
-{
|
|
| 166 |
- SSE_MATRIX(const float *matrix) |
|
| 167 |
- : row0(_mm_load_ps(matrix)) |
|
| 168 |
- , row1(_mm_load_ps(matrix+4)) |
|
| 169 |
- , row2(_mm_load_ps(matrix+8)) |
|
| 170 |
- , row3(_mm_load_ps(matrix+12)) |
|
| 171 |
- {}
|
|
| 172 |
- |
|
| 173 |
- union {
|
|
| 174 |
- __m128 rows[4]; |
|
| 175 |
- struct { __m128 row0; __m128 row1; __m128 row2; __m128 row3; };
|
|
| 176 |
- }; |
|
| 177 |
- |
|
| 178 |
-};*/ |
|
| 179 |
- |
|
| 180 |
-/*inline __m128 _util_MatrixMultVec4x4_(const SSE_MATRIX &mat, __m128 vec) |
|
| 181 |
-{
|
|
| 182 |
- __m128 xmm5 = _mm_shuffle_ps(vec, vec, B8(01010101)); |
|
| 183 |
- __m128 xmm6 = _mm_shuffle_ps(vec, vec, B8(10101010)); |
|
| 184 |
- __m128 xmm7 = _mm_shuffle_ps(vec, vec, B8(11111111)); |
|
| 185 |
- __m128 xmm4 = _mm_shuffle_ps(vec, vec, B8(00000000)); |
|
| 186 |
- |
|
| 187 |
- xmm4 = _mm_mul_ps(xmm4,mat.row0); |
|
| 188 |
- xmm5 = _mm_mul_ps(xmm5,mat.row1); |
|
| 189 |
- xmm6 = _mm_mul_ps(xmm6,mat.row2); |
|
| 190 |
- xmm7 = _mm_mul_ps(xmm7,mat.row3); |
|
| 191 |
- xmm4 = _mm_add_ps(xmm4,xmm5); |
|
| 192 |
- xmm4 = _mm_add_ps(xmm4,xmm6); |
|
| 193 |
- xmm4 = _mm_add_ps(xmm4,xmm7); |
|
| 194 |
- return xmm4; |
|
| 195 |
-}*/ |
|
| 196 |
- |
|
| 197 |
-/*inline void MatrixMultiply(float * matrix, const float * rightMatrix) |
|
| 198 |
-{
|
|
| 199 |
- //this seems to generate larger code, including many movaps, but maybe it is less harsh on the registers than the |
|
| 200 |
- //more hand-tailored approach |
|
| 201 |
- __m128 row0 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix)); |
|
| 202 |
- __m128 row1 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix+4)); |
|
| 203 |
- __m128 row2 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix+8)); |
|
| 204 |
- __m128 row3 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix+12)); |
|
| 205 |
- _mm_store_ps(matrix,row0); |
|
| 206 |
- _mm_store_ps(matrix+4,row1); |
|
| 207 |
- _mm_store_ps(matrix+8,row2); |
|
| 208 |
- _mm_store_ps(matrix+12,row3); |
|
| 209 |
-}*/ |
|
| 210 |
- |
|
| 211 |
- |
|
| 212 |
- |
|
| 213 |
-/*inline void MatrixMultVec4x4(const float *matrix, float *vecPtr) |
|
| 214 |
-{
|
|
| 215 |
- _mm_store_ps(vecPtr,_util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(vecPtr))); |
|
| 216 |
-}*/ |
|
| 217 |
- |
|
| 218 |
-/*inline void MatrixMultVec4x4_M2(const float *matrix, float *vecPtr) |
|
| 219 |
-{
|
|
| 220 |
- //there are hardly any gains from merging these manually |
|
| 221 |
- MatrixMultVec4x4(matrix+16,vecPtr); |
|
| 222 |
- MatrixMultVec4x4(matrix,vecPtr); |
|
| 223 |
-}*/ |
|
| 224 |
- |
|
| 225 |
-/*inline void MatrixMultVec3x3(const float * matrix, float * vecPtr) |
|
| 226 |
-{
|
|
| 227 |
- const __m128 vec = _mm_load_ps(vecPtr); |
|
| 228 |
- |
|
| 229 |
- __m128 xmm5 = _mm_shuffle_ps(vec, vec, B8(01010101)); |
|
| 230 |
- __m128 xmm6 = _mm_shuffle_ps(vec, vec, B8(10101010)); |
|
| 231 |
- __m128 xmm4 = _mm_shuffle_ps(vec, vec, B8(00000000)); |
|
| 232 |
- |
|
| 233 |
- const SSE_MATRIX mat(matrix); |
|
| 234 |
- |
|
| 235 |
- xmm4 = _mm_mul_ps(xmm4,mat.row0); |
|
| 236 |
- xmm5 = _mm_mul_ps(xmm5,mat.row1); |
|
| 237 |
- xmm6 = _mm_mul_ps(xmm6,mat.row2); |
|
| 238 |
- xmm4 = _mm_add_ps(xmm4,xmm5); |
|
| 239 |
- xmm4 = _mm_add_ps(xmm4,xmm6); |
|
| 240 |
- |
|
| 241 |
- _mm_store_ps(vecPtr,xmm4); |
|
| 242 |
-}*/ |
|
| 243 |
- |
|
| 244 |
-/*inline void MatrixTranslate(float *matrix, const float *ptr) |
|
| 245 |
-{
|
|
| 246 |
- __m128 xmm4 = _mm_load_ps(ptr); |
|
| 247 |
- __m128 xmm5 = _mm_shuffle_ps(xmm4, xmm4, B8(01010101)); |
|
| 248 |
- __m128 xmm6 = _mm_shuffle_ps(xmm4, xmm4, B8(10101010)); |
|
| 249 |
- xmm4 = _mm_shuffle_ps(xmm4, xmm4, B8(00000000)); |
|
| 250 |
- |
|
| 251 |
- xmm4 = _mm_mul_ps(xmm4,_mm_load_ps(matrix)); |
|
| 252 |
- xmm5 = _mm_mul_ps(xmm5,_mm_load_ps(matrix+4)); |
|
| 253 |
- xmm6 = _mm_mul_ps(xmm6,_mm_load_ps(matrix+8)); |
|
| 254 |
- xmm4 = _mm_add_ps(xmm4,xmm5); |
|
| 255 |
- xmm4 = _mm_add_ps(xmm4,xmm6); |
|
| 256 |
- xmm4 = _mm_add_ps(xmm4,_mm_load_ps(matrix+12)); |
|
| 257 |
- _mm_store_ps(matrix+12,xmm4); |
|
| 258 |
-}*/ |
|
| 259 |
- |
|
| 260 |
-/*inline void MatrixScale(float *matrix, const float *ptr) |
|
| 261 |
-{
|
|
| 262 |
- __m128 xmm4 = _mm_load_ps(ptr); |
|
| 263 |
- __m128 xmm5 = _mm_shuffle_ps(xmm4, xmm4, B8(01010101)); |
|
| 264 |
- __m128 xmm6 = _mm_shuffle_ps(xmm4, xmm4, B8(10101010)); |
|
| 265 |
- xmm4 = _mm_shuffle_ps(xmm4, xmm4, B8(00000000)); |
|
| 266 |
- |
|
| 267 |
- xmm4 = _mm_mul_ps(xmm4,_mm_load_ps(matrix)); |
|
| 268 |
- xmm5 = _mm_mul_ps(xmm5,_mm_load_ps(matrix+4)); |
|
| 269 |
- xmm6 = _mm_mul_ps(xmm6,_mm_load_ps(matrix+8)); |
|
| 270 |
- _mm_store_ps(matrix,xmm4); |
|
| 271 |
- _mm_store_ps(matrix+4,xmm5); |
|
| 272 |
- _mm_store_ps(matrix+8,xmm6); |
|
| 273 |
-}*/ |
|
| 274 |
- |
|
| 275 |
-/*template<int NUM_ROWS> |
|
| 276 |
-inline void vector_fix2float(float* matrix, const float divisor) |
|
| 277 |
-{
|
|
| 278 |
- CTASSERT(NUM_ROWS==3 || NUM_ROWS==4); |
|
| 279 |
- |
|
| 280 |
- const __m128 val = _mm_set_ps1(divisor); |
|
| 281 |
- |
|
| 282 |
- _mm_store_ps(matrix,_mm_div_ps(_mm_load_ps(matrix),val)); |
|
| 283 |
- _mm_store_ps(matrix+4,_mm_div_ps(_mm_load_ps(matrix+4),val)); |
|
| 284 |
- _mm_store_ps(matrix+8,_mm_div_ps(_mm_load_ps(matrix+8),val)); |
|
| 285 |
- if(NUM_ROWS==4) |
|
| 286 |
- _mm_store_ps(matrix+12,_mm_div_ps(_mm_load_ps(matrix+12),val)); |
|
| 287 |
-}*/ |
|
| 288 |
- |
|
| 289 |
-//WARNING: I do not think this is as fast as a memset, for some reason. |
|
| 290 |
-//at least in vc2005 with sse enabled. better figure out why before using it |
|
| 291 |
-/*template<int NUM> |
|
| 292 |
-static inline void memset_u8(void* _dst, uint8_t val) |
|
| 293 |
-{
|
|
| 294 |
- memset(_dst,val,NUM); |
|
| 295 |
- //const uint8_t* dst = (uint8_t*)_dst; |
|
| 296 |
- //uint32_t u32val = (val<<24)|(val<<16)|(val<<8)|val; |
|
| 297 |
- //const __m128i temp = _mm_set_epi32(u32val,u32val,u32val,u32val); |
|
| 298 |
- //MACRODO_N(NUM/16,_mm_store_si128((__m128i*)(dst+(X)*16), temp)); |
|
| 299 |
-}*/ |
|
| 300 |
- |
|
| 301 |
-#else //no sse |
|
| 302 |
- |
|
| 303 |
-//void MatrixMultVec4x4 (const float *matrix, float *vecPtr); |
|
| 304 |
-//void MatrixMultVec3x3(const float * matrix, float * vecPtr); |
|
| 305 |
-//void MatrixMultiply(float * matrix, const float * rightMatrix); |
|
| 306 |
-//void MatrixTranslate(float *matrix, const float *ptr); |
|
| 307 |
-//void MatrixScale(float * matrix, const float * ptr); |
|
| 308 |
- |
|
| 309 |
-/*inline void MatrixMultVec4x4_M2(const float *matrix, float *vecPtr) |
|
| 310 |
-{
|
|
| 311 |
- //there are hardly any gains from merging these manually |
|
| 312 |
- MatrixMultVec4x4(matrix+16,vecPtr); |
|
| 313 |
- MatrixMultVec4x4(matrix,vecPtr); |
|
| 314 |
-}*/ |
|
| 315 |
- |
|
| 316 |
-/*template<int NUM_ROWS> |
|
| 317 |
-inline void vector_fix2float(float* matrix, const float divisor) |
|
| 318 |
-{
|
|
| 319 |
- for(int i=0;i<NUM_ROWS*4;i++) |
|
| 320 |
- matrix[i] /= divisor; |
|
| 321 |
-}*/ |
|
| 322 |
- |
|
| 323 |
-/*template<int NUM> |
|
| 324 |
-static inline void memset_u8(void* dst, uint8_t val) |
|
| 325 |
-{
|
|
| 326 |
- memset(dst,val,NUM); |
|
| 327 |
-}*/ |
|
| 328 |
- |
|
| 329 |
-#endif //switched SSE functions |
|
| 330 |
- |
|
| 331 |
-//void MatrixMultVec4x4 (const int32_t *matrix, int32_t *vecPtr); |
|
| 332 |
- |
|
| 333 |
-//void MatrixMultVec4x4_M2(const int32_t *matrix, int32_t *vecPtr); |
|
| 334 |
- |
|
| 335 |
-//void MatrixMultiply(int32_t* matrix, const int32_t* rightMatrix); |
|
| 336 |
-//void MatrixScale(int32_t *matrix, const int32_t *ptr); |
|
| 337 |
-//void MatrixTranslate(int32_t *matrix, const int32_t *ptr); |
|
| 338 |
- |
|
| 339 | 66 |
#endif |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,339 @@ |
| 1 |
+/* |
|
| 2 |
+ Copyright (C) 2006-2007 shash |
|
| 3 |
+ Copyright (C) 2007-2012 DeSmuME team |
|
| 4 |
+ |
|
| 5 |
+ This file is free software: you can redistribute it and/or modify |
|
| 6 |
+ it under the terms of the GNU General Public License as published by |
|
| 7 |
+ the Free Software Foundation, either version 2 of the License, or |
|
| 8 |
+ (at your option) any later version. |
|
| 9 |
+ |
|
| 10 |
+ This file 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 |
+ |
|
| 15 |
+ You should have received a copy of the GNU General Public License |
|
| 16 |
+ along with the this software. If not, see <http://www.gnu.org/licenses/>. |
|
| 17 |
+*/ |
|
| 18 |
+ |
|
| 19 |
+#ifndef MATRIX_H |
|
| 20 |
+#define MATRIX_H |
|
| 21 |
+ |
|
| 22 |
+#include <cmath> |
|
| 23 |
+#include <cstring> |
|
| 24 |
+ |
|
| 25 |
+#include "types.h" |
|
| 26 |
+#include "mem.h" |
|
| 27 |
+ |
|
| 28 |
+/*#ifdef __SSE__ |
|
| 29 |
+#include <xmmintrin.h> |
|
| 30 |
+#endif*/ |
|
| 31 |
+ |
|
| 32 |
+#ifdef __SSE2__ |
|
| 33 |
+#include <emmintrin.h> |
|
| 34 |
+#endif |
|
| 35 |
+ |
|
| 36 |
+/*struct MatrixStack |
|
| 37 |
+{
|
|
| 38 |
+ MatrixStack(int size, int type); |
|
| 39 |
+ int32_t *matrix; |
|
| 40 |
+ int32_t position; |
|
| 41 |
+ int32_t size; |
|
| 42 |
+ uint8_t type; |
|
| 43 |
+};*/ |
|
| 44 |
+ |
|
| 45 |
+//void MatrixInit(float *matrix); |
|
| 46 |
+//void MatrixInit(int32_t *matrix); |
|
| 47 |
+ |
|
| 48 |
+//In order to conditionally use these asm optimized functions in visual studio |
|
| 49 |
+//without having to make new build types to exclude the assembly files. |
|
| 50 |
+//a bit sloppy, but there aint much to it |
|
| 51 |
+ |
|
| 52 |
+//float MatrixGetMultipliedIndex (int index, float *matrix, float *rightMatrix); |
|
| 53 |
+//int32_t MatrixGetMultipliedIndex (int index, int32_t *matrix, int32_t *rightMatrix); |
|
| 54 |
+//void MatrixSet (float *matrix, int x, int y, float value); |
|
| 55 |
+//void MatrixCopy (float * matrixDST, const float * matrixSRC); |
|
| 56 |
+//void MatrixCopy (int32_t * matrixDST, const int32_t * matrixSRC); |
|
| 57 |
+//int MatrixCompare (const float * matrixDST, const float * matrixSRC); |
|
| 58 |
+//void MatrixIdentity (float *matrix); |
|
| 59 |
+//void MatrixIdentity (int32_t *matrix); |
|
| 60 |
+ |
|
| 61 |
+//void MatrixTranspose (float *matrix); |
|
| 62 |
+//void MatrixStackInit (MatrixStack *stack); |
|
| 63 |
+//void MatrixStackSetMaxSize (MatrixStack *stack, int size); |
|
| 64 |
+//void MatrixStackPushMatrix (MatrixStack *stack, const int32_t *ptr); |
|
| 65 |
+//void MatrixStackPopMatrix (int32_t *mtxCurr, MatrixStack *stack, int size); |
|
| 66 |
+//int32_t* MatrixStackGetPos (MatrixStack *stack, int pos); |
|
| 67 |
+//int32_t* MatrixStackGet (MatrixStack *stack); |
|
| 68 |
+//void MatrixStackLoadMatrix (MatrixStack *stack, int pos, const int32_t *ptr); |
|
| 69 |
+ |
|
| 70 |
+//void Vector2Copy(float *dst, const float *src); |
|
| 71 |
+//void Vector2Add(float *dst, const float *src); |
|
| 72 |
+//void Vector2Subtract(float *dst, const float *src); |
|
| 73 |
+//float Vector2Dot(const float *a, const float *b); |
|
| 74 |
+//float Vector2Cross(const float *a, const float *b); |
|
| 75 |
+ |
|
| 76 |
+//float Vector3Dot(const float *a, const float *b); |
|
| 77 |
+//void Vector3Cross(float* dst, const float *a, const float *b); |
|
| 78 |
+//float Vector3Length(const float *a); |
|
| 79 |
+//void Vector3Add(float *dst, const float *src); |
|
| 80 |
+//void Vector3Subtract(float *dst, const float *src); |
|
| 81 |
+//void Vector3Scale(float *dst, const float scale); |
|
| 82 |
+//void Vector3Copy(float *dst, const float *src); |
|
| 83 |
+//void Vector3Normalize(float *dst); |
|
| 84 |
+ |
|
| 85 |
+//void Vector4Copy(float *dst, const float *src); |
|
| 86 |
+ |
|
| 87 |
+//these functions are an unreliable, inaccurate floor. |
|
| 88 |
+//it should only be used for positive numbers |
|
| 89 |
+//this isnt as fast as it could be if we used a visual c++ intrinsic, but those appear not to be universally available |
|
| 90 |
+inline uint32_t u32floor(float f) |
|
| 91 |
+{
|
|
| 92 |
+#ifdef __SSE2__ |
|
| 93 |
+ return (uint32_t)_mm_cvtt_ss2si(_mm_set_ss(f)); |
|
| 94 |
+#else |
|
| 95 |
+ return (uint32_t)f; |
|
| 96 |
+#endif |
|
| 97 |
+} |
|
| 98 |
+inline uint32_t u32floor(double d) |
|
| 99 |
+{
|
|
| 100 |
+#ifdef __SSE2__ |
|
| 101 |
+ return (uint32_t)_mm_cvttsd_si32(_mm_set_sd(d)); |
|
| 102 |
+#else |
|
| 103 |
+ return (uint32_t)d; |
|
| 104 |
+#endif |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+//same as above but works for negative values too. |
|
| 108 |
+//be sure that the results are the same thing as floorf! |
|
| 109 |
+inline int32_t s32floor(float f) |
|
| 110 |
+{
|
|
| 111 |
+#ifdef __SSE2__ |
|
| 112 |
+ return _mm_cvtss_si32( _mm_add_ss(_mm_set_ss(-0.5f),_mm_add_ss(_mm_set_ss(f), _mm_set_ss(f))) ) >> 1; |
|
| 113 |
+#else |
|
| 114 |
+ return (int32_t)floorf(f); |
|
| 115 |
+#endif |
|
| 116 |
+} |
|
| 117 |
+inline int32_t s32floor(double d) |
|
| 118 |
+{
|
|
| 119 |
+ return s32floor((float)d); |
|
| 120 |
+} |
|
| 121 |
+ |
|
| 122 |
+//switched SSE2 functions |
|
| 123 |
+//------------- |
|
| 124 |
+#ifdef __SSE2__ |
|
| 125 |
+ |
|
| 126 |
+/*template<int NUM> |
|
| 127 |
+inline void memset_u16_le(void* dst, uint16_t val) |
|
| 128 |
+{
|
|
| 129 |
+ uint32_t u32val; |
|
| 130 |
+ //just for the endian safety |
|
| 131 |
+ T1WriteWord((uint8_t*)&u32val,0,val); |
|
| 132 |
+ T1WriteWord((uint8_t*)&u32val,2,val); |
|
| 133 |
+ ////const __m128i temp = _mm_set_epi32(u32val,u32val,u32val,u32val); |
|
| 134 |
+ |
|
| 135 |
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) |
|
| 136 |
+ const __m128i temp = _mm_set_epi32(u32val,u32val,u32val,u32val); |
|
| 137 |
+ MACRODO_N(NUM/8,_mm_store_si128((__m128i*)((uint8_t*)dst+(X)*16), temp)); |
|
| 138 |
+#else |
|
| 139 |
+ __m128 temp; temp.m128_i32[0] = u32val; |
|
| 140 |
+ //MACRODO_N(NUM/8,_mm_store_si128((__m128i*)((uint8_t*)dst+(X)*16), temp)); |
|
| 141 |
+ MACRODO_N(NUM/8,_mm_store_ps1((float*)((uint8_t*)dst+(X)*16), temp)); |
|
| 142 |
+#endif |
|
| 143 |
+}*/ |
|
| 144 |
+ |
|
| 145 |
+#else //no sse2 |
|
| 146 |
+ |
|
| 147 |
+/*template<int NUM> |
|
| 148 |
+static inline void memset_u16_le(void* dst, uint16_t val) |
|
| 149 |
+{
|
|
| 150 |
+ for(int i=0;i<NUM;i++) |
|
| 151 |
+ T1WriteWord((uint8_t*)dst,i<<1,val); |
|
| 152 |
+}*/ |
|
| 153 |
+ |
|
| 154 |
+#endif |
|
| 155 |
+ |
|
| 156 |
+// NOSSE version always used in gfx3d.cpp |
|
| 157 |
+//void _NOSSE_MatrixMultVec4x4 (const float *matrix, float *vecPtr); |
|
| 158 |
+//void MatrixMultVec3x3_fixed(const int32_t *matrix, int32_t *vecPtr); |
|
| 159 |
+ |
|
| 160 |
+//--------------------------- |
|
| 161 |
+//switched SSE functions |
|
| 162 |
+#ifdef __SSE__ |
|
| 163 |
+ |
|
| 164 |
+/*struct SSE_MATRIX |
|
| 165 |
+{
|
|
| 166 |
+ SSE_MATRIX(const float *matrix) |
|
| 167 |
+ : row0(_mm_load_ps(matrix)) |
|
| 168 |
+ , row1(_mm_load_ps(matrix+4)) |
|
| 169 |
+ , row2(_mm_load_ps(matrix+8)) |
|
| 170 |
+ , row3(_mm_load_ps(matrix+12)) |
|
| 171 |
+ {}
|
|
| 172 |
+ |
|
| 173 |
+ union {
|
|
| 174 |
+ __m128 rows[4]; |
|
| 175 |
+ struct { __m128 row0; __m128 row1; __m128 row2; __m128 row3; };
|
|
| 176 |
+ }; |
|
| 177 |
+ |
|
| 178 |
+};*/ |
|
| 179 |
+ |
|
| 180 |
+/*inline __m128 _util_MatrixMultVec4x4_(const SSE_MATRIX &mat, __m128 vec) |
|
| 181 |
+{
|
|
| 182 |
+ __m128 xmm5 = _mm_shuffle_ps(vec, vec, B8(01010101)); |
|
| 183 |
+ __m128 xmm6 = _mm_shuffle_ps(vec, vec, B8(10101010)); |
|
| 184 |
+ __m128 xmm7 = _mm_shuffle_ps(vec, vec, B8(11111111)); |
|
| 185 |
+ __m128 xmm4 = _mm_shuffle_ps(vec, vec, B8(00000000)); |
|
| 186 |
+ |
|
| 187 |
+ xmm4 = _mm_mul_ps(xmm4,mat.row0); |
|
| 188 |
+ xmm5 = _mm_mul_ps(xmm5,mat.row1); |
|
| 189 |
+ xmm6 = _mm_mul_ps(xmm6,mat.row2); |
|
| 190 |
+ xmm7 = _mm_mul_ps(xmm7,mat.row3); |
|
| 191 |
+ xmm4 = _mm_add_ps(xmm4,xmm5); |
|
| 192 |
+ xmm4 = _mm_add_ps(xmm4,xmm6); |
|
| 193 |
+ xmm4 = _mm_add_ps(xmm4,xmm7); |
|
| 194 |
+ return xmm4; |
|
| 195 |
+}*/ |
|
| 196 |
+ |
|
| 197 |
+/*inline void MatrixMultiply(float * matrix, const float * rightMatrix) |
|
| 198 |
+{
|
|
| 199 |
+ //this seems to generate larger code, including many movaps, but maybe it is less harsh on the registers than the |
|
| 200 |
+ //more hand-tailored approach |
|
| 201 |
+ __m128 row0 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix)); |
|
| 202 |
+ __m128 row1 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix+4)); |
|
| 203 |
+ __m128 row2 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix+8)); |
|
| 204 |
+ __m128 row3 = _util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(rightMatrix+12)); |
|
| 205 |
+ _mm_store_ps(matrix,row0); |
|
| 206 |
+ _mm_store_ps(matrix+4,row1); |
|
| 207 |
+ _mm_store_ps(matrix+8,row2); |
|
| 208 |
+ _mm_store_ps(matrix+12,row3); |
|
| 209 |
+}*/ |
|
| 210 |
+ |
|
| 211 |
+ |
|
| 212 |
+ |
|
| 213 |
+/*inline void MatrixMultVec4x4(const float *matrix, float *vecPtr) |
|
| 214 |
+{
|
|
| 215 |
+ _mm_store_ps(vecPtr,_util_MatrixMultVec4x4_((SSE_MATRIX)matrix,_mm_load_ps(vecPtr))); |
|
| 216 |
+}*/ |
|
| 217 |
+ |
|
| 218 |
+/*inline void MatrixMultVec4x4_M2(const float *matrix, float *vecPtr) |
|
| 219 |
+{
|
|
| 220 |
+ //there are hardly any gains from merging these manually |
|
| 221 |
+ MatrixMultVec4x4(matrix+16,vecPtr); |
|
| 222 |
+ MatrixMultVec4x4(matrix,vecPtr); |
|
| 223 |
+}*/ |
|
| 224 |
+ |
|
| 225 |
+/*inline void MatrixMultVec3x3(const float * matrix, float * vecPtr) |
|
| 226 |
+{
|
|
| 227 |
+ const __m128 vec = _mm_load_ps(vecPtr); |
|
| 228 |
+ |
|
| 229 |
+ __m128 xmm5 = _mm_shuffle_ps(vec, vec, B8(01010101)); |
|
| 230 |
+ __m128 xmm6 = _mm_shuffle_ps(vec, vec, B8(10101010)); |
|
| 231 |
+ __m128 xmm4 = _mm_shuffle_ps(vec, vec, B8(00000000)); |
|
| 232 |
+ |
|
| 233 |
+ const SSE_MATRIX mat(matrix); |
|
| 234 |
+ |
|
| 235 |
+ xmm4 = _mm_mul_ps(xmm4,mat.row0); |
|
| 236 |
+ xmm5 = _mm_mul_ps(xmm5,mat.row1); |
|
| 237 |
+ xmm6 = _mm_mul_ps(xmm6,mat.row2); |
|
| 238 |
+ xmm4 = _mm_add_ps(xmm4,xmm5); |
|
| 239 |
+ xmm4 = _mm_add_ps(xmm4,xmm6); |
|
| 240 |
+ |
|
| 241 |
+ _mm_store_ps(vecPtr,xmm4); |
|
| 242 |
+}*/ |
|
| 243 |
+ |
|
| 244 |
+/*inline void MatrixTranslate(float *matrix, const float *ptr) |
|
| 245 |
+{
|
|
| 246 |
+ __m128 xmm4 = _mm_load_ps(ptr); |
|
| 247 |
+ __m128 xmm5 = _mm_shuffle_ps(xmm4, xmm4, B8(01010101)); |
|
| 248 |
+ __m128 xmm6 = _mm_shuffle_ps(xmm4, xmm4, B8(10101010)); |
|
| 249 |
+ xmm4 = _mm_shuffle_ps(xmm4, xmm4, B8(00000000)); |
|
| 250 |
+ |
|
| 251 |
+ xmm4 = _mm_mul_ps(xmm4,_mm_load_ps(matrix)); |
|
| 252 |
+ xmm5 = _mm_mul_ps(xmm5,_mm_load_ps(matrix+4)); |
|
| 253 |
+ xmm6 = _mm_mul_ps(xmm6,_mm_load_ps(matrix+8)); |
|
| 254 |
+ xmm4 = _mm_add_ps(xmm4,xmm5); |
|
| 255 |
+ xmm4 = _mm_add_ps(xmm4,xmm6); |
|
| 256 |
+ xmm4 = _mm_add_ps(xmm4,_mm_load_ps(matrix+12)); |
|
| 257 |
+ _mm_store_ps(matrix+12,xmm4); |
|
| 258 |
+}*/ |
|
| 259 |
+ |
|
| 260 |
+/*inline void MatrixScale(float *matrix, const float *ptr) |
|
| 261 |
+{
|
|
| 262 |
+ __m128 xmm4 = _mm_load_ps(ptr); |
|
| 263 |
+ __m128 xmm5 = _mm_shuffle_ps(xmm4, xmm4, B8(01010101)); |
|
| 264 |
+ __m128 xmm6 = _mm_shuffle_ps(xmm4, xmm4, B8(10101010)); |
|
| 265 |
+ xmm4 = _mm_shuffle_ps(xmm4, xmm4, B8(00000000)); |
|
| 266 |
+ |
|
| 267 |
+ xmm4 = _mm_mul_ps(xmm4,_mm_load_ps(matrix)); |
|
| 268 |
+ xmm5 = _mm_mul_ps(xmm5,_mm_load_ps(matrix+4)); |
|
| 269 |
+ xmm6 = _mm_mul_ps(xmm6,_mm_load_ps(matrix+8)); |
|
| 270 |
+ _mm_store_ps(matrix,xmm4); |
|
| 271 |
+ _mm_store_ps(matrix+4,xmm5); |
|
| 272 |
+ _mm_store_ps(matrix+8,xmm6); |
|
| 273 |
+}*/ |
|
| 274 |
+ |
|
| 275 |
+/*template<int NUM_ROWS> |
|
| 276 |
+inline void vector_fix2float(float* matrix, const float divisor) |
|
| 277 |
+{
|
|
| 278 |
+ CTASSERT(NUM_ROWS==3 || NUM_ROWS==4); |
|
| 279 |
+ |
|
| 280 |
+ const __m128 val = _mm_set_ps1(divisor); |
|
| 281 |
+ |
|
| 282 |
+ _mm_store_ps(matrix,_mm_div_ps(_mm_load_ps(matrix),val)); |
|
| 283 |
+ _mm_store_ps(matrix+4,_mm_div_ps(_mm_load_ps(matrix+4),val)); |
|
| 284 |
+ _mm_store_ps(matrix+8,_mm_div_ps(_mm_load_ps(matrix+8),val)); |
|
| 285 |
+ if(NUM_ROWS==4) |
|
| 286 |
+ _mm_store_ps(matrix+12,_mm_div_ps(_mm_load_ps(matrix+12),val)); |
|
| 287 |
+}*/ |
|
| 288 |
+ |
|
| 289 |
+//WARNING: I do not think this is as fast as a memset, for some reason. |
|
| 290 |
+//at least in vc2005 with sse enabled. better figure out why before using it |
|
| 291 |
+/*template<int NUM> |
|
| 292 |
+static inline void memset_u8(void* _dst, uint8_t val) |
|
| 293 |
+{
|
|
| 294 |
+ memset(_dst,val,NUM); |
|
| 295 |
+ //const uint8_t* dst = (uint8_t*)_dst; |
|
| 296 |
+ //uint32_t u32val = (val<<24)|(val<<16)|(val<<8)|val; |
|
| 297 |
+ //const __m128i temp = _mm_set_epi32(u32val,u32val,u32val,u32val); |
|
| 298 |
+ //MACRODO_N(NUM/16,_mm_store_si128((__m128i*)(dst+(X)*16), temp)); |
|
| 299 |
+}*/ |
|
| 300 |
+ |
|
| 301 |
+#else //no sse |
|
| 302 |
+ |
|
| 303 |
+//void MatrixMultVec4x4 (const float *matrix, float *vecPtr); |
|
| 304 |
+//void MatrixMultVec3x3(const float * matrix, float * vecPtr); |
|
| 305 |
+//void MatrixMultiply(float * matrix, const float * rightMatrix); |
|
| 306 |
+//void MatrixTranslate(float *matrix, const float *ptr); |
|
| 307 |
+//void MatrixScale(float * matrix, const float * ptr); |
|
| 308 |
+ |
|
| 309 |
+/*inline void MatrixMultVec4x4_M2(const float *matrix, float *vecPtr) |
|
| 310 |
+{
|
|
| 311 |
+ //there are hardly any gains from merging these manually |
|
| 312 |
+ MatrixMultVec4x4(matrix+16,vecPtr); |
|
| 313 |
+ MatrixMultVec4x4(matrix,vecPtr); |
|
| 314 |
+}*/ |
|
| 315 |
+ |
|
| 316 |
+/*template<int NUM_ROWS> |
|
| 317 |
+inline void vector_fix2float(float* matrix, const float divisor) |
|
| 318 |
+{
|
|
| 319 |
+ for(int i=0;i<NUM_ROWS*4;i++) |
|
| 320 |
+ matrix[i] /= divisor; |
|
| 321 |
+}*/ |
|
| 322 |
+ |
|
| 323 |
+/*template<int NUM> |
|
| 324 |
+static inline void memset_u8(void* dst, uint8_t val) |
|
| 325 |
+{
|
|
| 326 |
+ memset(dst,val,NUM); |
|
| 327 |
+}*/ |
|
| 328 |
+ |
|
| 329 |
+#endif //switched SSE functions |
|
| 330 |
+ |
|
| 331 |
+//void MatrixMultVec4x4 (const int32_t *matrix, int32_t *vecPtr); |
|
| 332 |
+ |
|
| 333 |
+//void MatrixMultVec4x4_M2(const int32_t *matrix, int32_t *vecPtr); |
|
| 334 |
+ |
|
| 335 |
+//void MatrixMultiply(int32_t* matrix, const int32_t* rightMatrix); |
|
| 336 |
+//void MatrixScale(int32_t *matrix, const int32_t *ptr); |
|
| 337 |
+//void MatrixTranslate(int32_t *matrix, const int32_t *ptr); |
|
| 338 |
+ |
|
| 339 |
+#endif |