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:
@@ -245,6 +245,8 @@ BVHNode* BVHBuild::run()
|
|||||||
foreach(BVHSpatialStorage &storage, spatial_storage) {
|
foreach(BVHSpatialStorage &storage, spatial_storage) {
|
||||||
storage.spatial_right_bounds.clear();
|
storage.spatial_right_bounds.clear();
|
||||||
storage.spatial_right_bounds.resize(num_bins);
|
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 {
|
struct BVHSpatialStorage {
|
||||||
vector<BoundBox> spatial_right_bounds;
|
vector<BoundBox> spatial_right_bounds;
|
||||||
BVHSpatialBin spatial_bins[3][BVHParams::NUM_SPATIAL_BINS];
|
BVHSpatialBin spatial_bins[3][BVHParams::NUM_SPATIAL_BINS];
|
||||||
|
vector<int> spatial_indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
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);
|
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
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
void bvh_reference_sort(int start, int end, BVHReference *data, int dim);
|
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
|
CCL_NAMESPACE_END
|
||||||
|
|
||||||
|
@@ -42,15 +42,25 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder,
|
|||||||
const BVHReference *ref_ptr = &builder->references[range.start()];
|
const BVHReference *ref_ptr = &builder->references[range.start()];
|
||||||
float min_sah = FLT_MAX;
|
float min_sah = FLT_MAX;
|
||||||
|
|
||||||
|
storage->spatial_indices.resize(range.size());
|
||||||
|
int *indices = &storage->spatial_indices[0];
|
||||||
|
|
||||||
for(int dim = 0; dim < 3; dim++) {
|
for(int dim = 0; dim < 3; dim++) {
|
||||||
/* sort references */
|
/* Sort references.
|
||||||
bvh_reference_sort(range.start(), range.end(), &builder->references[0], dim);
|
* 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. */
|
/* sweep right to left and determine bounds. */
|
||||||
BoundBox right_bounds = BoundBox::empty;
|
BoundBox right_bounds = BoundBox::empty;
|
||||||
|
|
||||||
for(int i = range.size() - 1; i > 0; i--) {
|
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;
|
storage_->spatial_right_bounds[i - 1] = right_bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +68,7 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder,
|
|||||||
BoundBox left_bounds = BoundBox::empty;
|
BoundBox left_bounds = BoundBox::empty;
|
||||||
|
|
||||||
for(int i = 1; i < range.size(); i++) {
|
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];
|
right_bounds = storage_->spatial_right_bounds[i - 1];
|
||||||
|
|
||||||
float sah = nodeSAH +
|
float sah = nodeSAH +
|
||||||
|
Reference in New Issue
Block a user