Cycles: Move triangle intersection precalc to an util file
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 23 Mar 2017 12:01:42 +0000 (13:01 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 23 Mar 2017 16:45:19 +0000 (17:45 +0100)
This is a preparation work for the followup commit which wil l move
remaining parts of Woop intersection logic to an utility file.

Doing it as a separate commit to keep changes more atomic and easier
to bisect when/if needed.

12 files changed:
intern/cycles/kernel/bvh/bvh_shadow_all.h
intern/cycles/kernel/bvh/bvh_subsurface.h
intern/cycles/kernel/bvh/bvh_traversal.h
intern/cycles/kernel/bvh/bvh_volume.h
intern/cycles/kernel/bvh/bvh_volume_all.h
intern/cycles/kernel/bvh/qbvh_shadow_all.h
intern/cycles/kernel/bvh/qbvh_subsurface.h
intern/cycles/kernel/bvh/qbvh_traversal.h
intern/cycles/kernel/bvh/qbvh_volume.h
intern/cycles/kernel/bvh/qbvh_volume_all.h
intern/cycles/kernel/geom/geom_triangle_intersect.h
intern/cycles/util/util_math_intersect.h

index b4f65bc..a6e23d9 100644 (file)
@@ -100,8 +100,8 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
        gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
 #endif  /* __KERNEL_SSE2__ */
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* traversal loop */
        do {
@@ -314,7 +314,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                        isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
 #  endif
 
-                                       triangle_intersect_precalc(dir, &isect_precalc);
+                                       ray_triangle_intersect_precalc(dir, &isect_precalc);
                                        num_hits_in_instance = 0;
                                        isect_array->t = isect_t;
 
@@ -354,7 +354,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
 #  endif
 
-                               triangle_intersect_precalc(dir, &isect_precalc);
+                               ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                                /* scale isect->t to adjust for instancing */
                                for(int i = 0; i < num_hits_in_instance; i++) {
@@ -367,7 +367,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 #  else
                                bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
 #  endif
-                               triangle_intersect_precalc(dir, &isect_precalc);
+                               ray_triangle_intersect_precalc(dir, &isect_precalc);
                        }
 
                        isect_t = tmax;
index 583f7f7..11ea1f8 100644 (file)
@@ -109,8 +109,8 @@ void BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
        gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
 #endif
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* traversal loop */
        do {
index 0eca0c8..7c4671e 100644 (file)
@@ -104,8 +104,8 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
        gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
 #endif
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* traversal loop */
        do {
@@ -358,7 +358,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 #  else
                                        isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
 #  endif
-                                       triangle_intersect_precalc(dir, &isect_precalc);
+                                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
 #  if defined(__KERNEL_SSE2__)
                                        Psplat[0] = ssef(P.x);
@@ -395,7 +395,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 #  else
                        isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
 #  endif
-                       triangle_intersect_precalc(dir, &isect_precalc);
+                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
 #  if defined(__KERNEL_SSE2__)
                        Psplat[0] = ssef(P.x);
index 136034a..45b5a3c 100644 (file)
@@ -97,8 +97,8 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
        gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
 #endif
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* traversal loop */
        do {
@@ -243,7 +243,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                                isect->t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect->t);
 #  endif
 
-                                               triangle_intersect_precalc(dir, &isect_precalc);
+                                               ray_triangle_intersect_precalc(dir, &isect_precalc);
 
 #  if defined(__KERNEL_SSE2__)
                                                Psplat[0] = ssef(P.x);
@@ -286,7 +286,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                        isect->t = bvh_instance_pop(kg, object, ray, &P, &dir, &idir, isect->t);
 #  endif
 
-                       triangle_intersect_precalc(dir, &isect_precalc);
+                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
 #  if defined(__KERNEL_SSE2__)
                        Psplat[0] = ssef(P.x);
index 6f3346e..62018e0 100644 (file)
@@ -101,8 +101,8 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
        gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
 #endif  /* __KERNEL_SSE2__ */
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* traversal loop */
        do {
@@ -294,7 +294,7 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
                                                isect_t = bvh_instance_push(kg, object, ray, &P, &dir, &idir, isect_t);
 #  endif
 
-                                               triangle_intersect_precalc(dir, &isect_precalc);
+                                               ray_triangle_intersect_precalc(dir, &isect_precalc);
                                                num_hits_in_instance = 0;
                                                isect_array->t = isect_t;
 
@@ -340,7 +340,7 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 #  else
                                bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
 #  endif
-                               triangle_intersect_precalc(dir, &isect_precalc);
+                               ray_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;
@@ -352,7 +352,7 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
 #  else
                                bvh_instance_pop(kg, object, ray, &P, &dir, &idir, FLT_MAX);
 #  endif
-                               triangle_intersect_precalc(dir, &isect_precalc);
+                               ray_triangle_intersect_precalc(dir, &isect_precalc);
                        }
 
                        isect_t = tmax;
index 2a4da3e..5a8ec47 100644 (file)
@@ -96,8 +96,8 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                               &near_x, &near_y, &near_z,
                               &far_x, &far_y, &far_z);
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* Traversal loop. */
        do {
@@ -414,7 +414,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                        org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                                       triangle_intersect_precalc(dir, &isect_precalc);
+                                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                                        ++stack_ptr;
                                        kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
@@ -471,7 +471,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                        org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                       triangle_intersect_precalc(dir, &isect_precalc);
+                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                        object = OBJECT_NONE;
                        node_addr = traversal_stack[stack_ptr].addr;
index a6431a9..d466fe7 100644 (file)
@@ -105,8 +105,8 @@ ccl_device void BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                               &near_x, &near_y, &near_z,
                               &far_x, &far_y, &far_z);
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* Traversal loop. */
        do {
index c20a8f3..bf69bfa 100644 (file)
@@ -106,8 +106,8 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                               &near_x, &near_y, &near_z,
                               &far_x, &far_y, &far_z);
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* Traversal loop. */
        do {
@@ -447,7 +447,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                        org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                                       triangle_intersect_precalc(dir, &isect_precalc);
+                                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                                        ++stack_ptr;
                                        kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
@@ -489,7 +489,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                        org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                       triangle_intersect_precalc(dir, &isect_precalc);
+                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                        object = OBJECT_NONE;
                        node_addr = traversal_stack[stack_ptr].addr;
index 859c5da..d34ddb6 100644 (file)
@@ -91,8 +91,8 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                               &near_x, &near_y, &near_z,
                               &far_x, &far_y, &far_z);
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* Traversal loop. */
        do {
@@ -316,7 +316,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                                org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                                               triangle_intersect_precalc(dir, &isect_precalc);
+                                               ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                                                ++stack_ptr;
                                                kernel_assert(stack_ptr < BVH_QSTACK_SIZE);
@@ -362,7 +362,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                        org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                       triangle_intersect_precalc(dir, &isect_precalc);
+                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                        object = OBJECT_NONE;
                        node_addr = traversal_stack[stack_ptr].addr;
index bbe588c..4e1ee04 100644 (file)
@@ -95,8 +95,8 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                               &near_x, &near_y, &near_z,
                               &far_x, &far_y, &far_z);
 
-       IsectPrecalc isect_precalc;
-       triangle_intersect_precalc(dir, &isect_precalc);
+       TriangleIsectPrecalc isect_precalc;
+       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
        /* Traversal loop. */
        do {
@@ -367,7 +367,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                                                org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                                               triangle_intersect_precalc(dir, &isect_precalc);
+                                               ray_triangle_intersect_precalc(dir, &isect_precalc);
                                                num_hits_in_instance = 0;
                                                isect_array->t = isect_t;
 
@@ -432,7 +432,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
                        org4 = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
 #  endif
 
-                       triangle_intersect_precalc(dir, &isect_precalc);
+                       ray_triangle_intersect_precalc(dir, &isect_precalc);
 
                        object = OBJECT_NONE;
                        node_addr = traversal_stack[stack_ptr].addr;
index ca6e54c..12700c7 100644 (file)
@@ -40,64 +40,8 @@ CCL_NAMESPACE_BEGIN
  * http://jcgt.org/published/0002/01/05/paper.pdf
  */
 
-/* Precalculated data for the ray->tri intersection. */
-typedef struct IsectPrecalc {
-       /* Maximal dimension kz, and orthogonal dimensions. */
-       int kx, ky, kz;
-
-       /* Shear constants. */
-       float Sx, Sy, Sz;
-} IsectPrecalc;
-
-#if (defined(__KERNEL_OPENCL_APPLE__)) || \
-    (defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)))
-ccl_device_noinline
-#else
-ccl_device_inline
-#endif
-void triangle_intersect_precalc(float3 dir,
-                                IsectPrecalc *isect_precalc)
-{
-       /* Calculate dimension where the ray direction is maximal. */
-#ifndef __KERNEL_SSE__
-       int kz = util_max_axis(make_float3(fabsf(dir.x),
-                                          fabsf(dir.y),
-                                          fabsf(dir.z)));
-       int kx = kz + 1; if(kx == 3) kx = 0;
-       int ky = kx + 1; if(ky == 3) ky = 0;
-#else
-       int kx, ky, kz;
-       /* Avoiding mispredicted branch on direction. */
-       kz = util_max_axis(fabs(dir));
-       static const char inc_xaxis[] = {1, 2, 0, 55};
-       static const char inc_yaxis[] = {2, 0, 1, 55};
-       kx = inc_xaxis[kz];
-       ky = inc_yaxis[kz];
-#endif
-
-       float dir_kz = IDX(dir, kz);
-
-       /* Swap kx and ky dimensions to preserve winding direction of triangles. */
-       if(dir_kz < 0.0f) {
-               int tmp = kx;
-               kx = ky;
-               ky = tmp;
-       }
-
-       /* Calculate the shear constants. */
-       float inv_dir_z = 1.0f / dir_kz;
-       isect_precalc->Sx = IDX(dir, kx) * inv_dir_z;
-       isect_precalc->Sy = IDX(dir, ky) * inv_dir_z;
-       isect_precalc->Sz = inv_dir_z;
-
-       /* Store the dimensions. */
-       isect_precalc->kx = kx;
-       isect_precalc->ky = ky;
-       isect_precalc->kz = kz;
-}
-
 ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
-                                          const IsectPrecalc *isect_precalc,
+                                          const TriangleIsectPrecalc *isect_precalc,
                                           Intersection *isect,
                                           float3 P,
                                           uint visibility,
@@ -255,7 +199,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
 #ifdef __SUBSURFACE__
 ccl_device_inline void triangle_intersect_subsurface(
         KernelGlobals *kg,
-        const IsectPrecalc *isect_precalc,
+        const TriangleIsectPrecalc *isect_precalc,
         SubsurfaceIntersection *ss_isect,
         float3 P,
         int object,
index 870f33c..7e02c04 100644 (file)
@@ -79,6 +79,82 @@ ccl_device bool ray_aligned_disk_intersect(
        return true;
 }
 
+/* Optimized watertight ray-triangle intersection.
+ *
+ * Sven Woop
+ * Watertight Ray/Triangle Intersection
+ *
+ * http://jcgt.org/published/0002/01/05/paper.pdf
+ */
+
+/* Precalculated data for the ray->tri intersection. */
+typedef struct TriangleIsectPrecalc {
+       /* Maximal dimension kz, and orthogonal dimensions. */
+       int kx, ky, kz;
+
+       /* Shear constants. */
+       float Sx, Sy, Sz;
+} TriangleIsectPrecalc;
+
+/* Workaround stupidness of CUDA/OpenCL which doesn't allow to access indexed
+ * component of float3 value.
+ */
+#ifdef __KERNEL_GPU__
+#  define IDX(vec, idx) \
+    ((idx == 0) ? ((vec).x) : ( (idx == 1) ? ((vec).y) : ((vec).z) ))
+#else
+#  define IDX(vec, idx) ((vec)[idx])
+#endif
+
+#if (defined(__KERNEL_OPENCL_APPLE__)) || \
+    (defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)))
+ccl_device_noinline
+#else
+ccl_device_inline
+#endif
+void ray_triangle_intersect_precalc(float3 dir,
+                                    TriangleIsectPrecalc *isect_precalc)
+{
+       /* Calculate dimension where the ray direction is maximal. */
+#ifndef __KERNEL_SSE__
+       int kz = util_max_axis(make_float3(fabsf(dir.x),
+                                          fabsf(dir.y),
+                                          fabsf(dir.z)));
+       int kx = kz + 1; if(kx == 3) kx = 0;
+       int ky = kx + 1; if(ky == 3) ky = 0;
+#else
+       int kx, ky, kz;
+       /* Avoiding mispredicted branch on direction. */
+       kz = util_max_axis(fabs(dir));
+       static const char inc_xaxis[] = {1, 2, 0, 55};
+       static const char inc_yaxis[] = {2, 0, 1, 55};
+       kx = inc_xaxis[kz];
+       ky = inc_yaxis[kz];
+#endif
+
+       float dir_kz = IDX(dir, kz);
+
+       /* Swap kx and ky dimensions to preserve winding direction of triangles. */
+       if(dir_kz < 0.0f) {
+               int tmp = kx;
+               kx = ky;
+               ky = tmp;
+       }
+
+       /* Calculate the shear constants. */
+       float inv_dir_z = 1.0f / dir_kz;
+       isect_precalc->Sx = IDX(dir, kx) * inv_dir_z;
+       isect_precalc->Sy = IDX(dir, ky) * inv_dir_z;
+       isect_precalc->Sz = inv_dir_z;
+
+       /* Store the dimensions. */
+       isect_precalc->kx = kx;
+       isect_precalc->ky = ky;
+       isect_precalc->kz = kz;
+}
+
+#undef IDX
+
 ccl_device_inline bool ray_triangle_intersect_uv(
         float3 ray_P, float3 ray_D, float ray_t,
         float3 v0, float3 v1, float3 v2,