Cycles: Option to disable OpenImageDenoise GPU per scene
To reduce memory usage if needed. Pull Request: https://projects.blender.org/blender/blender/pulls/117874
This commit is contained in:
parent
acdc3deaea
commit
bc886857f3
@ -352,6 +352,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO_NORMAL',
|
||||
)
|
||||
denoising_use_gpu: BoolProperty(
|
||||
name="Denoise on GPU",
|
||||
description="Perform denoising on GPU devices, if available. This is significantly faster than on CPU, but requires additional GPU memory. When large scenes need more GPU memory, this option can be disabled",
|
||||
default=True,
|
||||
)
|
||||
|
||||
use_preview_denoising: BoolProperty(
|
||||
name="Use Viewport Denoising",
|
||||
@ -382,6 +387,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
min=0, max=(1 << 24),
|
||||
default=1,
|
||||
)
|
||||
preview_denoising_use_gpu: BoolProperty(
|
||||
name="Denoise Preview on GPU",
|
||||
description="Perform denoising on GPU devices, if available. This is significantly faster than on CPU, but requires additional GPU memory. When large scenes need more GPU memory, this option can be disabled",
|
||||
default=True,
|
||||
)
|
||||
|
||||
samples: IntProperty(
|
||||
name="Samples",
|
||||
@ -1591,6 +1601,22 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
def has_active_device(self):
|
||||
return self.get_num_gpu_devices() > 0
|
||||
|
||||
def has_oidn_gpu_devices(self):
|
||||
import _cycles
|
||||
compute_device_type = context.preferences.addons[__package__].preferences.get_compute_device_type()
|
||||
|
||||
# We need non-CPU devices, used for rendering and supporting OIDN GPU denoising
|
||||
for device in _cycles.available_devices(compute_device_type):
|
||||
device_type = device[1]
|
||||
if device_type == 'CPU':
|
||||
continue
|
||||
|
||||
has_device_oidn_support = device[5]
|
||||
if has_device_oidn_support and self.find_existing_device_entry(device).use:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _draw_devices(self, layout, device_type, devices):
|
||||
box = layout.box()
|
||||
|
||||
|
@ -123,7 +123,6 @@ def use_optix(context):
|
||||
|
||||
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU' and backend_has_active_gpu(context))
|
||||
|
||||
|
||||
def use_oneapi(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
@ -156,6 +155,9 @@ def get_effective_preview_denoiser(context):
|
||||
|
||||
return 'OIDN'
|
||||
|
||||
def has_oidn_gpu_devices(context):
|
||||
return context.preferences.addons[__package__].preferences.has_oidn_gpu_devices()
|
||||
|
||||
|
||||
def use_mnee(context):
|
||||
# The MNEE kernel doesn't compile on macOS < 13.
|
||||
@ -236,6 +238,11 @@ class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
|
||||
|
||||
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
||||
|
||||
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
|
||||
row = col.row()
|
||||
row.active = not use_cpu(context) and has_oidn_gpu_devices(context)
|
||||
row.prop(cscene, "preview_denoising_use_gpu", text="Use GPU")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_render(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
@ -295,6 +302,11 @@ class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||
col.prop(cscene, "denoising_prefilter", text="Prefilter")
|
||||
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||
row = col.row()
|
||||
row.active = not use_cpu(context) and has_oidn_gpu_devices(context)
|
||||
row.prop(cscene, "denoising_use_gpu", text="Use GPU")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Path Guiding"
|
||||
|
@ -417,12 +417,14 @@ 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, 5, PyBool_FromLong(device.denoisers & DENOISER_OPENIMAGEDENOISE));
|
||||
PyTuple_SET_ITEM(ret, i, device_tuple);
|
||||
}
|
||||
|
||||
|
@ -474,6 +474,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
* is that the interface and the integrator are technically out of sync. */
|
||||
if (denoise_params.use) {
|
||||
integrator->set_denoiser_type(denoise_params.type);
|
||||
integrator->set_denoise_use_gpu(denoise_params.use_gpu);
|
||||
integrator->set_denoise_start_sample(denoise_params.start_sample);
|
||||
integrator->set_use_denoise_pass_albedo(denoise_params.use_pass_albedo);
|
||||
integrator->set_use_denoise_pass_normal(denoise_params.use_pass_normal);
|
||||
@ -970,6 +971,7 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
/* Final Render Denoising */
|
||||
denoising.use = get_boolean(cscene, "use_denoising");
|
||||
denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||
denoising.use_gpu = get_boolean(cscene, "denoising_use_gpu");
|
||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||
cscene, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE);
|
||||
|
||||
@ -988,6 +990,7 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
denoising.use = get_boolean(cscene, "use_preview_denoising");
|
||||
denoising.type = (DenoiserType)get_enum(
|
||||
cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||
denoising.use_gpu = get_boolean(cscene, "preview_denoising_use_gpu");
|
||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||
cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST);
|
||||
denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
|
||||
|
@ -63,6 +63,11 @@ class DenoiseParams : public Node {
|
||||
/* Configure the denoiser to use motion vectors, previous image and a temporally stable model. */
|
||||
bool temporally_stable = false;
|
||||
|
||||
/* If true, then allow, if supported, OpenImageDenoise to use GPU device.
|
||||
* If false, then OpenImageDenoise will always use CPU regardless of GPU device
|
||||
* precense. */
|
||||
bool use_gpu = true;
|
||||
|
||||
DenoiserPrefilter prefilter = DENOISER_PREFILTER_FAST;
|
||||
|
||||
static const NodeEnum *get_type_enum();
|
||||
@ -75,7 +80,8 @@ class DenoiseParams : public Node {
|
||||
return !(use == other.use && type == other.type && start_sample == other.start_sample &&
|
||||
use_pass_albedo == other.use_pass_albedo &&
|
||||
use_pass_normal == other.use_pass_normal &&
|
||||
temporally_stable == other.temporally_stable && prefilter == other.prefilter);
|
||||
temporally_stable == other.temporally_stable && use_gpu == other.use_gpu &&
|
||||
prefilter == other.prefilter);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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_CPU &&
|
||||
/* If available and allowed, then we will use OpenImageDenoise on GPU, otherwise on CPU. */
|
||||
if (params.type == DENOISER_OPENIMAGEDENOISE && params.use_gpu &&
|
||||
path_trace_device->info.type != DEVICE_CPU &&
|
||||
OIDNDenoiserGPU::is_device_supported(path_trace_device->info))
|
||||
{
|
||||
return make_unique<OIDNDenoiserGPU>(path_trace_device, params);
|
||||
|
@ -148,6 +148,7 @@ NODE_DEFINE(Integrator)
|
||||
"Denoiser Prefilter",
|
||||
denoiser_prefilter_enum,
|
||||
DENOISER_PREFILTER_ACCURATE);
|
||||
SOCKET_BOOLEAN(denoise_use_gpu, "Denoise on GPU", true);
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -393,6 +394,8 @@ DenoiseParams Integrator::get_denoise_params() const
|
||||
|
||||
denoise_params.type = denoiser_type;
|
||||
|
||||
denoise_params.use_gpu = denoise_use_gpu;
|
||||
|
||||
denoise_params.start_sample = denoise_start_sample;
|
||||
|
||||
denoise_params.use_pass_albedo = use_denoise_pass_albedo;
|
||||
|
@ -98,6 +98,7 @@ class Integrator : public Node {
|
||||
NODE_SOCKET_API(bool, use_denoise_pass_albedo);
|
||||
NODE_SOCKET_API(bool, use_denoise_pass_normal);
|
||||
NODE_SOCKET_API(DenoiserPrefilter, denoiser_prefilter);
|
||||
NODE_SOCKET_API(bool, denoise_use_gpu);
|
||||
|
||||
enum : uint32_t {
|
||||
AO_PASS_MODIFIED = (1 << 0),
|
||||
|
Loading…
Reference in New Issue
Block a user