accel.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "default.h"
  18. #include "ray.h"
  19. #include "context.h"
  20. namespace embree
  21. {
  22. class Scene;
  23. /*! Base class for the acceleration structure data. */
  24. class AccelData : public RefCount
  25. {
  26. public:
  27. enum Type { TY_UNKNOWN = 0, TY_ACCELN = 1, TY_ACCEL_INSTANCE = 2, TY_BVH4 = 3, TY_BVH8 = 4 };
  28. public:
  29. AccelData (const Type type)
  30. : bounds(empty), type(type) {}
  31. /*! notifies the acceleration structure about the deletion of some geometry */
  32. virtual void deleteGeometry(size_t geomID) {};
  33. /*! clears the acceleration structure data */
  34. virtual void clear() = 0;
  35. /*! returns normal bounds */
  36. __forceinline BBox3fa getBounds() const {
  37. return bounds.bounds();
  38. }
  39. /*! returns linear bounds */
  40. __forceinline LBBox3fa getLinearBounds() const {
  41. return bounds;
  42. }
  43. public:
  44. LBBox3fa bounds; // linear bounds
  45. Type type;
  46. };
  47. /*! Base class for all intersectable and buildable acceleration structures. */
  48. class Accel : public AccelData
  49. {
  50. ALIGNED_CLASS;
  51. public:
  52. /*! Type of intersect function pointer for single rays. */
  53. typedef void (*IntersectFunc)(void* ptr, /*!< pointer to user data */
  54. RTCRay& ray, /*!< ray to intersect */
  55. IntersectContext* context);
  56. /*! Type of intersect function pointer for ray packets of size 4. */
  57. typedef void (*IntersectFunc4)(const void* valid, /*!< pointer to valid mask */
  58. void* ptr, /*!< pointer to user data */
  59. RTCRay4& ray, /*!< ray packet to intersect */
  60. IntersectContext* context);
  61. /*! Type of intersect function pointer for ray packets of size 8. */
  62. typedef void (*IntersectFunc8)(const void* valid, /*!< pointer to valid mask */
  63. void* ptr, /*!< pointer to user data */
  64. RTCRay8& ray, /*!< ray packet to intersect */
  65. IntersectContext* context);
  66. /*! Type of intersect function pointer for ray packets of size 16. */
  67. typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */
  68. void* ptr, /*!< pointer to user data */
  69. RTCRay16& ray, /*!< ray packet to intersect */
  70. IntersectContext* context);
  71. /*! Type of intersect function pointer for ray packets of size N. */
  72. typedef void (*IntersectFuncN)(void* ptr, /*!< pointer to user data */
  73. RTCRay** ray, /*!< ray stream to intersect */
  74. const size_t N, /*!< number of rays in stream */
  75. IntersectContext* context /*!< layout flags */);
  76. /*! Type of occlusion function pointer for single rays. */
  77. typedef void (*OccludedFunc) (void* ptr, /*!< pointer to user data */
  78. RTCRay& ray, /*!< ray to test occlusion */
  79. IntersectContext* context);
  80. /*! Type of occlusion function pointer for ray packets of size 4. */
  81. typedef void (*OccludedFunc4) (const void* valid, /*! pointer to valid mask */
  82. void* ptr, /*!< pointer to user data */
  83. RTCRay4& ray, /*!< Ray packet to test occlusion. */
  84. IntersectContext* context);
  85. /*! Type of occlusion function pointer for ray packets of size 8. */
  86. typedef void (*OccludedFunc8) (const void* valid, /*! pointer to valid mask */
  87. void* ptr, /*!< pointer to user data */
  88. RTCRay8& ray, /*!< Ray packet to test occlusion. */
  89. IntersectContext* context);
  90. /*! Type of occlusion function pointer for ray packets of size 16. */
  91. typedef void (*OccludedFunc16) (const void* valid, /*! pointer to valid mask */
  92. void* ptr, /*!< pointer to user data */
  93. RTCRay16& ray, /*!< Ray packet to test occlusion. */
  94. IntersectContext* context);
  95. /*! Type of intersect function pointer for ray packets of size N. */
  96. typedef void (*OccludedFuncN)(void* ptr, /*!< pointer to user data */
  97. RTCRay** ray, /*!< ray stream to intersect */
  98. const size_t N, /*!< number of rays in stream */
  99. IntersectContext* context /*!< layout flags */);
  100. typedef void (*ErrorFunc) ();
  101. struct Intersector1
  102. {
  103. Intersector1 (ErrorFunc error = nullptr)
  104. : intersect((IntersectFunc)error), occluded((OccludedFunc)error), name(nullptr) {}
  105. Intersector1 (IntersectFunc intersect, OccludedFunc occluded, const char* name)
  106. : intersect(intersect), occluded(occluded), name(name) {}
  107. operator bool() const { return name; }
  108. public:
  109. static const char* type;
  110. IntersectFunc intersect;
  111. OccludedFunc occluded;
  112. const char* name;
  113. };
  114. struct Intersector4
  115. {
  116. Intersector4 (ErrorFunc error = nullptr)
  117. : intersect((IntersectFunc4)error), occluded((OccludedFunc4)error), name(nullptr) {}
  118. Intersector4 (IntersectFunc4 intersect, OccludedFunc4 occluded, const char* name)
  119. : intersect(intersect), occluded(occluded), name(name) {}
  120. operator bool() const { return name; }
  121. public:
  122. static const char* type;
  123. IntersectFunc4 intersect;
  124. OccludedFunc4 occluded;
  125. const char* name;
  126. };
  127. struct Intersector8
  128. {
  129. Intersector8 (ErrorFunc error = nullptr)
  130. : intersect((IntersectFunc8)error), occluded((OccludedFunc8)error), name(nullptr) {}
  131. Intersector8 (IntersectFunc8 intersect, OccludedFunc8 occluded, const char* name)
  132. : intersect(intersect), occluded(occluded), name(name) {}
  133. operator bool() const { return name; }
  134. public:
  135. static const char* type;
  136. IntersectFunc8 intersect;
  137. OccludedFunc8 occluded;
  138. const char* name;
  139. };
  140. struct Intersector16
  141. {
  142. Intersector16 (ErrorFunc error = nullptr)
  143. : intersect((IntersectFunc16)error), occluded((OccludedFunc16)error), name(nullptr) {}
  144. Intersector16 (IntersectFunc16 intersect, OccludedFunc16 occluded, const char* name)
  145. : intersect(intersect), occluded(occluded), name(name) {}
  146. operator bool() const { return name; }
  147. public:
  148. static const char* type;
  149. IntersectFunc16 intersect;
  150. OccludedFunc16 occluded;
  151. const char* name;
  152. };
  153. struct IntersectorN
  154. {
  155. IntersectorN (ErrorFunc error = nullptr)
  156. : intersect((IntersectFuncN)error), occluded((OccludedFuncN)error), name(nullptr) {}
  157. IntersectorN (IntersectFuncN intersect, OccludedFuncN occluded, const char* name)
  158. : intersect(intersect), occluded(occluded), name(name) {}
  159. operator bool() const { return name; }
  160. public:
  161. static const char* type;
  162. IntersectFuncN intersect;
  163. OccludedFuncN occluded;
  164. const char* name;
  165. };
  166. struct Intersectors
  167. {
  168. Intersectors()
  169. : ptr(nullptr) {}
  170. Intersectors (ErrorFunc error)
  171. : ptr(nullptr), intersector1(error), intersector4(error), intersector8(error), intersector16(error), intersectorN(error) {}
  172. void print(size_t ident)
  173. {
  174. if (intersector1.name) {
  175. for (size_t i=0; i<ident; i++) std::cout << " ";
  176. std::cout << "intersector1 = " << intersector1.name << std::endl;
  177. }
  178. if (intersector4.name) {
  179. for (size_t i=0; i<ident; i++) std::cout << " ";
  180. std::cout << "intersector4 = " << intersector4.name << std::endl;
  181. }
  182. if (intersector8.name) {
  183. for (size_t i=0; i<ident; i++) std::cout << " ";
  184. std::cout << "intersector8 = " << intersector8.name << std::endl;
  185. }
  186. if (intersector16.name) {
  187. for (size_t i=0; i<ident; i++) std::cout << " ";
  188. std::cout << "intersector16 = " << intersector16.name << std::endl;
  189. }
  190. if (intersectorN.name) {
  191. for (size_t i=0; i<ident; i++) std::cout << " ";
  192. std::cout << "intersectorN = " << intersectorN.name << std::endl;
  193. }
  194. }
  195. void select(bool filter4, bool filter8, bool filter16, bool filterN)
  196. {
  197. if (intersector4_filter) {
  198. if (filter4) intersector4 = intersector4_filter;
  199. else intersector4 = intersector4_nofilter;
  200. }
  201. if (intersector8_filter) {
  202. if (filter8) intersector8 = intersector8_filter;
  203. else intersector8 = intersector8_nofilter;
  204. }
  205. if (intersector16_filter) {
  206. if (filter16) intersector16 = intersector16_filter;
  207. else intersector16 = intersector16_nofilter;
  208. }
  209. if (intersectorN_filter) {
  210. if (filterN) intersectorN = intersectorN_filter;
  211. else intersectorN = intersectorN_nofilter;
  212. }
  213. }
  214. public:
  215. AccelData* ptr;
  216. Intersector1 intersector1;
  217. Intersector4 intersector4;
  218. Intersector4 intersector4_filter;
  219. Intersector4 intersector4_nofilter;
  220. Intersector8 intersector8;
  221. Intersector8 intersector8_filter;
  222. Intersector8 intersector8_nofilter;
  223. Intersector16 intersector16;
  224. Intersector16 intersector16_filter;
  225. Intersector16 intersector16_nofilter;
  226. IntersectorN intersectorN;
  227. IntersectorN intersectorN_filter;
  228. IntersectorN intersectorN_nofilter;
  229. };
  230. public:
  231. /*! Construction */
  232. Accel (const AccelData::Type type)
  233. : AccelData(type) {}
  234. /*! Construction */
  235. Accel (const AccelData::Type type, const Intersectors& intersectors)
  236. : AccelData(type), intersectors(intersectors) {}
  237. /*! Virtual destructor */
  238. virtual ~Accel() {}
  239. /*! makes the acceleration structure immutable */
  240. virtual void immutable () {}
  241. /*! build acceleration structure */
  242. virtual void build () = 0;
  243. /*! Intersects a single ray with the scene. */
  244. __forceinline void intersect (RTCRay& ray, IntersectContext* context) {
  245. assert(intersectors.intersector1.intersect);
  246. intersectors.intersector1.intersect(intersectors.ptr,ray,context);
  247. }
  248. /*! Intersects a packet of 4 rays with the scene. */
  249. __forceinline void intersect4 (const void* valid, RTCRay4& ray, IntersectContext* context) {
  250. assert(intersectors.intersector4.intersect);
  251. intersectors.intersector4.intersect(valid,intersectors.ptr,ray,context);
  252. }
  253. /*! Intersects a packet of 8 rays with the scene. */
  254. __forceinline void intersect8 (const void* valid, RTCRay8& ray, IntersectContext* context) {
  255. assert(intersectors.intersector8.intersect);
  256. intersectors.intersector8.intersect(valid,intersectors.ptr,ray,context);
  257. }
  258. /*! Intersects a packet of 16 rays with the scene. */
  259. __forceinline void intersect16 (const void* valid, RTCRay16& ray, IntersectContext* context) {
  260. assert(intersectors.intersector16.intersect);
  261. intersectors.intersector16.intersect(valid,intersectors.ptr,ray,context);
  262. }
  263. /*! Intersects a packet of N rays in SOA layout with the scene. */
  264. __forceinline void intersectN (RTCRay **rayN, const size_t N, IntersectContext* context)
  265. {
  266. //assert(intersectors.intersectorN.intersect);
  267. if (intersectors.intersectorN.intersect)
  268. intersectors.intersectorN.intersect(intersectors.ptr,rayN,N,context);
  269. else
  270. {
  271. if (likely(context->flags == IntersectContext::INPUT_RAY_DATA_AOS))
  272. for (size_t i=0; i<N; i++)
  273. intersect(*rayN[i],context);
  274. else
  275. {
  276. assert(context->getInputSIMDWidth() == VSIZEX);
  277. const size_t numPackets = (N+VSIZEX-1)/VSIZEX;
  278. for (size_t i=0; i<numPackets; i++)
  279. {
  280. RayK<VSIZEX> &ray = *(RayK<VSIZEX>*)rayN[i];
  281. vbool<VSIZEX> valid = ray.tnear <= ray.tfar;
  282. intersect(valid,ray,context);
  283. }
  284. }
  285. }
  286. }
  287. #if defined(__SSE__)
  288. __forceinline void intersect(const vbool4& valid, RayK<4>& ray, IntersectContext* context) {
  289. const vint<4> mask = valid.mask32();
  290. intersect4(&mask,(RTCRay4&)ray,context);
  291. }
  292. #endif
  293. #if defined(__AVX__)
  294. __forceinline void intersect(const vbool8& valid, RayK<8>& ray, IntersectContext* context) {
  295. const vint<8> mask = valid.mask32();
  296. intersect8(&mask,(RTCRay8&)ray,context);
  297. }
  298. #endif
  299. #if defined(__AVX512F__)
  300. __forceinline void intersect(const vbool16& valid, RayK<16>& ray, IntersectContext* context) {
  301. const vint<16> mask = valid.mask32();
  302. intersect16(&mask,(RTCRay16&)ray,context);
  303. }
  304. #endif
  305. /*! Tests if single ray is occluded by the scene. */
  306. __forceinline void occluded (RTCRay& ray, IntersectContext* context) {
  307. assert(intersectors.intersector1.occluded);
  308. intersectors.intersector1.occluded(intersectors.ptr,ray,context);
  309. }
  310. /*! Tests if a packet of 4 rays is occluded by the scene. */
  311. __forceinline void occluded4 (const void* valid, RTCRay4& ray, IntersectContext* context) {
  312. assert(intersectors.intersector4.occluded);
  313. intersectors.intersector4.occluded(valid,intersectors.ptr,ray,context);
  314. }
  315. /*! Tests if a packet of 8 rays is occluded by the scene. */
  316. __forceinline void occluded8 (const void* valid, RTCRay8& ray, IntersectContext* context) {
  317. assert(intersectors.intersector8.occluded);
  318. intersectors.intersector8.occluded(valid,intersectors.ptr,ray,context);
  319. }
  320. /*! Tests if a packet of 16 rays is occluded by the scene. */
  321. __forceinline void occluded16 (const void* valid, RTCRay16& ray, IntersectContext* context) {
  322. assert(intersectors.intersector16.occluded);
  323. intersectors.intersector16.occluded(valid,intersectors.ptr,ray,context);
  324. }
  325. /*! Tests if a packet of N rays in SOA layout is occluded by the scene. */
  326. __forceinline void occludedN (RTCRay** rayN, const size_t N, IntersectContext* context)
  327. {
  328. //assert(intersectors.intersectorN.occluded);
  329. if (intersectors.intersectorN.occluded)
  330. intersectors.intersectorN.occluded(intersectors.ptr,rayN,N,context);
  331. else
  332. {
  333. if (likely(context->flags == IntersectContext::INPUT_RAY_DATA_AOS))
  334. for (size_t i=0;i<N;i++)
  335. occluded(*rayN[i],context);
  336. else
  337. {
  338. assert(context->getInputSIMDWidth() == VSIZEX);
  339. const size_t numPackets = (N+VSIZEX-1)/VSIZEX;
  340. for (size_t i=0; i<numPackets; i++)
  341. {
  342. RayK<VSIZEX> &ray = *(RayK<VSIZEX>*)rayN[i];
  343. vbool<VSIZEX> valid = ray.tnear <= ray.tfar;
  344. occluded(valid,ray,context);
  345. }
  346. }
  347. }
  348. }
  349. #if defined(__SSE__)
  350. __forceinline void occluded(const vbool4& valid, RayK<4>& ray, IntersectContext* context) {
  351. const vint<4> mask = valid.mask32();
  352. occluded4(&mask,(RTCRay4&)ray,context);
  353. }
  354. #endif
  355. #if defined(__AVX__)
  356. __forceinline void occluded(const vbool8& valid, RayK<8>& ray, IntersectContext* context) {
  357. const vint<8> mask = valid.mask32();
  358. occluded8(&mask,(RTCRay8&)ray,context);
  359. }
  360. #endif
  361. #if defined(__AVX512F__)
  362. __forceinline void occluded(const vbool16& valid, RayK<16>& ray, IntersectContext* context) {
  363. const vint<16> mask = valid.mask32();
  364. occluded16(&mask,(RTCRay16&)ray,context);
  365. }
  366. #endif
  367. public:
  368. Intersectors intersectors;
  369. };
  370. #define DEFINE_INTERSECTOR1(symbol,intersector) \
  371. Accel::Intersector1 symbol() { \
  372. return Accel::Intersector1((Accel::IntersectFunc)intersector::intersect, \
  373. (Accel::OccludedFunc )intersector::occluded, \
  374. TOSTRING(isa) "::" TOSTRING(symbol)); \
  375. }
  376. #define DEFINE_INTERSECTOR4(symbol,intersector) \
  377. Accel::Intersector4 symbol() { \
  378. return Accel::Intersector4((Accel::IntersectFunc4)intersector::intersect, \
  379. (Accel::OccludedFunc4)intersector::occluded, \
  380. TOSTRING(isa) "::" TOSTRING(symbol)); \
  381. }
  382. #define DEFINE_INTERSECTOR8(symbol,intersector) \
  383. Accel::Intersector8 symbol() { \
  384. return Accel::Intersector8((Accel::IntersectFunc8)intersector::intersect, \
  385. (Accel::OccludedFunc8)intersector::occluded, \
  386. TOSTRING(isa) "::" TOSTRING(symbol)); \
  387. }
  388. #define DEFINE_INTERSECTOR16(symbol,intersector) \
  389. Accel::Intersector16 symbol() { \
  390. return Accel::Intersector16((Accel::IntersectFunc16)intersector::intersect, \
  391. (Accel::OccludedFunc16)intersector::occluded, \
  392. TOSTRING(isa) "::" TOSTRING(symbol)); \
  393. }
  394. #define DEFINE_INTERSECTORN(symbol,intersector) \
  395. Accel::IntersectorN symbol() { \
  396. return Accel::IntersectorN((Accel::IntersectFuncN)intersector::intersect, \
  397. (Accel::OccludedFuncN)intersector::occluded, \
  398. TOSTRING(isa) "::" TOSTRING(symbol)); \
  399. }
  400. /* ray stream filter interface */
  401. typedef void (*filterAOS_func)(Scene *scene, RTCRay* _rayN, const size_t N, const size_t stride, IntersectContext* context, const bool intersect);
  402. typedef void (*filterAOP_func)(Scene *scene, RTCRay** _rayN, const size_t N, IntersectContext* context, const bool intersect);
  403. typedef void (*filterSOA_func)(Scene *scene, char* rayN, const size_t N, const size_t streams, const size_t stream_offset, IntersectContext* context, const bool intersect);
  404. typedef void (*filterSOP_func)(Scene *scene, const RTCRayNp& rayN, const size_t N, IntersectContext* context, const bool intersect);
  405. struct RayStreamFilterFuncs
  406. {
  407. RayStreamFilterFuncs()
  408. : filterAOS(nullptr), filterSOA(nullptr), filterSOP(nullptr) {}
  409. RayStreamFilterFuncs(void (*ptr) ())
  410. : filterAOS((filterAOS_func) ptr), filterSOA((filterSOA_func) ptr), filterSOP((filterSOP_func) ptr) {}
  411. RayStreamFilterFuncs(filterAOS_func aos, filterAOP_func aop, filterSOA_func soa, filterSOP_func sop)
  412. : filterAOS(aos), filterAOP(aop), filterSOA(soa), filterSOP(sop) {}
  413. public:
  414. filterAOS_func filterAOS;
  415. filterAOP_func filterAOP;
  416. filterSOA_func filterSOA;
  417. filterSOP_func filterSOP;
  418. };
  419. typedef RayStreamFilterFuncs (*RayStreamFilterFuncsType)();
  420. }