[Bf-blender-cvs] [fa9fc59b560] master: Fix T104240: OptiX OSL texture loading broken with displacement

Patrick Mours noreply at git.blender.org
Tue Jan 31 16:41:33 CET 2023


Commit: fa9fc59b560a9743b1cbe7d46e0d5de98a2f3567
Author: Patrick Mours
Date:   Tue Jan 31 16:35:47 2023 +0100
Branches: master
https://developer.blender.org/rBfa9fc59b560a9743b1cbe7d46e0d5de98a2f3567

Fix T104240: OptiX OSL texture loading broken with displacement

The image manager used to handle OSL textures on the GPU by
default loads images after displacement is evaluated. This is a
problem when the displacement shader uses any textures, hence
why the geometry manager already makes the image manager
load any images used in the displacement shader graph early
(`GeometryManager::device_update_displacement_images`).
This only handled Cycles image nodes however, not OSL nodes, so
if any `texture` calls were made in OSL those would be missed and
therefore crash when accessed on the GPU. Unfortunately it is not
simple to determine which textures referenced by OSL are needed
for displacement, so the solution for now is to simply load all of
them early if true displacement is used.
This patch also fixes the result of the displacement shader not
being used properly in OptiX.

Maniphest Tasks: T104240

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

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

M	intern/cycles/kernel/osl/osl.h
M	intern/cycles/scene/geometry.cpp

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

diff --git a/intern/cycles/kernel/osl/osl.h b/intern/cycles/kernel/osl/osl.h
index ffaf87b7048..18288d202b5 100644
--- a/intern/cycles/kernel/osl/osl.h
+++ b/intern/cycles/kernel/osl/osl.h
@@ -161,7 +161,10 @@ ccl_device_inline void osl_eval_nodes(KernelGlobals kg,
                         /* shadeindex = */ 0);
 #  endif
 
-  if (globals.Ci) {
+  if constexpr (type == SHADER_TYPE_DISPLACEMENT) {
+    sd->P = globals.P;
+  }
+  else if (globals.Ci) {
     flatten_closure_tree(kg, sd, path_flag, globals.Ci);
   }
 }
diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp
index a1df24878c9..4c5013b5a9f 100644
--- a/intern/cycles/scene/geometry.cpp
+++ b/intern/cycles/scene/geometry.cpp
@@ -23,7 +23,10 @@
 #include "subd/patch_table.h"
 #include "subd/split.h"
 
-#include "kernel/osl/globals.h"
+#ifdef WITH_OSL
+#  include "kernel/osl/globals.h"
+#  include "kernel/osl/services.h"
+#endif
 
 #include "util/foreach.h"
 #include "util/log.h"
@@ -1671,6 +1674,7 @@ void GeometryManager::device_update_displacement_images(Device *device,
   TaskPool pool;
   ImageManager *image_manager = scene->image_manager;
   set<int> bump_images;
+  bool has_osl_node = false;
   foreach (Geometry *geom, scene->geometry) {
     if (geom->is_modified()) {
       /* Geometry-level check for hair shadow transparency.
@@ -1690,6 +1694,9 @@ void GeometryManager::device_update_displacement_images(Device *device,
           continue;
         }
         foreach (ShaderNode *node, shader->graph->nodes) {
+          if (node->special_type == SHADER_SPECIAL_TYPE_OSL) {
+            has_osl_node = true;
+          }
           if (node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
             continue;
           }
@@ -1705,6 +1712,28 @@ void GeometryManager::device_update_displacement_images(Device *device,
       }
     }
   }
+
+#ifdef WITH_OSL
+  /* If any OSL node is used for displacement, it may reference a texture. But it's
+   * unknown which ones, so have to load them all. */
+  if (has_osl_node) {
+    set<OSLRenderServices *> services_shared;
+    device->foreach_device([&services_shared](Device *sub_device) {
+      OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
+      services_shared.insert(og->services);
+    });
+
+    for (OSLRenderServices *services : services_shared) {
+      for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
+        if (it->second->handle.get_manager() == image_manager) {
+          const int slot = it->second->handle.svm_slot();
+          bump_images.insert(slot);
+        }
+      }
+    }
+  }
+#endif
+
   foreach (int slot, bump_images) {
     pool.push(function_bind(
         &ImageManager::device_update_slot, image_manager, device, scene, slot, &progress));



More information about the Bf-blender-cvs mailing list