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)
|
self._draw_devices(row, compute_device_type, devices)
|
||||||
|
|
||||||
import _cycles
|
import _cycles
|
||||||
has_peer_memory = 0
|
has_peer_memory = False
|
||||||
has_rt_api_support = {'METAL': False, 'HIP': False, 'ONEAPI': False}
|
has_enabled_hardware_rt = False
|
||||||
|
has_disabled_hardware_rt = False
|
||||||
for device in self.get_device_list(compute_device_type):
|
for device in self.get_device_list(compute_device_type):
|
||||||
if device[3] and self.find_existing_device_entry(device).use:
|
if not self.find_existing_device_entry(device).use:
|
||||||
has_peer_memory += 1
|
continue
|
||||||
if device[4] and self.find_existing_device_entry(device).use:
|
if device[1] != compute_device_type:
|
||||||
device_type = device[1]
|
continue
|
||||||
has_rt_api_support[device_type] = True
|
|
||||||
|
|
||||||
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 = layout.row()
|
||||||
row.use_property_split = True
|
row.use_property_split = True
|
||||||
row.prop(self, "peer_memory")
|
row.prop(self, "peer_memory")
|
||||||
@@ -1857,18 +1867,19 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.use_property_split = True
|
col.use_property_split = True
|
||||||
col.prop(self, "kernel_optimization_level")
|
col.prop(self, "kernel_optimization_level")
|
||||||
if has_rt_api_support['METAL']:
|
row = col.row()
|
||||||
col.prop(self, "metalrt")
|
row.active = has_hardware_rt
|
||||||
|
row.prop(self, "metalrt")
|
||||||
|
|
||||||
if compute_device_type == 'HIP':
|
if compute_device_type == 'HIP':
|
||||||
import platform
|
import platform
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.active = has_rt_api_support['HIP']
|
row.active = has_hardware_rt
|
||||||
row.prop(self, "use_hiprt")
|
row.prop(self, "use_hiprt")
|
||||||
|
|
||||||
elif compute_device_type == 'ONEAPI' and _cycles.with_embree_gpu:
|
elif compute_device_type == 'ONEAPI' and _cycles.with_embree_gpu:
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.active = has_rt_api_support['ONEAPI']
|
row.active = has_hardware_rt
|
||||||
row.prop(self, "use_oneapirt")
|
row.prop(self, "use_oneapirt")
|
||||||
|
|
||||||
def draw(self, context):
|
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);
|
adjust_device_info_from_preferences(device, cpreferences);
|
||||||
for (DeviceInfo &info : device.multi_devices) {
|
for (DeviceInfo &info : device.multi_devices) {
|
||||||
adjust_device_info_from_preferences(info, cpreferences);
|
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) {
|
if (preview) {
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ class MultiDevice : public Device {
|
|||||||
device_ptr unique_key = 1;
|
device_ptr unique_key = 1;
|
||||||
vector<vector<SubDevice *>> peer_islands;
|
vector<vector<SubDevice *>> peer_islands;
|
||||||
|
|
||||||
MultiDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless)
|
MultiDevice(const DeviceInfo &info_, Stats &stats, Profiler &profiler, bool headless)
|
||||||
: Device(info, stats, profiler, 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
|
/* Always add CPU devices at the back since GPU devices can change
|
||||||
* host memory pointers, which CPU uses as device pointer. */
|
* host memory pointers, which CPU uses as device pointer. */
|
||||||
SubDevice *sub;
|
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
|
const string &error_message() override
|
||||||
{
|
{
|
||||||
error_msg.clear();
|
error_msg.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user