[Bf-blender-cvs] [f0ed22812d7] cycles-x: Cycles X: Internal API support for tiled rendering

Sergey Sharybin noreply at git.blender.org
Fri Aug 6 12:40:07 CEST 2021


Commit: f0ed22812d75e7c2a82fbbc89f5aa0646a17f3e8
Author: Sergey Sharybin
Date:   Wed Aug 4 17:11:04 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBf0ed22812d75e7c2a82fbbc89f5aa0646a17f3e8

Cycles X: Internal API support for tiled rendering

No visible changes on user level yet: just a tiny step towards tiled
rendering support.

Tested by hard-coding tile size to `make_int2(256, 256)`.

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

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

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

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

diff --git a/intern/cycles/integrator/render_scheduler.cpp b/intern/cycles/integrator/render_scheduler.cpp
index 2d672591188..b5e9c7d1a3b 100644
--- a/intern/cycles/integrator/render_scheduler.cpp
+++ b/intern/cycles/integrator/render_scheduler.cpp
@@ -156,6 +156,11 @@ void RenderScheduler::reset(const BufferParams &buffer_params, int num_samples)
   rebalance_time_.reset();
 }
 
+void RenderScheduler::reset_for_next_tile()
+{
+  reset(buffer_params_, num_samples_);
+}
+
 bool RenderScheduler::render_work_reschedule_on_converge(RenderWork &render_work)
 {
   /* Move to the next resolution divider. Assume adaptive filtering is not needed during
diff --git a/intern/cycles/integrator/render_scheduler.h b/intern/cycles/integrator/render_scheduler.h
index b205e05aa97..261ba125cd3 100644
--- a/intern/cycles/integrator/render_scheduler.h
+++ b/intern/cycles/integrator/render_scheduler.h
@@ -126,6 +126,11 @@ class RenderScheduler {
    * Resets current rendered state, as well as scheduling information. */
   void reset(const BufferParams &buffer_params, int num_samples);
 
+  /* Reset scheduler upon switching to a next tile.
+   * Will keep the same number of samples and full-frame render parameters, but will reset progress
+   * and allow schedule renders works from the beginning of the new tile. */
+  void reset_for_next_tile();
+
   /* Reschedule adaptive sampling work when all pixels did converge.
    * If there is nothing else to be done for the adaptive sampling (pixels did converge to the
    * final threshold) then false is returned and the render scheduler will stop scheduling path
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 472dbab0a8c..f62e22532c3 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -43,9 +43,7 @@
 CCL_NAMESPACE_BEGIN
 
 Session::Session(const SessionParams &params_, const SceneParams &scene_params)
-    : params(params_),
-      tile_manager_(make_int2(4096, 4096)),
-      render_scheduler_(params.headless, params.background, params.pixel_size)
+    : params(params_), render_scheduler_(params.headless, params.background, params.pixel_size)
 {
   TaskScheduler::init(params.threads);
 
@@ -245,6 +243,7 @@ RenderWork Session::run_update_for_next_iteration()
   thread_scoped_lock reset_lock(delayed_reset_.mutex);
 
   bool have_tiles = true;
+  bool switched_to_new_tile = false;
 
   if (delayed_reset_.do_reset) {
     thread_scoped_lock buffers_lock(buffers_mutex_);
@@ -252,6 +251,7 @@ RenderWork Session::run_update_for_next_iteration()
 
     /* After reset make sure the tile manager is at the first big tile. */
     have_tiles = tile_manager_.next();
+    switched_to_new_tile = true;
   }
 
   /* Update number of samples in the integrator.
@@ -280,13 +280,31 @@ RenderWork Session::run_update_for_next_iteration()
       break;
     }
 
-    /* TODO(sergey): Add support of the multiple big tile. */
-    break;
+    have_tiles = tile_manager_.next();
+    if (have_tiles) {
+      render_scheduler_.reset_for_next_tile();
+      switched_to_new_tile = true;
+    }
   }
 
   if (render_work) {
     scoped_timer update_timer;
 
+    if (switched_to_new_tile) {
+      BufferParams tile_params = buffer_params_;
+
+      const Tile &tile = tile_manager_.get_current_tile();
+      tile_params.width = tile.width;
+      tile_params.height = tile.height;
+      tile_params.full_x = tile.x + buffer_params_.full_x;
+      tile_params.full_y = tile.y + buffer_params_.full_y;
+      tile_params.full_width = buffer_params_.full_width;
+      tile_params.full_height = buffer_params_.full_height;
+      tile_params.update_offset_stride();
+
+      path_trace_->reset(tile_params);
+    }
+
     const int resolution = render_work.resolution_divider;
     const int width = max(1, buffer_params_.full_width / resolution);
     const int height = max(1, buffer_params_.full_height / resolution);
@@ -349,8 +367,9 @@ void Session::do_delayed_reset()
   buffer_params_.update_passes(scene->passes);
 
   render_scheduler_.reset(buffer_params_, delayed_reset_.samples);
-  path_trace_->reset(buffer_params_);
-  tile_manager_.reset(buffer_params_);
+
+  /* TODO(sergey): Use real big tile size. */
+  tile_manager_.reset(buffer_params_, make_int2(buffer_params_.width, buffer_params_.height));
 
   progress.reset_sample();
 
@@ -570,7 +589,7 @@ int2 Session::get_render_tile_offset() const
 {
   const Tile &tile = tile_manager_.get_current_tile();
 
-  return make_int2(tile.x - tile.full_x, tile.y - tile.full_y);
+  return make_int2(tile.x, tile.y);
 }
 
 bool Session::copy_render_tile_from_device()
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 7389efd20a2..f69fa21e1a5 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -22,20 +22,16 @@
 
 CCL_NAMESPACE_BEGIN
 
-TileManager::TileManager(int2 tile_size) : tile_size_(tile_size)
-{
-  BufferParams buffer_params;
-  reset(buffer_params);
-}
-
-void TileManager::reset(BufferParams &params)
+void TileManager::reset(const BufferParams &params, int2 tile_size)
 {
+  tile_size_ = tile_size;
   buffer_params_ = params;
 
-  /* TODO(sergey): Multiple big tile support. */
+  num_tiles_x_ = divide_up(params.width, tile_size_.x);
+  num_tiles_y_ = divide_up(params.height, tile_size_.y);
 
   state_.next_tile_index = 0;
-  state_.num_tiles = 1;
+  state_.num_tiles = num_tiles_x_ * num_tiles_y_;
 
   state_.current_tile = Tile();
 }
@@ -51,15 +47,23 @@ bool TileManager::next()
     return false;
   }
 
-  ++state_.next_tile_index;
+  /* TODO(sergey): Consider using hilbert spiral, or. maybe, even configurable. Not sure this
+   * brings a lot of value since this is only applicable to BIG tiles. */
 
-  state_.current_tile.x = buffer_params_.full_x;
-  state_.current_tile.y = buffer_params_.full_y;
-  state_.current_tile.width = buffer_params_.width;
-  state_.current_tile.height = buffer_params_.height;
+  const int tile_y = state_.next_tile_index / num_tiles_x_;
+  const int tile_x = state_.next_tile_index - tile_y * num_tiles_x_;
 
-  state_.current_tile.full_x = buffer_params_.full_x;
-  state_.current_tile.full_y = buffer_params_.full_y;
+  state_.current_tile.x = tile_x * tile_size_.x;
+  state_.current_tile.y = tile_y * tile_size_.y;
+  state_.current_tile.width = tile_size_.x;
+  state_.current_tile.height = tile_size_.y;
+
+  state_.current_tile.width = min(state_.current_tile.width,
+                                  buffer_params_.width - state_.current_tile.x);
+  state_.current_tile.height = min(state_.current_tile.height,
+                                   buffer_params_.height - state_.current_tile.y);
+
+  ++state_.next_tile_index;
 
   return true;
 }
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 651a49ce874..19dd25a15c9 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -27,8 +27,6 @@ class Tile {
   int x = 0, y = 0;
   int width = 0, height = 0;
 
-  int full_x = 0, full_y = 0;
-
   Tile()
   {
   }
@@ -38,9 +36,13 @@ class Tile {
 
 class TileManager {
  public:
-  explicit TileManager(int2 tile_size);
+  TileManager() = default;
 
-  void reset(BufferParams &params);
+  /* Reset current progress and start new rendering of the full-frame parameters in tiles of the
+   * given size. */
+  /* TODO(sergey): Consider using tile area instead of exact size to help dealing with extreme
+   * cases of stretched renders. */
+  void reset(const BufferParams &params, int2 tile_size);
 
   bool next();
   bool done();
@@ -48,7 +50,10 @@ class TileManager {
   const Tile &get_current_tile() const;
 
  protected:
-  int2 tile_size_;
+  int2 tile_size_ = make_int2(0, 0);
+  int num_tiles_x_ = 0;
+  int num_tiles_y_ = 0;
+
   BufferParams buffer_params_;
 
   struct {



More information about the Bf-blender-cvs mailing list