From 4f07d79bcc1ee57f7673aa8f14da11dcf2cf5588 Mon Sep 17 00:00:00 2001 From: Nikita Sirgienko Date: Thu, 25 Jun 2026 10:51:09 +0200 Subject: [PATCH] Cycles: Show devices with outdated drivers as disabled in preferences When a GPU device's driver does not meet Blender's minimum required version, the device is now shown in the preferences as a greyed-out entry with a message inside the brackets, indicating which driver version is needed, instead of being silently hidden. This helps users understand why their GPU is not available for rendering and what action they can take to resolve the situation. Pull Request: https://projects.blender.org/blender/blender/pulls/159405 --- intern/cycles/blender/addon/properties.py | 115 +++++++++++++++++--- intern/cycles/blender/device.cpp | 17 ++- intern/cycles/blender/python.cpp | 3 +- intern/cycles/device/device.cpp | 34 +++++- intern/cycles/device/device.h | 8 ++ intern/cycles/device/hip/device.cpp | 15 ++- intern/cycles/device/hip/device.h | 2 +- intern/cycles/device/oneapi/device.cpp | 2 + intern/cycles/device/oneapi/device_impl.cpp | 49 ++++++--- intern/cycles/device/oneapi/device_impl.h | 2 +- intern/cycles/device/optix/device.cpp | 9 +- intern/cycles/device/optix/device.h | 4 +- 12 files changed, 219 insertions(+), 41 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index e644ccb9248..f8f2213f1c4 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1613,7 +1613,7 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): class CyclesDeviceSettings(bpy.types.PropertyGroup): # Runtime properties - __slots__ = ("is_optimized") + __slots__ = ("is_optimized", "meets_driver_requirement") # Properties saved in preferences id: StringProperty(name="ID", description="Unique identifier of the device") @@ -1751,6 +1751,7 @@ class CyclesPreferences(bpy.types.AddonPreferences): for device in device_list: entry = self.find_existing_device_entry(device) entry.is_optimized = device[7] + entry.meets_driver_requirement = device[8] if entry.type == compute_device_type: devices.append(entry) elif entry.type == 'CPU': @@ -1789,6 +1790,11 @@ class CyclesPreferences(bpy.types.AddonPreferences): for device in self.get_device_list(compute_device_type): if device[1] != compute_device_type: continue + + # Skip devices that do not meet the driver requirement. + if not device[8]: + continue + for dev in self.devices: if dev.use and dev.id == device[2]: num += 1 @@ -1800,6 +1806,11 @@ class CyclesPreferences(bpy.types.AddonPreferences): for device in self.get_device_list(compute_device_type): if device[1] == compute_device_type: continue + + # Skip devices that do not meet the driver requirement. + if not device[8]: + continue + for dev in self.devices: if dev.use and dev.id == device[2]: return True @@ -1819,6 +1830,10 @@ class CyclesPreferences(bpy.types.AddonPreferences): if device_type == 'CPU': continue + # Skip devices that do not meet the driver requirement. + if not device[8]: + continue + has_device_oidn_support = device[5] if has_device_oidn_support and self.find_existing_device_entry(device).use: return True @@ -1835,6 +1850,10 @@ class CyclesPreferences(bpy.types.AddonPreferences): if device_type == 'CPU': continue + # Skip devices that do not meet the driver requirement. + if not device[8]: + continue + has_device_optixdenoiser_support = device[6] if has_device_optixdenoiser_support and self.find_existing_device_entry(device).use: return True @@ -1861,6 +1880,14 @@ class CyclesPreferences(bpy.types.AddonPreferences): found_device = True break + optix_minimum_driver_version = "535" + hip_minimum_adrenalin_driver_version = "24.9.1" + hip_minimum_pro_driver_version = "24.Q4" + hip_minimum_linux_driver_version = "24.30" + hip_rocm_minimum_version = "6.3" + oneapi_minimum_windows_driver_version = "XX.X.101.8306" + oneapi_minimum_linux_driver_version = "XX.XX.37435.3" + if not found_device: col = box.column(align=True) col.label(text=rpt_("No compatible GPUs found for Cycles"), icon='INFO', translate=False) @@ -1871,36 +1898,31 @@ class CyclesPreferences(bpy.types.AddonPreferences): icon='BLANK1', translate=False) elif device_type == 'OPTIX': compute_capability = "5.0" - driver_version = "535" col.label(text=rpt_("Requires NVIDIA GPU with compute capability %s") % compute_capability, icon='BLANK1', translate=False) - col.label(text=rpt_("and NVIDIA driver version %s or newer") % driver_version, + col.label(text=rpt_("and NVIDIA driver version %s or newer") % optix_minimum_driver_version, icon='BLANK1', translate=False) elif device_type == 'HIP': import sys if sys.platform[:3] == "win": - adrenalin_driver_version = "24.9.1" - pro_driver_version = "24.Q4" col.label( text=rpt_("Requires AMD GPU with RDNA architecture"), icon='BLANK1', translate=False) col.label(text=rpt_("and AMD Adrenalin driver %s or newer") % - adrenalin_driver_version, icon='BLANK1', translate=False) + hip_minimum_adrenalin_driver_version, icon='BLANK1', translate=False) col.label(text=rpt_("or AMD Radeon Pro %s driver or newer") % - pro_driver_version, icon='BLANK1', translate=False) + hip_minimum_pro_driver_version, icon='BLANK1', translate=False) elif sys.platform.startswith("linux"): - rocm_version = "6.3" - driver_version = "24.30" col.label( text=rpt_("Requires AMD GPU with RDNA architecture"), icon='BLANK1', translate=False) col.label( text=rpt_("and ROCm HIP Runtime %s or newer") % - rocm_version, icon='BLANK1', translate=False) + hip_rocm_minimum_version, icon='BLANK1', translate=False) col.label(text=rpt_("or AMD driver version %s or newer") % - driver_version, icon='BLANK1', translate=False) + hip_minimum_linux_driver_version, icon='BLANK1', translate=False) elif device_type == 'ONEAPI': import sys if sys.platform.startswith("win"): @@ -1912,16 +1934,14 @@ class CyclesPreferences(bpy.types.AddonPreferences): # and no intermediate versions were publicly available between 8250 and 8331 for Intel® Arc™ GPUs. # As a result, we can safely recommend users to use driver version 8306 or higher, without needing # to distinguish between Intel® Arc™ and Intel® Arc™ Pro users. - driver_version = "XX.X.101.8306" col.label( text=self._format_device_name( rpt_("Requires Intel(R) Arc(TM) GPUs or newer Intel(R) Graphics")), icon='BLANK1', translate=False) - col.label(text=rpt_("with Windows driver version %s or newer") % driver_version, - icon='BLANK1', translate=False) + col.label(text=rpt_("with Windows driver version %s or newer") % + oneapi_minimum_windows_driver_version, icon='BLANK1', translate=False) elif sys.platform.startswith("linux"): - driver_version = "XX.XX.37435.3" col.label( text=self._format_device_name( rpt_("Requires Intel(R) Arc(TM) GPUs or newer Intel(R) Graphics")), @@ -1931,7 +1951,11 @@ class CyclesPreferences(bpy.types.AddonPreferences): text=rpt_(" - intel-level-zero-gpu or intel-compute-runtime version"), icon='BLANK1', translate=False) - col.label(text=rpt_(" %s or newer") % driver_version, icon='BLANK1', translate=False) + col.label( + text=rpt_(" %s or newer") % + oneapi_minimum_linux_driver_version, + icon='BLANK1', + translate=False) col.label(text=rpt_(" - oneAPI Level-Zero Loader"), icon='BLANK1', translate=False) elif device_type == 'METAL': mac_version = "12.2" @@ -1939,11 +1963,58 @@ class CyclesPreferences(bpy.types.AddonPreferences): icon='BLANK1', translate=False) return + has_usable_gpu_device = False for device in devices: name = self._format_device_name(device.name) if not device.is_optimized: name += rpt_(" (Unoptimized Performance)") - box.prop(device, "use", text=name, translate=False) + + col = box.column() + row = col.row() + + if not device.meets_driver_requirement: + import sys + row.active = False + name += rpt_(" (Disabled)") + row.prop(device, "use", text=name, translate=False) + + details = "" + if device.type == 'OPTIX': + details = rpt_("Requires NVIDIA driver version %s or newer") % optix_minimum_driver_version + elif device.type == 'HIP': + if sys.platform[:3] == "win": + details = rpt_("Requires AMD Adrenalin driver %s or newer, or AMD Radeon Pro %s driver or newer") % ( + hip_minimum_adrenalin_driver_version, hip_minimum_pro_driver_version) + elif sys.platform.startswith("linux"): + details = rpt_("Requires ROCm HIP Runtime %s or newer, or AMD driver version %s or newer") % ( + hip_rocm_minimum_version, hip_minimum_linux_driver_version) + elif device.type == 'ONEAPI': + if sys.platform.startswith("win"): + details = rpt_( + "Requires Windows driver version %s or newer") % oneapi_minimum_windows_driver_version + elif sys.platform.startswith("linux"): + details = rpt_( + "Requires intel-level-zero-gpu or intel-compute-runtime version %s or newer") % oneapi_minimum_linux_driver_version + + if not details: + details = rpt_("Driver upgrade required") + + sub = col.row() + sub.active = False + sub.label(icon='BLANK1', text=details, translate=False) + else: + if device.type != 'CPU': + if device.use: + has_usable_gpu_device = True + else: + # CPU is always listed last (by convention in get_devices()), + # see get_devices_for_type implementation. + # Grey it out if no GPU device is enabled, because CPU here + # is meant as a supplement to GPU rendering. For CPU-only + # rendering, select the "None" compute device type instead. + if not has_usable_gpu_device: + row.active = False + row.prop(device, "use", text=name, translate=False) def draw_impl(self, layout, context): row = layout.row() @@ -1966,8 +2037,18 @@ class CyclesPreferences(bpy.types.AddonPreferences): if device[1] != compute_device_type: continue + # device[8] == DeviceInfo.meets_driver_requirement + # For more details see available_devices_func function in python.cpp + if not device[8]: + # Devices that do not meet the driver requirement are not used; + # skip them. + continue + + # device[3] == DeviceInfo.has_peer_memory if device[3]: has_peer_memory = True + + # device[4] == DeviceInfo.use_hardware_raytracing if device[4]: has_enabled_hardware_rt = True else: diff --git a/intern/cycles/blender/device.cpp b/intern/cycles/blender/device.cpp index a13cb7bff6c..7148d007af1 100644 --- a/intern/cycles/blender/device.cpp +++ b/intern/cycles/blender/device.cpp @@ -142,7 +142,11 @@ DeviceInfo blender_device_info(blender::UserDef &b_preferences, const string id = get_string(device, "id"); for (const DeviceInfo &info : devices) { if (info.id == id) { - used_devices.push_back(info); + /* Devices not meeting driver requirements are still enumerated for UI reporting, + * but must not be added to the active render device list. */ + if (info.meets_driver_requirement) { + used_devices.push_back(info); + } break; } } @@ -164,7 +168,16 @@ DeviceInfo blender_device_info(blender::UserDef &b_preferences, DeviceInfo device; if (BlenderSession::device_override != DEVICE_MASK_ALL) { - const vector devices = Device::available_devices(BlenderSession::device_override); + const vector available_devices = Device::available_devices( + BlenderSession::device_override); + vector devices; + for (const DeviceInfo &info : available_devices) { + /* Devices not meeting driver requirements are still enumerated for UI reporting, + * but must not be added to the active render device list. */ + if (info.meets_driver_requirement) { + devices.push_back(info); + } + } if (devices.empty()) { device = Device::dummy_device("Found no Cycles device of the specified type"); diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp index adf00e7ac04..557448522bf 100644 --- a/intern/cycles/blender/python.cpp +++ b/intern/cycles/blender/python.cpp @@ -429,7 +429,7 @@ static PyObject *available_devices_func(PyObject * /*self*/, PyObject *args) for (size_t i = 0; i < devices.size(); i++) { const DeviceInfo &device = devices[i]; const string type_name = Device::string_from_type(device.type); - PyObject *device_tuple = PyTuple_New(8); + PyObject *device_tuple = PyTuple_New(9); PyTuple_SET_ITEM(device_tuple, 0, pyunicode_from_string(device.description.c_str())); PyTuple_SET_ITEM(device_tuple, 1, pyunicode_from_string(type_name.c_str())); PyTuple_SET_ITEM(device_tuple, 2, pyunicode_from_string(device.id.c_str())); @@ -439,6 +439,7 @@ static PyObject *available_devices_func(PyObject * /*self*/, PyObject *args) device_tuple, 5, PyBool_FromLong(device.denoisers & DENOISER_OPENIMAGEDENOISE)); PyTuple_SET_ITEM(device_tuple, 6, PyBool_FromLong(device.denoisers & DENOISER_OPTIX)); PyTuple_SET_ITEM(device_tuple, 7, PyBool_FromLong(device.has_execution_optimization)); + PyTuple_SET_ITEM(device_tuple, 8, PyBool_FromLong(device.meets_driver_requirement)); PyTuple_SET_ITEM(ret, i, device_tuple); } diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index ccc9481d8e2..ae6e285cc0f 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -276,8 +276,17 @@ vector Device::available_devices(const uint mask) #ifdef WITH_OPTIX if (mask & DEVICE_MASK_OPTIX) { if (!(devices_initialized_mask & DEVICE_MASK_OPTIX)) { - if (device_optix_init()) { + bool meets_nvidia_driver_requirement = true; + if (device_optix_init(&meets_nvidia_driver_requirement) || !meets_nvidia_driver_requirement) + { device_optix_info(cuda_devices(), optix_devices()); + for (DeviceInfo &info : optix_devices()) { + info.meets_driver_requirement = meets_nvidia_driver_requirement; + } + } + else { + /* `device_optix_init` has failed but not because of the driver being too old. + * Nothing to do in this case. */ } devices_initialized_mask |= DEVICE_MASK_OPTIX; } @@ -290,8 +299,29 @@ vector Device::available_devices(const uint mask) #ifdef WITH_HIP if (mask & DEVICE_MASK_HIP) { if (!(devices_initialized_mask & DEVICE_MASK_HIP)) { - if (device_hip_init()) { + bool meets_amd_driver_requirement = true; + if (device_hip_init(&meets_amd_driver_requirement)) { device_hip_info(hip_devices()); + for (DeviceInfo &info : hip_devices()) { + info.meets_driver_requirement = meets_amd_driver_requirement; + } + } + else if (meets_amd_driver_requirement == false) { + /* If we are here, then hipewInit has failed with HIPEW_ERROR_OLD_DRIVER. */ + /* It is unclear if proper device info can be collected at this point, so we create + * a placeholder device to communicate the need to upgrade the driver, as presumably + * the hardware is available. */ + DeviceInfo info = DeviceInfo(); + info.type = DEVICE_HIP; + info.description = "Unknown AMD device"; + info.id = "unknown_amd_device_with_outdated_driver"; + info.num = 0; + info.meets_driver_requirement = false; + hip_devices().push_back(info); + } + else { + /* `device_hip_init` has failed but not because of the driver being too old. + * Nothing to do in this case. */ } devices_initialized_mask |= DEVICE_MASK_HIP; } diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 2a9cb5abf45..264b93d14e4 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -96,6 +96,14 @@ class DeviceInfo { /* Indicate that device execution has been optimized by Blender or vendor developers. * For LTS versions, this helps communicate that newer versions may have better performance. */ bool has_execution_optimization = true; + /* True if device's driver is above the minimal Blender required version, false otherwise. + * Needed for properly communicating this fact back to the user, who then can choose to upgrade + * the driver or do nothing. + * + * Default value is chosen to be true intentionally - assume compliant unless proven otherwise, + * especially since CPU devices do not have any minimal versions, as well as some GPU backends, + * for example CUDA. */ + bool meets_driver_requirement = true; KernelOptimizationLevel kernel_optimization_level = KERNEL_OPTIMIZATION_LEVEL_FULL; /* Optimization level applied to path tracing diff --git a/intern/cycles/device/hip/device.cpp b/intern/cycles/device/hip/device.cpp index bf58f0292d3..24ea66a665b 100644 --- a/intern/cycles/device/hip/device.cpp +++ b/intern/cycles/device/hip/device.cpp @@ -24,8 +24,11 @@ CCL_NAMESPACE_BEGIN -bool device_hip_init() +bool device_hip_init(bool *r_meets_driver_requirement) { + if (r_meets_driver_requirement) { + *r_meets_driver_requirement = true; + } #if !defined(WITH_HIP) return false; #elif defined(WITH_HIP_DYNLOAD) @@ -43,6 +46,13 @@ bool device_hip_init() LOG_INFO << "HIPEW initialization succeeded"; if (!hipSupportsDriver()) { LOG_WARNING << "Driver version is too old"; + if (r_meets_driver_requirement) { + *r_meets_driver_requirement = false; + } + /* The device will not be used because it does not meet the driver requirement. + * Returning true ensures the real AMD device information is still reported + * in the UI. */ + result = true; } else if (HIPDevice::have_precompiled_kernels()) { LOG_INFO << "Found precompiled kernels"; @@ -64,6 +74,9 @@ bool device_hip_init() else if (hipew_result == HIPEW_ERROR_OLD_DRIVER) { LOG_WARNING << "HIPEW initialization failed: Driver version too old, requires AMD Adrenalin " "driver 24.9.1 or newer, or AMD Radeon Pro driver 24.Q4 or newer"; + if (r_meets_driver_requirement) { + *r_meets_driver_requirement = false; + } } else { LOG_WARNING << "HIPEW initialization failed: Error opening HIP dynamic library"; diff --git a/intern/cycles/device/hip/device.h b/intern/cycles/device/hip/device.h index e5188cec047..19ada1ae213 100644 --- a/intern/cycles/device/hip/device.h +++ b/intern/cycles/device/hip/device.h @@ -15,7 +15,7 @@ class DeviceInfo; class Profiler; class Stats; -bool device_hip_init(); +bool device_hip_init(bool *r_meets_driver_requirement = nullptr); unique_ptr device_hip_create(const DeviceInfo &info, Stats &stats, diff --git a/intern/cycles/device/oneapi/device.cpp b/intern/cycles/device/oneapi/device.cpp index 75a860b3787..4901b0dd118 100644 --- a/intern/cycles/device/oneapi/device.cpp +++ b/intern/cycles/device/oneapi/device.cpp @@ -105,6 +105,7 @@ static void device_iterator_cb(const char *id, bool hwrt_support, bool oidn_support, bool has_execution_optimization, + bool meets_driver_requirement, void *user_ptr) { vector *devices = (vector *)user_ptr; @@ -147,6 +148,7 @@ static void device_iterator_cb(const char *id, # endif info.has_execution_optimization = has_execution_optimization; + info.meets_driver_requirement = meets_driver_requirement; devices->push_back(info); LOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\"."; diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index 46cabfcc95c..3e94e5ecdd1 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -38,7 +38,12 @@ extern "C" void rtcSetDeviceSYCLDevice(RTCDevice device, const sycl::device sycl CCL_NAMESPACE_BEGIN -static std::vector available_sycl_devices( +struct SyclDeviceEntry { + sycl::device device; + bool meets_driver_requirement; +}; + +static std::vector available_sycl_devices( bool *multiple_level_zero_platforms_detected); static int parse_driver_build_version(const sycl::device &device); @@ -1051,13 +1056,21 @@ bool OneapiDevice::create_queue(SyclQueue *&external_queue, *multiple_level_zero_platforms_detected_pointer = false; try { - std::vector devices = available_sycl_devices( + std::vector devices = available_sycl_devices( multiple_level_zero_platforms_detected_pointer); + if (device_index < 0 || device_index >= devices.size()) { return false; } - sycl::queue *created_queue = new sycl::queue(devices[device_index], + if (devices[device_index].meets_driver_requirement == false) { + oneapi_error_string_ = "The device driver is too old."; + LOG_ERROR << "Internal error: The SYCL device does not meet minimum driver requirement, but " + "it was used anyway. Please report a bug."; + return false; + } + + sycl::queue *created_queue = new sycl::queue(devices[device_index].device, sycl::property::queue::in_order()); external_queue = reinterpret_cast(created_queue); @@ -1072,7 +1085,7 @@ bool OneapiDevice::create_queue(SyclQueue *&external_queue, "\"intel-level-zero-gpu-raytracing\" to enable it or disable Embree on GPU."; } else { - rtcSetDeviceSYCLDevice(*device_object_ptr, devices[device_index]); + rtcSetDeviceSYCLDevice(*device_object_ptr, devices[device_index].device); } } # else @@ -1439,10 +1452,10 @@ int parse_driver_build_version(const sycl::device &device) return driver_build_version; } -std::vector available_sycl_devices( +std::vector available_sycl_devices( bool *multiple_level_zero_platforms_detected = nullptr) { - std::vector available_devices; + std::vector available_devices; bool allow_all_devices = false; if (getenv("CYCLES_ONEAPI_ALL_DEVICES") != nullptr) { allow_all_devices = true; @@ -1470,6 +1483,7 @@ std::vector available_sycl_devices( for (const sycl::device &device : oneapi_devices) { bool filter_out = false; + bool meets_driver_requirement = true; if (!allow_all_devices) { /* For now we support all Intel(R) Arc(TM) devices and likely any future GPU, @@ -1520,7 +1534,7 @@ std::vector available_sycl_devices( lowest_supported_driver_version_win : lowest_supported_driver_version_neo; if (driver_build_version < lowest_supported_driver_version) { - filter_out = true; + meets_driver_requirement = false; LOG_WARNING << "Driver version for device \"" << device.get_info() @@ -1539,8 +1553,8 @@ std::vector available_sycl_devices( /* The order of adding devices is not important, as both duplicated GPUs are fully * functional and performant, so we can pick up the first one we find. */ if (!filter_out) { - for (const sycl::device &already_available_device : available_devices) { - std::array devices = {already_available_device, device}; + for (const SyclDeviceEntry &available_entry : available_devices) { + std::array devices = {available_entry.device, device}; std::vector uuids; for (int i = 0; i < 2; i++) { /* As this is an Intel-specific enumeration issue - we are collecting Intel UUID @@ -1577,7 +1591,7 @@ std::vector available_sycl_devices( } if (!filter_out) { - available_devices.push_back(device); + available_devices.push_back(SyclDeviceEntry{device, meets_driver_requirement}); } } } @@ -1670,8 +1684,10 @@ char *OneapiDevice::device_capabilities() { std::stringstream capabilities; - const std::vector &oneapi_devices = available_sycl_devices(); - for (const sycl::device &device : oneapi_devices) { + const std::vector &entries = available_sycl_devices(); + for (const SyclDeviceEntry &entry : entries) { + const sycl::device &device = entry.device; + const std::string &name = device.get_info(); capabilities << std::string("\t") << name << "\n"; @@ -1686,6 +1702,8 @@ char *OneapiDevice::device_capabilities() capabilities << arch_name << "\n"; capabilities << "\t\tsycl::info::device::is_cycles_optimized\t\t\t"; capabilities << is_optimised_for_arch << "\n"; + capabilities << "\t\tsycl::info::device::meets_driver_requirement\t\t\t"; + capabilities << entry.meets_driver_requirement << "\n"; # define WRITE_ATTR(attribute_name, attribute_variable) \ capabilities << "\t\tsycl::info::device::" #attribute_name "\t\t\t" << attribute_variable \ @@ -1785,8 +1803,10 @@ char *OneapiDevice::device_capabilities() void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr) { int num = 0; - std::vector devices = available_sycl_devices(); - for (sycl::device &device : devices) { + std::vector entries = available_sycl_devices(); + for (const SyclDeviceEntry &entry : entries) { + const sycl::device &device = entry.device; + const std::string &platform_name = device.get_platform().get_info(); std::string name = device.get_info(); @@ -1816,6 +1836,7 @@ void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_p hwrt_support, oidn_support, is_optimised_for_arch, + entry.meets_driver_requirement, user_ptr); num++; } diff --git a/intern/cycles/device/oneapi/device_impl.h b/intern/cycles/device/oneapi/device_impl.h index f1d319418a9..00a28d938b1 100644 --- a/intern/cycles/device/oneapi/device_impl.h +++ b/intern/cycles/device/oneapi/device_impl.h @@ -16,7 +16,7 @@ CCL_NAMESPACE_BEGIN class DeviceQueue; using OneAPIDeviceIteratorCallback = - void (*)(const char *, const char *, const int, bool, bool, bool, void *); + void (*)(const char *, const char *, const int, bool, bool, bool, bool, void *); class OneapiDevice : public GPUDevice { private: diff --git a/intern/cycles/device/optix/device.cpp b/intern/cycles/device/optix/device.cpp index 606c203e2e0..08e9a2157f9 100644 --- a/intern/cycles/device/optix/device.cpp +++ b/intern/cycles/device/optix/device.cpp @@ -28,8 +28,11 @@ CCL_NAMESPACE_BEGIN -bool device_optix_init() +bool device_optix_init(bool *r_meets_driver_requirement) { + if (r_meets_driver_requirement) { + *r_meets_driver_requirement = true; + } #ifdef WITH_OPTIX if (OPTIX_FUNCTION_TABLE_SYMBOL.optixDeviceContextCreate != nullptr) { /* Already initialized function table. */ @@ -46,6 +49,9 @@ bool device_optix_init() if (result == OPTIX_ERROR_UNSUPPORTED_ABI_VERSION) { LOG_WARNING << "OptiX initialization failed because the installed NVIDIA driver is too old. " "Please update to the latest driver first!"; + if (r_meets_driver_requirement) { + *r_meets_driver_requirement = false; + } return false; } if (result != OPTIX_SUCCESS) { @@ -93,6 +99,7 @@ void device_optix_info(const vector &cuda_devices, vector device_optix_create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless); +/** Generate proper OptiX DeviceInfo based on an existing CUDA DeviceInfo for the same device. + * Does not require usage of the OptiX API, only CUDA API. */ void device_optix_info(const vector &cuda_devices, vector &devices); CCL_NAMESPACE_END