diff options
author | Brecht Van Lommel <brecht@blender.org> | 2019-05-10 22:39:58 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2020-05-15 21:25:24 +0300 |
commit | d9773edaa394f61393f9c8b80275e62f74306097 (patch) | |
tree | 232b771b341e98a5403af16791bdcca133cb1edd /source/blender/render | |
parent | 3ff8ca60e94db2584ca76e323a54c738e677d5f8 (diff) |
Cycles: code refactor to bake using regular render session and tiles
There should be no user visible change from this, except that tile size
now affects performance. The goal here is to simplify bake denoising in
D3099, letting it reuse more denoising tiles and pass code.
A lot of code is now shared with regular rendering, with the two main
differences being that we read some render result passes from the bake API
when starting to render a tile, and call the bake kernel instead of the
path trace kernel.
With this kind of design where Cycles asks for tiles from the bake API,
it should eventually be easier to reduce memory usage, show tiles as
they are baked, or bake multiple passes at once, though there's still
quite some work needed for that.
Reviewers: #cycles
Subscribers: monio, wmatyjewicz, lukasstockner97, michaelknubben
Differential Revision: https://developer.blender.org/D3108
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/extern/include/RE_bake.h | 2 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_engine.h | 14 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_result.h | 11 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 129 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 18 |
6 files changed, 141 insertions, 35 deletions
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h index 372defbe8db..59e34404074 100644 --- a/source/blender/render/extern/include/RE_bake.h +++ b/source/blender/render/extern/include/RE_bake.h @@ -67,7 +67,7 @@ bool RE_bake_engine(struct Render *re, struct Object *object, const int object_id, const BakePixel pixel_array[], - const size_t num_pixels, + const BakeImages *bake_images, const int depth, const eScenePassType pass_type, const int pass_filter, diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index fd55a2a01df..82b45ba9d4a 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -87,11 +87,8 @@ typedef struct RenderEngineType { struct Object *object, const int pass_type, const int pass_filter, - const int object_id, - const struct BakePixel *pixel_array, - const int num_pixels, - const int depth, - void *result); + const int width, + const int height); void (*view_update)(struct RenderEngine *engine, const struct bContext *context, @@ -140,6 +137,13 @@ typedef struct RenderEngine { struct ReportList *reports; + struct { + const struct BakePixel *pixels; + float *result; + int width, height, depth; + int object_id; + } bake; + /* Depsgraph */ struct Depsgraph *depsgraph; diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index fabbd5fb096..0ed8871b224 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -84,11 +84,12 @@ void render_result_exr_file_begin(struct Render *re, struct RenderEngine *engine void render_result_exr_file_end(struct Render *re, struct RenderEngine *engine); /* render pass wrapper for gpencil */ -struct RenderPass *gp_add_pass(struct RenderResult *rr, - struct RenderLayer *rl, - int channels, - const char *name, - const char *viewname); +struct RenderPass *render_layer_add_pass(struct RenderResult *rr, + struct RenderLayer *rl, + int channels, + const char *name, + const char *viewname, + const char *chanid); void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart, diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 4770e98bd20..4d88bb82dd9 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -31,6 +31,7 @@ #include "BLI_ghash.h" #include "BLI_listbase.h" +#include "BLI_math_bits.h" #include "BLI_rect.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -167,6 +168,89 @@ void RE_engine_free(RenderEngine *engine) MEM_freeN(engine); } +/* Bake Render Results */ + +static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h) +{ + /* Create render result with specified size. */ + RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__); + + rr->rectx = w; + rr->recty = h; + rr->tilerect.xmin = x; + rr->tilerect.ymin = y; + rr->tilerect.xmax = x + w; + rr->tilerect.ymax = y + h; + + /* Add single baking render layer. */ + RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer"); + 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"); + RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA"); + RenderPass *differential_pass = render_layer_add_pass(rr, rl, 4, "BakeDifferential", "", "RGBA"); + + /* Fill render passes from bake pixel array, to be read by the render engine. */ + for (int ty = 0; ty < h; ty++) { + size_t offset = ty * w * 4; + 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; + + for (int tx = 0; tx < w; tx++) { + if (bake_pixel->object_id != engine->bake.object_id) { + primitive[0] = int_as_float(-1); + primitive[1] = int_as_float(-1); + } + else { + primitive[0] = int_as_float(bake_pixel->object_id); + primitive[1] = int_as_float(bake_pixel->primitive_id); + primitive[2] = bake_pixel->uv[0]; + primitive[3] = bake_pixel->uv[1]; + + differential[0] = bake_pixel->du_dx; + differential[1] = bake_pixel->du_dy; + differential[2] = bake_pixel->dv_dx; + differential[3] = bake_pixel->dv_dy; + } + + primitive += 4; + differential += 4; + bake_pixel++; + } + } + + return rr; +} + +static void render_result_to_bake(RenderEngine *engine, RenderResult *rr) +{ + RenderPass *rpass = RE_pass_find_by_name(rr->layers.first, RE_PASSNAME_COMBINED, ""); + + if (!rpass) { + return; + } + + /* Copy from tile render result to full image bake result. */ + int x = rr->tilerect.xmin; + int y = rr->tilerect.ymin; + int w = rr->tilerect.xmax - rr->tilerect.xmin; + int h = rr->tilerect.ymax - rr->tilerect.ymin; + + for (int ty = 0; ty < h; ty++) { + size_t offset = ty * w * engine->bake.depth; + size_t bake_offset = ((y + ty) * engine->bake.width + x) * engine->bake.depth; + size_t size = w * engine->bake.depth * sizeof(float); + + memcpy(engine->bake.result + bake_offset, rpass->rect + offset, size); + } +} + /* Render Results */ static RenderPart *get_part_from_result(Render *re, RenderResult *result) @@ -180,6 +264,12 @@ static RenderPart *get_part_from_result(Render *re, RenderResult *result) 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); + BLI_addtail(&engine->fullresult, result); + return result; + } + Render *re = engine->re; RenderResult *result; rcti disprect; @@ -237,6 +327,11 @@ RenderResult *RE_engine_begin_result( void RE_engine_update_result(RenderEngine *engine, RenderResult *result) { + if (engine->bake.pixels) { + /* No interactive baking updates for now. */ + return; + } + Render *re = engine->re; if (result) { @@ -270,6 +365,13 @@ void RE_engine_end_result( return; } + if (engine->bake.pixels) { + render_result_to_bake(engine, result); + BLI_remlink(&engine->fullresult, result); + render_result_free(result); + return; + } + /* merge. on break, don't merge in result for preview renders, looks nicer */ if (!highlight) { /* for exr tile render, detect tiles that are done */ @@ -574,7 +676,7 @@ bool RE_bake_engine(Render *re, Object *object, const int object_id, const BakePixel pixel_array[], - const size_t num_pixels, + const BakeImages *bake_images, const int depth, const eScenePassType pass_type, const int pass_filter, @@ -619,16 +721,21 @@ bool RE_bake_engine(Render *re, type->update(engine, re->main, engine->depsgraph); } - type->bake(engine, - engine->depsgraph, - object, - pass_type, - pass_filter, - object_id, - pixel_array, - num_pixels, - depth, - result); + for (int i = 0; i < bake_images->size; i++) { + const BakeImage *image = bake_images->data + i; + + engine->bake.pixels = pixel_array + image->offset; + engine->bake.result = result + image->offset * depth; + engine->bake.width = image->width; + engine->bake.height = image->height; + engine->bake.depth = depth; + engine->bake.object_id = object_id; + + type->bake( + engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height); + + memset(&engine->bake, 0, sizeof(engine->bake)); + } engine->depsgraph = NULL; } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 4a910d9e12c..d68f74751ec 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2955,5 +2955,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha BLI_freelinkN(&rl->passes, rp); } /* create a totally new pass */ - return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname); + return render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname, "RGBA"); } diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index b38c1b573f3..d829033656a 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -213,12 +213,12 @@ static void set_pass_full_name( /********************************** New **************************************/ -static RenderPass *render_layer_add_pass(RenderResult *rr, - RenderLayer *rl, - int channels, - const char *name, - const char *viewname, - const char *chan_id) +RenderPass *render_layer_add_pass(RenderResult *rr, + RenderLayer *rl, + int channels, + const char *name, + const char *viewname, + const char *chan_id) { const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name)); RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name); @@ -280,12 +280,6 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, return rpass; } -/* wrapper called from render_opengl */ -RenderPass *gp_add_pass( - RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname) -{ - return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA"); -} /* called by main render as well for parts */ /* will read info from Render *re to define layers */ |