From 83ce02879f7c6733adc098d00a01963fc4212abd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 6 Oct 2017 21:06:15 +0500 Subject: [PATCH] Cycles: Fix possible race condition when generating Beckmann table Two issues here: - Checking table size to be non-zero is not a proper way to go here. This is because we first resize the table and then fill it in. So it was possible that non-initialized table was used. Trickery with using temporary memory and then doing table.swap() might work, but we can not guarantee that table size will be set after the data pointer. - Mutex guard was useless, because every thread was using own mutex. Need to make mutex guard static so all threads are using same mutex. --- intern/cycles/render/shader.cpp | 7 +++++-- intern/cycles/render/shader.h | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 86378dfb495..864875361c0 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -33,7 +33,9 @@ CCL_NAMESPACE_BEGIN +thread_mutex ShaderManager::lookup_table_mutex; vector ShaderManager::beckmann_table; +bool ShaderManager::beckmann_table_ready = false; /* Beckmann sampling precomputed table, see bsdf_microfacet.h */ @@ -482,10 +484,11 @@ void ShaderManager::device_update_common(Device *device, /* beckmann lookup table */ if(beckmann_table_offset == TABLE_OFFSET_INVALID) { - if(beckmann_table.size() == 0) { + if(!beckmann_table_ready) { thread_scoped_lock lock(lookup_table_mutex); - if(beckmann_table.size() == 0) { + if(!beckmann_table_ready) { beckmann_table_build(beckmann_table); + beckmann_table_ready = true; } } beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table); diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 79a67d6756a..3fdcd3c0c5b 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -200,8 +200,9 @@ protected: typedef unordered_map AttributeIDMap; AttributeIDMap unique_attribute_id; - thread_mutex lookup_table_mutex; + static thread_mutex lookup_table_mutex; static vector beckmann_table; + static bool beckmann_table_ready; size_t beckmann_table_offset;