Cycles: Allow to choose OIDN denoise device on per-scene basis. #117876
|
@ -216,8 +216,33 @@ enum_guiding_directional_sampling_types = (
|
|||
def enum_openimagedenoise_denoiser(self, context):
|
||||
import _cycles
|
||||
if _cycles.with_openimagedenoise:
|
||||
return [('OPENIMAGEDENOISE', "OpenImageDenoise",
|
||||
"Use Intel OpenImageDenoise AI denoiser", 4)]
|
||||
has_oidn_cpu_devices = False
|
||||
has_oidn_gpu_devices = False
|
||||
|
||||
items = []
|
||||
|
||||
compute_device_type = context.preferences.addons[__package__].preferences.get_compute_device_type()
|
||||
# Blender always add CPU device to list of device of any compute type, so
|
||||
# no need to request CPU devices separately.
|
||||
for device in _cycles.available_devices(compute_device_type):
|
||||
has_oidn_support_in_device = device[5];
|
||||
device_type = device[1]
|
||||
if has_oidn_support_in_device:
|
||||
if device_type == 'CPU':
|
||||
has_oidn_cpu_devices = True
|
||||
else:
|
||||
has_oidn_gpu_devices = True
|
||||
|
||||
if has_oidn_cpu_devices:
|
||||
items.append(('OPENIMAGEDENOISE_CPU', "OpenImageDenoise on CPU",
|
||||
|
||||
"Use Intel OpenImageDenoise AI denoiser on CPU", 4))
|
||||
|
||||
if has_oidn_gpu_devices:
|
||||
items.append(('OPENIMAGEDENOISE_GPU', "OpenImageDenoise on GPU",
|
||||
"Use Intel OpenImageDenoise AI denoiser on GPU", 8))
|
||||
|
||||
return items
|
||||
|
||||
return []
|
||||
|
||||
|
||||
|
|
|
@ -154,7 +154,10 @@ def get_effective_preview_denoiser(context):
|
|||
if context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX'):
|
||||
return 'OPTIX'
|
||||
|
||||
return 'OIDN'
|
||||
if use_cpu(context):
|
||||
return 'OPENIMAGEDENOISE_CPU'
|
||||
else:
|
||||
return 'OPENIMAGEDENOISE_GPU'
|
||||
|
||||
|
||||
def use_mnee(context):
|
||||
|
@ -231,7 +234,7 @@ class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
|
|||
col.prop(cscene, "preview_denoising_input_passes", text="Passes")
|
||||
|
||||
effective_preview_denoiser = get_effective_preview_denoiser(context)
|
||||
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
|
||||
if effective_preview_denoiser == 'OPENIMAGEDENOISE_CPU' or effective_preview_denoiser == 'OPENIMAGEDENOISE_GPU':
|
||||
col.prop(cscene, "preview_denoising_prefilter", text="Prefilter")
|
||||
|
||||
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
||||
|
@ -292,7 +295,7 @@ class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
|
|||
col.active = cscene.use_denoising
|
||||
col.prop(cscene, "denoiser", text="Denoiser")
|
||||
col.prop(cscene, "denoising_input_passes", text="Passes")
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE_CPU' or cscene.denoiser == 'OPENIMAGEDENOISE_GPU':
|
||||
col.prop(cscene, "denoising_prefilter", text="Prefilter")
|
||||
|
||||
|
||||
|
|
|
@ -417,12 +417,16 @@ static PyObject *available_devices_func(PyObject * /*self*/, PyObject *args)
|
|||
for (size_t i = 0; i < devices.size(); i++) {
|
||||
DeviceInfo &device = devices[i];
|
||||
string type_name = Device::string_from_type(device.type);
|
||||
PyObject *device_tuple = PyTuple_New(5);
|
||||
PyObject *device_tuple = PyTuple_New(6);
|
||||
PyTuple_SET_ITEM(device_tuple, 0, pyunicode_from_string(device.description.c_str()));
|
||||
PyTuple_SET_ITEM(device_tuple, 1, pyunicode_from_string(type_name.c_str()));
|
||||
PyTuple_SET_ITEM(device_tuple, 2, pyunicode_from_string(device.id.c_str()));
|
||||
PyTuple_SET_ITEM(device_tuple, 3, PyBool_FromLong(device.has_peer_memory));
|
||||
PyTuple_SET_ITEM(device_tuple, 4, PyBool_FromLong(device.use_hardware_raytracing));
|
||||
PyTuple_SET_ITEM(device_tuple,
|
||||
Nikita Sirgienko
commented
|
||||
5,
|
||||
PyBool_FromLong(device.denoisers & (DENOISER_OPENIMAGEDENOISE_CPU |
|
||||
DENOISER_OPENIMAGEDENOISE_GPU)));
|
||||
PyTuple_SET_ITEM(ret, i, device_tuple);
|
||||
}
|
||||
|
||||
|
|
|
@ -997,11 +997,20 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
|||
|
||||
/* Auto select fastest denoiser. */
|
||||
if (denoising.type == DENOISER_NONE) {
|
||||
if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) {
|
||||
const vector<DeviceInfo> devices = Device::available_devices();
|
||||
ccl::DenoiserTypeMask denoiser_mask_all = DENOISER_NONE;
|
||||
for (const DeviceInfo &device : devices) {
|
||||
denoiser_mask_all |= device.denoisers;
|
||||
}
|
||||
|
||||
if (denoiser_mask_all & DENOISER_OPTIX) {
|
||||
denoising.type = DENOISER_OPTIX;
|
||||
}
|
||||
else if (openimagedenoise_supported()) {
|
||||
denoising.type = DENOISER_OPENIMAGEDENOISE;
|
||||
else if (denoiser_mask_all & DENOISER_OPENIMAGEDENOISE_GPU) {
|
||||
denoising.type = DENOISER_OPENIMAGEDENOISE_GPU;
|
||||
}
|
||||
else if (denoiser_mask_all & DENOISER_OPENIMAGEDENOISE_CPU) {
|
||||
denoising.type = DENOISER_OPENIMAGEDENOISE_CPU;
|
||||
}
|
||||
else {
|
||||
denoising.use = false;
|
||||
|
|
|
@ -37,7 +37,7 @@ void device_cpu_info(vector<DeviceInfo> &devices)
|
|||
info.has_guiding = false;
|
||||
}
|
||||
if (openimagedenoise_supported()) {
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE_CPU;
|
||||
}
|
||||
|
||||
devices.insert(devices.begin(), info);
|
||||
|
|
|
@ -166,7 +166,7 @@ void device_cuda_info(vector<DeviceInfo> &devices)
|
|||
|
||||
# if defined(WITH_OPENIMAGEDENOISE)
|
||||
if (OIDNDenoiserGPU::is_device_supported(info)) {
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE_GPU;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@ const char *denoiserTypeToHumanReadable(DenoiserType type)
|
|||
switch (type) {
|
||||
case DENOISER_OPTIX:
|
||||
return "OptiX";
|
||||
case DENOISER_OPENIMAGEDENOISE:
|
||||
return "OpenImageDenoise";
|
||||
case DENOISER_OPENIMAGEDENOISE_CPU:
|
||||
return "OpenImageDenoise on CPU";
|
||||
case DENOISER_OPENIMAGEDENOISE_GPU:
|
||||
return "OpenImageDenoise on GPU";
|
||||
|
||||
case DENOISER_NUM:
|
||||
case DENOISER_NONE:
|
||||
|
@ -29,7 +31,8 @@ const NodeEnum *DenoiseParams::get_type_enum()
|
|||
|
||||
if (type_enum.empty()) {
|
||||
type_enum.insert("optix", DENOISER_OPTIX);
|
||||
type_enum.insert("openimageio", DENOISER_OPENIMAGEDENOISE);
|
||||
type_enum.insert("openimagedenoise_cpu", DENOISER_OPENIMAGEDENOISE_CPU);
|
||||
type_enum.insert("openimagedenoise_gpu", DENOISER_OPENIMAGEDENOISE_GPU);
|
||||
}
|
||||
|
||||
return &type_enum;
|
||||
|
@ -57,7 +60,7 @@ NODE_DEFINE(DenoiseParams)
|
|||
|
||||
SOCKET_BOOLEAN(use, "Use", false);
|
||||
|
||||
SOCKET_ENUM(type, "Type", *type_enum, DENOISER_OPENIMAGEDENOISE);
|
||||
SOCKET_ENUM(type, "Type", *type_enum, DENOISER_OPENIMAGEDENOISE_CPU);
|
||||
|
||||
SOCKET_INT(start_sample, "Start Sample", 0);
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
enum DenoiserType {
|
||||
DENOISER_OPTIX = 2,
|
||||
DENOISER_OPENIMAGEDENOISE = 4,
|
||||
DENOISER_OPENIMAGEDENOISE_CPU = 4,
|
||||
DENOISER_OPENIMAGEDENOISE_GPU = 8,
|
||||
DENOISER_NUM,
|
||||
|
||||
DENOISER_NONE = 0,
|
||||
|
@ -51,7 +52,7 @@ class DenoiseParams : public Node {
|
|||
bool use = false;
|
||||
|
||||
/* Denoiser type. */
|
||||
DenoiserType type = DENOISER_OPENIMAGEDENOISE;
|
||||
DenoiserType type = DENOISER_OPENIMAGEDENOISE_CPU;
|
||||
|
||||
/* Viewport start sample. */
|
||||
int start_sample = 0;
|
||||
|
|
|
@ -185,7 +185,7 @@ void device_hip_info(vector<DeviceInfo> &devices)
|
|||
info.denoisers = 0;
|
||||
# if defined(WITH_OPENIMAGEDENOISE)
|
||||
if (OIDNDenoiserGPU::is_device_supported(info)) {
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE_GPU;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ static void device_iterator_cb(
|
|||
info.has_nanovdb = true;
|
||||
# if defined(WITH_OPENIMAGEDENOISE)
|
||||
if (OIDNDenoiserGPU::is_device_supported(info)) {
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE_GPU;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
|
|||
info.denoisers |= DENOISER_OPTIX;
|
||||
# if defined(WITH_OPENIMAGEDENOISE)
|
||||
if (OIDNDenoiserGPU::is_device_supported(info)) {
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE_GPU;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
|
@ -21,22 +21,26 @@ unique_ptr<Denoiser> Denoiser::create(Device *path_trace_device, const DenoisePa
|
|||
DCHECK(params.use);
|
||||
|
||||
#ifdef WITH_OPTIX
|
||||
if (params.type == DENOISER_OPTIX && Device::available_devices(DEVICE_MASK_OPTIX).size()) {
|
||||
bool has_optix_denoise_device = Device::available_devices(DEVICE_MASK_OPTIX).size();
|
||||
if (params.type == DENOISER_OPTIX && has_optix_denoise_device) {
|
||||
return make_unique<OptiXDenoiser>(path_trace_device, params);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENIMAGEDENOISE
|
||||
if (params.type == DENOISER_OPENIMAGEDENOISE && path_trace_device->info.type != DEVICE_CPU &&
|
||||
OIDNDenoiserGPU::is_device_supported(path_trace_device->info))
|
||||
{
|
||||
const ccl::vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_ALL);
|
||||
bool has_oidn_gpu_denoise_device = false;
|
||||
for (const DeviceInfo device : devices) {
|
||||
has_oidn_gpu_denoise_device |= device.denoisers & DENOISER_OPENIMAGEDENOISE_GPU;
|
||||
}
|
||||
if (params.type == DENOISER_OPENIMAGEDENOISE_GPU && has_oidn_gpu_denoise_device) {
|
||||
return make_unique<OIDNDenoiserGPU>(path_trace_device, params);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Always fallback to OIDN. */
|
||||
DenoiseParams oidn_params = params;
|
||||
oidn_params.type = DENOISER_OPENIMAGEDENOISE;
|
||||
oidn_params.type = DENOISER_OPENIMAGEDENOISE_CPU;
|
||||
return make_unique<OIDNDenoiser>(path_trace_device, oidn_params);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ thread_mutex OIDNDenoiser::mutex_;
|
|||
OIDNDenoiser::OIDNDenoiser(Device *path_trace_device, const DenoiseParams ¶ms)
|
||||
: Denoiser(path_trace_device, params)
|
||||
{
|
||||
DCHECK_EQ(params.type, DENOISER_OPENIMAGEDENOISE);
|
||||
DCHECK_EQ(params.type, DENOISER_OPENIMAGEDENOISE_CPU);
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENIMAGEDENOISE
|
||||
|
|
|
@ -77,7 +77,7 @@ bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
|
|||
OIDNDenoiserGPU::OIDNDenoiserGPU(Device *path_trace_device, const DenoiseParams ¶ms)
|
||||
: DenoiserGPU(path_trace_device, params)
|
||||
{
|
||||
DCHECK_EQ(params.type, DENOISER_OPENIMAGEDENOISE);
|
||||
DCHECK_EQ(params.type, DENOISER_OPENIMAGEDENOISE_GPU);
|
||||
}
|
||||
|
||||
OIDNDenoiserGPU::~OIDNDenoiserGPU()
|
||||
|
|
|
@ -129,7 +129,8 @@ NODE_DEFINE(Integrator)
|
|||
|
||||
static NodeEnum denoiser_type_enum;
|
||||
denoiser_type_enum.insert("optix", DENOISER_OPTIX);
|
||||
denoiser_type_enum.insert("openimagedenoise", DENOISER_OPENIMAGEDENOISE);
|
||||
denoiser_type_enum.insert("openimagedenoise_cpu", DENOISER_OPENIMAGEDENOISE_CPU);
|
||||
denoiser_type_enum.insert("openimagedenoise_gpu", DENOISER_OPENIMAGEDENOISE_GPU);
|
||||
|
||||
static NodeEnum denoiser_prefilter_enum;
|
||||
denoiser_prefilter_enum.insert("none", DENOISER_PREFILTER_NONE);
|
||||
|
@ -140,7 +141,7 @@ NODE_DEFINE(Integrator)
|
|||
* it's best use OptiX and disable the normal pass since it does not always have
|
||||
* the desired effect for that denoiser. */
|
||||
SOCKET_BOOLEAN(use_denoise, "Use Denoiser", false);
|
||||
SOCKET_ENUM(denoiser_type, "Denoiser Type", denoiser_type_enum, DENOISER_OPENIMAGEDENOISE);
|
||||
SOCKET_ENUM(denoiser_type, "Denoiser Type", denoiser_type_enum, DENOISER_OPENIMAGEDENOISE_CPU);
|
||||
SOCKET_INT(denoise_start_sample, "Start Sample to Denoise", 0);
|
||||
SOCKET_BOOLEAN(use_denoise_pass_albedo, "Use Albedo Pass for Denoiser", true);
|
||||
SOCKET_BOOLEAN(use_denoise_pass_normal, "Use Normal Pass for Denoiser", true);
|
||||
|
|
Loading…
Reference in New Issue
"OpenImageDenoise on CPU" or "OpenImageDenoise on GPU" are not exactly fully fitting in the default panel width, likely worth to change the default value in order to fit this strings fully, or use more short one.