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:
@@ -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):
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user