acceln.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. #include "acceln.h"
  17. #include "ray.h"
  18. #include "../../include/embree2/rtcore_ray.h"
  19. #include "../../common/algorithms/parallel_for.h"
  20. namespace embree
  21. {
  22. AccelN::AccelN ()
  23. : Accel(AccelData::TY_ACCELN), accels(nullptr), validAccels(nullptr), validIntersectorN(false) {}
  24. AccelN::~AccelN()
  25. {
  26. for (size_t i=0; i<accels.size(); i++)
  27. delete accels[i];
  28. }
  29. void AccelN::add(Accel* accel)
  30. {
  31. assert(accel);
  32. if (accels.size() == accels.max_size())
  33. throw_RTCError(RTC_UNKNOWN_ERROR,"internal error: AccelN too small");
  34. accels.push_back(accel);
  35. }
  36. void AccelN::intersect (void* ptr, RTCRay& ray, IntersectContext* context)
  37. {
  38. AccelN* This = (AccelN*)ptr;
  39. for (size_t i=0; i<This->validAccels.size(); i++)
  40. This->validAccels[i]->intersect(ray,context);
  41. }
  42. void AccelN::intersect4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context)
  43. {
  44. AccelN* This = (AccelN*)ptr;
  45. for (size_t i=0; i<This->validAccels.size(); i++)
  46. This->validAccels[i]->intersect4(valid,ray,context);
  47. }
  48. void AccelN::intersect8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context)
  49. {
  50. AccelN* This = (AccelN*)ptr;
  51. for (size_t i=0; i<This->validAccels.size(); i++)
  52. This->validAccels[i]->intersect8(valid,ray,context);
  53. }
  54. void AccelN::intersect16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context)
  55. {
  56. AccelN* This = (AccelN*)ptr;
  57. for (size_t i=0; i<This->validAccels.size(); i++)
  58. This->validAccels[i]->intersect16(valid,ray,context);
  59. }
  60. void AccelN::intersectN (void* ptr, RTCRay** ray, const size_t N, IntersectContext* context)
  61. {
  62. AccelN* This = (AccelN*)ptr;
  63. for (size_t i=0; i<This->validAccels.size(); i++)
  64. This->validAccels[i]->intersectN(ray,N,context);
  65. }
  66. void AccelN::occluded (void* ptr, RTCRay& ray, IntersectContext* context)
  67. {
  68. AccelN* This = (AccelN*)ptr;
  69. for (size_t i=0; i<This->validAccels.size(); i++) {
  70. This->validAccels[i]->occluded(ray,context);
  71. if (ray.geomID == 0) break;
  72. }
  73. }
  74. void AccelN::occluded4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context)
  75. {
  76. AccelN* This = (AccelN*)ptr;
  77. for (size_t i=0; i<This->validAccels.size(); i++) {
  78. This->validAccels[i]->occluded4(valid,ray,context);
  79. #if defined(__SSE2__)
  80. vbool4 valid0 = ((vbool4*)valid)[0];
  81. vbool4 hit0 = ((vint4*)ray.geomID)[0] == vint4(0);
  82. if (all(valid0,hit0)) break;
  83. #endif
  84. }
  85. }
  86. void AccelN::occluded8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context)
  87. {
  88. AccelN* This = (AccelN*)ptr;
  89. for (size_t i=0; i<This->validAccels.size(); i++) {
  90. This->validAccels[i]->occluded8(valid,ray,context);
  91. #if defined(__SSE2__) // FIXME: use AVX code
  92. vbool4 valid0 = ((vbool4*)valid)[0];
  93. vbool4 hit0 = ((vint4*)ray.geomID)[0] == vint4(0);
  94. vbool4 valid1 = ((vbool4*)valid)[1];
  95. vbool4 hit1 = ((vint4*)ray.geomID)[1] == vint4(0);
  96. if (all(valid0,hit0) && all(valid1,hit1)) break;
  97. #endif
  98. }
  99. }
  100. void AccelN::occluded16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context)
  101. {
  102. AccelN* This = (AccelN*)ptr;
  103. for (size_t i=0; i<This->validAccels.size(); i++) {
  104. This->validAccels[i]->occluded16(valid,ray,context);
  105. #if defined(__AVX512F__) // FIXME: this code gets never compiler with __AVX512F__ enabled
  106. vbool16 valid0 = ((vbool16*)valid)[0];
  107. vbool16 hit0 = ((vint16*)ray.geomID)[0] == vint16(0);
  108. if (all(valid0,hit0)) break;
  109. #endif
  110. }
  111. }
  112. void AccelN::occludedN (void* ptr, RTCRay** ray, const size_t N, IntersectContext* context)
  113. {
  114. AccelN* This = (AccelN*)ptr;
  115. size_t M = N;
  116. for (size_t i=0; i<This->validAccels.size(); i++)
  117. {
  118. This->validAccels[i]->occludedN(ray,M,context);
  119. /* only do this optimization if input rays are given in AOS format */
  120. if (context->flags == IntersectContext::INPUT_RAY_DATA_AOS)
  121. Ray::filterOutOccluded((Ray**)ray,M);
  122. if (M == 0) break;
  123. }
  124. }
  125. void AccelN::print(size_t ident)
  126. {
  127. for (size_t i=0; i<validAccels.size(); i++)
  128. {
  129. for (size_t j=0; j<ident; j++) std::cout << " ";
  130. std::cout << "accels[" << i << "]" << std::endl;
  131. validAccels[i]->intersectors.print(ident+2);
  132. }
  133. }
  134. void AccelN::immutable()
  135. {
  136. for (size_t i=0; i<accels.size(); i++)
  137. accels[i]->immutable();
  138. }
  139. void AccelN::build ()
  140. {
  141. /* build all acceleration structures in parallel */
  142. parallel_for (accels.size(), [&] (size_t i) {
  143. accels[i]->build();
  144. });
  145. /* create list of non-empty acceleration structures */
  146. validAccels.clear();
  147. validIntersectorN = true;
  148. for (size_t i=0; i<accels.size(); i++) {
  149. if (accels[i]->bounds.empty()) continue;
  150. validAccels.push_back(accels[i]);
  151. if (!accels[i]->intersectors.intersectorN) validIntersectorN = false;
  152. }
  153. if (validAccels.size() == 1) {
  154. intersectors = validAccels[0]->intersectors;
  155. }
  156. else
  157. {
  158. intersectors.ptr = this;
  159. intersectors.intersector1 = Intersector1(&intersect,&occluded,"AccelN::intersector1");
  160. intersectors.intersector4 = Intersector4(&intersect4,&occluded4,"AccelN::intersector4");
  161. intersectors.intersector8 = Intersector8(&intersect8,&occluded8,"AccelN::intersector8");
  162. intersectors.intersector16 = Intersector16(&intersect16,&occluded16,"AccelN::intersector16");
  163. intersectors.intersectorN = IntersectorN(&intersectN,&occludedN,"AccelN::intersectorN");
  164. }
  165. /*! calculate bounds */
  166. bounds = empty;
  167. for (size_t i=0; i<validAccels.size(); i++)
  168. bounds.extend(validAccels[i]->bounds);
  169. }
  170. void AccelN::select(bool filter4, bool filter8, bool filter16, bool filterN)
  171. {
  172. for (size_t i=0; i<accels.size(); i++)
  173. accels[i]->intersectors.select(filter4,filter8,filter16,filterN);
  174. }
  175. void AccelN::deleteGeometry(size_t geomID)
  176. {
  177. for (size_t i=0; i<accels.size(); i++)
  178. accels[i]->deleteGeometry(geomID);
  179. }
  180. void AccelN::clear()
  181. {
  182. for (size_t i=0; i<accels.size(); i++)
  183. accels[i]->clear();
  184. }
  185. }