[Bf-blender-cvs] [03fbfb30923] blender-v3.3-release: Fix part of T100626: Cycles not using tiles for baking

Brecht Van Lommel noreply at git.blender.org
Wed Sep 21 16:38:42 CEST 2022


Commit: 03fbfb30923ed5aaab4a389b8c0dbd5b71c0e35b
Author: Brecht Van Lommel
Date:   Tue Aug 30 17:20:00 2022 +0200
Branches: blender-v3.3-release
https://developer.blender.org/rB03fbfb30923ed5aaab4a389b8c0dbd5b71c0e35b

Fix part of T100626: Cycles not using tiles for baking

Leading to excessive memory usage compared to Blender 2.93. There's still
some avoidable memory usage remaining, due to the full float buffer in the
new image editor drawing and not loading the cached EXR from disk in tiles.

Main difficulty was handling multi-image baking and disk caches, which is
solved by associating a unique layer name with each image so it can be
matched when reading back the image from the disk.

Also some minor header changes to be able to use RE_MAXNAME in RE_bake.h.

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

M	intern/cycles/blender/session.cpp
M	intern/cycles/session/session.cpp
M	source/blender/freestyle/intern/application/Controller.h
M	source/blender/render/RE_bake.h
M	source/blender/render/RE_engine.h
M	source/blender/render/RE_pipeline.h
M	source/blender/render/intern/engine.c
M	source/blender/render/intern/render_types.h

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

diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp
index 6d27b8e7d87..30128ccf348 100644
--- a/intern/cycles/blender/session.cpp
+++ b/intern/cycles/blender/session.cpp
@@ -657,6 +657,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
 
   session->set_display_driver(nullptr);
   session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
+  session->full_buffer_written_cb = [&](string_view filename) { full_buffer_written(filename); };
 
   /* Sync scene. */
   BL::Object b_camera_override(b_engine.camera_override());
@@ -698,6 +699,10 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
     BufferParams buffer_params;
     buffer_params.width = bake_width;
     buffer_params.height = bake_height;
+    buffer_params.window_width = bake_width;
+    buffer_params.window_height = bake_height;
+    /* Unique layer name for multi-image baking. */
+    buffer_params.layer = string_printf("bake_%d\n", (int)full_buffer_files_.size());
 
     /* Update session. */
     session->reset(session_params, buffer_params);
@@ -711,8 +716,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
     session->start();
     session->wait();
   }
-
-  session->set_output_driver(nullptr);
 }
 
 void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp
index c94b53535a7..de685a47003 100644
--- a/intern/cycles/session/session.cpp
+++ b/intern/cycles/session/session.cpp
@@ -436,8 +436,7 @@ int2 Session::get_effective_tile_size() const
   const int image_width = buffer_params_.width;
   const int image_height = buffer_params_.height;
 
-  /* No support yet for baking with tiles. */
-  if (!params.use_auto_tile || scene->bake_manager->get_baking()) {
+  if (!params.use_auto_tile) {
     return make_int2(image_width, image_height);
   }
 
diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h
index b5ef0fba1f7..8e59b277ff3 100644
--- a/source/blender/freestyle/intern/application/Controller.h
+++ b/source/blender/freestyle/intern/application/Controller.h
@@ -20,6 +20,10 @@
 #  include "MEM_guardedalloc.h"
 #endif
 
+struct Depsgraph;
+struct Render;
+struct ViewLayer;
+
 namespace Freestyle {
 
 class AppCanvas;
diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h
index 56c66df5925..ebfc7509504 100644
--- a/source/blender/render/RE_bake.h
+++ b/source/blender/render/RE_bake.h
@@ -7,6 +7,8 @@
 
 #pragma once
 
+#include "RE_pipeline.h"
+
 struct Depsgraph;
 struct ImBuf;
 struct MLoopUV;
@@ -24,6 +26,9 @@ typedef struct BakeImage {
   int width;
   int height;
   size_t offset;
+
+  /* For associating render result layer with image. */
+  char render_layer_name[RE_MAXNAME];
 } BakeImage;
 
 typedef struct BakeTargets {
diff --git a/source/blender/render/RE_engine.h b/source/blender/render/RE_engine.h
index d7815ef3f3c..5d10da8dac0 100644
--- a/source/blender/render/RE_engine.h
+++ b/source/blender/render/RE_engine.h
@@ -15,6 +15,7 @@
 
 #include "BLI_threads.h"
 
+struct BakeTargets;
 struct BakePixel;
 struct Depsgraph;
 struct Main;
@@ -140,9 +141,10 @@ typedef struct RenderEngine {
   struct ReportList *reports;
 
   struct {
+    const struct BakeTargets *targets;
     const struct BakePixel *pixels;
     float *result;
-    int width, height, depth;
+    int image_id;
     int object_id;
   } bake;
 
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index 548e38d3ef3..66057c06058 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -7,7 +7,7 @@
 
 #pragma once
 
-#include "DEG_depsgraph.h"
+#include "DNA_ID.h"
 #include "DNA_listBase.h"
 #include "DNA_vec_types.h"
 
diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c
index 266e66092b8..484e4443469 100644
--- a/source/blender/render/intern/engine.c
+++ b/source/blender/render/intern/engine.c
@@ -178,8 +178,18 @@ void RE_engine_free(RenderEngine *engine)
 
 /* Bake Render Results */
 
-static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h)
+static RenderResult *render_result_from_bake(
+    RenderEngine *engine, int x, int y, int w, int h, const char *layername)
 {
+  BakeImage *image = &engine->bake.targets->images[engine->bake.image_id];
+  const BakePixel *pixels = engine->bake.pixels + image->offset;
+  const size_t channels_num = engine->bake.targets->channels_num;
+
+  /* Remember layer name for to match images in render_frame_finish. */
+  if (image->render_layer_name[0] == '\0') {
+    STRNCPY(image->render_layer_name, layername);
+  }
+
   /* Create render result with specified size. */
   RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
 
@@ -192,12 +202,13 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y,
 
   /* Add single baking render layer. */
   RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer");
+  STRNCPY(rl->name, layername);
   rl->rectx = w;
   rl->recty = h;
   BLI_addtail(&rr->layers, rl);
 
   /* Add render passes. */
-  render_layer_add_pass(rr, rl, engine->bake.depth, RE_PASSNAME_COMBINED, "", "RGBA", true);
+  render_layer_add_pass(rr, rl, channels_num, RE_PASSNAME_COMBINED, "", "RGBA", true);
 
   RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA", true);
   RenderPass *differential_pass = render_layer_add_pass(
@@ -209,8 +220,8 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y,
     float *primitive = primitive_pass->rect + offset;
     float *differential = differential_pass->rect + offset;
 
-    size_t bake_offset = (y + ty) * engine->bake.width + x;
-    const BakePixel *bake_pixel = engine->bake.pixels + bake_offset;
+    size_t bake_offset = (y + ty) * image->width + x;
+    const BakePixel *bake_pixel = pixels + bake_offset;
 
     for (int tx = 0; tx < w; tx++) {
       if (bake_pixel->object_id != engine->bake.object_id) {
@@ -240,35 +251,50 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y,
 
 static void render_result_to_bake(RenderEngine *engine, RenderResult *rr)
 {
-  RenderPass *rpass = RE_pass_find_by_name(rr->layers.first, RE_PASSNAME_COMBINED, "");
-
+  RenderLayer *rl = rr->layers.first;
+  RenderPass *rpass = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, "");
   if (!rpass) {
     return;
   }
 
+  /* Find bake image corresponding to layer. */
+  int image_id = 0;
+  for (; image_id < engine->bake.targets->images_num; image_id++) {
+    if (STREQ(engine->bake.targets->images[image_id].render_layer_name, rl->name)) {
+      break;
+    }
+  }
+  if (image_id == engine->bake.targets->images_num) {
+    return;
+  }
+
+  const BakeImage *image = &engine->bake.targets->images[image_id];
+  const BakePixel *pixels = engine->bake.pixels + image->offset;
+  const size_t channels_num = engine->bake.targets->channels_num;
+  const size_t channels_size = channels_num * sizeof(float);
+  float *result = engine->bake.result + image->offset * channels_num;
+
   /* Copy from tile render result to full image bake result. Just the pixels for the
    * object currently being baked, to preserve other objects when baking multiple. */
   const int x = rr->tilerect.xmin;
   const int y = rr->tilerect.ymin;
   const int w = rr->tilerect.xmax - rr->tilerect.xmin;
   const int h = rr->tilerect.ymax - rr->tilerect.ymin;
-  const size_t pixel_depth = engine->bake.depth;
-  const size_t pixel_size = pixel_depth * sizeof(float);
 
   for (int ty = 0; ty < h; ty++) {
     const size_t offset = ty * w;
-    const size_t bake_offset = (y + ty) * engine->bake.width + x;
+    const size_t bake_offset = (y + ty) * image->width + x;
 
-    const float *pass_rect = rpass->rect + offset * pixel_depth;
-    const BakePixel *bake_pixel = engine->bake.pixels + bake_offset;
-    float *bake_result = engine->bake.result + bake_offset * pixel_depth;
+    const float *pass_rect = rpass->rect + offset * channels_num;
+    const BakePixel *bake_pixel = pixels + bake_offset;
+    float *bake_result = result + bake_offset * channels_num;
 
     for (int tx = 0; tx < w; tx++) {
       if (bake_pixel->object_id == engine->bake.object_id) {
-        memcpy(bake_result, pass_rect, pixel_size);
+        memcpy(bake_result, pass_rect, channels_size);
       }
-      pass_rect += pixel_depth;
-      bake_result += pixel_depth;
+      pass_rect += channels_num;
+      bake_result += channels_num;
       bake_pixel++;
     }
   }
@@ -318,8 +344,8 @@ static void engine_tile_highlight_set(RenderEngine *engine,
 RenderResult *RE_engine_begin_result(
     RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
 {
-  if (engine->bake.pixels) {
-    RenderResult *result = render_result_from_bake(engine, x, y, w, h);
+  if (engine->bake.targets) {
+    RenderResult *result = render_result_from_bake(engine, x, y, w, h, layername);
     BLI_addtail(&engine->fullresult, result);
     return result;
   }
@@ -380,7 +406,7 @@ static void re_ensure_passes_allocated_thread_safe(Render *re)
 
 void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
 {
-  if (engine->bake.pixels) {
+  if (engine->bake.targets) {
     /* No interactive baking updates for now. */
     return;
   }
@@ -419,8 +445,10 @@ void RE_engine_end_result(
     return;
   }
 
-  if (engine->bake.pixels) {
-    render_result_to_bake(engine, result);
+  if (engine->bake.targets) {
+    if (!cancel || merge_results) {
+      render_result_to_bake(engine, result);
+    }
     BLI_remlink(&engine->fullresult, result);
     render_result_free(result);
     return;
@@ -829,22 +857,28 @@ bool RE_bake_engine(Render *re,
       type->update(engine, re->main, engine->depsgraph);
     }
 
-    for (int i = 0; i < targets->images_num; i++) {
-      const BakeImage *image = targets->images + i;
+    /* Bake all images. */
+    engine->bake.targets = targets;
+    engine->bake.pixels = pixel_array;
+    engine->bake.result = result;
+    engine->bake.object_id = ob

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list