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