Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_session.cpp
| Show First 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsgraph) | ||||
| b_engine.use_highlight_tiles(session_params.progressive_refine == false); | b_engine.use_highlight_tiles(session_params.progressive_refine == false); | ||||
| /* reset time */ | /* reset time */ | ||||
| start_resize_time = 0.0; | start_resize_time = 0.0; | ||||
| } | } | ||||
| void BlenderSession::free_session() | void BlenderSession::free_session() | ||||
| { | { | ||||
| if (sync) | |||||
| delete sync; | delete sync; | ||||
| delete session; | delete session; | ||||
| } | } | ||||
| static ShaderEvalType get_shader_type(const string &pass_type) | static ShaderEvalType get_shader_type(const string &pass_type) | ||||
| { | { | ||||
| const char *shader_type = pass_type.c_str(); | const char *shader_type = pass_type.c_str(); | ||||
| /* data passes */ | /* data passes */ | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | static void end_render_result(BL::RenderEngine &b_engine, | ||||
| bool highlight, | bool highlight, | ||||
| bool do_merge_results) | bool do_merge_results) | ||||
| { | { | ||||
| 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 highlight) | bool highlight) | ||||
| { | { | ||||
| int x = rtile.x - session->tile_manager.params.full_x; | int x = rtile.x - session->tile_manager.params.full_x; | ||||
| int y = rtile.y - session->tile_manager.params.full_y; | int y = rtile.y - session->tile_manager.params.full_y; | ||||
| int w = rtile.w; | int w = rtile.w; | ||||
| int h = rtile.h; | int h = rtile.h; | ||||
| /* get render result */ | /* get render result */ | ||||
| Show All 9 Lines | void BlenderSession::do_write_update_render_tile(RenderTile &rtile, | ||||
| b_rr.layers.begin(b_single_rlay); | b_rr.layers.begin(b_single_rlay); | ||||
| /* layer will be missing if it was disabled in the UI */ | /* layer will be missing if it was disabled in the UI */ | ||||
| if (b_single_rlay == b_rr.layers.end()) | if (b_single_rlay == b_rr.layers.end()) | ||||
| return; | return; | ||||
| BL::RenderLayer b_rlay = *b_single_rlay; | BL::RenderLayer b_rlay = *b_single_rlay; | ||||
| if (do_update_only) { | if (do_read_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 = BlenderSync::get_pass_type(b_pass); | |||||
| int components = b_pass.channels(); | |||||
| rtile.buffers->set_pass_rect(pass_type, components, (float *)b_pass.rect()); | |||||
| } | |||||
| end_render_result(b_engine, b_rr, false, false, false); | |||||
| } | |||||
| 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.sample != 0) && (rtile.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 { | ||||
| /* Write final render result. */ | /* Write final render result. */ | ||||
| write_render_result(b_rlay, rtile); | write_render_result(b_rlay, rtile); | ||||
| end_render_result(b_engine, b_rr, false, false, true); | end_render_result(b_engine, b_rr, false, false, true); | ||||
| } | } | ||||
| } | } | ||||
| void BlenderSession::read_render_tile(RenderTile &rtile) | |||||
| { | |||||
| do_write_update_render_tile(rtile, false, true, false); | |||||
| } | |||||
| void BlenderSession::write_render_tile(RenderTile &rtile) | void BlenderSession::write_render_tile(RenderTile &rtile) | ||||
| { | { | ||||
| do_write_update_render_tile(rtile, false, false); | do_write_update_render_tile(rtile, false, false, false); | ||||
| } | } | ||||
| void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight) | void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight) | ||||
| { | { | ||||
| /* use final write for preview renders, otherwise render result wouldn't be | /* use final write for preview renders, otherwise render result wouldn't be | ||||
| * be updated in blender side | * be updated in blender side | ||||
| * would need to be investigated a bit further, but for now shall be fine | * would need to be investigated a bit further, but for now shall be fine | ||||
| */ | */ | ||||
| if (!b_engine.is_preview()) | if (!b_engine.is_preview()) | ||||
| do_write_update_render_tile(rtile, true, highlight); | do_write_update_render_tile(rtile, true, false, highlight); | ||||
| else | else | ||||
| do_write_update_render_tile(rtile, false, false); | do_write_update_render_tile(rtile, false, false, false); | ||||
| } | } | ||||
| static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest) | static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest) | ||||
| { | { | ||||
| string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0)); | string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0)); | ||||
| string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/"; | string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/"; | ||||
| render_add_metadata(b_rr, prefix + "name", name); | render_add_metadata(b_rr, prefix + "name", name); | ||||
| ▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | #if 0 | ||||
| session->device_free(); | session->device_free(); | ||||
| delete sync; | delete sync; | ||||
| sync = NULL; | sync = NULL; | ||||
| #endif | #endif | ||||
| } | } | ||||
| static void populate_bake_data(BakeData *data, | |||||
| const int object_id, | |||||
| BL::BakePixel &pixel_array, | |||||
| const int num_pixels) | |||||
| { | |||||
| BL::BakePixel bp = pixel_array; | |||||
| int i; | |||||
| for (i = 0; i < num_pixels; i++) { | |||||
| if (bp.object_id() == object_id) { | |||||
| data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy()); | |||||
| } | |||||
| else { | |||||
| data->set_null(i); | |||||
| } | |||||
| bp = bp.next(); | |||||
| } | |||||
| } | |||||
| static int bake_pass_filter_get(const int pass_filter) | static int bake_pass_filter_get(const int pass_filter) | ||||
| { | { | ||||
| int flag = BAKE_FILTER_NONE; | int flag = BAKE_FILTER_NONE; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0) | if ((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0) | ||||
| flag |= BAKE_FILTER_DIRECT; | flag |= BAKE_FILTER_DIRECT; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0) | if ((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0) | ||||
| flag |= BAKE_FILTER_INDIRECT; | flag |= BAKE_FILTER_INDIRECT; | ||||
| Show All 14 Lines | static int bake_pass_filter_get(const int pass_filter) | ||||
| return flag; | return flag; | ||||
| } | } | ||||
| void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, | void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, | ||||
| BL::Object &b_object, | BL::Object &b_object, | ||||
| const string &pass_type, | const string &pass_type, | ||||
| const int pass_filter, | const int pass_filter, | ||||
| const int object_id, | const int bake_width, | ||||
| BL::BakePixel &pixel_array, | const int bake_height) | ||||
| const size_t num_pixels, | |||||
| const int /*depth*/, | |||||
| float result[]) | |||||
| { | { | ||||
| b_depsgraph = b_depsgraph_; | b_depsgraph = b_depsgraph_; | ||||
| ShaderEvalType shader_type = get_shader_type(pass_type); | ShaderEvalType shader_type = get_shader_type(pass_type); | ||||
| /* Set baking flag in advance, so kernel loading can check if we need | |||||
| * any baking capabilities. | |||||
| */ | |||||
| scene->bake_manager->set_baking(true); | |||||
| /* ensure kernels are loaded before we do any scene updates */ | |||||
| session->load_kernels(); | |||||
| if (shader_type == SHADER_EVAL_UV) { | |||||
| /* force UV to be available */ | |||||
| Pass::add(PASS_UV, scene->film->passes); | |||||
| } | |||||
| int bake_pass_filter = bake_pass_filter_get(pass_filter); | int bake_pass_filter = bake_pass_filter_get(pass_filter); | ||||
| bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter); | |||||
| /* force use_light_pass to be true if we bake more than just colors */ | /* Initialize bake manager, before we load the baking kernels. */ | ||||
| if (bake_pass_filter & ~BAKE_FILTER_COLOR) { | scene->bake_manager->set(scene, b_object.name(), shader_type, bake_pass_filter); | ||||
| Pass::add(PASS_LIGHT, scene->film->passes); | |||||
| } | |||||
| /* create device and update scene */ | /* Passes are identified by name, so in order to return the combined pass we need to set the name. */ | ||||
| scene->film->tag_update(scene); | Pass::add(PASS_COMBINED, scene->film->passes, "Combined"); | ||||
| scene->integrator->tag_update(scene); | |||||
| session->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); | |||||
| if (!session->progress.get_cancel()) { | if (!session->progress.get_cancel()) { | ||||
| /* update 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(); | ||||
| } | } | ||||
| BakeData *bake_data = NULL; | /* Object might have been disabled for rendering or excluded in some | ||||
| * other way, in that case Blender will report a warning afterwards. */ | |||||
| if (!session->progress.get_cancel()) { | bool object_found = false; | ||||
| /* get buffer parameters */ | foreach (Object *ob, scene->objects) { | ||||
| SessionParams session_params = BlenderSync::get_session_params( | if (ob->name == b_object.name()) { | ||||
| b_engine, b_userpref, b_scene, background); | object_found = true; | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | |||||
| b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); | |||||
| scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y()); | |||||
| /* set number of samples */ | |||||
| session->tile_manager.set_samples(session_params.samples); | |||||
| session->reset(buffer_params, session_params.samples); | |||||
| session->update_scene(); | |||||
| /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */ | |||||
| size_t object_index = OBJECT_NONE; | |||||
| int tri_offset = 0; | |||||
| for (size_t i = 0; i < scene->objects.size(); i++) { | |||||
| const Object *object = scene->objects[i]; | |||||
| const Geometry *geom = object->geometry; | |||||
| if (object->name == b_object.name() && geom->type == Geometry::MESH) { | |||||
| const Mesh *mesh = static_cast<const Mesh *>(geom); | |||||
| object_index = i; | |||||
| tri_offset = mesh->prim_offset; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* Object might have been disabled for rendering or excluded in some | if (object_found && !session->progress.get_cancel()) { | ||||
| * other way, in that case Blender will report a warning afterwards. */ | /* Get session and buffer parameters. */ | ||||
| if (object_index != OBJECT_NONE) { | SessionParams session_params = BlenderSync::get_session_params( | ||||
| int object = object_index; | b_engine, b_userpref, b_scene, background); | ||||
| session_params.progressive_refine = false; | |||||
| bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); | BufferParams buffer_params; | ||||
| populate_bake_data(bake_data, object_id, pixel_array, num_pixels); | buffer_params.width = bake_width; | ||||
| } | buffer_params.height = bake_height; | ||||
| buffer_params.passes = scene->film->passes; | |||||
| /* set number of samples */ | /* Update session. */ | ||||
| session->tile_manager.set_samples(session_params.samples); | session->tile_manager.set_samples(session_params.samples); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| session->update_scene(); | |||||
| session->progress.set_update_callback( | session->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 (!session->progress.get_cancel() && bake_data) { | if (object_found && !session->progress.get_cancel()) { | ||||
| scene->bake_manager->bake(scene->device, | session->start(); | ||||
| &scene->dscene, | session->wait(); | ||||
| scene, | |||||
| session->progress, | |||||
| shader_type, | |||||
| bake_pass_filter, | |||||
| bake_data, | |||||
| result); | |||||
| } | } | ||||
| /* free all memory used (host and device), so we wouldn't leave render | session->read_bake_tile_cb = function_null; | ||||
| * engine with extra memory allocated | session->write_render_tile_cb = function_null; | ||||
| */ | |||||
| session->device_free(); | |||||
| delete sync; | |||||
| sync = 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.buffers; | ||||
| ▲ Show 20 Lines • Show All 421 Lines • Show Last 20 Lines | |||||