From c0f0e2ca6f3fc0aefab93542211e01bc61be8f34 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 18 Feb 2025 16:20:59 +0100 Subject: [PATCH] Fix #129596: Cycles oneAPI crash with interactive BVH updates There is a bug in Embree that makes BVH updates crash. Disabling multithreaded BVH updates after the initial BVH build appears to work around it, at the cost of some performance. This will not affect performance of the initial BVH build, transforming objects or editing a single mesh. It will only affect performance when multiple smaller meshes are edited together, as those can no longer have their BVH updated in parallel or benefit from parallellization over many primitives. Pull Request: https://projects.blender.org/blender/blender/pulls/134747 --- intern/cycles/device/device.cpp | 13 +++++++++++++ intern/cycles/device/device.h | 2 ++ intern/cycles/scene/geometry.cpp | 14 ++++++++++++-- intern/cycles/scene/geometry.h | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index cf77f76bec6..44fa7988f2a 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -816,4 +816,17 @@ bool GPUDevice::is_shared(const void *shared_pointer, /* DeviceInfo */ +bool DeviceInfo::contains_device_type(const DeviceType type) const +{ + if (this->type == type) { + return true; + } + for (const DeviceInfo &info : multi_devices) { + if (info.contains_device_type(type)) { + return true; + } + } + return false; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 8912000f788..f55fa3f7f18 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -130,6 +130,8 @@ class DeviceInfo { { return !(*this == info); } + + bool contains_device_type(const DeviceType type) const; }; /* Device */ diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index d51e7c6270c..7443dbbd8f2 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -943,13 +943,23 @@ void GeometryManager::device_update(Device *device, }); TaskPool pool; + /* Work around Embree/oneAPI bug #129596 with BVH updates. */ + const bool use_multithreaded_build = first_bvh_build || + !device->info.contains_device_type(DEVICE_ONEAPI); + first_bvh_build = false; + size_t i = 0; for (Geometry *geom : scene->geometry) { if (geom->is_modified() || geom->need_update_bvh_for_offset) { need_update_scene_bvh = true; - pool.push([geom, device, dscene, scene, &progress, i, num_bvh] { + if (use_multithreaded_build) { + pool.push([geom, device, dscene, scene, &progress, i, num_bvh] { + geom->compute_bvh(device, dscene, &scene->params, &progress, i, num_bvh); + }); + } + else { geom->compute_bvh(device, dscene, &scene->params, &progress, i, num_bvh); - }); + } if (geom->need_build_bvh(bvh_layout)) { i++; } diff --git a/intern/cycles/scene/geometry.h b/intern/cycles/scene/geometry.h index 4b57d7fa692..6144bf19c83 100644 --- a/intern/cycles/scene/geometry.h +++ b/intern/cycles/scene/geometry.h @@ -225,6 +225,7 @@ class GeometryManager { /* Update Flags */ bool need_flags_update; + bool first_bvh_build = true; /* Constructor/Destructor */ GeometryManager();