From adb31c481bb14841a6ea9b87a739f66a513607c0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 26 May 2023 18:04:05 +0200 Subject: [PATCH 1/3] Fix #108316: CUDA error rendering Attic scene The light tree dependent on the first threshold to evaluate to 1 when picking up an emitter. --- intern/cycles/kernel/light/tree.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 284f8eb5397..0dfdc094e16 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -509,6 +509,19 @@ ccl_device void sample_reservoir(const int current_index, return; } total_weight += current_weight; + + /* When `-fast-math` is used it is possible that the threshold is almost 1 but not quite. + * For this case we check the first assignment explicitly (instead of relying on the threshold to + * be 1, giving it certain probability). */ + if (selected_index == -1) { + selected_index = current_index; + selected_weight = current_weight; + /* The threshold is expected to be 1 in this case with strict mathematics, so no need to divide + * the rand. In fact, division in such case could lead the rand to exceed 1 because of division + * by something smaller than 1. */ + return; + } + float thresh = current_weight / total_weight; if (rand <= thresh) { selected_index = current_index; @@ -519,7 +532,6 @@ ccl_device void sample_reservoir(const int current_index, rand = (rand - thresh) / (1.0f - thresh); } kernel_assert(rand >= 0.0f && rand <= 1.0f); - return; } /* Pick an emitter from a leaf node using reservoir sampling, keep two reservoirs for upper and -- 2.30.2 From 49105bf7b4f983dffb6aa0b0846f386d873547eb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 26 May 2023 18:24:58 +0200 Subject: [PATCH 2/3] Ensure the rand is always within 0 .. 1 --- intern/cycles/kernel/light/tree.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 0dfdc094e16..1e78ce8b8ec 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -531,7 +531,8 @@ ccl_device void sample_reservoir(const int current_index, else { rand = (rand - thresh) / (1.0f - thresh); } - kernel_assert(rand >= 0.0f && rand <= 1.0f); + + rand = saturatef(rand); } /* Pick an emitter from a leaf node using reservoir sampling, keep two reservoirs for upper and -- 2.30.2 From 0e9c30e3154fa3781cd947c553c6d05562bee22f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 26 May 2023 18:28:45 +0200 Subject: [PATCH 3/3] Use correct compiler flag name in the comment --- intern/cycles/kernel/light/tree.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 1e78ce8b8ec..cb8f85d206d 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -510,7 +510,7 @@ ccl_device void sample_reservoir(const int current_index, } total_weight += current_weight; - /* When `-fast-math` is used it is possible that the threshold is almost 1 but not quite. + /* When `-ffast-math` is used it is possible that the threshold is almost 1 but not quite. * For this case we check the first assignment explicitly (instead of relying on the threshold to * be 1, giving it certain probability). */ if (selected_index == -1) { @@ -532,6 +532,8 @@ ccl_device void sample_reservoir(const int current_index, rand = (rand - thresh) / (1.0f - thresh); } + /* Ensure the `rand` is always within 0..1 range, which could be violated above when + * `-ffast-math` is used. */ rand = saturatef(rand); } -- 2.30.2