[Bf-blender-cvs] [aa81152dd90] cycles-x: Fix missing result when cancelling render with denoiser in Cycles X

Sergey Sharybin noreply at git.blender.org
Tue Aug 31 15:15:17 CEST 2021


Commit: aa81152dd90f0cfaf40f68fa27f985491804ada5
Author: Sergey Sharybin
Date:   Fri Aug 27 12:41:17 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBaa81152dd90f0cfaf40f68fa27f985491804ada5

Fix missing result when cancelling render with denoiser in Cycles X

OIDN will stop demoising when user cancel is requested. This might
leave render buffers in a partially updated state, so the tile write
logic will wrongly assume denoised result exists.

Differential Revision: https://developer.blender.org/D12334

===================================================================

M	intern/cycles/device/device.h
M	intern/cycles/device/optix/device_impl.cpp
M	intern/cycles/device/optix/device_impl.h
M	intern/cycles/integrator/denoiser.h
M	intern/cycles/integrator/denoiser_device.cpp
M	intern/cycles/integrator/denoiser_device.h
M	intern/cycles/integrator/denoiser_oidn.cpp
M	intern/cycles/integrator/denoiser_oidn.h
M	intern/cycles/integrator/path_trace.cpp

===================================================================

diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 4413e02039d..1397214c897 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -222,10 +222,11 @@ class Device {
 
   /* Buffer denoising. */
 
-  /* TODO(sergey): Need to pass real parameters needed for denoising. */
-  virtual void denoise_buffer(const DeviceDenoiseTask & /*task*/)
+  /* Returns true if task is fully handled. */
+  virtual bool denoise_buffer(const DeviceDenoiseTask & /*task*/)
   {
     LOG(ERROR) << "Request buffer denoising from a device which does not support it.";
+    return false;
   }
 
   virtual DeviceQueue *get_denoise_queue()
diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp
index 60c2175937a..7f78b458038 100644
--- a/intern/cycles/device/optix/device_impl.cpp
+++ b/intern/cycles/device/optix/device_impl.cpp
@@ -613,19 +613,19 @@ class OptiXDevice::DenoisePass {
   bool use_denoising_albedo;
 };
 
-void OptiXDevice::denoise_buffer(const DeviceDenoiseTask &task)
+bool OptiXDevice::denoise_buffer(const DeviceDenoiseTask &task)
 {
   const CUDAContextScope scope(this);
 
   DenoiseContext context(this, task);
 
   if (!denoise_ensure(context)) {
-    return;
+    return false;
   }
 
   if (!denoise_filter_guiding_preprocess(context)) {
     LOG(ERROR) << "Error preprocessing guiding passes.";
-    return;
+    return false;
   }
 
   /* Passes which will use real albedo when it is available. */
@@ -634,6 +634,8 @@ void OptiXDevice::denoise_buffer(const DeviceDenoiseTask &task)
 
   /* Passes which do not need albedo and hence if real is present it needs to become fake. */
   denoise_pass(context, PASS_SHADOW_CATCHER);
+
+  return true;
 }
 
 DeviceQueue *OptiXDevice::get_denoise_queue()
diff --git a/intern/cycles/device/optix/device_impl.h b/intern/cycles/device/optix/device_impl.h
index d5f1912b091..742ae0f1bab 100644
--- a/intern/cycles/device/optix/device_impl.h
+++ b/intern/cycles/device/optix/device_impl.h
@@ -140,7 +140,7 @@ class OptiXDevice : public CUDADevice {
   class DenoiseContext;
   class DenoisePass;
 
-  virtual void denoise_buffer(const DeviceDenoiseTask &task) override;
+  virtual bool denoise_buffer(const DeviceDenoiseTask &task) override;
   virtual DeviceQueue *get_denoise_queue() override;
 
   /* Read guiding passes from the render buffers, preprocess them in a way which is expected by
diff --git a/intern/cycles/integrator/denoiser.h b/intern/cycles/integrator/denoiser.h
index 0995c00bebb..3101b45e31b 100644
--- a/intern/cycles/integrator/denoiser.h
+++ b/intern/cycles/integrator/denoiser.h
@@ -76,8 +76,11 @@ class Denoiser {
    * The `allow_inplace_modification` means that the denoiser is allowed to do in-place
    * modification of the input passes (scaling them down i.e.). This will lower the memory
    * footprint of the denoiser but will make input passes "invalid" (from path tracer) point of
-   * view. */
-  virtual void denoise_buffer(const BufferParams &buffer_params,
+   * view.
+   *
+   * Returns true when all passes are denoised. Will return false if there is a denoiser error (for
+   * example, caused by misconfigured denoiser) or when user requested to cancel rendering. */
+  virtual bool denoise_buffer(const BufferParams &buffer_params,
                               RenderBuffers *render_buffers,
                               const int num_samples,
                               bool allow_inplace_modification) = 0;
diff --git a/intern/cycles/integrator/denoiser_device.cpp b/intern/cycles/integrator/denoiser_device.cpp
index d843700c323..8088cfd7800 100644
--- a/intern/cycles/integrator/denoiser_device.cpp
+++ b/intern/cycles/integrator/denoiser_device.cpp
@@ -36,14 +36,14 @@ DeviceDenoiser::~DeviceDenoiser()
   /* Explicit implementation, to allow forward declaration of Device in the header. */
 }
 
-void DeviceDenoiser::denoise_buffer(const BufferParams &buffer_params,
+bool DeviceDenoiser::denoise_buffer(const BufferParams &buffer_params,
                                     RenderBuffers *render_buffers,
                                     const int num_samples,
                                     bool allow_inplace_modification)
 {
   Device *denoiser_device = get_denoiser_device();
   if (!denoiser_device) {
-    return;
+    return false;
   }
 
   DeviceDenoiseTask task;
@@ -89,7 +89,7 @@ void DeviceDenoiser::denoise_buffer(const BufferParams &buffer_params,
     task.allow_inplace_modification = true;
   }
 
-  denoiser_device->denoise_buffer(task);
+  const bool denoise_result = denoiser_device->denoise_buffer(task);
 
   if (local_buffer_used) {
     local_render_buffers.copy_from_device();
@@ -99,6 +99,8 @@ void DeviceDenoiser::denoise_buffer(const BufferParams &buffer_params,
 
     render_buffers->copy_to_device();
   }
+
+  return denoise_result;
 }
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/denoiser_device.h b/intern/cycles/integrator/denoiser_device.h
index 282cee2bfe3..0fd934dba79 100644
--- a/intern/cycles/integrator/denoiser_device.h
+++ b/intern/cycles/integrator/denoiser_device.h
@@ -31,7 +31,7 @@ class DeviceDenoiser : public Denoiser {
   DeviceDenoiser(Device *path_trace_device, const DenoiseParams &params);
   ~DeviceDenoiser();
 
-  virtual void denoise_buffer(const BufferParams &buffer_params,
+  virtual bool denoise_buffer(const BufferParams &buffer_params,
                               RenderBuffers *render_buffers,
                               const int num_samples,
                               bool allow_inplace_modification) override;
diff --git a/intern/cycles/integrator/denoiser_oidn.cpp b/intern/cycles/integrator/denoiser_oidn.cpp
index 12bf6425e06..1a573be5367 100644
--- a/intern/cycles/integrator/denoiser_oidn.cpp
+++ b/intern/cycles/integrator/denoiser_oidn.cpp
@@ -547,7 +547,7 @@ class OIDNDenoiseContext {
 };
 #endif
 
-void OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
+bool OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
                                   RenderBuffers *render_buffers,
                                   const int num_samples,
                                   bool allow_inplace_modification)
@@ -576,7 +576,7 @@ void OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
     for (const PassType pass_type : passes) {
       context.denoise_pass(pass_type);
       if (is_cancelled()) {
-        return;
+        return false;
       }
     }
 
@@ -585,6 +585,10 @@ void OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
     render_buffers->buffer.copy_to_device();
   }
 #endif
+
+  /* This code is not supposed to run when compiled without OIDN support, so can assume if we made
+   * it up here all passes are properly denoised. */
+  return true;
 }
 
 uint OIDNDenoiser::get_device_type_mask() const
diff --git a/intern/cycles/integrator/denoiser_oidn.h b/intern/cycles/integrator/denoiser_oidn.h
index c672ab8b5bb..2448a4c362b 100644
--- a/intern/cycles/integrator/denoiser_oidn.h
+++ b/intern/cycles/integrator/denoiser_oidn.h
@@ -32,7 +32,7 @@ class OIDNDenoiser : public Denoiser {
   OIDNDenoiser(Device *path_trace_device, const DenoiseParams &params);
   ~OIDNDenoiser();
 
-  virtual void denoise_buffer(const BufferParams &buffer_params,
+  virtual bool denoise_buffer(const BufferParams &buffer_params,
                               RenderBuffers *render_buffers,
                               const int num_samples,
                               bool allow_inplace_modification) override;
diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp
index a2a591e441c..689ecc68dab 100644
--- a/intern/cycles/integrator/path_trace.cpp
+++ b/intern/cycles/integrator/path_trace.cpp
@@ -479,10 +479,12 @@ void PathTrace::denoise(const RenderWork &render_work)
     allow_inplace_modification = true;
   }
 
-  denoiser_->denoise_buffer(render_state_.effective_big_tile_params,
-                            buffer_to_denoise,
-                            get_num_samples_in_buffer(),
-                            allow_inplace_modification);
+  if (denoiser_->denoise_buffer(render_state_.effective_big_tile_params,
+                                buffer_to_denoise,
+                                get_num_samples_in_buffer(),
+                                allow_inplace_modification)) {
+    render_state_.has_denoised_result = true;
+  }
 
   if (multi_device_buffers) {
     multi_device_buffers->copy_from_device();
@@ -493,8 +495,6 @@ void PathTrace::denoise(const RenderWork &render_work)
   }
 
   render_scheduler_.report_denoise_time(render_work, time_dt() - start_time);
-
-  render_state_.has_denoised_result = true;
 }
 
 void PathTrace::set_gpu_display(unique_ptr<GPUDisplay> gpu_display)



More information about the Bf-blender-cvs mailing list