diff --git a/include/mitsuba/core/sse.h b/include/mitsuba/core/sse.h index 9735c326..2baf9a80 100644 --- a/include/mitsuba/core/sse.h +++ b/include/mitsuba/core/sse.h @@ -51,6 +51,7 @@ #ifndef MTS_SSE #define SSE_STR "SSE2 disabled" #define enable_fpexcept_sse() +#define query_fpexcept_sse() 0 #define disable_fpexcept_sse() #else /* Include SSE intrinsics header file */ @@ -61,8 +62,9 @@ #define splat_epi32(ps, i) _mm_shuffle_epi32((ps), (i<<6) | (i<<4) | (i<<2) | i) #define mux_ps(sel, op1, op2) _mm_or_ps (_mm_and_ps ((sel), (op1)), _mm_andnot_ps ((sel), (op2))) #define mux_epi32(sel, op1, op2) _mm_or_si128(_mm_and_si128((sel), (op1)), _mm_andnot_si128((sel), (op2))) -#define enable_fpexcept_sse() _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~(_MM_MASK_INVALID| _MM_MASK_DIV_ZERO)) -#define disable_fpexcept_sse() _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() | (_MM_MASK_INVALID| _MM_MASK_DIV_ZERO)) +#define enable_fpexcept_sse() _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~(_MM_MASK_INVALID | _MM_MASK_DIV_ZERO)) +#define query_fpexcept_sse() (~_MM_GET_EXCEPTION_MASK() & (_MM_MASK_INVALID | _MM_MASK_DIV_ZERO)) +#define disable_fpexcept_sse() _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() | (_MM_MASK_INVALID | _MM_MASK_DIV_ZERO)) #define load1_epi32(i) _mm_shuffle_epi32(_mm_cvtsi32_si128(i), 0) #ifdef __MSVC__ diff --git a/src/libcore/util.cpp b/src/libcore/util.cpp index 3f4a17f7..fddeed0c 100644 --- a/src/libcore/util.cpp +++ b/src/libcore/util.cpp @@ -248,6 +248,11 @@ bool enableFPExceptions() { exceptionsWereEnabled = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); cw &= ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); _controlfp(cw, _MCW_EM); +#elif defined(__OSX__) +#if !defined(MTS_SSE) +#error SSE must be enabled to handle FP exceptions on OSX +#endif + exceptionsWereEnabled = query_fpexcept_sse() != 0; #else exceptionsWereEnabled = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); @@ -267,6 +272,8 @@ bool disableFPExceptions() { exceptionsWereEnabled = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); cw |= _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; _controlfp(cw, _MCW_EM); +#elif defined(__OSX__) + exceptionsWereEnabled = query_fpexcept_sse() != 0; #else exceptionsWereEnabled = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); @@ -283,6 +290,8 @@ void restoreFPExceptions(bool oldState) { #if defined(WIN32) unsigned int cw = _controlfp(0, 0); currentState = ~cw & (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW); +#elif defined(__OSX__) + currentState = query_fpexcept_sse() != 0; #else currentState = fegetexcept() & (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); #endif diff --git a/src/medium/heterogeneous-stencil.cpp b/src/medium/heterogeneous-stencil.cpp index 8fc7b9e7..54fa6e6b 100644 --- a/src/medium/heterogeneous-stencil.cpp +++ b/src/medium/heterogeneous-stencil.cpp @@ -76,7 +76,7 @@ public: if (m_albedo.get() == NULL) Log(EError, "No albedo specified!"); if (m_orientations.get() == NULL) - Log(EError, "No orientations specified!"); + Log(EWarn, "No orientations specified!"); if (m_shapes.size() != 0) { m_kdTree->build(); @@ -86,10 +86,12 @@ public: } if (m_stepSize == 0) { - m_stepSize = std::min(std::min( + m_stepSize = std::min( m_densities->getStepSize(), - m_albedo->getStepSize()), - m_orientations->getStepSize()); + m_albedo->getStepSize()); + if (m_orientations) + m_stepSize = std::min(m_stepSize, + m_orientations->getStepSize()); if (m_stepSize == std::numeric_limits::infinity()) Log(EError, "Unable to infer step size, please specify!"); @@ -329,7 +331,8 @@ public: mRec.sigmaS = currentAlbedo * currentSigmaT; mRec.sigmaA = Spectrum(currentSigmaT) - mRec.sigmaS; mRec.albedo = currentAlbedo.max(); - mRec.orientation = m_orientations->lookupVector(mRec.p); + mRec.orientation = m_orientations.get() + ? m_orientations->lookupVector(mRec.p) : Vector(0.0f); mRec.medium = this; return true; }