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.
This commit is contained in:
Sergey Sharybin 2018-09-28 12:39:49 +02:00
parent 45271007cf
commit b030277e79
11 changed files with 28 additions and 59 deletions

View 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);

View 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));

View 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

View 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;

View 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;

View 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

View 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));

View 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;

View 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;

View 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;

View 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