1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "curveNv.h"
7#include "curveNi_intersector.h"
8
9namespace embree
10{
11 namespace isa
12 {
13 template<int M>
14 struct CurveNvIntersector1 : public CurveNiIntersector1<M>
15 {
16 typedef CurveNv<M> Primitive;
17 typedef CurvePrecalculations1 Precalculations;
18
19 template<typename Intersector, typename Epilog>
20 static __forceinline void intersect_t(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& prim)
21 {
22 vfloat<M> tNear;
23 vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear);
24
25 const size_t N = prim.N;
26 size_t mask = movemask(valid);
27 while (mask)
28 {
29 const size_t i = bscf(mask);
30 STAT3(normal.trav_prims,1,1,1);
31 const unsigned int geomID = prim.geomID(N);
32 const unsigned int primID = prim.primID(N)[i];
33 const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
34 const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
35 const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
36 const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
37 const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
38
39 size_t mask1 = mask;
40 const size_t i1 = bscf(mask1);
41 if (mask) {
42 prefetchL1(&prim.vertices(i1,N)[0]);
43 prefetchL1(&prim.vertices(i1,N)[4]);
44 if (mask1) {
45 const size_t i2 = bsf(mask1);
46 prefetchL2(&prim.vertices(i2,N)[0]);
47 prefetchL2(&prim.vertices(i2,N)[4]);
48 }
49 }
50
51 Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID));
52 mask &= movemask(tNear <= vfloat<M>(ray.tfar));
53 }
54 }
55
56 template<typename Intersector, typename Epilog>
57 static __forceinline bool occluded_t(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& prim)
58 {
59 vfloat<M> tNear;
60 vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear);
61
62 const size_t N = prim.N;
63 size_t mask = movemask(valid);
64 while (mask)
65 {
66 const size_t i = bscf(mask);
67 STAT3(shadow.trav_prims,1,1,1);
68 const unsigned int geomID = prim.geomID(N);
69 const unsigned int primID = prim.primID(N)[i];
70 const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
71 const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
72 const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
73 const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
74 const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
75
76 size_t mask1 = mask;
77 const size_t i1 = bscf(mask1);
78 if (mask) {
79 prefetchL1(&prim.vertices(i1,N)[0]);
80 prefetchL1(&prim.vertices(i1,N)[4]);
81 if (mask1) {
82 const size_t i2 = bsf(mask1);
83 prefetchL2(&prim.vertices(i2,N)[0]);
84 prefetchL2(&prim.vertices(i2,N)[4]);
85 }
86 }
87
88 if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID)))
89 return true;
90
91 mask &= movemask(tNear <= vfloat<M>(ray.tfar));
92 }
93 return false;
94 }
95 };
96
97 template<int M, int K>
98 struct CurveNvIntersectorK : public CurveNiIntersectorK<M,K>
99 {
100 typedef CurveNv<M> Primitive;
101 typedef CurvePrecalculationsK<K> Precalculations;
102
103 template<typename Intersector, typename Epilog>
104 static __forceinline void intersect_t(Precalculations& pre, RayHitK<K>& ray, const size_t k, IntersectContext* context, const Primitive& prim)
105 {
106 vfloat<M> tNear;
107 vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear);
108
109 const size_t N = prim.N;
110 size_t mask = movemask(valid);
111 while (mask)
112 {
113 const size_t i = bscf(mask);
114 STAT3(normal.trav_prims,1,1,1);
115 const unsigned int geomID = prim.geomID(N);
116 const unsigned int primID = prim.primID(N)[i];
117 const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
118 const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
119 const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
120 const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
121 const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
122
123 size_t mask1 = mask;
124 const size_t i1 = bscf(mask1);
125 if (mask) {
126 prefetchL1(&prim.vertices(i1,N)[0]);
127 prefetchL1(&prim.vertices(i1,N)[4]);
128 if (mask1) {
129 const size_t i2 = bsf(mask1);
130 prefetchL2(&prim.vertices(i2,N)[0]);
131 prefetchL2(&prim.vertices(i2,N)[4]);
132 }
133 }
134
135 Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID));
136 mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
137 }
138 }
139
140 template<typename Intersector, typename Epilog>
141 static __forceinline bool occluded_t(Precalculations& pre, RayK<K>& ray, const size_t k, IntersectContext* context, const Primitive& prim)
142 {
143 vfloat<M> tNear;
144 vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear);
145
146 const size_t N = prim.N;
147 size_t mask = movemask(valid);
148 while (mask)
149 {
150 const size_t i = bscf(mask);
151 STAT3(shadow.trav_prims,1,1,1);
152 const unsigned int geomID = prim.geomID(N);
153 const unsigned int primID = prim.primID(N)[i];
154 const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
155 const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
156 const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
157 const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
158 const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
159
160 size_t mask1 = mask;
161 const size_t i1 = bscf(mask1);
162 if (mask) {
163 prefetchL1(&prim.vertices(i1,N)[0]);
164 prefetchL1(&prim.vertices(i1,N)[4]);
165 if (mask1) {
166 const size_t i2 = bsf(mask1);
167 prefetchL2(&prim.vertices(i2,N)[0]);
168 prefetchL2(&prim.vertices(i2,N)[4]);
169 }
170 }
171
172 if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID)))
173 return true;
174
175 mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
176 }
177 return false;
178 }
179 };
180 }
181}
182