[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