diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-09-09 11:25:56 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-09-09 11:39:36 +0300 |
commit | d13a0e8f4ac0352de25e76756509e613a9cc6514 (patch) | |
tree | 83af860a5d07bac37dfa125af945e948f0a0cc56 /intern/cycles/kernel/geom/geom_triangle_intersect.h | |
parent | 46d2abf78fe5422289e4e7304428bb468df4c61f (diff) |
Cycles: Limit triangle magnitude check for only GPU
Found a way to make AVX2 CPUs happy by reshuffling instructions a bit,
so now there's no weird precision errors happening in there.
This solves some render speed regressions on CPU, but unfortunately
this doesn't help for GPU rendering.
Diffstat (limited to 'intern/cycles/kernel/geom/geom_triangle_intersect.h')
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle_intersect.h | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index 5f88ef09256..fd521c18cc7 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -140,13 +140,15 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, /* Calculate scaled barycentric coordinates. */ float U = Cx * By - Cy * Bx; - int sign_mask = (__float_as_int(U) & 0x80000000); float V = Ax * Cy - Ay * Cx; - if(sign_mask != (__float_as_int(V) & 0x80000000)) { - return false; - } float W = Bx * Ay - By * Ax; - if(sign_mask != (__float_as_int(W) & 0x80000000)) { + const int sign_mask = (__float_as_int(U) & 0x80000000); + /* TODO(sergey): Check if multiplication plus sign check is faster + * or at least same speed (but robust for endian types). + */ + if(sign_mask != (__float_as_int(V) & 0x80000000) || + sign_mask != (__float_as_int(W) & 0x80000000)) + { return false; } @@ -173,6 +175,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility) #endif { +#ifdef __KERNEL_GPU__ float4 a = tri_b - tri_a, b = tri_c - tri_a; if(len_squared(make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, @@ -180,6 +183,8 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, { return false; } +#endif + /* Normalize U, V, W, and T. */ const float inv_det = 1.0f / det; isect->prim = triAddr; |