Fix #143662: Crash with Cycles persistent data and file thumbnail generation

The Embree scene contains a TBB task group that has a parent pointer to the
task group it was created in. In Cycles this task group was only temporarily
created on the stack, resulting in a dangling parent pointer.

The simple solution is to make the Cycles side task group persistent too.

Many thanks to Aras for figuring this one out, this was a very tricky one.

Pull Request: https://projects.blender.org/blender/blender/pulls/145515
This commit is contained in:
Brecht Van Lommel
2025-09-02 13:14:07 +02:00
committed by Brecht Van Lommel
parent 5cdc506750
commit 8421de0277
2 changed files with 9 additions and 3 deletions

View File

@@ -954,9 +954,9 @@ void GeometryManager::device_update(Device *device,
scene->update_stats->geometry.times.add_entry({"device_update (build object BVHs)", time});
}
});
TaskPool pool;
/* Work around Embree/oneAPI bug #129596 with BVH updates. */
/* Also note the use of #bvh_task_pool_, see its definition for details. */
const bool use_multithreaded_build = first_bvh_build ||
!device->info.contains_device_type(DEVICE_ONEAPI);
first_bvh_build = false;
@@ -973,7 +973,7 @@ void GeometryManager::device_update(Device *device,
}
if (use_multithreaded_build) {
pool.push([geom, device, dscene, scene, &progress, i, &num_bvh] {
bvh_task_pool_.push([geom, device, dscene, scene, &progress, i, &num_bvh] {
geom->compute_bvh(device, dscene, &scene->params, &progress, i, num_bvh);
});
}
@@ -984,7 +984,7 @@ void GeometryManager::device_update(Device *device,
}
TaskPool::Summary summary;
pool.wait_work(&summary);
bvh_task_pool_.wait_work(&summary);
LOG_DEBUG << "Objects BVH build pool statistics:\n" << summary.full_report();
}

View File

@@ -12,6 +12,7 @@
#include "util/boundbox.h"
#include "util/set.h"
#include "util/task.h"
#include "util/transform.h"
#include "util/types.h"
#include "util/vector.h"
@@ -200,6 +201,11 @@ class Geometry : public Node {
class GeometryManager {
uint32_t update_flags;
/* Persistent task pool for BVH building, because the Embree scene creates its own
* task group that has a parent pointer to this one. And if we create a task pool
* on the stack, that becomes a dangling pointer. See #143662 for details. */
TaskPool bvh_task_pool_;
public:
enum : uint32_t {
UV_PASS_NEEDED = (1 << 0),