From ad45b8d6a439f131bae545e054ba5e31a95bb0ea Mon Sep 17 00:00:00 2001 From: Milan Jaros Date: Fri, 10 Jul 2020 11:49:52 +0200 Subject: Cycles: optimize camera inside volume tests Only run when there are volumes in the scene, and compute in parallel. Ref T56939 Differential Revision: https://developer.blender.org/D8261 --- intern/cycles/render/camera.cpp | 40 ++++++++++++++++++++++++++++------------ intern/cycles/util/util_tbb.h | 5 +++++ 2 files changed, 33 insertions(+), 12 deletions(-) (limited to 'intern') diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 74953afae9d..bbc111cb798 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -26,6 +26,7 @@ #include "util/util_function.h" #include "util/util_logging.h" #include "util/util_math_cdf.h" +#include "util/util_task.h" #include "util/util_vector.h" /* needed for calculating differentials */ @@ -496,20 +497,35 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen if (!need_device_update && !need_flags_update) { return; } - KernelCamera *kcam = &dscene->data.cam; - BoundBox viewplane_boundbox = viewplane_bounds_get(); - for (size_t i = 0; i < scene->objects.size(); ++i) { - Object *object = scene->objects[i]; - if (object->geometry->has_volume && viewplane_boundbox.intersects(object->bounds)) { - /* TODO(sergey): Consider adding more grained check. */ - VLOG(1) << "Detected camera inside volume."; - kcam->is_inside_volume = 1; - break; + + KernelIntegrator *kintegrator = &dscene->data.integrator; + if (kintegrator->use_volumes) { + KernelCamera *kcam = &dscene->data.cam; + BoundBox viewplane_boundbox = viewplane_bounds_get(); + + /* Parallel object update, with grain size to avoid too much threading overhead + * for individual objects. */ + static const int OBJECTS_PER_TASK = 32; + parallel_for(blocked_range(0, scene->objects.size(), OBJECTS_PER_TASK), + [&](const blocked_range &r) { + for (size_t i = r.begin(); i != r.end(); i++) { + Object *object = scene->objects[i]; + if (object->geometry->has_volume && + viewplane_boundbox.intersects(object->bounds)) { + /* TODO(sergey): Consider adding more grained check. */ + VLOG(1) << "Detected camera inside volume."; + kcam->is_inside_volume = 1; + parallel_for_cancel(); + break; + } + } + }); + + if (!kcam->is_inside_volume) { + VLOG(1) << "Camera is outside of the volume."; } } - if (!kcam->is_inside_volume) { - VLOG(1) << "Camera is outside of the volume."; - } + need_device_update = false; need_flags_update = false; } diff --git a/intern/cycles/util/util_tbb.h b/intern/cycles/util/util_tbb.h index 301cb80c5b0..206ba106ca6 100644 --- a/intern/cycles/util/util_tbb.h +++ b/intern/cycles/util/util_tbb.h @@ -34,6 +34,11 @@ using tbb::blocked_range; using tbb::enumerable_thread_specific; using tbb::parallel_for; +static inline void parallel_for_cancel() +{ + tbb::task::self().cancel_group_execution(); +} + CCL_NAMESPACE_END #endif /* __UTIL_TBB_H__ */ -- cgit v1.2.3