Blender  V3.3
device/device.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #ifndef __DEVICE_H__
5 #define __DEVICE_H__
6 
7 #include <stdlib.h>
8 
9 #include "bvh/params.h"
10 
11 #include "device/denoise.h"
12 #include "device/memory.h"
13 
14 #include "util/function.h"
15 #include "util/list.h"
16 #include "util/log.h"
17 #include "util/stats.h"
18 #include "util/string.h"
19 #include "util/texture.h"
20 #include "util/thread.h"
21 #include "util/types.h"
22 #include "util/unique_ptr.h"
23 #include "util/vector.h"
24 
26 
27 class BVH;
28 class DeviceQueue;
29 class Progress;
30 class CPUKernels;
32 class Scene;
33 
34 /* Device Types */
35 
36 enum DeviceType {
46 };
47 
55  DEVICE_MASK_ALL = ~0
56 };
57 
58 #define DEVICE_MASK(type) (DeviceTypeMask)(1 << type)
59 
60 class DeviceInfo {
61  public:
63  string description;
64  string id; /* used for user preferences, should stay fixed with changing hardware config */
65  int num;
66  bool display_device; /* GPU is used as a display device. */
67  bool has_nanovdb; /* Support NanoVDB volumes. */
68  bool has_osl; /* Support Open Shading Language. */
69  bool has_profiling; /* Supports runtime collection of profiling info. */
70  bool has_peer_memory; /* GPU has P2P access to memory of another GPU. */
71  bool has_gpu_queue; /* Device supports GPU queue. */
72  bool use_metalrt; /* Use MetalRT to accelerate ray queries (Metal only). */
73  DenoiserTypeMask denoisers; /* Supported denoiser types. */
76  string error_msg;
77 
79  {
80  type = DEVICE_CPU;
81  id = "CPU";
82  num = 0;
83  cpu_threads = 0;
84  display_device = false;
85  has_nanovdb = false;
86  has_osl = false;
87  has_profiling = false;
88  has_peer_memory = false;
89  has_gpu_queue = false;
90  use_metalrt = false;
92  }
93 
94  bool operator==(const DeviceInfo &info) const
95  {
96  /* Multiple Devices with the same ID would be very bad. */
97  assert(id != info.id ||
98  (type == info.type && num == info.num && description == info.description));
99  return id == info.id;
100  }
101 };
102 
103 /* Device */
104 
105 class Device {
106  friend class device_sub_ptr;
107 
108  protected:
109  Device(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
110  : info(info_), stats(stats_), profiler(profiler_)
111  {
112  }
113 
114  string error_msg;
115 
116  virtual device_ptr mem_alloc_sub_ptr(device_memory & /*mem*/, size_t /*offset*/, size_t /*size*/)
117  {
118  /* Only required for devices that implement denoising. */
119  assert(false);
120  return (device_ptr)0;
121  }
122  virtual void mem_free_sub_ptr(device_ptr /*ptr*/){};
123 
124  public:
125  /* noexcept needed to silence TBB warning. */
126  virtual ~Device() noexcept(false);
127 
128  /* info */
130  virtual const string &error_message()
131  {
132  return error_msg;
133  }
134  bool have_error()
135  {
136  return !error_message().empty();
137  }
138  virtual void set_error(const string &error)
139  {
140  if (!have_error()) {
141  error_msg = error;
142  }
143  fprintf(stderr, "%s\n", error.c_str());
144  fflush(stderr);
145  }
146  virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
147 
148  /* statistics */
151 
152  /* constant memory */
153  virtual void const_copy_to(const char *name, void *host, size_t size) = 0;
154 
155  /* load/compile kernels, must be called before adding tasks */
156  virtual bool load_kernels(uint /*kernel_features*/)
157  {
158  return true;
159  }
160 
161  /* GPU device only functions.
162  * These may not be used on CPU or multi-devices. */
163 
164  /* Create new queue for executing kernels in. */
165  virtual unique_ptr<DeviceQueue> gpu_queue_create();
166 
167  /* CPU device only functions.
168  * These may not be used on GPU or multi-devices. */
169 
170  /* Get CPU kernel functions for native instruction set. */
171  static const CPUKernels &get_cpu_kernels();
172  /* Get kernel globals to pass to kernels. */
173  virtual void get_cpu_kernel_thread_globals(
174  vector<CPUKernelThreadGlobals> & /*kernel_thread_globals*/);
175  /* Get OpenShadingLanguage memory buffer. */
176  virtual void *get_cpu_osl_memory();
177 
178  /* acceleration structure building */
179  virtual void build_bvh(BVH *bvh, Progress &progress, bool refit);
180 
181  /* OptiX specific destructor. */
182  virtual void release_optix_bvh(BVH * /*bvh*/){};
183 
184  /* multi device */
185  virtual int device_number(Device * /*sub_device*/)
186  {
187  return 0;
188  }
189 
190  /* Called after kernel texture setup, and prior to integrator state setup. */
191  virtual void optimize_for_scene(Scene * /*scene*/)
192  {
193  }
194 
195  virtual bool is_resident(device_ptr /*key*/, Device *sub_device)
196  {
197  /* Memory is always resident if this is not a multi device, regardless of whether the pointer
198  * is valid or not (since it may not have been allocated yet). */
199  return sub_device == this;
200  }
201  virtual bool check_peer_access(Device * /*peer_device*/)
202  {
203  return false;
204  }
205 
206  /* Graphics resources interoperability.
207  *
208  * The interoperability comes here by the meaning that the device is capable of computing result
209  * directly into an OpenGL (or other graphics library) buffer. */
210 
211  /* Check display is to be updated using graphics interoperability.
212  * The interoperability can not be used is it is not supported by the device. But the device
213  * might also force disable the interoperability if it detects that it will be slower than
214  * copying pixels from the render buffer. */
216  {
217  return false;
218  }
219 
220  /* Buffer denoising. */
221 
222  /* Returns true if task is fully handled. */
223  virtual bool denoise_buffer(const DeviceDenoiseTask & /*task*/)
224  {
225  LOG(ERROR) << "Request buffer denoising from a device which does not support it.";
226  return false;
227  }
228 
230  {
231  LOG(ERROR) << "Request denoising queue from a device which does not support it.";
232  return nullptr;
233  }
234 
235  /* Sub-devices */
236 
237  /* Run given callback for every individual device which will be handling rendering.
238  * For the single device the callback is called for the device itself. For the multi-device the
239  * callback is only called for the sub-devices. */
240  virtual void foreach_device(const function<void(Device *)> &callback)
241  {
242  callback(this);
243  }
244 
245  /* static */
246  static Device *create(const DeviceInfo &info, Stats &stats, Profiler &profiler);
247 
248  static DeviceType type_from_string(const char *name);
249  static string string_from_type(DeviceType type);
251  static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL);
252  static DeviceInfo dummy_device(const string &error_msg = "");
253  static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL);
254  static DeviceInfo get_multi_device(const vector<DeviceInfo> &subdevices,
255  int threads,
256  bool background);
257 
258  /* Tag devices lists for update. */
259  static void tag_update();
260 
261  static void free_memory();
262 
263  protected:
264  /* Memory allocation, only accessed through device_memory. */
265  friend class MultiDevice;
266  friend class DeviceServer;
267  friend class device_memory;
268 
269  virtual void mem_alloc(device_memory &mem) = 0;
270  virtual void mem_copy_to(device_memory &mem) = 0;
271  virtual void mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem) = 0;
272  virtual void mem_zero(device_memory &mem) = 0;
273  virtual void mem_free(device_memory &mem) = 0;
274 
275  private:
276  /* Indicted whether device types and devices lists were initialized. */
277  static bool need_types_update, need_devices_update;
278  static thread_mutex device_mutex;
279  static vector<DeviceInfo> cuda_devices;
280  static vector<DeviceInfo> optix_devices;
281  static vector<DeviceInfo> cpu_devices;
282  static vector<DeviceInfo> hip_devices;
283  static vector<DeviceInfo> metal_devices;
284  static vector<DeviceInfo> oneapi_devices;
285  static uint devices_initialized_mask;
286 };
287 
289 
290 #endif /* __DEVICE_H__ */
unsigned int uint
Definition: BLI_sys_types.h:67
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void refit(btStridingMeshInterface *triangles, const btVector3 &aabbMin, const btVector3 &aabbMax)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Definition: bvh/bvh.h:63
vector< DeviceInfo > multi_devices
Definition: device/device.h:75
DenoiserTypeMask denoisers
Definition: device/device.h:73
bool operator==(const DeviceInfo &info) const
Definition: device/device.h:94
bool display_device
Definition: device/device.h:66
string error_msg
Definition: device/device.h:76
bool has_peer_memory
Definition: device/device.h:70
bool has_nanovdb
Definition: device/device.h:67
bool has_gpu_queue
Definition: device/device.h:71
bool has_profiling
Definition: device/device.h:69
DeviceType type
Definition: device/device.h:62
bool use_metalrt
Definition: device/device.h:72
string description
Definition: device/device.h:63
virtual void optimize_for_scene(Scene *)
virtual void release_optix_bvh(BVH *)
virtual bool is_resident(device_ptr, Device *sub_device)
static void free_memory()
virtual BVHLayoutMask get_bvh_layout_mask() const =0
static DeviceInfo dummy_device(const string &error_msg="")
static void tag_update()
static vector< DeviceInfo > available_devices(uint device_type_mask=DEVICE_MASK_ALL)
static const CPUKernels & get_cpu_kernels()
virtual void const_copy_to(const char *name, void *host, size_t size)=0
virtual void mem_zero(device_memory &mem)=0
virtual void get_cpu_kernel_thread_globals(vector< CPUKernelThreadGlobals > &)
string error_msg
Device(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
virtual int device_number(Device *)
static Device * create(const DeviceInfo &info, Stats &stats, Profiler &profiler)
virtual ~Device() noexcept(false)
virtual void mem_copy_from(device_memory &mem, size_t y, size_t w, size_t h, size_t elem)=0
virtual void mem_free_sub_ptr(device_ptr)
virtual unique_ptr< DeviceQueue > gpu_queue_create()
Profiler & profiler
Stats & stats
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit)
virtual bool load_kernels(uint)
static DeviceType type_from_string(const char *name)
virtual const string & error_message()
virtual void * get_cpu_osl_memory()
virtual bool check_peer_access(Device *)
virtual void mem_free(device_memory &mem)=0
virtual void foreach_device(const function< void(Device *)> &callback)
virtual void set_error(const string &error)
virtual void mem_copy_to(device_memory &mem)=0
virtual DeviceQueue * get_denoise_queue()
virtual device_ptr mem_alloc_sub_ptr(device_memory &, size_t, size_t)
static string device_capabilities(uint device_type_mask=DEVICE_MASK_ALL)
friend class DeviceServer
DeviceInfo info
static vector< DeviceType > available_types()
static string string_from_type(DeviceType type)
virtual void mem_alloc(device_memory &mem)=0
static DeviceInfo get_multi_device(const vector< DeviceInfo > &subdevices, int threads, bool background)
virtual bool should_use_graphics_interop()
virtual bool denoise_buffer(const DeviceDenoiseTask &)
bool have_error()
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
int DenoiserTypeMask
Definition: denoise.h:24
@ DENOISER_NONE
Definition: denoise.h:17
DEGForeachIDComponentCallback callback
DeviceTypeMask
Definition: device/device.h:48
@ DEVICE_MASK_OPTIX
Definition: device/device.h:51
@ DEVICE_MASK_CPU
Definition: device/device.h:49
@ DEVICE_MASK_HIP
Definition: device/device.h:52
@ DEVICE_MASK_ALL
Definition: device/device.h:55
@ DEVICE_MASK_CUDA
Definition: device/device.h:50
@ DEVICE_MASK_METAL
Definition: device/device.h:53
@ DEVICE_MASK_ONEAPI
Definition: device/device.h:54
DeviceType
Definition: device/device.h:36
@ DEVICE_DUMMY
Definition: device/device.h:45
@ DEVICE_NONE
Definition: device/device.h:37
@ DEVICE_METAL
Definition: device/device.h:43
@ DEVICE_MULTI
Definition: device/device.h:40
@ DEVICE_CUDA
Definition: device/device.h:39
@ DEVICE_CPU
Definition: device/device.h:38
@ DEVICE_OPTIX
Definition: device/device.h:41
@ DEVICE_HIP
Definition: device/device.h:42
@ DEVICE_ONEAPI
Definition: device/device.h:44
#define LOG(severity)
Definition: log.h:36
static void error(const char *str)
Definition: meshlaplacian.c:51
ListBase threads
list of all thread for every CPUDevice in cpudevices a thread exists.
int BVHLayoutMask
Definition: params.h:47
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
Definition: thread.h:27
uint64_t device_ptr
Definition: util/types.h:43