aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/helpers.c10
-rw-r--r--OpenAL32/Include/alMain.h3
2 files changed, 13 insertions, 0 deletions
diff --git a/Alc/helpers.c b/Alc/helpers.c
index 8e6306ae..e9eb5faf 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -295,6 +295,13 @@ void SetMixerFPUMode(FPUCtl *ctl)
{
#ifdef HAVE_FENV_H
fegetenv(STATIC_CAST(fenv_t, ctl));
+#ifdef _WIN32
+ /* HACK: A nasty bug in MinGW-W64 causes fegetenv and fesetenv to not save
+ * and restore the FPU rounding mode, so we have to do it manually. Don't
+ * know if this also applies to MSVC.
+ */
+ ctl->round_mode = fegetround();
+#endif
#if defined(__GNUC__) && defined(HAVE_SSE)
/* FIXME: Some fegetenv implementations can get the SSE environment too?
* How to tell when it does? */
@@ -341,6 +348,9 @@ void RestoreFPUMode(const FPUCtl *ctl)
{
#ifdef HAVE_FENV_H
fesetenv(STATIC_CAST(fenv_t, ctl));
+#ifdef _WIN32
+ fesetround(ctl->round_mode);
+#endif
#if defined(__GNUC__) && defined(HAVE_SSE)
if((CPUCapFlags&CPU_CAP_SSE))
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&ctl->sse_state));
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index f24eb000..614c3b43 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -901,6 +901,9 @@ void ALCcontext_ProcessUpdates(ALCcontext *context);
typedef struct {
#ifdef HAVE_FENV_H
DERIVE_FROM_TYPE(fenv_t);
+#ifdef _WIN32
+ int round_mode;
+#endif
#else
int state;
#endif