Path: blob/master/thirdparty/embree/kernels/bvh/bvh_builder_sah.cpp
9906 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#include "bvh.h"4#include "bvh_builder.h"5#include "../builders/primrefgen.h"6#include "../builders/splitter.h"78#include "../geometry/linei.h"9#include "../geometry/triangle.h"10#include "../geometry/trianglev.h"11#include "../geometry/trianglev_mb.h"12#include "../geometry/trianglei.h"13#include "../geometry/quadv.h"14#include "../geometry/quadi.h"15#include "../geometry/object.h"16#include "../geometry/instance.h"17#include "../geometry/instance_array.h"18#include "../geometry/subgrid.h"1920#include "../common/state.h"21#include "../../common/algorithms/parallel_for_for.h"22#include "../../common/algorithms/parallel_for_for_prefix_sum.h"2324#define PROFILE 025#define PROFILE_RUNS 202627namespace embree28{29namespace isa30{31template<int N, typename Primitive>32struct CreateLeaf33{34typedef BVHN<N> BVH;35typedef typename BVH::NodeRef NodeRef;3637__forceinline CreateLeaf (BVH* bvh) : bvh(bvh) {}3839__forceinline NodeRef operator() (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) const40{41size_t n = set.size();42size_t items = Primitive::blocks(n);43size_t start = set.begin();44Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);45typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);46for (size_t i=0; i<items; i++) {47accel[i].fill(prims,start,set.end(),bvh->scene);48}49return node;50}5152BVH* bvh;53};545556template<int N, typename Primitive>57struct CreateLeafQuantized58{59typedef BVHN<N> BVH;60typedef typename BVH::NodeRef NodeRef;6162__forceinline CreateLeafQuantized (BVH* bvh) : bvh(bvh) {}6364__forceinline NodeRef operator() (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) const65{66size_t n = set.size();67size_t items = Primitive::blocks(n);68size_t start = set.begin();69Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);70typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);71for (size_t i=0; i<items; i++) {72accel[i].fill(prims,start,set.end(),bvh->scene);73}74return node;75}7677BVH* bvh;78};7980/************************************************************************************/81/************************************************************************************/82/************************************************************************************/83/************************************************************************************/8485template<int N, typename Primitive>86struct BVHNBuilderSAH : public Builder87{88typedef BVHN<N> BVH;89typedef typename BVHN<N>::NodeRef NodeRef;9091BVH* bvh;92Scene* scene;93Geometry* mesh;94mvector<PrimRef> prims;95GeneralBVHBuilder::Settings settings;96Geometry::GTypeMask gtype_;97unsigned int geomID_ = std::numeric_limits<unsigned int>::max ();98bool primrefarrayalloc;99unsigned int numPreviousPrimitives = 0;100101BVHNBuilderSAH (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize,102const Geometry::GTypeMask gtype, bool primrefarrayalloc = false)103: bvh(bvh), scene(scene), mesh(nullptr), prims(scene->device,0),104settings(sahBlockSize, minLeafSize, min(maxLeafSize,Primitive::max_size()*BVH::maxLeafBlocks), travCost, intCost, DEFAULT_SINGLE_THREAD_THRESHOLD), gtype_(gtype), primrefarrayalloc(primrefarrayalloc) {}105106BVHNBuilderSAH (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)107: 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) {}108109// FIXME: shrink bvh->alloc in destructor here and in other builders too110111void build()112{113/* we reset the allocator when the mesh size changed */114if (mesh && mesh->numPrimitives != numPreviousPrimitives) {115bvh->alloc.clear();116}117118/* if we use the primrefarray for allocations we have to take it back from the BVH */119if (settings.primrefarrayalloc != size_t(inf))120bvh->alloc.unshare(prims);121122/* skip build for empty scene */123const size_t numPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(gtype_,false);124numPreviousPrimitives = numPrimitives;125if (numPrimitives == 0) {126bvh->clear();127prims.clear();128return;129}130131double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::BVH" + toString(N) + "BuilderSAH");132133#if PROFILE134profile(2,PROFILE_RUNS,numPrimitives,[&] (ProfileTimer& timer) {135#endif136137/* create primref array */138if (primrefarrayalloc) {139settings.primrefarrayalloc = numPrimitives/1000;140if (settings.primrefarrayalloc < 1000)141settings.primrefarrayalloc = inf;142}143144/* enable os_malloc for two level build */145if (mesh)146bvh->alloc.setOSallocation(true);147148/* initialize allocator */149const size_t node_bytes = numPrimitives*sizeof(typename BVH::AABBNodeMB)/(4*N);150const size_t leaf_bytes = size_t(1.2*Primitive::blocks(numPrimitives)*sizeof(Primitive));151bvh->alloc.init_estimate(node_bytes+leaf_bytes);152settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,numPrimitives,node_bytes+leaf_bytes);153prims.resize(numPrimitives);154155PrimInfo pinfo = mesh ?156createPrimRefArray(mesh,geomID_,numPrimitives,prims,bvh->scene->progressInterface) :157createPrimRefArray(scene,gtype_,false,numPrimitives,prims,bvh->scene->progressInterface);158159/* pinfo might has zero size due to invalid geometry */160if (unlikely(pinfo.size() == 0))161{162bvh->clear();163prims.clear();164return;165}166167/* call BVH builder */168NodeRef root = BVHNBuilderVirtual<N>::build(&bvh->alloc,CreateLeaf<N,Primitive>(bvh),bvh->scene->progressInterface,prims.data(),pinfo,settings);169bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());170bvh->layoutLargeNodes(size_t(pinfo.size()*0.005f));171172#if PROFILE173});174#endif175176/* if we allocated using the primrefarray we have to keep it alive */177if (settings.primrefarrayalloc != size_t(inf))178bvh->alloc.share(prims);179180/* for static geometries we can do some cleanups */181else if (scene && scene->isStaticAccel()) {182prims.clear();183}184bvh->cleanup();185bvh->postBuild(t0);186}187188void clear() {189prims.clear();190}191};192193/************************************************************************************/194/************************************************************************************/195/************************************************************************************/196/************************************************************************************/197198template<int N, typename Primitive>199struct BVHNBuilderSAHQuantized : public Builder200{201typedef BVHN<N> BVH;202typedef typename BVHN<N>::NodeRef NodeRef;203204BVH* bvh;205Scene* scene;206Geometry* mesh;207mvector<PrimRef> prims;208GeneralBVHBuilder::Settings settings;209Geometry::GTypeMask gtype_;210unsigned int geomID_ = std::numeric_limits<unsigned int>::max();211unsigned int numPreviousPrimitives = 0;212213BVHNBuilderSAHQuantized (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const Geometry::GTypeMask gtype)214: 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) {}215216BVHNBuilderSAHQuantized (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)217: 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) {}218219// FIXME: shrink bvh->alloc in destructor here and in other builders too220221void build()222{223/* we reset the allocator when the mesh size changed */224if (mesh && mesh->numPrimitives != numPreviousPrimitives) {225bvh->alloc.clear();226}227228/* skip build for empty scene */229const size_t numPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(gtype_,false);230numPreviousPrimitives = numPrimitives;231if (numPrimitives == 0) {232prims.clear();233bvh->clear();234return;235}236237double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::QBVH" + toString(N) + "BuilderSAH");238239#if PROFILE240profile(2,PROFILE_RUNS,numPrimitives,[&] (ProfileTimer& timer) {241#endif242/* create primref array */243prims.resize(numPrimitives);244PrimInfo pinfo = mesh ?245createPrimRefArray(mesh,geomID_,numPrimitives,prims,bvh->scene->progressInterface) :246createPrimRefArray(scene,gtype_,false,numPrimitives,prims,bvh->scene->progressInterface);247248/* enable os_malloc for two level build */249if (mesh)250bvh->alloc.setOSallocation(true);251252/* call BVH builder */253const size_t node_bytes = numPrimitives*sizeof(typename BVH::QuantizedNode)/(4*N);254const size_t leaf_bytes = size_t(1.2*Primitive::blocks(numPrimitives)*sizeof(Primitive));255bvh->alloc.init_estimate(node_bytes+leaf_bytes);256settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,numPrimitives,node_bytes+leaf_bytes);257NodeRef root = BVHNBuilderQuantizedVirtual<N>::build(&bvh->alloc,CreateLeafQuantized<N,Primitive>(bvh),bvh->scene->progressInterface,prims.data(),pinfo,settings);258bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());259//bvh->layoutLargeNodes(pinfo.size()*0.005f); // FIXME: COPY LAYOUT FOR LARGE NODES !!!260#if PROFILE261});262#endif263264/* clear temporary data for static geometry */265if (scene && scene->isStaticAccel()) {266prims.clear();267}268bvh->cleanup();269bvh->postBuild(t0);270}271272void clear() {273prims.clear();274}275};276277/************************************************************************************/278/************************************************************************************/279/************************************************************************************/280/************************************************************************************/281282283template<int N, typename Primitive>284struct CreateLeafGrid285{286typedef BVHN<N> BVH;287typedef typename BVH::NodeRef NodeRef;288289__forceinline CreateLeafGrid (BVH* bvh, const SubGridBuildData * const sgrids) : bvh(bvh),sgrids(sgrids) {}290291__forceinline NodeRef operator() (const PrimRef* prims, const range<size_t>& set, const FastAllocator::CachedAllocator& alloc) const292{293const size_t items = set.size(); //Primitive::blocks(n);294const size_t start = set.begin();295296/* collect all subsets with unique geomIDs */297assert(items <= N);298unsigned int geomIDs[N];299unsigned int num_geomIDs = 1;300geomIDs[0] = prims[start].geomID();301302for (size_t i=1;i<items;i++)303{304bool found = false;305const unsigned int new_geomID = prims[start+i].geomID();306for (size_t j=0;j<num_geomIDs;j++)307if (new_geomID == geomIDs[j])308{ found = true; break; }309if (!found)310geomIDs[num_geomIDs++] = new_geomID;311}312313/* allocate all leaf memory in one single block */314SubGridQBVHN<N>* accel = (SubGridQBVHN<N>*) alloc.malloc1(num_geomIDs*sizeof(SubGridQBVHN<N>),BVH::byteAlignment);315typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,num_geomIDs);316317for (size_t g=0;g<num_geomIDs;g++)318{319unsigned int x[N];320unsigned int y[N];321unsigned int primID[N];322BBox3fa bounds[N];323unsigned int pos = 0;324for (size_t i=0;i<items;i++)325{326if (unlikely(prims[start+i].geomID() != geomIDs[g])) continue;327328const SubGridBuildData& sgrid_bd = sgrids[prims[start+i].primID()];329x[pos] = sgrid_bd.sx;330y[pos] = sgrid_bd.sy;331primID[pos] = sgrid_bd.primID;332bounds[pos] = prims[start+i].bounds();333pos++;334}335assert(pos <= N);336new (&accel[g]) SubGridQBVHN<N>(x,y,primID,bounds,geomIDs[g],pos);337}338339return node;340}341342BVH* bvh;343const SubGridBuildData * const sgrids;344};345346347template<int N>348struct BVHNBuilderSAHGrid : public Builder349{350typedef BVHN<N> BVH;351typedef typename BVHN<N>::NodeRef NodeRef;352353BVH* bvh;354Scene* scene;355GridMesh* mesh;356mvector<PrimRef> prims;357mvector<SubGridBuildData> sgrids;358GeneralBVHBuilder::Settings settings;359const unsigned int geomID_ = std::numeric_limits<unsigned int>::max();360unsigned int numPreviousPrimitives = 0;361362BVHNBuilderSAHGrid (BVH* bvh, Scene* scene, const size_t sahBlockSize, const float intCost, const size_t minLeafSize, const size_t maxLeafSize, const size_t mode)363: 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) {}364365BVHNBuilderSAHGrid (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)366: 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) {}367368void build()369{370/* we reset the allocator when the mesh size changed */371if (mesh && mesh->numPrimitives != numPreviousPrimitives) {372bvh->alloc.clear();373}374375/* if we use the primrefarray for allocations we have to take it back from the BVH */376if (settings.primrefarrayalloc != size_t(inf))377bvh->alloc.unshare(prims);378379const size_t numGridPrimitives = mesh ? mesh->size() : scene->getNumPrimitives(GridMesh::geom_type,false);380numPreviousPrimitives = numGridPrimitives;381382383PrimInfo pinfo = mesh ? createPrimRefArrayGrids(mesh,prims,sgrids) : createPrimRefArrayGrids(scene,prims,sgrids);384const size_t numPrimitives = pinfo.size();385/* no primitives */386if (numPrimitives == 0) {387bvh->clear();388prims.clear();389sgrids.clear();390return;391}392393double t0 = bvh->preBuild(mesh ? "" : TOSTRING(isa) "::BVH" + toString(N) + "BuilderSAH");394395/* create primref array */396settings.primrefarrayalloc = numPrimitives/1000;397if (settings.primrefarrayalloc < 1000)398settings.primrefarrayalloc = inf;399400/* enable os_malloc for two level build */401if (mesh)402bvh->alloc.setOSallocation(true);403404/* initialize allocator */405const size_t node_bytes = numPrimitives*sizeof(typename BVH::AABBNodeMB)/(4*N);406const size_t leaf_bytes = size_t(1.2*(float)numPrimitives/N * sizeof(SubGridQBVHN<N>));407408bvh->alloc.init_estimate(node_bytes+leaf_bytes);409settings.singleThreadThreshold = bvh->alloc.fixSingleThreadThreshold(N,DEFAULT_SINGLE_THREAD_THRESHOLD,numPrimitives,node_bytes+leaf_bytes);410411/* pinfo might has zero size due to invalid geometry */412if (unlikely(pinfo.size() == 0))413{414bvh->clear();415sgrids.clear();416prims.clear();417return;418}419420/* call BVH builder */421NodeRef root = BVHNBuilderVirtual<N>::build(&bvh->alloc,CreateLeafGrid<N,SubGridQBVHN<N>>(bvh,sgrids.data()),bvh->scene->progressInterface,prims.data(),pinfo,settings);422bvh->set(root,LBBox3fa(pinfo.geomBounds),pinfo.size());423bvh->layoutLargeNodes(size_t(pinfo.size()*0.005f));424425/* clear temporary array */426sgrids.clear();427428/* if we allocated using the primrefarray we have to keep it alive */429if (settings.primrefarrayalloc != size_t(inf))430bvh->alloc.share(prims);431432/* for static geometries we can do some cleanups */433else if (scene && scene->isStaticAccel()) {434prims.clear();435}436bvh->cleanup();437bvh->postBuild(t0);438}439440void clear() {441prims.clear();442}443};444445/************************************************************************************/446/************************************************************************************/447/************************************************************************************/448/************************************************************************************/449450451#if defined(EMBREE_GEOMETRY_TRIANGLE)452Builder* 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); }453Builder* 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); }454Builder* 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); }455456Builder* BVH4Triangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }457Builder* BVH4Triangle4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Triangle4v>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }458Builder* 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); }459460Builder* BVH4QuantizedTriangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Triangle4i>((BVH4*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }461#if defined(__AVX__)462Builder* 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); }463Builder* 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); }464Builder* 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); }465466Builder* BVH8Triangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Triangle4>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }467Builder* BVH8Triangle4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Triangle4v>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }468Builder* 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); }469Builder* BVH8QuantizedTriangle4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Triangle4i>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }470Builder* BVH8QuantizedTriangle4SceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Triangle4>((BVH8*)bvh,scene,4,1.0f,4,inf,TriangleMesh::geom_type); }471472473474#endif475#endif476477#if defined(EMBREE_GEOMETRY_QUAD)478Builder* 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); }479Builder* 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); }480Builder* BVH4Quad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<4,Quad4v>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }481Builder* 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); }482Builder* BVH4QuantizedQuad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Quad4v>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }483Builder* BVH4QuantizedQuad4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<4,Quad4i>((BVH4*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }484485#if defined(__AVX__)486Builder* BVH8Quad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAH<8,Quad4v>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }487Builder* 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); }488Builder* BVH8QuantizedQuad4vSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Quad4v>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }489Builder* BVH8QuantizedQuad4iSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) { return new BVHNBuilderSAHQuantized<8,Quad4i>((BVH8*)bvh,scene,4,1.0f,4,inf,QuadMesh::geom_type); }490Builder* 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); }491492#endif493#endif494495#if defined(EMBREE_GEOMETRY_USER)496497Builder* BVH4VirtualSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) {498int minLeafSize = scene->device->object_accel_min_leaf_size;499int maxLeafSize = scene->device->object_accel_max_leaf_size;500return new BVHNBuilderSAH<4,Object>((BVH4*)bvh,scene,4,1.0f,minLeafSize,maxLeafSize,UserGeometry::geom_type);501}502503Builder* BVH4VirtualMeshBuilderSAH (void* bvh, UserGeometry* mesh, unsigned int geomID, size_t mode) {504return new BVHNBuilderSAH<4,Object>((BVH4*)bvh,mesh,geomID,4,1.0f,1,inf,UserGeometry::geom_type);505}506#if defined(__AVX__)507508Builder* BVH8VirtualSceneBuilderSAH (void* bvh, Scene* scene, size_t mode) {509int minLeafSize = scene->device->object_accel_min_leaf_size;510int maxLeafSize = scene->device->object_accel_max_leaf_size;511return new BVHNBuilderSAH<8,Object>((BVH8*)bvh,scene,8,1.0f,minLeafSize,maxLeafSize,UserGeometry::geom_type);512}513514Builder* BVH8VirtualMeshBuilderSAH (void* bvh, UserGeometry* mesh, unsigned int geomID, size_t mode) {515return new BVHNBuilderSAH<8,Object>((BVH8*)bvh,mesh,geomID,8,1.0f,1,inf,UserGeometry::geom_type);516}517#endif518#endif519520#if defined(EMBREE_GEOMETRY_INSTANCE)521Builder* BVH4InstanceSceneBuilderSAH (void* bvh, Scene* scene, Geometry::GTypeMask gtype) {522return new BVHNBuilderSAH<4,InstancePrimitive>((BVH4*)bvh,scene,4,1.0f,1,1,gtype);523}524Builder* BVH4InstanceMeshBuilderSAH (void* bvh, Instance* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) {525return new BVHNBuilderSAH<4,InstancePrimitive>((BVH4*)bvh,mesh,geomID,4,1.0f,1,inf,gtype);526}527#if defined(__AVX__)528Builder* BVH8InstanceSceneBuilderSAH (void* bvh, Scene* scene, Geometry::GTypeMask gtype) {529return new BVHNBuilderSAH<8,InstancePrimitive>((BVH8*)bvh,scene,8,1.0f,1,1,gtype);530}531Builder* BVH8InstanceMeshBuilderSAH (void* bvh, Instance* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) {532return new BVHNBuilderSAH<8,InstancePrimitive>((BVH8*)bvh,mesh,geomID,8,1.0f,1,1,gtype);533}534#endif535#endif536537#if defined(EMBREE_GEOMETRY_INSTANCE_ARRAY)538Builder* BVH4InstanceArraySceneBuilderSAH (void* bvh, Scene* scene, Geometry::GTypeMask gtype) {539return new BVHNBuilderSAH<4,InstanceArrayPrimitive>((BVH4*)bvh,scene,4,1.0f,1,1,gtype);540}541Builder* BVH4InstanceArrayMeshBuilderSAH (void* bvh, InstanceArray* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) {542return new BVHNBuilderSAH<4,InstanceArrayPrimitive>((BVH4*)bvh,mesh,geomID,4,1.0f,1,1,gtype);543}544#if defined(__AVX__)545Builder* BVH8InstanceArraySceneBuilderSAH (void* bvh, Scene* scene, Geometry::GTypeMask gtype) {546return new BVHNBuilderSAH<8,InstanceArrayPrimitive>((BVH8*)bvh,scene,8,1.0f,1,1,gtype);547}548Builder* BVH8InstanceArrayMeshBuilderSAH (void* bvh, InstanceArray* mesh, Geometry::GTypeMask gtype, unsigned int geomID, size_t mode) {549return new BVHNBuilderSAH<8,InstanceArrayPrimitive>((BVH8*)bvh,mesh,geomID,8,1.0f,1,1,gtype);550}551#endif552#endif553554#if defined(EMBREE_GEOMETRY_GRID)555Builder* 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); }556Builder* 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 correct557558#if defined(__AVX__)559Builder* 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); }560Builder* 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 correct561#endif562#endif563}564}565566567