From 5376b3eeca6ee54470808dd7bb10d3d0d44be36b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 19 Jul 2017 11:04:04 +0200 Subject: Fix T52116: Blender internal BVH build crash in degenerate cases. --- source/blender/render/intern/raytrace/rayobject_rtbuild.cpp | 12 ++++++++++++ source/blender/render/intern/raytrace/rayobject_rtbuild.h | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'source/blender/render') diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 81e41a20f2e..103fa3e6034 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -59,6 +59,7 @@ static void rtbuild_init(RTBuilder *b) b->primitives.begin = NULL; b->primitives.end = NULL; b->primitives.maxsize = 0; + b->depth = 0; for (int i = 0; i < RTBUILD_MAX_CHILDS; i++) b->child_offset[i] = 0; @@ -178,6 +179,8 @@ RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) { rtbuild_init(tmp); + tmp->depth = b->depth + 1; + for (int i = 0; i < 3; i++) if (b->sorted_begin[i]) { tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child]; @@ -336,6 +339,15 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds) int baxis = -1, boffset = 0; if (size > nchilds) { + if (b->depth > RTBUILD_MAX_SAH_DEPTH) { + // for degenerate cases we avoid running out of stack space + // by simply splitting the children in the middle + b->child_offset[0] = 0; + b->child_offset[1] = (size+1)/2; + b->child_offset[2] = size; + return 2; + } + float bcost = FLT_MAX; baxis = -1; boffset = size / 2; diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h index 9e296da144b..83042ef3d7e 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -49,7 +49,8 @@ extern "C" { * generate with simple calls, and then convert to the theirs * specific structure on the fly. */ -#define RTBUILD_MAX_CHILDS 32 +#define RTBUILD_MAX_CHILDS 32 +#define RTBUILD_MAX_SAH_DEPTH 256 typedef struct RTBuilder { @@ -79,6 +80,8 @@ typedef struct RTBuilder { float bb[6]; + /* current depth */ + int depth; } RTBuilder; /* used during creation */ -- cgit v1.2.3