Blender V4.3
blender/device.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "blender/device.h"
6#include "blender/session.h"
7#include "blender/util.h"
8
9#include "util/foreach.h"
10
12
23
24int blender_device_threads(BL::Scene &b_scene)
25{
26 BL::RenderSettings b_r = b_scene.render();
27
28 if (b_r.threads_mode() == BL::RenderSettings::threads_mode_FIXED) {
29 return b_r.threads();
30 }
31 else {
32 return 0;
33 }
34}
35
37{
38 if (!get_boolean(cpreferences, "peer_memory")) {
39 info.has_peer_memory = false;
40 }
41
42 if (info.type == DEVICE_METAL) {
44 cpreferences, "metalrt", METALRT_NUM_SETTINGS, METALRT_AUTO);
45
47 if (use_metalrt == METALRT_OFF) {
48 info.use_hardware_raytracing = false;
49 }
50 else if (use_metalrt == METALRT_ON) {
51 info.use_hardware_raytracing = true;
52 }
53 }
54
55 if (info.type == DEVICE_ONEAPI && !get_boolean(cpreferences, "use_oneapirt")) {
56 info.use_hardware_raytracing = false;
57 }
58
59 if (info.type == DEVICE_HIP && !get_boolean(cpreferences, "use_hiprt")) {
60 info.use_hardware_raytracing = false;
61 }
62}
63
64void static adjust_device_info(DeviceInfo &device, PointerRNA cpreferences, bool preview)
65{
66 adjust_device_info_from_preferences(device, cpreferences);
67 foreach (DeviceInfo &info, device.multi_devices) {
68 adjust_device_info_from_preferences(info, cpreferences);
69
70 /* There is an accumulative logic here, because Multi-devices are supported only for
71 * the same backend + CPU in Blender right now, and both oneAPI and Metal have a
72 * global boolean backend setting for enabling/disabling Hardware Ray Tracing,
73 * so all sub-devices in the multi-device should enable (or disable) Hardware Ray Tracing
74 * simultaneously (and CPU device is expected to ignore `use_hardware_raytracing` setting). */
76 }
77
78 if (preview) {
79 /* Disable specialization for preview renders. */
81 }
82 else {
84 cpreferences,
85 "kernel_optimization_level",
88 }
89}
90
91DeviceInfo blender_device_info(BL::Preferences &b_preferences,
92 BL::Scene &b_scene,
93 bool background,
94 bool preview,
95 DeviceInfo &preferences_device)
96{
97 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
98
99 /* Find cycles preferences. */
100 PointerRNA cpreferences;
101 for (BL::Addon &b_addon : b_preferences.addons) {
102 if (b_addon.module() == "cycles") {
103 cpreferences = b_addon.preferences().ptr;
104 break;
105 }
106 }
107
108 /* Default to CPU device. */
110
111 /* Device, which is chosen in the Blender Preferences. Default to CPU device. */
112 preferences_device = cpu_device;
113
114 /* Test if we are using GPU devices. */
115 ComputeDevice compute_device = (ComputeDevice)get_enum(
116 cpreferences, "compute_device_type", COMPUTE_DEVICE_NUM, COMPUTE_DEVICE_CPU);
117
118 if (compute_device != COMPUTE_DEVICE_CPU) {
119 /* Query GPU devices with matching types. */
120 uint mask = DEVICE_MASK_CPU;
121 if (compute_device == COMPUTE_DEVICE_CUDA) {
122 mask |= DEVICE_MASK_CUDA;
123 }
124 else if (compute_device == COMPUTE_DEVICE_OPTIX) {
125 mask |= DEVICE_MASK_OPTIX;
126 }
127 else if (compute_device == COMPUTE_DEVICE_HIP) {
128 mask |= DEVICE_MASK_HIP;
129 }
130 else if (compute_device == COMPUTE_DEVICE_METAL) {
131 mask |= DEVICE_MASK_METAL;
132 }
133 else if (compute_device == COMPUTE_DEVICE_ONEAPI) {
134 mask |= DEVICE_MASK_ONEAPI;
135 }
137
138 /* Match device preferences and available devices. */
139 vector<DeviceInfo> used_devices;
140 RNA_BEGIN (&cpreferences, device, "devices") {
141 if (get_boolean(device, "use")) {
142 string id = get_string(device, "id");
143 foreach (DeviceInfo &info, devices) {
144 if (info.id == id) {
145 used_devices.push_back(info);
146 break;
147 }
148 }
149 }
150 }
151 RNA_END;
152
153 if (!used_devices.empty()) {
154 int threads = blender_device_threads(b_scene);
155 preferences_device = Device::get_multi_device(used_devices, threads, background);
156 }
157 }
158
159 adjust_device_info(preferences_device, cpreferences, preview);
160 adjust_device_info(cpu_device, cpreferences, preview);
161
162 /* Device, which will be used, according to Settings, Scene preferences and command line
163 * parameters. */
164 DeviceInfo device;
165
168
169 if (devices.empty()) {
170 device = Device::dummy_device("Found no Cycles device of the specified type");
171 }
172 else {
173 int threads = blender_device_threads(b_scene);
174 device = Device::get_multi_device(devices, threads, background);
175 }
176 adjust_device_info(device, cpreferences, preview);
177 }
178 else {
179 /* 1 is a "GPU compute" in properties.py for Scene settings. */
180 if (get_enum(cscene, "device") == 1) {
181 device = preferences_device;
182 }
183 else {
184 device = cpu_device;
185 }
186 }
187
188 return device;
189}
190
unsigned int uint
#define RNA_BEGIN(sptr, itemptr, propname)
#define RNA_END
static void adjust_device_info_from_preferences(DeviceInfo &info, PointerRNA cpreferences)
DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background, bool preview, DeviceInfo &preferences_device)
ComputeDevice
@ COMPUTE_DEVICE_ONEAPI
@ COMPUTE_DEVICE_HIP
@ COMPUTE_DEVICE_METAL
@ COMPUTE_DEVICE_CUDA
@ COMPUTE_DEVICE_OPTIX
@ COMPUTE_DEVICE_NUM
@ COMPUTE_DEVICE_CPU
static void adjust_device_info(DeviceInfo &device, PointerRNA cpreferences, bool preview)
int blender_device_threads(BL::Scene &b_scene)
static DeviceTypeMask device_override
KernelOptimizationLevel kernel_optimization_level
vector< DeviceInfo > multi_devices
bool has_peer_memory
bool use_metalrt_by_default
DeviceType type
bool use_hardware_raytracing
static DeviceInfo dummy_device(const string &error_msg="")
static vector< DeviceInfo > available_devices(uint device_type_mask=DEVICE_MASK_ALL)
static DeviceInfo get_multi_device(const vector< DeviceInfo > &subdevices, int threads, bool background)
static bool get_boolean(PointerRNA &ptr, const char *name)
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
static string get_string(PointerRNA &ptr, const char *name)
#define CCL_NAMESPACE_END
KernelOptimizationLevel
@ KERNEL_OPTIMIZATION_LEVEL_OFF
@ KERNEL_OPTIMIZATION_LEVEL_FULL
@ KERNEL_OPTIMIZATION_NUM_LEVELS
@ DEVICE_MASK_OPTIX
@ DEVICE_MASK_CPU
@ DEVICE_MASK_HIP
@ DEVICE_MASK_ALL
@ DEVICE_MASK_CUDA
@ DEVICE_MASK_METAL
@ DEVICE_MASK_ONEAPI
MetalRTSetting
@ METALRT_OFF
@ METALRT_NUM_SETTINGS
@ METALRT_ON
@ METALRT_AUTO
@ DEVICE_METAL
@ DEVICE_HIP
@ DEVICE_ONEAPI
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)