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:
Sergey Sharybin
2016-02-22 16:25:33 +01:00
parent bbbbe68473
commit d9b729e342
5 changed files with 72 additions and 5 deletions

View File

@@ -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);
} }
} }

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 +