Compare commits
4
Commits
devel3
...
experimental
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86dbc8a437 | ||
|
|
4c93274a31 | ||
|
|
bd7ea15f50 | ||
|
|
1df9591a8c |
@@ -230,6 +230,8 @@ namespace embree
|
||||
// __forceinline vuint4 operator *(const vuint4& a, unsigned int b) { return a * vuint4(b); }
|
||||
// __forceinline vuint4 operator *(unsigned int a, const vuint4& b) { return vuint4(a) * b; }
|
||||
|
||||
__forceinline vuint4 operator /(const vuint4& a, const vuint4& b) { return vuint4(a[0]/b[0],a[1]/b[1],a[2]/b[2],a[3]/b[3]); }
|
||||
|
||||
__forceinline vuint4 operator &(const vuint4& a, const vuint4& b) { return _mm_and_si128(a, b); }
|
||||
__forceinline vuint4 operator &(const vuint4& a, unsigned int b) { return a & vuint4(b); }
|
||||
__forceinline vuint4 operator &(unsigned int a, const vuint4& b) { return vuint4(a) & b; }
|
||||
|
||||
@@ -36,12 +36,12 @@ namespace embree
|
||||
{
|
||||
/*! default settings */
|
||||
Settings ()
|
||||
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8), finished_range_threshold(inf) {}
|
||||
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8), finished_range_threshold(inf) {}
|
||||
|
||||
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 sahBlockSize; //!< blocksize for SAH heuristic
|
||||
size_t minLeafSize; //!< minimum size of a leaf
|
||||
size_t maxLeafSize; //!< maximum size of a leaf
|
||||
size_t finished_range_threshold; //!< finished range threshold
|
||||
@@ -179,14 +179,14 @@ namespace embree
|
||||
{
|
||||
/* variable to track the SAH of the best splitting approach */
|
||||
float bestSAH = inf;
|
||||
const size_t blocks = (pinfo.size()+(1ull<<cfg.logBlockSize)-1ull) >> cfg.logBlockSize;
|
||||
const size_t blocks = (pinfo.size()+cfg.sahBlockSize-1) / cfg.sahBlockSize;
|
||||
const float leafSAH = intCost*float(blocks)*halfArea(pinfo.geomBounds);
|
||||
|
||||
/* try standard binning in aligned space */
|
||||
float alignedObjectSAH = inf;
|
||||
HeuristicBinningSAH::Split alignedObjectSplit;
|
||||
if (aligned) {
|
||||
alignedObjectSplit = alignedHeuristic.find(pinfo,cfg.logBlockSize);
|
||||
alignedObjectSplit = alignedHeuristic.find(pinfo,cfg.sahBlockSize);
|
||||
alignedObjectSAH = travCostAligned*halfArea(pinfo.geomBounds) + intCost*alignedObjectSplit.splitSAH();
|
||||
bestSAH = min(alignedObjectSAH,bestSAH);
|
||||
}
|
||||
@@ -198,7 +198,7 @@ namespace embree
|
||||
if (bestSAH > 0.7f*leafSAH) {
|
||||
uspace = unalignedHeuristic.computeAlignedSpace(pinfo);
|
||||
const PrimInfoRange sinfo = unalignedHeuristic.computePrimInfo(pinfo,uspace);
|
||||
unalignedObjectSplit = unalignedHeuristic.find(sinfo,cfg.logBlockSize,uspace);
|
||||
unalignedObjectSplit = unalignedHeuristic.find(sinfo,cfg.sahBlockSize,uspace);
|
||||
unalignedObjectSAH = travCostUnaligned*halfArea(pinfo.geomBounds) + intCost*unalignedObjectSplit.splitSAH();
|
||||
bestSAH = min(unalignedObjectSAH,bestSAH);
|
||||
}
|
||||
@@ -207,7 +207,7 @@ namespace embree
|
||||
HeuristicStrandSplitSAH::Split strandSplit;
|
||||
float strandSAH = inf;
|
||||
if (bestSAH > 0.7f*leafSAH && pinfo.size() <= 256) {
|
||||
strandSplit = strandHeuristic.find(pinfo,cfg.logBlockSize);
|
||||
strandSplit = strandHeuristic.find(pinfo,cfg.sahBlockSize);
|
||||
strandSAH = travCostUnaligned*halfArea(pinfo.geomBounds) + intCost*strandSplit.splitSAH();
|
||||
bestSAH = min(strandSAH,bestSAH);
|
||||
}
|
||||
|
||||
@@ -194,14 +194,14 @@ namespace embree
|
||||
{
|
||||
/*! default settings */
|
||||
Settings ()
|
||||
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8),
|
||||
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8),
|
||||
travCost(1.0f), intCost(1.0f), singleLeafTimeSegment(false),
|
||||
singleThreadThreshold(1024) {}
|
||||
|
||||
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 sahBlockSize; //!< 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
|
||||
@@ -294,18 +294,18 @@ namespace embree
|
||||
const Split find(const SetMB& set)
|
||||
{
|
||||
/* first try standard object split */
|
||||
const Split object_split = heuristicObjectSplit.find(set,cfg.logBlockSize);
|
||||
const Split object_split = heuristicObjectSplit.find(set,cfg.sahBlockSize);
|
||||
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);
|
||||
const float leaf_sah = set.leafSAH(cfg.sahBlockSize);
|
||||
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 Split temporal_split = heuristicTemporalSplit.find(set,cfg.sahBlockSize);
|
||||
const float temporal_split_sah = temporal_split.splitSAH();
|
||||
|
||||
/* take temporal split if it improved SAH */
|
||||
@@ -534,7 +534,7 @@ namespace embree
|
||||
const Split csplit = find(current.prims);
|
||||
|
||||
/*! compute leaf and split cost */
|
||||
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize);
|
||||
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.sahBlockSize);
|
||||
const float splitSAH = cfg.travCost*current.prims.halfArea()+cfg.intCost*csplit.splitSAH();
|
||||
assert((current.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0)));
|
||||
|
||||
|
||||
@@ -34,12 +34,12 @@ namespace embree
|
||||
{
|
||||
/*! default settings */
|
||||
Settings ()
|
||||
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8) {}
|
||||
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8) {}
|
||||
|
||||
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 sahBlockSize; //!< blocksize for SAH heuristic
|
||||
size_t minLeafSize; //!< minimum size of a leaf
|
||||
size_t maxLeafSize; //!< maximum size of a leaf
|
||||
};
|
||||
@@ -259,10 +259,10 @@ namespace embree
|
||||
{
|
||||
/* variable to track the SAH of the best splitting approach */
|
||||
float bestSAH = inf;
|
||||
const float leafSAH = current.prims.leafSAH(cfg.logBlockSize);
|
||||
const float leafSAH = current.prims.leafSAH(cfg.sahBlockSize);
|
||||
|
||||
/* perform standard binning in aligned space */
|
||||
HeuristicBinning::Split alignedObjectSplit = alignedHeuristic.find(current.prims,cfg.logBlockSize);
|
||||
HeuristicBinning::Split alignedObjectSplit = alignedHeuristic.find(current.prims,cfg.sahBlockSize);
|
||||
float alignedObjectSAH = alignedObjectSplit.splitSAH();
|
||||
bestSAH = min(alignedObjectSAH,bestSAH);
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace embree
|
||||
if (alignedObjectSAH > 0.7f*leafSAH) {
|
||||
uspace = unalignedHeuristic.computeAlignedSpaceMB(scene,current.prims);
|
||||
const SetMB sset = current.prims.primInfo(recalculatePrimRef,uspace);
|
||||
unalignedObjectSplit = unalignedHeuristic.find(sset,cfg.logBlockSize,uspace);
|
||||
unalignedObjectSplit = unalignedHeuristic.find(sset,cfg.sahBlockSize,uspace);
|
||||
unalignedObjectSAH = 1.3f*unalignedObjectSplit.splitSAH(); // makes unaligned splits more expensive
|
||||
bestSAH = min(unalignedObjectSAH,bestSAH);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ namespace embree
|
||||
typename HeuristicTemporal::Split temporal_split;
|
||||
if (bestSAH > 0.5f*leafSAH) {
|
||||
if (current.prims.time_range.size() > 1.01f/float(current.prims.max_num_time_segments)) {
|
||||
temporal_split = temporalSplitHeuristic.find(current.prims,cfg.logBlockSize);
|
||||
temporal_split = temporalSplitHeuristic.find(current.prims,cfg.sahBlockSize);
|
||||
temporal_split_sah = temporal_split.splitSAH();
|
||||
bestSAH = min(temporal_split_sah,bestSAH);
|
||||
}
|
||||
|
||||
@@ -45,17 +45,17 @@ namespace embree
|
||||
{
|
||||
/*! default settings */
|
||||
Settings ()
|
||||
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8),
|
||||
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8),
|
||||
travCost(1.0f), intCost(1.0f), singleThreadThreshold(1024), primrefarrayalloc(inf) {}
|
||||
|
||||
/*! initialize settings from API settings */
|
||||
Settings (const RTCBuildArguments& settings)
|
||||
: branchingFactor(2), maxDepth(32), logBlockSize(0), minLeafSize(1), maxLeafSize(8),
|
||||
: branchingFactor(2), maxDepth(32), sahBlockSize(1), minLeafSize(1), maxLeafSize(8),
|
||||
travCost(1.0f), intCost(1.0f), singleThreadThreshold(1024), primrefarrayalloc(inf)
|
||||
{
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,maxBranchingFactor)) branchingFactor = settings.maxBranchingFactor;
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,maxDepth )) maxDepth = settings.maxDepth;
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,sahBlockSize )) logBlockSize = bsr(settings.sahBlockSize);
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,sahBlockSize )) sahBlockSize = settings.sahBlockSize;
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,minLeafSize )) minLeafSize = settings.minLeafSize;
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,maxLeafSize )) maxLeafSize = settings.maxLeafSize;
|
||||
if (RTC_BUILD_ARGUMENTS_HAS(settings,traversalCost )) travCost = settings.traversalCost;
|
||||
@@ -63,13 +63,13 @@ namespace embree
|
||||
}
|
||||
|
||||
Settings (size_t sahBlockSize, size_t minLeafSize, size_t maxLeafSize, float travCost, float intCost, size_t singleThreadThreshold, size_t primrefarrayalloc = inf)
|
||||
: branchingFactor(2), maxDepth(32), logBlockSize(bsr(sahBlockSize)), minLeafSize(minLeafSize), maxLeafSize(maxLeafSize),
|
||||
: branchingFactor(2), maxDepth(32), sahBlockSize(sahBlockSize), minLeafSize(minLeafSize), maxLeafSize(maxLeafSize),
|
||||
travCost(travCost), intCost(intCost), singleThreadThreshold(singleThreadThreshold), primrefarrayalloc(primrefarrayalloc) {}
|
||||
|
||||
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 sahBlockSize; //!< 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
|
||||
@@ -213,10 +213,10 @@ namespace embree
|
||||
progressMonitor(current.size());
|
||||
|
||||
/*! find best split */
|
||||
auto split = heuristic.find(current.prims,cfg.logBlockSize);
|
||||
auto split = heuristic.find(current.prims,cfg.sahBlockSize);
|
||||
|
||||
/*! compute leaf and split cost */
|
||||
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize);
|
||||
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.sahBlockSize);
|
||||
const float splitSAH = cfg.travCost*halfArea(current.prims.geomBounds)+cfg.intCost*split.splitSAH();
|
||||
assert((current.prims.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0)));
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace embree
|
||||
BuildRecord& brecord = children[bestChild];
|
||||
BuildRecord lrecord(current.depth+1);
|
||||
BuildRecord rrecord(current.depth+1);
|
||||
auto split = heuristic.find(brecord.prims,cfg.logBlockSize);
|
||||
auto split = heuristic.find(brecord.prims,cfg.sahBlockSize);
|
||||
heuristic.split(split,brecord.prims,lrecord.prims,rrecord.prims);
|
||||
children[bestChild ] = lrecord;
|
||||
children[numChildren] = rrecord;
|
||||
|
||||
@@ -350,7 +350,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best split by scanning binning information */
|
||||
__forceinline Split best(const BinMapping<BINS>& mapping, const size_t blocks_shift) const
|
||||
__forceinline Split best(const BinMapping<BINS>& mapping, const size_t sahBlockSize) const
|
||||
{
|
||||
/* sweep from right to left and compute parallel prefix of merged bounds */
|
||||
vfloat4 rAreas[BINS];
|
||||
@@ -366,7 +366,7 @@ namespace embree
|
||||
rAreas[i][3] = 0.0f;
|
||||
}
|
||||
/* sweep from left to right and compute SAH */
|
||||
vuint4 blocks_add = (1 << blocks_shift)-1;
|
||||
vuint4 blocks_add = sahBlockSize-1;
|
||||
vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0;
|
||||
count = 0; bx = empty; by = empty; bz = empty;
|
||||
for (size_t i=1; i<mapping.size(); i++, ii+=1)
|
||||
@@ -377,8 +377,8 @@ namespace embree
|
||||
bz.extend(bounds(i-1,2)); float Az = expectedApproxHalfArea(bz);
|
||||
const vfloat4 lArea = vfloat4(Ax,Ay,Az,Az);
|
||||
const vfloat4 rArea = rAreas[i];
|
||||
const vuint4 lCount = (count +blocks_add) >> (unsigned int)(blocks_shift); // if blocks_shift >=1 then lCount < 4B and could be represented with an vint4, which would allow for faster vfloat4 conversions.
|
||||
const vuint4 rCount = (rCounts[i]+blocks_add) >> (unsigned int)(blocks_shift);
|
||||
const vuint4 lCount = (count +blocks_add) / vuint4(sahBlockSize); // if blocks_shift >=1 then lCount < 4B and could be represented with an vint4, which would allow for faster vfloat4 conversions.
|
||||
const vuint4 rCount = (rCounts[i]+blocks_add) / vuint4(sahBlockSize);
|
||||
const vfloat4 sah = madd(lArea,vfloat4(lCount),rArea*vfloat4(rCount));
|
||||
//const vfloat4 sah = madd(lArea,vfloat4(vint4(lCount)),rArea*vfloat4(vint4(rCount)));
|
||||
|
||||
@@ -458,7 +458,7 @@ namespace embree
|
||||
vuint4 _counts[BINS]; //!< counts number of primitives that map into the bins
|
||||
};
|
||||
|
||||
#if defined(__AVX512ER__) // KNL
|
||||
#if 0 && defined(__AVX512ER__) // KNL
|
||||
|
||||
/*! mapping into bins */
|
||||
template<>
|
||||
@@ -831,8 +831,10 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best split by scanning binning information */
|
||||
__forceinline Split best(const BinMapping<16>& mapping, const size_t blocks_shift) const
|
||||
__forceinline Split best(const BinMapping<16>& mapping, const size_t sahBlockSize) const
|
||||
{
|
||||
const size_t blocks_shift = bsr(sahBlockSize);
|
||||
|
||||
/* find best dimension */
|
||||
float bestSAH = inf;
|
||||
int bestDim = -1;
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace embree
|
||||
return expectedApproxHalfArea(geomBounds)*float(size());
|
||||
}
|
||||
|
||||
__forceinline float leafSAH(size_t block_shift) const {
|
||||
return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<<block_shift)-1) >> block_shift);
|
||||
__forceinline float leafSAH(size_t sahBlockSize) const {
|
||||
return expectedApproxHalfArea(geomBounds)*float((size()+sahBlockSize-1) / sahBlockSize);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -70,21 +70,21 @@ namespace embree
|
||||
: prims(prims) {}
|
||||
|
||||
/*! finds the best split */
|
||||
__noinline const Split find(const PrimInfoRange& pinfo, const size_t logBlockSize)
|
||||
__noinline const Split find(const PrimInfoRange& pinfo, const size_t sahBlockSize)
|
||||
{
|
||||
if (likely(pinfo.size() < PARALLEL_THRESHOLD))
|
||||
return find_template<false>(pinfo,logBlockSize);
|
||||
return find_template<false>(pinfo,sahBlockSize);
|
||||
else
|
||||
return find_template<true>(pinfo,logBlockSize);
|
||||
return find_template<true>(pinfo,sahBlockSize);
|
||||
}
|
||||
|
||||
template<bool parallel>
|
||||
__forceinline const Split find_template(const PrimInfoRange& pinfo, const size_t logBlockSize)
|
||||
__forceinline const Split find_template(const PrimInfoRange& pinfo, const size_t sahBlockSize)
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<BINS> mapping(pinfo);
|
||||
bin_serial_or_parallel<parallel>(binner,prims,pinfo.begin(),pinfo.end(),PARALLEL_FIND_BLOCK_SIZE,mapping);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
return binner.best(mapping,sahBlockSize);
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
@@ -186,12 +186,12 @@ namespace embree
|
||||
static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128;
|
||||
|
||||
/*! finds the best split */
|
||||
const Split find(const SetMB& set, const size_t logBlockSize)
|
||||
const Split find(const SetMB& set, const size_t sahBlockSize)
|
||||
{
|
||||
ObjectBinner binner(empty);
|
||||
const BinMapping<BINS> mapping(set.size(),set.centBounds);
|
||||
bin_parallel(binner,set.prims->data(),set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping);
|
||||
Split osplit = binner.best(mapping,logBlockSize);
|
||||
Split osplit = binner.best(mapping,sahBlockSize);
|
||||
osplit.sah *= set.time_range.size();
|
||||
if (!osplit.valid()) osplit.data = Split::SPLIT_FALLBACK; // use fallback split
|
||||
return osplit;
|
||||
|
||||
@@ -104,23 +104,23 @@ namespace embree
|
||||
};
|
||||
|
||||
/*! finds the best split */
|
||||
__forceinline const Split find(const PrimInfoRange& pinfo, const size_t logBlockSize, const LinearSpace3fa& space)
|
||||
__forceinline const Split find(const PrimInfoRange& pinfo, const size_t sahBlockSize, const LinearSpace3fa& space)
|
||||
{
|
||||
if (likely(pinfo.size() < 10000))
|
||||
return find_template<false>(pinfo,logBlockSize,space);
|
||||
return find_template<false>(pinfo,sahBlockSize,space);
|
||||
else
|
||||
return find_template<true>(pinfo,logBlockSize,space);
|
||||
return find_template<true>(pinfo,sahBlockSize,space);
|
||||
}
|
||||
|
||||
/*! finds the best split */
|
||||
template<bool parallel>
|
||||
const Split find_template(const PrimInfoRange& set, const size_t logBlockSize, const LinearSpace3fa& space)
|
||||
const Split find_template(const PrimInfoRange& set, const size_t sahBlockSize, const LinearSpace3fa& space)
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<BINS> mapping(set);
|
||||
BinBoundsAndCenter binBoundsAndCenter(scene,space);
|
||||
bin_serial_or_parallel<parallel>(binner,prims,set.begin(),set.end(),size_t(4096),mapping,binBoundsAndCenter);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
return binner.best(mapping,sahBlockSize);
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
@@ -278,13 +278,13 @@ namespace embree
|
||||
};
|
||||
|
||||
/*! finds the best split */
|
||||
const Split find(const SetMB& set, const size_t logBlockSize, const LinearSpace3fa& space)
|
||||
const Split find(const SetMB& set, const size_t sahBlockSize, const LinearSpace3fa& space)
|
||||
{
|
||||
BinBoundsAndCenter binBoundsAndCenter(scene,set.time_range,space);
|
||||
ObjectBinner binner(empty);
|
||||
const BinMapping<BINS> mapping(set.size(),set.centBounds);
|
||||
bin_parallel(binner,set.prims->data(),set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping,binBoundsAndCenter);
|
||||
Split osplit = binner.best(mapping,logBlockSize);
|
||||
Split osplit = binner.best(mapping,sahBlockSize);
|
||||
osplit.sah *= set.time_range.size();
|
||||
if (!osplit.valid()) osplit.data = Split::SPLIT_FALLBACK; // use fallback split
|
||||
return osplit;
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace embree
|
||||
}
|
||||
}
|
||||
|
||||
__noinline const Split find(PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
__noinline const Split find(PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
/* single element */
|
||||
if (set.size() <= 1)
|
||||
@@ -294,28 +294,28 @@ namespace embree
|
||||
}
|
||||
|
||||
/* find best split */
|
||||
return object_find(set,logBlockSize);
|
||||
return object_find(set,sahBlockSize);
|
||||
}
|
||||
|
||||
|
||||
/*! finds the best object split */
|
||||
__forceinline const Split object_find(const PrimInfoExtRange& set,const size_t logBlockSize)
|
||||
__forceinline const Split object_find(const PrimInfoExtRange& set,const size_t sahBlockSize)
|
||||
{
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,logBlockSize);
|
||||
else return parallel_object_find (set,logBlockSize);
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,sahBlockSize);
|
||||
else return parallel_object_find (set,sahBlockSize);
|
||||
}
|
||||
|
||||
/*! finds the best object split */
|
||||
__noinline const Split sequential_object_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
__noinline const Split sequential_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<OBJECT_BINS> mapping(set.centBounds);
|
||||
binner.bin(prims0,set.begin(),set.end(),mapping);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
return binner.best(mapping,sahBlockSize);
|
||||
}
|
||||
|
||||
/*! finds the best split */
|
||||
__noinline const Split parallel_object_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
__noinline const Split parallel_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<OBJECT_BINS> mapping(set.centBounds);
|
||||
@@ -327,7 +327,7 @@ namespace embree
|
||||
Binner r = b0; r.merge(b1,_mapping.size()); return r;
|
||||
};
|
||||
binner = parallel_reduce(set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,binner,body,reduction);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
return binner.best(mapping,sahBlockSize);
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
|
||||
@@ -344,7 +344,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best split by scanning binning information */
|
||||
SpatialBinSplit<BINS> best(const SpatialBinMapping<BINS>& mapping, const size_t blocks_shift) const
|
||||
SpatialBinSplit<BINS> best(const SpatialBinMapping<BINS>& mapping, const size_t sahBlockSize) const
|
||||
{
|
||||
/* sweep from right to left and compute parallel prefix of merged bounds */
|
||||
vfloat4 rAreas[BINS];
|
||||
@@ -361,7 +361,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* sweep from left to right and compute SAH */
|
||||
vuint4 blocks_add = (1 << blocks_shift)-1;
|
||||
vuint4 blocks_add = sahBlockSize-1;
|
||||
vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0; vuint4 vbestlCount = 0; vuint4 vbestrCount = 0;
|
||||
count = 0; bx = empty; by = empty; bz = empty;
|
||||
for (size_t i=1; i<BINS; i++, ii+=1)
|
||||
@@ -372,8 +372,8 @@ namespace embree
|
||||
bz.extend(bounds[i-1][2]); float Az = halfArea(bz);
|
||||
const vfloat4 lArea = vfloat4(Ax,Ay,Az,Az);
|
||||
const vfloat4 rArea = rAreas[i];
|
||||
const vuint4 lCount = (count +blocks_add) >> (unsigned int)(blocks_shift);
|
||||
const vuint4 rCount = (rCounts[i]+blocks_add) >> (unsigned int)(blocks_shift);
|
||||
const vuint4 lCount = (count +blocks_add) / vuint4(sahBlockSize);
|
||||
const vuint4 rCount = (rCounts[i]+blocks_add) / vuint4(sahBlockSize);
|
||||
const vfloat4 sah = madd(lArea,vfloat4(lCount),rArea*vfloat4(rCount));
|
||||
// const vfloat4 sah = madd(lArea,vfloat4(vint4(lCount)),rArea*vfloat4(vint4(rCount)));
|
||||
const vbool4 mask = sah < vbestSAH;
|
||||
|
||||
@@ -48,8 +48,8 @@ namespace embree
|
||||
return expectedApproxHalfArea(geomBounds)*float(size());
|
||||
}
|
||||
|
||||
__forceinline float leafSAH(size_t block_shift) const {
|
||||
return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<<block_shift)-1) >> block_shift);
|
||||
__forceinline float leafSAH(size_t sahBlockSize) const {
|
||||
return expectedApproxHalfArea(geomBounds)*float((size()+sahBlockSize-1) / sahBlockSize);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -186,10 +186,10 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best split */
|
||||
const Split find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
const Split find(const PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
SplitInfo oinfo;
|
||||
const ObjectSplit object_split = object_find(set,logBlockSize,oinfo);
|
||||
const ObjectSplit object_split = object_find(set,sahBlockSize,oinfo);
|
||||
const float object_split_sah = object_split.splitSAH();
|
||||
|
||||
if (unlikely(set.has_ext_range()))
|
||||
@@ -200,7 +200,7 @@ namespace embree
|
||||
if (safeArea(overlap) >= SPATIAL_ASPLIT_AREA_THRESHOLD*safeArea(root_info.geomBounds) &&
|
||||
safeArea(overlap) >= SPATIAL_ASPLIT_OVERLAP_THRESHOLD*safeArea(set.geomBounds))
|
||||
{
|
||||
const SpatialSplit spatial_split = spatial_find(set, logBlockSize);
|
||||
const SpatialSplit spatial_split = spatial_find(set, sahBlockSize);
|
||||
const float spatial_split_sah = spatial_split.splitSAH();
|
||||
|
||||
/* valid spatial split, better SAH and number of splits do not exceed extended range */
|
||||
@@ -216,25 +216,25 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best object split */
|
||||
__forceinline const ObjectSplit object_find(const PrimInfoExtRange& set, const size_t logBlockSize, SplitInfo &info)
|
||||
__forceinline const ObjectSplit object_find(const PrimInfoExtRange& set, const size_t sahBlockSize, SplitInfo &info)
|
||||
{
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,logBlockSize,info);
|
||||
else return parallel_object_find (set,logBlockSize,info);
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,sahBlockSize,info);
|
||||
else return parallel_object_find (set,sahBlockSize,info);
|
||||
}
|
||||
|
||||
/*! finds the best object split */
|
||||
__noinline const ObjectSplit sequential_object_find(const PrimInfoExtRange& set, const size_t logBlockSize, SplitInfo &info)
|
||||
__noinline const ObjectSplit sequential_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize, SplitInfo &info)
|
||||
{
|
||||
ObjectBinner binner(empty);
|
||||
const BinMapping<OBJECT_BINS> mapping(set);
|
||||
binner.bin(prims0,set.begin(),set.end(),mapping);
|
||||
ObjectSplit s = binner.best(mapping,logBlockSize);
|
||||
ObjectSplit s = binner.best(mapping,sahBlockSize);
|
||||
binner.getSplitInfo(mapping, s, info);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*! finds the best split */
|
||||
__noinline const ObjectSplit parallel_object_find(const PrimInfoExtRange& set, const size_t logBlockSize, SplitInfo &info)
|
||||
__noinline const ObjectSplit parallel_object_find(const PrimInfoExtRange& set, const size_t sahBlockSize, SplitInfo &info)
|
||||
{
|
||||
ObjectBinner binner(empty);
|
||||
const BinMapping<OBJECT_BINS> mapping(set);
|
||||
@@ -242,29 +242,29 @@ namespace embree
|
||||
binner = parallel_reduce(set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,binner,
|
||||
[&] (const range<size_t>& r) -> ObjectBinner { ObjectBinner binner(empty); binner.bin(prims0+r.begin(),r.size(),_mapping); return binner; },
|
||||
[&] (const ObjectBinner& b0, const ObjectBinner& b1) -> ObjectBinner { ObjectBinner r = b0; r.merge(b1,_mapping.size()); return r; });
|
||||
ObjectSplit s = binner.best(mapping,logBlockSize);
|
||||
ObjectSplit s = binner.best(mapping,sahBlockSize);
|
||||
binner.getSplitInfo(mapping, s, info);
|
||||
return s;
|
||||
}
|
||||
|
||||
/*! finds the best spatial split */
|
||||
__forceinline const SpatialSplit spatial_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
__forceinline const SpatialSplit spatial_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_spatial_find(set, logBlockSize);
|
||||
else return parallel_spatial_find (set, logBlockSize);
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_spatial_find(set, sahBlockSize);
|
||||
else return parallel_spatial_find (set, sahBlockSize);
|
||||
}
|
||||
|
||||
/*! finds the best spatial split */
|
||||
__noinline const SpatialSplit sequential_spatial_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
__noinline const SpatialSplit sequential_spatial_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
SpatialBinner binner(empty);
|
||||
const SpatialBinMapping<SPATIAL_BINS> mapping(set);
|
||||
binner.bin2(splitterFactory,prims0,set.begin(),set.end(),mapping);
|
||||
/* todo: best spatial split not exeeding the extended range does not provide any benefit ?*/
|
||||
return binner.best(mapping,logBlockSize); //,set.ext_size());
|
||||
return binner.best(mapping,sahBlockSize); //,set.ext_size());
|
||||
}
|
||||
|
||||
__noinline const SpatialSplit parallel_spatial_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
__noinline const SpatialSplit parallel_spatial_find(const PrimInfoExtRange& set, const size_t sahBlockSize)
|
||||
{
|
||||
SpatialBinner binner(empty);
|
||||
const SpatialBinMapping<SPATIAL_BINS> mapping(set);
|
||||
@@ -276,7 +276,7 @@ namespace embree
|
||||
return binner; },
|
||||
[&] (const SpatialBinner& b0, const SpatialBinner& b1) -> SpatialBinner { return SpatialBinner::reduce(b0,b1); });
|
||||
/* todo: best spatial split not exeeding the extended range does not provide any benefit ?*/
|
||||
return binner.best(mapping,logBlockSize); //,set.ext_size());
|
||||
return binner.best(mapping,sahBlockSize); //,set.ext_size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best split */
|
||||
const Split find(const range<size_t>& set, size_t logBlockSize)
|
||||
const Split find(const range<size_t>& set, size_t sahBlockSize)
|
||||
{
|
||||
Vec3fa axis0(0,0,1);
|
||||
uint64_t bestGeomPrimID = -1;
|
||||
@@ -132,8 +132,8 @@ namespace embree
|
||||
return Split(inf,axis0,axis1);
|
||||
|
||||
/*! calculate sah for the split */
|
||||
const size_t lblocks = (lnum+(1ull<<logBlockSize)-1ull) >> logBlockSize;
|
||||
const size_t rblocks = (rnum+(1ull<<logBlockSize)-1ull) >> logBlockSize;
|
||||
const size_t lblocks = (lnum+sahBlockSize-1ull) / sahBlockSize;
|
||||
const size_t rblocks = (rnum+sahBlockSize-1ull) / sahBlockSize;
|
||||
const float sah = madd(float(lblocks),halfArea(lbounds),float(rblocks)*halfArea(rbounds));
|
||||
return Split(sah,axis0,axis1);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace embree
|
||||
TemporalBinInfo r = a; r.merge(b); return r;
|
||||
}
|
||||
|
||||
Split best(int logBlockSize, BBox1f time_range, const SetMB& set)
|
||||
Split best(int sahBlockSize, BBox1f time_range, const SetMB& set)
|
||||
{
|
||||
float bestSAH = inf;
|
||||
float bestPos = 0.0f;
|
||||
@@ -139,8 +139,8 @@ namespace embree
|
||||
const BBox1f dt1(center_time,time_range.upper);
|
||||
|
||||
/* calculate sah */
|
||||
const size_t lCount = (count0[b]+(size_t(1) << logBlockSize)-1) >> int(logBlockSize);
|
||||
const size_t rCount = (count1[b]+(size_t(1) << logBlockSize)-1) >> int(logBlockSize);
|
||||
const size_t lCount = (count0[b]+sahBlockSize-1) / sahBlockSize;
|
||||
const size_t rCount = (count1[b]+sahBlockSize-1) / sahBlockSize;
|
||||
float sah0 = expectedApproxHalfArea(bounds0[b])*float(lCount)*dt0.size();
|
||||
float sah1 = expectedApproxHalfArea(bounds1[b])*float(rCount)*dt1.size();
|
||||
if (unlikely(lCount == 0)) sah0 = 0.0f; // happens for initial splits when objects not alive over entire shutter time
|
||||
@@ -163,12 +163,12 @@ namespace embree
|
||||
};
|
||||
|
||||
/*! finds the best split */
|
||||
const Split find(const SetMB& set, const size_t logBlockSize)
|
||||
const Split find(const SetMB& set, const size_t sahBlockSize)
|
||||
{
|
||||
assert(set.size() > 0);
|
||||
TemporalBinInfo binner(empty);
|
||||
binner.bin_parallel(set.prims->data(),set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,set.time_range,set,recalculatePrimRef);
|
||||
Split tsplit = binner.best((int)logBlockSize,set.time_range,set);
|
||||
Split tsplit = binner.best((int)sahBlockSize,set.time_range,set);
|
||||
if (!tsplit.valid()) tsplit.data = Split::SPLIT_FALLBACK; // use fallback split
|
||||
return tsplit;
|
||||
}
|
||||
|
||||
@@ -145,8 +145,8 @@ namespace embree
|
||||
//return halfArea(geomBounds)*blocks(num);
|
||||
}
|
||||
|
||||
__forceinline float leafSAH(size_t block_shift) const {
|
||||
return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<<block_shift)-1) >> block_shift);
|
||||
__forceinline float leafSAH(size_t sahBlockSize) const {
|
||||
return expectedApproxHalfArea(geomBounds)*float((size()+sahBlockSize-1) / sahBlockSize);
|
||||
//return halfArea(geomBounds)*float((num+3) >> 2);
|
||||
//return halfArea(geomBounds)*blocks(num);
|
||||
}
|
||||
@@ -231,8 +231,8 @@ namespace embree
|
||||
return time_range.size()*expectedApproxHalfArea(geomBounds)*float(num_time_segments);
|
||||
}
|
||||
|
||||
__forceinline float leafSAH(size_t block_shift) const {
|
||||
return time_range.size()*expectedApproxHalfArea(geomBounds)*float((num_time_segments+(size_t(1)<<block_shift)-1) >> block_shift);
|
||||
__forceinline float leafSAH(size_t sahBlockSize) const {
|
||||
return time_range.size()*expectedApproxHalfArea(geomBounds)*float((num_time_segments+sahBlockSize-1) / sahBlockSize);
|
||||
}
|
||||
|
||||
__forceinline float align_time(float ct) const
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace embree
|
||||
/* builder settings */
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = bsf(CurvePrimitive::max_size());
|
||||
settings.sahBlockSize = CurvePrimitive::max_size();
|
||||
settings.minLeafSize = CurvePrimitive::max_size();
|
||||
settings.maxLeafSize = CurvePrimitive::max_size();
|
||||
settings.finished_range_threshold = numPrimitives/1000;
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace embree
|
||||
BVHBuilderHairMSMBlur::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = bsf(CurvePrimitive::max_size());
|
||||
settings.sahBlockSize = CurvePrimitive::max_size();
|
||||
settings.minLeafSize = CurvePrimitive::max_size();
|
||||
settings.maxLeafSize = CurvePrimitive::max_size();
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace embree
|
||||
GeneralBVHBuilder::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = bsr(sahBlockSize);
|
||||
settings.sahBlockSize = sahBlockSize;
|
||||
settings.minLeafSize = minLeafSize;
|
||||
settings.maxLeafSize = maxLeafSize;
|
||||
settings.travCost = travCost;
|
||||
@@ -202,7 +202,7 @@ namespace embree
|
||||
BVHBuilderMSMBlur::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxDepth;
|
||||
settings.logBlockSize = bsr(sahBlockSize);
|
||||
settings.sahBlockSize = sahBlockSize;
|
||||
settings.minLeafSize = minLeafSize;
|
||||
settings.maxLeafSize = maxLeafSize;
|
||||
settings.travCost = travCost;
|
||||
@@ -590,7 +590,7 @@ namespace embree
|
||||
GeneralBVHBuilder::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = bsr(sahBlockSize);
|
||||
settings.sahBlockSize = sahBlockSize;
|
||||
settings.minLeafSize = minLeafSize;
|
||||
settings.maxLeafSize = maxLeafSize;
|
||||
settings.travCost = travCost;
|
||||
@@ -635,7 +635,7 @@ namespace embree
|
||||
BVHBuilderMSMBlur::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxDepth;
|
||||
settings.logBlockSize = bsr(sahBlockSize);
|
||||
settings.sahBlockSize = sahBlockSize;
|
||||
settings.minLeafSize = minLeafSize;
|
||||
settings.maxLeafSize = maxLeafSize;
|
||||
settings.travCost = travCost;
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace embree
|
||||
|
||||
/* settings for BVH build */
|
||||
GeneralBVHBuilder::Settings settings;
|
||||
settings.logBlockSize = bsr(N);
|
||||
settings.sahBlockSize = N;
|
||||
settings.minLeafSize = 1;
|
||||
settings.maxLeafSize = 1;
|
||||
settings.travCost = 1.0f;
|
||||
@@ -328,7 +328,7 @@ namespace embree
|
||||
BVHBuilderMSMBlur::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxDepth;
|
||||
settings.logBlockSize = bsr(N);
|
||||
settings.sahBlockSize = N;
|
||||
settings.minLeafSize = 1;
|
||||
settings.maxLeafSize = 1;
|
||||
settings.travCost = 1.0f;
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace embree
|
||||
GeneralBVHBuilder::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = bsr(N);
|
||||
settings.sahBlockSize = N;
|
||||
settings.minLeafSize = 1;
|
||||
settings.maxLeafSize = 1;
|
||||
settings.travCost = 1.0f;
|
||||
|
||||
Reference in New Issue
Block a user