1// ======================================================================== //
2// Copyright 2009-2019 Intel Corporation //
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#pragma once
18
19#include <algorithm>
20#include "oidn.h"
21
22namespace oidn {
23
24 // --------------------------------------------------------------------------
25 // Buffer
26 // --------------------------------------------------------------------------
27
28 // Formats for images and other data stored in buffers
29 enum class Format
30 {
31 Undefined = OIDN_FORMAT_UNDEFINED,
32
33 // 32-bit single-precision floating point scalar and vector formats
34 Float = OIDN_FORMAT_FLOAT,
35 Float2 = OIDN_FORMAT_FLOAT2,
36 Float3 = OIDN_FORMAT_FLOAT3,
37 Float4 = OIDN_FORMAT_FLOAT4,
38 };
39
40 // Access modes for mapping buffers
41 enum class Access
42 {
43 Read = OIDN_ACCESS_READ, // read-only access
44 Write = OIDN_ACCESS_WRITE, // write-only access
45 ReadWrite = OIDN_ACCESS_READ_WRITE, // read and write access
46 WriteDiscard = OIDN_ACCESS_WRITE_DISCARD, // write-only access, previous contents discarded
47 };
48
49 // Buffer object with automatic reference counting
50 class BufferRef
51 {
52 private:
53 OIDNBuffer handle;
54
55 public:
56 BufferRef() : handle(nullptr) {}
57 BufferRef(OIDNBuffer handle) : handle(handle) {}
58
59 BufferRef(const BufferRef& other) : handle(other.handle)
60 {
61 if (handle)
62 oidnRetainBuffer(handle);
63 }
64
65 BufferRef(BufferRef&& other) : handle(other.handle)
66 {
67 other.handle = nullptr;
68 }
69
70 BufferRef& operator =(const BufferRef& other)
71 {
72 if (&other != this)
73 {
74 if (other.handle)
75 oidnRetainBuffer(other.handle);
76 if (handle)
77 oidnReleaseBuffer(handle);
78 handle = other.handle;
79 }
80 return *this;
81 }
82
83 BufferRef& operator =(BufferRef&& other)
84 {
85 std::swap(handle, other.handle);
86 return *this;
87 }
88
89 BufferRef& operator =(OIDNBuffer other)
90 {
91 if (other)
92 oidnRetainBuffer(other);
93 if (handle)
94 oidnReleaseBuffer(handle);
95 handle = other;
96 return *this;
97 }
98
99 ~BufferRef()
100 {
101 if (handle)
102 oidnReleaseBuffer(handle);
103 }
104
105 OIDNBuffer getHandle() const
106 {
107 return handle;
108 }
109
110 operator bool() const
111 {
112 return handle != nullptr;
113 }
114
115 // Maps a region of the buffer to host memory.
116 // If byteSize is 0, the maximum available amount of memory will be mapped.
117 void* map(Access access = Access::ReadWrite, size_t byteOffset = 0, size_t byteSize = 0)
118 {
119 return oidnMapBuffer(handle, (OIDNAccess)access, byteOffset, byteSize);
120 }
121
122 // Unmaps a region of the buffer.
123 // mappedPtr must be a pointer returned by a previous call to map.
124 void unmap(void* mappedPtr)
125 {
126 oidnUnmapBuffer(handle, mappedPtr);
127 }
128 };
129
130 // --------------------------------------------------------------------------
131 // Filter
132 // --------------------------------------------------------------------------
133
134 // Progress monitor callback function
135 typedef bool (*ProgressMonitorFunction)(void* userPtr, double n);
136
137 // Filter object with automatic reference counting
138 class FilterRef
139 {
140 private:
141 OIDNFilter handle;
142
143 public:
144 FilterRef() : handle(nullptr) {}
145 FilterRef(OIDNFilter handle) : handle(handle) {}
146
147 FilterRef(const FilterRef& other) : handle(other.handle)
148 {
149 if (handle)
150 oidnRetainFilter(handle);
151 }
152
153 FilterRef(FilterRef&& other) : handle(other.handle)
154 {
155 other.handle = nullptr;
156 }
157
158 FilterRef& operator =(const FilterRef& other)
159 {
160 if (&other != this)
161 {
162 if (other.handle)
163 oidnRetainFilter(other.handle);
164 if (handle)
165 oidnReleaseFilter(handle);
166 handle = other.handle;
167 }
168 return *this;
169 }
170
171 FilterRef& operator =(FilterRef&& other)
172 {
173 std::swap(handle, other.handle);
174 return *this;
175 }
176
177 FilterRef& operator =(OIDNFilter other)
178 {
179 if (other)
180 oidnRetainFilter(other);
181 if (handle)
182 oidnReleaseFilter(handle);
183 handle = other;
184 return *this;
185 }
186
187 ~FilterRef()
188 {
189 if (handle)
190 oidnReleaseFilter(handle);
191 }
192
193 OIDNFilter getHandle() const
194 {
195 return handle;
196 }
197
198 operator bool() const
199 {
200 return handle != nullptr;
201 }
202
203 // Sets an image parameter of the filter (stored in a buffer).
204 void setImage(const char* name,
205 const BufferRef& buffer, Format format,
206 size_t width, size_t height,
207 size_t byteOffset = 0,
208 size_t bytePixelStride = 0, size_t byteRowStride = 0)
209 {
210 oidnSetFilterImage(handle, name,
211 buffer.getHandle(), (OIDNFormat)format,
212 width, height,
213 byteOffset,
214 bytePixelStride, byteRowStride);
215 }
216
217 // Sets an image parameter of the filter (owned by the user).
218 void setImage(const char* name,
219 void* ptr, Format format,
220 size_t width, size_t height,
221 size_t byteOffset = 0,
222 size_t bytePixelStride = 0, size_t byteRowStride = 0)
223 {
224 oidnSetSharedFilterImage(handle, name,
225 ptr, (OIDNFormat)format,
226 width, height,
227 byteOffset,
228 bytePixelStride, byteRowStride);
229 }
230
231 // Sets a boolean parameter of the filter.
232 void set(const char* name, bool value)
233 {
234 oidnSetFilter1b(handle, name, value);
235 }
236
237 // Sets an integer parameter of the filter.
238 void set(const char* name, int value)
239 {
240 oidnSetFilter1i(handle, name, value);
241 }
242
243 // Sets a float parameter of the filter.
244 void set(const char* name, float value)
245 {
246 oidnSetFilter1f(handle, name, value);
247 }
248
249 // Gets a parameter of the filter.
250 template<typename T>
251 T get(const char* name);
252
253 // Sets the progress monitor callback function of the filter.
254 void setProgressMonitorFunction(ProgressMonitorFunction func, void* userPtr = nullptr)
255 {
256 oidnSetFilterProgressMonitorFunction(handle, (OIDNProgressMonitorFunction)func, userPtr);
257 }
258
259 // Commits all previous changes to the filter.
260 void commit()
261 {
262 oidnCommitFilter(handle);
263 }
264
265 // Executes the filter.
266 void execute()
267 {
268 oidnExecuteFilter(handle);
269 }
270 };
271
272 // Gets a boolean parameter of the filter.
273 template<>
274 inline bool FilterRef::get(const char* name)
275 {
276 return oidnGetFilter1b(handle, name);
277 }
278
279 // Gets an integer parameter of the filter.
280 template<>
281 inline int FilterRef::get(const char* name)
282 {
283 return oidnGetFilter1i(handle, name);
284 }
285
286 // Gets a float parameter of the filter.
287 template<>
288 inline float FilterRef::get(const char* name)
289 {
290 return oidnGetFilter1f(handle, name);
291 }
292
293 // --------------------------------------------------------------------------
294 // Device
295 // --------------------------------------------------------------------------
296
297 // Device types
298 enum class DeviceType
299 {
300 Default = OIDN_DEVICE_TYPE_DEFAULT, // select device automatically
301
302 CPU = OIDN_DEVICE_TYPE_CPU, // CPU device
303 };
304
305 // Error codes
306 enum class Error
307 {
308 None = OIDN_ERROR_NONE, // no error occurred
309 Unknown = OIDN_ERROR_UNKNOWN, // an unknown error occurred
310 InvalidArgument = OIDN_ERROR_INVALID_ARGUMENT, // an invalid argument was specified
311 InvalidOperation = OIDN_ERROR_INVALID_OPERATION, // the operation is not allowed
312 OutOfMemory = OIDN_ERROR_OUT_OF_MEMORY, // not enough memory to execute the operation
313 UnsupportedHardware = OIDN_ERROR_UNSUPPORTED_HARDWARE, // the hardware (e.g. CPU) is not supported
314 Cancelled = OIDN_ERROR_CANCELLED, // the operation was cancelled by the user
315 };
316
317 // Error callback function
318 typedef void (*ErrorFunction)(void* userPtr, Error code, const char* message);
319
320 // Device object with automatic reference counting
321 class DeviceRef
322 {
323 private:
324 OIDNDevice handle;
325
326 public:
327 DeviceRef() : handle(nullptr) {}
328 DeviceRef(OIDNDevice handle) : handle(handle) {}
329
330 DeviceRef(const DeviceRef& other) : handle(other.handle)
331 {
332 if (handle)
333 oidnRetainDevice(handle);
334 }
335
336 DeviceRef(DeviceRef&& other) : handle(other.handle)
337 {
338 other.handle = nullptr;
339 }
340
341 DeviceRef& operator =(const DeviceRef& other)
342 {
343 if (&other != this)
344 {
345 if (other.handle)
346 oidnRetainDevice(other.handle);
347 if (handle)
348 oidnReleaseDevice(handle);
349 handle = other.handle;
350 }
351 return *this;
352 }
353
354 DeviceRef& operator =(DeviceRef&& other)
355 {
356 std::swap(handle, other.handle);
357 return *this;
358 }
359
360 DeviceRef& operator =(OIDNDevice other)
361 {
362 if (other)
363 oidnRetainDevice(other);
364 if (handle)
365 oidnReleaseDevice(handle);
366 handle = other;
367 return *this;
368 }
369
370 ~DeviceRef()
371 {
372 if (handle)
373 oidnReleaseDevice(handle);
374 }
375
376 OIDNDevice getHandle() const
377 {
378 return handle;
379 }
380
381 operator bool() const
382 {
383 return handle != nullptr;
384 }
385
386 // Sets a boolean parameter of the device.
387 void set(const char* name, bool value)
388 {
389 oidnSetDevice1b(handle, name, value);
390 }
391
392 // Sets an integer parameter of the device.
393 void set(const char* name, int value)
394 {
395 oidnSetDevice1i(handle, name, value);
396 }
397
398 // Gets a parameter of the device.
399 template<typename T>
400 T get(const char* name);
401
402 // Sets the error callback function of the device.
403 void setErrorFunction(ErrorFunction func, void* userPtr = nullptr)
404 {
405 oidnSetDeviceErrorFunction(handle, (OIDNErrorFunction)func, userPtr);
406 }
407
408 // Returns the first unqueried error code and clears the stored error.
409 // Can be called for a null device as well to check why a device creation failed.
410 Error getError()
411 {
412 return (Error)oidnGetDeviceError(handle, nullptr);
413 }
414
415 // Returns the first unqueried error code and string message, and clears the stored error.
416 // Can be called for a null device as well to check why a device creation failed.
417 Error getError(const char*& outMessage)
418 {
419 return (Error)oidnGetDeviceError(handle, &outMessage);
420 }
421
422 // Commits all previous changes to the device.
423 // Must be called before first using the device (e.g. creating filters).
424 void commit()
425 {
426 oidnCommitDevice(handle);
427 }
428
429 // Creates a new buffer (data allocated and owned by the device).
430 BufferRef newBuffer(size_t byteSize)
431 {
432 return oidnNewBuffer(handle, byteSize);
433 }
434
435 // Creates a new shared buffer (data allocated and owned by the user).
436 BufferRef newBuffer(void* ptr, size_t byteSize)
437 {
438 return oidnNewSharedBuffer(handle, ptr, byteSize);
439 }
440
441 // Creates a new filter of the specified type (e.g. "RT").
442 FilterRef newFilter(const char* type)
443 {
444 return oidnNewFilter(handle, type);
445 }
446 };
447
448 // Gets a boolean parameter of the device.
449 template<>
450 inline bool DeviceRef::get(const char* name)
451 {
452 return oidnGetDevice1b(handle, name);
453 }
454
455 // Gets an integer parameter of the device (e.g. "version").
456 template<>
457 inline int DeviceRef::get(const char* name)
458 {
459 return oidnGetDevice1i(handle, name);
460 }
461
462 // Creates a new device.
463 inline DeviceRef newDevice(DeviceType type = DeviceType::Default)
464 {
465 return DeviceRef(oidnNewDevice((OIDNDeviceType)type));
466 }
467
468} // namespace oidn
469