diff options
author | Patrick Mours <pmours@nvidia.com> | 2019-08-26 18:29:06 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-08-26 18:39:57 +0300 |
commit | f6da680946e2bf982c4831c2135305cb0674215f (patch) | |
tree | 761f97b6ba45bd5f2e394dac10a276c0e0c23bf8 /intern | |
parent | 2dd1e6b376bf6b275f7b0053dae3910afb1c924a (diff) |
Cycles: refactor of BVH building to prepare for Optix
Ref D5363
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/bvh/bvh.cpp | 49 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh.h | 14 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh2.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh2.h | 2 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh4.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh4.h | 2 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh8.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh8.h | 2 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_embree.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_embree.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 42 | ||||
-rw-r--r-- | intern/cycles/render/mesh.h | 18 |
12 files changed, 108 insertions, 56 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 53c66777928..b6a4aba74b5 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -71,7 +71,11 @@ BVHLayout BVHParams::best_bvh_layout(BVHLayout requested_layout, BVHLayoutMask s /* This is a mask of supported BVH layouts which are narrower than the * requested one. */ - const BVHLayoutMask allowed_layouts_mask = (supported_layouts & (requested_layout_mask - 1)); + BVHLayoutMask allowed_layouts_mask = (supported_layouts & (requested_layout_mask - 1)); + /* If the requested layout is not supported, choose from the supported layouts instead. */ + if (allowed_layouts_mask == 0) { + allowed_layouts_mask = supported_layouts; + } /* We get widest from allowed ones and convert mask to actual layout. */ const BVHLayoutMask widest_allowed_layout_mask = __bsr(allowed_layouts_mask); return (BVHLayout)(1 << widest_allowed_layout_mask); @@ -90,23 +94,27 @@ int BVHStackEntry::encodeIdx() const /* BVH */ -BVH::BVH(const BVHParams ¶ms_, const vector<Object *> &objects_) - : params(params_), objects(objects_) +BVH::BVH(const BVHParams ¶ms_, const vector<Mesh *> &meshes_, const vector<Object *> &objects_) + : params(params_), meshes(meshes_), objects(objects_) { } -BVH *BVH::create(const BVHParams ¶ms, const vector<Object *> &objects) +BVH *BVH::create(const BVHParams ¶ms, + const vector<Mesh *> &meshes, + const vector<Object *> &objects) { switch (params.bvh_layout) { case BVH_LAYOUT_BVH2: - return new BVH2(params, objects); + return new BVH2(params, meshes, objects); case BVH_LAYOUT_BVH4: - return new BVH4(params, objects); + return new BVH4(params, meshes, objects); case BVH_LAYOUT_BVH8: - return new BVH8(params, objects); + return new BVH8(params, meshes, objects); case BVH_LAYOUT_EMBREE: #ifdef WITH_EMBREE - return new BVHEmbree(params, objects); + return new BVHEmbree(params, meshes, objects); +#else + break; #endif case BVH_LAYOUT_NONE: case BVH_LAYOUT_ALL: @@ -356,26 +364,17 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) size_t pack_leaf_nodes_offset = leaf_nodes_size; size_t object_offset = 0; - map<Mesh *, int> mesh_map; - - foreach (Object *ob, objects) { - Mesh *mesh = ob->mesh; + foreach (Mesh *mesh, meshes) { BVH *bvh = mesh->bvh; - 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(); - - mesh_map[mesh] = 1; - } + if (mesh->need_build_bvh(params.bvh_layout)) { + 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(); } } - mesh_map.clear(); - pack.prim_index.resize(prim_index_size); pack.prim_type.resize(prim_index_size); pack.prim_object.resize(prim_index_size); @@ -400,6 +399,8 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL; float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL; + map<Mesh *, int> mesh_map; + /* merge */ foreach (Object *ob, objects) { Mesh *mesh = ob->mesh; @@ -407,7 +408,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) /* 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()) { + if (!mesh->need_build_bvh(params.bvh_layout)) { pack.object_node[object_offset++] = 0; continue; } diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index edce3ca6f2a..92082e4de86 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -26,11 +26,14 @@ CCL_NAMESPACE_BEGIN class Stats; +class Device; +class DeviceScene; class BVHNode; struct BVHStackEntry; class BVHParams; class BoundBox; class LeafNode; +class Mesh; class Object; class Progress; @@ -81,18 +84,25 @@ class BVH { public: PackedBVH pack; BVHParams params; + vector<Mesh *> meshes; vector<Object *> objects; - static BVH *create(const BVHParams ¶ms, const vector<Object *> &objects); + static BVH *create(const BVHParams ¶ms, + const vector<Mesh *> &meshes, + const vector<Object *> &objects); virtual ~BVH() { } virtual void build(Progress &progress, Stats *stats = NULL); + virtual void copy_to_device(Progress & /*progress*/, DeviceScene * /*dscene*/) + { + } + void refit(Progress &progress); protected: - BVH(const BVHParams ¶ms, const vector<Object *> &objects); + BVH(const BVHParams ¶ms, const vector<Mesh *> &meshes, const vector<Object *> &objects); /* Refit range of primitives. */ void refit_primitives(int start, int end, BoundBox &bbox, uint &visibility); diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp index f419d413ef6..b1a9148c297 100644 --- a/intern/cycles/bvh/bvh2.cpp +++ b/intern/cycles/bvh/bvh2.cpp @@ -25,7 +25,10 @@ CCL_NAMESPACE_BEGIN -BVH2::BVH2(const BVHParams ¶ms_, const vector<Object *> &objects_) : BVH(params_, objects_) +BVH2::BVH2(const BVHParams ¶ms_, + const vector<Mesh *> &meshes_, + const vector<Object *> &objects_) + : BVH(params_, meshes_, objects_) { } diff --git a/intern/cycles/bvh/bvh2.h b/intern/cycles/bvh/bvh2.h index c6a4e6fa73a..a3eaff9cf65 100644 --- a/intern/cycles/bvh/bvh2.h +++ b/intern/cycles/bvh/bvh2.h @@ -46,7 +46,7 @@ class BVH2 : public BVH { protected: /* constructor */ friend class BVH; - BVH2(const BVHParams ¶ms, const vector<Object *> &objects); + BVH2(const BVHParams ¶ms, const vector<Mesh *> &meshes, const vector<Object *> &objects); /* Building process. */ virtual BVHNode *widen_children_nodes(const BVHNode *root) override; diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp index b6df9024ffa..89b42ee1d21 100644 --- a/intern/cycles/bvh/bvh4.cpp +++ b/intern/cycles/bvh/bvh4.cpp @@ -31,7 +31,10 @@ CCL_NAMESPACE_BEGIN * life easier all over the place. */ -BVH4::BVH4(const BVHParams ¶ms_, const vector<Object *> &objects_) : BVH(params_, objects_) +BVH4::BVH4(const BVHParams ¶ms_, + const vector<Mesh *> &meshes_, + const vector<Object *> &objects_) + : BVH(params_, meshes_, objects_) { params.bvh_layout = BVH_LAYOUT_BVH4; } diff --git a/intern/cycles/bvh/bvh4.h b/intern/cycles/bvh/bvh4.h index 38b0961d3df..c44f2833c84 100644 --- a/intern/cycles/bvh/bvh4.h +++ b/intern/cycles/bvh/bvh4.h @@ -46,7 +46,7 @@ class BVH4 : public BVH { protected: /* constructor */ friend class BVH; - BVH4(const BVHParams ¶ms, const vector<Object *> &objects); + BVH4(const BVHParams ¶ms, const vector<Mesh *> &meshes, const vector<Object *> &objects); /* Building process. */ virtual BVHNode *widen_children_nodes(const BVHNode *root) override; diff --git a/intern/cycles/bvh/bvh8.cpp b/intern/cycles/bvh/bvh8.cpp index 10fd01dd8d0..d3516525f78 100644 --- a/intern/cycles/bvh/bvh8.cpp +++ b/intern/cycles/bvh/bvh8.cpp @@ -36,7 +36,10 @@ CCL_NAMESPACE_BEGIN -BVH8::BVH8(const BVHParams ¶ms_, const vector<Object *> &objects_) : BVH(params_, objects_) +BVH8::BVH8(const BVHParams ¶ms_, + const vector<Mesh *> &meshes_, + const vector<Object *> &objects_) + : BVH(params_, meshes_, objects_) { } diff --git a/intern/cycles/bvh/bvh8.h b/intern/cycles/bvh/bvh8.h index 6292353c7d4..5f26fd423e1 100644 --- a/intern/cycles/bvh/bvh8.h +++ b/intern/cycles/bvh/bvh8.h @@ -57,7 +57,7 @@ class BVH8 : public BVH { protected: /* constructor */ friend class BVH; - BVH8(const BVHParams ¶ms, const vector<Object *> &objects); + BVH8(const BVHParams ¶ms, const vector<Mesh *> &meshes, const vector<Object *> &objects); /* Building process. */ virtual BVHNode *widen_children_nodes(const BVHNode *root) override; diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp index b011bc63dbd..d12a0c137ea 100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@ -285,8 +285,10 @@ RTCDevice BVHEmbree::rtc_shared_device = NULL; int BVHEmbree::rtc_shared_users = 0; thread_mutex BVHEmbree::rtc_shared_mutex; -BVHEmbree::BVHEmbree(const BVHParams ¶ms_, const vector<Object *> &objects_) - : BVH(params_, objects_), +BVHEmbree::BVHEmbree(const BVHParams ¶ms_, + const vector<Mesh *> &meshes_, + const vector<Object *> &objects_) + : BVH(params_, meshes_, objects_), scene(NULL), mem_used(0), top_level(NULL), @@ -497,6 +499,11 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) stats = NULL; } +void BVHEmbree::copy_to_device(Progress & /*progress*/, DeviceScene *dscene) +{ + dscene->data.bvh.scene = scene; +} + BVHNode *BVHEmbree::widen_children_nodes(const BVHNode * /*root*/) { assert(!"Must not be called."); @@ -840,7 +847,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) Mesh *mesh = ob->mesh; BVH *bvh = mesh->bvh; - if (mesh->need_build_bvh()) { + if (mesh->need_build_bvh(BVH_LAYOUT_EMBREE)) { 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(); @@ -872,7 +879,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) /* 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()) { + if (!mesh->need_build_bvh(BVH_LAYOUT_EMBREE)) { pack.object_node[object_offset++] = prim_offset; continue; } diff --git a/intern/cycles/bvh/bvh_embree.h b/intern/cycles/bvh/bvh_embree.h index 60702713583..123e87dd9b0 100644 --- a/intern/cycles/bvh/bvh_embree.h +++ b/intern/cycles/bvh/bvh_embree.h @@ -36,6 +36,7 @@ class Mesh; class BVHEmbree : public BVH { public: virtual void build(Progress &progress, Stats *stats) override; + virtual void copy_to_device(Progress &progress, DeviceScene *dscene) override; virtual ~BVHEmbree(); RTCScene scene; static void destroy(RTCScene); @@ -45,7 +46,9 @@ class BVHEmbree : public BVH { protected: friend class BVH; - BVHEmbree(const BVHParams ¶ms, const vector<Object *> &objects); + BVHEmbree(const BVHParams ¶ms, + const vector<Mesh *> &meshes, + const vector<Object *> &objects); virtual void pack_nodes(const BVHNode *) override; virtual void refit_nodes() override; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 6ac66661859..c7e0430fe7e 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -433,6 +433,8 @@ Mesh::Mesh() : Node(node_type) attr_map_offset = 0; + prim_offset = 0; + num_subd_verts = 0; attributes.triangle_mesh = this; @@ -1013,9 +1015,11 @@ void Mesh::compute_bvh( compute_bounds(); - if (need_build_bvh()) { + const BVHLayout bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout, + device->get_bvh_layout_mask()); + if (need_build_bvh(bvh_layout)) { string msg = "Updating Mesh BVH "; - if (name == "") + if (name.empty()) msg += string_printf("%u/%u", (uint)(n + 1), (uint)total); else msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total); @@ -1023,12 +1027,17 @@ void Mesh::compute_bvh( Object object; object.mesh = this; + vector<Mesh *> meshes; + meshes.push_back(this); vector<Object *> objects; objects.push_back(&object); if (bvh && !need_update_rebuild) { progress->set_status(msg, "Refitting BVH"); + + bvh->meshes = meshes; bvh->objects = objects; + bvh->refit(*progress); } else { @@ -1036,8 +1045,7 @@ void Mesh::compute_bvh( BVHParams bparams; bparams.use_spatial_split = params->use_bvh_spatial_split; - bparams.bvh_layout = BVHParams::best_bvh_layout(params->bvh_layout, - device->get_bvh_layout_mask()); + bparams.bvh_layout = bvh_layout; bparams.use_unaligned_nodes = dscene->data.bvh.have_curves && params->use_bvh_unaligned_nodes; bparams.num_motion_triangle_steps = params->num_bvh_time_steps; @@ -1047,7 +1055,7 @@ void Mesh::compute_bvh( bparams.curve_subdivisions = dscene->data.curve.subdivisions; delete bvh; - bvh = BVH::create(bparams, objects); + bvh = BVH::create(bparams, meshes, objects); MEM_GUARDED_CALL(progress, bvh->build, *progress); } } @@ -1128,7 +1136,7 @@ int Mesh::motion_step(float time) const return -1; } -bool Mesh::need_build_bvh() const +bool Mesh::need_build_bvh(BVHLayout) const { return !transform_applied || has_surface_bssrdf; } @@ -1722,6 +1730,8 @@ void MeshManager::mesh_calc_offset(Scene *scene) size_t face_size = 0; size_t corner_size = 0; + size_t prim_size = 0; + foreach (Mesh *mesh, scene->meshes) { mesh->vert_offset = vert_size; mesh->tri_offset = tri_size; @@ -1751,6 +1761,9 @@ void MeshManager::mesh_calc_offset(Scene *scene) } face_size += mesh->subd_faces.size(); corner_size += mesh->subd_face_corners.size(); + + mesh->prim_offset = prim_size; + prim_size += mesh->num_primitives(); } } @@ -1929,7 +1942,7 @@ void MeshManager::device_update_bvh(Device *device, } #endif - BVH *bvh = BVH::create(bparams, scene->objects); + BVH *bvh = BVH::create(bparams, scene->meshes, scene->objects); bvh->build(progress, &device->stats); if (progress.get_cancel()) { @@ -1994,14 +2007,7 @@ void MeshManager::device_update_bvh(Device *device, dscene->data.bvh.bvh_layout = bparams.bvh_layout; dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0); -#ifdef WITH_EMBREE - if (bparams.bvh_layout == BVH_LAYOUT_EMBREE) { - dscene->data.bvh.scene = ((BVHEmbree *)bvh)->scene; - } - else { - dscene->data.bvh.scene = NULL; - } -#endif + bvh->copy_to_device(progress, dscene); delete bvh; } @@ -2213,6 +2219,8 @@ void MeshManager::device_update(Device *device, /* Update displacement. */ bool displacement_done = false; size_t num_bvh = 0; + BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout, + device->get_bvh_layout_mask()); foreach (Mesh *mesh, scene->meshes) { if (mesh->need_update) { @@ -2220,7 +2228,7 @@ void MeshManager::device_update(Device *device, displacement_done = true; } - if (mesh->need_build_bvh()) { + if (mesh->need_build_bvh(bvh_layout)) { num_bvh++; } } @@ -2245,7 +2253,7 @@ void MeshManager::device_update(Device *device, if (mesh->need_update) { pool.push(function_bind( &Mesh::compute_bvh, mesh, device, dscene, &scene->params, &progress, i, num_bvh)); - if (mesh->need_build_bvh()) { + if (mesh->need_build_bvh(bvh_layout)) { i++; } } diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index 5bb6ab328b7..50b1f0e69f1 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -19,6 +19,7 @@ #include "graph/node.h" +#include "bvh/bvh_params.h" #include "render/attribute.h" #include "render/shader.h" @@ -94,7 +95,7 @@ class Mesh : public Node { int first_key; int num_keys; - int num_segments() + int num_segments() const { return num_keys - 1; } @@ -167,6 +168,16 @@ class Mesh : public Node { return curve_first_key.size(); } + size_t num_segments() const + { + return curve_keys.size() - curve_first_key.size(); + } + + size_t num_primitives() const + { + return num_triangles() + num_segments(); + } + /* Mesh SubdFace */ struct SubdFace { int start_corner; @@ -268,6 +279,8 @@ class Mesh : public Node { size_t attr_map_offset; + size_t prim_offset; + size_t num_subd_verts; /* Functions */ @@ -332,8 +345,9 @@ class Mesh : public Node { * same BVH tree. * - Special ray intersection is needed, for example to limit subsurface rays * to only the mesh itself. + * - The BVH layout requires the top level to only contain instances. */ - bool need_build_bvh() const; + bool need_build_bvh(BVHLayout layout) const; /* Check if the mesh should be treated as instanced. */ bool is_instanced() const; |