Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/blender_session.cpp')
-rw-r--r--intern/cycles/blender/blender_session.cpp323
1 files changed, 174 insertions, 149 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 00d23b9095e..eec13d04d7d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -52,21 +52,22 @@ int BlenderSession::end_resumable_chunk = 0;
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
- BL::Scene& b_scene)
-: b_engine(b_engine),
+ bool preview_osl)
+: session(NULL),
+ b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
b_render(b_engine.render()),
- b_scene(b_scene),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
b_v3d(PointerRNA_NULL),
b_rv3d(PointerRNA_NULL),
+ width(0),
+ height(0),
+ preview_osl(preview_osl),
python_thread_state(NULL)
{
/* offline render */
-
- width = render_resolution_x(b_render);
- height = render_resolution_y(b_render);
-
background = true;
last_redraw_time = 0.0;
start_resize_time = 0.0;
@@ -76,23 +77,24 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
- BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height)
-: b_engine(b_engine),
+: session(NULL),
+ b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
- b_render(b_scene.render()),
- b_scene(b_scene),
+ b_render(b_engine.render()),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
b_v3d(b_v3d),
b_rv3d(b_rv3d),
width(width),
height(height),
+ preview_osl(false),
python_thread_state(NULL)
{
/* 3d view render */
-
background = false;
last_redraw_time = 0.0;
start_resize_time = 0.0;
@@ -141,26 +143,19 @@ void BlenderSession::create_session()
session->scene = scene;
+ /* There is no single depsgraph to use for the entire render.
+ * So we need to handle this differently.
+ *
+ * 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.
+ */
/* create sync */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
BL::Object b_camera_override(b_engine.camera_override());
if(b_v3d) {
- if(session_pause == false) {
- /* full data sync */
- sync->sync_view(b_v3d, b_rv3d, width, height);
- sync->sync_data(b_render,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state,
- b_rlay_name.c_str());
- }
+ sync->sync_view(b_v3d, b_rv3d, width, height);
}
else {
- /* for final render we will do full data sync per render layer, only
- * do some basic syncing here, no objects or materials for speed */
- sync->sync_render_layers(b_v3d, NULL);
- sync->sync_integrator();
sync->sync_camera(b_render, b_camera_override, width, height, "");
}
@@ -173,18 +168,40 @@ void BlenderSession::create_session()
update_resumable_tile_manager(session_params.samples);
}
-void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
+void BlenderSession::reset_session(BL::BlendData& b_data, BL::Depsgraph& b_depsgraph)
{
- b_data = b_data_;
- b_render = b_engine.render();
- b_scene = b_scene_;
+ this->b_data = b_data;
+ this->b_depsgraph = b_depsgraph;
+ this->b_scene = b_depsgraph.scene_eval();
+
+ if (preview_osl) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ RNA_boolean_set(&cscene, "shading_system", preview_osl);
+ }
+
+ if (b_v3d) {
+ this->b_render = b_scene.render();
+ }
+ else {
+ this->b_render = b_engine.render();
+ width = render_resolution_x(b_render);
+ height = render_resolution_y(b_render);
+ }
+
+ if (session == NULL) {
+ create();
+ }
+
+ if (b_v3d) {
+ /* NOTE: We need to create session, but all the code from below
+ * will make viewport render to stuck on initialization.
+ */
+ return;
+ }
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- width = render_resolution_x(b_render);
- height = render_resolution_y(b_render);
-
if(scene->params.modified(scene_params) ||
session->params.modified(session_params) ||
!scene_params.persistent_data)
@@ -210,16 +227,12 @@ void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
*/
session->stats.mem_peak = session->stats.mem_used;
+ /* There is no single depsgraph to use for the entire render.
+ * See note on create_session().
+ */
/* sync object should be re-created */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
- /* for final render we will do full data sync per render layer, only
- * do some basic syncing here, no objects or materials for speed */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_render_layers(b_v3d, NULL);
- sync->sync_integrator();
- sync->sync_camera(b_render, b_camera_override, width, height, "");
-
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render,
@@ -368,8 +381,10 @@ void BlenderSession::update_render_tile(RenderTile& rtile, bool highlight)
do_write_update_render_tile(rtile, false, false);
}
-void BlenderSession::render()
+void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
{
+ b_depsgraph = b_depsgraph_;
+
/* 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, _2);
@@ -379,123 +394,110 @@ void BlenderSession::render()
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
/* render each layer */
- BL::RenderSettings r = b_scene.render();
- BL::RenderSettings::layers_iterator b_layer_iter;
- BL::RenderResult::views_iterator b_view_iter;
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
/* We do some special meta attributes when we only have single layer. */
- const bool is_single_layer = (r.layers.length() == 1);
-
- for(r.layers.begin(b_layer_iter); b_layer_iter != r.layers.end(); ++b_layer_iter) {
- b_rlay_name = b_layer_iter->name();
+ const bool is_single_layer = (b_scene.view_layers.length() == 1);
- /* temporary render result to find needed passes and views */
- BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_rlay_name.c_str(), NULL);
- BL::RenderResult::layers_iterator b_single_rlay;
- b_rr.layers.begin(b_single_rlay);
+ /* temporary render result to find needed passes and views */
+ BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+ BL::RenderLayer b_rlay = *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, true, false);
- continue;
- }
+ /* add passes */
+ array<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer, session_params);
+ buffer_params.passes = passes;
+
+ PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ bool use_denoising = get_boolean(crl, "use_denoising");
+ buffer_params.denoising_data_pass = use_denoising;
+ session->tile_manager.schedule_denoising = use_denoising;
+ session->params.use_denoising = use_denoising;
+ scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
+ scene->film->denoising_flags = 0;
+ if(!get_boolean(crl, "denoising_diffuse_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_DIFFUSE_DIR;
+ if(!get_boolean(crl, "denoising_diffuse_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_DIFFUSE_IND;
+ if(!get_boolean(crl, "denoising_glossy_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_GLOSSY_DIR;
+ if(!get_boolean(crl, "denoising_glossy_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_GLOSSY_IND;
+ if(!get_boolean(crl, "denoising_transmission_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_TRANSMISSION_DIR;
+ if(!get_boolean(crl, "denoising_transmission_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_TRANSMISSION_IND;
+ if(!get_boolean(crl, "denoising_subsurface_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_SUBSURFACE_DIR;
+ if(!get_boolean(crl, "denoising_subsurface_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_SUBSURFACE_IND;
+ scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
+ buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass;
+ session->params.denoising_radius = get_int(crl, "denoising_radius");
+ session->params.denoising_strength = get_float(crl, "denoising_strength");
+ session->params.denoising_feature_strength = get_float(crl, "denoising_feature_strength");
+ session->params.denoising_relative_pca = get_boolean(crl, "denoising_relative_pca");
+
+ scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
+ scene->film->tag_passes_update(scene, passes);
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
- BL::RenderLayer b_rlay = *b_single_rlay;
-
- /* add passes */
- array<Pass> passes = sync->sync_render_passes(b_rlay, *b_layer_iter, session_params);
- buffer_params.passes = passes;
-
- PointerRNA crl = RNA_pointer_get(&b_layer_iter->ptr, "cycles");
- bool use_denoising = get_boolean(crl, "use_denoising");
- buffer_params.denoising_data_pass = use_denoising;
- session->tile_manager.schedule_denoising = use_denoising;
- session->params.use_denoising = use_denoising;
- scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
- scene->film->denoising_flags = 0;
- if(!get_boolean(crl, "denoising_diffuse_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_DIFFUSE_DIR;
- if(!get_boolean(crl, "denoising_diffuse_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_DIFFUSE_IND;
- if(!get_boolean(crl, "denoising_glossy_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_GLOSSY_DIR;
- if(!get_boolean(crl, "denoising_glossy_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_GLOSSY_IND;
- if(!get_boolean(crl, "denoising_transmission_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_TRANSMISSION_DIR;
- if(!get_boolean(crl, "denoising_transmission_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_TRANSMISSION_IND;
- if(!get_boolean(crl, "denoising_subsurface_direct")) scene->film->denoising_flags |= DENOISING_CLEAN_SUBSURFACE_DIR;
- if(!get_boolean(crl, "denoising_subsurface_indirect")) scene->film->denoising_flags |= DENOISING_CLEAN_SUBSURFACE_IND;
- scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
- buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass;
- session->params.denoising_radius = get_int(crl, "denoising_radius");
- session->params.denoising_strength = get_float(crl, "denoising_strength");
- session->params.denoising_feature_strength = get_float(crl, "denoising_feature_strength");
- session->params.denoising_relative_pca = get_boolean(crl, "denoising_relative_pca");
-
- scene->film->pass_alpha_threshold = b_layer_iter->pass_alpha_threshold();
- scene->film->tag_passes_update(scene, passes);
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
-
- int view_index = 0;
- for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter, ++view_index) {
- b_rview_name = b_view_iter->name();
-
- /* set the current view */
- b_engine.active_view_set(b_rview_name.c_str());
-
- /* update scene */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
- sync->sync_data(b_render,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state,
- b_rlay_name.c_str());
-
- /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
- if(view_index != 0) {
- scene->integrator->seed += hash_int_2d(scene->integrator->seed, hash_int(view_index * 0xdeadbeef));
- scene->integrator->tag_update(scene);
- }
+ BL::RenderResult::views_iterator b_view_iter;
+ int view_index = 0;
+ for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter, ++view_index) {
+ b_rlay_name = b_view_layer.name();
+ b_rview_name = b_view_iter->name();
- /* Update number of samples per layer. */
- int samples = sync->get_layer_samples();
- bool bound_samples = sync->get_layer_bound_samples();
- int effective_layer_samples;
+ /* set the current view */
+ b_engine.active_view_set(b_rview_name.c_str());
- if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
- effective_layer_samples = samples;
- else
- effective_layer_samples = session_params.samples;
+ /* update scene */
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
+ sync->sync_data(b_render,
+ b_depsgraph,
+ b_v3d,
+ b_camera_override,
+ width, height,
+ &python_thread_state);
+ builtin_images_load();
- /* Update tile manager if we're doing resumable render. */
- update_resumable_tile_manager(effective_layer_samples);
+ /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
+ if(view_index != 0) {
+ scene->integrator->seed += hash_int_2d(scene->integrator->seed, hash_int(view_index * 0xdeadbeef));
+ scene->integrator->tag_update(scene);
+ }
- /* Update session itself. */
- session->reset(buffer_params, effective_layer_samples);
+ /* Update number of samples per layer. */
+ int samples = sync->get_layer_samples();
+ bool bound_samples = sync->get_layer_bound_samples();
+ int effective_layer_samples;
- /* render */
- session->start();
- session->wait();
+ if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
+ effective_layer_samples = samples;
+ else
+ effective_layer_samples = session_params.samples;
- if(session->progress.get_cancel())
- break;
- }
+ /* Update tile manager if we're doing resumable render. */
+ update_resumable_tile_manager(effective_layer_samples);
- if(is_single_layer) {
- BL::RenderResult b_rr = b_engine.get_result();
- string num_aa_samples = string_printf("%d", session->params.samples);
- b_rr.stamp_data_add_field("Cycles Samples", num_aa_samples.c_str());
- /* TODO(sergey): Report whether we're doing resumable render
- * and also start/end sample if so.
- */
- }
+ /* Update session itself. */
+ session->reset(buffer_params, effective_layer_samples);
- /* free result without merging */
- end_render_result(b_engine, b_rr, true, true, false);
+ /* render */
+ session->start();
+ session->wait();
if(session->progress.get_cancel())
break;
}
+ if(is_single_layer) {
+ BL::RenderResult b_rr = b_engine.get_result();
+ string num_aa_samples = string_printf("%d", session->params.samples);
+ b_rr.stamp_data_add_field("Cycles Samples", num_aa_samples.c_str());
+ /* TODO(sergey): Report whether we're doing resumable render
+ * and also start/end sample if so.
+ */
+ }
+
+ /* free result without merging */
+ end_render_result(b_engine, b_rr, true, true, false);
+
double total_time, render_time;
session->progress.get_time(total_time, render_time);
VLOG(1) << "Total render time: " << total_time;
@@ -505,6 +507,8 @@ void BlenderSession::render()
session->write_render_tile_cb = function_null;
session->update_render_tile_cb = function_null;
+ /* TODO: find a way to clear this data for persistent data render */
+#if 0
/* free all memory used (host and device), so we wouldn't leave render
* engine with extra memory allocated
*/
@@ -513,6 +517,7 @@ void BlenderSession::render()
delete sync;
sync = NULL;
+#endif
}
static void populate_bake_data(BakeData *data, const
@@ -561,7 +566,8 @@ static int bake_pass_filter_get(const int pass_filter)
return flag;
}
-void BlenderSession::bake(BL::Object& b_object,
+void BlenderSession::bake(BL::Depsgraph& b_depsgraph_,
+ BL::Object& b_object,
const string& pass_type,
const int pass_filter,
const int object_id,
@@ -570,6 +576,8 @@ void BlenderSession::bake(BL::Object& b_object,
const int /*depth*/,
float result[])
{
+ b_depsgraph = b_depsgraph_;
+
ShaderEvalType shader_type = get_shader_type(pass_type);
/* Set baking flag in advance, so kernel loading can check if we need
@@ -602,11 +610,12 @@ void BlenderSession::bake(BL::Object& b_object,
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(b_render,
+ b_depsgraph,
b_v3d,
b_camera_override,
width, height,
- &python_thread_state,
- b_rlay_name.c_str());
+ &python_thread_state);
+ builtin_images_load();
}
BakeData *bake_data = NULL;
@@ -740,7 +749,7 @@ void BlenderSession::update_render_result(BL::RenderResult& b_rr,
do_write_update_render_result(b_rr, b_rlay, rtile, true);
}
-void BlenderSession::synchronize()
+void BlenderSession::synchronize(BL::Depsgraph& b_depsgraph_)
{
/* only used for viewport render */
if(!b_v3d)
@@ -766,7 +775,7 @@ void BlenderSession::synchronize()
/* 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 */
- sync->sync_recalc();
+ sync->sync_recalc(b_depsgraph_);
/* don't do synchronization if on pause */
if(session_pause) {
@@ -781,19 +790,23 @@ void BlenderSession::synchronize()
}
/* data and camera synchronize */
+ b_depsgraph = b_depsgraph_;
+
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_data(b_render,
+ b_depsgraph,
b_v3d,
b_camera_override,
width, height,
- &python_thread_state,
- b_rlay_name.c_str());
+ &python_thread_state);
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
sync->sync_camera(b_render, b_camera_override, width, height, "");
+ builtin_images_load();
+
/* unlock */
session->scene->mutex.unlock();
@@ -1301,6 +1314,9 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
}
else {
+ /* We originally were passing view_layer here but in reality we need a
+ * a depsgraph to pass to the RE_point_density_minmax() function.
+ */
/* TODO(sergey): Check we're indeed in shader node tree. */
PointerRNA ptr;
RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
@@ -1308,14 +1324,23 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
int length;
- int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */
- b_point_density_node.calc_point_density(b_scene, settings, &length, &pixels);
+ b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
}
}
return false;
}
+void BlenderSession::builtin_images_load()
+{
+ /* Force builtin images to be loaded along with Blender data sync. This
+ * is needed because we may be reading from depsgraph evaluated data which
+ * can be freed by Blender before Cycles reads it. */
+ ImageManager *manager = session->scene->image_manager;
+ Device *device = session->device;
+ manager->device_load_builtin(device, session->scene, session->progress);
+}
+
void BlenderSession::update_resumable_tile_manager(int num_samples)
{
const int num_resumable_chunks = BlenderSession::num_resumable_chunks,