From 46d82a2a1246c3a2497e591f604e4fc62c7b519d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 27 Sep 2012 17:42:09 +0000 Subject: Fix #32618: cycles multithreaded image loading could crash with CUDA, was a threading issue that happens once every X frames. --- intern/cycles/render/image.cpp | 42 +++++++++++++++++++++++++++++++----------- intern/cycles/render/image.h | 2 ++ 2 files changed, 33 insertions(+), 11 deletions(-) (limited to 'intern') diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 4ee024dd52a..f136f08dc2c 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -366,8 +366,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl device_vector& tex_img = dscene->tex_float_image[slot]; - if(tex_img.device_pointer) + if(tex_img.device_pointer) { + thread_scoped_lock device_lock(device_mutex); device->tex_free(tex_img); + } if(!file_load_float_image(img, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ @@ -384,8 +386,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl if(slot >= 10) name = string_printf("__tex_image_float_0%d", slot); else name = string_printf("__tex_image_float_00%d", slot); - if(!pack_images) + if(!pack_images) { + thread_scoped_lock device_lock(device_mutex); device->tex_alloc(name.c_str(), tex_img, true, true); + } } else { string filename = path_filename(images[slot - tex_image_byte_start]->filename); @@ -393,8 +397,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl device_vector& tex_img = dscene->tex_image[slot - tex_image_byte_start]; - if(tex_img.device_pointer) + if(tex_img.device_pointer) { + thread_scoped_lock device_lock(device_mutex); device->tex_free(tex_img); + } if(!file_load_image(img, tex_img)) { /* on failure to load, we set a 1x1 pixels pink image */ @@ -411,8 +417,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl if(slot >= 10) name = string_printf("__tex_image_0%d", slot); else name = string_printf("__tex_image_00%d", slot); - if(!pack_images) + if(!pack_images) { + thread_scoped_lock device_lock(device_mutex); device->tex_alloc(name.c_str(), tex_img, true, true); + } } img->need_load = false; @@ -440,15 +448,27 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, int sl #endif } else if(is_float) { - device->tex_free(dscene->tex_float_image[slot]); - dscene->tex_float_image[slot].clear(); + device_vector& tex_img = dscene->tex_float_image[slot]; + + if(tex_img.device_pointer) { + thread_scoped_lock device_lock(device_mutex); + device->tex_free(tex_img); + } + + tex_img.clear(); delete float_images[slot]; float_images[slot] = NULL; } else { - device->tex_free(dscene->tex_image[slot - tex_image_byte_start]); - dscene->tex_image[slot - tex_image_byte_start].clear(); + device_vector& tex_img = dscene->tex_image[slot - tex_image_byte_start]; + + if(tex_img.device_pointer) { + thread_scoped_lock device_lock(device_mutex); + device->tex_free(tex_img); + } + + tex_img.clear(); delete images[slot - tex_image_byte_start]; images[slot - tex_image_byte_start] = NULL; @@ -460,7 +480,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& { if(!need_update) return; - + TaskPool pool; for(size_t slot = 0; slot < images.size(); slot++) { @@ -542,9 +562,9 @@ void ImageManager::device_free(Device *device, DeviceScene *dscene) device_free_image(device, dscene, slot); device->tex_free(dscene->tex_image_packed); - dscene->tex_image_packed.clear(); - device->tex_free(dscene->tex_image_packed_info); + + dscene->tex_image_packed.clear(); dscene->tex_image_packed_info.clear(); images.clear(); diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 04a705c27bf..8fb229282dc 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -22,6 +22,7 @@ #include "device_memory.h" #include "util_string.h" +#include "util_thread.h" #include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -66,6 +67,7 @@ private: int tex_num_images; int tex_num_float_images; int tex_image_byte_start; + thread_mutex device_mutex; struct Image { string filename; -- cgit v1.2.3