diff options
Diffstat (limited to 'thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h')
-rw-r--r-- | thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h b/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h deleted file mode 100644 index 4c138dacdb..0000000000 --- a/thirdparty/embree-aarch64/kernels/builders/bvh_builder_msmblur.h +++ /dev/null @@ -1,692 +0,0 @@ -// Copyright 2009-2020 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#define MBLUR_NUM_TEMPORAL_BINS 2 -#define MBLUR_NUM_OBJECT_BINS 32 - -#include "../bvh/bvh.h" -#include "../common/primref_mb.h" -#include "heuristic_binning_array_aligned.h" -#include "heuristic_timesplit_array.h" - -namespace embree -{ - namespace isa - { - template<typename T> - struct SharedVector - { - __forceinline SharedVector() {} - - __forceinline SharedVector(T* ptr, size_t refCount = 1) - : prims(ptr), refCount(refCount) {} - - __forceinline void incRef() { - refCount++; - } - - __forceinline void decRef() - { - if (--refCount == 0) - delete prims; - } - - T* prims; - size_t refCount; - }; - - template<typename BuildRecord, int MAX_BRANCHING_FACTOR> - struct LocalChildListT - { - typedef SharedVector<mvector<PrimRefMB>> SharedPrimRefVector; - - __forceinline LocalChildListT (const BuildRecord& record) - : numChildren(1), numSharedPrimVecs(1) - { - /* the local root will be freed in the ancestor where it was created (thus refCount is 2) */ - children[0] = record; - primvecs[0] = new (&sharedPrimVecs[0]) SharedPrimRefVector(record.prims.prims, 2); - } - - __forceinline ~LocalChildListT() - { - for (size_t i = 0; i < numChildren; i++) - primvecs[i]->decRef(); - } - - __forceinline BuildRecord& operator[] ( const size_t i ) { - return children[i]; - } - - __forceinline size_t size() const { - return numChildren; - } - - __forceinline void split(ssize_t bestChild, const BuildRecord& lrecord, const BuildRecord& rrecord, std::unique_ptr<mvector<PrimRefMB>> new_vector) - { - SharedPrimRefVector* bsharedPrimVec = primvecs[bestChild]; - if (lrecord.prims.prims == bsharedPrimVec->prims) { - primvecs[bestChild] = bsharedPrimVec; - bsharedPrimVec->incRef(); - } - else { - primvecs[bestChild] = new (&sharedPrimVecs[numSharedPrimVecs++]) SharedPrimRefVector(lrecord.prims.prims); - } - - if (rrecord.prims.prims == bsharedPrimVec->prims) { - primvecs[numChildren] = bsharedPrimVec; - bsharedPrimVec->incRef(); - } - else { - primvecs[numChildren] = new (&sharedPrimVecs[numSharedPrimVecs++]) SharedPrimRefVector(rrecord.prims.prims); - } - bsharedPrimVec->decRef(); - new_vector.release(); - - children[bestChild] = lrecord; - children[numChildren] = rrecord; - numChildren++; - } - - public: - array_t<BuildRecord,MAX_BRANCHING_FACTOR> children; - array_t<SharedPrimRefVector*,MAX_BRANCHING_FACTOR> primvecs; - size_t numChildren; - - array_t<SharedPrimRefVector,2*MAX_BRANCHING_FACTOR> sharedPrimVecs; - size_t numSharedPrimVecs; - }; - - template<typename Mesh> - struct RecalculatePrimRef - { - Scene* scene; - - __forceinline RecalculatePrimRef (Scene* scene) - : scene(scene) {} - - __forceinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range) const - { - const unsigned geomID = prim.geomID(); - const unsigned primID = prim.primID(); - const Mesh* mesh = scene->get<Mesh>(geomID); - const LBBox3fa lbounds = mesh->linearBounds(primID, time_range); - const range<int> tbounds = mesh->timeSegmentRange(time_range); - return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID); - } - - // __noinline is workaround for ICC16 bug under MacOSX - __noinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const - { - const unsigned geomID = prim.geomID(); - const unsigned primID = prim.primID(); - const Mesh* mesh = scene->get<Mesh>(geomID); - const LBBox3fa lbounds = mesh->linearBounds(space, primID, time_range); - const range<int> tbounds = mesh->timeSegmentRange(time_range); - return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID); - } - - __forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range) const { - return scene->get<Mesh>(prim.geomID())->linearBounds(prim.primID(), time_range); - } - - // __noinline is workaround for ICC16 bug under MacOSX - __noinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const { - return scene->get<Mesh>(prim.geomID())->linearBounds(space, prim.primID(), time_range); - } - }; - - struct VirtualRecalculatePrimRef - { - Scene* scene; - - __forceinline VirtualRecalculatePrimRef (Scene* scene) - : scene(scene) {} - - __forceinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range) const - { - const unsigned geomID = prim.geomID(); - const unsigned primID = prim.primID(); - const Geometry* mesh = scene->get(geomID); - const LBBox3fa lbounds = mesh->vlinearBounds(primID, time_range); - const range<int> tbounds = mesh->timeSegmentRange(time_range); - return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID); - } - - __forceinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const - { - const unsigned geomID = prim.geomID(); - const unsigned primID = prim.primID(); - const Geometry* mesh = scene->get(geomID); - const LBBox3fa lbounds = mesh->vlinearBounds(space, primID, time_range); - const range<int> tbounds = mesh->timeSegmentRange(time_range); - return PrimRefMB (lbounds, tbounds.size(), mesh->time_range, mesh->numTimeSegments(), geomID, primID); - } - - __forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range) const { - return scene->get(prim.geomID())->vlinearBounds(prim.primID(), time_range); - } - - __forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const { - return scene->get(prim.geomID())->vlinearBounds(space, prim.primID(), time_range); - } - }; - - struct BVHBuilderMSMBlur - { - /*! settings for msmblur builder */ - struct Settings - { - /*! default settings */ - Settings () - : branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8), - travCost(1.0f), intCost(1.0f), singleLeafTimeSegment(false), - singleThreadThreshold(1024) {} - - - Settings (size_t sahBlockSize, size_t minLeafSize, size_t maxLeafSize, float travCost, float intCost, size_t singleThreadThreshold) - : branchingFactor(2), maxDepth(32), logBlockSize(bsr(sahBlockSize)), minLeafSize(minLeafSize), maxLeafSize(maxLeafSize), - travCost(travCost), intCost(intCost), singleThreadThreshold(singleThreadThreshold) - { - minLeafSize = min(minLeafSize,maxLeafSize); - } - - public: - size_t branchingFactor; //!< branching factor of BVH to build - size_t maxDepth; //!< maximum depth of BVH to build - size_t logBlockSize; //!< log2 of blocksize for SAH heuristic - size_t minLeafSize; //!< minimum size of a leaf - size_t maxLeafSize; //!< maximum size of a leaf - float travCost; //!< estimated cost of one traversal step - float intCost; //!< estimated cost of one primitive intersection - bool singleLeafTimeSegment; //!< split time to single time range - size_t singleThreadThreshold; //!< threshold when we switch to single threaded build - }; - - struct BuildRecord - { - public: - __forceinline BuildRecord () {} - - __forceinline BuildRecord (size_t depth) - : depth(depth) {} - - __forceinline BuildRecord (const SetMB& prims, size_t depth) - : depth(depth), prims(prims) {} - - __forceinline friend bool operator< (const BuildRecord& a, const BuildRecord& b) { - return a.prims.size() < b.prims.size(); - } - - __forceinline size_t size() const { - return prims.size(); - } - - public: - size_t depth; //!< Depth of the root of this subtree. - SetMB prims; //!< The list of primitives. - }; - - struct BuildRecordSplit : public BuildRecord - { - __forceinline BuildRecordSplit () {} - - __forceinline BuildRecordSplit (size_t depth) - : BuildRecord(depth) {} - - __forceinline BuildRecordSplit (const BuildRecord& record, const BinSplit<MBLUR_NUM_OBJECT_BINS>& split) - : BuildRecord(record), split(split) {} - - BinSplit<MBLUR_NUM_OBJECT_BINS> split; - }; - - template< - typename NodeRef, - typename RecalculatePrimRef, - typename Allocator, - typename CreateAllocFunc, - typename CreateNodeFunc, - typename SetNodeFunc, - typename CreateLeafFunc, - typename ProgressMonitor> - - class BuilderT - { - ALIGNED_CLASS_(16); - static const size_t MAX_BRANCHING_FACTOR = 16; //!< maximum supported BVH branching factor - static const size_t MIN_LARGE_LEAF_LEVELS = 8; //!< create balanced tree if we are that many levels before the maximum tree depth - - typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D; - typedef BinSplit<MBLUR_NUM_OBJECT_BINS> Split; - typedef mvector<PrimRefMB>* PrimRefVector; - typedef SharedVector<mvector<PrimRefMB>> SharedPrimRefVector; - typedef LocalChildListT<BuildRecord,MAX_BRANCHING_FACTOR> LocalChildList; - typedef LocalChildListT<BuildRecordSplit,MAX_BRANCHING_FACTOR> LocalChildListSplit; - - public: - - BuilderT (MemoryMonitorInterface* device, - const RecalculatePrimRef recalculatePrimRef, - const CreateAllocFunc createAlloc, - const CreateNodeFunc createNode, - const SetNodeFunc setNode, - const CreateLeafFunc createLeaf, - const ProgressMonitor progressMonitor, - const Settings& settings) - : cfg(settings), - heuristicObjectSplit(), - heuristicTemporalSplit(device, recalculatePrimRef), - recalculatePrimRef(recalculatePrimRef), createAlloc(createAlloc), createNode(createNode), setNode(setNode), createLeaf(createLeaf), - progressMonitor(progressMonitor) - { - if (cfg.branchingFactor > MAX_BRANCHING_FACTOR) - throw_RTCError(RTC_ERROR_UNKNOWN,"bvh_builder: branching factor too large"); - } - - /*! finds the best split */ - const Split find(const SetMB& set) - { - /* first try standard object split */ - const Split object_split = heuristicObjectSplit.find(set,cfg.logBlockSize); - const float object_split_sah = object_split.splitSAH(); - - /* test temporal splits only when object split was bad */ - const float leaf_sah = set.leafSAH(cfg.logBlockSize); - if (object_split_sah < 0.50f*leaf_sah) - return object_split; - - /* do temporal splits only if the the time range is big enough */ - if (set.time_range.size() > 1.01f/float(set.max_num_time_segments)) - { - const Split temporal_split = heuristicTemporalSplit.find(set,cfg.logBlockSize); - const float temporal_split_sah = temporal_split.splitSAH(); - - /* take temporal split if it improved SAH */ - if (temporal_split_sah < object_split_sah) - return temporal_split; - } - - return object_split; - } - - /*! array partitioning */ - __forceinline std::unique_ptr<mvector<PrimRefMB>> split(const Split& split, const SetMB& set, SetMB& lset, SetMB& rset) - { - /* perform object split */ - if (likely(split.data == Split::SPLIT_OBJECT)) { - heuristicObjectSplit.split(split,set,lset,rset); - } - /* perform temporal split */ - else if (likely(split.data == Split::SPLIT_TEMPORAL)) { - return heuristicTemporalSplit.split(split,set,lset,rset); - } - /* perform fallback split */ - else if (unlikely(split.data == Split::SPLIT_FALLBACK)) { - set.deterministic_order(); - splitFallback(set,lset,rset); - } - /* split by geometry */ - else if (unlikely(split.data == Split::SPLIT_GEOMID)) { - set.deterministic_order(); - splitByGeometry(set,lset,rset); - } - else - assert(false); - - return std::unique_ptr<mvector<PrimRefMB>>(); - } - - /*! finds the best fallback split */ - __noinline Split findFallback(const SetMB& set) - { - /* split if primitives are not from same geometry */ - if (!sameGeometry(set)) - return Split(0.0f,Split::SPLIT_GEOMID); - - /* if a leaf can only hold a single time-segment, we might have to do additional temporal splits */ - if (cfg.singleLeafTimeSegment) - { - /* test if one primitive has more than one time segment in time range, if so split time */ - for (size_t i=set.begin(); i<set.end(); i++) - { - const PrimRefMB& prim = (*set.prims)[i]; - const range<int> itime_range = prim.timeSegmentRange(set.time_range); - const int localTimeSegments = itime_range.size(); - assert(localTimeSegments > 0); - if (localTimeSegments > 1) { - const int icenter = (itime_range.begin() + itime_range.end())/2; - const float splitTime = prim.timeStep(icenter); - return Split(0.0f,(unsigned)Split::SPLIT_TEMPORAL,0,splitTime); - } - } - } - - /* otherwise return fallback split */ - return Split(0.0f,Split::SPLIT_FALLBACK); - } - - /*! performs fallback split */ - void splitFallback(const SetMB& set, SetMB& lset, SetMB& rset) - { - mvector<PrimRefMB>& prims = *set.prims; - - const size_t begin = set.begin(); - const size_t end = set.end(); - const size_t center = (begin + end)/2; - - PrimInfoMB linfo = empty; - for (size_t i=begin; i<center; i++) - linfo.add_primref(prims[i]); - - PrimInfoMB rinfo = empty; - for (size_t i=center; i<end; i++) - rinfo.add_primref(prims[i]); - - new (&lset) SetMB(linfo,set.prims,range<size_t>(begin,center),set.time_range); - new (&rset) SetMB(rinfo,set.prims,range<size_t>(center,end ),set.time_range); - } - - /*! checks if all primitives are from the same geometry */ - __forceinline bool sameGeometry(const SetMB& set) - { - if (set.size() == 0) return true; - mvector<PrimRefMB>& prims = *set.prims; - const size_t begin = set.begin(); - const size_t end = set.end(); - unsigned int firstGeomID = prims[begin].geomID(); - for (size_t i=begin+1; i<end; i++) { - if (prims[i].geomID() != firstGeomID){ - return false; - } - } - return true; - } - - /* split by geometry ID */ - void splitByGeometry(const SetMB& set, SetMB& lset, SetMB& rset) - { - assert(set.size() > 1); - - mvector<PrimRefMB>& prims = *set.prims; - const size_t begin = set.begin(); - const size_t end = set.end(); - - PrimInfoMB left(empty); - PrimInfoMB right(empty); - unsigned int geomID = prims[begin].geomID(); - size_t center = serial_partitioning(prims.data(),begin,end,left,right, - [&] ( const PrimRefMB& prim ) { return prim.geomID() == geomID; }, - [ ] ( PrimInfoMB& dst, const PrimRefMB& prim ) { dst.add_primref(prim); }); - - new (&lset) SetMB(left, set.prims,range<size_t>(begin,center),set.time_range); - new (&rset) SetMB(right,set.prims,range<size_t>(center,end ),set.time_range); - } - - const NodeRecordMB4D createLargeLeaf(const BuildRecord& in, Allocator alloc) - { - /* this should never occur but is a fatal error */ - if (in.depth > cfg.maxDepth) - throw_RTCError(RTC_ERROR_UNKNOWN,"depth limit reached"); - - /* replace already found split by fallback split */ - const BuildRecordSplit current(BuildRecord(in.prims,in.depth),findFallback(in.prims)); - - /* special case when directly creating leaf without any splits that could shrink time_range */ - bool force_split = false; - if (current.depth == 1 && current.size() > 0) - { - BBox1f c = empty; - BBox1f p = current.prims.time_range; - for (size_t i=current.prims.begin(); i<current.prims.end(); i++) { - mvector<PrimRefMB>& prims = *current.prims.prims; - c.extend(prims[i].time_range); - } - - force_split = c.lower > p.lower || c.upper < p.upper; - } - - /* create leaf for few primitives */ - if (current.size() <= cfg.maxLeafSize && current.split.data < Split::SPLIT_ENFORCE && !force_split) - return createLeaf(current,alloc); - - /* fill all children by always splitting the largest one */ - bool hasTimeSplits = false; - NodeRecordMB4D values[MAX_BRANCHING_FACTOR]; - LocalChildListSplit children(current); - - do { - /* find best child with largest bounding box area */ - size_t bestChild = -1; - size_t bestSize = 0; - for (size_t i=0; i<children.size(); i++) - { - /* ignore leaves as they cannot get split */ - if (children[i].size() <= cfg.maxLeafSize && children[i].split.data < Split::SPLIT_ENFORCE && !force_split) - continue; - - force_split = false; - - /* remember child with largest size */ - if (children[i].size() > bestSize) { - bestSize = children[i].size(); - bestChild = i; - } - } - if (bestChild == -1) break; - - /* perform best found split */ - BuildRecordSplit& brecord = children[bestChild]; - BuildRecordSplit lrecord(current.depth+1); - BuildRecordSplit rrecord(current.depth+1); - std::unique_ptr<mvector<PrimRefMB>> new_vector = split(brecord.split,brecord.prims,lrecord.prims,rrecord.prims); - hasTimeSplits |= new_vector != nullptr; - - /* find new splits */ - lrecord.split = findFallback(lrecord.prims); - rrecord.split = findFallback(rrecord.prims); - children.split(bestChild,lrecord,rrecord,std::move(new_vector)); - - } while (children.size() < cfg.branchingFactor); - - /* detect time_ranges that have shrunken */ - for (size_t i=0; i<children.size(); i++) { - const BBox1f c = children[i].prims.time_range; - const BBox1f p = in.prims.time_range; - hasTimeSplits |= c.lower > p.lower || c.upper < p.upper; - } - - /* create node */ - auto node = createNode(children.children.data(),children.numChildren,alloc,hasTimeSplits); - - /* recurse into each child and perform reduction */ - LBBox3fa gbounds = empty; - for (size_t i=0; i<children.size(); i++) { - values[i] = createLargeLeaf(children[i],alloc); - gbounds.extend(values[i].lbounds); - } - - setNode(current,children.children.data(),node,values,children.numChildren); - - /* calculate geometry bounds of this node */ - if (hasTimeSplits) - return NodeRecordMB4D(node,current.prims.linearBounds(recalculatePrimRef),current.prims.time_range); - else - return NodeRecordMB4D(node,gbounds,current.prims.time_range); - } - - const NodeRecordMB4D recurse(const BuildRecord& current, Allocator alloc, bool toplevel) - { - /* get thread local allocator */ - if (!alloc) - alloc = createAlloc(); - - /* call memory monitor function to signal progress */ - if (toplevel && current.size() <= cfg.singleThreadThreshold) - progressMonitor(current.size()); - - /*! find best split */ - const Split csplit = find(current.prims); - - /*! compute leaf and split cost */ - const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize); - const float splitSAH = cfg.travCost*current.prims.halfArea()+cfg.intCost*csplit.splitSAH(); - assert((current.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0))); - - /*! create a leaf node when threshold reached or SAH tells us to stop */ - if (current.size() <= cfg.minLeafSize || current.depth+MIN_LARGE_LEAF_LEVELS >= cfg.maxDepth || (current.size() <= cfg.maxLeafSize && leafSAH <= splitSAH)) { - current.prims.deterministic_order(); - return createLargeLeaf(current,alloc); - } - - /*! perform initial split */ - SetMB lprims,rprims; - std::unique_ptr<mvector<PrimRefMB>> new_vector = split(csplit,current.prims,lprims,rprims); - bool hasTimeSplits = new_vector != nullptr; - NodeRecordMB4D values[MAX_BRANCHING_FACTOR]; - LocalChildList children(current); - { - BuildRecord lrecord(lprims,current.depth+1); - BuildRecord rrecord(rprims,current.depth+1); - children.split(0,lrecord,rrecord,std::move(new_vector)); - } - - /*! split until node is full or SAH tells us to stop */ - while (children.size() < cfg.branchingFactor) - { - /*! find best child to split */ - float bestArea = neg_inf; - ssize_t bestChild = -1; - for (size_t i=0; i<children.size(); i++) - { - if (children[i].size() <= cfg.minLeafSize) continue; - if (expectedApproxHalfArea(children[i].prims.geomBounds) > bestArea) { - bestChild = i; bestArea = expectedApproxHalfArea(children[i].prims.geomBounds); - } - } - if (bestChild == -1) break; - - /* perform split */ - BuildRecord& brecord = children[bestChild]; - BuildRecord lrecord(current.depth+1); - BuildRecord rrecord(current.depth+1); - Split csplit = find(brecord.prims); - std::unique_ptr<mvector<PrimRefMB>> new_vector = split(csplit,brecord.prims,lrecord.prims,rrecord.prims); - hasTimeSplits |= new_vector != nullptr; - children.split(bestChild,lrecord,rrecord,std::move(new_vector)); - } - - /* detect time_ranges that have shrunken */ - for (size_t i=0; i<children.size(); i++) { - const BBox1f c = children[i].prims.time_range; - const BBox1f p = current.prims.time_range; - hasTimeSplits |= c.lower > p.lower || c.upper < p.upper; - } - - /* sort buildrecords for simpler shadow ray traversal */ - //std::sort(&children[0],&children[children.size()],std::greater<BuildRecord>()); // FIXME: reduces traversal performance of bvh8.triangle4 (need to verified) !! - - /*! create an inner node */ - auto node = createNode(children.children.data(), children.numChildren, alloc, hasTimeSplits); - LBBox3fa gbounds = empty; - - /* spawn tasks */ - if (unlikely(current.size() > cfg.singleThreadThreshold)) - { - /*! parallel_for is faster than spawing sub-tasks */ - parallel_for(size_t(0), children.size(), [&] (const range<size_t>& r) { - for (size_t i=r.begin(); i<r.end(); i++) { - values[i] = recurse(children[i],nullptr,true); - _mm_mfence(); // to allow non-temporal stores during build - } - }); - - /*! merge bounding boxes */ - for (size_t i=0; i<children.size(); i++) - gbounds.extend(values[i].lbounds); - } - /* recurse into each child */ - else - { - //for (size_t i=0; i<children.size(); i++) - for (ssize_t i=children.size()-1; i>=0; i--) { - values[i] = recurse(children[i],alloc,false); - gbounds.extend(values[i].lbounds); - } - } - - setNode(current,children.children.data(),node,values,children.numChildren); - - /* calculate geometry bounds of this node */ - if (unlikely(hasTimeSplits)) - return NodeRecordMB4D(node,current.prims.linearBounds(recalculatePrimRef),current.prims.time_range); - else - return NodeRecordMB4D(node,gbounds,current.prims.time_range); - } - - /*! builder entry function */ - __forceinline const NodeRecordMB4D operator() (mvector<PrimRefMB>& prims, const PrimInfoMB& pinfo) - { - const SetMB set(pinfo,&prims); - auto ret = recurse(BuildRecord(set,1),nullptr,true); - _mm_mfence(); // to allow non-temporal stores during build - return ret; - } - - private: - Settings cfg; - HeuristicArrayBinningMB<PrimRefMB,MBLUR_NUM_OBJECT_BINS> heuristicObjectSplit; - HeuristicMBlurTemporalSplit<PrimRefMB,RecalculatePrimRef,MBLUR_NUM_TEMPORAL_BINS> heuristicTemporalSplit; - const RecalculatePrimRef recalculatePrimRef; - const CreateAllocFunc createAlloc; - const CreateNodeFunc createNode; - const SetNodeFunc setNode; - const CreateLeafFunc createLeaf; - const ProgressMonitor progressMonitor; - }; - - template<typename NodeRef, - typename RecalculatePrimRef, - typename CreateAllocFunc, - typename CreateNodeFunc, - typename SetNodeFunc, - typename CreateLeafFunc, - typename ProgressMonitorFunc> - - static const BVHNodeRecordMB4D<NodeRef> build(mvector<PrimRefMB>& prims, - const PrimInfoMB& pinfo, - MemoryMonitorInterface* device, - const RecalculatePrimRef recalculatePrimRef, - const CreateAllocFunc createAlloc, - const CreateNodeFunc createNode, - const SetNodeFunc setNode, - const CreateLeafFunc createLeaf, - const ProgressMonitorFunc progressMonitor, - const Settings& settings) - { - typedef BuilderT< - NodeRef, - RecalculatePrimRef, - decltype(createAlloc()), - CreateAllocFunc, - CreateNodeFunc, - SetNodeFunc, - CreateLeafFunc, - ProgressMonitorFunc> Builder; - - Builder builder(device, - recalculatePrimRef, - createAlloc, - createNode, - setNode, - createLeaf, - progressMonitor, - settings); - - - return builder(prims,pinfo); - } - }; - } -} |