[Bf-blender-cvs] [6a69f2e] cycles_bvh: Cycles: Optimize aligned triangle storage a bit

Sergey Sharybin noreply at git.blender.org
Mon Jun 13 16:47:39 CEST 2016


Commit: 6a69f2ed1ce290de3c01ecef9e67a55d25fe121e
Author: Sergey Sharybin
Date:   Mon Jun 13 16:18:10 2016 +0200
Branches: cycles_bvh
https://developer.blender.org/rB6a69f2ed1ce290de3c01ecef9e67a55d25fe121e

Cycles: Optimize aligned triangle storage a bit

The idea is to keep triangle storage aligned with the BVH traversal code.

This gives couple of percent speedup comparing to previous version and
reduces overall slowdown (which is now 4% on the barcelona file here on
own desktop, and half of it is caused by the inner BVH node visibility
commit),

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

M	intern/cycles/bvh/bvh.cpp
M	intern/cycles/bvh/bvh.h
M	intern/cycles/kernel/geom/geom_motion_triangle.h
M	intern/cycles/kernel/geom/geom_triangle.h
M	intern/cycles/kernel/geom/geom_triangle_intersect.h
M	intern/cycles/kernel/kernel_textures.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/scene.h

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

diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index a8af8e4..5669bab 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -121,25 +121,57 @@ void BVH::refit(Progress& progress)
 
 /* Triangles */
 
-void BVH::pack_primitives()
+void BVH::pack_triangle(int idx, float4 tri_verts[3])
 {
-	size_t tidx_size = pack.prim_index.size();
+	int tob = pack.prim_object[idx];
+	assert(tob >= 0 && tob < objects.size());
+	const Mesh *mesh = objects[tob]->mesh;
+
+	int tidx = pack.prim_index[idx];
+	Mesh::Triangle t = mesh->get_triangle(tidx);
+	const float3 *vpos = &mesh->verts[0];
+	float3 v0 = vpos[t.v[0]];
+	float3 v1 = vpos[t.v[1]];
+	float3 v2 = vpos[t.v[2]];
+
+	tri_verts[0] = float3_to_float4(v0);
+	tri_verts[1] = float3_to_float4(v1);
+	tri_verts[2] = float3_to_float4(v2);
+}
 
+void BVH::pack_primitives()
+{
+	const size_t tidx_size = pack.prim_index.size();
+	size_t num_prim_triangles = 0;
+	/* Count number of triangles primitives in BVH. */
+	for(unsigned int i = 0; i < tidx_size; i++) {
+		if((pack.prim_index[i] != -1)) {
+			if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
+				++num_prim_triangles;
+			}
+		}
+	}
+	/* Reserve size for arrays. */
 	pack.prim_tri_index.clear();
 	pack.prim_tri_index.resize(tidx_size);
+	pack.prim_tri_verts.clear();
+	pack.prim_tri_verts.resize(num_prim_triangles * 3);
 	pack.prim_visibility.clear();
 	pack.prim_visibility.resize(tidx_size);
-
+	/* Fill in all the arrays. */
+	size_t prim_triangle_index = 0;
 	for(unsigned int i = 0; i < tidx_size; i++) {
 		if(pack.prim_index[i] != -1) {
 			int tob = pack.prim_object[i];
 			Object *ob = objects[tob];
 
-			if(pack.prim_type[i] & PRIMITIVE_TRIANGLE) {
-				pack.prim_tri_index[i] = 3 * (pack.prim_index[i] + ob->mesh->tri_offset);
+			if((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
+				pack_triangle(i, (float4*)&pack.prim_tri_verts[3 * prim_triangle_index]);
+				pack.prim_tri_index[i] = 3 * prim_triangle_index;
+				++prim_triangle_index;
 			}
 			else {
-				pack.prim_tri_index[i] = 0;
+				pack.prim_tri_index[i] = -1;
 			}
 
 			pack.prim_visibility[i] = ob->visibility;
@@ -148,7 +180,7 @@ void BVH::pack_primitives()
 				pack.prim_visibility[i] |= PATH_RAY_CURVE;
 		}
 		else {
-			pack.prim_tri_index[i] = 0;
+			pack.prim_tri_index[i] = -1;
 			pack.prim_visibility[i] = 0;
 		}
 	}
@@ -185,8 +217,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 
 	/* reserve */
 	size_t prim_index_size = pack.prim_index.size();
+	size_t prim_tri_verts_size = pack.prim_tri_verts.size();
 
 	size_t pack_prim_index_offset = prim_index_size;
+	size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
 	size_t pack_nodes_offset = nodes_size;
 	size_t pack_leaf_nodes_offset = leaf_nodes_size;
 	size_t object_offset = 0;
@@ -200,6 +234,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 		if(mesh->need_build_bvh()) {
 			if(mesh_map.find(mesh) == mesh_map.end()) {
 				prim_index_size += bvh->pack.prim_index.size();
+				prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
 				nodes_size += bvh->pack.nodes.size();
 				leaf_nodes_size += bvh->pack.leaf_nodes.size();
 
@@ -214,6 +249,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 	pack.prim_type.resize(prim_index_size);
 	pack.prim_object.resize(prim_index_size);
 	pack.prim_visibility.resize(prim_index_size);
+	pack.prim_tri_verts.resize(prim_tri_verts_size);
 	pack.prim_tri_index.resize(prim_index_size);
 	pack.nodes.resize(nodes_size);
 	pack.leaf_nodes.resize(leaf_nodes_size);
@@ -223,6 +259,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 	int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
 	int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
 	uint *pack_prim_visibility = (pack.prim_visibility.size())? &pack.prim_visibility[0]: NULL;
+	float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size())? &pack.prim_tri_verts[0]: NULL;
 	uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL;
 	int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL;
 	int4 *pack_leaf_nodes = (pack.leaf_nodes.size())? &pack.leaf_nodes[0]: NULL;
@@ -275,11 +312,12 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 			for(size_t i = 0; i < bvh_prim_index_size; i++) {
 				if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
 					pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_curve_offset;
-					pack_prim_tri_index[pack_prim_index_offset] = 0;
+					pack_prim_tri_index[pack_prim_index_offset] = -1;
 				}
 				else {
 					pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset;
-					pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i];
+					pack_prim_tri_index[pack_prim_index_offset] =
+					        bvh_prim_tri_index[i] + pack_prim_tri_verts_offset;
 				}
 
 				pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
@@ -289,6 +327,15 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
 			}
 		}
 
+		/* Merge triangle vertices data. */
+		if(bvh->pack.prim_tri_verts.size()) {
+			const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
+			memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
+			       &bvh->pack.prim_tri_verts[0],
+			       prim_tri_size*sizeof(float4));
+			pack_prim_tri_verts_offset += prim_tri_size;
+		}
+
 		/* merge nodes */
 		if(bvh->pack.leaf_nodes.size()) {
 			int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 5dd91fb..da7c9f3 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -52,8 +52,10 @@ struct PackedBVH {
 	array<int4> leaf_nodes;
 	/* object index to BVH node index mapping for instances */
 	array<int> object_node; 
-	/* Mapping from pndex from primitive to triangle. */
+	/* Mapping from primitive index to index in triangle array. */
 	array<uint> prim_tri_index;
+	/* Continuous storage of triangle vertices. */
+	array<float4> prim_tri_verts;
 	/* primitive type - triangle or strand */
 	array<int> prim_type;
 	/* visibility visibilitys for primitives */
@@ -91,8 +93,9 @@ public:
 protected:
 	BVH(const BVHParams& params, const vector<Object*>& objects);
 
-	/* triangles and strands*/
+	/* triangles and strands */
 	void pack_primitives();
+	void pack_triangle(int idx, float4 storage[3]);
 
 	/* merge instance BVH's */
 	void pack_instances(size_t nodes_size, size_t leaf_nodes_size);
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
index b1208e1..2fb8e21 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -51,9 +51,9 @@ ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals *kg, uint4 t
 {
 	if(step == numsteps) {
 		/* center step: regular vertex location */
-		verts[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+0));
-		verts[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+1));
-		verts[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+2));
+		verts[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
+		verts[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
+		verts[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
 	}
 	else {
 		/* center step not store in this array */
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 54281c0..0c2351e 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -28,9 +28,9 @@ ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
 {
 	/* load triangle vertices */
 	const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim));
-	const float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+0));
-	const float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+1));
-	const float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+2));
+	const float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
+	const float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
+	const float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
 
 	/* return normal */
 	if(ccl_fetch(sd, flag) & SD_NEGATIVE_SCALE_APPLIED)
@@ -44,9 +44,9 @@ ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int
 {
 	/* load triangle vertices */
 	const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
-	float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+0));
-	float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+1));
-	float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+2));
+	float3 v0 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
+	float3 v1 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
+	float3 v2 = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
 
 	/* compute point */
 	float t = 1.0f - u - v;
@@ -70,9 +70,9 @@ ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int
 ccl_device_inline void triangle_vertices(KernelGlobals *kg, int prim, float3 P[3])
 {
 	const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
-	P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+0));
-	P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+1));
-	P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w+2));
+	P[0] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+0));
+	P[1] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+1));
+	P[2] = float4_to_float3(kernel_tex_fetch(__prim_tri_verts, tri_vindex.w+2));
 }
 
 /* Interpolate smooth vertex normal from vertices */
@@ -94,9 +94,9 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, ccl_addr_spa
 {
 	/* fetch triangle vertex coordinates */
 	const u

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list