[Bf-blender-cvs] [0ceded7bc97] master: Cycles: Introduce scene host_update function

Sergey Sharybin noreply at git.blender.org
Mon Oct 11 12:27:32 CEST 2021


Commit: 0ceded7bc97852564c4d26951b41853e8289925e
Author: Sergey Sharybin
Date:   Wed Oct 6 11:43:58 2021 +0200
Branches: master
https://developer.blender.org/rB0ceded7bc97852564c4d26951b41853e8289925e

Cycles: Introduce scene host_update function

The longer-term goal is to separate host-only scene update
from device update: make it possible to make kernel features
depend on actual scene state and flags.

This change makes it so shaders are compiled before kernel
load, making checks like "has_volume" available at the
kernel features calculation state.

No functional changes are expected at this point.

Differential Revision: https://developer.blender.org/D12795

===================================================================

M	intern/cycles/render/osl.cpp
M	intern/cycles/render/osl.h
M	intern/cycles/render/scene.cpp
M	intern/cycles/render/scene.h
M	intern/cycles/render/shader.cpp
M	intern/cycles/render/shader.h
M	intern/cycles/render/svm.cpp
M	intern/cycles/render/svm.h

===================================================================

diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 5a43b641872..b6c743ac295 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -91,24 +91,20 @@ void OSLShaderManager::reset(Scene * /*scene*/)
   shading_system_init();
 }
 
-void OSLShaderManager::device_update_specific(Device *device,
-                                              DeviceScene *dscene,
-                                              Scene *scene,
-                                              Progress &progress)
+void OSLShaderManager::host_update_specific(Device *device, Scene *scene, Progress &progress)
 {
-  if (!need_update())
+  if (!need_update()) {
     return;
+  }
 
   scoped_callback_timer timer([scene](double time) {
     if (scene->update_stats) {
-      scene->update_stats->osl.times.add_entry({"device_update", time});
+      scene->update_stats->osl.times.add_entry({"host_update", time});
     }
   });
 
   VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
 
-  device_free(device, dscene, scene);
-
   /* set texture system */
   scene->image_manager->set_osl_texture_system((void *)ts);
 
@@ -116,13 +112,14 @@ void OSLShaderManager::device_update_specific(Device *device,
   OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
   Shader *background_shader = scene->background->get_shader(scene);
 
-  foreach (Shader *shader, scene->shaders) {
+  for (Shader *shader : scene->shaders) {
     assert(shader->graph);
 
-    if (progress.get_cancel())
+    if (progress.get_cancel()) {
       return;
+    }
 
-    /* we can only compile one shader at the time as the OSL ShadingSytem
+    /* we can only compile one shader at the time as the OSL ShadingSystem
      * has a single state, but we put the lock here so different renders can
      * compile shaders alternating */
     thread_scoped_lock lock(ss_mutex);
@@ -131,30 +128,15 @@ void OSLShaderManager::device_update_specific(Device *device,
     compiler.background = (shader == background_shader);
     compiler.compile(og, shader);
 
-    if (shader->get_use_mis() && shader->has_surface_emission)
+    if (shader->get_use_mis() && shader->has_surface_emission) {
       scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
+    }
   }
 
-  /* setup shader engine */
-  og->ss = ss;
-  og->ts = ts;
-  og->services = services;
-
-  int background_id = scene->shader_manager->get_shader_id(background_shader);
-  og->background_state = og->surface_state[background_id & SHADER_MASK];
-  og->use = true;
-
-  foreach (Shader *shader, scene->shaders)
-    shader->clear_modified();
-
-  update_flags = UPDATE_NONE;
-
   /* add special builtin texture types */
   services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
   services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
 
-  device_update_common(device, dscene, scene, progress);
-
   {
     /* Perform greedyjit optimization.
      *
@@ -172,6 +154,43 @@ void OSLShaderManager::device_update_specific(Device *device,
   }
 }
 
+void OSLShaderManager::device_update_specific(Device *device,
+                                              DeviceScene *dscene,
+                                              Scene *scene,
+                                              Progress &progress)
+{
+  if (!need_update())
+    return;
+
+  scoped_callback_timer timer([scene](double time) {
+    if (scene->update_stats) {
+      scene->update_stats->osl.times.add_entry({"device_update", time});
+    }
+  });
+
+  device_free(device, dscene, scene);
+
+  OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
+  Shader *background_shader = scene->background->get_shader(scene);
+
+  /* Setup shader engine. */
+  og->ss = ss;
+  og->ts = ts;
+  og->services = services;
+
+  const int background_id = scene->shader_manager->get_shader_id(background_shader);
+  og->background_state = og->surface_state[background_id & SHADER_MASK];
+  og->use = true;
+
+  foreach (Shader *shader, scene->shaders) {
+    shader->clear_modified();
+  }
+
+  update_flags = UPDATE_NONE;
+
+  device_update_common(device, dscene, scene, progress);
+}
+
 void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
 {
   OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index dfeec54d915..019dca16df7 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -79,6 +79,8 @@ class OSLShaderManager : public ShaderManager {
     return true;
   }
 
+  void host_update_specific(Device *device, Scene *scene, Progress &progress) override;
+
   void device_update_specific(Device *device,
                               DeviceScene *dscene,
                               Scene *scene,
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index eeb92122825..e65f542bd2e 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -228,6 +228,22 @@ void Scene::free_memory(bool final)
   }
 }
 
+void Scene::host_update(Device *device, Progress &progress)
+{
+  if (update_stats) {
+    update_stats->clear();
+  }
+
+  scoped_callback_timer timer([this](double time) {
+    if (update_stats) {
+      update_stats->scene.times.add_entry({"host_update", time});
+    }
+  });
+
+  progress.set_status("Updating Shaders");
+  shader_manager->host_update(device, this, progress);
+}
+
 void Scene::device_update(Device *device_, Progress &progress)
 {
   if (!device)
@@ -235,10 +251,6 @@ void Scene::device_update(Device *device_, Progress &progress)
 
   bool print_stats = need_data_update();
 
-  if (update_stats) {
-    update_stats->clear();
-  }
-
   scoped_callback_timer timer([this, print_stats](double time) {
     if (update_stats) {
       update_stats->scene.times.add_entry({"device_update", time});
@@ -537,11 +549,17 @@ bool Scene::update(Progress &progress)
     return false;
   }
 
-  /* Load render kernels, before device update where we upload data to the GPU. */
+  /* Update scene data on the host side.
+   * Only updates which do not depend on the kernel (including kernel features). */
+  progress.set_status("Updating Scene");
+  MEM_GUARDED_CALL(&progress, host_update, device, progress);
+
+  /* Load render kernels. After host scene update so that the required kernel features are known.
+   */
   load_kernels(progress, false);
 
-  /* Upload scene data to the GPU. */
-  progress.set_status("Updating Scene");
+  /* Upload scene data to the device. */
+  progress.set_status("Updating Scene Device");
   MEM_GUARDED_CALL(&progress, device_update, device, progress);
 
   return true;
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 001da31e893..83abb4c28db 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -251,6 +251,10 @@ class Scene : public NodeOwner {
   Scene(const SceneParams &params, Device *device);
   ~Scene();
 
+  /* NOTE: Device can only use used to access invariant data. For example, OSL globals is valid
+   * but anything what is related on kernel and kernel features is not. */
+  void host_update(Device *device, Progress &progress);
+
   void device_update(Device *device, Progress &progress);
 
   bool need_global_attribute(AttributeStandard std);
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 23786a3390f..cf18b269d4c 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -462,10 +462,7 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
   return id;
 }
 
-void ShaderManager::device_update(Device *device,
-                                  DeviceScene *dscene,
-                                  Scene *scene,
-                                  Progress &progress)
+void ShaderManager::host_update(Device *device, Scene *scene, Progress &progress)
 {
   if (!need_update()) {
     return;
@@ -483,6 +480,18 @@ void ShaderManager::device_update(Device *device,
   assert(scene->default_background->reference_count() != 0);
   assert(scene->default_empty->reference_count() != 0);
 
+  host_update_specific(device, scene, progress);
+}
+
+void ShaderManager::device_update(Device *device,
+                                  DeviceScene *dscene,
+                                  Scene *scene,
+                                  Progress &progress)
+{
+  if (!need_update()) {
+    return;
+  }
+
   device_update_specific(device, dscene, scene, progress);
 }
 
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 5f9adea3949..db5e06a715e 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -193,6 +193,9 @@ class ShaderManager {
     return false;
   }
 
+  void host_update(Device *device, Scene *scene, Progress &progress);
+  virtual void host_update_specific(Device *device, Scene *scene, Progress &progress) = 0;
+
   /* device update */
   void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
   virtual void device_update_specific(Device *device,
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 2379eb775a0..efbc446fc49 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -47,10 +47,10 @@ void SVMShaderManager::reset(Scene * /*scene*/)
 {
 }
 
-void SVMShaderManager::device_update_shader(Scene *scene,
-                                            Shader *shader,
-                                            Progress *progress,
-                                            array<int4> *svm_nodes)
+static void host_compile_shader(Scene *scene,
+                                Shader *shader,
+                                Progress *progress,
+                                array<int4> *svm_nodes)
 {
   if (progress->get_cancel()) {
     return;
@@ -69,6 +69,32 @@ void SVMShaderManager::device_update_shader(Scene *scene,
           << summary.full_report();
 }
 
+void SVMShaderManager::host_update_specific(Device * /*device*/, Scene *scene, Progress &progress)
+{
+  if (!need_update()) {
+    return;
+  }
+
+  scoped_callback_timer time

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list