[Bf-blender-cvs] [05274ca8297] blender-v2.83-release: Fix T75432: Cycles progressive refine render slow with denoising data

Brecht Van Lommel noreply at git.blender.org
Tue Apr 28 22:41:48 CEST 2020


Commit: 05274ca82971332866d94bac07c843aa2ae97f80
Author: Brecht Van Lommel
Date:   Tue Apr 28 20:27:03 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rB05274ca82971332866d94bac07c843aa2ae97f80

Fix T75432: Cycles progressive refine render slow with denoising data

Only perform denoising prefilter for the last sample, not every sample.

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

M	intern/cycles/render/session.cpp
M	intern/cycles/render/session.h
M	intern/cycles/render/tile.cpp
M	intern/cycles/render/tile.h

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

diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 58bcc7ccdfb..f7df81a0601 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -293,14 +293,12 @@ void Session::run_gpu()
        * reset and draw in between */
       thread_scoped_lock buffers_lock(buffers_mutex);
 
-      /* avoid excessive denoising in viewport after reaching a certain amount of samples */
-      bool need_denoise = tile_manager.schedule_denoising || tile_manager.state.sample < 20 ||
-                          (time_dt() - last_display_time) >= params.progressive_update_timeout;
-
       /* update status and timing */
       update_status_time();
 
       /* render */
+      bool delayed_denoise = false;
+      const bool need_denoise = render_need_denoise(delayed_denoise);
       render(need_denoise);
 
       device->task_wait();
@@ -311,7 +309,7 @@ void Session::run_gpu()
       /* update status and timing */
       update_status_time();
 
-      gpu_need_display_buffer_update = need_denoise || !params.run_denoising;
+      gpu_need_display_buffer_update = !delayed_denoise;
       gpu_draw_ready = true;
       progress.set_update();
 
@@ -477,7 +475,7 @@ void Session::update_tile_sample(RenderTile &rtile)
   update_status_time();
 }
 
-void Session::release_tile(RenderTile &rtile)
+void Session::release_tile(RenderTile &rtile, const bool need_denoise)
 {
   thread_scoped_lock tile_lock(tile_mutex);
 
@@ -485,7 +483,7 @@ void Session::release_tile(RenderTile &rtile)
 
   bool delete_tile;
 
-  if (tile_manager.finish_tile(rtile.tile_index, delete_tile)) {
+  if (tile_manager.finish_tile(rtile.tile_index, need_denoise, delete_tile)) {
     if (write_render_tile_cb && params.progressive_refine == false) {
       write_render_tile_cb(rtile);
     }
@@ -687,21 +685,19 @@ void Session::run_cpu()
        * reset and draw in between */
       thread_scoped_lock buffers_lock(buffers_mutex);
 
-      /* avoid excessive denoising in viewport after reaching a certain amount of samples */
-      bool need_denoise = tile_manager.schedule_denoising || tile_manager.state.sample < 20 ||
-                          (time_dt() - last_display_time) >= params.progressive_update_timeout;
-
       /* update status and timing */
       update_status_time();
 
       /* render */
+      bool delayed_denoise = false;
+      const bool need_denoise = render_need_denoise(delayed_denoise);
       render(need_denoise);
 
       /* update status and timing */
       update_status_time();
 
       if (!params.background)
-        need_copy_to_display_buffer = need_denoise || !params.run_denoising;
+        need_copy_to_display_buffer = !delayed_denoise;
 
       if (!device->error_message().empty())
         progress.set_error(device->error_message());
@@ -1083,7 +1079,46 @@ void Session::update_status_time(bool show_pause, bool show_done)
   progress.set_status(status, substatus);
 }
 
-void Session::render(bool with_denoising)
+bool Session::render_need_denoise(bool &delayed)
+{
+  delayed = false;
+
+  /* Denoising enabled? */
+  if (!params.run_denoising) {
+    return false;
+  }
+
+  if (params.background) {
+    /* Background render, only denoise when rendering the last sample. */
+    return tile_manager.done();
+  }
+
+  /* Viewport render. */
+
+  /* It can happen that denoising was already enabled, but the scene still needs an update. */
+  if (scene->film->need_update || !scene->film->denoising_data_offset) {
+    return false;
+  }
+
+  /* Do not denoise until the sample at which denoising should start is reached. */
+  if (tile_manager.state.sample < params.denoising_start_sample) {
+    return false;
+  }
+
+  /* Cannot denoise with resolution divider and separate denoising devices.
+   * It breaks the copy in 'MultiDevice::map_neighbor_tiles' (which operates on
+   * the full buffer dimensions and not the scaled ones). */
+  if (!params.device.denoising_devices.empty() && tile_manager.state.resolution_divider > 1) {
+    return false;
+  }
+
+  /* Avoid excessive denoising in viewport after reaching a certain amount of samples. */
+  delayed = (tile_manager.state.sample >= 20 &&
+             (time_dt() - last_display_time) < params.progressive_update_timeout);
+  return !delayed;
+}
+
+void Session::render(bool need_denoise)
 {
   if (buffers && tile_manager.state.sample == tile_manager.range_start_sample) {
     /* Clear buffers. */
@@ -1098,7 +1133,7 @@ void Session::render(bool with_denoising)
   DeviceTask task(DeviceTask::RENDER);
 
   task.acquire_tile = function_bind(&Session::acquire_tile, this, _2, _1, _3);
-  task.release_tile = function_bind(&Session::release_tile, this, _1);
+  task.release_tile = function_bind(&Session::release_tile, this, _1, need_denoise);
   task.map_neighbor_tiles = function_bind(&Session::map_neighbor_tiles, this, _1, _2);
   task.unmap_neighbor_tiles = function_bind(&Session::unmap_neighbor_tiles, this, _1, _2);
   task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
@@ -1115,27 +1150,7 @@ void Session::render(bool with_denoising)
   /* Acquire render tiles by default. */
   task.tile_types = RenderTile::PATH_TRACE;
 
-  with_denoising = params.run_denoising && with_denoising;
-  if (with_denoising) {
-    /* Do not denoise viewport until the sample at which denoising should start is reached. */
-    if (!params.background && tile_manager.state.sample < params.denoising_start_sample) {
-      with_denoising = false;
-    }
-
-    /* Cannot denoise with resolution divider and separate denoising devices.
-     * It breaks the copy in 'MultiDevice::map_neighbor_tiles' (which operates on the full buffer
-     * dimensions and not the scaled ones). */
-    if (!params.device.denoising_devices.empty() && tile_manager.state.resolution_divider > 1) {
-      with_denoising = false;
-    }
-
-    /* It can happen that denoising was already enabled, but the scene still needs an update. */
-    if (scene->film->need_update || !scene->film->denoising_data_offset) {
-      with_denoising = false;
-    }
-  }
-
-  if (with_denoising) {
+  if (need_denoise) {
     task.denoising = params.denoising;
 
     task.pass_stride = scene->film->pass_stride;
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 61970d87e9c..f06952e8020 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -186,7 +186,7 @@ class Session {
 
   void update_status_time(bool show_pause = false, bool show_done = false);
 
-  void render(bool with_denoising);
+  void render(bool use_denoise);
   void copy_to_display_buffer(int sample);
 
   void reset_(BufferParams &params, int samples);
@@ -199,9 +199,11 @@ class Session {
   bool draw_gpu(BufferParams &params, DeviceDrawParams &draw_params);
   void reset_gpu(BufferParams &params, int samples);
 
+  bool render_need_denoise(bool &delayed);
+
   bool acquire_tile(RenderTile &tile, Device *tile_device, uint tile_types);
   void update_tile_sample(RenderTile &tile);
-  void release_tile(RenderTile &tile);
+  void release_tile(RenderTile &tile, const bool need_denoise);
 
   void map_neighbor_tiles(RenderTile *tiles, Device *tile_device);
   void unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device);
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 1480b6d1aab..375c9fd8e09 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -441,13 +441,13 @@ bool TileManager::check_neighbor_state(int index, Tile::State min_state)
 
 /* Returns whether the tile should be written (and freed if no denoising is used) instead of
  * updating. */
-bool TileManager::finish_tile(int index, bool &delete_tile)
+bool TileManager::finish_tile(const int index, const bool need_denoise, bool &delete_tile)
 {
   delete_tile = false;
 
   switch (state.tiles[index].state) {
     case Tile::RENDER: {
-      if (!schedule_denoising) {
+      if (!(schedule_denoising && need_denoise)) {
         state.tiles[index].state = Tile::DONE;
         delete_tile = !progressive;
         return true;
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 9fb9c1ca782..4858a275d5c 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -107,7 +107,7 @@ class TileManager {
   void set_samples(int num_samples);
   bool next();
   bool next_tile(Tile *&tile, int device, uint tile_types);
-  bool finish_tile(int index, bool &delete_tile);
+  bool finish_tile(const int index, const bool need_denoise, bool &delete_tile);
   bool done();
   bool has_tiles();



More information about the Bf-blender-cvs mailing list