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
path: root/intern
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2020-08-18 11:46:12 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2020-08-18 12:50:37 +0300
commitc82166ffcd88dcb5fe5b694faa33043f1a4979b4 (patch)
tree246ef7896ddfacb994fa7274befea6d70794a98d /intern
parent286fc2233d18edf3006b796241a8afa3aa662c31 (diff)
Cycles: move some Scene related methods out of Session
This moves `Session::get_requested_device_features`, `Session::load_kernels`, and `Session::update_scene` out of `Session` and into `Scene`, as mentioned in D8544. Reviewed By: brecht Differential Revision: https://developer.blender.org/D8590
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/device/device.h4
-rw-r--r--intern/cycles/render/scene.cpp162
-rw-r--r--intern/cycles/render/scene.h18
-rw-r--r--intern/cycles/render/session.cpp160
-rw-r--r--intern/cycles/render/session.h14
5 files changed, 183 insertions, 175 deletions
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 115b05e3911..58472f645e0 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -180,7 +180,6 @@ class DeviceRequestedFeatures {
DeviceRequestedFeatures()
{
/* TODO(sergey): Find more meaningful defaults. */
- experimental = false;
max_nodes_group = 0;
nodes_features = 0;
use_hair = false;
@@ -203,8 +202,7 @@ class DeviceRequestedFeatures {
bool modified(const DeviceRequestedFeatures &requested_features)
{
- return !(experimental == requested_features.experimental &&
- max_nodes_group == requested_features.max_nodes_group &&
+ return !(max_nodes_group == requested_features.max_nodes_group &&
nodes_features == requested_features.nodes_features &&
use_hair == requested_features.use_hair &&
use_hair_thick == requested_features.use_hair_thick &&
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 9016a8d325f..e68ab335da4 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -29,6 +29,7 @@
#include "render/osl.h"
#include "render/particles.h"
#include "render/scene.h"
+#include "render/session.h"
#include "render/shader.h"
#include "render/svm.h"
#include "render/tables.h"
@@ -109,6 +110,10 @@ Scene::Scene(const SceneParams &params_, Device *device)
image_manager = new ImageManager(device->info);
particle_system_manager = new ParticleSystemManager();
bake_manager = new BakeManager();
+ kernels_loaded = false;
+
+ /* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
+ max_closure_global = 1;
/* OSL only works on the CPU */
if (device->info.has_osl)
@@ -396,4 +401,161 @@ void Scene::collect_statistics(RenderStats *stats)
image_manager->collect_statistics(stats);
}
+DeviceRequestedFeatures Scene::get_requested_device_features()
+{
+ DeviceRequestedFeatures requested_features;
+
+ shader_manager->get_requested_features(this, &requested_features);
+
+ /* This features are not being tweaked as often as shaders,
+ * so could be done selective magic for the viewport as well.
+ */
+ bool use_motion = need_motion() == Scene::MotionType::MOTION_BLUR;
+ requested_features.use_hair = false;
+ requested_features.use_hair_thick = (params.hair_shape == CURVE_THICK);
+ requested_features.use_object_motion = false;
+ requested_features.use_camera_motion = use_motion && camera->use_motion();
+ foreach (Object *object, objects) {
+ Geometry *geom = object->geometry;
+ if (use_motion) {
+ requested_features.use_object_motion |= object->use_motion() | geom->use_motion_blur;
+ requested_features.use_camera_motion |= geom->use_motion_blur;
+ }
+ if (object->is_shadow_catcher) {
+ requested_features.use_shadow_tricks = true;
+ }
+ if (geom->type == Geometry::MESH) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+#ifdef WITH_OPENSUBDIV
+ if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
+ requested_features.use_patch_evaluation = true;
+ }
+#endif
+ requested_features.use_true_displacement |= mesh->has_true_displacement();
+ }
+ else if (geom->type == Geometry::HAIR) {
+ requested_features.use_hair = true;
+ }
+ }
+
+ requested_features.use_background_light = light_manager->has_background_light(this);
+
+ requested_features.use_baking = bake_manager->get_baking();
+ requested_features.use_integrator_branched = (integrator->method == Integrator::BRANCHED_PATH);
+ if (film->denoising_data_pass) {
+ requested_features.use_denoising = true;
+ requested_features.use_shadow_tricks = true;
+ }
+
+ return requested_features;
+}
+
+bool Scene::update(Progress &progress, bool &kernel_switch_needed)
+{
+ /* update scene */
+ if (need_update()) {
+ /* Updated used shader tag so we know which features are need for the kernel. */
+ shader_manager->update_shaders_used(this);
+
+ /* Update max_closures. */
+ KernelIntegrator *kintegrator = &dscene.data.integrator;
+ if (params.background) {
+ kintegrator->max_closures = get_max_closure_count();
+ }
+ else {
+ /* Currently viewport render is faster with higher max_closures, needs investigating. */
+ kintegrator->max_closures = MAX_CLOSURE;
+ }
+
+ /* Load render kernels, before device update where we upload data to the GPU. */
+ bool new_kernels_needed = load_kernels(progress, false);
+
+ progress.set_status("Updating Scene");
+ MEM_GUARDED_CALL(&progress, device_update, device, progress);
+
+ DeviceKernelStatus kernel_switch_status = device->get_active_kernel_switch_state();
+ kernel_switch_needed = kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE ||
+ kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
+ if (kernel_switch_status == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
+ progress.set_kernel_status("Compiling render kernels");
+ }
+ if (new_kernels_needed || kernel_switch_needed) {
+ progress.set_kernel_status("Compiling render kernels");
+ device->wait_for_availability(loaded_kernel_features);
+ progress.set_kernel_status("");
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool Scene::load_kernels(Progress &progress, bool lock_scene)
+{
+ thread_scoped_lock scene_lock;
+ if (lock_scene) {
+ scene_lock = thread_scoped_lock(mutex);
+ }
+
+ DeviceRequestedFeatures requested_features = get_requested_device_features();
+
+ if (!kernels_loaded || loaded_kernel_features.modified(requested_features)) {
+ progress.set_status("Loading render kernels (may take a few minutes the first time)");
+
+ scoped_timer timer;
+
+ VLOG(2) << "Requested features:\n" << requested_features;
+ if (!device->load_kernels(requested_features)) {
+ string message = device->error_message();
+ if (message.empty())
+ message = "Failed loading render kernel, see console for errors";
+
+ progress.set_error(message);
+ progress.set_status(message);
+ progress.set_update();
+ return false;
+ }
+
+ progress.add_skip_time(timer, false);
+ VLOG(1) << "Total time spent loading kernels: " << time_dt() - timer.get_start();
+
+ kernels_loaded = true;
+ loaded_kernel_features = requested_features;
+ return true;
+ }
+ return false;
+}
+
+int Scene::get_max_closure_count()
+{
+ if (shader_manager->use_osl()) {
+ /* OSL always needs the maximum as we can't predict the
+ * number of closures a shader might generate. */
+ return MAX_CLOSURE;
+ }
+
+ int max_closures = 0;
+ for (int i = 0; i < shaders.size(); i++) {
+ Shader *shader = shaders[i];
+ if (shader->used) {
+ int num_closures = shader->graph->get_num_closures();
+ max_closures = max(max_closures, num_closures);
+ }
+ }
+ max_closure_global = max(max_closure_global, max_closures);
+
+ if (max_closure_global > MAX_CLOSURE) {
+ /* This is usually harmless as more complex shader tend to get many
+ * closures discarded due to mixing or low weights. We need to limit
+ * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
+ * avoids excessive memory usage for split kernels. */
+ VLOG(2) << "Maximum number of closures exceeded: " << max_closure_global << " > "
+ << MAX_CLOSURE;
+
+ max_closure_global = MAX_CLOSURE;
+ }
+
+ return max_closure_global;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 67616262c03..24f431b82fd 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -22,6 +22,7 @@
#include "render/image.h"
#include "render/shader.h"
+#include "device/device.h"
#include "device/device_memory.h"
#include "util/util_param.h"
@@ -276,6 +277,8 @@ class Scene {
void collect_statistics(RenderStats *stats);
+ bool update(Progress &progress, bool &kernel_switch_needed);
+
protected:
/* Check if some heavy data worth logging was updated.
* Mainly used to suppress extra annoying logging.
@@ -283,6 +286,21 @@ class Scene {
bool need_data_update();
void free_memory(bool final);
+
+ bool kernels_loaded;
+ DeviceRequestedFeatures loaded_kernel_features;
+
+ bool load_kernels(Progress &progress, bool lock_scene = true);
+
+ /* ** Split kernel routines ** */
+
+ DeviceRequestedFeatures get_requested_device_features();
+
+ /* Maximumnumber of closure during session lifetime. */
+ int max_closure_global;
+
+ /* Get maximum number of closures to be used in kernel. */
+ int get_max_closure_count();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 70c4214c684..c22e29043d3 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -90,10 +90,6 @@ Session::Session(const SessionParams &params_)
gpu_draw_ready = false;
gpu_need_display_buffer_update = false;
pause = false;
- kernels_loaded = false;
-
- /* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
- max_closure_global = 1;
}
Session::~Session()
@@ -767,95 +763,6 @@ void Session::run_cpu()
update_progressive_refine(true);
}
-DeviceRequestedFeatures Session::get_requested_device_features()
-{
- /* TODO(sergey): Consider moving this to the Scene level. */
- DeviceRequestedFeatures requested_features;
- requested_features.experimental = params.experimental;
-
- scene->shader_manager->get_requested_features(scene, &requested_features);
-
- /* This features are not being tweaked as often as shaders,
- * so could be done selective magic for the viewport as well.
- */
- bool use_motion = scene->need_motion() == Scene::MotionType::MOTION_BLUR;
- requested_features.use_hair = false;
- requested_features.use_hair_thick = (scene->params.hair_shape == CURVE_THICK);
- requested_features.use_object_motion = false;
- requested_features.use_camera_motion = use_motion && scene->camera->use_motion();
- foreach (Object *object, scene->objects) {
- Geometry *geom = object->geometry;
- if (use_motion) {
- requested_features.use_object_motion |= object->use_motion() | geom->use_motion_blur;
- requested_features.use_camera_motion |= geom->use_motion_blur;
- }
- if (object->is_shadow_catcher) {
- requested_features.use_shadow_tricks = true;
- }
- if (geom->type == Geometry::MESH) {
- Mesh *mesh = static_cast<Mesh *>(geom);
-#ifdef WITH_OPENSUBDIV
- if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
- requested_features.use_patch_evaluation = true;
- }
-#endif
- requested_features.use_true_displacement |= mesh->has_true_displacement();
- }
- else if (geom->type == Geometry::HAIR) {
- requested_features.use_hair = true;
- }
- }
-
- requested_features.use_background_light = scene->light_manager->has_background_light(scene);
-
- BakeManager *bake_manager = scene->bake_manager;
- requested_features.use_baking = bake_manager->get_baking();
- requested_features.use_integrator_branched = (scene->integrator->method ==
- Integrator::BRANCHED_PATH);
- if (params.denoising.use || params.denoising.store_passes) {
- requested_features.use_denoising = true;
- requested_features.use_shadow_tricks = true;
- }
-
- return requested_features;
-}
-
-bool Session::load_kernels(bool lock_scene)
-{
- thread_scoped_lock scene_lock;
- if (lock_scene) {
- scene_lock = thread_scoped_lock(scene->mutex);
- }
-
- DeviceRequestedFeatures requested_features = get_requested_device_features();
-
- if (!kernels_loaded || loaded_kernel_features.modified(requested_features)) {
- progress.set_status("Loading render kernels (may take a few minutes the first time)");
-
- scoped_timer timer;
-
- VLOG(2) << "Requested features:\n" << requested_features;
- if (!device->load_kernels(requested_features)) {
- string message = device->error_message();
- if (message.empty())
- message = "Failed loading render kernel, see console for errors";
-
- progress.set_error(message);
- progress.set_status(message);
- progress.set_update();
- return false;
- }
-
- progress.add_skip_time(timer, false);
- VLOG(1) << "Total time spent loading kernels: " << time_dt() - timer.get_start();
-
- kernels_loaded = true;
- loaded_kernel_features = requested_features;
- return true;
- }
- return false;
-}
-
void Session::run()
{
if (params.use_profiling && (params.device.type == DEVICE_CPU)) {
@@ -1032,39 +939,8 @@ bool Session::update_scene()
}
}
- /* update scene */
- if (scene->need_update()) {
- /* Updated used shader tag so we know which features are need for the kernel. */
- scene->shader_manager->update_shaders_used(scene);
-
- /* Update max_closures. */
- KernelIntegrator *kintegrator = &scene->dscene.data.integrator;
- if (params.background) {
- kintegrator->max_closures = get_max_closure_count();
- }
- else {
- /* Currently viewport render is faster with higher max_closures, needs investigating. */
- kintegrator->max_closures = MAX_CLOSURE;
- }
-
- /* Load render kernels, before device update where we upload data to the GPU. */
- bool new_kernels_needed = load_kernels(false);
-
- progress.set_status("Updating Scene");
- MEM_GUARDED_CALL(&progress, scene->device_update, device, progress);
-
- DeviceKernelStatus kernel_switch_status = device->get_active_kernel_switch_state();
- bool kernel_switch_needed = kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE ||
- kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
- if (kernel_switch_status == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
- progress.set_kernel_status("Compiling render kernels");
- }
- if (new_kernels_needed || kernel_switch_needed) {
- progress.set_kernel_status("Compiling render kernels");
- device->wait_for_availability(loaded_kernel_features);
- progress.set_kernel_status("");
- }
-
+ bool kernel_switch_needed = false;
+ if (scene->update(progress, kernel_switch_needed)) {
if (kernel_switch_needed) {
reset(tile_manager.params, params.samples);
}
@@ -1334,36 +1210,4 @@ void Session::collect_statistics(RenderStats *render_stats)
}
}
-int Session::get_max_closure_count()
-{
- if (scene->shader_manager->use_osl()) {
- /* OSL always needs the maximum as we can't predict the
- * number of closures a shader might generate. */
- return MAX_CLOSURE;
- }
-
- int max_closures = 0;
- for (int i = 0; i < scene->shaders.size(); i++) {
- Shader *shader = scene->shaders[i];
- if (shader->used) {
- int num_closures = shader->graph->get_num_closures();
- max_closures = max(max_closures, num_closures);
- }
- }
- max_closure_global = max(max_closure_global, max_closures);
-
- if (max_closure_global > MAX_CLOSURE) {
- /* This is usually harmless as more complex shader tend to get many
- * closures discarded due to mixing or low weights. We need to limit
- * to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
- * avoids excessive memory usage for split kernels. */
- VLOG(2) << "Maximum number of closures exceeded: " << max_closure_global << " > "
- << MAX_CLOSURE;
-
- max_closure_global = MAX_CLOSURE;
- }
-
- return max_closure_global;
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index e3ac054ead3..a22bf7731ae 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -157,7 +157,6 @@ class Session {
void set_denoising_start_sample(int sample);
bool update_scene();
- bool load_kernels(bool lock_scene = true);
void device_free();
@@ -219,25 +218,12 @@ class Session {
thread_mutex display_mutex;
thread_condition_variable denoising_cond;
- bool kernels_loaded;
- DeviceRequestedFeatures loaded_kernel_features;
-
double reset_time;
double last_update_time;
double last_display_time;
/* progressive refine */
bool update_progressive_refine(bool cancel);
-
- DeviceRequestedFeatures get_requested_device_features();
-
- /* ** Split kernel routines ** */
-
- /* Maximumnumber of closure during session lifetime. */
- int max_closure_global;
-
- /* Get maximum number of closures to be used in kernel. */
- int get_max_closure_count();
};
CCL_NAMESPACE_END