Original Post
hi guys, i'm using SSE for vector calculation. but i failed and got access violation. the problematic line is this //EDIT: Fixed your code tags, you can read about how they work in the FAQ. - jba. [Edited by - jbadams on January 21, 2008 11:57:10 PM]
inline void operator+=(Vector& v1,const Vector& v2)
{
v1.data=_mm_add_ps(v1.data,v2.data);
}
i know that The memory the sse instructions access need to be 16-byte aligned. so i did do my own new and delete operations like this:
static void* operator new(size_t size)
{
void *p=_aligned_malloc(size,16);
return p;
};
static void operator delete (void *p)
{
_aligned_free(p);
}
i found a post here talking about the same problem, but no solution was given. http://www.devmaster.net/forums/archive/index.php/t-4995.html can any one tell me how to fix this? thank you very much.
class Vector
{
protected:
__m128 data;
public:
float getX()
{
return data.m128_f32[0];
};
float getY()
{
return data.m128_f32[1];
};
float getZ()
{
return data.m128_f32[2];
};
float getW()
{
return data.m128_f32[3];
};
void setX(float x)
{
data.m128_f32[0]=x;
};
void setY(float y)
{
data.m128_f32[1]=y;
};
void setZ(float z)
{
data.m128_f32[2]=z;
};
void setW(float w)
{
data.m128_f32[3]=w;
};
void setVector(float x,float y,float z)
{
data.m128_f32[0]=x;
data.m128_f32[1]=y;
data.m128_f32[2]=z;
data.m128_f32[3]=1.0f;
};
void setVector(float x,float y,float z,float w)
{
data.m128_f32[0]=x;
data.m128_f32[1]=y;
data.m128_f32[2]=z;
data.m128_f32[3]=w;
};
public:
Vector(void)
{
data.m128_f32[0]=0.0f;
data.m128_f32[1]=0.0f;
data.m128_f32[2]=0.0f;
data.m128_f32[3]=1.0f;
};
Vector(float f)
{
data.m128_f32[0]=data.m128_f32[1]=data.m128_f32[2]=data.m128_f32[3]=f;
};
Vector(float f1,float f2)
{
data.m128_f32[0]=data.m128_f32[1]=data.m128_f32[2]=f1;
data.m128_f32[3]=f2;
};
Vector(Vector& v)
{
float a=v.getX();
data.m128_f32[0]=v.getX();
data.m128_f32[1]=v.getY();
data.m128_f32[2]=v.getZ();
data.m128_f32[3]=v.getW();
};
Vector(float x,float y,float z)
{
data.m128_f32[0]=x;
data.m128_f32[1]=y;
data.m128_f32[2]=z;
data.m128_f32[3]=1.0f;
};
Vector(float x, float y, float z, float w)
{
data.m128_f32[0]=x;
data.m128_f32[1]=y;
data.m128_f32[2]=z;
data.m128_f32[3]=w;
};
void operator=(Vector& in)
{
data.m128_f32[0]=in.getX();
data.m128_f32[1]=in.getY();
data.m128_f32[2]=in.getZ();
data.m128_f32[3]=in.getW();
};
void null()
{
data.m128_f32[0]=data.m128_f32[1]=data.m128_f32[2]=0.0f;
data.m128_f32[3]=1.0f;
};
static void* operator new(size_t size)
{
void *p=_aligned_malloc(size,16);
return p;
};
static void operator delete (void *p)
{
_aligned_free(p);
}
friend void operator+=(Vector& v1, const Vector& v2);
friend void operator-=(Vector& v1, const Vector& v2);
friend Vector operator-(Vector& v1, Vector& v2);
friend Vector operator+(Vector& v1,Vector& v2);
float operator[](int i)
{
return data.m128_f32;
};
friend void operator*=(Vector &v,float f);
friend void operator/=(Vector &v,float f);
friend void operator*=(Vector &v1,Vector &v2);
friend void operator/=(Vector &v1,Vector &v2);
friend Vector operator*(Vector &v1,Vector &v2);
friend Vector operator/(Vector &v1,Vector &v2);
friend Vector operator*(Vector &v1,float f);
friend Vector operator*(float f,Vector &v1);
friend Vector operator/(Vector &v1,float f);
bool operator==(Vector &v)
{
return (data.m128_f32[0]==v.getX())&&(data.m128_f32[1]==v.getY())&&(data.m128_f32[2]==v.getZ())&&(data.m128_f32[3]==v.getW());
};
float getLength()
{
__m128 temp1=data;
__m128 temp2;
temp1.m128_f32[3]=0.0f;
temp2=(temp1=_mm_mul_ps(temp1,temp1));
temp2=_mm_shuffle_ps(temp2,temp2,0x4E);
temp1=_mm_add_ps(temp1,temp2);
temp2=_mm_shuffle_ps(temp1,temp1,0x11);
temp1=_mm_add_ss(temp1,temp2);
temp1=_mm_sqrt_ss(temp1);
return temp1.m128_f32[0];
};
float getLengthSquare()
{
__m128 temp1=data;
__m128 temp2;
temp1.m128_f32[3]=0.0f;
temp2=(temp1=_mm_mul_ps(temp1,temp1));
temp2=_mm_shuffle_ps(temp2,temp2,0x4E);
temp1=_mm_add_ps(temp1,temp2);
temp2=_mm_shuffle_ps(temp1,temp1,0x11);
temp1=_mm_add_ss(temp1,temp2);
return temp1.m128_f32[0];
};
float distanceTo(Vector &v)
{
__m128 temp1;
temp1.m128_f32[0]=v.getX();
temp1.m128_f32[1]=v.getY();
temp1.m128_f32[2]=v.getZ();
temp1.m128_f32[3]=0.0f;
temp1=_mm_sub_ps(data,temp1);
__m128 temp2;
temp1.m128_f32[3]=0.0f;
temp2=(temp1=_mm_mul_ps(temp1,temp1));
temp2=_mm_shuffle_ps(temp2,temp2,0x4E);
temp1=_mm_add_ps(temp1,temp2);
temp2=_mm_shuffle_ps(temp1,temp1,0x11);
temp1=_mm_add_ss(temp1,temp2);
temp1=_mm_sqrt_ss(temp1);
return temp1.m128_f32[0];
};
float distanceToSquare(Vector &v)
{
__m128 temp1;
temp1.m128_f32[0]=v.getX();
temp1.m128_f32[1]=v.getY();
temp1.m128_f32[2]=v.getZ();
temp1.m128_f32[3]=0.0f;
temp1=_mm_sub_ps(data,temp1);
__m128 temp2;
temp1.m128_f32[3]=0.0f;
temp2=(temp1=_mm_mul_ps(temp1,temp1));
temp2=_mm_shuffle_ps(temp2,temp2,0x4E);
temp1=_mm_add_ps(temp1,temp2);
temp2=_mm_shuffle_ps(temp1,temp1,0x11);
temp1=_mm_add_ss(temp1,temp2);
return temp1.m128_f32[0];
}
void negate()
{
__m128 temp;
temp.m128_f32[0]=temp.m128_f32[1]=temp.m128_f32[2]=temp.m128_f32[3]=0.0f;
data=_mm_sub_ps(temp,data);
}
friend Vector cross(Vector &v1,Vector &v2);
void normalize()
{
__m128 temp1=data;
__m128 temp2;
temp1.m128_f32[3]=0.0f;
temp2=(temp1=_mm_mul_ps(temp1,temp1));
temp2=_mm_shuffle_ps(temp2,temp2,0x4E);
temp1=_mm_add_ps(temp1,temp2);
temp2=_mm_shuffle_ps(temp1,temp1,0x11);
temp1=_mm_add_ss(temp1,temp2);
temp1=_mm_sqrt_ss(temp1);
temp2.m128_f32[0]=temp2.m128_f32[1]=temp2.m128_f32[2]=temp1.m128_f32[0];
temp2.m128_f32[3]=1.0f;
data=_mm_div_ps(data,temp2);
}
public:
~Vector(void){};
};
inline void operator+=(Vector& v1,const Vector& v2)
{
v1.data=_mm_add_ps(v1.data,v2.data);
}
inline void operator-=(Vector& v1, const Vector& v2)
{
v1.data=_mm_sub_ps(v1.data,v2.data);
}
inline Vector cross(Vector &v1,Vector &v2)
{
__m128 data1;
__m128 data2;
data1.m128_f32[0]=v1.getX();
data1.m128_f32[1]=v1.getY();
data1.m128_f32[2]=v1.getZ();
data1.m128_f32[3]=v1.getW();
data2.m128_f32[0]=v2.getX();
data2.m128_f32[1]=v2.getY();
data2.m128_f32[2]=v2.getZ();
data2.m128_f32[3]=v2.getW();
__m128 temp1=_mm_shuffle_ps(data1,data1,0xc9);
__m128 temp2=_mm_shuffle_ps(data2,data2,0xd2);
temp1=_mm_mul_ps(temp1,temp2);
__m128 temp3=_mm_shuffle_ps(data1,data1,0xd2);
__m128 temp4=_mm_shuffle_ps(data2,data2,0xc9);
temp3=_mm_mul_ps(temp3,temp4);
temp4=_mm_sub_ps(temp1,temp3);
Vector result(temp4.m128_f32[0],temp4.m128_f32[1],temp4.m128_f32[2]);
return result;
}
inline Vector operator-(Vector& v1, Vector& v2)
{
__m128 temp1;
__m128 temp2;
temp1.m128_f32[0]=v1.getX();
temp1.m128_f32[1]=v1.getY();
temp1.m128_f32[2]=v1.getZ();
temp1.m128_f32[3]=v1.getW();
temp2.m128_f32[0]=v2.getX();
temp2.m128_f32[1]=v2.getY();
temp2.m128_f32[2]=v2.getZ();
temp2.m128_f32[3]=v2.getW();
__m128 temp=_mm_sub_ps(temp1,temp2);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline Vector operator+(Vector& v1,Vector& v2)
{
__m128 temp1;
__m128 temp2;
temp1.m128_f32[0]=v1.getX();
temp1.m128_f32[1]=v1.getY();
temp1.m128_f32[2]=v1.getZ();
temp1.m128_f32[3]=v1.getW();
temp2.m128_f32[0]=v2.getX();
temp2.m128_f32[1]=v2.getY();
temp2.m128_f32[2]=v2.getZ();
temp2.m128_f32[3]=v2.getW();
__m128 temp=_mm_add_ps(temp1,temp2);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline void operator*=(Vector &v,float f)
{
__m128 temp;
temp.m128_f32[0]=temp.m128_f32[1]=temp.m128_f32[2]=f;
temp.m128_f32[3]=1.0f;
v.data=_mm_mul_ps(v.data,temp);
}
inline void operator/=(Vector &v,float f)
{
__m128 temp;
temp.m128_f32[0]=temp.m128_f32[1]=temp.m128_f32[2]=f;
temp.m128_f32[3]=1.0f;
v.data=_mm_div_ps(v.data,temp);
}
inline void operator*=(Vector &v1,Vector &v2)
{
v1.data=_mm_mul_ps(v1.data,v2.data);
}
inline void operator/=(Vector &v1,Vector &v2)
{
v1.data=_mm_div_ps(v1.data,v2.data);
}
inline Vector operator*(Vector &v1,Vector &v2)
{
__m128 temp;
temp=_mm_mul_ps(v1.data,v2.data);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline Vector operator/(Vector &v1,Vector &v2)
{
__m128 temp;
temp=_mm_div_ps(v1.data,v2.data);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline Vector operator*(Vector &v1,float f)
{
__m128 temp;
temp.m128_f32[0]=temp.m128_f32[1]=temp.m128_f32[2]=f;
temp.m128_f32[3]=1.0f;
temp=_mm_mul_ps(temp,v1.data);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline Vector operator*(float f,Vector &v1)
{
__m128 temp;
temp.m128_f32[0]=temp.m128_f32[1]=temp.m128_f32[2]=f;
temp.m128_f32[3]=1.0f;
temp=_mm_mul_ps(temp,v1.data);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline Vector operator/(Vector &v1,float f)
{
__m128 temp;
temp.m128_f32[0]=temp.m128_f32[1]=temp.m128_f32[2]=f;
temp.m128_f32[3]=1.0f;
temp=_mm_mul_ps(v1.data,temp);
Vector result(temp.m128_f32[0],temp.m128_f32[1],temp.m128_f32[2]);
return result;
}
inline Vector perpendicular(Vector& v1,Vector& v2)
{
Vector result(cross(v1,v2));
float temp=result.getZ();
result.setZ(result.getX());
result.setX(temp);
return result;
}