Cycles: Correct isfinite check used in integrator

Use fast-math friendly version of this function.

We should probably avoid unsafe fast math, but this is to be done with
real care with all the benchmarks properly done.

For now comitting much safer fix.
This commit is contained in:
Sergey Sharybin 2017-03-24 15:22:27 +01:00
parent 6aa972ebd4
commit 5b45715f8a
2 changed files with 16 additions and 15 deletions

View File

@ -399,7 +399,7 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi
float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
/* Reject invalid value */
if(!isfinite(sum)) {
if(!isfinite_safe(sum)) {
kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
L_sum = make_float3(0.0f, 0.0f, 0.0f);
@ -468,7 +468,7 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadi
/* Reject invalid value */
float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
if(!isfinite(sum)) {
if(!isfinite_safe(sum)) {
kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
L_sum = make_float3(0.0f, 0.0f, 0.0f);
}

View File

@ -1241,19 +1241,6 @@ ccl_device_inline float __uint_as_float(uint i)
return u.f;
}
/* Versions of functions which are safe for fast math. */
ccl_device_inline bool isnan_safe(float f)
{
unsigned int x = __float_as_uint(f);
return (x << 1) > 0xff000000u;
}
ccl_device_inline bool isfinite_safe(float f)
{
/* By IEEE 754 rule, 2*Inf equals Inf */
unsigned int x = __float_as_uint(f);
return (f == f) && (x == 0 || (f != 2.0f*f));
}
/* Interpolation */
@ -1271,6 +1258,20 @@ ccl_device_inline float triangle_area(const float3& v1, const float3& v2, const
#endif
/* Versions of functions which are safe for fast math. */
ccl_device_inline bool isnan_safe(float f)
{
unsigned int x = __float_as_uint(f);
return (x << 1) > 0xff000000u;
}
ccl_device_inline bool isfinite_safe(float f)
{
/* By IEEE 754 rule, 2*Inf equals Inf */
unsigned int x = __float_as_uint(f);
return (f == f) && (x == 0 || (f != 2.0f*f)) && !((x << 1) > 0xff000000u);
}
/* Orthonormal vectors */
ccl_device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)