Merge remote-tracking branch 'origin/blender-v2.93-release'
[blender.git] / intern / cycles / device / device.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __DEVICE_H__
18 #define __DEVICE_H__
19
20 #include <stdlib.h>
21
22 #include "bvh/bvh_params.h"
23
24 #include "device/device_memory.h"
25 #include "device/device_task.h"
26
27 #include "util/util_list.h"
28 #include "util/util_stats.h"
29 #include "util/util_string.h"
30 #include "util/util_texture.h"
31 #include "util/util_thread.h"
32 #include "util/util_types.h"
33 #include "util/util_vector.h"
34
35 CCL_NAMESPACE_BEGIN
36
37 class BVH;
38 class Progress;
39 class RenderTile;
40
41 /* Device Types */
42
43 enum DeviceType {
44   DEVICE_NONE = 0,
45   DEVICE_CPU,
46   DEVICE_OPENCL,
47   DEVICE_CUDA,
48   DEVICE_NETWORK,
49   DEVICE_MULTI,
50   DEVICE_OPTIX,
51   DEVICE_DUMMY,
52 };
53
54 enum DeviceTypeMask {
55   DEVICE_MASK_CPU = (1 << DEVICE_CPU),
56   DEVICE_MASK_OPENCL = (1 << DEVICE_OPENCL),
57   DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
58   DEVICE_MASK_OPTIX = (1 << DEVICE_OPTIX),
59   DEVICE_MASK_NETWORK = (1 << DEVICE_NETWORK),
60   DEVICE_MASK_ALL = ~0
61 };
62
63 enum DeviceKernelStatus {
64   DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
65   DEVICE_KERNEL_USING_FEATURE_KERNEL,
66   DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
67   DEVICE_KERNEL_UNKNOWN,
68 };
69
70 #define DEVICE_MASK(type) (DeviceTypeMask)(1 << type)
71
72 class DeviceInfo {
73  public:
74   DeviceType type;
75   string description;
76   string id; /* used for user preferences, should stay fixed with changing hardware config */
77   int num;
78   bool display_device;               /* GPU is used as a display device. */
79   bool has_half_images;              /* Support half-float textures. */
80   bool has_nanovdb;                  /* Support NanoVDB volumes. */
81   bool has_volume_decoupled;         /* Decoupled volume shading. */
82   bool has_branched_path;            /* Supports branched path tracing. */
83   bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
84   bool has_osl;                      /* Support Open Shading Language. */
85   bool use_split_kernel;             /* Use split or mega kernel. */
86   bool has_profiling;                /* Supports runtime collection of profiling info. */
87   bool has_peer_memory;              /* GPU has P2P access to memory of another GPU. */
88   DenoiserTypeMask denoisers;        /* Supported denoiser types. */
89   int cpu_threads;
90   vector<DeviceInfo> multi_devices;
91   vector<DeviceInfo> denoising_devices;
92   string error_msg;
93
94   DeviceInfo()
95   {
96     type = DEVICE_CPU;
97     id = "CPU";
98     num = 0;
99     cpu_threads = 0;
100     display_device = false;
101     has_half_images = false;
102     has_nanovdb = false;
103     has_volume_decoupled = false;
104     has_branched_path = true;
105     has_adaptive_stop_per_sample = false;
106     has_osl = false;
107     use_split_kernel = false;
108     has_profiling = false;
109     has_peer_memory = false;
110     denoisers = DENOISER_NONE;
111   }
112
113   bool operator==(const DeviceInfo &info)
114   {
115     /* Multiple Devices with the same ID would be very bad. */
116     assert(id != info.id ||
117            (type == info.type && num == info.num && description == info.description));
118     return id == info.id;
119   }
120
121   /* Add additional devices needed for the specified denoiser. */
122   void add_denoising_devices(DenoiserType denoiser_type);
123 };
124
125 class DeviceRequestedFeatures {
126  public:
127   /* Use experimental feature set. */
128   bool experimental;
129
130   /* Selective nodes compilation. */
131
132   /* Identifier of a node group up to which all the nodes needs to be
133    * compiled in. Nodes from higher group indices will be ignores.
134    */
135   int max_nodes_group;
136
137   /* Features bitfield indicating which features from the requested group
138    * will be compiled in. Nodes which corresponds to features which are not
139    * in this bitfield will be ignored even if they're in the requested group.
140    */
141   int nodes_features;
142
143   /* BVH/sampling kernel features. */
144   bool use_hair;
145   bool use_hair_thick;
146   bool use_object_motion;
147   bool use_camera_motion;
148
149   /* Denotes whether baking functionality is needed. */
150   bool use_baking;
151
152   /* Use subsurface scattering materials. */
153   bool use_subsurface;
154
155   /* Use volume materials. */
156   bool use_volume;
157
158   /* Use branched integrator. */
159   bool use_integrator_branched;
160
161   /* Use OpenSubdiv patch evaluation */
162   bool use_patch_evaluation;
163
164   /* Use Transparent shadows */
165   bool use_transparent;
166
167   /* Use various shadow tricks, such as shadow catcher. */
168   bool use_shadow_tricks;
169
170   /* Per-uber shader usage flags. */
171   bool use_principled;
172
173   /* Denoising features. */
174   bool use_denoising;
175
176   /* Use raytracing in shaders. */
177   bool use_shader_raytrace;
178
179   /* Use true displacement */
180   bool use_true_displacement;
181
182   /* Use background lights */
183   bool use_background_light;
184
185   DeviceRequestedFeatures()
186   {
187     /* TODO(sergey): Find more meaningful defaults. */
188     max_nodes_group = 0;
189     nodes_features = 0;
190     use_hair = false;
191     use_hair_thick = false;
192     use_object_motion = false;
193     use_camera_motion = false;
194     use_baking = false;
195     use_subsurface = false;
196     use_volume = false;
197     use_integrator_branched = false;
198     use_patch_evaluation = false;
199     use_transparent = false;
200     use_shadow_tricks = false;
201     use_principled = false;
202     use_denoising = false;
203     use_shader_raytrace = false;
204     use_true_displacement = false;
205     use_background_light = false;
206   }
207
208   bool modified(const DeviceRequestedFeatures &requested_features)
209   {
210     return !(max_nodes_group == requested_features.max_nodes_group &&
211              nodes_features == requested_features.nodes_features &&
212              use_hair == requested_features.use_hair &&
213              use_hair_thick == requested_features.use_hair_thick &&
214              use_object_motion == requested_features.use_object_motion &&
215              use_camera_motion == requested_features.use_camera_motion &&
216              use_baking == requested_features.use_baking &&
217              use_subsurface == requested_features.use_subsurface &&
218              use_volume == requested_features.use_volume &&
219              use_integrator_branched == requested_features.use_integrator_branched &&
220              use_patch_evaluation == requested_features.use_patch_evaluation &&
221              use_transparent == requested_features.use_transparent &&
222              use_shadow_tricks == requested_features.use_shadow_tricks &&
223              use_principled == requested_features.use_principled &&
224              use_denoising == requested_features.use_denoising &&
225              use_shader_raytrace == requested_features.use_shader_raytrace &&
226              use_true_displacement == requested_features.use_true_displacement &&
227              use_background_light == requested_features.use_background_light);
228   }
229
230   /* Convert the requested features structure to a build options,
231    * which could then be passed to compilers.
232    */
233   string get_build_options() const
234   {
235     string build_options = "";
236     if (experimental) {
237       build_options += "-D__KERNEL_EXPERIMENTAL__ ";
238     }
239     build_options += "-D__NODES_MAX_GROUP__=" + string_printf("%d", max_nodes_group);
240     build_options += " -D__NODES_FEATURES__=" + string_printf("%d", nodes_features);
241     if (!use_hair) {
242       build_options += " -D__NO_HAIR__";
243     }
244     if (!use_object_motion) {
245       build_options += " -D__NO_OBJECT_MOTION__";
246     }
247     if (!use_camera_motion) {
248       build_options += " -D__NO_CAMERA_MOTION__";
249     }
250     if (!use_baking) {
251       build_options += " -D__NO_BAKING__";
252     }
253     if (!use_volume) {
254       build_options += " -D__NO_VOLUME__";
255     }
256     if (!use_subsurface) {
257       build_options += " -D__NO_SUBSURFACE__";
258     }
259     if (!use_integrator_branched) {
260       build_options += " -D__NO_BRANCHED_PATH__";
261     }
262     if (!use_patch_evaluation) {
263       build_options += " -D__NO_PATCH_EVAL__";
264     }
265     if (!use_transparent && !use_volume) {
266       build_options += " -D__NO_TRANSPARENT__";
267     }
268     if (!use_shadow_tricks) {
269       build_options += " -D__NO_SHADOW_TRICKS__";
270     }
271     if (!use_principled) {
272       build_options += " -D__NO_PRINCIPLED__";
273     }
274     if (!use_denoising) {
275       build_options += " -D__NO_DENOISING__";
276     }
277     if (!use_shader_raytrace) {
278       build_options += " -D__NO_SHADER_RAYTRACE__";
279     }
280     return build_options;
281   }
282 };
283
284 std::ostream &operator<<(std::ostream &os, const DeviceRequestedFeatures &requested_features);
285
286 /* Device */
287
288 struct DeviceDrawParams {
289   function<void()> bind_display_space_shader_cb;
290   function<void()> unbind_display_space_shader_cb;
291 };
292
293 class Device {
294   friend class device_sub_ptr;
295
296  protected:
297   enum {
298     FALLBACK_SHADER_STATUS_NONE = 0,
299     FALLBACK_SHADER_STATUS_ERROR,
300     FALLBACK_SHADER_STATUS_SUCCESS,
301   };
302
303   Device(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background)
304       : background(background),
305         vertex_buffer(0),
306         fallback_status(FALLBACK_SHADER_STATUS_NONE),
307         fallback_shader_program(0),
308         info(info_),
309         stats(stats_),
310         profiler(profiler_)
311   {
312   }
313
314   bool background;
315   string error_msg;
316
317   /* used for real time display */
318   unsigned int vertex_buffer;
319   int fallback_status, fallback_shader_program;
320   int image_texture_location, fullscreen_location;
321
322   bool bind_fallback_display_space_shader(const float width, const float height);
323
324   virtual device_ptr mem_alloc_sub_ptr(device_memory & /*mem*/, int /*offset*/, int /*size*/)
325   {
326     /* Only required for devices that implement denoising. */
327     assert(false);
328     return (device_ptr)0;
329   }
330   virtual void mem_free_sub_ptr(device_ptr /*ptr*/){};
331
332  public:
333   /* noexcept needed to silence TBB warning. */
334   virtual ~Device() noexcept(false);
335
336   /* info */
337   DeviceInfo info;
338   virtual const string &error_message()
339   {
340     return error_msg;
341   }
342   bool have_error()
343   {
344     return !error_message().empty();
345   }
346   virtual void set_error(const string &error)
347   {
348     if (!have_error()) {
349       error_msg = error;
350     }
351     fprintf(stderr, "%s\n", error.c_str());
352     fflush(stderr);
353   }
354   virtual bool show_samples() const
355   {
356     return false;
357   }
358   virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
359
360   /* statistics */
361   Stats &stats;
362   Profiler &profiler;
363
364   /* memory alignment */
365   virtual int mem_sub_ptr_alignment()
366   {
367     return MIN_ALIGNMENT_CPU_DATA_TYPES;
368   }
369
370   /* constant memory */
371   virtual void const_copy_to(const char *name, void *host, size_t size) = 0;
372
373   /* open shading language, only for CPU device */
374   virtual void *osl_memory()
375   {
376     return NULL;
377   }
378
379   /* load/compile kernels, must be called before adding tasks */
380   virtual bool load_kernels(const DeviceRequestedFeatures & /*requested_features*/)
381   {
382     return true;
383   }
384
385   /* Wait for device to become available to upload data and receive tasks
386    * This method is used by the OpenCL device to load the
387    * optimized kernels or when not (yet) available load the
388    * generic kernels (only during foreground rendering) */
389   virtual bool wait_for_availability(const DeviceRequestedFeatures & /*requested_features*/)
390   {
391     return true;
392   }
393   /* Check if there are 'better' kernels available to be used
394    * We can switch over to these kernels
395    * This method is used to determine if we can switch the preview kernels
396    * to regular kernels */
397   virtual DeviceKernelStatus get_active_kernel_switch_state()
398   {
399     return DEVICE_KERNEL_USING_FEATURE_KERNEL;
400   }
401
402   /* tasks */
403   virtual int get_split_task_count(DeviceTask &)
404   {
405     return 1;
406   }
407
408   virtual void task_add(DeviceTask &task) = 0;
409   virtual void task_wait() = 0;
410   virtual void task_cancel() = 0;
411
412   /* opengl drawing */
413   virtual void draw_pixels(device_memory &mem,
414                            int y,
415                            int w,
416                            int h,
417                            int width,
418                            int height,
419                            int dx,
420                            int dy,
421                            int dw,
422                            int dh,
423                            bool transparent,
424                            const DeviceDrawParams &draw_params);
425
426   /* acceleration structure building */
427   virtual void build_bvh(BVH *bvh, Progress &progress, bool refit);
428
429   /* OptiX specific destructor. */
430   virtual void release_optix_bvh(BVH *){};
431
432 #ifdef WITH_NETWORK
433   /* networking */
434   void server_run();
435 #endif
436
437   /* multi device */
438   virtual void map_tile(Device * /*sub_device*/, RenderTile & /*tile*/)
439   {
440   }
441   virtual int device_number(Device * /*sub_device*/)
442   {
443     return 0;
444   }
445   virtual void map_neighbor_tiles(Device * /*sub_device*/, RenderTileNeighbors & /*neighbors*/)
446   {
447   }
448   virtual void unmap_neighbor_tiles(Device * /*sub_device*/, RenderTileNeighbors & /*neighbors*/)
449   {
450   }
451
452   virtual bool is_resident(device_ptr /*key*/, Device *sub_device)
453   {
454     /* Memory is always resident if this is not a multi device, regardless of whether the pointer
455      * is valid or not (since it may not have been allocated yet). */
456     return sub_device == this;
457   }
458   virtual bool check_peer_access(Device * /*peer_device*/)
459   {
460     return false;
461   }
462
463   /* static */
464   static Device *create(DeviceInfo &info,
465                         Stats &stats,
466                         Profiler &profiler,
467                         bool background = true);
468
469   static DeviceType type_from_string(const char *name);
470   static string string_from_type(DeviceType type);
471   static vector<DeviceType> available_types();
472   static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
473   static DeviceInfo dummy_device(const string &error_msg = "");
474   static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
475   static DeviceInfo get_multi_device(const vector<DeviceInfo> &subdevices,
476                                      int threads,
477                                      bool background);
478
479   /* Tag devices lists for update. */
480   static void tag_update();
481
482   static void free_memory();
483
484  protected:
485   /* Memory allocation, only accessed through device_memory. */
486   friend class MultiDevice;
487   friend class DeviceServer;
488   friend class device_memory;
489
490   virtual void mem_alloc(device_memory &mem) = 0;
491   virtual void mem_copy_to(device_memory &mem) = 0;
492   virtual void mem_copy_from(device_memory &mem, int y, int w, int h, int elem) = 0;
493   virtual void mem_zero(device_memory &mem) = 0;
494   virtual void mem_free(device_memory &mem) = 0;
495
496  private:
497   /* Indicted whether device types and devices lists were initialized. */
498   static bool need_types_update, need_devices_update;
499   static thread_mutex device_mutex;
500   static vector<DeviceInfo> cuda_devices;
501   static vector<DeviceInfo> optix_devices;
502   static vector<DeviceInfo> opencl_devices;
503   static vector<DeviceInfo> cpu_devices;
504   static vector<DeviceInfo> network_devices;
505   static uint devices_initialized_mask;
506 };
507
508 CCL_NAMESPACE_END
509
510 #endif /* __DEVICE_H__ */