Fix T55436: crash with point density and shader tweaking.

With copy-on-write we can no longer assumes the point density data is
available after Cycles synchronization with Blender data is done. So
force it to be loaded earlier, even if it's not great for interactivity.
This commit is contained in:
Brecht Van Lommel 2018-06-11 16:29:49 +02:00
parent 84692844a3
commit 0461f45e5e
Notes: blender-bot 2023-02-14 11:21:43 +01:00
Referenced by issue #55436, Crash when tweaking shader values connected to Point Density node
7 changed files with 71 additions and 18 deletions

View File

@ -454,6 +454,7 @@ void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
b_camera_override,
width, height,
&python_thread_state);
builtin_images_load();
/* Make sure all views have different noise patterns. - hardcoded value just to make it random */
if(view_index != 0) {
@ -614,6 +615,7 @@ void BlenderSession::bake(BL::Depsgraph& b_depsgraph_,
b_camera_override,
width, height,
&python_thread_state);
builtin_images_load();
}
BakeData *bake_data = NULL;
@ -803,6 +805,8 @@ void BlenderSession::synchronize(BL::Depsgraph& b_depsgraph_)
else
sync->sync_camera(b_render, b_camera_override, width, height, "");
builtin_images_load();
/* unlock */
session->scene->mutex.unlock();
@ -1327,6 +1331,16 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
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,

View File

@ -166,6 +166,7 @@ protected:
float *pixels,
const size_t pixels_size,
const bool free_cache);
void builtin_images_load();
/* Update tile manager to reflect resumable render settings. */
void update_resumable_tile_manager(int num_samples);

View File

@ -862,9 +862,11 @@ static ShaderNode *add_node(Scene *scene,
point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
point_density->interpolation = get_image_interpolation(b_point_density_node);
point_density->builtin_data = b_point_density_node.ptr.data;
point_density->image_manager = scene->image_manager;
/* TODO(sergey): Use more proper update flag. */
if(true) {
point_density->add_image();
b_point_density_node.cache_point_density(b_depsgraph);
scene->image_manager->tag_reload_image(
point_density->filename.string(),

View File

@ -943,6 +943,39 @@ void ImageManager::device_update_slot(Device *device,
}
}
void ImageManager::device_load_builtin(Device *device,
Scene *scene,
Progress& progress)
{
/* Load only builtin images, Blender needs this to load evaluated
* scene data from depsgraph before it is freed. */
if(!need_update) {
return;
}
TaskPool pool;
for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
for(size_t slot = 0; slot < images[type].size(); slot++) {
if(!images[type][slot])
continue;
if(images[type][slot]->need_load) {
if(images[type][slot]->builtin_data) {
pool.push(function_bind(&ImageManager::device_load_image,
this,
device,
scene,
(ImageDataType)type,
slot,
&progress));
}
}
}
}
pool.wait_work();
}
void ImageManager::device_free_builtin(Device *device)
{
for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {

View File

@ -80,6 +80,10 @@ public:
int flat_slot,
Progress *progress);
void device_free(Device *device);
void device_load_builtin(Device *device,
Scene *scene,
Progress& progress);
void device_free_builtin(Device *device);
void set_osl_texture_system(void *texture_system);

View File

@ -1488,6 +1488,19 @@ void PointDensityTextureNode::attributes(Shader *shader,
ShaderNode::attributes(shader, attributes);
}
void PointDensityTextureNode::add_image()
{
if(slot == -1) {
ImageMetaData metadata;
slot = image_manager->add_image(filename.string(), builtin_data,
false, 0,
interpolation,
EXTENSION_CLIP,
true,
metadata);
}
}
void PointDensityTextureNode::compile(SVMCompiler& compiler)
{
ShaderInput *vector_in = input("Vector");
@ -1500,15 +1513,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(use_density || use_color) {
if(slot == -1) {
ImageMetaData metadata;
slot = image_manager->add_image(filename.string(), builtin_data,
false, 0,
interpolation,
EXTENSION_CLIP,
true,
metadata);
}
add_image();
if(slot != -1) {
compiler.stack_assign(vector_in);
@ -1551,15 +1556,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler)
image_manager = compiler.image_manager;
if(use_density || use_color) {
if(slot == -1) {
ImageMetaData metadata;
slot = image_manager->add_image(filename.string(), builtin_data,
false, 0,
interpolation,
EXTENSION_CLIP,
true,
metadata);
}
add_image();
if(slot != -1) {
compiler.parameter("filename", string_printf("@i%d", slot).c_str());

View File

@ -265,6 +265,8 @@ public:
bool has_spatial_varying() { return true; }
bool has_object_dependency() { return true; }
void add_image();
ustring filename;
NodeTexVoxelSpace space;
InterpolationType interpolation;