Cycles: Enable HIP devices for OpenImageDenoise

This enables the HIP backend of OpenImageDenoise on supported devices.

Co-authored-by: Werner, Stefan <stefan.werner@intel.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/115854
This commit is contained in:
Stefan Werner
2023-12-13 21:38:19 +01:00
parent f372ac6f61
commit fd8bb41224
4 changed files with 61 additions and 4 deletions

View File

@@ -14,6 +14,7 @@ if(NOT APPLE)
${OIDN_EXTRA_ARGS}
-DOIDN_DEVICE_SYCL=ON
-DOIDN_DEVICE_SYCL_AOT=OFF
-DOIDN_DEVICE_HIP=ON
-DLEVEL_ZERO_ROOT=${LIBDIR}/level-zero/lib
)
endif()

View File

@@ -10,6 +10,8 @@
# include "device/device.h"
# include "device/hip/device_impl.h"
# include "integrator/denoiser_oidn_gpu.h"
# include "util/string.h"
# include "util/windows.h"
#endif /* WITH_HIP */
@@ -158,6 +160,11 @@ void device_hip_info(vector<DeviceInfo> &devices)
info.has_light_tree = true;
info.has_mnee = true;
info.denoisers = 0;
# if defined(WITH_OPENIMAGEDENOISE)
if (OIDNDenoiserGPU::is_device_supported(info)) {
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
info.has_gpu_queue = true;
/* Check if the device has P2P access to any other device in the system. */

View File

@@ -27,7 +27,9 @@ unique_ptr<Denoiser> Denoiser::create(Device *path_trace_device, const DenoisePa
#endif
#ifdef WITH_OPENIMAGEDENOISE
if (params.type == DENOISER_OPENIMAGEDENOISE && path_trace_device->info.type == DEVICE_ONEAPI) {
if (params.type == DENOISER_OPENIMAGEDENOISE &&
OIDNDenoiserGPU::is_device_supported(path_trace_device->info))
{
return make_unique<OIDNDenoiserGPU>(path_trace_device, params);
}
#endif

View File

@@ -30,16 +30,48 @@ CCL_NAMESPACE_BEGIN
bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
{
/* Currently falls back to checking just the device type, can be improved. */
int device_type = OIDN_DEVICE_TYPE_DEFAULT;
switch (device.type) {
# ifdef OIDN_DEVICE_SYCL
/* Assume all devices with Cycles support are also supported by OIDN2. */
case DEVICE_ONEAPI:
return true;
device_type = OIDN_DEVICE_TYPE_SYCL;
break;
# endif
# ifdef OIDN_DEVICE_HIP
case DEVICE_HIP:
device_type = OIDN_DEVICE_TYPE_HIP;
break;
# endif
# ifdef OIDN_DEVICE_CUDA
case DEVICE_CUDA:
case DEVICE_OPTIX:
device_type = OIDN_DEVICE_TYPE_CUDA;
break;
# endif
case DEVICE_CPU:
/* This is the GPU denoiser - CPU devices shouldn't end up here. */
assert(0);
default:
return false;
}
/* Match GPUs by their PCI ID. */
const int num_devices = oidnGetNumPhysicalDevices();
for (int i = 0; i < num_devices; i++) {
if (oidnGetPhysicalDeviceInt(i, "type") == device_type) {
if (oidnGetPhysicalDeviceBool(i, "pciAddressSupported")) {
unsigned int pci_domain = oidnGetPhysicalDeviceInt(i, "pciDomain");
unsigned int pci_bus = oidnGetPhysicalDeviceInt(i, "pciBus");
unsigned int pci_device = oidnGetPhysicalDeviceInt(i, "pciDevice");
string pci_id = string_printf("%04x:%02x:%02x", pci_domain, pci_bus, pci_device);
if (device.id.find(pci_id) != string::npos) {
return true;
}
}
}
}
return false;
}
OIDNDenoiserGPU::OIDNDenoiserGPU(Device *path_trace_device, const DenoiseParams &params)
@@ -78,6 +110,9 @@ uint OIDNDenoiserGPU::get_device_type_mask() const
uint device_mask = 0;
# ifdef OIDN_DEVICE_SYCL
device_mask |= DEVICE_MASK_ONEAPI;
# endif
# ifdef OIDN_DEVICE_HIP
device_mask |= DEVICE_MASK_HIP;
# endif
return device_mask;
}
@@ -122,15 +157,27 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
1);
denoiser_queue_->init_execution();
break;
# endif
# if defined(OIDN_DEVICE_HIP) && defined(WITH_HIP)
case DEVICE_HIP: {
hipStream_t stream = nullptr;
oidn_device_ = oidnNewHIPDevice(&denoiser_device_->info.num, &stream, 1);
break;
}
# endif
default:
break;
}
if (!oidn_device_) {
denoiser_device_->set_error("Failed to create OIDN device");
return false;
}
if (denoiser_queue_) {
denoiser_queue_->init_execution();
}
oidnCommitDevice(oidn_device_);
oidn_filter_ = create_filter();