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 | |
9 | namespace 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(v&: 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(i: geomID); |
34 | const Vec3ff a0 = Vec3ff::loadu(a: &prim.vertices(i,N)[0]); |
35 | const Vec3ff a1 = Vec3ff::loadu(a: &prim.vertices(i,N)[1]); |
36 | const Vec3ff a2 = Vec3ff::loadu(a: &prim.vertices(i,N)[2]); |
37 | const Vec3ff a3 = Vec3ff::loadu(a: &prim.vertices(i,N)[3]); |
38 | |
39 | size_t mask1 = mask; |
40 | const size_t i1 = bscf(v&: 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(v: 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(v&: 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(i: geomID); |
71 | const Vec3ff a0 = Vec3ff::loadu(a: &prim.vertices(i,N)[0]); |
72 | const Vec3ff a1 = Vec3ff::loadu(a: &prim.vertices(i,N)[1]); |
73 | const Vec3ff a2 = Vec3ff::loadu(a: &prim.vertices(i,N)[2]); |
74 | const Vec3ff a3 = Vec3ff::loadu(a: &prim.vertices(i,N)[3]); |
75 | |
76 | size_t mask1 = mask; |
77 | const size_t i1 = bscf(v&: 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(v: 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(v&: 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(i: geomID); |
118 | const Vec3ff a0 = Vec3ff::loadu(a: &prim.vertices(i,N)[0]); |
119 | const Vec3ff a1 = Vec3ff::loadu(a: &prim.vertices(i,N)[1]); |
120 | const Vec3ff a2 = Vec3ff::loadu(a: &prim.vertices(i,N)[2]); |
121 | const Vec3ff a3 = Vec3ff::loadu(a: &prim.vertices(i,N)[3]); |
122 | |
123 | size_t mask1 = mask; |
124 | const size_t i1 = bscf(v&: 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(v: 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(v&: 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(i: geomID); |
155 | const Vec3ff a0 = Vec3ff::loadu(a: &prim.vertices(i,N)[0]); |
156 | const Vec3ff a1 = Vec3ff::loadu(a: &prim.vertices(i,N)[1]); |
157 | const Vec3ff a2 = Vec3ff::loadu(a: &prim.vertices(i,N)[2]); |
158 | const Vec3ff a3 = Vec3ff::loadu(a: &prim.vertices(i,N)[3]); |
159 | |
160 | size_t mask1 = mask; |
161 | const size_t i1 = bscf(v&: 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(v: 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 | |