Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_session.cpp
| Show First 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | void BlenderSession::create_session() | ||||
| /* reset status/progress */ | /* reset status/progress */ | ||||
| last_status = ""; | last_status = ""; | ||||
| last_error = ""; | last_error = ""; | ||||
| last_progress = -1.0f; | last_progress = -1.0f; | ||||
| start_resize_time = 0.0; | start_resize_time = 0.0; | ||||
| /* create session */ | /* create session */ | ||||
| session = new Session(session_params); | session = new Session(session_params); | ||||
| session->scene = scene; | session->set_scene(scene); | ||||
| session->progress.set_update_callback(function_bind(&BlenderSession::tag_redraw, this)); | session->get_progress().set_update_callback(function_bind(&BlenderSession::tag_redraw, this)); | ||||
| session->progress.set_cancel_callback(function_bind(&BlenderSession::test_cancel, this)); | session->get_progress().set_cancel_callback(function_bind(&BlenderSession::test_cancel, this)); | ||||
| session->set_pause(session_pause); | session->set_pause(session_pause); | ||||
| /* create scene */ | /* create scene */ | ||||
| scene = new Scene(scene_params, session->device); | scene = new Scene(scene_params, session->get_device()); | ||||
| scene->name = b_scene.name(); | scene->set_name(b_scene.name()); | ||||
| session->scene = scene; | session->set_scene(scene); | ||||
| /* There is no single depsgraph to use for the entire render. | /* There is no single depsgraph to use for the entire render. | ||||
| * So we need to handle this differently. | * So we need to handle this differently. | ||||
| * | * | ||||
| * We could loop over the final render result render layers in pipeline and keep Cycles unaware | * We could loop over the final render result render layers in pipeline and keep Cycles unaware | ||||
| * of multiple layers, or perhaps move syncing further down in the pipeline. | * of multiple layers, or perhaps move syncing further down in the pipeline. | ||||
| */ | */ | ||||
| /* create sync */ | /* create sync */ | ||||
| sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress); | sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->get_progress()); | ||||
| BL::Object b_camera_override(b_engine.camera_override()); | BL::Object b_camera_override(b_engine.camera_override()); | ||||
| if (b_v3d) { | if (b_v3d) { | ||||
| sync->sync_view(b_v3d, b_rv3d, width, height); | sync->sync_view(b_v3d, b_rv3d, width, height); | ||||
| } | } | ||||
| else { | else { | ||||
| sync->sync_camera(b_render, b_camera_override, width, height, ""); | sync->sync_camera(b_render, b_camera_override, width, height, ""); | ||||
| } | } | ||||
| /* set buffer parameters */ | /* set buffer parameters */ | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params( | ||||
| b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); | b_render, b_v3d, b_rv3d, scene->get_camera(), width, height, session_params.denoising.use); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| b_engine.use_highlight_tiles(session_params.progressive_refine == false); | b_engine.use_highlight_tiles(session_params.progressive_refine == false); | ||||
| update_resumable_tile_manager(session_params.samples); | update_resumable_tile_manager(session_params.samples); | ||||
| } | } | ||||
| void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph) | void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph) | ||||
| Show All 34 Lines | if (b_v3d) { | ||||
| */ | */ | ||||
| return; | return; | ||||
| } | } | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background); | b_engine, b_userpref, b_scene, background); | ||||
| SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); | SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); | ||||
| if (scene->params.modified(scene_params) || session->params.modified(session_params) || | if (scene->get_params().modified(scene_params) || | ||||
| !scene_params.persistent_data) { | session->get_params().modified(session_params) || !scene_params.persistent_data) { | ||||
| /* if scene or session parameters changed, it's easier to simply re-create | /* if scene or session parameters changed, it's easier to simply re-create | ||||
| * them rather than trying to distinguish which settings need to be updated | * them rather than trying to distinguish which settings need to be updated | ||||
| */ | */ | ||||
| if (!is_new_session) { | if (!is_new_session) { | ||||
| free_session(); | free_session(); | ||||
| create_session(); | create_session(); | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| session->progress.reset(); | session->get_progress().reset(); | ||||
| scene->reset(); | scene->reset(); | ||||
| session->tile_manager.set_tile_order(session_params.tile_order); | session->get_tile_manager().set_tile_order(session_params.tile_order); | ||||
| /* peak memory usage should show current render peak, not peak for all renders | /* peak memory usage should show current render peak, not peak for all renders | ||||
| * made by this render session | * made by this render session | ||||
| */ | */ | ||||
| session->stats.mem_peak = session->stats.mem_used; | session->get_stats().set_mem_peak(session->get_stats().get_mem_used()); | ||||
| /* There is no single depsgraph to use for the entire render. | /* There is no single depsgraph to use for the entire render. | ||||
| * See note on create_session(). | * See note on create_session(). | ||||
| */ | */ | ||||
| /* sync object should be re-created */ | /* sync object should be re-created */ | ||||
| delete sync; | delete sync; | ||||
| sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress); | sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->get_progress()); | ||||
| BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL); | BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL); | ||||
| BL::RegionView3D b_null_region_view3d(PointerRNA_NULL); | BL::RegionView3D b_null_region_view3d(PointerRNA_NULL); | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, | BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, | ||||
| b_null_space_view3d, | b_null_space_view3d, | ||||
| b_null_region_view3d, | b_null_region_view3d, | ||||
| scene->camera, | scene->get_camera(), | ||||
| width, | width, | ||||
| height, | height, | ||||
| session_params.denoising.use); | session_params.denoising.use); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| b_engine.use_highlight_tiles(session_params.progressive_refine == false); | b_engine.use_highlight_tiles(session_params.progressive_refine == false); | ||||
| /* reset time */ | /* reset time */ | ||||
| ▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | static void end_render_result(BL::RenderEngine &b_engine, | ||||
| b_engine.end_result(b_rr, (int)cancel, (int)highlight, (int)do_merge_results); | b_engine.end_result(b_rr, (int)cancel, (int)highlight, (int)do_merge_results); | ||||
| } | } | ||||
| void BlenderSession::do_write_update_render_tile(RenderTile &rtile, | void BlenderSession::do_write_update_render_tile(RenderTile &rtile, | ||||
| bool do_update_only, | bool do_update_only, | ||||
| bool do_read_only, | bool do_read_only, | ||||
| bool highlight) | bool highlight) | ||||
| { | { | ||||
| int x = rtile.x - session->tile_manager.params.full_x; | int x = rtile.get_x() - session->get_tile_manager().get_params().get_full_x(); | ||||
| int y = rtile.y - session->tile_manager.params.full_y; | int y = rtile.get_y() - session->get_tile_manager().get_params().get_full_y(); | ||||
| int w = rtile.w; | int w = rtile.get_w(); | ||||
| int h = rtile.h; | int h = rtile.get_h(); | ||||
| /* get render result */ | /* get render result */ | ||||
| BL::RenderResult b_rr = begin_render_result( | BL::RenderResult b_rr = begin_render_result( | ||||
| b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str()); | b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str()); | ||||
| /* can happen if the intersected rectangle gives 0 width or height */ | /* can happen if the intersected rectangle gives 0 width or height */ | ||||
| if (b_rr.ptr.data == NULL) { | if (b_rr.ptr.data == NULL) { | ||||
| return; | return; | ||||
| Show All 14 Lines | if (do_read_only) { | ||||
| for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { | for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { | ||||
| BL::RenderPass b_pass(*b_iter); | BL::RenderPass b_pass(*b_iter); | ||||
| /* find matching pass type */ | /* find matching pass type */ | ||||
| PassType pass_type = BlenderSync::get_pass_type(b_pass); | PassType pass_type = BlenderSync::get_pass_type(b_pass); | ||||
| int components = b_pass.channels(); | int components = b_pass.channels(); | ||||
| rtile.buffers->set_pass_rect( | rtile.get_buffers()->set_pass_rect( | ||||
| pass_type, components, (float *)b_pass.rect(), rtile.num_samples); | pass_type, components, (float *)b_pass.rect(), rtile.get_num_samples()); | ||||
| } | } | ||||
| end_render_result(b_engine, b_rr, false, false, false); | end_render_result(b_engine, b_rr, false, false, false); | ||||
| } | } | ||||
| else if (do_update_only) { | else if (do_update_only) { | ||||
| /* Sample would be zero at initial tile update, which is only needed | /* Sample would be zero at initial tile update, which is only needed | ||||
| * to tag tile form blender side as IN PROGRESS for proper highlight | * to tag tile form blender side as IN PROGRESS for proper highlight | ||||
| * no buffers should be sent to blender yet. For denoise we also | * no buffers should be sent to blender yet. For denoise we also | ||||
| * keep showing the noisy buffers until denoise is done. */ | * keep showing the noisy buffers until denoise is done. */ | ||||
| bool merge = (rtile.sample != 0) && (rtile.task != RenderTile::DENOISE); | bool merge = (rtile.get_sample() != 0) && (rtile.get_task() != RenderTile::DENOISE); | ||||
| if (merge) { | if (merge) { | ||||
| update_render_result(b_rlay, rtile); | update_render_result(b_rlay, rtile); | ||||
| } | } | ||||
| end_render_result(b_engine, b_rr, true, highlight, merge); | end_render_result(b_engine, b_rr, true, highlight, merge); | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 38 Lines | |||||
| void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_layer_name) | void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_layer_name) | ||||
| { | { | ||||
| BL::RenderResult b_rr = b_engine.get_result(); | BL::RenderResult b_rr = b_engine.get_result(); | ||||
| string prefix = "cycles." + view_layer_name + "."; | string prefix = "cycles." + view_layer_name + "."; | ||||
| /* Configured number of samples for the view layer. */ | /* Configured number of samples for the view layer. */ | ||||
| b_rr.stamp_data_add_field((prefix + "samples").c_str(), | b_rr.stamp_data_add_field((prefix + "samples").c_str(), | ||||
| to_string(session->params.samples).c_str()); | to_string(session->get_params().samples).c_str()); | ||||
| /* Store ranged samples information. */ | /* Store ranged samples information. */ | ||||
| if (session->tile_manager.range_num_samples != -1) { | if (session->get_tile_manager().get_range_num_samples() != -1) { | ||||
| b_rr.stamp_data_add_field((prefix + "range_start_sample").c_str(), | b_rr.stamp_data_add_field( | ||||
| to_string(session->tile_manager.range_start_sample).c_str()); | (prefix + "range_start_sample").c_str(), | ||||
| b_rr.stamp_data_add_field((prefix + "range_num_samples").c_str(), | to_string(session->get_tile_manager().get_range_start_sample()).c_str()); | ||||
| to_string(session->tile_manager.range_num_samples).c_str()); | b_rr.stamp_data_add_field( | ||||
| (prefix + "range_num_samples").c_str(), | |||||
| to_string(session->get_tile_manager().get_range_num_samples()).c_str()); | |||||
| } | } | ||||
| /* Write cryptomatte metadata. */ | /* Write cryptomatte metadata. */ | ||||
| if (scene->film->get_cryptomatte_passes() & CRYPT_OBJECT) { | if (scene->get_film()->get_cryptomatte_passes() & CRYPT_OBJECT) { | ||||
| add_cryptomatte_layer(b_rr, | add_cryptomatte_layer(b_rr, | ||||
| view_layer_name + ".CryptoObject", | view_layer_name + ".CryptoObject", | ||||
| scene->object_manager->get_cryptomatte_objects(scene)); | scene->get_object_manager()->get_cryptomatte_objects(scene)); | ||||
| } | } | ||||
| if (scene->film->get_cryptomatte_passes() & CRYPT_MATERIAL) { | if (scene->get_film()->get_cryptomatte_passes() & CRYPT_MATERIAL) { | ||||
| add_cryptomatte_layer(b_rr, | add_cryptomatte_layer(b_rr, | ||||
| view_layer_name + ".CryptoMaterial", | view_layer_name + ".CryptoMaterial", | ||||
| scene->shader_manager->get_cryptomatte_materials(scene)); | scene->get_shader_manager()->get_cryptomatte_materials(scene)); | ||||
| } | } | ||||
| if (scene->film->get_cryptomatte_passes() & CRYPT_ASSET) { | if (scene->get_film()->get_cryptomatte_passes() & CRYPT_ASSET) { | ||||
| add_cryptomatte_layer(b_rr, | add_cryptomatte_layer(b_rr, | ||||
| view_layer_name + ".CryptoAsset", | view_layer_name + ".CryptoAsset", | ||||
| scene->object_manager->get_cryptomatte_assets(scene)); | scene->get_object_manager()->get_cryptomatte_assets(scene)); | ||||
| } | } | ||||
| /* Store synchronization and bare-render times. */ | /* Store synchronization and bare-render times. */ | ||||
| double total_time, render_time; | double total_time, render_time; | ||||
| session->progress.get_time(total_time, render_time); | session->get_progress().get_time(total_time, render_time); | ||||
| b_rr.stamp_data_add_field((prefix + "total_time").c_str(), | b_rr.stamp_data_add_field((prefix + "total_time").c_str(), | ||||
| time_human_readable_from_seconds(total_time).c_str()); | time_human_readable_from_seconds(total_time).c_str()); | ||||
| b_rr.stamp_data_add_field((prefix + "render_time").c_str(), | b_rr.stamp_data_add_field((prefix + "render_time").c_str(), | ||||
| time_human_readable_from_seconds(render_time).c_str()); | time_human_readable_from_seconds(render_time).c_str()); | ||||
| b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(), | b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(), | ||||
| time_human_readable_from_seconds(total_time - render_time).c_str()); | time_human_readable_from_seconds(total_time - render_time).c_str()); | ||||
| } | } | ||||
| void BlenderSession::render(BL::Depsgraph &b_depsgraph_) | void BlenderSession::render(BL::Depsgraph &b_depsgraph_) | ||||
| { | { | ||||
| b_depsgraph = b_depsgraph_; | b_depsgraph = b_depsgraph_; | ||||
| if (session->progress.get_cancel()) { | if (session->get_progress().get_cancel()) { | ||||
| update_status_progress(); | update_status_progress(); | ||||
| return; | return; | ||||
| } | } | ||||
| /* set callback to write out render results */ | /* set callback to write out render results */ | ||||
| session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1); | session->set_write_render_tile_cb(function_bind(&BlenderSession::write_render_tile, this, _1)); | ||||
| session->update_render_tile_cb = function_bind( | session->set_update_render_tile_cb( | ||||
| &BlenderSession::update_render_tile, this, _1, _2); | function_bind(&BlenderSession::update_render_tile, this, _1, _2)); | ||||
| BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); | BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); | ||||
| /* get buffer parameters */ | /* get buffer parameters */ | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background, b_view_layer); | b_engine, b_userpref, b_scene, background, b_view_layer); | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params( | ||||
| b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); | b_render, b_v3d, b_rv3d, scene->get_camera(), width, height, session_params.denoising.use); | ||||
| /* temporary render result to find needed passes and views */ | /* temporary render result to find needed passes and views */ | ||||
| BL::RenderResult b_rr = begin_render_result( | BL::RenderResult b_rr = begin_render_result( | ||||
| b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL); | b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL); | ||||
| BL::RenderResult::layers_iterator b_single_rlay; | BL::RenderResult::layers_iterator b_single_rlay; | ||||
| b_rr.layers.begin(b_single_rlay); | b_rr.layers.begin(b_single_rlay); | ||||
| BL::RenderLayer b_rlay = *b_single_rlay; | BL::RenderLayer b_rlay = *b_single_rlay; | ||||
| b_rlay_name = b_view_layer.name(); | b_rlay_name = b_view_layer.name(); | ||||
| /* Update denoising parameters. */ | /* Update denoising parameters. */ | ||||
| session->set_denoising(session_params.denoising); | session->set_denoising(session_params.denoising); | ||||
| /* Compute render passes and film settings. */ | /* Compute render passes and film settings. */ | ||||
| vector<Pass> passes = sync->sync_render_passes( | vector<Pass> passes = sync->sync_render_passes( | ||||
| b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising); | b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising); | ||||
| /* Set buffer params, using film settings from sync_render_passes. */ | /* Set buffer params, using film settings from sync_render_passes. */ | ||||
| buffer_params.passes = passes; | buffer_params.set_passes(passes); | ||||
| buffer_params.denoising_data_pass = scene->film->get_denoising_data_pass(); | buffer_params.set_denoising_data_pass(scene->get_film()->get_denoising_data_pass()); | ||||
| buffer_params.denoising_clean_pass = scene->film->get_denoising_clean_pass(); | buffer_params.set_denoising_clean_pass(scene->get_film()->get_denoising_clean_pass()); | ||||
| buffer_params.denoising_prefiltered_pass = scene->film->get_denoising_prefiltered_pass(); | buffer_params.set_denoising_prefiltered_pass( | ||||
| scene->get_film()->get_denoising_prefiltered_pass()); | |||||
| BL::RenderResult::views_iterator b_view_iter; | BL::RenderResult::views_iterator b_view_iter; | ||||
| int num_views = 0; | int num_views = 0; | ||||
| for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) { | for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) { | ||||
| num_views++; | num_views++; | ||||
| } | } | ||||
| Show All 20 Lines | for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); | ||||
| */ | */ | ||||
| if (view_index == num_views - 1) { | if (view_index == num_views - 1) { | ||||
| free_blender_memory_if_possible(); | free_blender_memory_if_possible(); | ||||
| } | } | ||||
| /* Make sure all views have different noise patterns. - hardcoded value just to make it random | /* Make sure all views have different noise patterns. - hardcoded value just to make it random | ||||
| */ | */ | ||||
| if (view_index != 0) { | if (view_index != 0) { | ||||
| int seed = scene->integrator->get_seed(); | int seed = scene->get_integrator()->get_seed(); | ||||
| seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0)); | seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0)); | ||||
| scene->integrator->set_seed(seed); | scene->get_integrator()->set_seed(seed); | ||||
| scene->integrator->tag_update(scene); | scene->get_integrator()->tag_update(scene); | ||||
| } | } | ||||
| /* Update number of samples per layer. */ | /* Update number of samples per layer. */ | ||||
| int samples = sync->get_layer_samples(); | int samples = sync->get_layer_samples(); | ||||
| bool bound_samples = sync->get_layer_bound_samples(); | bool bound_samples = sync->get_layer_bound_samples(); | ||||
| int effective_layer_samples; | int effective_layer_samples; | ||||
| if (samples != 0 && (!bound_samples || (samples < session_params.samples))) | if (samples != 0 && (!bound_samples || (samples < session_params.samples))) | ||||
| Show All 16 Lines | for (b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); | ||||
| session->wait(); | session->wait(); | ||||
| if (!b_engine.is_preview() && background && print_render_stats) { | if (!b_engine.is_preview() && background && print_render_stats) { | ||||
| RenderStats stats; | RenderStats stats; | ||||
| session->collect_statistics(&stats); | session->collect_statistics(&stats); | ||||
| printf("Render statistics:\n%s\n", stats.full_report().c_str()); | printf("Render statistics:\n%s\n", stats.full_report().c_str()); | ||||
| } | } | ||||
| if (session->progress.get_cancel()) | if (session->get_progress().get_cancel()) | ||||
| break; | break; | ||||
| } | } | ||||
| /* add metadata */ | /* add metadata */ | ||||
| stamp_view_layer_metadata(scene, b_rlay_name); | stamp_view_layer_metadata(scene, b_rlay_name); | ||||
| /* free result without merging */ | /* free result without merging */ | ||||
| end_render_result(b_engine, b_rr, true, true, false); | end_render_result(b_engine, b_rr, true, true, false); | ||||
| double total_time, render_time; | double total_time, render_time; | ||||
| session->progress.get_time(total_time, render_time); | session->get_progress().get_time(total_time, render_time); | ||||
| VLOG(1) << "Total render time: " << total_time; | VLOG(1) << "Total render time: " << total_time; | ||||
| VLOG(1) << "Render time (without synchronization): " << render_time; | VLOG(1) << "Render time (without synchronization): " << render_time; | ||||
| /* clear callback */ | /* clear callback */ | ||||
| session->write_render_tile_cb = function_null; | session->set_write_render_tile_cb(function_null); | ||||
| session->update_render_tile_cb = function_null; | session->set_update_render_tile_cb(function_null); | ||||
| /* TODO: find a way to clear this data for persistent data render */ | /* TODO: find a way to clear this data for persistent data render */ | ||||
| #if 0 | #if 0 | ||||
| /* free all memory used (host and device), so we wouldn't leave render | /* free all memory used (host and device), so we wouldn't leave render | ||||
| * engine with extra memory allocated | * engine with extra memory allocated | ||||
| */ | */ | ||||
| session->device_free(); | session->device_free(); | ||||
| Show All 37 Lines | void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, | ||||
| const int bake_height) | const int bake_height) | ||||
| { | { | ||||
| b_depsgraph = b_depsgraph_; | b_depsgraph = b_depsgraph_; | ||||
| ShaderEvalType shader_type = get_shader_type(pass_type); | ShaderEvalType shader_type = get_shader_type(pass_type); | ||||
| int bake_pass_filter = bake_pass_filter_get(pass_filter); | int bake_pass_filter = bake_pass_filter_get(pass_filter); | ||||
| /* Initialize bake manager, before we load the baking kernels. */ | /* Initialize bake manager, before we load the baking kernels. */ | ||||
| scene->bake_manager->set(scene, b_object.name(), shader_type, bake_pass_filter); | scene->get_bake_manager()->set(scene, b_object.name(), shader_type, bake_pass_filter); | ||||
| /* Passes are identified by name, so in order to return the combined pass we need to set the | /* Passes are identified by name, so in order to return the combined pass we need to set the | ||||
| * name. */ | * name. */ | ||||
| Pass::add(PASS_COMBINED, scene->passes, "Combined"); | Pass::add(PASS_COMBINED, scene->get_passes(), "Combined"); | ||||
| session->read_bake_tile_cb = function_bind(&BlenderSession::read_render_tile, this, _1); | session->set_read_bake_tile_cb(function_bind(&BlenderSession::read_render_tile, this, _1)); | ||||
| session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1); | session->set_write_render_tile_cb(function_bind(&BlenderSession::write_render_tile, this, _1)); | ||||
| if (!session->progress.get_cancel()) { | if (!session->get_progress().get_cancel()) { | ||||
| /* Sync scene. */ | /* Sync scene. */ | ||||
| BL::Object b_camera_override(b_engine.camera_override()); | BL::Object b_camera_override(b_engine.camera_override()); | ||||
| sync->sync_camera(b_render, b_camera_override, width, height, ""); | sync->sync_camera(b_render, b_camera_override, width, height, ""); | ||||
| sync->sync_data( | sync->sync_data( | ||||
| b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state); | b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state); | ||||
| builtin_images_load(); | builtin_images_load(); | ||||
| } | } | ||||
| /* Object might have been disabled for rendering or excluded in some | /* Object might have been disabled for rendering or excluded in some | ||||
| * other way, in that case Blender will report a warning afterwards. */ | * other way, in that case Blender will report a warning afterwards. */ | ||||
| bool object_found = false; | bool object_found = false; | ||||
| foreach (Object *ob, scene->objects) { | foreach (Object *ob, scene->get_objects()) { | ||||
| if (ob->name == b_object.name()) { | if (ob->get_name() == b_object.name()) { | ||||
| object_found = true; | object_found = true; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (object_found && !session->progress.get_cancel()) { | if (object_found && !session->get_progress().get_cancel()) { | ||||
| /* Get session and buffer parameters. */ | /* Get session and buffer parameters. */ | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background); | b_engine, b_userpref, b_scene, background); | ||||
| session_params.progressive_refine = false; | session_params.progressive_refine = false; | ||||
| BufferParams buffer_params; | BufferParams buffer_params; | ||||
| buffer_params.width = bake_width; | buffer_params.set_width(bake_width); | ||||
| buffer_params.height = bake_height; | buffer_params.set_height(bake_height); | ||||
| buffer_params.passes = scene->passes; | buffer_params.set_passes(scene->get_passes()); | ||||
| /* Update session. */ | /* Update session. */ | ||||
| session->tile_manager.set_samples(session_params.samples); | session->get_tile_manager().set_samples(session_params.samples); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| session->progress.set_update_callback( | session->get_progress().set_update_callback( | ||||
| function_bind(&BlenderSession::update_bake_progress, this)); | function_bind(&BlenderSession::update_bake_progress, this)); | ||||
| } | } | ||||
| /* Perform bake. Check cancel to avoid crash with incomplete scene data. */ | /* Perform bake. Check cancel to avoid crash with incomplete scene data. */ | ||||
| if (object_found && !session->progress.get_cancel()) { | if (object_found && !session->get_progress().get_cancel()) { | ||||
| session->start(); | session->start(); | ||||
| session->wait(); | session->wait(); | ||||
| } | } | ||||
| session->read_bake_tile_cb = function_null; | session->set_read_bake_tile_cb(function_null); | ||||
| session->write_render_tile_cb = function_null; | session->set_write_render_tile_cb(function_null); | ||||
| } | } | ||||
| void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay, | void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay, | ||||
| RenderTile &rtile, | RenderTile &rtile, | ||||
| bool do_update_only) | bool do_update_only) | ||||
| { | { | ||||
| RenderBuffers *buffers = rtile.buffers; | RenderBuffers *buffers = rtile.get_buffers(); | ||||
| /* copy data from device */ | /* copy data from device */ | ||||
| if (!buffers->copy_from_device()) | if (!buffers->copy_from_device()) | ||||
| return; | return; | ||||
| float exposure = scene->film->get_exposure(); | float exposure = scene->get_film()->get_exposure(); | ||||
| vector<float> pixels(rtile.w * rtile.h * 4); | vector<float> pixels(rtile.get_w() * rtile.get_h() * 4); | ||||
| /* Adjust absolute sample number to the range. */ | /* Adjust absolute sample number to the range. */ | ||||
| int sample = rtile.sample; | int sample = rtile.get_sample(); | ||||
| const int range_start_sample = session->tile_manager.range_start_sample; | const int range_start_sample = session->get_tile_manager().get_range_start_sample(); | ||||
| if (range_start_sample != -1) { | if (range_start_sample != -1) { | ||||
| sample -= range_start_sample; | sample -= range_start_sample; | ||||
| } | } | ||||
| if (!do_update_only) { | if (!do_update_only) { | ||||
| /* copy each pass */ | /* copy each pass */ | ||||
| BL::RenderLayer::passes_iterator b_iter; | BL::RenderLayer::passes_iterator b_iter; | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (!b_v3d) | ||||
| return; | return; | ||||
| /* on session/scene parameter changes, we recreate session entirely */ | /* on session/scene parameter changes, we recreate session entirely */ | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background); | b_engine, b_userpref, b_scene, background); | ||||
| SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); | SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); | ||||
| bool session_pause = BlenderSync::get_session_pause(b_scene, background); | bool session_pause = BlenderSync::get_session_pause(b_scene, background); | ||||
| if (session->params.modified(session_params) || scene->params.modified(scene_params)) { | if (session->get_params().modified(session_params) || | ||||
| scene->get_params().modified(scene_params)) { | |||||
| free_session(); | free_session(); | ||||
| create_session(); | create_session(); | ||||
| } | } | ||||
| /* increase samples, but never decrease */ | /* increase samples, but never decrease */ | ||||
| session->set_samples(session_params.samples); | session->set_samples(session_params.samples); | ||||
| session->set_denoising_start_sample(session_params.denoising.start_sample); | session->set_denoising_start_sample(session_params.denoising.start_sample); | ||||
| session->set_pause(session_pause); | session->set_pause(session_pause); | ||||
| /* copy recalc flags, outside of mutex so we can decide to do the real | /* copy recalc flags, outside of mutex so we can decide to do the real | ||||
| * synchronization at a later time to not block on running updates */ | * synchronization at a later time to not block on running updates */ | ||||
| sync->sync_recalc(b_depsgraph_, b_v3d); | sync->sync_recalc(b_depsgraph_, b_v3d); | ||||
| /* don't do synchronization if on pause */ | /* don't do synchronization if on pause */ | ||||
| if (session_pause) { | if (session_pause) { | ||||
| tag_update(); | tag_update(); | ||||
| return; | return; | ||||
| } | } | ||||
| /* try to acquire mutex. if we don't want to or can't, come back later */ | /* try to acquire mutex. if we don't want to or can't, come back later */ | ||||
| if (!session->ready_to_reset() || !session->scene->mutex.try_lock()) { | if (!session->ready_to_reset() || !session->get_scene()->get_mutex().try_lock()) { | ||||
| tag_update(); | tag_update(); | ||||
| return; | return; | ||||
| } | } | ||||
| /* data and camera synchronize */ | /* data and camera synchronize */ | ||||
| b_depsgraph = b_depsgraph_; | b_depsgraph = b_depsgraph_; | ||||
| BL::Object b_camera_override(b_engine.camera_override()); | BL::Object b_camera_override(b_engine.camera_override()); | ||||
| sync->sync_data( | sync->sync_data( | ||||
| b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state); | b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state); | ||||
| if (b_rv3d) | if (b_rv3d) | ||||
| sync->sync_view(b_v3d, b_rv3d, width, height); | sync->sync_view(b_v3d, b_rv3d, width, height); | ||||
| else | else | ||||
| sync->sync_camera(b_render, b_camera_override, width, height, ""); | sync->sync_camera(b_render, b_camera_override, width, height, ""); | ||||
| /* get buffer parameters */ | /* get buffer parameters */ | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params( | ||||
| b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); | b_render, b_v3d, b_rv3d, scene->get_camera(), width, height, session_params.denoising.use); | ||||
| if (!buffer_params.denoising_data_pass) { | if (!buffer_params.get_denoising_data_pass()) { | ||||
| session_params.denoising.use = false; | session_params.denoising.use = false; | ||||
| } | } | ||||
| session->set_denoising(session_params.denoising); | session->set_denoising(session_params.denoising); | ||||
| /* Update film if denoising data was enabled or disabled. */ | /* Update film if denoising data was enabled or disabled. */ | ||||
| scene->film->set_denoising_data_pass(buffer_params.denoising_data_pass); | scene->get_film()->set_denoising_data_pass(buffer_params.get_denoising_data_pass()); | ||||
| /* reset if needed */ | /* reset if needed */ | ||||
| if (scene->need_reset()) { | if (scene->need_reset()) { | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| /* After session reset, so device is not accessing image data anymore. */ | /* After session reset, so device is not accessing image data anymore. */ | ||||
| builtin_images_load(); | builtin_images_load(); | ||||
| /* reset time */ | /* reset time */ | ||||
| start_resize_time = 0.0; | start_resize_time = 0.0; | ||||
| } | } | ||||
| /* unlock */ | /* unlock */ | ||||
| session->scene->mutex.unlock(); | session->get_scene()->get_mutex().unlock(); | ||||
| /* Start rendering thread, if it's not running already. Do this | /* Start rendering thread, if it's not running already. Do this | ||||
| * after all scene data has been synced at least once. */ | * after all scene data has been synced at least once. */ | ||||
| session->start(); | session->start(); | ||||
| } | } | ||||
| bool BlenderSession::draw(int w, int h) | bool BlenderSession::draw(int w, int h) | ||||
| { | { | ||||
| Show All 20 Lines | if (width != w || height != h) { | ||||
| else { | else { | ||||
| width = w; | width = w; | ||||
| height = h; | height = h; | ||||
| reset = true; | reset = true; | ||||
| } | } | ||||
| } | } | ||||
| /* try to acquire mutex. if we can't, come back later */ | /* try to acquire mutex. if we can't, come back later */ | ||||
| if (!session->scene->mutex.try_lock()) { | if (!session->get_scene()->get_mutex().try_lock()) { | ||||
| tag_update(); | tag_update(); | ||||
| } | } | ||||
| else { | else { | ||||
| /* update camera from 3d view */ | /* update camera from 3d view */ | ||||
| sync->sync_view(b_v3d, b_rv3d, width, height); | sync->sync_view(b_v3d, b_rv3d, width, height); | ||||
| if (scene->camera->is_modified()) | if (scene->get_camera()->is_modified()) | ||||
| reset = true; | reset = true; | ||||
| session->scene->mutex.unlock(); | session->get_scene()->get_mutex().unlock(); | ||||
| } | } | ||||
| /* reset if requested */ | /* reset if requested */ | ||||
| if (reset) { | if (reset) { | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background); | b_engine, b_userpref, b_scene, background); | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, | ||||
| b_render, b_v3d, b_rv3d, scene->camera, width, height, session_params.denoising.use); | b_v3d, | ||||
| b_rv3d, | |||||
| scene->get_camera(), | |||||
| width, | |||||
| height, | |||||
| session_params.denoising.use); | |||||
| bool session_pause = BlenderSync::get_session_pause(b_scene, background); | bool session_pause = BlenderSync::get_session_pause(b_scene, background); | ||||
| if (session_pause == false) { | if (session_pause == false) { | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| start_resize_time = 0.0; | start_resize_time = 0.0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| tag_update(); | tag_update(); | ||||
| } | } | ||||
| /* update status and progress for 3d view draw */ | /* update status and progress for 3d view draw */ | ||||
| update_status_progress(); | update_status_progress(); | ||||
| /* draw */ | /* draw */ | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, | ||||
| b_render, b_v3d, b_rv3d, scene->camera, width, height, session->params.denoising.use); | b_v3d, | ||||
| b_rv3d, | |||||
| scene->get_camera(), | |||||
| width, | |||||
| height, | |||||
| session->get_params().denoising.use); | |||||
| DeviceDrawParams draw_params; | DeviceDrawParams draw_params; | ||||
| if (session->params.display_buffer_linear) { | if (session->get_params().display_buffer_linear) { | ||||
| draw_params.bind_display_space_shader_cb = function_bind( | draw_params.bind_display_space_shader_cb = function_bind( | ||||
| &BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene); | &BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene); | ||||
| draw_params.unbind_display_space_shader_cb = function_bind( | draw_params.unbind_display_space_shader_cb = function_bind( | ||||
| &BL::RenderEngine::unbind_display_space_shader, &b_engine); | &BL::RenderEngine::unbind_display_space_shader, &b_engine); | ||||
| } | } | ||||
| return !session->draw(buffer_params, draw_params); | return !session->draw(buffer_params, draw_params); | ||||
| } | } | ||||
| void BlenderSession::get_status(string &status, string &substatus) | void BlenderSession::get_status(string &status, string &substatus) | ||||
| { | { | ||||
| session->progress.get_status(status, substatus); | session->get_progress().get_status(status, substatus); | ||||
| } | } | ||||
| void BlenderSession::get_kernel_status(string &kernel_status) | void BlenderSession::get_kernel_status(string &kernel_status) | ||||
| { | { | ||||
| session->progress.get_kernel_status(kernel_status); | session->get_progress().get_kernel_status(kernel_status); | ||||
| } | } | ||||
| void BlenderSession::get_progress(float &progress, double &total_time, double &render_time) | void BlenderSession::get_progress(float &progress, double &total_time, double &render_time) | ||||
| { | { | ||||
| session->progress.get_time(total_time, render_time); | session->get_progress().get_time(total_time, render_time); | ||||
| progress = session->progress.get_progress(); | progress = session->get_progress().get_progress(); | ||||
| } | } | ||||
| void BlenderSession::update_bake_progress() | void BlenderSession::update_bake_progress() | ||||
| { | { | ||||
| float progress = session->progress.get_progress(); | float progress = session->get_progress().get_progress(); | ||||
| if (progress != last_progress) { | if (progress != last_progress) { | ||||
| b_engine.update_progress(progress); | b_engine.update_progress(progress); | ||||
| last_progress = progress; | last_progress = progress; | ||||
| } | } | ||||
| } | } | ||||
| void BlenderSession::update_status_progress() | void BlenderSession::update_status_progress() | ||||
| { | { | ||||
| string timestatus, status, substatus, kernel_status; | string timestatus, status, substatus, kernel_status; | ||||
| string scene_status = ""; | string scene_status = ""; | ||||
| float progress; | float progress; | ||||
| double total_time, remaining_time = 0, render_time; | double total_time, remaining_time = 0, render_time; | ||||
| float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f; | float mem_used = (float)session->get_stats().get_mem_used() / 1024.0f / 1024.0f; | ||||
| float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f; | float mem_peak = (float)session->get_stats().get_mem_peak() / 1024.0f / 1024.0f; | ||||
| get_status(status, substatus); | get_status(status, substatus); | ||||
| get_kernel_status(kernel_status); | get_kernel_status(kernel_status); | ||||
| get_progress(progress, total_time, render_time); | get_progress(progress, total_time, render_time); | ||||
| if (progress > 0) | if (progress > 0) | ||||
| remaining_time = (1.0 - (double)progress) * (render_time / (double)progress); | remaining_time = (1.0 - (double)progress) * (render_time / (double)progress); | ||||
| if (background) { | if (background) { | ||||
| if (scene) | if (scene) | ||||
| scene_status += " | " + scene->name; | scene_status += " | " + scene->get_name(); | ||||
| if (b_rlay_name != "") | if (b_rlay_name != "") | ||||
| scene_status += ", " + b_rlay_name; | scene_status += ", " + b_rlay_name; | ||||
| if (b_rview_name != "") | if (b_rview_name != "") | ||||
| scene_status += ", " + b_rview_name; | scene_status += ", " + b_rview_name; | ||||
| if (remaining_time > 0) { | if (remaining_time > 0) { | ||||
| timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | "; | timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | "; | ||||
| Show All 19 Lines | if (status != last_status || (!headless && (current_time - last_status_time) > 1.0)) { | ||||
| last_status = status; | last_status = status; | ||||
| last_status_time = current_time; | last_status_time = current_time; | ||||
| } | } | ||||
| if (progress != last_progress) { | if (progress != last_progress) { | ||||
| b_engine.update_progress(progress); | b_engine.update_progress(progress); | ||||
| last_progress = progress; | last_progress = progress; | ||||
| } | } | ||||
| if (session->progress.get_error()) { | if (session->get_progress().get_error()) { | ||||
| string error = session->progress.get_error_message(); | string error = session->get_progress().get_error_message(); | ||||
| if (error != last_error) { | if (error != last_error) { | ||||
| /* TODO(sergey): Currently C++ RNA API doesn't let us to | /* TODO(sergey): Currently C++ RNA API doesn't let us to | ||||
| * use mnemonic name for the variable. Would be nice to | * use mnemonic name for the variable. Would be nice to | ||||
| * have this figured out. | * have this figured out. | ||||
| * | * | ||||
| * For until then, 1 << 5 means RPT_ERROR. | * For until then, 1 << 5 means RPT_ERROR. | ||||
| */ | */ | ||||
| b_engine.report(1 << 5, error.c_str()); | b_engine.report(1 << 5, error.c_str()); | ||||
| Show All 28 Lines | void BlenderSession::tag_redraw() | ||||
| } | } | ||||
| } | } | ||||
| void BlenderSession::test_cancel() | void BlenderSession::test_cancel() | ||||
| { | { | ||||
| /* test if we need to cancel rendering */ | /* test if we need to cancel rendering */ | ||||
| if (background) | if (background) | ||||
| if (b_engine.test_break()) | if (b_engine.test_break()) | ||||
| session->progress.set_cancel("Cancelled"); | session->get_progress().set_cancel("Cancelled"); | ||||
| } | } | ||||
| void BlenderSession::update_resumable_tile_manager(int num_samples) | void BlenderSession::update_resumable_tile_manager(int num_samples) | ||||
| { | { | ||||
| const int num_resumable_chunks = BlenderSession::num_resumable_chunks, | const int num_resumable_chunks = BlenderSession::num_resumable_chunks, | ||||
| current_resumable_chunk = BlenderSession::current_resumable_chunk; | current_resumable_chunk = BlenderSession::current_resumable_chunk; | ||||
| if (num_resumable_chunks == 0) { | if (num_resumable_chunks == 0) { | ||||
| return; | return; | ||||
| Show All 30 Lines | void BlenderSession::update_resumable_tile_manager(int num_samples) | ||||
| /* Make sure we don't overshoot. */ | /* Make sure we don't overshoot. */ | ||||
| if (rounded_range_start_sample + rounded_range_num_samples > num_samples) { | if (rounded_range_start_sample + rounded_range_num_samples > num_samples) { | ||||
| rounded_range_num_samples = num_samples - rounded_range_num_samples; | rounded_range_num_samples = num_samples - rounded_range_num_samples; | ||||
| } | } | ||||
| VLOG(1) << "Samples range start is " << range_start_sample << ", " | VLOG(1) << "Samples range start is " << range_start_sample << ", " | ||||
| << "number of samples to render is " << range_num_samples; | << "number of samples to render is " << range_num_samples; | ||||
| scene->integrator->set_start_sample(rounded_range_start_sample); | scene->get_integrator()->set_start_sample(rounded_range_start_sample); | ||||
| if (scene->integrator->is_modified()) { | if (scene->get_integrator()->is_modified()) { | ||||
| scene->integrator->tag_update(scene); | scene->get_integrator()->tag_update(scene); | ||||
| } | } | ||||
| session->tile_manager.range_start_sample = rounded_range_start_sample; | session->get_tile_manager().set_range_start_sample(rounded_range_start_sample); | ||||
| session->tile_manager.range_num_samples = rounded_range_num_samples; | session->get_tile_manager().set_range_num_samples(rounded_range_num_samples); | ||||
| } | } | ||||
| void BlenderSession::free_blender_memory_if_possible() | void BlenderSession::free_blender_memory_if_possible() | ||||
| { | { | ||||
| if (!background) { | if (!background) { | ||||
| /* During interactive render we can not free anything: attempts to save | /* During interactive render we can not free anything: attempts to save | ||||
| * memory would cause things to be allocated and evaluated for every | * memory would cause things to be allocated and evaluated for every | ||||
| * updated sample. | * updated sample. | ||||
| */ | */ | ||||
| return; | return; | ||||
| } | } | ||||
| b_engine.free_blender_memory(); | b_engine.free_blender_memory(); | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||