bvh_builder_sah.cpp 27 KB

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