diff options
Diffstat (limited to 'intern/cycles/kernel/geom/geom_bvh_shadow.h')
-rw-r--r-- | intern/cycles/kernel/geom/geom_bvh_shadow.h | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h index aee4097d77e..193f49074a3 100644 --- a/intern/cycles/kernel/geom/geom_bvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h @@ -17,6 +17,10 @@ * limitations under the License. */ +#ifdef __QBVH__ +#include "geom_qbvh_shadow.h" +#endif + /* This is a template BVH traversal function, where various features can be * enabled/disabled. This way we can compile optimized versions for each case * without new features slowing things down. @@ -27,10 +31,11 @@ * */ -#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0) - -ccl_device bool BVH_FUNCTION_NAME -(KernelGlobals *kg, const Ray *ray, Intersection *isect_array, const uint max_hits, uint *num_hits) +ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, + const Ray *ray, + Intersection *isect_array, + const uint max_hits, + uint *num_hits) { /* todo: * - likely and unlikely for if() statements @@ -53,11 +58,11 @@ ccl_device bool BVH_FUNCTION_NAME int object = OBJECT_NONE; float isect_t = tmax; -#if FEATURE(BVH_MOTION) +#if BVH_FEATURE(BVH_MOTION) Transform ob_tfm; #endif -#if FEATURE(BVH_INSTANCING) +#if BVH_FEATURE(BVH_INSTANCING) int num_hits_in_instance = 0; #endif @@ -81,6 +86,9 @@ ccl_device bool BVH_FUNCTION_NAME gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz); #endif + IsectPrecalc isect_precalc; + triangle_intersect_precalc(dir, &isect_precalc); + /* traversal loop */ do { do { @@ -174,6 +182,7 @@ ccl_device bool BVH_FUNCTION_NAME } ++stackPtr; + kernel_assert(stackPtr < BVH_STACK_SIZE); traversalStack[stackPtr] = nodeAddrChild1; } else { @@ -191,13 +200,15 @@ ccl_device bool BVH_FUNCTION_NAME /* if node is leaf, fetch triangle list */ if(nodeAddr < 0) { - float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1)); + float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+3); int primAddr = __float_as_int(leaf.x); -#if FEATURE(BVH_INSTANCING) +#if BVH_FEATURE(BVH_INSTANCING) if(primAddr >= 0) { #endif - int primAddr2 = __float_as_int(leaf.y); + const int primAddr2 = __float_as_int(leaf.y); + const uint type = __float_as_int(leaf.w); + const uint p_type = type & PRIMITIVE_ALL; /* pop */ nodeAddr = traversalStack[stackPtr]; @@ -205,25 +216,26 @@ ccl_device bool BVH_FUNCTION_NAME /* primitive intersection */ while(primAddr < primAddr2) { + kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type); + bool hit; - uint type = kernel_tex_fetch(__prim_type, primAddr); /* todo: specialized intersect functions which don't fill in * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW? * might give a few % performance improvement */ - switch(type & PRIMITIVE_ALL) { + switch(p_type) { case PRIMITIVE_TRIANGLE: { - hit = triangle_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr); + hit = triangle_intersect(kg, &isect_precalc, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr); break; } -#if FEATURE(BVH_MOTION) +#if BVH_FEATURE(BVH_MOTION) case PRIMITIVE_MOTION_TRIANGLE: { hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, PATH_RAY_SHADOW, object, primAddr); break; } #endif -#if FEATURE(BVH_HAIR) +#if BVH_FEATURE(BVH_HAIR) case PRIMITIVE_CURVE: case PRIMITIVE_MOTION_CURVE: { if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) @@ -274,7 +286,7 @@ ccl_device bool BVH_FUNCTION_NAME /* move on to next entry in intersections array */ isect_array++; (*num_hits)++; -#if FEATURE(BVH_INSTANCING) +#if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; #endif @@ -284,52 +296,55 @@ ccl_device bool BVH_FUNCTION_NAME primAddr++; } } -#if FEATURE(BVH_INSTANCING) +#if BVH_FEATURE(BVH_INSTANCING) else { /* instance push */ object = kernel_tex_fetch(__prim_object, -primAddr-1); -#if FEATURE(BVH_MOTION) +#if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif + triangle_intersect_precalc(dir, &isect_precalc); num_hits_in_instance = 0; + isect_array->t = isect_t; #if defined(__KERNEL_SSE2__) Psplat[0] = ssef(P.x); Psplat[1] = ssef(P.y); Psplat[2] = ssef(P.z); - isect_array->t = isect_t; tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t); - gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz); #endif ++stackPtr; + kernel_assert(stackPtr < BVH_STACK_SIZE); traversalStack[stackPtr] = ENTRYPOINT_SENTINEL; nodeAddr = kernel_tex_fetch(__object_node, object); } } -#endif +#endif /* FEATURE(BVH_INSTANCING) */ } while(nodeAddr != ENTRYPOINT_SENTINEL); -#if FEATURE(BVH_INSTANCING) +#if BVH_FEATURE(BVH_INSTANCING) if(stackPtr >= 0) { kernel_assert(object != OBJECT_NONE); if(num_hits_in_instance) { float t_fac; -#if FEATURE(BVH_MOTION) +#if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif + triangle_intersect_precalc(dir, &isect_precalc); + /* scale isect->t to adjust for instancing */ for(int i = 0; i < num_hits_in_instance; i++) (isect_array-i-1)->t *= t_fac; @@ -337,22 +352,23 @@ ccl_device bool BVH_FUNCTION_NAME else { float ignore_t = FLT_MAX; -#if FEATURE(BVH_MOTION) +#if BVH_FEATURE(BVH_MOTION) bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif + triangle_intersect_precalc(dir, &isect_precalc); } + isect_t = tmax; + isect_array->t = isect_t; + #if defined(__KERNEL_SSE2__) Psplat[0] = ssef(P.x); Psplat[1] = ssef(P.y); Psplat[2] = ssef(P.z); - isect_t = tmax; - isect_array->t = isect_t; tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t); - gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz); #endif @@ -360,13 +376,37 @@ ccl_device bool BVH_FUNCTION_NAME nodeAddr = traversalStack[stackPtr]; --stackPtr; } -#endif +#endif /* FEATURE(BVH_INSTANCING) */ } while(nodeAddr != ENTRYPOINT_SENTINEL); return false; } -#undef FEATURE +ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg, + const Ray *ray, + Intersection *isect_array, + const uint max_hits, + uint *num_hits) +{ +#ifdef __QBVH__ + if(kernel_data.bvh.use_qbvh) { + return BVH_FUNCTION_FULL_NAME(QBVH)(kg, + ray, + isect_array, + max_hits, + num_hits); + } + else +#endif + { + kernel_assert(kernel_data.bvh.use_qbvh == false); + return BVH_FUNCTION_FULL_NAME(BVH)(kg, + ray, + isect_array, + max_hits, + num_hits); + } +} + #undef BVH_FUNCTION_NAME #undef BVH_FUNCTION_FEATURES - |