Fix: Cycles hardware RT is only supported if all multi devices have it

Pull Request: https://projects.blender.org/blender/blender/pulls/135179
This commit is contained in:
Brecht Van Lommel
2025-02-27 15:12:54 +01:00
parent 8ce58f2973
commit 8f00d8b0c8
3 changed files with 56 additions and 22 deletions
+23 -12
View File
@@ -1835,16 +1835,26 @@ class CyclesPreferences(bpy.types.AddonPreferences):
self._draw_devices(row, compute_device_type, devices)
import _cycles
has_peer_memory = 0
has_rt_api_support = {'METAL': False, 'HIP': False, 'ONEAPI': False}
has_peer_memory = False
has_enabled_hardware_rt = False
has_disabled_hardware_rt = False
for device in self.get_device_list(compute_device_type):
if device[3] and self.find_existing_device_entry(device).use:
has_peer_memory += 1
if device[4] and self.find_existing_device_entry(device).use:
device_type = device[1]
has_rt_api_support[device_type] = True
if not self.find_existing_device_entry(device).use:
continue
if device[1] != compute_device_type:
continue
if has_peer_memory > 1:
if device[3]:
has_peer_memory = True
if device[4]:
has_enabled_hardware_rt = True
else:
has_disabled_hardware_rt = True
# Any device without RT support will disable it for all.
has_hardware_rt = has_enabled_hardware_rt and not has_disabled_hardware_rt
if has_peer_memory:
row = layout.row()
row.use_property_split = True
row.prop(self, "peer_memory")
@@ -1857,18 +1867,19 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col = layout.column()
col.use_property_split = True
col.prop(self, "kernel_optimization_level")
if has_rt_api_support['METAL']:
col.prop(self, "metalrt")
row = col.row()
row.active = has_hardware_rt
row.prop(self, "metalrt")
if compute_device_type == 'HIP':
import platform
row = layout.row()
row.active = has_rt_api_support['HIP']
row.active = has_hardware_rt
row.prop(self, "use_hiprt")
elif compute_device_type == 'ONEAPI' and _cycles.with_embree_gpu:
row = layout.row()
row.active = has_rt_api_support['ONEAPI']
row.active = has_hardware_rt
row.prop(self, "use_oneapirt")
def draw(self, context):
-7
View File
@@ -63,13 +63,6 @@ static void adjust_device_info(DeviceInfo &device, PointerRNA cpreferences, bool
adjust_device_info_from_preferences(device, cpreferences);
for (DeviceInfo &info : device.multi_devices) {
adjust_device_info_from_preferences(info, cpreferences);
/* There is an accumulative logic here, because Multi-devices are supported only for
* the same backend + CPU in Blender right now, and both oneAPI and Metal have a
* global boolean backend setting for enabling/disabling Hardware Ray Tracing,
* so all sub-devices in the multi-device should enable (or disable) Hardware Ray Tracing
* simultaneously (and CPU device is expected to ignore `use_hardware_raytracing` setting). */
device.use_hardware_raytracing |= info.use_hardware_raytracing;
}
if (preview) {
+33 -3
View File
@@ -31,10 +31,12 @@ class MultiDevice : public Device {
device_ptr unique_key = 1;
vector<vector<SubDevice *>> peer_islands;
MultiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless)
: Device(info, stats, profiler, headless)
MultiDevice(const DeviceInfo &info_, Stats &stats, Profiler &profiler, bool headless)
: Device(info_, stats, profiler, headless)
{
for (const DeviceInfo &subinfo : info.multi_devices) {
verify_hardware_raytracing();
for (const DeviceInfo &subinfo : this->info.multi_devices) {
/* Always add CPU devices at the back since GPU devices can change
* host memory pointers, which CPU uses as device pointer. */
SubDevice *sub;
@@ -78,6 +80,34 @@ class MultiDevice : public Device {
}
}
void verify_hardware_raytracing()
{
/* Determine if we can use hardware ray-tracing. It is only supported if all selected
* GPU devices support it. Both the backends and scene update code do not support mixed
* BVH2 and hardware raytracing. The CPU device will ignore this setting. */
bool have_disabled_hardware_rt = false;
bool have_enabled_hardware_rt = false;
for (const DeviceInfo &subinfo : info.multi_devices) {
if (subinfo.type != DEVICE_CPU) {
if (subinfo.use_hardware_raytracing) {
have_enabled_hardware_rt = true;
}
else {
have_disabled_hardware_rt = true;
}
}
}
info.use_hardware_raytracing = have_enabled_hardware_rt && !have_disabled_hardware_rt;
for (DeviceInfo &subinfo : info.multi_devices) {
if (subinfo.type != DEVICE_CPU) {
subinfo.use_hardware_raytracing = info.use_hardware_raytracing;
}
}
}
const string &error_message() override
{
error_msg.clear();