bvh_builder_sah.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include "bvh.h"
  4. #include "bvh_builder.h"
  5. #include "../builders/primrefgen.h"
  6. #include "../builders/splitter.h"
  7. #include "../geometry/linei.h"
  8. #include "../geometry/triangle.h"
  9. #include "../geometry/trianglev.h"
  10. #include "../geometry/trianglev_mb.h"
  11. #include "../geometry/trianglei.h"
  12. #include "../geometry/quadv.h"
  13. #include "../geometry/quadi.h"
  14. #include "../geometry/object.h"
  15. #include "../geometry/instance.h"
  16. #include "../geometry/subgrid.h"
  17. #include "../common/state.h"
  18. #include "../../common/algorithms/parallel_for_for.h"
  19. #include "../../common/algorithms/parallel_for_for_prefix_sum.h"
  20. #define PROFILE 0
  21. #define PROFILE_RUNS 20
  22. namespace embree
  23. {
  24. namespace isa
  25. {
  26. template<int N, typename Primitive>
  27. struct CreateLeaf
  28. {
  29. typedef BVHN<N> BVH;
  30. typedef typename BVH::NodeRef NodeRef;
  31. __forceinline CreateLeaf (BVH* bvh) : bvh(bvh) {}
  32. __forceinline NodeRef operator() (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) const
  33. {
  34. size_t n = set.size();
  35. size_t items = Primitive::blocks(n);
  36. size_t start = set.begin();
  37. Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
  38. typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
  39. for (size_t i=0; i<items; i++) {
  40. accel[i].fill(prims,start,set.end(),bvh->scene);
  41. }
  42. return node;
  43. }
  44. BVH* bvh;
  45. };
  46. template<int N, typename Primitive>
  47. struct CreateLeafQuantized
  48. {
  49. typedef BVHN<N> BVH;
  50. typedef typename BVH::NodeRef NodeRef;
  51. __forceinline CreateLeafQuantized (BVH* bvh) : bvh(bvh) {}
  52. __forceinline NodeRef operator() (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) const
  53. {
  54. size_t n = set.size();
  55. size_t items = Primitive::blocks(n);
  56. size_t start = set.begin();
  57. Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
  58. typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
  59. for (size_t i=0; i<items; i++) {
  60. accel[i].fill(prims,start,set.end(),bvh->scene);
  61. }
  62. return node;
  63. }
  64. BVH* bvh;
  65. };
  66. /************************************************************************************/
  67. /************************************************************************************/
  68. /************************************************************************************/
  69. /************************************************************************************/
  70. template<int N, typename Primitive>
  71. struct BVHNBuilderSAH : public Builder
  72. {
  73. typedef BVHN<N> BVH;
  74. typedef typename BVHN<N>::NodeRef NodeRef;
  75. BVH* bvh;
  76. Scene* scene;
  77. Geometry* mesh;
  78. mvector<PrimRef> prims;
  79. GeneralBVHBuilder::Settings settings;
  80. Geometry::GTypeMask gtype_;
  81. unsigned int geomID_ = std::numeric_limits<unsigned int>::max ();
  82. bool primrefarrayalloc;
  83. unsigned int numPreviousPrimitives = 0;
  84. BVHNBuilderSAH (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize,
  85. const Geometry::GTypeMask gtype, bool primrefarrayalloc = false)
  86. : bvh(bvh), scene(scene), mesh(nullptr), prims(scene->device,0),
  87. settings(sahBlockSize, minLeafSize, min(maxLeafSize,Primitive::max_size()*BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD), gtype_(gtype), primrefarrayalloc(primrefarrayalloc) {}
  88. BVHNBuilderSAH (BVH* bvh, Geometry* mesh, unsigned int geomID, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const Geometry::GTypeMask gtype)
  89. : bvh(bvh), scene(nullptr), mesh(mesh), prims(bvh->device,0), settings(sahBlockSize, minLeafSize, min(maxLeafSize,Primitive::max_size()*BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD), gtype_(gtype), geomID_(geomID), primrefarrayalloc(false) {}
  90. // FIXME: shrink bvh->alloc in destructor here and in other builders too
  91. void build()
  92. {
  93. /* we reset the allocator when the mesh size changed */
  94. if (mesh && mesh->numPrimitives != numPreviousPrimitives) {
  95. bvh->alloc.clear();
  96. }
  97. /* if we use the primrefarray for allocations we have to take it back from the BVH */
  98. if (settings.primrefarrayalloc != size_t(inf))
  99. bvh->alloc.unshare(prims);
  100. /* skip build for empty scene */
  101. const size_t numPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(gtype_,false);
  102. numPreviousPrimitives = numPrimitives;
  103. if (numPrimitives == 0) {
  104. bvh->clear();
  105. prims.clear();
  106. return;
  107. }
  108. double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::BVH" + toString(N) + "BuilderSAH");
  109. #if PROFILE
  110. profile(2,PROFILE_RUNS,numPrimitives,[&] (ProfileTimer& timer) {
  111. #endif
  112. /* create primref array */
  113. if (primrefarrayalloc) {
  114. settings.primrefarrayalloc = numPrimitives/1000;
  115. if (settings.primrefarrayalloc < 1000)
  116. settings.primrefarrayalloc = inf;
  117. }
  118. /* enable os_malloc for two level build */
  119. if (mesh)
  120. bvh->alloc.setOSallocation(true);
  121. /* initialize allocator */
  122. const size_t node_bytes = numPrimitives*sizeof(typename BVH::AABBNodeMB)/(4*N);
  123. const size_t leaf_bytes = size_t(1.2*Primitive::blocks(numPrimitives)*sizeof(Primitive));
  124. bvh->alloc.init_estimate(node_bytes+leaf_bytes);
  125. settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,numPrimitives,node_bytes+leaf_bytes);
  126. prims.resize(numPrimitives);
  127. PrimInfo pinfo = mesh ?
  128. createPrimRefArray(mesh,geomID_,numPrimitives,prims,bvh->scene->progressInterface) :
  129. createPrimRefArray(scene,gtype_,false,numPrimitives,prims,bvh->scene->progressInterface);
  130. /* pinfo might has zero size due to invalid geometry */
  131. if (unlikely(pinfo.size() == 0))
  132. {
  133. bvh->clear();
  134. prims.clear();
  135. return;
  136. }
  137. /* call BVH builder */
  138. NodeRef root = BVHNBuilderVirtual<N>::build(&bvh->alloc,CreateLeaf<N,Primitive>(bvh),bvh->scene->progressInterface,prims.data(),pinfo,settings);
  139. bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());
  140. bvh->layoutLargeNodes(size_t(pinfo.size()*0.005f));
  141. #if PROFILE
  142. });
  143. #endif
  144. /* if we allocated using the primrefarray we have to keep it alive */
  145. if (settings.primrefarrayalloc != size_t(inf))
  146. bvh->alloc.share(prims);
  147. /* for static geometries we can do some cleanups */
  148. else if (scene && scene->isStaticAccel()) {
  149. prims.clear();
  150. }
  151. bvh->cleanup();
  152. bvh->postBuild(t0);
  153. }
  154. void clear() {
  155. prims.clear();
  156. }
  157. };
  158. /************************************************************************************/
  159. /************************************************************************************/
  160. /************************************************************************************/
  161. /************************************************************************************/
  162. template<int N, typename Primitive>
  163. struct BVHNBuilderSAHQuantized : public Builder
  164. {
  165. typedef BVHN<N> BVH;
  166. typedef typename BVHN<N>::NodeRef NodeRef;
  167. BVH* bvh;
  168. Scene* scene;
  169. Geometry* mesh;
  170. mvector<PrimRef> prims;
  171. GeneralBVHBuilder::Settings settings;
  172. Geometry::GTypeMask gtype_;
  173. unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
  174. unsigned int numPreviousPrimitives = 0;
  175. BVHNBuilderSAHQuantized (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const Geometry::GTypeMask gtype)
  176. : bvh(bvh), scene(scene), mesh(nullptr), prims(scene->device,0), settings(sahBlockSize, minLeafSize, min(maxLeafSize,Primitive::max_size()*BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD), gtype_(gtype) {}
  177. BVHNBuilderSAHQuantized (BVH* bvh, Geometry* mesh, unsigned int geomID, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const Geometry::GTypeMask gtype)
  178. : bvh(bvh), scene(nullptr), mesh(mesh), prims(bvh->device,0), settings(sahBlockSize, minLeafSize, min(maxLeafSize,Primitive::max_size()*BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD), gtype_(gtype), geomID_(geomID) {}
  179. // FIXME: shrink bvh->alloc in destructor here and in other builders too
  180. void build()
  181. {
  182. /* we reset the allocator when the mesh size changed */
  183. if (mesh && mesh->numPrimitives != numPreviousPrimitives) {
  184. bvh->alloc.clear();
  185. }
  186. /* skip build for empty scene */
  187. const size_t numPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(gtype_,false);
  188. numPreviousPrimitives = numPrimitives;
  189. if (numPrimitives == 0) {
  190. prims.clear();
  191. bvh->clear();
  192. return;
  193. }
  194. double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::QBVH" + toString(N) + "BuilderSAH");
  195. #if PROFILE
  196. profile(2,PROFILE_RUNS,numPrimitives,[&] (ProfileTimer& timer) {
  197. #endif
  198. /* create primref array */
  199. prims.resize(numPrimitives);
  200. PrimInfo pinfo = mesh ?
  201. createPrimRefArray(mesh,geomID_,numPrimitives,prims,bvh->scene->progressInterface) :
  202. createPrimRefArray(scene,gtype_,false,numPrimitives,prims,bvh->scene->progressInterface);
  203. /* enable os_malloc for two level build */
  204. if (mesh)
  205. bvh->alloc.setOSallocation(true);
  206. /* call BVH builder */
  207. const size_t node_bytes = numPrimitives*sizeof(typename BVH::QuantizedNode)/(4*N);
  208. const size_t leaf_bytes = size_t(1.2*Primitive::blocks(numPrimitives)*sizeof(Primitive));
  209. bvh->alloc.init_estimate(node_bytes+leaf_bytes);
  210. settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,numPrimitives,node_bytes+leaf_bytes);
  211. NodeRef root = BVHNBuilderQuantizedVirtual<N>::build(&bvh->alloc,CreateLeafQuantized<N,Primitive>(bvh),bvh->scene->progressInterface,prims.data(),pinfo,settings);
  212. bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());
  213. //bvh->layoutLargeNodes(pinfo.size()*0.005f); // FIXME: COPY LAYOUT FOR LARGE NODES !!!
  214. #if PROFILE
  215. });
  216. #endif
  217. /* clear temporary data for static geometry */
  218. if (scene && scene->isStaticAccel()) {
  219. prims.clear();
  220. }
  221. bvh->cleanup();
  222. bvh->postBuild(t0);
  223. }
  224. void clear() {
  225. prims.clear();
  226. }
  227. };
  228. /************************************************************************************/
  229. /************************************************************************************/
  230. /************************************************************************************/
  231. /************************************************************************************/
  232. template<int N, typename Primitive>
  233. struct CreateLeafGrid
  234. {
  235. typedef BVHN<N> BVH;
  236. typedef typename BVH::NodeRef NodeRef;
  237. __forceinline CreateLeafGrid (BVH* bvh, const SubGridBuildData * const sgrids) : bvh(bvh),sgrids(sgrids) {}
  238. __forceinline NodeRef operator() (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) const
  239. {
  240. const size_t items = set.size(); //Primitive::blocks(n);
  241. const size_t start = set.begin();
  242. /* collect all subsets with unique geomIDs */
  243. assert(items <= N);
  244. unsigned int geomIDs[N];
  245. unsigned int num_geomIDs = 1;
  246. geomIDs[0] = prims[start].geomID();
  247. for (size_t i=1;i<items;i++)
  248. {
  249. bool found = false;
  250. const unsigned int new_geomID = prims[start+i].geomID();
  251. for (size_t j=0;j<num_geomIDs;j++)
  252. if (new_geomID == geomIDs[j])
  253. { found = true; break; }
  254. if (!found)
  255. geomIDs[num_geomIDs++] = new_geomID;
  256. }
  257. /* allocate all leaf memory in one single block */
  258. SubGridQBVHN<N>* accel = (SubGridQBVHN<N>*) alloc.malloc1(num_geomIDs*sizeof(SubGridQBVHN<N>),BVH::byteAlignment);
  259. typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,num_geomIDs);
  260. for (size_t g=0;g<num_geomIDs;g++)
  261. {
  262. unsigned int x[N];
  263. unsigned int y[N];
  264. unsigned int primID[N];
  265. BBox3fa bounds[N];
  266. unsigned int pos = 0;
  267. for (size_t i=0;i<items;i++)
  268. {
  269. if (unlikely(prims[start+i].geomID() != geomIDs[g])) continue;
  270. const SubGridBuildData& sgrid_bd = sgrids[prims[start+i].primID()];
  271. x[pos] = sgrid_bd.sx;
  272. y[pos] = sgrid_bd.sy;
  273. primID[pos] = sgrid_bd.primID;
  274. bounds[pos] = prims[start+i].bounds();
  275. pos++;
  276. }
  277. assert(pos <= N);
  278. new (&accel[g]) SubGridQBVHN<N>(x,y,primID,bounds,geomIDs[g],pos);
  279. }
  280. return node;
  281. }
  282. BVH* bvh;
  283. const SubGridBuildData * const sgrids;
  284. };
  285. template<int N>
  286. struct BVHNBuilderSAHGrid : public Builder
  287. {
  288. typedef BVHN<N> BVH;
  289. typedef typename BVHN<N>::NodeRef NodeRef;
  290. BVH* bvh;
  291. Scene* scene;
  292. GridMesh* mesh;
  293. mvector<PrimRef> prims;
  294. mvector<SubGridBuildData> sgrids;
  295. GeneralBVHBuilder::Settings settings;
  296. const unsigned int geomID_ = std::numeric_limits<unsigned int>::max();
  297. unsigned int numPreviousPrimitives = 0;
  298. BVHNBuilderSAHGrid (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const size_t mode)
  299. : bvh(bvh), scene(scene), mesh(nullptr), prims(scene->device,0), sgrids(scene->device,0), settings(sahBlockSize, minLeafSize, min(maxLeafSize,BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD) {}
  300. BVHNBuilderSAHGrid (BVH* bvh, GridMesh* mesh, unsigned int geomID, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const size_t mode)
  301. : bvh(bvh), scene(nullptr), mesh(mesh), prims(bvh->device,0), sgrids(scene->device,0), settings(sahBlockSize, minLeafSize, min(maxLeafSize,BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD), geomID_(geomID) {}
  302. void build()
  303. {
  304. /* we reset the allocator when the mesh size changed */
  305. if (mesh && mesh->numPrimitives != numPreviousPrimitives) {
  306. bvh->alloc.clear();
  307. }
  308. /* if we use the primrefarray for allocations we have to take it back from the BVH */
  309. if (settings.primrefarrayalloc != size_t(inf))
  310. bvh->alloc.unshare(prims);
  311. const size_t numGridPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(GridMesh::geom_type,false);
  312. numPreviousPrimitives = numGridPrimitives;
  313. PrimInfo pinfo = mesh ? createPrimRefArrayGrids(mesh,prims,sgrids) : createPrimRefArrayGrids(scene,prims,sgrids);
  314. const size_t numPrimitives = pinfo.size();
  315. /* no primitives */
  316. if (numPrimitives == 0) {
  317. bvh->clear();
  318. prims.clear();
  319. sgrids.clear();
  320. return;
  321. }
  322. double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::BVH" + toString(N) + "BuilderSAH");
  323. /* create primref array */
  324. settings.primrefarrayalloc = numPrimitives/1000;
  325. if (settings.primrefarrayalloc < 1000)
  326. settings.primrefarrayalloc = inf;
  327. /* enable os_malloc for two level build */
  328. if (mesh)
  329. bvh->alloc.setOSallocation(true);
  330. /* initialize allocator */
  331. const size_t node_bytes = numPrimitives*sizeof(typename BVH::AABBNodeMB)/(4*N);
  332. const size_t leaf_bytes = size_t(1.2*(float)numPrimitives/N * sizeof(SubGridQBVHN<N>));
  333. bvh->alloc.init_estimate(node_bytes+leaf_bytes);
  334. settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,numPrimitives,node_bytes+leaf_bytes);
  335. /* pinfo might has zero size due to invalid geometry */
  336. if (unlikely(pinfo.size() == 0))
  337. {
  338. bvh->clear();
  339. sgrids.clear();
  340. prims.clear();
  341. return;
  342. }
  343. /* call BVH builder */
  344. NodeRef root = BVHNBuilderVirtual<N>::build(&bvh->alloc,CreateLeafGrid<N,SubGridQBVHN<N>>(bvh,sgrids.data()),bvh->scene->progressInterface,prims.data(),pinfo,settings);
  345. bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());
  346. bvh->layoutLargeNodes(size_t(pinfo.size()*0.005f));
  347. /* clear temporary array */
  348. sgrids.clear();
  349. /* if we allocated using the primrefarray we have to keep it alive */
  350. if (settings.primrefarrayalloc != size_t(inf))
  351. bvh->alloc.share(prims);
  352. /* for static geometries we can do some cleanups */
  353. else if (scene && scene->isStaticAccel()) {
  354. prims.clear();
  355. }
  356. bvh->cleanup();
  357. bvh->postBuild(t0);
  358. }
  359. void clear() {
  360. prims.clear();
  361. }
  362. };
  363. /************************************************************************************/
  364. /************************************************************************************/
  365. /************************************************************************************/
  366. /************************************************************************************/
  367. #if defined(EMBREE_GEOMETRY_TRIANGLE)
  368. Builder* BVH4Triangle4MeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Triangle4>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); }
  369. Builder* BVH4Triangle4vMeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Triangle4v>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); }
  370. Builder* BVH4Triangle4iMeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Triangle4i>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); }
  371. Builder* BVH4Triangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  372. Builder* BVH4Triangle4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4v>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  373. Builder* BVH4Triangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4i>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type,true); }
  374. Builder* BVH4QuantizedTriangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Triangle4i>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  375. #if defined(__AVX__)
  376. Builder* BVH8Triangle4MeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<8,Triangle4>((BVH8*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); }
  377. Builder* BVH8Triangle4vMeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<8,Triangle4v>((BVH8*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); }
  378. Builder* BVH8Triangle4iMeshBuilderSAH (void* bvh, TriangleMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<8,Triangle4i>((BVH8*)bvh,mesh,geomID,4,1.0f,4,inf,TriangleMesh::geom_type); }
  379. Builder* BVH8Triangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Triangle4>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  380. Builder* BVH8Triangle4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Triangle4v>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  381. Builder* BVH8Triangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Triangle4i>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type,true); }
  382. Builder* BVH8QuantizedTriangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Triangle4i>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  383. Builder* BVH8QuantizedTriangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Triangle4>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }
  384. #endif
  385. #endif
  386. #if defined(EMBREE_GEOMETRY_QUAD)
  387. Builder* BVH4Quad4vMeshBuilderSAH (void* bvh, QuadMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Quad4v>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,QuadMesh::geom_type); }
  388. Builder* BVH4Quad4iMeshBuilderSAH (void* bvh, QuadMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<4,Quad4i>((BVH4*)bvh,mesh,geomID,4,1.0f,4,inf,QuadMesh::geom_type); }
  389. Builder* BVH4Quad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Quad4v>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }
  390. Builder* BVH4Quad4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Quad4i>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type,true); }
  391. Builder* BVH4QuantizedQuad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Quad4v>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }
  392. Builder* BVH4QuantizedQuad4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Quad4i>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }
  393. #if defined(__AVX__)
  394. Builder* BVH8Quad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Quad4v>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }
  395. Builder* BVH8Quad4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Quad4i>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type,true); }
  396. Builder* BVH8QuantizedQuad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Quad4v>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }
  397. Builder* BVH8QuantizedQuad4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Quad4i>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }
  398. Builder* BVH8Quad4vMeshBuilderSAH (void* bvh, QuadMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAH<8,Quad4v>((BVH8*)bvh,mesh,geomID,4,1.0f,4,inf,QuadMesh::geom_type); }
  399. #endif
  400. #endif
  401. #if defined(EMBREE_GEOMETRY_USER)
  402. Builder* BVH4VirtualSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) {
  403. int minLeafSize = scene->device->object_accel_min_leaf_size;
  404. int maxLeafSize = scene->device->object_accel_max_leaf_size;
  405. return new BVHNBuilderSAH<4,Object>((BVH4*)bvh,scene,4,1.0f,minLeafSize,maxLeafSize,UserGeometry::geom_type);
  406. }
  407. Builder* BVH4VirtualMeshBuilderSAH (void* bvh, UserGeometry* mesh, unsigned int geomID, size_t mode) {
  408. return new BVHNBuilderSAH<4,Object>((BVH4*)bvh,mesh,geomID,4,1.0f,1,inf,UserGeometry::geom_type);
  409. }
  410. #if defined(__AVX__)
  411. Builder* BVH8VirtualSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) {
  412. int minLeafSize = scene->device->object_accel_min_leaf_size;
  413. int maxLeafSize = scene->device->object_accel_max_leaf_size;
  414. return new BVHNBuilderSAH<8,Object>((BVH8*)bvh,scene,8,1.0f,minLeafSize,maxLeafSize,UserGeometry::geom_type);
  415. }
  416. Builder* BVH8VirtualMeshBuilderSAH (void* bvh, UserGeometry* mesh, unsigned int geomID, size_t mode) {
  417. return new BVHNBuilderSAH<8,Object>((BVH8*)bvh,mesh,geomID,8,1.0f,1,inf,UserGeometry::geom_type);
  418. }
  419. #endif
  420. #endif
  421. #if defined(EMBREE_GEOMETRY_INSTANCE)
  422. Builder* BVH4InstanceSceneBuilderSAH (void* bvh, Scene* scene, Geometry::GTypeMask gtype) { return new BVHNBuilderSAH<4,InstancePrimitive>((BVH4*)bvh,scene,4,1.0f,1,1,gtype); }
  423. Builder* BVH4InstanceMeshBuilderSAH (void* bvh, Instance* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) {
  424. return new BVHNBuilderSAH<4,InstancePrimitive>((BVH4*)bvh,mesh,geomID,4,1.0f,1,inf,gtype);
  425. }
  426. #if defined(__AVX__)
  427. Builder* BVH8InstanceSceneBuilderSAH (void* bvh, Scene* scene, Geometry::GTypeMask gtype) { return new BVHNBuilderSAH<8,InstancePrimitive>((BVH8*)bvh,scene,8,1.0f,1,1,gtype); }
  428. Builder* BVH8InstanceMeshBuilderSAH (void* bvh, Instance* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) {
  429. return new BVHNBuilderSAH<8,InstancePrimitive>((BVH8*)bvh,mesh,geomID,8,1.0f,1,inf,gtype);
  430. }
  431. #endif
  432. #endif
  433. #if defined(EMBREE_GEOMETRY_GRID)
  434. Builder* BVH4GridMeshBuilderSAH (void* bvh, GridMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAHGrid<4>((BVH4*)bvh,mesh,geomID,4,1.0f,4,4,mode); }
  435. Builder* BVH4GridSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHGrid<4>((BVH4*)bvh,scene,4,1.0f,4,4,mode); } // FIXME: check whether cost factors are correct
  436. #if defined(__AVX__)
  437. Builder* BVH8GridMeshBuilderSAH (void* bvh, GridMesh* mesh, unsigned int geomID, size_t mode) { return new BVHNBuilderSAHGrid<8>((BVH8*)bvh,mesh,geomID,8,1.0f,8,8,mode); }
  438. Builder* BVH8GridSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHGrid<8>((BVH8*)bvh,scene,8,1.0f,8,8,mode); } // FIXME: check whether cost factors are correct
  439. #endif
  440. #endif
  441. }
  442. }