| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  | // Copyright 2009-2021 Intel Corporation
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  | // SPDX-License-Identifier: Apache-2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "curveNv.h"
 | 
					
						
							|  |  |  | #include "curveNi_intersector.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace embree | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   namespace isa | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     template<int M> | 
					
						
							|  |  |  |       struct CurveNvIntersector1 : public CurveNiIntersector1<M> | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       typedef CurveNv<M> Primitive; | 
					
						
							|  |  |  |       typedef CurvePrecalculations1 Precalculations; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       template<typename Intersector, typename Epilog> | 
					
						
							|  |  |  |         static __forceinline void intersect_t(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& prim) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         vfloat<M> tNear; | 
					
						
							|  |  |  |         vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const size_t N = prim.N; | 
					
						
							|  |  |  |         size_t mask = movemask(valid); | 
					
						
							|  |  |  |         while (mask) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const size_t i = bscf(mask); | 
					
						
							|  |  |  |           STAT3(normal.trav_prims,1,1,1); | 
					
						
							|  |  |  |           const unsigned int geomID = prim.geomID(N); | 
					
						
							|  |  |  |           const unsigned int primID = prim.primID(N)[i]; | 
					
						
							|  |  |  |           const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID); | 
					
						
							|  |  |  |           const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]); | 
					
						
							|  |  |  |           const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]); | 
					
						
							|  |  |  |           const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]); | 
					
						
							|  |  |  |           const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           size_t mask1 = mask; | 
					
						
							|  |  |  |           const size_t i1 = bscf(mask1); | 
					
						
							|  |  |  |           if (mask) { | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[0]); | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[4]); | 
					
						
							|  |  |  |             if (mask1) { | 
					
						
							|  |  |  |               const size_t i2 = bsf(mask1); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[0]); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[4]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID)); | 
					
						
							|  |  |  |           mask &= movemask(tNear <= vfloat<M>(ray.tfar)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       template<typename Intersector, typename Epilog> | 
					
						
							|  |  |  |         static __forceinline bool occluded_t(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& prim) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         vfloat<M> tNear; | 
					
						
							|  |  |  |         vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const size_t N = prim.N; | 
					
						
							|  |  |  |         size_t mask = movemask(valid); | 
					
						
							|  |  |  |         while (mask) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const size_t i = bscf(mask); | 
					
						
							|  |  |  |           STAT3(shadow.trav_prims,1,1,1); | 
					
						
							|  |  |  |           const unsigned int geomID = prim.geomID(N); | 
					
						
							|  |  |  |           const unsigned int primID = prim.primID(N)[i]; | 
					
						
							|  |  |  |           const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID); | 
					
						
							|  |  |  |           const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]); | 
					
						
							|  |  |  |           const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]); | 
					
						
							|  |  |  |           const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]); | 
					
						
							|  |  |  |           const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           size_t mask1 = mask; | 
					
						
							|  |  |  |           const size_t i1 = bscf(mask1); | 
					
						
							|  |  |  |           if (mask) { | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[0]); | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[4]); | 
					
						
							|  |  |  |             if (mask1) { | 
					
						
							|  |  |  |               const size_t i2 = bsf(mask1); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[0]); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[4]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |           if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID))) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |           mask &= movemask(tNear <= vfloat<M>(ray.tfar)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<int M, int K> | 
					
						
							|  |  |  |       struct CurveNvIntersectorK : public CurveNiIntersectorK<M,K> | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       typedef CurveNv<M> Primitive; | 
					
						
							|  |  |  |       typedef CurvePrecalculationsK<K> Precalculations; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       template<typename Intersector, typename Epilog> | 
					
						
							|  |  |  |         static __forceinline void intersect_t(Precalculations& pre, RayHitK<K>& ray, const size_t k, IntersectContext* context, const Primitive& prim) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         vfloat<M> tNear; | 
					
						
							|  |  |  |         vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const size_t N = prim.N; | 
					
						
							|  |  |  |         size_t mask = movemask(valid); | 
					
						
							|  |  |  |         while (mask) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const size_t i = bscf(mask); | 
					
						
							|  |  |  |           STAT3(normal.trav_prims,1,1,1); | 
					
						
							|  |  |  |           const unsigned int geomID = prim.geomID(N); | 
					
						
							|  |  |  |           const unsigned int primID = prim.primID(N)[i]; | 
					
						
							|  |  |  |           const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID); | 
					
						
							|  |  |  |           const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]); | 
					
						
							|  |  |  |           const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]); | 
					
						
							|  |  |  |           const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]); | 
					
						
							|  |  |  |           const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           size_t mask1 = mask; | 
					
						
							|  |  |  |           const size_t i1 = bscf(mask1); | 
					
						
							|  |  |  |           if (mask) { | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[0]); | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[4]); | 
					
						
							|  |  |  |             if (mask1) { | 
					
						
							|  |  |  |               const size_t i2 = bsf(mask1); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[0]); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[4]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID)); | 
					
						
							|  |  |  |           mask &= movemask(tNear <= vfloat<M>(ray.tfar[k])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       template<typename Intersector, typename Epilog> | 
					
						
							|  |  |  |         static __forceinline bool occluded_t(Precalculations& pre, RayK<K>& ray, const size_t k, IntersectContext* context, const Primitive& prim) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         vfloat<M> tNear; | 
					
						
							|  |  |  |         vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const size_t N = prim.N; | 
					
						
							|  |  |  |         size_t mask = movemask(valid); | 
					
						
							|  |  |  |         while (mask) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const size_t i = bscf(mask); | 
					
						
							|  |  |  |           STAT3(shadow.trav_prims,1,1,1); | 
					
						
							|  |  |  |           const unsigned int geomID = prim.geomID(N); | 
					
						
							|  |  |  |           const unsigned int primID = prim.primID(N)[i]; | 
					
						
							|  |  |  |           const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID); | 
					
						
							|  |  |  |           const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]); | 
					
						
							|  |  |  |           const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]); | 
					
						
							|  |  |  |           const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]); | 
					
						
							|  |  |  |           const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           size_t mask1 = mask; | 
					
						
							|  |  |  |           const size_t i1 = bscf(mask1); | 
					
						
							|  |  |  |           if (mask) { | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[0]); | 
					
						
							|  |  |  |             prefetchL1(&prim.vertices(i1,N)[4]); | 
					
						
							|  |  |  |             if (mask1) { | 
					
						
							|  |  |  |               const size_t i2 = bsf(mask1); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[0]); | 
					
						
							|  |  |  |               prefetchL2(&prim.vertices(i2,N)[4]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID))) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           mask &= movemask(tNear <= vfloat<M>(ray.tfar[k])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |