diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-28 13:39:49 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-09-28 14:57:50 +0300 |
commit | b030277e791e429e8f8de90316144830eda6bbf8 (patch) | |
tree | 8a221109f49d2c936be8e05dc980324d79f45518 /intern/cycles/kernel/bvh/bvh.h | |
parent | 45271007cfaf4a515bb73530c48c33dab27b0d39 (diff) |
Cycles: Fix crash with BVH8 on certain scenes
The crash was caused by BVH traversal stack being overflowed.
That overflow was caused by lots of false-positive intersections
for rays originating on a non-finite location.
Not sure why those rays will be existing in the first place,
this is to be investigated separately.
This commit moves pre-SSE4.1 check to a higher level function
and enables it for all miroarchitectures.
Diffstat (limited to 'intern/cycles/kernel/bvh/bvh.h')
-rw-r--r-- | intern/cycles/kernel/bvh/bvh.h | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index 2ad55d041bf..b3135573878 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -160,6 +160,19 @@ CCL_NAMESPACE_BEGIN #undef BVH_NAME_EVAL #undef BVH_FUNCTION_FULL_NAME +ccl_device_inline bool scene_intersect_valid(const Ray *ray) +{ + /* NOTE: Due to some vectorization code non-finite origin point might + * cause lots of false-positive intersections which will overflow traversal + * stack. + * This code is a quick way to perform early output, to avoid crashes in + * such cases. + * From production scenes so far it seems it's enough to test first element + * only. + */ + return finite(ray->P.x); +} + /* Note: ray is passed by value to work around a possible CUDA compiler bug. */ ccl_device_intersect bool scene_intersect(KernelGlobals *kg, const Ray ray, @@ -169,6 +182,9 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg, float difl, float extmax) { + if (!scene_intersect_valid(&ray)) { + return false; + } #ifdef __OBJECT_MOTION__ if(kernel_data.bvh.have_motion) { # ifdef __HAIR__ @@ -213,6 +229,9 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg, uint *lcg_state, int max_hits) { + if (!scene_intersect_valid(&ray)) { + return false; + } #ifdef __OBJECT_MOTION__ if(kernel_data.bvh.have_motion) { return bvh_intersect_local_motion(kg, @@ -240,6 +259,9 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, uint max_hits, uint *num_hits) { + if (!scene_intersect_valid(ray)) { + return false; + } # ifdef __OBJECT_MOTION__ if(kernel_data.bvh.have_motion) { # ifdef __HAIR__ @@ -299,6 +321,9 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg, Intersection *isect, const uint visibility) { + if (!scene_intersect_valid(ray)) { + return false; + } # ifdef __OBJECT_MOTION__ if(kernel_data.bvh.have_motion) { return bvh_intersect_volume_motion(kg, ray, isect, visibility); @@ -327,6 +352,9 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg, const uint max_hits, const uint visibility) { + if (!scene_intersect_valid(ray)) { + return false; + } # ifdef __OBJECT_MOTION__ if(kernel_data.bvh.have_motion) { return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility); |