Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1053 - trunk/Model/Primitives


Chronological Thread 
  • 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.

Top of page