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 | |
22 | namespace 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 | |