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)); _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
