14 #ifndef __MUDBOXSDK_SSE_H__
15 #define __MUDBOXSDK_SSE_H__
26 #error This file was intended to compiled with SSE3 instruction set enabled.
34 #include <xmmintrin.h>
35 #include <pmmintrin.h>
38 #if defined(WIN32) || defined(WIN64)
39 #include <xmmintrin.h>
43 #ifndef MB_SSE_ALIGN16_VAR
46 #define MB_SSE_ALIGN16_VAR(v) __declspec(align(16)) v
47 #define MB_SSE_ALIGN16_CLASS __declspec(align(16))
49 #define __attribute__(_a)
51 #elif defined(__GNUC__)
52 #define MB_SSE_ALIGN16_VAR(v) v __attribute__ ((aligned(16)))
53 #define MB_SSE_ALIGN16_CLASS __attribute__ ((aligned(16)))
55 #define __forceinline inline
58 #error The MB_SSE_ALIGN16_VAR needs to be ported for this compiler.
66 inline HWVector(
void ) __attribute__((always_inline)){};
68 inline void setZero(
void ) __attribute__((always_inline))
73 inline HWVector(
float f ) __attribute__((always_inline))
80 v = _mm_set_ps(
h.x,
h.y,
h.z, 0);
82 inline HWVector(
float x,
float y,
float z,
float w = 0 ) __attribute__((always_inline))
84 v = _mm_set_ps( x,y,z,
w );
87 inline HWVector(
const float a[4] ) __attribute__((always_inline))
89 v = _mm_loadu_ps(
a );
92 inline void ShiftLeft(
HWVector &result) __attribute__((always_inline)){ result.v = _mm_shuffle_ps(
v,
v,_MM_SHUFFLE(2,1,3,0)); }
93 inline void ShiftLeftInPlace() __attribute__((always_inline)){
v = _mm_shuffle_ps(
v,
v,_MM_SHUFFLE(2,1,3,0)); }
95 inline void ShiftRight(
HWVector &result ) __attribute__((always_inline)){ result.v = _mm_shuffle_ps(
v,
v,_MM_SHUFFLE(1,3,2,0)); };
111 r.v = _mm_mul_ps(
v, o.v );
113 r.v = _mm_hadd_ps( r.v, r.v );
114 r.v = _mm_hadd_ps( r.v, r.v );
121 r.v = _mm_sqrt_ss( r.v );
138 float fDistance = (d|(*this))-(d|vStart);
139 return fDistance>0?fDistance:(-fDistance);
142 inline void Normalize(
void ) __attribute__((always_inline))
145 f.v = _mm_rsqrt_ps( f.v );
146 v = _mm_mul_ps( f.v,
v );
151 static const unsigned int a = (1 << 23);
152 static const float twoTo23AsFloat = (float)a;
153 static const __m128 twoTo23 = _mm_set_ps( twoTo23AsFloat, twoTo23AsFloat, twoTo23AsFloat, twoTo23AsFloat );
155 __m128
b = _mm_castsi128_ps(_mm_srli_epi32( _mm_slli_epi32( _mm_castps_si128(
v),1 ), 1 ));
157 __m128 d = _mm_sub_ps( _mm_add_ps( _mm_add_ps( _mm_sub_ps(
v, twoTo23 ), twoTo23 ), twoTo23 ), twoTo23 );
159 __m128 largeMaskE = _mm_cmpgt_ps( b, twoTo23 );
161 __m128
g = _mm_cmplt_ps(
v, d );
163 __m128
h = _mm_cvtepi32_ps( _mm_castps_si128(g) );
165 __m128
t = _mm_add_ps( d, h );
167 __m128
w = _mm_and_ps(
v, largeMaskE );
168 t = _mm_andnot_ps( largeMaskE, t );
170 vResult.v = _mm_or_ps( t, w );
179 inline void operator -=(
const HWVector &o ) __attribute__((always_inline)){
v = _mm_sub_ps(
v, o.v ); };
180 inline void operator *=(
const HWVector &o ) __attribute__((always_inline)){
v = _mm_mul_ps(
v, o.v ); };
181 inline void operator /=(
const HWVector &o ) __attribute__((always_inline)){
v = _mm_div_ps(
v, o.v ); };
185 inline void operator *=(
float f ) __attribute__((always_inline)){
v = _mm_mul_ps(
v, _mm_set1_ps(
f ) ); };
186 inline void Store(
float *
p ) __attribute__((always_inline)){ _mm_storeu_ps(
p,
v ); };
187 inline void Load(
float f ) __attribute__((always_inline)) {
v = _mm_set_ps1(
f ); };
194 static const MB_SSE_ALIGN16_VAR(
float c[4]) = { 32740.0f, 32740.0f, 32740.0f, 32740.0f };
196 __m128
f = _mm_load_ps( c );
197 f = _mm_mul_ps( f,
v );
198 __m128i i = _mm_cvtps_epi32( f );
199 _mm_storeu_si128( (__m128i *)pBuffer, i );
201 inline void StoreAsInt(
int *pBuffer )
const __attribute__((always_inline))
203 __m128i i = _mm_cvtps_epi32(
v );
204 _mm_storeu_si128( (__m128i *)pBuffer, i );
208 __m128i i = _mm_cvttps_epi32(
v );
209 _mm_storeu_si128( (__m128i *)pBuffer, i );
211 inline operator float(
void ) const __attribute__((always_inline))
213 MB_SSE_ALIGN16_VAR(
float f);
214 _mm_store_ss( &f,
v );
220 __m128
t = _mm_shuffle_ps(
v,
v, _MM_SHUFFLE(2,1,0,3) );
221 _mm_store_ss( &r.
x, t );
222 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
223 _mm_store_ss( &r.
y, t );
224 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
225 _mm_store_ss( &r.
z, t );
231 __m128
t = _mm_shuffle_ps(
v,
v, _MM_SHUFFLE(2,1,0,3) );
232 _mm_store_ss( &r.
x, t );
233 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
234 _mm_store_ss( &r.
y, t );
235 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
236 _mm_store_ss( &r.
z, t );
237 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
238 _mm_store_ss( &r.
w, t );
242 MB_SSE_ALIGN16_VAR(__m128
v);
247 __m128
t = _mm_shuffle_ps( r.v, r.v, _MM_SHUFFLE(2,1,0,3) );
248 _mm_store_ss( &v.
x, t );
249 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
250 _mm_store_ss( &v.
y, t );
251 t = _mm_shuffle_ps( t, t, _MM_SHUFFLE(2,1,0,3) );
252 _mm_store_ss( &v.
z, t );
267 inline HWMatrix(
void ) __attribute__((always_inline)){};
270 r0 = _mm_loadu_ps( &m._11 );
271 r1 = _mm_loadu_ps( &m._21 );
272 r2 = _mm_loadu_ps( &m._31 );
273 r3 = _mm_loadu_ps( &m._41 );
275 void MirrorX(
void ) __attribute__((always_inline))
277 r0 = _mm_shuffle_ps( r0, r0, _MM_SHUFFLE(0, 1, 2, 3) );
278 r1 = _mm_shuffle_ps( r1, r1, _MM_SHUFFLE(0, 1, 2, 3) );
279 r2 = _mm_shuffle_ps( r2, r2, _MM_SHUFFLE(0, 1, 2, 3) );
280 r3 = _mm_shuffle_ps( r3, r3, _MM_SHUFFLE(0, 1, 2, 3) );
289 __m128
v0 = _mm_shuffle_ps( v.v, v.v, _MM_SHUFFLE(3,3,3,3) );
290 __m128
v1 = _mm_shuffle_ps( v.v, v.v, _MM_SHUFFLE(2,2,2,2) );
291 __m128
v2 = _mm_shuffle_ps( v.v, v.v, _MM_SHUFFLE(1,1,1,1) );
292 __m128
v3 = _mm_load_ps( c );
294 __m128 a0 = _mm_mul_ps( v0, r0 );
295 __m128 a1 = _mm_mul_ps( v1, r1 );
296 __m128 a2 = _mm_mul_ps( v2, r2 );
297 __m128 a3 = _mm_mul_ps( v3, r3 );
299 __m128
r = _mm_add_ps( a0, _mm_add_ps( a1, _mm_add_ps( a2, a3 ) ) );
309 __m128
v0 = _mm_shuffle_ps(
v.v,
v.v, _MM_SHUFFLE(3,3,3,3) );
310 __m128
v1 = _mm_shuffle_ps(
v.v,
v.v, _MM_SHUFFLE(2,2,2,2) );
311 __m128
v2 = _mm_shuffle_ps(
v.v,
v.v, _MM_SHUFFLE(1,1,1,1) );
312 __m128
v3 = _mm_load_ps( c );
314 __m128 a0 = _mm_mul_ps( v0, r0 );
315 __m128 a1 = _mm_mul_ps( v1, r1 );
316 __m128 a2 = _mm_mul_ps( v2, r2 );
317 __m128 a3 = _mm_mul_ps( v3, r3 );
319 __m128
r = _mm_add_ps( a0, _mm_add_ps( a1, _mm_add_ps( a2, a3 ) ) );
320 __m128 d = _mm_shuffle_ps( r, r, _MM_SHUFFLE(3,3,3,3) );
323 z.v = _mm_div_ps( r, d );
HWVector LengthSquared(void) const __attribute__((always_inline))
GLdouble GLdouble GLdouble r
bool MBDLL_DECL hasAVX256()
Query if AVX is available. present on Sandybridge.
const QPoint operator/(const QPoint &p, qreal c)
bool MBDLL_DECL hasSSE41()
Query if SSE4.1 is available. Present on Penryn (later Core 2)
HWVector(const float a[4]) __attribute__((always_inline))
Represents a 3D vector or point with S23E8 floating point elements.
HWVector Floor(void) __attribute__((always_inline))
This class represents a four dimensional vector stored in the SSE registers.
QByteArray & operator+=(QByteArray &a, const QStringBuilder< A, B > &b)
HWVector Length(void) const __attribute__((always_inline))
GLfloat GLfloat GLfloat v2
HWMatrix(void) __attribute__((always_inline))
HWVector Minimum(const HWVector &o) const __attribute__((always_inline))
mudbox::Vector & operator<<(mudbox::Vector &v, const HWVector &r)
HWVector(float x, float y, float z, float w=0) __attribute__((always_inline))
This class represents a four by four matrix stored in the SSE registers.
Q_CORE_EXPORT QBitArray operator&(const QBitArray &, const QBitArray &)
float DistanceFromLine(const HWVector &vStart, const HWVector &vEnd) const __attribute__((always_inline))
bool MBDLL_DECL hasSSE42()
Query if SSE4.2 is available. Present on Nehalem (Core i5, Corei7)
This class represents a 4x4 transformation matrix.
HWVector ShiftLeft(void) const __attribute__((always_inline))
HWVector(void) __attribute__((always_inline))
bool MBDLL_DECL hasSSE3()
Query if SSE3 is available. Present on Prescott, Core2 and later.
void ShiftRight(HWVector &result) __attribute__((always_inline))
A four dimensionsional vector (X, Y, Z, and W)
const QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
HWVector(const mudbox::Vector &h) __attribute__((always_inline))
HWVector ProjectedTransform(const HWVector &v) const __attribute__((always_inline))
void Normalize(void) __attribute__((always_inline))
void ShiftLeft(HWVector &result) __attribute__((always_inline))
MBDLL_DECL Vector operator*(float f, const Vector &v)
Multiplies a float scalar value by a vector, the result is a vector.
int int int int int int h
HWVector(float f) __attribute__((always_inline))
HWVector Maximum(const HWVector &o) const __attribute__((always_inline))
void setZero(void) __attribute__((always_inline))
GLubyte GLubyte GLubyte a
HWVector Transform(const HWVector &v, float w=1.0f) const __attribute__((always_inline))
const QPoint operator-(const QPoint &p1, const QPoint &p2)
void Store(float *p) __attribute__((always_inline))
void Load(float f) __attribute__((always_inline))
void MirrorX(void) __attribute__((always_inline))
MB_SSE_ALIGN16_VAR(__m128 r0)
void StoreAsIntTruncate(int *pBuffer) const __attribute__((always_inline))
Q_CORE_EXPORT QBitArray operator|(const QBitArray &, const QBitArray &)
GLubyte GLubyte GLubyte GLubyte w
HWVector ShiftRight(void) const __attribute__((always_inline))
GLfloat GLfloat GLfloat GLfloat v3
void ShiftLeftInPlace() __attribute__((always_inline))
HWMatrix(const mudbox::Matrix &m) __attribute__((always_inline))
void StoreNormalAsInt(int *pBuffer) const __attribute__((always_inline))
void StoreAsInt(int *pBuffer) const __attribute__((always_inline))