[Bf-blender-cvs] [29681f186e1] master: Fix T93283: Cycles render error with CUDA CPU + GPU after recent optimization

Brecht Van Lommel noreply at git.blender.org
Mon Nov 22 21:07:03 CET 2021


Commit: 29681f186e1a6865da0b4936805df5a608b90ee9
Author: Brecht Van Lommel
Date:   Mon Nov 22 20:41:19 2021 +0100
Branches: master
https://developer.blender.org/rB29681f186e1a6865da0b4936805df5a608b90ee9

Fix T93283: Cycles render error with CUDA CPU + GPU after recent optimization

BVH2 triangle intersection was broken on the GPU since packed floats can't
be loaded directly into SSE. The better long term solution for performance
would be to build a BVH2 for GPU and Embree for CPU, similar to what we do
for OptiX.

===================================================================

M	intern/cycles/kernel/geom/motion_triangle_intersect.h
M	intern/cycles/kernel/geom/triangle_intersect.h
M	intern/cycles/kernel/light/light.h
M	intern/cycles/util/math_intersect.h

===================================================================

diff --git a/intern/cycles/kernel/geom/motion_triangle_intersect.h b/intern/cycles/kernel/geom/motion_triangle_intersect.h
index 256e7add21e..72ad237eeeb 100644
--- a/intern/cycles/kernel/geom/motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/motion_triangle_intersect.h
@@ -163,19 +163,7 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
   motion_triangle_vertices(kg, fobject, prim, time, verts);
   /* Ray-triangle intersection, unoptimized. */
   float t, u, v;
-  if (ray_triangle_intersect(P,
-                             dir,
-                             tmax,
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-                             (ssef *)verts,
-#else
-                             verts[0],
-                             verts[1],
-                             verts[2],
-#endif
-                             &u,
-                             &v,
-                             &t)) {
+  if (ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
 #ifdef __VISIBILITY_FLAG__
     /* Visibility flag test. we do it here under the assumption
      * that most triangles are culled by node flags.
@@ -229,19 +217,7 @@ ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
   motion_triangle_vertices(kg, local_object, prim, time, verts);
   /* Ray-triangle intersection, unoptimized. */
   float t, u, v;
-  if (!ray_triangle_intersect(P,
-                              dir,
-                              tmax,
-#  if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-                              (ssef *)verts,
-#  else
-                              verts[0],
-                              verts[1],
-                              verts[2],
-#  endif
-                              &u,
-                              &v,
-                              &t)) {
+  if (!ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
     return false;
   }
 
diff --git a/intern/cycles/kernel/geom/triangle_intersect.h b/intern/cycles/kernel/geom/triangle_intersect.h
index 720eceec4ed..57a6ae7fe72 100644
--- a/intern/cycles/kernel/geom/triangle_intersect.h
+++ b/intern/cycles/kernel/geom/triangle_intersect.h
@@ -37,27 +37,11 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
 {
   const int prim = kernel_tex_fetch(__prim_index, prim_addr);
   const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  const ssef *ssef_verts = (ssef *)&kg->__tri_verts.data[tri_vindex];
-#else
   const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
                tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
                tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
-#endif
   float t, u, v;
-  if (ray_triangle_intersect(P,
-                             dir,
-                             tmax,
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-                             ssef_verts,
-#else
-                             tri_a,
-                             tri_b,
-                             tri_c,
-#endif
-                             &u,
-                             &v,
-                             &t)) {
+  if (ray_triangle_intersect(P, dir, tmax, tri_a, tri_b, tri_c, &u, &v, &t)) {
 #ifdef __VISIBILITY_FLAG__
     /* Visibility flag test. we do it here under the assumption
      * that most triangles are culled by node flags.
@@ -106,27 +90,11 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
 
   const int prim = kernel_tex_fetch(__prim_index, prim_addr);
   const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
-#  if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  const ssef *ssef_verts = (ssef *)&kg->__tri_verts.data[tri_vindex];
-#  else
   const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
                tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
                tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
-#  endif
   float t, u, v;
-  if (!ray_triangle_intersect(P,
-                              dir,
-                              tmax,
-#  if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-                              ssef_verts,
-#  else
-                              tri_a,
-                              tri_b,
-                              tri_c,
-#  endif
-                              &u,
-                              &v,
-                              &t)) {
+  if (!ray_triangle_intersect(P, dir, tmax, tri_a, tri_b, tri_c, &u, &v, &t)) {
     return false;
   }
 
@@ -178,11 +146,6 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
   isect->t = t;
 
   /* Record geometric normal. */
-#  if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
-               tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
-               tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
-#  endif
   local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
 
   return false;
diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index 2e7f862a715..3f7d0e0899e 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -676,19 +676,7 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg,
     ls->D = z * B + safe_sqrtf(1.0f - z * z) * safe_normalize(C_ - dot(C_, B) * B);
 
     /* calculate intersection with the planar triangle */
-    if (!ray_triangle_intersect(P,
-                                ls->D,
-                                FLT_MAX,
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-                                (ssef *)V,
-#else
-                                V[0],
-                                V[1],
-                                V[2],
-#endif
-                                &ls->u,
-                                &ls->v,
-                                &ls->t)) {
+    if (!ray_triangle_intersect(P, ls->D, FLT_MAX, V[0], V[1], V[2], &ls->u, &ls->v, &ls->t)) {
       ls->pdf = 0.0f;
       return;
     }
diff --git a/intern/cycles/util/math_intersect.h b/intern/cycles/util/math_intersect.h
index 0c431a36afb..54ce3ab4b66 100644
--- a/intern/cycles/util/math_intersect.h
+++ b/intern/cycles/util/math_intersect.h
@@ -88,29 +88,16 @@ ccl_device bool ray_aligned_disk_intersect(float3 ray_P,
 ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P,
                                                    float3 ray_dir,
                                                    float ray_t,
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-                                                   const ssef *ssef_verts,
-#else
                                                    const float3 tri_a,
                                                    const float3 tri_b,
                                                    const float3 tri_c,
-#endif
                                                    ccl_private float *isect_u,
                                                    ccl_private float *isect_v,
                                                    ccl_private float *isect_t)
 {
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  typedef ssef float3;
-  const float3 tri_a(ssef_verts[0]);
-  const float3 tri_b(ssef_verts[1]);
-  const float3 tri_c(ssef_verts[2]);
-  const float3 P(ray_P);
-  const float3 dir(ray_dir);
-#else
-#  define dot3(a, b) dot(a, b)
+#define dot3(a, b) dot(a, b)
   const float3 P = ray_P;
   const float3 dir = ray_dir;
-#endif
 
   /* Calculate vertices relative to ray origin. */
   const float3 v0 = tri_c - P;
@@ -123,43 +110,16 @@ ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P,
   const float3 e2 = v1 - v2;
 
   /* Perform edge tests. */
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  const float3 crossU = cross(v2 + v0, e0);
-  const float3 crossV = cross(v0 + v1, e1);
-  const float3 crossW = cross(v1 + v2, e2);
-
-  ssef crossX(crossU);
-  ssef crossY(crossV);
-  ssef crossZ(crossW);
-  ssef zero = _mm_setzero_ps();
-  _MM_TRANSPOSE4_PS(crossX, crossY, crossZ, zero);
-
-  const ssef dirX(ray_dir.x);
-  const ssef dirY(ray_dir.y);
-  const ssef dirZ(ray_dir.z);
-
-  ssef UVWW = madd(crossX, dirX, madd(crossY, dirY, crossZ * dirZ));
-#else  /* __KERNEL_SSE2__ */
   const float U = dot(cross(v2 + v0, e0), ray_dir);
   const float V = dot(cross(v0 + v1, e1), ray_dir);
   const float W = dot(cross(v1 + v2, e2), ray_dir);
-#endif /* __KERNEL_SSE2__ */
 
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  int uvw_sign = movemask(UVWW) & 0x7;
-  if (uvw_sign != 0) {
-    if (uvw_sign != 0x7) {
-      return false;
-    }
-  }
-#else
   const float minUVW = min(U, min(V, W));
   const float maxUVW = max(U, max(V, W));
 
   if (minUVW < 0.0f && maxUVW > 0.0f) {
     return false;
   }
-#endif
 
   /* Calculate geometry normal and denominator. */
   const float3 Ng1 = cross(e1, e0);
@@ -180,14 +140,8 @@ ccl_device_forceinline bool ray_triangle_intersect(float3 ray_P,
   }
 
   const float inv_den = 1.0f / den;
-#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
-  UVWW *= inv_den;
-  _mm_store_ss(isect_u, UVWW);
-  _mm_store_ss(isect_v, shuffle<1, 1, 3, 3>(UVWW));
-#else
   *isect_u = U * inv_den;
   *isect_v = V * inv_den;
-#endif
   *isect_t = T * inv_den;
   return true;



More information about the Bf-blender-cvs mailing list