Cycles: Fix crash with BVH8 on certain scenes
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 28 Sep 2018 10:39:49 +0000 (12:39 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 28 Sep 2018 11:57:50 +0000 (13:57 +0200)
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.

intern/cycles/kernel/bvh/bvh.h
intern/cycles/kernel/bvh/obvh_local.h
intern/cycles/kernel/bvh/obvh_shadow_all.h
intern/cycles/kernel/bvh/obvh_traversal.h
intern/cycles/kernel/bvh/obvh_volume.h
intern/cycles/kernel/bvh/obvh_volume_all.h
intern/cycles/kernel/bvh/qbvh_local.h
intern/cycles/kernel/bvh/qbvh_shadow_all.h
intern/cycles/kernel/bvh/qbvh_traversal.h
intern/cycles/kernel/bvh/qbvh_volume.h
intern/cycles/kernel/bvh/qbvh_volume_all.h

index 2ad55d041bfc95a895b38c6114e295bd1396e2a9..b313557387838ee166020b551f4796ca33184d43 100644 (file)
@@ -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);
index 92143193a6a4b7090616893f0c45a129f60d560d..eb24a607caa5164c42d7f19da1284857ecd0bbf5 100644 (file)
@@ -73,12 +73,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
                object = local_object;
        }
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
        avxf tnear(0.0f), tfar(isect_t);
 #if BVH_FEATURE(BVH_HAIR)
        avx3f dir4(avxf(dir.x), avxf(dir.y), avxf(dir.z));
index 3e8770651275ff4c547951b4e20dd6a9770e73c7..6ea93c5e7b25bb14a566f46320c679731a3e99f2 100644 (file)
@@ -66,12 +66,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
        *num_hits = 0;
        isect_array->t = tmax;
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
 #if BVH_FEATURE(BVH_INSTANCING)
        int num_hits_in_instance = 0;
 #endif
index 98cd8f000ba12dee5564d14f1d35476e5e7afd3b..5010983057d3701694f338c948f2a84275076536 100644 (file)
@@ -64,12 +64,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
        Transform ob_itfm;
 #endif
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
        isect->t = ray->t;
        isect->u = 0.0f;
        isect->v = 0.0f;
index da9ddbd4f242368a88911341f6798f5cd46426cd..80d09c59039f775a8d1693b2ff5300c34628f608 100644 (file)
@@ -52,12 +52,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
        Transform ob_itfm;
 #endif
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
        isect->t = ray->t;
        isect->u = 0.0f;
        isect->v = 0.0f;
index a88573e6f86098d966f30ff22e8e6ade3ac8b5f8..87216127ddbb18c668c289718662cb28ffac4a93 100644 (file)
@@ -58,12 +58,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(OBVH)(KernelGlobals *kg,
        uint num_hits = 0;
        isect_array->t = tmax;
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return 0;
-       }
-#endif
-
 #if BVH_FEATURE(BVH_INSTANCING)
        int num_hits_in_instance = 0;
 #endif
index ee3827de3098fab978132e308b23218f19b5fd4a..22d434a8737d97e305519072dc4e25f8e9f6d421 100644 (file)
@@ -82,12 +82,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                object = local_object;
        }
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
        ssef tnear(0.0f), tfar(isect_t);
 #if BVH_FEATURE(BVH_HAIR)
        sse3f dir4(ssef(dir.x), ssef(dir.y), ssef(dir.z));
index 46fd178aed6bd32ef6bafd138b8cce977d0e794c..3610bdd560b18c7a98c1b7fb508274da986a02c2 100644 (file)
@@ -66,11 +66,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
        *num_hits = 0;
        isect_array->t = tmax;
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
 
 #if BVH_FEATURE(BVH_INSTANCING)
        int num_hits_in_instance = 0;
index b36689b2a2ee02bc67d76333efc8a666fa122199..ff675cab76bf7a478bdef86fcf20f66437eae221 100644 (file)
@@ -71,12 +71,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
        Transform ob_itfm;
 #endif
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
        isect->t = ray->t;
        isect->u = 0.0f;
        isect->v = 0.0f;
index 192ce0095243be04af27fdb5a20f456bf5a71a83..7ec264e5f78b6840809ead0b147f4f8edb3132c8 100644 (file)
@@ -58,12 +58,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
        Transform ob_itfm;
 #endif
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return false;
-       }
-#endif
-
        isect->t = ray->t;
        isect->u = 0.0f;
        isect->v = 0.0f;
index 1e454e4d36b3edcdac8c6ce823db421fd420693f..dd603d79334f865c38af5cc9fb7478542ea6e79f 100644 (file)
@@ -64,12 +64,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
        uint num_hits = 0;
        isect_array->t = tmax;
 
-#ifndef __KERNEL_SSE41__
-       if(!isfinite(P.x)) {
-               return 0;
-       }
-#endif
-
 #if BVH_FEATURE(BVH_INSTANCING)
        int num_hits_in_instance = 0;
 #endif