[Bf-blender-cvs] [dd70d328ece] cycles_embree: Cycles: Embree accelerator now supports instanced triangle meshes

Stefan Werner noreply at git.blender.org
Sun Nov 26 23:11:07 CET 2017


Commit: dd70d328eceac433a6c42c7966a737d80e1d3aab
Author: Stefan Werner
Date:   Tue Jun 6 14:41:20 2017 +0200
Branches: cycles_embree
https://developer.blender.org/rBdd70d328eceac433a6c42c7966a737d80e1d3aab

Cycles: Embree accelerator now supports instanced triangle meshes

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

M	intern/cycles/bvh/bvh_embree.cpp
M	intern/cycles/bvh/bvh_embree.h
M	intern/cycles/kernel/bvh/bvh.h
A	intern/cycles/kernel/bvh/bvh_embree_traversal.h

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

diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 220e5b1d6e0..331657d270a 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -24,9 +24,21 @@
 #include "util/util_foreach.h"
 
 #include "embree2/rtcore_geometry.h"
+#include "kernel/bvh/bvh_embree_traversal.h"
+
+#include "xmmintrin.h"
+#include "pmmintrin.h"
+
+// #define EMBREE_CURVES
+#define EMBREE_SHARED_MEM 1
 
 CCL_NAMESPACE_BEGIN
 
+void cclFilterFunc(void* userDataPtr, RTCRay& ray)
+{
+	return;
+}
+
 /* This is to have a shared device between all BVH instances */
 RTCDevice BVHEmbree::rtc_shared_device = NULL;
 int BVHEmbree::rtc_shared_users = 0;
@@ -35,9 +47,11 @@ thread_mutex BVHEmbree::rtc_shared_mutex;
 BVHEmbree::BVHEmbree(const BVHParams& params_, const vector<Object*>& objects_)
 : BVH(params_, objects_), scene(NULL)
 {
+	_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
+	_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
 	thread_scoped_lock lock(rtc_shared_mutex);
 	if(rtc_shared_users == 0) {
-		rtc_shared_device = rtcNewDevice("verbose=2");
+		rtc_shared_device = rtcNewDevice("verbose=1");
 	}
 	rtc_shared_users++;
 
@@ -66,6 +80,14 @@ void BVHEmbree::destroy(RTCScene scene)
 	}
 }
 
+void BVHEmbree::delete_rtcScene()
+{
+	if(scene) {
+		rtcDeleteScene(scene);
+		scene = NULL;
+	}
+}
+
 void BVHEmbree::build(Progress& progress)
 {
 	progress.set_substatus("Building BVH");
@@ -75,7 +97,7 @@ void BVHEmbree::build(Progress& progress)
 		scene = NULL;
 	}
 
-	scene = rtcDeviceNewScene(rtc_shared_device, RTC_SCENE_DYNAMIC|RTC_SCENE_ROBUST, RTC_INTERSECT1);
+	scene = rtcDeviceNewScene(rtc_shared_device, RTC_SCENE_STATIC|RTC_SCENE_INCOHERENT|RTC_SCENE_HIGH_QUALITY|RTC_SCENE_ROBUST, RTC_INTERSECT1);
 
 	int i = 0;
 
@@ -84,70 +106,76 @@ void BVHEmbree::build(Progress& progress)
 	foreach(Object *ob, objects) {
 		unsigned geom_id;
 
+		size_t prim_index_offset = pack.prim_index.size();
 		if(params.top_level) {
 			if(!ob->is_traceable()) {
 				++i;
 				continue;
 			}
 			if(!ob->mesh->is_instanced())
-				geom_id = add_reference_mesh(ob->mesh, i);
+				geom_id = add_mesh(ob->mesh, i);
 			else
-				geom_id = add_reference_object(ob, i);
+				geom_id = add_instance(ob, i);
 
-			rtcSetUserData(scene, geom_id, (void*)ob->mesh->tri_offset);
 		}
 		else
-			geom_id = add_reference_mesh(ob->mesh, i);
+			geom_id = add_mesh(ob->mesh, i);
 
+		if(geom_id != RTC_INVALID_GEOMETRY_ID) {
+			if(!ob->mesh->is_instanced()) {
+				rtcSetUserData(scene, geom_id, (void*)prim_index_offset);
+				rtcSetIntersectionFilterFunction(scene, geom_id, cclFilterFunc);
+			}
+			else {
+				rtcSetUserData(scene, geom_id, (void*)0);
+			}
+		}
 		i++;
 
 		if(progress.get_cancel()) return;
 	}
 
 	if(progress.get_cancel()) {
-	//	if(root) root->deleteSubtree();
+		delete_rtcScene();
 		return;
 	}
 
-	progress.set_substatus("Packing BVH triangles and strands");
+	progress.set_substatus("Building embree acceleration structure");
 	rtcCommit(scene);
 
 	pack_primitives();
 
 	if(progress.get_cancel()) {
-	//	root->deleteSubtree();
+		delete_rtcScene();
 		return;
 	}
 
-	progress.set_substatus("Packing BVH nodes");
+	progress.set_substatus("Packing geometry");
 	pack_nodes(NULL);
-
-	//root->deleteSubtree();
 }
 
-unsigned BVHEmbree::add_reference_mesh(Mesh *mesh, int i)
+unsigned BVHEmbree::add_mesh(Mesh *mesh, int i)
 {
-	unsigned geom_id = 0;
-	if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
-		geom_id = add_reference_triangles(mesh, i);
+	unsigned geom_id = RTC_INVALID_GEOMETRY_ID;
+	if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) {
+		geom_id = add_triangles(mesh, i);
 	}
-	if(params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves()) {
-		geom_id = add_reference_curves(mesh, i);
+	if(params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
+		geom_id = add_curves(mesh, i);
 	}
-//	assert(0);
 	return geom_id;
 }
 
-unsigned BVHEmbree::add_reference_object(Object *ob, int i)
+unsigned BVHEmbree::add_instance(Object *ob, int i)
 {
 	if(!ob || !ob->mesh) {
 		assert(0);
-		return 0;
+		return RTC_INVALID_GEOMETRY_ID;
 	}
 	BVHEmbree *instance_bvh = (BVHEmbree*)(ob->mesh->bvh);
 
 	const size_t num_motion_steps = ob->use_motion ? 3 : 1;
-	unsigned geom_id = rtcNewInstance2(scene, instance_bvh->scene, num_motion_steps);
+	unsigned geom_id = rtcNewInstance3(scene, instance_bvh->scene, num_motion_steps, i*2);
 
 	if(ob->use_motion) {
 		rtcSetTransform2(scene, geom_id, RTC_MATRIX_ROW_MAJOR, (const float*)&ob->motion.pre, 0);
@@ -157,10 +185,14 @@ unsigned BVHEmbree::add_reference_object(Object *ob, int i)
 		rtcSetTransform2(scene, geom_id, RTC_MATRIX_ROW_MAJOR, (const float*)&ob->tfm);
 	}
 
+	pack.prim_index.push_back_slow(-1);
+	pack.prim_object.push_back_slow(i);
+	pack.prim_type.push_back_slow(PRIMITIVE_NONE);
+	pack.prim_tri_index.push_back_slow(-1);
 	return geom_id;
 }
 
-unsigned BVHEmbree::add_reference_triangles(Mesh *mesh, int i)
+unsigned BVHEmbree::add_triangles(Mesh *mesh, int i)
 {
 	const Attribute *attr_mP = NULL;
 	size_t num_motion_steps = 1;
@@ -178,14 +210,15 @@ unsigned BVHEmbree::add_reference_triangles(Mesh *mesh, int i)
 	const size_t num_triangles = mesh->num_triangles();
 	const size_t num_verts = mesh->verts.size();
 	unsigned geom_id = rtcNewTriangleMesh2(scene,
-						RTC_GEOMETRY_DEFORMABLE,
+						RTC_GEOMETRY_STATIC,
 						num_triangles,
 						num_verts,
-						num_motion_steps);
+						num_motion_steps,
+						i*2);
 
-#if 0
+#ifdef EMBREE_SHARED_MEM
 	// embree and Cycles use the same memory layout, so we can conveniently use the rtcSetBuffer2 calls
-	//rtcSetBuffer2(scene, geom_id, RTC_INDEX_BUFFER, &mesh->triangles[0], 0, sizeof(int) * 3);
+	rtcSetBuffer2(scene, geom_id, RTC_INDEX_BUFFER, &mesh->triangles[0], 0, sizeof(int) * 3);
 #else
 	void* raw_buffer = rtcMapBuffer(scene, geom_id, RTC_INDEX_BUFFER);
 	unsigned *rtc_indices = (unsigned*) raw_buffer;
@@ -207,7 +240,7 @@ unsigned BVHEmbree::add_reference_triangles(Mesh *mesh, int i)
 			int t_ = (t > t_mid) ? (t - 1) : t;
 			verts = &attr_mP->data_float3()[t_ * num_verts];
 		}
-#if 0
+#ifdef EMBREE_SHARED_MEM
 		rtcSetBuffer(scene, geom_id, buffer_type, verts, 0, sizeof(float3));
 #else
 		raw_buffer = rtcMapBuffer(scene, geom_id, buffer_type);
@@ -237,8 +270,11 @@ unsigned BVHEmbree::add_reference_triangles(Mesh *mesh, int i)
 	return geom_id;
 }
 
-unsigned BVHEmbree::add_reference_curves(Mesh *mesh, int i)
+unsigned BVHEmbree::add_curves(Mesh *mesh, int i)
 {
+#ifndef EMBREE_CURVES
+	return RTC_INVALID_GEOMETRY_ID;
+#endif
 	const Attribute *attr_mP = NULL;
 	size_t num_motion_steps = 1;
 	if(mesh->has_motion_blur()) {
@@ -254,10 +290,11 @@ unsigned BVHEmbree::add_reference_curves(Mesh *mesh, int i)
 	}
 	const size_t num_keys = mesh->curve_keys.size();
 	unsigned geom_id = rtcNewBezierHairGeometry2(scene,
-												 RTC_GEOMETRY_DEFORMABLE,
+												 RTC_GEOMETRY_STATIC,
 												 num_curves,
 												 num_keys,
-												 num_motion_steps);
+												 num_motion_steps,
+												 i*2+1);
 
 	void* raw_buffer = rtcMapBuffer(scene, geom_id, RTC_INDEX_BUFFER);
 	unsigned *rtc_indices = (unsigned*) raw_buffer;
@@ -364,14 +401,16 @@ void BVHEmbree::pack_nodes(const BVHNode *root)
 	uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL;
 
 	/* merge */
+	unsigned geom_id = 0;
 	foreach(Object *ob, objects) {
+		geom_id += 2;
 		Mesh *mesh = ob->mesh;
 
 		/* We assume that if mesh doesn't need own BVH it was already included
 		 * into a top-level BVH and no packing here is needed.
 		 */
 		if(!mesh->need_build_bvh()) {
-			pack.object_node[object_offset++] = 0;
+			pack.object_node[object_offset++] = prim_offset;
 			continue;
 		}
 
@@ -392,9 +431,9 @@ void BVHEmbree::pack_nodes(const BVHNode *root)
 
 		/* fill in node indexes for instances */
 		if(bvh->pack.root_index == -1)
-			pack.object_node[object_offset++] = 0;//todo (Stefan)
+			pack.object_node[object_offset++] = prim_offset;//todo (Stefan)
 		else
-			pack.object_node[object_offset++] = 0; // todo (Stefan)
+			pack.object_node[object_offset++] = prim_offset; // todo (Stefan)
 
 		mesh_map[mesh] = pack.object_node[object_offset-1];
 
@@ -436,8 +475,6 @@ void BVHEmbree::pack_nodes(const BVHNode *root)
 
 		prim_offset += bvh->pack.prim_index.size();
 	}
-
-	// TODO Stefan
 }
 
 void BVHEmbree::refit_nodes()
diff --git a/intern/cycles/bvh/bvh_embree.h b/intern/cycles/bvh/bvh_embree.h
index fb231e1ed5a..d56bbbb37ab 100644
--- a/intern/cycles/bvh/bvh_embree.h
+++ b/intern/cycles/bvh/bvh_embree.h
@@ -48,11 +48,13 @@ protected:
 	virtual void pack_nodes(const BVHNode *root);
 	virtual void refit_nodes();
 
-	unsigned add_reference_mesh(Mesh *mesh, int i);
-	unsigned add_reference_object(Object *ob, int i);
-	unsigned add_reference_curves(Mesh *mesh, int i);
-	unsigned add_reference_triangles(Mesh *mesh, int i);
+	unsigned add_mesh(Mesh *mesh, int i);
+	unsigned add_instance(Object *ob, int i);
+	unsigned add_curves(Mesh *mesh, int i);
+	unsigned add_triangles(Mesh *mesh, int i);
 private:
+	void delete_rtcScene();
+
 	static RTCDevice rtc_shared_device;
 	static int rtc_shared_users;
 	static thread_mutex rtc_shared_mutex;
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index 2107baa8850..26d86cfb1e6 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -26,8 +26,7 @@
  * with CPU/CUDA/OpenCL. */
 
 #ifdef __EMBREE__
-#include "embree2/rtcore_ray.h"
-#include "embree2/rtcore_scene.h"
+#include "kernel/bvh/bvh_embree_traversal.h"
 #endif
 
 CCL_NAMESPACE_BEGIN
@@ -191,10 +190,12 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
 			isect->v = rtc_ray.u;
 			isect->t = rtc_ray.tfar;
 			if(rtc_ray.instID != RTC_INVALID_GEOMETRY_ID) {
-				isect->prim = rtc_ray.primID + (intptr_t)rtcGetUserData(kernel_data.bvh.scene, rtc_ray.instID);
-				isect->object = rtc_ray.instID;
+//				isect->prim = rtc_ray.primID + (intptr_t)rtcGetUserData(kernel_data.bvh.scene, rtc_ray.geomID);
+				isect->prim = rtc_ray.primID + kernel_tex_fetch(__object_node, rtc_ray.instID/2);
+				isect->object = rtc_ray.instID/2;
 			} els

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list