Cycles: Use denoising device info to pick automatic denoiser

Ever since the introduction of GPU OIDN denoising on CPU devices,
using the path_tracing_device info to pick the automatic denoiser has
typically led to incorrect results.

This commit fixes this issue by using the denoising device info to pick
the denoiser.

Pull Request: https://projects.blender.org/blender/blender/pulls/123593
This commit is contained in:
Alaska 2024-06-24 11:28:02 +02:00 committed by Brecht Van Lommel
parent 37e2a27bdd
commit 9e267bbd57
5 changed files with 18 additions and 16 deletions

@ -405,7 +405,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
width, width,
height, height,
&python_thread_state, &python_thread_state,
session_params.device); session_params.denoise_device);
/* At the moment we only free if we are not doing multi-view /* At the moment we only free if we are not doing multi-view
* (or if we are rendering the last view). See #58142/D4239 for discussion. * (or if we are rendering the last view). See #58142/D4239 for discussion.
@ -702,7 +702,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
width, width,
height, height,
&python_thread_state, &python_thread_state,
session_params.device); session_params.denoise_device);
/* Save the current state of the denoiser, as it might be disabled by the pass configuration (for /* Save the current state of the denoiser, as it might be disabled by the pass configuration (for
* passed which do not support denoising). */ * passed which do not support denoising). */
@ -827,7 +827,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
width, width,
height, height,
&python_thread_state, &python_thread_state,
session_params.device); session_params.denoise_device);
if (b_rv3d) { if (b_rv3d) {
sync->sync_view(b_v3d, b_rv3d, width, height); sync->sync_view(b_v3d, b_rv3d, width, height);

@ -254,7 +254,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
int width, int width,
int height, int height,
void **python_thread_state, void **python_thread_state,
const DeviceInfo &device_info) const DeviceInfo &denoise_device_info)
{ {
/* For auto refresh images. */ /* For auto refresh images. */
ImageManager *image_manager = scene->image_manager; ImageManager *image_manager = scene->image_manager;
@ -274,7 +274,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
const bool background = !b_v3d; const bool background = !b_v3d;
sync_view_layer(b_view_layer); sync_view_layer(b_view_layer);
sync_integrator(b_view_layer, background, device_info); sync_integrator(b_view_layer, background, denoise_device_info);
sync_film(b_view_layer, b_v3d); sync_film(b_view_layer, b_v3d);
sync_shaders(b_depsgraph, b_v3d, auto_refresh_update); sync_shaders(b_depsgraph, b_v3d, auto_refresh_update);
sync_images(); sync_images();
@ -303,7 +303,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer,
bool background, bool background,
const DeviceInfo &device_info) const DeviceInfo &denoise_device_info)
{ {
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@ -488,7 +488,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer,
} }
DenoiseParams denoise_params = get_denoise_params( DenoiseParams denoise_params = get_denoise_params(
b_scene, b_view_layer, background, device_info); b_scene, b_view_layer, background, denoise_device_info);
/* No denoising support for vertex color baking, vertices packed into image /* No denoising support for vertex color baking, vertices packed into image
* buffer have no relation to neighbors. */ * buffer have no relation to neighbors. */
@ -990,7 +990,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene, DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
BL::ViewLayer &b_view_layer, BL::ViewLayer &b_view_layer,
bool background, bool background,
const DeviceInfo &device_info) const DeviceInfo &denoise_device_info)
{ {
enum DenoiserInput { enum DenoiserInput {
DENOISER_INPUT_RGB = 1, DENOISER_INPUT_RGB = 1,
@ -1042,7 +1042,7 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
/* Auto select fastest denoiser. */ /* Auto select fastest denoiser. */
if (denoising.type == DENOISER_NONE) { if (denoising.type == DENOISER_NONE) {
denoising.type = Denoiser::automatic_viewport_denoiser_type(device_info); denoising.type = Denoiser::automatic_viewport_denoiser_type(denoise_device_info);
if (denoising.type == DENOISER_NONE) { if (denoising.type == DENOISER_NONE) {
denoising.use = false; denoising.use = false;
} }

@ -66,12 +66,12 @@ class BlenderSync {
int width, int width,
int height, int height,
void **python_thread_state, void **python_thread_state,
const DeviceInfo &device_info); const DeviceInfo &denoise_device_info);
void sync_view_layer(BL::ViewLayer &b_view_layer); void sync_view_layer(BL::ViewLayer &b_view_layer);
void sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer); void sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer);
void sync_integrator(BL::ViewLayer &b_view_layer, void sync_integrator(BL::ViewLayer &b_view_layer,
bool background, bool background,
const DeviceInfo &device_info); const DeviceInfo &denoise_device_info);
void sync_camera(BL::RenderSettings &b_render, void sync_camera(BL::RenderSettings &b_render,
BL::Object &b_override, BL::Object &b_override,
int width, int width,
@ -105,7 +105,7 @@ class BlenderSync {
static DenoiseParams get_denoise_params(BL::Scene &b_scene, static DenoiseParams get_denoise_params(BL::Scene &b_scene,
BL::ViewLayer &b_view_layer, BL::ViewLayer &b_view_layer,
bool background, bool background,
const DeviceInfo &device); const DeviceInfo &denoise_device);
private: private:
/* sync */ /* sync */

@ -122,14 +122,16 @@ unique_ptr<Denoiser> Denoiser::create(Device *denoiser_device,
is_cpu_denoiser_device ? single_denoiser_device : cpu_fallback_device, oidn_params); is_cpu_denoiser_device ? single_denoiser_device : cpu_fallback_device, oidn_params);
} }
DenoiserType Denoiser::automatic_viewport_denoiser_type(const DeviceInfo &path_trace_device_info) DenoiserType Denoiser::automatic_viewport_denoiser_type(const DeviceInfo &denoise_device_info)
{ {
#ifdef WITH_OPENIMAGEDENOISE #ifdef WITH_OPENIMAGEDENOISE
if (OIDNDenoiserGPU::is_device_supported(path_trace_device_info)) { if (denoise_device_info.type != DEVICE_CPU &&
OIDNDenoiserGPU::is_device_supported(denoise_device_info))
{
return DENOISER_OPENIMAGEDENOISE; return DENOISER_OPENIMAGEDENOISE;
} }
#else #else
(void)path_trace_device_info; (void)denoise_device_info;
#endif #endif
#ifdef WITH_OPTIX #ifdef WITH_OPTIX

@ -45,7 +45,7 @@ class Denoiser {
const DenoiseParams &get_params() const; const DenoiseParams &get_params() const;
/* Recommended type for viewport denoising. */ /* Recommended type for viewport denoising. */
static DenoiserType automatic_viewport_denoiser_type(const DeviceInfo &path_trace_device_info); static DenoiserType automatic_viewport_denoiser_type(const DeviceInfo &denoise_device_info);
/* Create devices and load kernels needed for denoising. /* Create devices and load kernels needed for denoising.
* The progress is used to communicate state when kernels actually needs to be loaded. * The progress is used to communicate state when kernels actually needs to be loaded.