Text archives Help
- From: sparker@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r1053 - trunk/Model/Primitives
- Date: Tue, 9 May 2006 18:20:30 -0600 (MDT)
Author: sparker
Date: Tue May 9 18:20:29 2006
New Revision: 1053
Modified:
trunk/Model/Primitives/Sphere.cc
Log:
Vectorize another case in Sphere
Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc (original)
+++ trunk/Model/Primitives/Sphere.cc Tue May 9 18:20:29 2006
@@ -64,7 +64,112 @@
// Rays of constant origin and normalized directions
Vector O(rays.getOrigin(0)-center);
Real C = Dot(O, O) - radius*radius;
- for(int i = rays.begin();i<rays.end();i++){
+#ifdef MANTA_SSE
+ int b = (rays.rayBegin + 3) & (~3);
+ int e = rays.rayEnd & (~3);
+ if(b == e){
+ for(int i = rays.begin(); i < rays.end(); i++){
+ Vector D(rays.getDirection(i));
+ Real B = Dot(O, D);
+ Real disc = B*B-C;
+ if(disc >= 0){
+ Real r = Sqrt(disc);
+ Real t0 = -(r+B);
+ if(t0 > T_EPSILON){
+ rays.hit(i, t0, getMaterial(), this, getTexCoordMapper());
+ } else {
+ Real t1 = r-B;
+ rays.hit(i, t1, getMaterial(), this, getTexCoordMapper());
+ }
+ }
+ }
+ } else {
+ int i = rays.rayBegin;
+ for(;i<b;i++){
+ Vector D(rays.getDirection(i));
+ Real B = Dot(O, D);
+ Real disc = B*B-C;
+ if(disc >= 0){
+ Real r = Sqrt(disc);
+ Real t0 = -(r+B);
+ if(t0 > T_EPSILON){
+ rays.hit(i, t0, getMaterial(), this, getTexCoordMapper());
+ } else {
+ Real t1 = r-B;
+ rays.hit(i, t1, getMaterial(), this, getTexCoordMapper());
+ }
+ }
+ }
+ RayPacketData* data = rays.data;
+ for(;i<e;i+=4){
+ __m128 Ox = _mm_sub_ps(_mm_load_ps(&data->origin[0][i]),
_mm_set1_ps(center[0]));
+ __m128 Oy = _mm_sub_ps(_mm_load_ps(&data->origin[1][i]),
_mm_set1_ps(center[1]));
+ __m128 Oz = _mm_sub_ps(_mm_load_ps(&data->origin[2][i]),
_mm_set1_ps(center[2]));
+ __m128 Dx = _mm_load_ps(&data->direction[0][i]);
+ __m128 Dy = _mm_load_ps(&data->direction[1][i]);
+ __m128 Dz = _mm_load_ps(&data->direction[2][i]);
+ __m128 B = _mm_add_ps(_mm_add_ps(_mm_mul_ps(Ox, Dx),
_mm_mul_ps(Oy, Dy)), _mm_mul_ps(Oz, Dz));
+ __m128 disc = _mm_sub_ps(_mm_mul_ps(B, B), _mm_set1_ps(C));
+ __m128 hit = _mm_cmpge_ps(disc, _mm_setzero_ps());
+ if(_mm_movemask_ps(hit) == 0)
+ continue;
+
+ __m128 r = _mm_sqrt_ps(disc);
+ // -(r+B) The xor negates the value
+ __m128 t0 = _mm_xor_ps(_mm_add_ps(r, B),
(__m128)_mm_set1_epi32(0x80000000));
+ __m128 hit0 = _mm_and_ps(hit, _mm_cmpgt_ps(t0,
_mm_set1_ps(T_EPSILON)));
+ if(_mm_movemask_ps(hit0) != 0){
+ hit0 = _mm_and_ps(hit, _mm_cmplt_ps(t0,
_mm_load_ps(&data->minT[i])));
+ if(_mm_movemask_ps(hit0) == 15){
+ _mm_store_ps(&data->minT[i], t0);
+ _mm_store_si128((__m128i*)&data->hitMatl[i],
_mm_set1_epi32((int)getMaterial()));
+ _mm_store_si128((__m128i*)&data->hitPrim[i],
_mm_set1_epi32((int)this));
+ _mm_store_si128((__m128i*)&data->hitTex[i],
_mm_set1_epi32((int)getTexCoordMapper()));
+ } else if(_mm_movemask_ps(hit0) != 0) {
+ _mm_maskmoveu_si128((__m128i)t0, (__m128i)hit0,
(char*)&data->minT[i]);
+ _mm_maskmoveu_si128(_mm_set1_epi32((int)getMaterial()),
(__m128i)hit0, (char*)&data->hitMatl[i]);
+ _mm_maskmoveu_si128(_mm_set1_epi32((int)this), (__m128i)hit0,
(char*)&data->hitPrim[i]);
+ _mm_maskmoveu_si128(_mm_set1_epi32((int)getTexCoordMapper()),
(__m128i)hit0, (char*)&data->hitTex[i]);
+ }
+ // Mask off rays that successfully hit at t0
+ hit = _mm_andnot_ps(hit, hit0);
+ if(_mm_movemask_ps(hit) == 0)
+ continue;
+ }
+
+ __m128 t1 = _mm_sub_ps(r, B);
+ __m128 hit1 = _mm_and_ps(hit, _mm_cmpgt_ps(t1,
_mm_set1_ps(T_EPSILON)));
+ hit1 = _mm_and_ps(hit1, _mm_cmplt_ps(t1,
_mm_load_ps(&data->minT[i])));
+ if(_mm_movemask_ps(hit1) == 15){
+ _mm_store_ps(&data->minT[i], t1);
+ _mm_store_si128((__m128i*)&data->hitMatl[i],
_mm_set1_epi32((int)getMaterial()));
+ _mm_store_si128((__m128i*)&data->hitPrim[i],
_mm_set1_epi32((int)this));
+ _mm_store_si128((__m128i*)&data->hitTex[i],
_mm_set1_epi32((int)getTexCoordMapper()));
+ } else if(_mm_movemask_ps(hit1) != 0){
+ _mm_maskmoveu_si128((__m128i)t1, (__m128i)hit1,
(char*)&data->minT[i]);
+ _mm_maskmoveu_si128(_mm_set1_epi32((int)getMaterial()),
(__m128i)hit1, (char*)&data->hitMatl[i]);
+ _mm_maskmoveu_si128(_mm_set1_epi32((int)this), (__m128i)hit1,
(char*)&data->hitPrim[i]);
+ _mm_maskmoveu_si128(_mm_set1_epi32((int)getTexCoordMapper()),
(__m128i)hit1, (char*)&data->hitTex[i]);
+ }
+ }
+ for(;i<rays.rayEnd;i++){
+ Vector D(rays.getDirection(i));
+ Real B = Dot(O, D);
+ Real disc = B*B-C;
+ if(disc >= 0){
+ Real r = Sqrt(disc);
+ Real t0 = -(r+B);
+ if(t0 > T_EPSILON){
+ rays.hit(i, t0, getMaterial(), this, getTexCoordMapper());
+ } else {
+ Real t1 = r-B;
+ rays.hit(i, t1, getMaterial(), this, getTexCoordMapper());
+ }
+ }
+ }
+ }
+#else
+ for(int i = rays.begin(); i < rays.end(); i++){
Vector D(rays.getDirection(i));
Real B = Dot(O, D);
Real disc = B*B-C;
@@ -78,6 +183,9 @@
rays.hit(i, t1, getMaterial(), this, getTexCoordMapper());
}
}
+ }
+#endif
+ for(int i = rays.begin();i<rays.end();i++){
}
}
break;
- [MANTA] r1053 - trunk/Model/Primitives, sparker, 05/09/2006
Archive powered by MHonArc 2.6.16.