Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2022-08-30 18:20:00 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-09-21 17:27:05 +0300
commit03fbfb30923ed5aaab4a389b8c0dbd5b71c0e35b (patch)
tree9b728fe5cfc4a6f2468a94df315570a47755380f
parent5fddc4a3b12832af1d06a782b35d5035955bcae8 (diff)
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.
-rw-r--r--intern/cycles/blender/session.cpp7
-rw-r--r--intern/cycles/session/session.cpp3
-rw-r--r--source/blender/freestyle/intern/application/Controller.h4
-rw-r--r--source/blender/render/RE_bake.h5
-rw-r--r--source/blender/render/RE_engine.h4
-rw-r--r--source/blender/render/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/engine.c92
-rw-r--r--source/blender/render/intern/render_types.h3
8 files changed, 84 insertions, 36 deletions
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 = object_id;
- engine->bake.pixels = pixel_array + image->offset;
- engine->bake.result = result + image->offset * targets->channels_num;
- engine->bake.width = image->width;
- engine->bake.height = image->height;
- engine->bake.depth = targets->channels_num;
- engine->bake.object_id = object_id;
+ for (int i = 0; i < targets->images_num; i++) {
+ const BakeImage *image = &targets->images[i];
+ engine->bake.image_id = i;
type->bake(
engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height);
+ }
- memset(&engine->bake, 0, sizeof(engine->bake));
+ /* Optionally let render images read bake images from disk delayed. */
+ if (type->render_frame_finish) {
+ engine->bake.image_id = 0;
+ type->render_frame_finish(engine);
}
+ memset(&engine->bake, 0, sizeof(engine->bake));
+
engine->depsgraph = NULL;
}
diff --git a/source/blender/render/intern/render_types.h b/source/blender/render/intern/render_types.h
index 58a15e3f013..64b6d0edb28 100644
--- a/source/blender/render/intern/render_types.h
+++ b/source/blender/render/intern/render_types.h
@@ -21,6 +21,7 @@
#include "RE_pipeline.h"
struct GHash;
+struct Depsgraph;
struct GSet;
struct Main;
struct Object;
@@ -91,7 +92,7 @@ struct Render {
/* NOTE: This is a minimal dependency graph and evaluated scene which is enough to access view
* layer visibility and use for postprocessing (compositor and sequencer). */
- Depsgraph *pipeline_depsgraph;
+ struct Depsgraph *pipeline_depsgraph;
Scene *pipeline_scene_eval;
/* callbacks */