[Bf-blender-cvs] [e89fb443169] cycles-x: Cycles X: Switch TileManager to use BufferPass

Sergey Sharybin noreply at git.blender.org
Wed Sep 15 19:37:00 CEST 2021


Commit: e89fb443169a798c492da8e8d9e0433342c9f9b0
Author: Sergey Sharybin
Date:   Tue Sep 14 11:07:02 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBe89fb443169a798c492da8e8d9e0433342c9f9b0

Cycles X: Switch TileManager to use BufferPass

Continuation of work related on making buffers a sufficient entity
to properly access pass pixels.

For the ease of (de)serialization the buffer pass and parameters
are now subclass of Node. Can try looking into adding an explicit
Serializable API, but it will be outside of this patch and not
currently sure it will make things more clear.

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

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

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

diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 78f7076c34e..378b85f0d62 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -43,45 +43,101 @@ static int pass_type_mode_to_index(PassType pass_type, PassMode mode)
   return index;
 }
 
-static int scene_pass_to_index(const Pass *pass)
+static int pass_to_index(const BufferPass &pass)
 {
-  return pass_type_mode_to_index(pass->get_type(), pass->get_mode());
+  return pass_type_mode_to_index(pass.type, pass.mode);
 }
 
 /* --------------------------------------------------------------------
  * Buffer pass.
  */
 
+NODE_DEFINE(BufferPass)
+{
+  NodeType *type = NodeType::add("buffer_pass", create);
+
+  const NodeEnum *pass_type_enum = Pass::get_type_enum();
+  const NodeEnum *pass_mode_enum = Pass::get_mode_enum();
+
+  SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED);
+  SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
+  SOCKET_STRING(name, "Name", ustring());
+  SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
+
+  SOCKET_INT(offset, "Offset", -1);
+
+  return type;
+}
+
+BufferPass::BufferPass() : Node(get_node_type())
+{
+}
+
 BufferPass::BufferPass(const Pass *scene_pass)
-    : type(scene_pass->get_type()),
+    : Node(get_node_type()),
+      type(scene_pass->get_type()),
       mode(scene_pass->get_mode()),
       name(scene_pass->get_name()),
       include_albedo(scene_pass->get_include_albedo())
 {
 }
 
+PassInfo BufferPass::get_info() const
+{
+  return Pass::get_info(type, include_albedo);
+}
+
 /* --------------------------------------------------------------------
  * Buffer Params.
  */
 
-BufferParams::BufferParams()
+NODE_DEFINE(BufferParams)
 {
-  width = 0;
-  height = 0;
+  NodeType *type = NodeType::add("buffer_params", create);
+
+  SOCKET_INT(width, "Width", 0);
+  SOCKET_INT(height, "Height", 0);
+
+  SOCKET_INT(full_x, "Full X", 0);
+  SOCKET_INT(full_y, "Full Y", 0);
+  SOCKET_INT(full_width, "Full Width", 0);
+  SOCKET_INT(full_height, "Full Height", 0);
 
-  full_x = 0;
-  full_y = 0;
-  full_width = 0;
-  full_height = 0;
+  /* Notes:
+   *  - Skip passes since they do not follow typical container socket definition.
+   *    Might look into covering those as a socket in the future.
+   *
+   *  - Skip offset, stride, and pass stride since those can be delivered from the passes and
+   *    rest of the sockets. */
 
+  return type;
+}
+
+BufferParams::BufferParams() : Node(get_node_type())
+{
   reset_pass_offset();
 }
 
-void BufferParams::update_passes(const vector<Pass *> &scene_passes)
+void BufferParams::update_passes()
 {
   update_offset_stride();
   reset_pass_offset();
 
+  pass_stride = 0;
+  for (const BufferPass &pass : passes) {
+    if (pass.offset != PASS_UNUSED) {
+      const int index = pass_to_index(pass);
+      if (pass_offset_[index] == PASS_UNUSED) {
+        pass_offset_[index] = pass_stride;
+      }
+
+      pass_stride += pass.get_info().num_components;
+    }
+  }
+}
+
+void BufferParams::update_passes(const vector<Pass *> &scene_passes)
+{
   passes.clear();
 
   pass_stride = 0;
@@ -90,12 +146,6 @@ void BufferParams::update_passes(const vector<Pass *> &scene_passes)
 
     if (scene_pass->is_written()) {
       buffer_pass.offset = pass_stride;
-
-      const int index = scene_pass_to_index(scene_pass);
-      if (pass_offset_[index] == PASS_UNUSED) {
-        pass_offset_[index] = pass_stride;
-      }
-
       pass_stride += scene_pass->get_info().num_components;
     }
     else {
@@ -104,6 +154,8 @@ void BufferParams::update_passes(const vector<Pass *> &scene_passes)
 
     passes.emplace_back(std::move(buffer_pass));
   }
+
+  update_passes();
 }
 
 void BufferParams::reset_pass_offset()
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index e192bc4baff..0bf149eb0ec 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -18,7 +18,7 @@
 #define __BUFFERS_H__
 
 #include "device/device_memory.h"
-
+#include "graph/node.h"
 #include "render/pass.h"
 
 #include "kernel/kernel_types.h"
@@ -34,8 +34,11 @@ class Device;
 struct DeviceDrawParams;
 struct float4;
 
-class BufferPass {
+/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization. */
+class BufferPass : public Node {
  public:
+  NODE_DECLARE
+
   PassType type = PASS_NONE;
   PassMode mode = PassMode::NOISY;
   ustring name;
@@ -43,8 +46,19 @@ class BufferPass {
 
   int offset = -1;
 
+  BufferPass();
   explicit BufferPass(const Pass *scene_pass);
 
+  BufferPass(BufferPass &&other) noexcept = default;
+  BufferPass(const BufferPass &other) = default;
+
+  BufferPass &operator=(BufferPass &&other) = default;
+  BufferPass &operator=(const BufferPass &other) = default;
+
+  ~BufferPass() = default;
+
+  PassInfo get_info() const;
+
   inline bool operator==(const BufferPass &other) const
   {
     return type == other.type && mode == other.mode && name == other.name &&
@@ -59,8 +73,11 @@ class BufferPass {
 /* Buffer Parameters
  * Size of render buffer and how it fits in the full image (border render). */
 
-class BufferParams {
+/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization. */
+class BufferParams : public Node {
  public:
+  NODE_DECLARE
+
   /* width/height of the physical buffer */
   int width = 0;
   int height = 0;
@@ -79,10 +96,23 @@ class BufferParams {
 
   vector<BufferPass> passes;
 
-  /* functions */
   BufferParams();
 
-  /* Pre-calculate all fields which depends on the scene passes. */
+  BufferParams(BufferParams &&other) noexcept = default;
+  BufferParams(const BufferParams &other) = default;
+
+  BufferParams &operator=(BufferParams &&other) = default;
+  BufferParams &operator=(const BufferParams &other) = default;
+
+  ~BufferParams() = default;
+
+  /* Pre-calculate all fields which depends on the passes.
+   *
+   * When the scene passes are given, the buffer passes will be created from them and stored in
+   * this params, and then params are updated for those passes.
+   * The `update_passes()` without parameters updates offsets and stries which are stored outside
+   * of the passes. */
+  void update_passes();
   void update_passes(const vector<Pass *> &scene_passes);
 
   /* Returns PASS_UNUSED if there is no such pass in the buffer. */
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 6fe7df0a160..53a4cd633be 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -407,7 +407,7 @@ void Session::do_delayed_reset()
 
   /* Update for new state of passes. */
   buffer_params_.update_passes(scene->passes);
-  tile_manager_.update_passes(buffer_params_, scene->passes);
+  tile_manager_.update_passes(buffer_params_);
 
   /* Progress. */
   progress.reset_sample();
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 15117873099..1cae4fe8907 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -33,11 +33,7 @@ CCL_NAMESPACE_BEGIN
 static const char *ATTR_PASSES_COUNT = "cycles.passes.count";
 
 static const char *ATTR_PASS_SOCKET_PREFIX_FORMAT = "cycles.passes.%d.";
-
-static const char *ATTR_BUFFER_FULL_X = "cycles.buffer.full_x";
-static const char *ATTR_BUFFER_FULL_Y = "cycles.buffer.full_y";
-static const char *ATTR_BUFFER_FULL_WIDTH = "cycles.buffer.full_width";
-static const char *ATTR_BUFFER_FULL_HEIGHT = "cycles.buffer.full_height";
+static const char *ATTR_BUFFER_SOCKET_PREFIX = "cycles.buffer.";
 
 /* Global counter of ToleManager object instances. */
 static std::atomic<uint64_t> g_instance_index = 0;
@@ -46,19 +42,19 @@ static std::atomic<uint64_t> g_instance_index = 0;
  * in render buffers corresponding to the given passes.
  *
  * Returns `std` datatypes so that it can be assigned directly to the OIIO's `ImageSpec`. */
-static std::vector<std::string> exr_channel_names_for_passes(const vector<Pass *> &passes)
+static std::vector<std::string> exr_channel_names_for_passes(const BufferParams &buffer_params)
 {
   static const char *component_suffixes[] = {"R", "G", "B", "A"};
 
   int pass_index = 0;
   int num_channels = 0;
   std::vector<std::string> channel_names;
-  for (const Pass *pass : passes) {
-    if (!pass->is_written()) {
+  for (const BufferPass &pass : buffer_params.passes) {
+    if (pass.offset == PASS_UNUSED) {
       continue;
     }
 
-    const PassInfo pass_info = pass->get_info();
+    const PassInfo pass_info = pass.get_info();
     num_channels += pass_info.num_components;
 
     /* EXR canonically expects first part of channel names to be sorted alphabetically, which is
@@ -67,7 +63,7 @@ static std::vector<std::string> exr_channel_names_for_passes(const vector<Pass *
      * buffers memory to disk and read it back without doing extra mapping. */
     const string prefix = string_printf("%08d", pass_index);
 
-    const string channel_name_prefix = prefix + string(pass->get_name()) + ".";
+    const string channel_name_prefix = prefix + string(pass.name) + ".";
 
     for (int i = 0; i < pass_info.num_components; ++i) {
       channel_names.push_back(channel_name_prefix + component_suffixes[i]);
@@ -79,32 +75,6 @@ static std::vector<std::string> exr_channel_names_for_passes(const vector<Pass *
   return channel_names;
 }
 
-static bool buffer_params_to_image_spec_atttributes(ImageSpec *image_spec,
-                                                    const BufferParams &buffer_params)
-{
-  image_spec->attribute(ATTR_BUFFER_FULL_X, buffer_params.full_x);
-  image_spec->attribute(ATTR_BUFFER_FULL_Y, buffer_params.full_y);
-  image_spec->attribute(ATTR_BUFFER_FULL_WIDTH, buffer_params.full_width);
-  image_spec->attribute(ATTR_BUFFER_FULL_HEIGHT, buffer_params.full_height);
-
-  return true;
-}
-
-/* NOTE: The parameters needs to be updated with passes after this call still
- * (`buffer_params->update_passes()`). */
-static bool buffer_params_from_image_spec_atttributes(BufferParams *buffer_params,
-                                                      const ImageSpec &image_spec)
-{
-  buffer_params->width = image_spec.width;
-  buffer_params->height = image_sp

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list