diff options
Diffstat (limited to 'intern/cycles/render/geometry.cpp')
-rw-r--r-- | intern/cycles/render/geometry.cpp | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index 12f4eaf0b79..64b98a91853 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -15,8 +15,7 @@ */ #include "bvh/bvh.h" -#include "bvh/bvh_build.h" -#include "bvh/bvh_embree.h" +#include "bvh/bvh2.h" #include "device/device.h" @@ -41,6 +40,7 @@ #include "util/util_foreach.h" #include "util/util_logging.h" #include "util/util_progress.h" +#include "util/util_task.h" CCL_NAMESPACE_BEGIN @@ -162,7 +162,8 @@ int Geometry::motion_step(float time) const bool Geometry::need_build_bvh(BVHLayout layout) const { - return !transform_applied || has_surface_bssrdf || layout == BVH_LAYOUT_OPTIX; + return is_instanced() || layout == BVH_LAYOUT_OPTIX || layout == BVH_LAYOUT_MULTI_OPTIX || + layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE; } bool Geometry::is_instanced() const @@ -218,7 +219,7 @@ void Geometry::compute_bvh( bvh->geometry = geometry; bvh->objects = objects; - bvh->refit(*progress); + device->build_bvh(bvh, *progress, true); } else { progress->set_status(msg, "Building BVH"); @@ -235,7 +236,7 @@ void Geometry::compute_bvh( delete bvh; bvh = BVH::create(bparams, geometry, objects, device); - MEM_GUARDED_CALL(progress, bvh->build, *progress); + MEM_GUARDED_CALL(progress, device->build_bvh, bvh, *progress, false); } } @@ -1162,25 +1163,66 @@ void GeometryManager::device_update_bvh(Device *device, VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout."; - BVH *bvh = BVH::create(bparams, scene->geometry, scene->objects, device); - bvh->build(progress, &device->stats); + delete scene->bvh; + BVH *bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device); + device->build_bvh(bvh, progress, false); if (progress.get_cancel()) { -#ifdef WITH_EMBREE - if (dscene->data.bvh.scene) { - BVHEmbree::destroy(dscene->data.bvh.scene); - dscene->data.bvh.scene = NULL; - } -#endif - delete bvh; return; } + PackedBVH pack; + if (bparams.bvh_layout == BVH_LAYOUT_BVH2) { + pack = std::move(static_cast<BVH2 *>(bvh)->pack); + } + else { + progress.set_status("Updating Scene BVH", "Packing BVH primitives"); + + size_t num_prims = 0; + size_t num_tri_verts = 0; + foreach (Geometry *geom, scene->geometry) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { + Mesh *mesh = static_cast<Mesh *>(geom); + num_prims += mesh->num_triangles(); + num_tri_verts += 3 * mesh->num_triangles(); + } + else if (geom->is_hair()) { + Hair *hair = static_cast<Hair *>(geom); + num_prims += hair->num_segments(); + } + } + + pack.root_index = -1; + pack.prim_tri_index.reserve(num_prims); + pack.prim_tri_verts.reserve(num_tri_verts); + pack.prim_type.reserve(num_prims); + pack.prim_index.reserve(num_prims); + pack.prim_object.reserve(num_prims); + pack.prim_visibility.reserve(num_prims); + + // Merge visibility flags of all objects and find object index for non-instanced geometry + unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info; + geometry_to_object_info.reserve(scene->geometry.size()); + foreach (Object *ob, scene->objects) { + const Geometry *const geom = ob->get_geometry(); + pair<int, uint> &info = geometry_to_object_info[geom]; + info.second |= ob->visibility_for_tracing(); + if (!geom->is_instanced()) { + info.first = ob->get_device_index(); + } + } + + // Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated + // based on that list, which may be ordered differently from the object list. + foreach (Geometry *geom, scene->geometry) { + const pair<int, uint> &info = geometry_to_object_info[geom]; + geom->pack_primitives(pack, info.first, info.second); + } + } + /* copy to device */ progress.set_status("Updating Scene BVH", "Copying BVH to device"); - PackedBVH &pack = bvh->pack; - if (pack.nodes.size()) { dscene->bvh_nodes.steal_data(pack.nodes); dscene->bvh_nodes.copy_to_device(); @@ -1226,10 +1268,8 @@ void GeometryManager::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); dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions(); - - bvh->copy_to_device(progress, dscene); - - delete bvh; + /* The scene handle is set in 'CPUDevice::const_copy_to' and 'OptiXDevice::const_copy_to' */ + dscene->data.bvh.scene = NULL; } void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress) @@ -1653,14 +1693,6 @@ void GeometryManager::device_update(Device *device, void GeometryManager::device_free(Device *device, DeviceScene *dscene) { -#ifdef WITH_EMBREE - if (dscene->data.bvh.scene) { - if (dscene->data.bvh.bvh_layout == BVH_LAYOUT_EMBREE) - BVHEmbree::destroy(dscene->data.bvh.scene); - dscene->data.bvh.scene = NULL; - } -#endif - dscene->bvh_nodes.free(); dscene->bvh_leaf_nodes.free(); dscene->object_node.free(); |