1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "../common/scene.h"
7#include "../common/ray.h"
8#include "../common/point_query.h"
9#include "../bvh/node_intersector1.h"
10#include "../bvh/node_intersector_packet.h"
11
12namespace embree
13{
14 namespace isa
15 {
16 template<typename Intersector>
17 struct ArrayIntersector1
18 {
19 typedef typename Intersector::Primitive Primitive;
20 typedef typename Intersector::Precalculations Precalculations;
21
22 template<int N, bool robust>
23 static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
24 {
25 for (size_t i=0; i<num; i++)
26 Intersector::intersect(pre,ray,context,prim[i]);
27 }
28
29 template<int N, bool robust>
30 static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
31 {
32 for (size_t i=0; i<num; i++) {
33 if (Intersector::occluded(pre,ray,context,prim[i]))
34 return true;
35 }
36 return false;
37 }
38
39 template<int N>
40 static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, const Primitive* prim, size_t num, const TravPointQuery<N> &tquery, size_t& lazy_node)
41 {
42 bool changed = false;
43 for (size_t i=0; i<num; i++)
44 changed |= Intersector::pointQuery(query, context, prim[i]);
45 return changed;
46 }
47
48 template<int K>
49 static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
50 {
51 }
52
53 template<int K>
54 static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
55 {
56 return valid;
57 }
58 };
59
60 template<int K, typename Intersector>
61 struct ArrayIntersectorK_1
62 {
63 typedef typename Intersector::Primitive Primitive;
64 typedef typename Intersector::Precalculations Precalculations;
65
66 template<bool robust>
67 static __forceinline void intersect(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRayK<K, robust> &tray, size_t& lazy_node)
68 {
69 for (size_t i=0; i<num; i++) {
70 Intersector::intersect(valid,pre,ray,context,prim[i]);
71 }
72 }
73
74 template<bool robust>
75 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 num, const TravRayK<K, robust> &tray, size_t& lazy_node)
76 {
77 vbool<K> valid0 = valid;
78 for (size_t i=0; i<num; i++) {
79 valid0 &= !Intersector::occluded(valid0,pre,ray,context,prim[i]);
80 if (none(valid0)) break;
81 }
82 return !valid0;
83 }
84
85 template<int N, bool robust>
86 static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
87 {
88 for (size_t i=0; i<num; i++) {
89 Intersector::intersect(pre,ray,k,context,prim[i]);
90 }
91 }
92
93 template<int N, bool robust>
94 static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
95 {
96 for (size_t i=0; i<num; i++) {
97 if (Intersector::occluded(pre,ray,k,context,prim[i]))
98 return true;
99 }
100 return false;
101 }
102 };
103
104 // =============================================================================================
105
106 template<int K, typename IntersectorK>
107 struct ArrayIntersectorKStream
108 {
109 typedef typename IntersectorK::Primitive PrimitiveK;
110 typedef typename IntersectorK::Precalculations PrecalculationsK;
111
112 static __forceinline void intersectK(const vbool<K>& valid, const Accel::Intersectors* This, /* PrecalculationsK& pre, */ RayHitK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
113 {
114 PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
115
116 for (size_t i=0; i<num; i++) {
117 IntersectorK::intersect(valid,pre,ray,context,prim[i]);
118 }
119 }
120
121 static __forceinline vbool<K> occludedK(const vbool<K>& valid, const Accel::Intersectors* This, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
122 {
123 PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
124 vbool<K> valid0 = valid;
125 for (size_t i=0; i<num; i++) {
126 valid0 &= !IntersectorK::occluded(valid0,pre,ray,context,prim[i]);
127 if (none(valid0)) break;
128 }
129 return !valid0;
130 }
131
132 static __forceinline void intersect(const Accel::Intersectors* This, RayHitK<K>& ray, size_t k, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
133 {
134 PrecalculationsK pre(ray.tnear() <= ray.tfar,ray); // FIXME: might cause trouble
135 for (size_t i=0; i<num; i++) {
136 IntersectorK::intersect(pre,ray,k,context,prim[i]);
137 }
138 }
139
140 static __forceinline bool occluded(const Accel::Intersectors* This, RayK<K>& ray, size_t k, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
141 {
142 PrecalculationsK pre(ray.tnear() <= ray.tfar,ray); // FIXME: might cause trouble
143 for (size_t i=0; i<num; i++) {
144 if (IntersectorK::occluded(pre,ray,k,context,prim[i]))
145 return true;
146 }
147 return false;
148 }
149
150 static __forceinline size_t occluded(const Accel::Intersectors* This, size_t cur_mask, RayK<K>** __restrict__ inputPackets, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
151 {
152 size_t m_occluded = 0;
153 for (size_t i=0; i<num; i++) {
154 size_t bits = cur_mask & (~m_occluded);
155 for (; bits!=0; )
156 {
157 const size_t rayID = bscf(bits);
158 RayHitK<K> &ray = *inputPackets[rayID / K];
159 const size_t k = rayID % K;
160 PrecalculationsK pre(ray.tnear() <= ray.tfar,ray); // FIXME: might cause trouble
161 if (IntersectorK::occluded(pre,ray,k,context,prim[i]))
162 {
163 m_occluded |= (size_t)1 << rayID;
164 ray.tfar[k] = neg_inf;
165 }
166 }
167 }
168 return m_occluded;
169 }
170 };
171 }
172}
173