Cycles: merge of changes from tomato branch.
Regular rendering now works tiled, and supports save buffers to save memory during render and cache render results. Brick texture node by Thomas. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Brick_Texture Image texture Blended Box Mapping. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Image_Texture http://mango.blender.org/production/blended_box/ Various bug fixes by Sergey and Campbell. * Fix for reading freed memory in some node setups. * Fix incorrect memory read when synchronizing mesh motion. * Fix crash appearing when direct light usage is different on different layers. * Fix for vector pass gives wrong result in some circumstances. * Fix for wrong resolution used for rendering Render Layer node. * Option to cancel rendering when doing initial synchronization. * No more texture limit when using CPU render. * Many fixes for new tiled rendering.
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
#include "RE_engine.h"
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
#include "initrender.h"
|
||||
#include "render_types.h"
|
||||
#include "render_result.h"
|
||||
|
||||
@@ -149,7 +150,7 @@ void RE_engine_free(RenderEngine *engine)
|
||||
|
||||
/* Render Results */
|
||||
|
||||
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h)
|
||||
RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername)
|
||||
{
|
||||
Render *re = engine->re;
|
||||
RenderResult *result;
|
||||
@@ -172,7 +173,9 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
|
||||
disprect.ymin = y;
|
||||
disprect.ymax = y + h;
|
||||
|
||||
result = render_result_new(re, &disprect, 0, RR_USE_MEM);
|
||||
result = render_result_new(re, &disprect, 0, RR_USE_MEM, layername);
|
||||
|
||||
/* todo: make this thread safe */
|
||||
|
||||
/* can be NULL if we CLAMP the width or height to 0 */
|
||||
if (result) {
|
||||
@@ -197,25 +200,41 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
|
||||
}
|
||||
}
|
||||
|
||||
void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
|
||||
void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel)
|
||||
{
|
||||
Render *re = engine->re;
|
||||
RenderPart *pa;
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
/* merge. on break, don't merge in result for preview renders, looks nicer */
|
||||
if (!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
|
||||
render_result_merge(re->result, result);
|
||||
if (!cancel) {
|
||||
/* for exr tile render, detect tiles that are done */
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (result->tilerect.xmin == pa->disprect.xmin &&
|
||||
result->tilerect.ymin == pa->disprect.ymin &&
|
||||
result->tilerect.xmax == pa->disprect.xmax &&
|
||||
result->tilerect.ymax == pa->disprect.ymax) {
|
||||
pa->ready = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw */
|
||||
if (!re->test_break(re->tbh)) {
|
||||
result->renlay = result->layers.first; /* weak, draws first layer always */
|
||||
re->display_draw(re->ddh, result, NULL);
|
||||
if (re->result->do_exr_tile)
|
||||
render_result_exr_file_merge(re->result, result);
|
||||
else if (!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
|
||||
render_result_merge(re->result, result);
|
||||
|
||||
/* draw */
|
||||
if (!re->test_break(re->tbh)) {
|
||||
result->renlay = result->layers.first; /* weak, draws first layer always */
|
||||
re->display_draw(re->ddh, result, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* free */
|
||||
render_result_free_list(&engine->fullresult, result);
|
||||
BLI_remlink(&engine->fullresult, result);
|
||||
render_result_free(result);
|
||||
}
|
||||
|
||||
/* Cancel */
|
||||
@@ -294,12 +313,16 @@ int RE_engine_render(Render *re, int do_all)
|
||||
/* create render result */
|
||||
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
|
||||
if (re->result == NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
|
||||
int savebuffers;
|
||||
|
||||
if (re->result)
|
||||
render_result_free(re->result);
|
||||
re->result = render_result_new(re, &re->disprect, 0, 0);
|
||||
|
||||
savebuffers = (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM;
|
||||
re->result = render_result_new(re, &re->disprect, 0, savebuffers, RR_ALL_LAYERS);
|
||||
}
|
||||
BLI_rw_mutex_unlock(&re->resultmutex);
|
||||
|
||||
|
||||
if (re->result == NULL)
|
||||
return 1;
|
||||
|
||||
@@ -318,14 +341,35 @@ int RE_engine_render(Render *re, int do_all)
|
||||
engine->flag |= RE_ENGINE_PREVIEW;
|
||||
engine->camera_override = re->camera_override;
|
||||
|
||||
engine->resolution_x = re->winx;
|
||||
engine->resolution_y = re->winy;
|
||||
|
||||
if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_PREVIEWBUTS)) == 0)
|
||||
BKE_scene_update_for_newframe(re->main, re->scene, re->lay);
|
||||
|
||||
initparts(re, FALSE);
|
||||
engine->tile_x = re->partx;
|
||||
engine->tile_y = re->party;
|
||||
|
||||
if (re->result->do_exr_tile)
|
||||
render_result_exr_file_begin(re);
|
||||
|
||||
if (type->update)
|
||||
type->update(engine, re->main, re->scene);
|
||||
|
||||
if (type->render)
|
||||
type->render(engine, re->scene);
|
||||
|
||||
if (re->result->do_exr_tile) {
|
||||
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
|
||||
render_result_exr_file_end(re);
|
||||
BLI_rw_mutex_unlock(&re->resultmutex);
|
||||
}
|
||||
|
||||
engine->tile_x = 0;
|
||||
engine->tile_y = 0;
|
||||
freeparts(re);
|
||||
|
||||
render_result_free_list(&engine->fullresult, engine->fullresult.first);
|
||||
|
||||
RE_engine_free(engine);
|
||||
|
||||
@@ -537,7 +537,7 @@ void freeparts(Render *re)
|
||||
BLI_freelistN(&re->parts);
|
||||
}
|
||||
|
||||
void initparts(Render *re)
|
||||
void initparts(Render *re, int do_crop)
|
||||
{
|
||||
int nr, xd, yd, partx, party, xparts, yparts;
|
||||
int xminb, xmaxb, yminb, ymaxb;
|
||||
@@ -618,7 +618,7 @@ void initparts(Render *re)
|
||||
RenderPart *pa = MEM_callocN(sizeof(RenderPart), "new part");
|
||||
|
||||
/* Non-box filters need 2 pixels extra to work */
|
||||
if ((re->r.filtertype || (re->r.mode & R_EDGE))) {
|
||||
if (do_crop && (re->r.filtertype || (re->r.mode & R_EDGE))) {
|
||||
pa->crop = 2;
|
||||
disprect.xmin -= pa->crop;
|
||||
disprect.ymin -= pa->crop;
|
||||
|
||||
@@ -640,7 +640,7 @@ static void *do_part_thread(void *pa_v)
|
||||
if (!R.sss_points && (R.r.scemode & R_FULL_SAMPLE))
|
||||
pa->result = render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM);
|
||||
else
|
||||
pa->result = render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM);
|
||||
pa->result = render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
|
||||
if (R.sss_points)
|
||||
zbufshade_sss_tile(pa);
|
||||
@@ -650,7 +650,7 @@ static void *do_part_thread(void *pa_v)
|
||||
zbufshade_tile(pa);
|
||||
|
||||
/* merge too on break! */
|
||||
if (R.result->exrhandle) {
|
||||
if (R.result->do_exr_tile) {
|
||||
render_result_exr_file_merge(R.result, pa->result);
|
||||
}
|
||||
else if (render_display_draw_enabled(&R)) {
|
||||
@@ -794,12 +794,12 @@ static void threaded_tile_processor(Render *re)
|
||||
render_result_free(re->result);
|
||||
|
||||
if (re->sss_points && render_display_draw_enabled(re))
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
else if (re->r.scemode & R_FULL_SAMPLE)
|
||||
re->result = render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR);
|
||||
else
|
||||
re->result = render_result_new(re, &re->disprect, 0,
|
||||
(re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM);
|
||||
(re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM, RR_ALL_LAYERS);
|
||||
}
|
||||
|
||||
BLI_rw_mutex_unlock(&re->resultmutex);
|
||||
@@ -809,9 +809,9 @@ static void threaded_tile_processor(Render *re)
|
||||
|
||||
/* warning; no return here without closing exr file */
|
||||
|
||||
initparts(re);
|
||||
initparts(re, TRUE);
|
||||
|
||||
if (re->result->exrhandle)
|
||||
if (re->result->do_exr_tile)
|
||||
render_result_exr_file_begin(re);
|
||||
|
||||
BLI_init_threads(&threads, do_part_thread, re->r.threads);
|
||||
@@ -891,7 +891,7 @@ static void threaded_tile_processor(Render *re)
|
||||
|
||||
}
|
||||
|
||||
if (re->result->exrhandle) {
|
||||
if (re->result->do_exr_tile) {
|
||||
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
|
||||
render_result_exr_file_end(re);
|
||||
BLI_rw_mutex_unlock(&re->resultmutex);
|
||||
@@ -1044,7 +1044,7 @@ static void do_render_blur_3d(Render *re)
|
||||
int blur = re->r.mblur_samples;
|
||||
|
||||
/* create accumulation render result */
|
||||
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM);
|
||||
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
|
||||
/* do the blur steps */
|
||||
while (blur--) {
|
||||
@@ -1169,7 +1169,7 @@ static void do_render_fields_3d(Render *re)
|
||||
re->disprect.ymax *= 2;
|
||||
|
||||
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
|
||||
if (rr2) {
|
||||
if (re->r.mode & R_ODDFIELD)
|
||||
@@ -1232,7 +1232,7 @@ static void do_render_fields_blur_3d(Render *re)
|
||||
re->rectx = re->winx;
|
||||
re->recty = re->winy;
|
||||
|
||||
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM);
|
||||
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
|
||||
render_result_merge(rres, re->result);
|
||||
render_result_free(re->result);
|
||||
@@ -1552,7 +1552,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
|
||||
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
|
||||
|
||||
render_result_free(re->result);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
|
||||
BLI_rw_mutex_unlock(&re->resultmutex);
|
||||
|
||||
@@ -1847,7 +1847,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r
|
||||
if (scene->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) {
|
||||
char str[FILE_MAX];
|
||||
|
||||
render_result_exr_file_path(scene, 0, str);
|
||||
render_result_exr_file_path(scene, "", 0, str);
|
||||
|
||||
if (BLI_file_is_writable(str) == 0) {
|
||||
BKE_report(reports, RPT_ERROR, "Can not save render buffers, check the temp default path");
|
||||
@@ -1931,7 +1931,7 @@ static void validate_render_settings(Render *re)
|
||||
|
||||
if (RE_engine_is_external(re)) {
|
||||
/* not supported yet */
|
||||
re->r.scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE);
|
||||
re->r.scemode &= ~(R_FULL_SAMPLE);
|
||||
re->r.mode &= ~(R_FIELDS | R_MBLUR);
|
||||
}
|
||||
}
|
||||
@@ -2421,7 +2421,7 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char
|
||||
|
||||
void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename)
|
||||
{
|
||||
if (!render_result_exr_file_read_path(result, filename)) {
|
||||
if (!render_result_exr_file_read_path(result, NULL, filename)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "RE_result_rect_from_file: failed to load '%s'\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -384,10 +384,10 @@ static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channel
|
||||
rpass->recty = rl->recty;
|
||||
BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
|
||||
|
||||
if (rr->exrhandle) {
|
||||
if (rl->exrhandle) {
|
||||
int a;
|
||||
for (a = 0; a < channels; a++)
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
|
||||
}
|
||||
else {
|
||||
float *rect;
|
||||
@@ -413,7 +413,7 @@ static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channel
|
||||
/* will read info from Render *re to define layers */
|
||||
/* called in threads */
|
||||
/* re->winx,winy is coordinate space of entire image, partrct the part within */
|
||||
RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers)
|
||||
RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername)
|
||||
{
|
||||
RenderResult *rr;
|
||||
RenderLayer *rl;
|
||||
@@ -435,17 +435,21 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
|
||||
|
||||
/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
|
||||
rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
|
||||
rr->tilerect.xmax = partrct->xmax - re->disprect.xmax;
|
||||
rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
|
||||
rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
|
||||
rr->tilerect.ymax = partrct->ymax - re->disprect.ymax;
|
||||
rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
|
||||
|
||||
if (savebuffers) {
|
||||
rr->exrhandle = IMB_exr_get_handle();
|
||||
rr->do_exr_tile = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* check renderdata for amount of layers */
|
||||
for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {
|
||||
|
||||
|
||||
if (layername && layername[0])
|
||||
if (strcmp(srl->name, layername) != 0)
|
||||
continue;
|
||||
|
||||
if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay)
|
||||
continue;
|
||||
if (srl->layflag & SCE_LAY_DISABLE)
|
||||
@@ -466,11 +470,13 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
|
||||
rl->rectx = rectx;
|
||||
rl->recty = recty;
|
||||
|
||||
if (rr->exrhandle) {
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
|
||||
if (rr->do_exr_tile) {
|
||||
rl->exrhandle = IMB_exr_get_handle();
|
||||
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
|
||||
}
|
||||
else
|
||||
rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
|
||||
@@ -532,7 +538,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
|
||||
|
||||
}
|
||||
/* sss, previewrender and envmap don't do layers, so we make a default one */
|
||||
if (rr->layers.first == NULL) {
|
||||
if (rr->layers.first == NULL && !(layername && layername[0])) {
|
||||
rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
|
||||
BLI_addtail(&rr->layers, rl);
|
||||
|
||||
@@ -540,11 +546,13 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
|
||||
rl->recty = recty;
|
||||
|
||||
/* duplicate code... */
|
||||
if (rr->exrhandle) {
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
|
||||
if (rr->do_exr_tile) {
|
||||
rl->exrhandle = IMB_exr_get_handle();
|
||||
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
|
||||
IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
|
||||
}
|
||||
else
|
||||
rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
|
||||
@@ -570,10 +578,10 @@ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *part
|
||||
int a;
|
||||
|
||||
if (re->osa == 0)
|
||||
return render_result_new(re, partrct, crop, savebuffers);
|
||||
return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
|
||||
|
||||
for (a = 0; a < re->osa; a++) {
|
||||
RenderResult *rr = render_result_new(re, partrct, crop, savebuffers);
|
||||
RenderResult *rr = render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
|
||||
BLI_addtail(lb, rr);
|
||||
rr->sample_nr = a;
|
||||
}
|
||||
@@ -682,15 +690,18 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
|
||||
RenderLayer *rl, *rlp;
|
||||
RenderPass *rpass, *rpassp;
|
||||
|
||||
for (rl = rr->layers.first, rlp = rrpart->layers.first; rl && rlp; rl = rl->next, rlp = rlp->next) {
|
||||
|
||||
/* combined */
|
||||
if (rl->rectf && rlp->rectf)
|
||||
do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
|
||||
|
||||
/* passes are allocated in sync */
|
||||
for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp; rpass = rpass->next, rpassp = rpassp->next) {
|
||||
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
|
||||
for (rl = rr->layers.first; rl; rl = rl->next) {
|
||||
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
|
||||
if (strcmp(rlp->name, rl->name) == 0) {
|
||||
/* combined */
|
||||
if (rl->rectf && rlp->rectf)
|
||||
do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
|
||||
|
||||
/* passes are allocated in sync */
|
||||
for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp; rpass = rpass->next, rpassp = rpassp->next) {
|
||||
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,13 +838,16 @@ void render_result_single_layer_end(Render *re)
|
||||
|
||||
static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
|
||||
{
|
||||
RenderLayer *rlp;
|
||||
RenderLayer *rlp, *rl;
|
||||
RenderPass *rpassp;
|
||||
int offs, partx, party;
|
||||
|
||||
BLI_lock_thread(LOCK_IMAGE);
|
||||
|
||||
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
|
||||
for (rl = rr->layers.first; rl; rl = rl->next)
|
||||
if (strcmp(rl->name, rlp->name) == 0)
|
||||
break;
|
||||
|
||||
if (rrpart->crop) { /* filters add pixel extra */
|
||||
offs = (rrpart->crop + rrpart->crop * rrpart->rectx);
|
||||
@@ -846,7 +860,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
|
||||
if (rlp->rectf) {
|
||||
int a, xstride = 4;
|
||||
for (a = 0; a < xstride; a++)
|
||||
IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
|
||||
IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
|
||||
xstride, xstride * rrpart->rectx, rlp->rectf + a + xstride * offs);
|
||||
}
|
||||
|
||||
@@ -854,7 +868,7 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
|
||||
for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
|
||||
int a, xstride = rpassp->channels;
|
||||
for (a = 0; a < xstride; a++)
|
||||
IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
|
||||
IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
|
||||
xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
|
||||
}
|
||||
|
||||
@@ -862,7 +876,14 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
|
||||
|
||||
party = rrpart->tilerect.ymin + rrpart->crop;
|
||||
partx = rrpart->tilerect.xmin + rrpart->crop;
|
||||
IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
|
||||
|
||||
for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
|
||||
for (rl = rr->layers.first; rl; rl = rl->next)
|
||||
if (strcmp(rl->name, rlp->name) == 0)
|
||||
break;
|
||||
|
||||
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
|
||||
}
|
||||
|
||||
BLI_unlock_thread(LOCK_IMAGE);
|
||||
}
|
||||
@@ -871,15 +892,18 @@ static void save_empty_result_tiles(Render *re)
|
||||
{
|
||||
RenderPart *pa;
|
||||
RenderResult *rr;
|
||||
RenderLayer *rl;
|
||||
|
||||
for (rr = re->result; rr; rr = rr->next) {
|
||||
IMB_exrtile_clear_channels(rr->exrhandle);
|
||||
for (rl = rr->layers.first; rl; rl = rl->next) {
|
||||
IMB_exrtile_clear_channels(rl->exrhandle);
|
||||
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready == 0) {
|
||||
int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
|
||||
int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
|
||||
IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
|
||||
for (pa = re->parts.first; pa; pa = pa->next) {
|
||||
if (pa->ready == 0) {
|
||||
int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
|
||||
int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
|
||||
IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -889,13 +913,15 @@ static void save_empty_result_tiles(Render *re)
|
||||
void render_result_exr_file_begin(Render *re)
|
||||
{
|
||||
RenderResult *rr;
|
||||
RenderLayer *rl;
|
||||
char str[FILE_MAX];
|
||||
|
||||
|
||||
for (rr = re->result; rr; rr = rr->next) {
|
||||
render_result_exr_file_path(re->scene, rr->sample_nr, str);
|
||||
|
||||
printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
|
||||
IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
|
||||
for (rl = rr->layers.first; rl; rl = rl->next) {
|
||||
render_result_exr_file_path(re->scene, rl->name, rr->sample_nr, str);
|
||||
printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
|
||||
IMB_exrtile_begin_write(rl->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -903,12 +929,17 @@ void render_result_exr_file_begin(Render *re)
|
||||
void render_result_exr_file_end(Render *re)
|
||||
{
|
||||
RenderResult *rr;
|
||||
RenderLayer *rl;
|
||||
|
||||
save_empty_result_tiles(re);
|
||||
|
||||
for (rr = re->result; rr; rr = rr->next) {
|
||||
IMB_exr_close(rr->exrhandle);
|
||||
rr->exrhandle = NULL;
|
||||
for (rl = rr->layers.first; rl; rl = rl->next) {
|
||||
IMB_exr_close(rl->exrhandle);
|
||||
rl->exrhandle = NULL;
|
||||
}
|
||||
|
||||
rr->do_exr_tile = FALSE;
|
||||
}
|
||||
|
||||
render_result_free_list(&re->fullresult, re->result);
|
||||
@@ -925,17 +956,17 @@ void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
|
||||
}
|
||||
|
||||
/* path to temporary exr file */
|
||||
void render_result_exr_file_path(Scene *scene, int sample, char *filepath)
|
||||
void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
|
||||
{
|
||||
char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
|
||||
char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
|
||||
|
||||
BLI_strncpy(di, G.main->name, FILE_MAX);
|
||||
BLI_splitdirstring(di, fi);
|
||||
|
||||
if (sample == 0)
|
||||
BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name + 2);
|
||||
BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
|
||||
else
|
||||
BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name + 2, sample);
|
||||
BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
|
||||
|
||||
BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
|
||||
}
|
||||
@@ -943,29 +974,30 @@ void render_result_exr_file_path(Scene *scene, int sample, char *filepath)
|
||||
/* only for temp buffer files, makes exact copy of render result */
|
||||
int render_result_exr_file_read(Render *re, int sample)
|
||||
{
|
||||
RenderLayer *rl;
|
||||
char str[FILE_MAX];
|
||||
int success;
|
||||
int success = TRUE;
|
||||
|
||||
RE_FreeRenderResult(re->result);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM);
|
||||
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
|
||||
|
||||
render_result_exr_file_path(re->scene, sample, str);
|
||||
printf("read exr tmp file: %s\n", str);
|
||||
for (rl = re->result->layers.first; rl; rl = rl->next) {
|
||||
|
||||
if (render_result_exr_file_read_path(re->result, str)) {
|
||||
success = TRUE;
|
||||
}
|
||||
else {
|
||||
printf("cannot read: %s\n", str);
|
||||
success = FALSE;
|
||||
render_result_exr_file_path(re->scene, rl->name, sample, str);
|
||||
printf("read exr tmp file: %s\n", str);
|
||||
|
||||
if (!render_result_exr_file_read_path(re->result, rl, str)) {
|
||||
printf("cannot read: %s\n", str);
|
||||
success = FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/* called for reading temp files, and for external engines */
|
||||
int render_result_exr_file_read_path(RenderResult *rr, const char *filepath)
|
||||
int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, const char *filepath)
|
||||
{
|
||||
RenderLayer *rl;
|
||||
RenderPass *rpass;
|
||||
@@ -988,6 +1020,9 @@ int render_result_exr_file_read_path(RenderResult *rr, const char *filepath)
|
||||
}
|
||||
|
||||
for (rl = rr->layers.first; rl; rl = rl->next) {
|
||||
if (rl_single && rl_single != rl)
|
||||
continue;
|
||||
|
||||
/* combined */
|
||||
if (rl->rectf) {
|
||||
int a, xstride = 4;
|
||||
|
||||
Reference in New Issue
Block a user