From 26c93c835986a80f388a945ee46d4640638b7e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20=C3=81fra?= Date: Tue, 7 May 2024 14:07:39 +0200 Subject: [PATCH] Cycles: Enable OIDN 2.3 lazy device module loading This enables the new lazy module loading behavior introduced in OIDN 2.3, without breaking compatibility with older versions of OIDN (using separate code paths). Also, the detection of OIDN support for devices is now much cleaner, and devices do not need to be matched by PCI address or device name anymore. Pull Request: https://projects.blender.org/blender/blender/pulls/121362 --- intern/cycles/device/cuda/device.cpp | 4 ++ intern/cycles/device/hip/device.cpp | 4 ++ intern/cycles/device/metal/device.mm | 4 ++ intern/cycles/device/oneapi/device.cpp | 13 +++++- intern/cycles/device/oneapi/device_impl.cpp | 14 ++++++- intern/cycles/device/oneapi/device_impl.h | 8 +++- intern/cycles/device/optix/device.cpp | 4 ++ .../cycles/integrator/denoiser_oidn_gpu.cpp | 41 +++++++++++++------ intern/cycles/integrator/denoiser_oidn_gpu.h | 5 +-- 9 files changed, 75 insertions(+), 22 deletions(-) diff --git a/intern/cycles/device/cuda/device.cpp b/intern/cycles/device/cuda/device.cpp index a423d54b32e..40760bf077d 100644 --- a/intern/cycles/device/cuda/device.cpp +++ b/intern/cycles/device/cuda/device.cpp @@ -165,7 +165,11 @@ void device_cuda_info(vector &devices) (unsigned int)pci_location[2]); # if defined(WITH_OPENIMAGEDENOISE) +# if OIDN_VERSION >= 20300 + if (oidnIsCUDADeviceSupported(num)) { +# else if (OIDNDenoiserGPU::is_device_supported(info)) { +# endif info.denoisers |= DENOISER_OPENIMAGEDENOISE; } # endif diff --git a/intern/cycles/device/hip/device.cpp b/intern/cycles/device/hip/device.cpp index c955529c276..4c387a0b64a 100644 --- a/intern/cycles/device/hip/device.cpp +++ b/intern/cycles/device/hip/device.cpp @@ -186,7 +186,11 @@ void device_hip_info(vector &devices) # if defined(WITH_OPENIMAGEDENOISE) /* Check first if OIDN supports it, not doing so can crash the HIP driver with * "hipErrorNoBinaryForGpu: Unable to find code object for all current devices". */ +# if OIDN_VERSION >= 20300 + if (hipSupportsDeviceOIDN(num) && oidnIsHIPDeviceSupported(num)) { +# else if (hipSupportsDeviceOIDN(num) && OIDNDenoiserGPU::is_device_supported(info)) { +# endif info.denoisers |= DENOISER_OPENIMAGEDENOISE; } # endif diff --git a/intern/cycles/device/metal/device.mm b/intern/cycles/device/metal/device.mm index 1922932b453..bfb9f58efc0 100644 --- a/intern/cycles/device/metal/device.mm +++ b/intern/cycles/device/metal/device.mm @@ -57,7 +57,11 @@ void device_metal_info(vector &devices) info.denoisers = DENOISER_NONE; info.id = id; # if defined(WITH_OPENIMAGEDENOISE) +# if OIDN_VERSION >= 20300 + if (oidnIsMetalDeviceSupported(device)) { +# else if (OIDNDenoiserGPU::is_device_supported(info)) { +# endif info.denoisers |= DENOISER_OPENIMAGEDENOISE; } # endif diff --git a/intern/cycles/device/oneapi/device.cpp b/intern/cycles/device/oneapi/device.cpp index c068abb6026..5309529ac18 100644 --- a/intern/cycles/device/oneapi/device.cpp +++ b/intern/cycles/device/oneapi/device.cpp @@ -93,8 +93,12 @@ Device *device_oneapi_create(const DeviceInfo &info, Stats &stats, Profiler &pro } #ifdef WITH_ONEAPI -static void device_iterator_cb( - const char *id, const char *name, int num, bool hwrt_support, void *user_ptr) +static void device_iterator_cb(const char *id, + const char *name, + int num, + bool hwrt_support, + bool oidn_support, + void *user_ptr) { vector *devices = (vector *)user_ptr; @@ -109,10 +113,15 @@ static void device_iterator_cb( info.has_nanovdb = true; # if defined(WITH_OPENIMAGEDENOISE) +# if OIDN_VERSION >= 20300 + if (oidn_support) { +# else if (OIDNDenoiserGPU::is_device_supported(info)) { +# endif info.denoisers |= DENOISER_OPENIMAGEDENOISE; } # endif + (void)oidn_support; info.has_gpu_queue = true; diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index 4cb013262f7..f7bffea3b78 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -17,6 +17,13 @@ # include "bvh/embree.h" # endif +# if defined(WITH_OPENIMAGEDENOISE) +# include +# if OIDN_VERSION >= 20300 +# include "util/openimagedenoise.h" +# endif +# endif + # include "kernel/device/oneapi/globals.h" # include "kernel/device/oneapi/kernel.h" @@ -1107,12 +1114,17 @@ void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_p bool hwrt_support = rtcIsSYCLDeviceSupported(device); # else bool hwrt_support = false; +# endif +# if defined(WITH_OPENIMAGEDENOISE) && OIDN_VERSION >= 20300 + bool oidn_support = oidnIsSYCLDeviceSupported(&device); +# else + bool oidn_support = false; # endif std::string id = "ONEAPI_" + platform_name + "_" + name; if (device.has(sycl::aspect::ext_intel_pci_address)) { id.append("_" + device.get_info()); } - (cb)(id.c_str(), name.c_str(), num, hwrt_support, user_ptr); + (cb)(id.c_str(), name.c_str(), num, hwrt_support, oidn_support, user_ptr); num++; } } diff --git a/intern/cycles/device/oneapi/device_impl.h b/intern/cycles/device/oneapi/device_impl.h index 5c7d6485d0c..11d5acf6a5d 100644 --- a/intern/cycles/device/oneapi/device_impl.h +++ b/intern/cycles/device/oneapi/device_impl.h @@ -14,8 +14,12 @@ CCL_NAMESPACE_BEGIN class DeviceQueue; -typedef void (*OneAPIDeviceIteratorCallback)( - const char *id, const char *name, int num, bool hwrt_support, void *user_ptr); +typedef void (*OneAPIDeviceIteratorCallback)(const char *id, + const char *name, + int num, + bool hwrt_support, + bool oidn_support, + void *user_ptr); class OneapiDevice : public Device { private: diff --git a/intern/cycles/device/optix/device.cpp b/intern/cycles/device/optix/device.cpp index 5431ea79da4..283f23e40ee 100644 --- a/intern/cycles/device/optix/device.cpp +++ b/intern/cycles/device/optix/device.cpp @@ -79,7 +79,11 @@ void device_optix_info(const vector &cuda_devices, vector= 20300 + if (oidnIsCUDADeviceSupported(info.num)) { +# else if (OIDNDenoiserGPU::is_device_supported(info)) { +# endif info.denoisers |= DENOISER_OPENIMAGEDENOISE; } # endif diff --git a/intern/cycles/integrator/denoiser_oidn_gpu.cpp b/intern/cycles/integrator/denoiser_oidn_gpu.cpp index b516aa65be1..c2b1f40a572 100644 --- a/intern/cycles/integrator/denoiser_oidn_gpu.cpp +++ b/intern/cycles/integrator/denoiser_oidn_gpu.cpp @@ -15,7 +15,6 @@ # include "session/buffers.h" # include "util/array.h" # include "util/log.h" -# include "util/openimagedenoise.h" # include "kernel/device/cpu/compat.h" # include "kernel/device/cpu/kernel.h" @@ -28,6 +27,7 @@ CCL_NAMESPACE_BEGIN +# if OIDN_VERSION < 20300 static const char *oidn_device_type_to_string(const OIDNDeviceType type) { switch (type) { @@ -37,26 +37,40 @@ static const char *oidn_device_type_to_string(const OIDNDeviceType type) return "CPU"; /* The initial GPU support was added in OIDN 2.0. */ -# if OIDN_VERSION_MAJOR >= 2 +# if OIDN_VERSION_MAJOR >= 2 case OIDN_DEVICE_TYPE_SYCL: return "SYCL"; case OIDN_DEVICE_TYPE_CUDA: return "CUDA"; case OIDN_DEVICE_TYPE_HIP: return "HIP"; -# endif +# endif /* The Metal support was added in OIDN 2.2. */ -# if (OIDN_VERSION_MAJOR > 2) || ((OIDN_VERSION_MAJOR == 2) && (OIDN_VERSION_MINOR >= 2)) +# if (OIDN_VERSION_MAJOR > 2) || ((OIDN_VERSION_MAJOR == 2) && (OIDN_VERSION_MINOR >= 2)) case OIDN_DEVICE_TYPE_METAL: return "METAL"; -# endif +# endif } return "UNKNOWN"; } +# endif bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device) { +# if OIDN_VERSION >= 20300 + if (device.type == DEVICE_MULTI) { + for (const DeviceInfo &multi_device : device.multi_devices) { + if (multi_device.type != DEVICE_CPU && multi_device.denoisers & DENOISER_OPENIMAGEDENOISE) { + return true; + } + } + + return false; + } + + return device.denoisers & DENOISER_OPENIMAGEDENOISE; +# else if (device.type == DEVICE_MULTI) { for (const DeviceInfo &multi_device : device.multi_devices) { if (multi_device.type != DEVICE_CPU && is_device_supported(multi_device)) { @@ -72,23 +86,23 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device) int device_type = OIDN_DEVICE_TYPE_DEFAULT; switch (device.type) { -# ifdef OIDN_DEVICE_SYCL +# ifdef OIDN_DEVICE_SYCL case DEVICE_ONEAPI: device_type = OIDN_DEVICE_TYPE_SYCL; break; -# endif -# ifdef OIDN_DEVICE_HIP +# endif +# ifdef OIDN_DEVICE_HIP case DEVICE_HIP: device_type = OIDN_DEVICE_TYPE_HIP; break; -# endif -# ifdef OIDN_DEVICE_CUDA +# endif +# ifdef OIDN_DEVICE_CUDA case DEVICE_CUDA: case DEVICE_OPTIX: device_type = OIDN_DEVICE_TYPE_CUDA; break; -# endif -# ifdef OIDN_DEVICE_METAL +# endif +# ifdef OIDN_DEVICE_METAL case DEVICE_METAL: { const int num_devices = oidnGetNumPhysicalDevices(); VLOG_DEBUG << "Found " << num_devices << " OIDN device(s)"; @@ -107,7 +121,7 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device) VLOG_DEBUG << "No matched OIDN device found"; return false; } -# endif +# endif case DEVICE_CPU: /* This is the GPU denoiser - CPU devices shouldn't end up here. */ assert(0); @@ -142,6 +156,7 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device) } VLOG_DEBUG << "No matched OIDN device found"; return false; +# endif } OIDNDenoiserGPU::OIDNDenoiserGPU(Device *path_trace_device, const DenoiseParams ¶ms) diff --git a/intern/cycles/integrator/denoiser_oidn_gpu.h b/intern/cycles/integrator/denoiser_oidn_gpu.h index bec026bfae7..0cea7a8a916 100644 --- a/intern/cycles/integrator/denoiser_oidn_gpu.h +++ b/intern/cycles/integrator/denoiser_oidn_gpu.h @@ -7,13 +7,10 @@ #if defined(WITH_OPENIMAGEDENOISE) # include "integrator/denoiser_gpu.h" +# include "util/openimagedenoise.h" # include "util/thread.h" # include "util/unique_ptr.h" -typedef struct OIDNDeviceImpl *OIDNDevice; -typedef struct OIDNFilterImpl *OIDNFilter; -typedef struct OIDNBufferImpl *OIDNBuffer; - CCL_NAMESPACE_BEGIN /* Implementation of a GPU denoiser which uses OpenImageDenoise library. */