Blender V5.0
oidn.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#ifdef WITH_OPENIMAGEDENOISE
6
7# include <cstdint>
8
9# include "BLI_array.hh"
10# include "BLI_assert.h"
11# include "BLI_span.hh"
12
13# include "GPU_platform.hh"
14
15# include "COM_context.hh"
16# include "COM_utilities_oidn.hh"
17
18# include <OpenImageDenoise/oidn.hpp>
19
20namespace blender::compositor {
21
22static oidn::DeviceRef create_oidn_gpu_device(const Context &context)
23{
24
25 /* The compositor uses CPU execution and does not have an active GPU context or device, so let
26 * OIDN select the best device, which is typically the fastest. */
27 if (!context.use_gpu()) {
28 return oidn::newDevice(oidn::DeviceType::Default);
29 }
30
31 /* Try to select the device that is used by the currently active GPU context. First, try to
32 * select the device based on the device LUID. */
33 const Span<uint8_t> platform_luid = GPU_platform_luid();
34 const uint32_t platform_luid_node_mask = GPU_platform_luid_node_mask();
35 const int devices_count = oidn::getNumPhysicalDevices();
36 for (int i = 0; i < devices_count; i++) {
37 oidn::PhysicalDeviceRef physical_device(i);
38 if (!physical_device.get<bool>("luidSupported")) {
39 continue;
40 }
41
42 oidn::LUID luid = physical_device.get<oidn::LUID>("luid");
43 uint32_t luid_node_mask = physical_device.get<uint32_t>("nodeMask");
44 if (platform_luid == Span<uint8_t>(luid.bytes, sizeof(luid.bytes)) &&
45 platform_luid_node_mask == luid_node_mask)
46 {
47 return physical_device.newDevice();
48 }
49 }
50
51 /* If LUID matching was unsuccessful, try to match based on UUID. We rely on multiple selection
52 * methods because not all platforms support both UUID and LUID, but all platforms support either
53 * one of them. UUID supports all except MacOS Metal, while LUID only supports Windows and MacOS
54 * Metal. Note that we prefer LUID as a first match because UUID is unreliable in practice as
55 * some implementations report the same UUID for different devices in the same machine. */
56 const Span<uint8_t> platform_uuid = GPU_platform_uuid();
57 for (int i = 0; i < devices_count; i++) {
58 oidn::PhysicalDeviceRef physical_device(i);
59 if (!physical_device.get<bool>("uuidSupported")) {
60 continue;
61 }
62
63 oidn::UUID uuid = physical_device.get<oidn::UUID>("uuid");
64 if (platform_uuid == Span<uint8_t>(uuid.bytes, sizeof(uuid.bytes))) {
65 return physical_device.newDevice();
66 }
67 }
68
69 return oidn::newDevice(oidn::DeviceType::Default);
70}
71
72oidn::DeviceRef create_oidn_device(const Context &context)
73{
74 const eCompositorDenoiseDevice preferred_denoise_device = static_cast<eCompositorDenoiseDevice>(
75 context.get_render_data().compositor_denoise_device);
76
77 switch (preferred_denoise_device) {
79 return oidn::newDevice(oidn::DeviceType::CPU);
81 return create_oidn_gpu_device(context);
83 if (!context.use_gpu()) {
84 return oidn::newDevice(oidn::DeviceType::CPU);
85 }
86 else {
87 return create_oidn_gpu_device(context);
88 }
89 }
90
92 return oidn::newDevice(oidn::DeviceType::Default);
93}
94
95oidn::BufferRef create_oidn_buffer(const oidn::DeviceRef &device, const MutableSpan<float> image)
96{
97 /* The device can access host-side data, so create a shared buffer that wraps the data. */
98 const bool can_access_host_memory = device.get<bool>("systemMemorySupported");
99 if (can_access_host_memory) {
100 return device.newBuffer(image.data(), image.size_in_bytes());
101 }
102
103 /* Otherwise, create a device-only buffer and copy the data to it. */
104 oidn::BufferRef buffer = device.newBuffer(image.size_in_bytes(), oidn::Storage::Device);
105 buffer.write(0, image.size_in_bytes(), image.data());
106 return buffer;
107}
108
109} // namespace blender::compositor
110
111#endif
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
eCompositorDenoiseDevice
@ SCE_COMPOSITOR_DENOISE_DEVICE_GPU
@ SCE_COMPOSITOR_DENOISE_DEVICE_AUTO
@ SCE_COMPOSITOR_DENOISE_DEVICE_CPU
blender::Span< uint8_t > GPU_platform_uuid()
blender::Span< uint8_t > GPU_platform_luid()
uint32_t GPU_platform_luid_node_mask()
constexpr T * data() const
Definition BLI_span.hh:539
constexpr int64_t size_in_bytes() const
Definition BLI_span.hh:501
int context(const bContext *C, const char *member, bContextDataResult *result)
i
Definition text_draw.cc:230