[Bf-blender-cvs] [d9b729e] master: Cycles: Only sort indices when finding a best dimension to split

Sergey Sharybin noreply at git.blender.org
Thu Mar 31 10:23:28 CEST 2016


Commit: d9b729e342b72bfe31e7932723a149db3b7aa77c
Author: Sergey Sharybin
Date:   Mon Feb 22 16:25:33 2016 +0100
Branches: master
https://developer.blender.org/rBd9b729e342b72bfe31e7932723a149db3b7aa77c

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.

===================================================================

M	intern/cycles/bvh/bvh_build.cpp
M	intern/cycles/bvh/bvh_params.h
M	intern/cycles/bvh/bvh_sort.cpp
M	intern/cycles/bvh/bvh_sort.h
M	intern/cycles/bvh/bvh_split.cpp

===================================================================

diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index b83c1e8..ce15e1b 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -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);
 		}
 	}
 
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index c9b4f2b..2b280d6 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -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
diff --git a/intern/cycles/bvh/bvh_sort.cpp b/intern/cycles/bvh/bvh_sort.cpp
index 3140bf2..8088dcc 100644
--- a/intern/cycles/bvh/bvh_sort.cpp
+++ b/intern/cycles/bvh/bvh_sort.cpp
@@ -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
diff --git a/intern/cycles/bvh/bvh_sort.h b/intern/cycles/bvh/bvh_sort.h
index 18aafb5..ec6edc4 100644
--- a/intern/cycles/bvh/bvh_sort.h
+++ b/intern/cycles/bvh/bvh_sort.h
@@ -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
 
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 037702c..ff0142f 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -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 +




More information about the Bf-blender-cvs mailing list