1 | // Copyright 2009-2021 Intel Corporation |
2 | // SPDX-License-Identifier: Apache-2.0 |
3 | |
4 | #pragma once |
5 | |
6 | #include "subdivpatch1.h" |
7 | #include "grid_soa.h" |
8 | #include "grid_soa_intersector1.h" |
9 | #include "grid_soa_intersector_packet.h" |
10 | #include "../common/ray.h" |
11 | |
12 | namespace embree |
13 | { |
14 | namespace isa |
15 | { |
16 | template<typename T> |
17 | class SubdivPatch1Precalculations : public T |
18 | { |
19 | public: |
20 | __forceinline SubdivPatch1Precalculations (const Ray& ray, const void* ptr) |
21 | : T(ray,ptr) {} |
22 | }; |
23 | |
24 | template<int K, typename T> |
25 | class SubdivPatch1PrecalculationsK : public T |
26 | { |
27 | public: |
28 | __forceinline SubdivPatch1PrecalculationsK (const vbool<K>& valid, RayK<K>& ray) |
29 | : T(valid,ray) {} |
30 | }; |
31 | |
32 | class SubdivPatch1Intersector1 |
33 | { |
34 | public: |
35 | typedef GridSOA Primitive; |
36 | typedef SubdivPatch1Precalculations<GridSOAIntersector1::Precalculations> Precalculations; |
37 | |
38 | static __forceinline bool processLazyNode(Precalculations& pre, IntersectContext* context, const Primitive* prim, size_t& lazy_node) |
39 | { |
40 | lazy_node = prim->root(0); |
41 | pre.grid = (Primitive*)prim; |
42 | return false; |
43 | } |
44 | |
45 | /*! Intersect a ray with the primitive. */ |
46 | template<int N, bool robust> |
47 | static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
48 | { |
49 | if (likely(ty == 0)) GridSOAIntersector1::intersect(pre,ray,context,prim,lazy_node); |
50 | else processLazyNode(pre,context,prim,lazy_node); |
51 | } |
52 | |
53 | template<int N, bool robust> |
54 | static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { |
55 | intersect(This,pre,ray,context,prim,ty,tray,lazy_node); |
56 | } |
57 | |
58 | /*! Test if the ray is occluded by the primitive */ |
59 | template<int N, bool robust> |
60 | static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
61 | { |
62 | if (likely(ty == 0)) return GridSOAIntersector1::occluded(pre,ray,context,prim,lazy_node); |
63 | else return processLazyNode(pre,context,prim,lazy_node); |
64 | } |
65 | |
66 | template<int N, bool robust> |
67 | static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { |
68 | return occluded(This,pre,ray,context,prim,ty,tray,lazy_node); |
69 | } |
70 | |
71 | template<int N> |
72 | static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, const Primitive* prim, size_t ty, const TravPointQuery<N> &tquery, size_t& lazy_node) |
73 | { |
74 | // TODO: PointQuery implement |
75 | assert(false && "not implemented" ); |
76 | return false; |
77 | } |
78 | |
79 | template<int N> |
80 | static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravPointQuery<N> &tquery, size_t& lazy_node) { |
81 | return pointQuery(This,query,context,prim,ty,tquery,lazy_node); |
82 | } |
83 | }; |
84 | |
85 | class SubdivPatch1MBIntersector1 |
86 | { |
87 | public: |
88 | typedef SubdivPatch1 Primitive; |
89 | typedef GridSOAMBIntersector1::Precalculations Precalculations; |
90 | |
91 | static __forceinline bool processLazyNode(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim_i, size_t& lazy_node) |
92 | { |
93 | Primitive* prim = (Primitive*) prim_i; |
94 | GridSOA* grid = nullptr; |
95 | grid = (GridSOA*) prim->root_ref.get(); |
96 | pre.itime = getTimeSegment(ray.time(), float(grid->time_steps-1), pre.ftime); |
97 | lazy_node = grid->root(pre.itime); |
98 | pre.grid = grid; |
99 | return false; |
100 | } |
101 | |
102 | /*! Intersect a ray with the primitive. */ |
103 | template<int N, bool robust> |
104 | static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
105 | { |
106 | if (likely(ty == 0)) GridSOAMBIntersector1::intersect(pre,ray,context,prim,lazy_node); |
107 | else processLazyNode(pre,ray,context,prim,lazy_node); |
108 | } |
109 | |
110 | template<int N, bool robust> |
111 | static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { |
112 | intersect(This,pre,ray,context,prim,ty,tray,lazy_node); |
113 | } |
114 | |
115 | /*! Test if the ray is occluded by the primitive */ |
116 | template<int N, bool robust> |
117 | static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
118 | { |
119 | if (likely(ty == 0)) return GridSOAMBIntersector1::occluded(pre,ray,context,prim,lazy_node); |
120 | else return processLazyNode(pre,ray,context,prim,lazy_node); |
121 | } |
122 | |
123 | template<int N, bool robust> |
124 | static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) { |
125 | return occluded(This,pre,ray,context,prim,ty,tray,lazy_node); |
126 | } |
127 | |
128 | template<int N> |
129 | static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, const Primitive* prim, size_t ty, const TravPointQuery<N> &tquery, size_t& lazy_node) |
130 | { |
131 | // TODO: PointQuery implement |
132 | assert(false && "not implemented" ); |
133 | return false; |
134 | } |
135 | |
136 | template<int N, bool robust> |
137 | static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, size_t ty0, const Primitive* prim, size_t ty, const TravPointQuery<N> &tquery, size_t& lazy_node) { |
138 | return pointQuery(This,query,context,prim,ty,tquery,lazy_node); |
139 | } |
140 | }; |
141 | |
142 | template <int K> |
143 | struct SubdivPatch1IntersectorK |
144 | { |
145 | typedef GridSOA Primitive; |
146 | typedef SubdivPatch1PrecalculationsK<K,typename GridSOAIntersectorK<K>::Precalculations> Precalculations; |
147 | |
148 | static __forceinline bool processLazyNode(Precalculations& pre, IntersectContext* context, const Primitive* prim, size_t& lazy_node) |
149 | { |
150 | lazy_node = prim->root(0); |
151 | pre.grid = (Primitive*)prim; |
152 | return false; |
153 | } |
154 | |
155 | template<bool robust> |
156 | static __forceinline void intersect(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRayK<K, robust> &tray, size_t& lazy_node) |
157 | { |
158 | if (likely(ty == 0)) GridSOAIntersectorK<K>::intersect(valid,pre,ray,context,prim,lazy_node); |
159 | else processLazyNode(pre,context,prim,lazy_node); |
160 | } |
161 | |
162 | template<bool robust> |
163 | static __forceinline vbool<K> occluded(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRayK<K, robust> &tray, size_t& lazy_node) |
164 | { |
165 | if (likely(ty == 0)) return GridSOAIntersectorK<K>::occluded(valid,pre,ray,context,prim,lazy_node); |
166 | else return processLazyNode(pre,context,prim,lazy_node); |
167 | } |
168 | |
169 | template<int N, bool robust> |
170 | static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
171 | { |
172 | if (likely(ty == 0)) GridSOAIntersectorK<K>::intersect(pre,ray,k,context,prim,lazy_node); |
173 | else processLazyNode(pre,context,prim,lazy_node); |
174 | } |
175 | |
176 | template<int N, bool robust> |
177 | static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
178 | { |
179 | if (likely(ty == 0)) return GridSOAIntersectorK<K>::occluded(pre,ray,k,context,prim,lazy_node); |
180 | else return processLazyNode(pre,context,prim,lazy_node); |
181 | } |
182 | }; |
183 | |
184 | typedef SubdivPatch1IntersectorK<4> SubdivPatch1Intersector4; |
185 | typedef SubdivPatch1IntersectorK<8> SubdivPatch1Intersector8; |
186 | typedef SubdivPatch1IntersectorK<16> SubdivPatch1Intersector16; |
187 | |
188 | template <int K> |
189 | struct SubdivPatch1MBIntersectorK |
190 | { |
191 | typedef SubdivPatch1 Primitive; |
192 | //typedef GridSOAMBIntersectorK<K>::Precalculations Precalculations; |
193 | typedef SubdivPatch1PrecalculationsK<K,typename GridSOAMBIntersectorK<K>::Precalculations> Precalculations; |
194 | |
195 | static __forceinline bool processLazyNode(Precalculations& pre, IntersectContext* context, const Primitive* prim_i, size_t& lazy_node) |
196 | { |
197 | Primitive* prim = (Primitive*) prim_i; |
198 | GridSOA* grid = (GridSOA*) prim->root_ref.get(); |
199 | lazy_node = grid->troot; |
200 | pre.grid = grid; |
201 | return false; |
202 | } |
203 | |
204 | template<bool robust> |
205 | static __forceinline void intersect(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRayK<K, robust> &tray, size_t& lazy_node) |
206 | { |
207 | if (likely(ty == 0)) GridSOAMBIntersectorK<K>::intersect(valid,pre,ray,context,prim,lazy_node); |
208 | else processLazyNode(pre,context,prim,lazy_node); |
209 | } |
210 | |
211 | template<bool robust> |
212 | static __forceinline vbool<K> occluded(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, const TravRayK<K, robust> &tray, size_t& lazy_node) |
213 | { |
214 | if (likely(ty == 0)) return GridSOAMBIntersectorK<K>::occluded(valid,pre,ray,context,prim,lazy_node); |
215 | else return processLazyNode(pre,context,prim,lazy_node); |
216 | } |
217 | |
218 | template<int N, bool robust> |
219 | static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
220 | { |
221 | if (likely(ty == 0)) GridSOAMBIntersectorK<K>::intersect(pre,ray,k,context,prim,lazy_node); |
222 | else processLazyNode(pre,context,prim,lazy_node); |
223 | } |
224 | |
225 | template<int N, bool robust> |
226 | static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, const TravRay<N,robust> &tray, size_t& lazy_node) |
227 | { |
228 | if (likely(ty == 0)) return GridSOAMBIntersectorK<K>::occluded(pre,ray,k,context,prim,lazy_node); |
229 | else return processLazyNode(pre,context,prim,lazy_node); |
230 | } |
231 | }; |
232 | |
233 | typedef SubdivPatch1MBIntersectorK<4> SubdivPatch1MBIntersector4; |
234 | typedef SubdivPatch1MBIntersectorK<8> SubdivPatch1MBIntersector8; |
235 | typedef SubdivPatch1MBIntersectorK<16> SubdivPatch1MBIntersector16; |
236 | } |
237 | } |
238 | |