Fix: Cyles HIP-RT random crashes editing the scene

Perform delayed freeing of the geometry BVHs similar to OptiX.

Previously BLAS memory was allocated in the device class as part of
device_update, but released in the BVHHIPRT destructor which gets called
when deleting geometry outside of device_update.

To avoid the GPU accessing unmapped memory, do a delayed free of this
memory in the device class as part of either device_update or device
destruction. This ensures it is in sync with other device memory changes.

Fix #148276
Fix #139013
Fix #138043
Fix #140763

Pull Request: https://projects.blender.org/blender/blender/pulls/147247
This commit is contained in:
salipour
2025-10-17 16:32:23 +02:00
committed by Brecht Van Lommel
parent 58b8ae1717
commit b491002a9d
3 changed files with 35 additions and 5 deletions

View File

@@ -114,6 +114,7 @@ HIPRTDevice::HIPRTDevice(const DeviceInfo &info,
HIPRTDevice::~HIPRTDevice()
{
HIPContextScope scope(this);
free_bvh_memory_delayed();
user_instance_id.free();
prim_visibility.free();
hiprt_blas_ptr.free();
@@ -1150,12 +1151,33 @@ hiprtScene HIPRTDevice::build_tlas(BVHHIPRT *bvh,
return scene;
}
void HIPRTDevice::free_bvh_memory_delayed()
{
thread_scoped_lock lock(hiprt_mutex);
if (stale_bvh.size()) {
for (int bvh_index = 0; bvh_index < stale_bvh.size(); bvh_index++) {
hiprtGeometry hiprt_geom = stale_bvh[bvh_index];
hiprtDestroyGeometry(hiprt_context, hiprt_geom);
hiprt_geom = nullptr;
}
stale_bvh.clear();
}
}
void HIPRTDevice::release_bvh(BVH *bvh)
{
BVHHIPRT *current_bvh = static_cast<BVHHIPRT *>(bvh);
thread_scoped_lock lock(hiprt_mutex);
/* Tracks BLAS pointers whose BVH destructors have been called. */
stale_bvh.push_back(current_bvh->hiprt_geom);
}
void HIPRTDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
{
if (have_error()) {
return;
}
free_bvh_memory_delayed();
progress.set_substatus("Building HIPRT acceleration structure");
hiprtBuildOptions options;
@@ -1173,6 +1195,7 @@ void HIPRTDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
if (scene) {
hiprtDestroyScene(hiprt_context, scene);
scene = nullptr;
}
scene = build_tlas(bvh_rt, bvh_rt->objects, options, refit);
}