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:
authorSergey Sharybin <sergey@blender.org>2021-08-04 16:37:18 +0300
committerSergey Sharybin <sergey@blender.org>2021-08-24 17:20:57 +0300
commit038f9b7f4a0e58da671079fd09aecdb926f12b0f (patch)
tree11e1ed18297d3cd006262b265f72489c2b09c3dd /source/blender/render
parent7aff40f410f4bb869c8045a67cda6a6ab6810a13 (diff)
Render: Lazily allocate render passes pixels storage
The idea is to only allocate pixel storage only when there is an actual data to be written to them. This moves the code forward a better support of high-res rendering when pixel storage is not allocated until render engine is ready to provide pixel data. Is expected to be no functional changes for neither users no external engines. The only difference is that the motion and depth passes will be displayed as transparent for until render engine provides any tile result (at which point the pixels will be allocated and initialized to infinite depth). Differential Revision: https://developer.blender.org/D12195
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/engine.c11
-rw-r--r--source/blender/render/intern/pipeline.c1
-rw-r--r--source/blender/render/intern/render_result.c65
-rw-r--r--source/blender/render/intern/render_result.h2
5 files changed, 53 insertions, 28 deletions
diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h
index 4534c86f7f7..cd839385bfb 100644
--- a/source/blender/render/RE_pipeline.h
+++ b/source/blender/render/RE_pipeline.h
@@ -155,6 +155,8 @@ typedef struct RenderResult {
char *error;
struct StampData *stamp_data;
+
+ bool passes_allocated;
} RenderResult;
typedef struct RenderStats {
diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c
index 75b3f2db249..1510587502b 100644
--- a/source/blender/render/intern/engine.c
+++ b/source/blender/render/intern/engine.c
@@ -212,6 +212,8 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y,
RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA");
RenderPass *differential_pass = render_layer_add_pass(rr, rl, 4, "BakeDifferential", "", "RGBA");
+ render_result_passes_allocated_ensure(rr);
+
/* 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;
@@ -328,6 +330,7 @@ RenderResult *RE_engine_begin_result(
/* can be NULL if we CLAMP the width or height to 0 */
if (result) {
render_result_clone_passes(re, result, viewname);
+ render_result_passes_allocated_ensure(result);
RenderPart *pa;
@@ -400,6 +403,14 @@ void RE_engine_end_result(
return;
}
+ if (!re->result->passes_allocated) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ if (!re->result->passes_allocated) {
+ render_result_passes_allocated_ensure(re->result);
+ }
+ BLI_rw_mutex_unlock(&re->resultmutex);
+ }
+
/* merge. on break, don't merge in result for preview renders, looks nicer */
if (!highlight) {
/* for exr tile render, detect tiles that are done */
diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c
index 479ad9209f0..9ef52b4bf41 100644
--- a/source/blender/render/intern/pipeline.c
+++ b/source/blender/render/intern/pipeline.c
@@ -354,6 +354,7 @@ RenderResult *RE_AcquireResultWrite(Render *re)
{
if (re) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_passes_allocated_ensure(re->result);
return re->result;
}
diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c
index 091f5964291..c29ab342ed7 100644
--- a/source/blender/render/intern/render_result.c
+++ b/source/blender/render/intern/render_result.c
@@ -222,7 +222,6 @@ RenderPass *render_layer_add_pass(RenderResult *rr,
{
const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
- size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
rpass->channels = channels;
rpass->rectx = rl->rectx;
@@ -249,33 +248,6 @@ RenderPass *render_layer_add_pass(RenderResult *rr,
}
}
- /* Always allocate combined for display, in case of save buffers
- * other passes are not allocated and only saved to the EXR file. */
- if (rl->exrhandle == NULL || STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
- float *rect;
- int x;
-
- rpass->rect = MEM_callocN(sizeof(float) * rectsize, name);
- if (rpass->rect == NULL) {
- MEM_freeN(rpass);
- return NULL;
- }
-
- if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
- /* initialize to max speed */
- rect = rpass->rect;
- for (x = rectsize - 1; x >= 0; x--) {
- rect[x] = PASS_VECTOR_MAX;
- }
- }
- else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
- rect = rpass->rect;
- for (x = rectsize - 1; x >= 0; x--) {
- rect[x] = 10e10;
- }
- }
- }
-
BLI_addtail(&rl->passes, rpass);
return rpass;
@@ -316,6 +288,8 @@ RenderResult *render_result_new(
rr->do_exr_tile = true;
}
+ rr->passes_allocated = false;
+
render_result_views_new(rr, &re->r);
/* check renderdata for amount of layers */
@@ -484,6 +458,40 @@ RenderResult *render_result_new(
return rr;
}
+void render_result_passes_allocated_ensure(RenderResult *rr)
+{
+ LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
+ LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) {
+ if (rl->exrhandle != NULL && !STREQ(rp->name, RE_PASSNAME_COMBINED)) {
+ continue;
+ }
+
+ if (rp->rect != NULL) {
+ continue;
+ }
+
+ const size_t rectsize = ((size_t)rr->rectx) * rr->recty * rp->channels;
+ rp->rect = MEM_callocN(sizeof(float) * rectsize, rp->name);
+
+ if (STREQ(rp->name, RE_PASSNAME_VECTOR)) {
+ /* initialize to max speed */
+ float *rect = rp->rect;
+ for (int x = rectsize - 1; x >= 0; x--) {
+ rect[x] = PASS_VECTOR_MAX;
+ }
+ }
+ else if (STREQ(rp->name, RE_PASSNAME_Z)) {
+ float *rect = rp->rect;
+ for (int x = rectsize - 1; x >= 0; x--) {
+ rect[x] = 10e10;
+ }
+ }
+ }
+ }
+
+ rr->passes_allocated = true;
+}
+
void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
{
RenderLayer *rl;
@@ -1243,6 +1251,7 @@ void render_result_exr_file_end(Render *re, RenderEngine *engine)
render_result_free_list(&re->fullresult, re->result);
re->result = render_result_new(re, &re->disprect, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
re->result->stamp_data = stamp_data;
+ render_result_passes_allocated_ensure(re->result);
BLI_rw_mutex_unlock(&re->resultmutex);
LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) {
diff --git a/source/blender/render/intern/render_result.h b/source/blender/render/intern/render_result.h
index 7732c113700..1fc64a4ea97 100644
--- a/source/blender/render/intern/render_result.h
+++ b/source/blender/render/intern/render_result.h
@@ -55,6 +55,8 @@ struct RenderResult *render_result_new(struct Render *re,
const char *layername,
const char *viewname);
+void render_result_passes_allocated_ensure(struct RenderResult *rr);
+
struct RenderResult *render_result_new_from_exr(
void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty);