forked from bartvdbraak/blender
Cycles: Only sort indices when finding a best dimension to split
This reduces amount of data being moved back and forth, which should have positive effect on the performance.
This commit is contained in:
parent
bbbbe68473
commit
d9b729e342
@ -245,6 +245,8 @@ BVHNode* BVHBuild::run()
|
||||
foreach(BVHSpatialStorage &storage, spatial_storage) {
|
||||
storage.spatial_right_bounds.clear();
|
||||
storage.spatial_right_bounds.resize(num_bins);
|
||||
storage.spatial_indices.clear();
|
||||
storage.spatial_indices.reserve(num_bins);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,6 +185,7 @@ struct BVHSpatialBin
|
||||
struct BVHSpatialStorage {
|
||||
vector<BoundBox> spatial_right_bounds;
|
||||
BVHSpatialBin spatial_bins[3][BVHParams::NUM_SPATIAL_BINS];
|
||||
vector<int> spatial_indices;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -65,5 +65,54 @@ void bvh_reference_sort(int start, int end, BVHReference *data, int dim)
|
||||
sort(data+start, data+end, compare);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
struct BVHReferenceCompareIndexed {
|
||||
public:
|
||||
BVHReferenceCompareIndexed(int dim, const BVHReference *data, int start)
|
||||
: dim_(dim),
|
||||
start_(start),
|
||||
data_(data)
|
||||
{}
|
||||
|
||||
bool operator()(const int a, const int b)
|
||||
{
|
||||
const BVHReference& ra = data_[start_ + a];
|
||||
const BVHReference& rb = data_[start_ + b];
|
||||
NO_EXTENDED_PRECISION float ca = ra.bounds().min[dim_] + ra.bounds().max[dim_];
|
||||
NO_EXTENDED_PRECISION float cb = rb.bounds().min[dim_] + rb.bounds().max[dim_];
|
||||
|
||||
if(ca < cb) return true;
|
||||
else if(ca > cb) return false;
|
||||
else if(ra.prim_object() < rb.prim_object()) return true;
|
||||
else if(ra.prim_object() > rb.prim_object()) return false;
|
||||
else if(ra.prim_index() < rb.prim_index()) return true;
|
||||
else if(ra.prim_index() > rb.prim_index()) return false;
|
||||
else if(ra.prim_type() < rb.prim_type()) return true;
|
||||
else if(ra.prim_type() > rb.prim_type()) return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
int dim_, start_;
|
||||
const BVHReference *data_;
|
||||
};
|
||||
|
||||
/* NOTE: indices are always from 0 to count, even in the cases when start is not
|
||||
* zero. This is to simplify indexing in the object splitter. Index array is also
|
||||
* always zero-based index.
|
||||
*/
|
||||
void bvh_reference_sort_indices(int start,
|
||||
int end,
|
||||
const BVHReference *data,
|
||||
int *indices,
|
||||
int dim)
|
||||
{
|
||||
const int count = end - start;
|
||||
for(int i = 0; i < count; ++i) {
|
||||
indices[i] = i;
|
||||
}
|
||||
BVHReferenceCompareIndexed compare(dim, data, start);
|
||||
sort(indices, indices+count, compare);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -21,6 +21,11 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void bvh_reference_sort(int start, int end, BVHReference *data, int dim);
|
||||
void bvh_reference_sort_indices(int start,
|
||||
int end,
|
||||
const BVHReference *data,
|
||||
int *indices,
|
||||
int dim);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@ -42,15 +42,25 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder,
|
||||
const BVHReference *ref_ptr = &builder->references[range.start()];
|
||||
float min_sah = FLT_MAX;
|
||||
|
||||
storage->spatial_indices.resize(range.size());
|
||||
int *indices = &storage->spatial_indices[0];
|
||||
|
||||
for(int dim = 0; dim < 3; dim++) {
|
||||
/* sort references */
|
||||
bvh_reference_sort(range.start(), range.end(), &builder->references[0], dim);
|
||||
/* Sort references.
|
||||
* We only sort indices, to save amount of memory being sent back
|
||||
* and forth.
|
||||
*/
|
||||
bvh_reference_sort_indices(range.start(),
|
||||
range.end(),
|
||||
&builder->references[0],
|
||||
indices,
|
||||
dim);
|
||||
|
||||
/* sweep right to left and determine bounds. */
|
||||
BoundBox right_bounds = BoundBox::empty;
|
||||
|
||||
for(int i = range.size() - 1; i > 0; i--) {
|
||||
right_bounds.grow(ref_ptr[i].bounds());
|
||||
right_bounds.grow(ref_ptr[indices[i]].bounds());
|
||||
storage_->spatial_right_bounds[i - 1] = right_bounds;
|
||||
}
|
||||
|
||||
@ -58,7 +68,7 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder,
|
||||
BoundBox left_bounds = BoundBox::empty;
|
||||
|
||||
for(int i = 1; i < range.size(); i++) {
|
||||
left_bounds.grow(ref_ptr[i - 1].bounds());
|
||||
left_bounds.grow(ref_ptr[indices[i - 1]].bounds());
|
||||
right_bounds = storage_->spatial_right_bounds[i - 1];
|
||||
|
||||
float sah = nodeSAH +
|
||||
|
Loading…
Reference in New Issue
Block a user