primrefgen.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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 "primrefgen.h"
  17. #include "../../common/algorithms/parallel_for_for.h"
  18. #include "../../common/algorithms/parallel_for_for_prefix_sum.h"
  19. namespace embree
  20. {
  21. namespace isa
  22. {
  23. template<typename Mesh>
  24. PrimInfo createPrimRefArray(Mesh* mesh, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor)
  25. {
  26. ParallelPrefixSumState<PrimInfo> pstate;
  27. /* first try */
  28. progressMonitor(0);
  29. PrimInfo pinfo = parallel_prefix_sum( pstate, size_t(0), mesh->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo
  30. {
  31. size_t k = r.begin();
  32. PrimInfo pinfo(empty);
  33. for (size_t j=r.begin(); j<r.end(); j++)
  34. {
  35. BBox3fa bounds = empty;
  36. if (!mesh->buildBounds(j,&bounds)) continue;
  37. const PrimRef prim(bounds,mesh->id,unsigned(j));
  38. pinfo.add(bounds,bounds.center2());
  39. prims[k++] = prim;
  40. }
  41. return pinfo;
  42. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  43. /* if we need to filter out geometry, run again */
  44. if (pinfo.size() != prims.size())
  45. {
  46. progressMonitor(0);
  47. pinfo = parallel_prefix_sum( pstate, size_t(0), mesh->size(), size_t(1024), PrimInfo(empty), [&](const range<size_t>& r, const PrimInfo& base) -> PrimInfo
  48. {
  49. size_t k = base.size();
  50. PrimInfo pinfo(empty);
  51. for (size_t j=r.begin(); j<r.end(); j++)
  52. {
  53. BBox3fa bounds = empty;
  54. if (!mesh->buildBounds(j,&bounds)) continue;
  55. const PrimRef prim(bounds,mesh->id,unsigned(j));
  56. pinfo.add(bounds,bounds.center2());
  57. prims[k++] = prim;
  58. }
  59. return pinfo;
  60. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  61. }
  62. return pinfo;
  63. }
  64. template<typename Mesh, bool mblur>
  65. PrimInfo createPrimRefArray(Scene* scene, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor)
  66. {
  67. ParallelForForPrefixSumState<PrimInfo> pstate;
  68. Scene::Iterator<Mesh,mblur> iter(scene);
  69. /* first try */
  70. progressMonitor(0);
  71. pstate.init(iter,size_t(1024));
  72. PrimInfo pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Mesh* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  73. {
  74. PrimInfo pinfo(empty);
  75. for (size_t j=r.begin(); j<r.end(); j++)
  76. {
  77. BBox3fa bounds = empty;
  78. if (!mesh->buildBounds(j,&bounds)) continue;
  79. const PrimRef prim(bounds,mesh->id,unsigned(j));
  80. pinfo.add(bounds,bounds.center2());
  81. prims[k++] = prim;
  82. }
  83. return pinfo;
  84. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  85. /* if we need to filter out geometry, run again */
  86. if (pinfo.size() != prims.size())
  87. {
  88. progressMonitor(0);
  89. pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Mesh* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  90. {
  91. k = base.size();
  92. PrimInfo pinfo(empty);
  93. for (size_t j=r.begin(); j<r.end(); j++)
  94. {
  95. BBox3fa bounds = empty;
  96. if (!mesh->buildBounds(j,&bounds)) continue;
  97. const PrimRef prim(bounds,mesh->id,unsigned(j));
  98. pinfo.add(bounds,bounds.center2());
  99. prims[k++] = prim;
  100. }
  101. return pinfo;
  102. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  103. }
  104. return pinfo;
  105. }
  106. template<typename Mesh>
  107. PrimInfo createPrimRefArrayMBlur(size_t timeSegment, size_t numTimeSteps, Scene* scene, mvector<PrimRef>& prims, BuildProgressMonitor& progressMonitor)
  108. {
  109. ParallelForForPrefixSumState<PrimInfo> pstate;
  110. Scene::Iterator<Mesh,true> iter(scene);
  111. /* first try */
  112. progressMonitor(0);
  113. pstate.init(iter,size_t(1024));
  114. PrimInfo pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Mesh* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  115. {
  116. PrimInfo pinfo(empty);
  117. for (size_t j=r.begin(); j<r.end(); j++)
  118. {
  119. BBox3fa bounds = empty;
  120. if (!mesh->buildBounds(j,timeSegment,numTimeSteps,bounds)) continue;
  121. const PrimRef prim(bounds,mesh->id,unsigned(j));
  122. pinfo.add(bounds,bounds.center2());
  123. prims[k++] = prim;
  124. }
  125. return pinfo;
  126. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  127. /* if we need to filter out geometry, run again */
  128. if (pinfo.size() != prims.size())
  129. {
  130. progressMonitor(0);
  131. pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](Mesh* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  132. {
  133. k = base.size();
  134. PrimInfo pinfo(empty);
  135. for (size_t j=r.begin(); j<r.end(); j++)
  136. {
  137. BBox3fa bounds = empty;
  138. if (!mesh->buildBounds(j,timeSegment,numTimeSteps,bounds)) continue;
  139. const PrimRef prim(bounds,mesh->id,unsigned(j));
  140. pinfo.add(bounds,bounds.center2());
  141. prims[k++] = prim;
  142. }
  143. return pinfo;
  144. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  145. }
  146. return pinfo;
  147. }
  148. PrimInfo createBezierRefArray(Scene* scene, mvector<BezierPrim>& prims, BuildProgressMonitor& progressMonitor)
  149. {
  150. ParallelForForPrefixSumState<PrimInfo> pstate;
  151. Scene::Iterator<NativeCurves,false> iter(scene);
  152. /* first try */
  153. progressMonitor(0);
  154. pstate.init(iter,size_t(1024));
  155. PrimInfo pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](NativeCurves* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  156. {
  157. PrimInfo pinfo(empty);
  158. for (size_t j=r.begin(); j<r.end(); j++)
  159. {
  160. const size_t ofs = mesh->curve(j);
  161. if ((ssize_t)ofs < 0 || ofs+3 >= mesh->numVertices())
  162. continue;
  163. Vec3fa p0 = mesh->vertex(ofs+0,0);
  164. Vec3fa p1 = mesh->vertex(ofs+1,0);
  165. Vec3fa p2 = mesh->vertex(ofs+2,0);
  166. Vec3fa p3 = mesh->vertex(ofs+3,0);
  167. if (!isvalid((vfloat4)p0) || !isvalid((vfloat4)p1) || !isvalid((vfloat4)p2) || !isvalid((vfloat4)p3))
  168. continue;
  169. const BezierPrim bezier(mesh->subtype,p0,p1,p2,p3,mesh->tessellationRate,mesh->id,unsigned(j));
  170. const BBox3fa bounds = bezier.bounds();
  171. pinfo.add(bounds);
  172. prims[k++] = bezier;
  173. }
  174. return pinfo;
  175. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  176. /* if we need to filter out geometry, run again */
  177. if (pinfo.size() != prims.size())
  178. {
  179. progressMonitor(0);
  180. pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](NativeCurves* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  181. {
  182. k = base.size();
  183. PrimInfo pinfo(empty);
  184. for (size_t j=r.begin(); j<r.end(); j++)
  185. {
  186. const size_t ofs = mesh->curve(j);
  187. if ((ssize_t)ofs < 0 || ofs+3 >= mesh->numVertices())
  188. continue;
  189. Vec3fa p0 = mesh->vertex(ofs+0,0);
  190. Vec3fa p1 = mesh->vertex(ofs+1,0);
  191. Vec3fa p2 = mesh->vertex(ofs+2,0);
  192. Vec3fa p3 = mesh->vertex(ofs+3,0);
  193. if (!isvalid((vfloat4)p0) || !isvalid((vfloat4)p1) || !isvalid((vfloat4)p2) || !isvalid((vfloat4)p3))
  194. continue;
  195. const BezierPrim bezier(mesh->subtype,p0,p1,p2,p3,mesh->tessellationRate,mesh->id,unsigned(j));
  196. const BBox3fa bounds = bezier.bounds();
  197. pinfo.add(bounds);
  198. prims[k++] = bezier;
  199. }
  200. return pinfo;
  201. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  202. }
  203. return pinfo;
  204. }
  205. PrimInfo createBezierRefArrayMBlur(size_t timeSegment, size_t numTimeSteps, Scene* scene, mvector<BezierPrim>& prims, BuildProgressMonitor& progressMonitor)
  206. {
  207. ParallelForForPrefixSumState<PrimInfo> pstate;
  208. Scene::Iterator<NativeCurves,true> iter(scene);
  209. /* first try */
  210. progressMonitor(0);
  211. pstate.init(iter,size_t(1024));
  212. PrimInfo pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](NativeCurves* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  213. {
  214. PrimInfo pinfo(empty);
  215. for (size_t j=r.begin(); j<r.end(); j++)
  216. {
  217. Vec3fa c0,c1,c2,c3;
  218. if (!mesh->buildPrim(j,timeSegment,numTimeSteps,c0,c1,c2,c3)) continue;
  219. const BezierPrim bezier(mesh->subtype,c0,c1,c2,c3,mesh->tessellationRate,mesh->id,unsigned(j));
  220. pinfo.add(bezier.bounds());
  221. prims[k++] = bezier;
  222. }
  223. return pinfo;
  224. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  225. /* if we need to filter out geometry, run again */
  226. if (pinfo.size() != prims.size())
  227. {
  228. progressMonitor(0);
  229. pinfo = parallel_for_for_prefix_sum( pstate, iter, PrimInfo(empty), [&](NativeCurves* mesh, const range<size_t>& r, size_t k, const PrimInfo& base) -> PrimInfo
  230. {
  231. k = base.size();
  232. PrimInfo pinfo(empty);
  233. for (size_t j=r.begin(); j<r.end(); j++)
  234. {
  235. Vec3fa c0,c1,c2,c3;
  236. if (!mesh->buildPrim(j,timeSegment,numTimeSteps,c0,c1,c2,c3)) continue;
  237. const BezierPrim bezier(mesh->subtype,c0,c1,c2,c3,mesh->tessellationRate,mesh->id,unsigned(j));
  238. pinfo.add(bezier.bounds());
  239. prims[k++] = bezier;
  240. }
  241. return pinfo;
  242. }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); });
  243. }
  244. return pinfo;
  245. }
  246. template<typename Mesh>
  247. size_t createMortonCodeArray(Mesh* mesh, mvector<BVHBuilderMorton::BuildPrim>& morton, BuildProgressMonitor& progressMonitor)
  248. {
  249. size_t numPrimitives = morton.size();
  250. /* compute scene bounds */
  251. std::pair<size_t,BBox3fa> cb_empty(0,empty);
  252. auto cb = parallel_reduce
  253. ( size_t(0), numPrimitives, size_t(1024), cb_empty, [&](const range<size_t>& r) -> std::pair<size_t,BBox3fa>
  254. {
  255. size_t num = 0;
  256. BBox3fa bounds = empty;
  257. for (size_t j=r.begin(); j<r.end(); j++)
  258. {
  259. BBox3fa prim_bounds = empty;
  260. if (unlikely(!mesh->buildBounds(j,&prim_bounds))) continue;
  261. bounds.extend(center2(prim_bounds));
  262. num++;
  263. }
  264. return std::make_pair(num,bounds);
  265. }, [] (const std::pair<size_t,BBox3fa>& a, const std::pair<size_t,BBox3fa>& b) {
  266. return std::make_pair(a.first + b.first,merge(a.second,b.second));
  267. });
  268. size_t numPrimitivesGen = cb.first;
  269. const BBox3fa centBounds = cb.second;
  270. /* compute morton codes */
  271. if (likely(numPrimitivesGen == numPrimitives))
  272. {
  273. /* fast path if all primitives were valid */
  274. BVHBuilderMorton::MortonCodeMapping mapping(centBounds);
  275. parallel_for( size_t(0), numPrimitives, size_t(1024), [&](const range<size_t>& r) -> void {
  276. BVHBuilderMorton::MortonCodeGenerator generator(mapping,&morton.data()[r.begin()]);
  277. for (size_t j=r.begin(); j<r.end(); j++)
  278. generator(mesh->bounds(j),unsigned(j));
  279. });
  280. }
  281. else
  282. {
  283. /* slow path, fallback in case some primitives were invalid */
  284. ParallelPrefixSumState<size_t> pstate;
  285. BVHBuilderMorton::MortonCodeMapping mapping(centBounds);
  286. parallel_prefix_sum( pstate, size_t(0), numPrimitives, size_t(1024), size_t(0), [&](const range<size_t>& r, const size_t base) -> size_t {
  287. size_t num = 0;
  288. BVHBuilderMorton::MortonCodeGenerator generator(mapping,&morton.data()[r.begin()]);
  289. for (size_t j=r.begin(); j<r.end(); j++)
  290. {
  291. BBox3fa bounds = empty;
  292. if (unlikely(!mesh->buildBounds(j,&bounds))) continue;
  293. generator(bounds,unsigned(j));
  294. num++;
  295. }
  296. return num;
  297. }, std::plus<size_t>());
  298. parallel_prefix_sum( pstate, size_t(0), numPrimitives, size_t(1024), size_t(0), [&](const range<size_t>& r, const size_t base) -> size_t {
  299. size_t num = 0;
  300. BVHBuilderMorton::MortonCodeGenerator generator(mapping,&morton.data()[base]);
  301. for (size_t j=r.begin(); j<r.end(); j++)
  302. {
  303. BBox3fa bounds = empty;
  304. if (!mesh->buildBounds(j,&bounds)) continue;
  305. generator(bounds,unsigned(j));
  306. num++;
  307. }
  308. return num;
  309. }, std::plus<size_t>());
  310. }
  311. return numPrimitivesGen;
  312. }
  313. IF_ENABLED_TRIS (template PrimInfo createPrimRefArray<TriangleMesh>(TriangleMesh* mesh COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  314. IF_ENABLED_QUADS(template PrimInfo createPrimRefArray<QuadMesh>(QuadMesh* mesh COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  315. IF_ENABLED_HAIR (template PrimInfo createPrimRefArray<NativeCurves>(NativeCurves* mesh COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  316. IF_ENABLED_LINES(template PrimInfo createPrimRefArray<LineSegments>(LineSegments* mesh COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  317. IF_ENABLED_USER(template PrimInfo createPrimRefArray<AccelSet>(AccelSet* mesh COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  318. IF_ENABLED_TRIS (template PrimInfo createPrimRefArray<TriangleMesh COMMA false>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  319. IF_ENABLED_TRIS (template PrimInfo createPrimRefArray<TriangleMesh COMMA true>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  320. IF_ENABLED_QUADS(template PrimInfo createPrimRefArray<QuadMesh COMMA false>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  321. IF_ENABLED_QUADS(template PrimInfo createPrimRefArray<QuadMesh COMMA true>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  322. IF_ENABLED_HAIR (template PrimInfo createPrimRefArray<NativeCurves COMMA false>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  323. IF_ENABLED_LINES(template PrimInfo createPrimRefArray<LineSegments COMMA false>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  324. IF_ENABLED_LINES(template PrimInfo createPrimRefArray<LineSegments COMMA true>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  325. IF_ENABLED_USER(template PrimInfo createPrimRefArray<AccelSet COMMA false>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  326. IF_ENABLED_USER(template PrimInfo createPrimRefArray<AccelSet COMMA true>(Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  327. IF_ENABLED_TRIS (template PrimInfo createPrimRefArrayMBlur<TriangleMesh>(size_t timeSegment COMMA size_t numTimeSteps COMMA Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  328. IF_ENABLED_QUADS(template PrimInfo createPrimRefArrayMBlur<QuadMesh>(size_t timeSegment COMMA size_t numTimeSteps COMMA Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  329. IF_ENABLED_LINES(template PrimInfo createPrimRefArrayMBlur<LineSegments>(size_t timeSegment COMMA size_t numTimeSteps COMMA Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  330. IF_ENABLED_USER(template PrimInfo createPrimRefArrayMBlur<AccelSet>(size_t timeSegment COMMA size_t numTimeSteps COMMA Scene* scene COMMA mvector<PrimRef>& prims COMMA BuildProgressMonitor& progressMonitor));
  331. IF_ENABLED_TRIS (template size_t createMortonCodeArray<TriangleMesh>(TriangleMesh* mesh COMMA mvector<BVHBuilderMorton::BuildPrim>& morton COMMA BuildProgressMonitor& progressMonitor));
  332. IF_ENABLED_QUADS(template size_t createMortonCodeArray<QuadMesh>(QuadMesh* mesh COMMA mvector<BVHBuilderMorton::BuildPrim>& morton COMMA BuildProgressMonitor& progressMonitor));
  333. IF_ENABLED_USER (template size_t createMortonCodeArray<AccelSet>(AccelSet* mesh COMMA mvector<BVHBuilderMorton::BuildPrim>& morton COMMA BuildProgressMonitor& progressMonitor));
  334. }
  335. }