diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-09-04 17:29:07 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-09-04 17:29:07 +0400 |
commit | adea12cb01e4c4f18f345dfbbf49e9e622192e4e (patch) | |
tree | b43018344c696e4d59437fabc7f17f5b9d6a8e80 /intern/cycles/blender/blender_session.cpp | |
parent | 68563134d4800be4eb46aa6b598fd719cdaf2980 (diff) |
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.
Diffstat (limited to 'intern/cycles/blender/blender_session.cpp')
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 209 |
1 files changed, 145 insertions, 64 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index d09e43bd76d..7b80c520e72 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -42,14 +42,13 @@ CCL_NAMESPACE_BEGIN BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_, BL::BlendData b_data_, BL::Scene b_scene_) : b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_), - b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL), - b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL) + b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL) { /* offline render */ - BL::RenderSettings r = b_scene.render(); - width = (int)(r.resolution_x()*r.resolution_percentage()/100); - height = (int)(r.resolution_y()*r.resolution_percentage()/100); + width = b_engine.resolution_x(); + height = b_engine.resolution_y(); + background = true; last_redraw_time = 0.0f; @@ -60,7 +59,7 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b BL::BlendData b_data_, BL::Scene b_scene_, BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_) : b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_), - b_v3d(b_v3d_), b_rv3d(b_rv3d_), b_rr(PointerRNA_NULL), b_rlay(PointerRNA_NULL) + b_v3d(b_v3d_), b_rv3d(b_rv3d_) { /* 3d view render */ width = width_; @@ -80,17 +79,24 @@ BlenderSession::~BlenderSession() void BlenderSession::create_session() { SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); - SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); + SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); /* reset status/progress */ last_status = ""; last_progress = -1.0f; /* create scene */ - scene = new Scene(scene_params); + scene = new Scene(scene_params, session_params.device); + + /* create session */ + session = new Session(session_params); + session->scene = scene; + session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this)); + session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this)); + session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* create sync */ - sync = new BlenderSync(b_data, b_scene, scene, !background); + sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress); sync->sync_data(b_v3d, b_engine.camera_override()); if(b_rv3d) @@ -98,13 +104,6 @@ void BlenderSession::create_session() else sync->sync_camera(b_engine.camera_override(), width, height); - /* create session */ - session = new Session(session_params); - session->scene = scene; - session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this)); - session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this)); - session->set_pause(BlenderSync::get_session_pause(b_scene, background)); - /* set buffer parameters */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); session->reset(buffer_params, session_params.samples); @@ -177,35 +176,100 @@ static PassType get_pass_type(BL::RenderPass b_pass) return PASS_NONE; } +static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername) +{ + RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, x, y, w, h, layername); + PointerRNA rrptr; + RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr); + return BL::RenderResult(rrptr); +} + +static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr, bool cancel = false) +{ + RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data, (int)cancel); +} + +void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only) +{ + BufferParams& params = rtile.buffers->params; + int x = params.full_x - session->tile_manager.params.full_x; + int y = params.full_y - session->tile_manager.params.full_y; + int w = params.width; + int h = params.height; + + /* get render result */ + BL::RenderResult b_rr = begin_render_result(b_engine, x, y, w, h, b_rlay_name.c_str()); + + /* can happen if the intersected rectangle gives 0 width or height */ + if (b_rr.ptr.data == NULL) { + return; + } + + BL::RenderResult::layers_iterator b_single_rlay; + b_rr.layers.begin(b_single_rlay); + BL::RenderLayer b_rlay = *b_single_rlay; + + if (do_update_only) { + /* update only needed */ + update_render_result(b_rr, b_rlay, rtile); + end_render_result(b_engine, b_rr, true); + } + else { + /* write result */ + write_render_result(b_rr, b_rlay, rtile); + end_render_result(b_engine, b_rr); + } +} + +void BlenderSession::write_render_tile(RenderTile& rtile) +{ + do_write_update_render_tile(rtile, false); +} + +void BlenderSession::update_render_tile(RenderTile& rtile) +{ + do_write_update_render_tile(rtile, true); +} + void BlenderSession::render() { + /* set callback to write out render results */ + session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1); + session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1); + /* get buffer parameters */ - SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); + SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); - int w = buffer_params.width, h = buffer_params.height; - - /* create render result */ - RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h); - PointerRNA rrptr; - RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr); - b_rr = BL::RenderResult(rrptr); + /* render each layer */ BL::RenderSettings r = b_scene.render(); - BL::RenderResult::layers_iterator b_iter; - BL::RenderLayers b_rr_layers(r.ptr); + BL::RenderSettings::layers_iterator b_iter; - /* render each layer */ - for(b_rr.layers.begin(b_iter); b_iter != b_rr.layers.end(); ++b_iter) { - /* set layer */ - b_rlay = *b_iter; + for(r.layers.begin(b_iter); b_iter != r.layers.end(); ++b_iter) { + b_rlay_name = b_iter->name(); + + /* temporary render result to find needed passes */ + BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_rlay_name.c_str()); + BL::RenderResult::layers_iterator b_single_rlay; + b_rr.layers.begin(b_single_rlay); + + /* layer will be missing if it was disabled in the UI */ + if(b_single_rlay == b_rr.layers.end()) { + end_render_result(b_engine, b_rr, true); + continue; + } + + BL::RenderLayer b_rlay = *b_single_rlay; /* add passes */ vector<Pass> passes; Pass::add(PASS_COMBINED, passes); if(session_params.device.advanced_shading) { + + /* loop over passes */ BL::RenderLayer::passes_iterator b_pass_iter; - + for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) { BL::RenderPass b_pass(*b_pass_iter); PassType pass_type = get_pass_type(b_pass); @@ -217,13 +281,16 @@ void BlenderSession::render() } } + /* free result without merging */ + end_render_result(b_engine, b_rr, true); + buffer_params.passes = passes; scene->film->tag_passes_update(scene, passes); scene->film->tag_update(scene); scene->integrator->tag_update(scene); /* update scene */ - sync->sync_data(b_v3d, b_engine.camera_override(), b_iter->name().c_str()); + sync->sync_data(b_v3d, b_engine.camera_override(), b_rlay_name.c_str()); /* update session */ int samples = sync->get_layer_samples(); @@ -235,19 +302,16 @@ void BlenderSession::render() if(session->progress.get_cancel()) break; - - /* write result */ - write_render_result(); } - /* delete render result */ - RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data); + /* clear callback */ + session->write_render_tile_cb = NULL; + session->update_render_tile_cb = NULL; } -void BlenderSession::write_render_result() +void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only) { - /* get state */ - RenderBuffers *buffers = session->buffers; + RenderBuffers *buffers = rtile.buffers; /* copy data from device */ if(!buffers->copy_from_device()) @@ -255,41 +319,49 @@ void BlenderSession::write_render_result() BufferParams& params = buffers->params; float exposure = scene->film->exposure; - double total_time, sample_time; - int sample; - - session->progress.get_sample(sample, total_time, sample_time); vector<float> pixels(params.width*params.height*4); - /* copy each pass */ - BL::RenderLayer::passes_iterator b_iter; - - for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { - BL::RenderPass b_pass(*b_iter); + if (!do_update_only) { + /* copy each pass */ + BL::RenderLayer::passes_iterator b_iter; + + for(b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { + BL::RenderPass b_pass(*b_iter); - /* find matching pass type */ - PassType pass_type = get_pass_type(b_pass); - int components = b_pass.channels(); + /* find matching pass type */ + PassType pass_type = get_pass_type(b_pass); + int components = b_pass.channels(); - /* copy pixels */ - if(buffers->get_pass(pass_type, exposure, sample, components, &pixels[0])) - rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]); + /* copy pixels */ + if(buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0])) + rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]); + } } /* copy combined pass */ - if(buffers->get_pass(PASS_COMBINED, exposure, sample, 4, &pixels[0])) + if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0])) rna_RenderLayer_rect_set(&b_rlay.ptr, &pixels[0]); /* tag result as updated */ RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data); } +void BlenderSession::write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile) +{ + do_write_update_render_result(b_rr, b_rlay, rtile, false); +} + +void BlenderSession::update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile) +{ + do_write_update_render_result(b_rr, b_rlay, rtile, true); +} + void BlenderSession::synchronize() { /* on session/scene parameter changes, we recreate session entirely */ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); - SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); + SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); if(session->params.modified(session_params) || scene->params.modified(scene_params)) @@ -364,7 +436,7 @@ bool BlenderSession::draw(int w, int h) /* reset if requested */ if(reset) { - SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); + SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, w, h); session->reset(buffer_params, session_params.samples); @@ -387,11 +459,16 @@ void BlenderSession::get_status(string& status, string& substatus) void BlenderSession::get_progress(float& progress, double& total_time) { - double sample_time; - int sample; + double tile_time; + int tile, sample, samples_per_tile; + int tile_total = session->tile_manager.state.num_tiles; + + session->progress.get_tile(tile, total_time, tile_time); - session->progress.get_sample(sample, total_time, sample_time); - progress = ((float)sample/(float)session->params.samples); + sample = session->progress.get_sample(); + samples_per_tile = session->tile_manager.state.num_samples; + + progress = ((float)sample/(float)(tile_total * samples_per_tile)); } void BlenderSession::update_status_progress() @@ -404,8 +481,13 @@ void BlenderSession::update_status_progress() get_status(status, substatus); get_progress(progress, total_time); + timestatus = b_scene.name(); + if(b_rlay_name != "") + timestatus += ", " + b_rlay_name; + timestatus += " | "; + BLI_timestr(total_time, time_str); - timestatus = "Elapsed: " + string(time_str) + " | "; + timestatus += "Elapsed: " + string(time_str) + " | "; if(substatus.size() > 0) status += " | " + substatus; @@ -435,7 +517,6 @@ void BlenderSession::tag_redraw() /* offline render, redraw if timeout passed */ if(time_dt() - last_redraw_time > 1.0) { - write_render_result(); engine_tag_redraw((RenderEngine*)b_engine.ptr.data); last_redraw_time = time_dt(); } |