aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-05-04 02:05:26 -0700
committerChris Robinson <[email protected]>2018-05-04 02:09:32 -0700
commit75e2cb97f74aeed2e50e4355607f041414a43976 (patch)
tree70d5957e9616fccc65b81a1dc4ff62babf1b6b36 /Alc
parentac8dbd7a56e4ca0ccfbef61b89bdb55775abea6a (diff)
Don't assume round-to-zero for fastf2i
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALu.c6
-rw-r--r--Alc/fpu_modes.h17
-rw-r--r--Alc/helpers.c53
3 files changed, 18 insertions, 58 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 0c930a29..81914850 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1092,7 +1092,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *p
if(Pitch > (ALfloat)MAX_PITCH)
voice->Step = MAX_PITCH<<FRACTIONBITS;
else
- voice->Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1);
+ voice->Step = maxi(fastf2i(Pitch * FRACTIONONE), 1);
if(props->Resampler == BSinc24Resampler)
BsincPrepare(voice->Step, &voice->ResampleState.bsinc, &bsinc24);
else if(props->Resampler == BSinc12Resampler)
@@ -1453,7 +1453,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop
if(Pitch > (ALfloat)MAX_PITCH)
voice->Step = MAX_PITCH<<FRACTIONBITS;
else
- voice->Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1);
+ voice->Step = maxi(fastf2i(Pitch * FRACTIONONE), 1);
if(props->Resampler == BSinc24Resampler)
BsincPrepare(voice->Step, &voice->ResampleState.bsinc, &bsinc24);
else if(props->Resampler == BSinc12Resampler)
@@ -1663,7 +1663,7 @@ static void ApplyDither(ALfloat (*restrict Samples)[BUFFERSIZE], ALuint *dither_
ALuint rng0 = dither_rng(&seed);
ALuint rng1 = dither_rng(&seed);
val += (ALfloat)(rng0*(1.0/UINT_MAX) - rng1*(1.0/UINT_MAX));
- samples[i] = roundf(val) * invscale;
+ samples[i] = fastf2i(val) * invscale;
}
}
*dither_seed = seed;
diff --git a/Alc/fpu_modes.h b/Alc/fpu_modes.h
index 750252fc..eb305967 100644
--- a/Alc/fpu_modes.h
+++ b/Alc/fpu_modes.h
@@ -7,16 +7,13 @@
typedef struct FPUCtl {
-#ifdef HAVE_FENV_H
- fenv_t flt_env;
-#ifdef _WIN32
- int round_mode;
-#endif
-#else
- int state;
-#endif
-#ifdef HAVE_SSE
- int sse_state;
+#if defined(__GNUC__) && defined(HAVE_SSE)
+ unsigned int sse_state;
+#elif defined(HAVE___CONTROL87_2)
+ unsigned int state;
+ unsigned int sse_state;
+#elif defined(HAVE__CONTROLFP)
+ unsigned int state;
#endif
} FPUCtl;
void SetMixerFPUMode(FPUCtl *ctl);
diff --git a/Alc/helpers.c b/Alc/helpers.c
index c311ea2e..7bcb3f4a 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -269,81 +269,44 @@ void FillCPUCaps(int capfilter)
void SetMixerFPUMode(FPUCtl *ctl)
{
-#ifdef HAVE_FENV_H
- fegetenv(&ctl->flt_env);
-#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? */
- if((CPUCapFlags&CPU_CAP_SSE))
- __asm__ __volatile__("stmxcsr %0" : "=m" (*&ctl->sse_state));
-#endif
-
-#ifdef FE_TOWARDZERO
- fesetround(FE_TOWARDZERO);
-#endif
#if defined(__GNUC__) && defined(HAVE_SSE)
if((CPUCapFlags&CPU_CAP_SSE))
{
- int sseState = ctl->sse_state;
- sseState |= 0x6000; /* set round-to-zero */
+ __asm__ __volatile__("stmxcsr %0" : "=m" (*&ctl->sse_state));
+ unsigned int sseState = ctl->sse_state;
sseState |= 0x8000; /* set flush-to-zero */
if((CPUCapFlags&CPU_CAP_SSE2))
sseState |= 0x0040; /* set denormals-are-zero */
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&sseState));
}
-#endif
#elif defined(HAVE___CONTROL87_2)
- int mode;
- __control87_2(0, 0, &ctl->state, NULL);
- __control87_2(_RC_CHOP, _MCW_RC, &mode, NULL);
-#ifdef HAVE_SSE
- if((CPUCapFlags&CPU_CAP_SSE))
- {
- __control87_2(0, 0, NULL, &ctl->sse_state);
- __control87_2(_RC_CHOP|_DN_FLUSH, _MCW_RC|_MCW_DN, NULL, &mode);
- }
-#endif
+ __control87_2(0, 0, &ctl->state, &ctl->sse_state);
+ _control87(_DN_FLUSH, _MCW_DN);
#elif defined(HAVE__CONTROLFP)
ctl->state = _controlfp(0, 0);
- (void)_controlfp(_RC_CHOP, _MCW_RC);
+ _controlfp(_DN_FLUSH, _MCW_DN);
#endif
}
void RestoreFPUMode(const FPUCtl *ctl)
{
-#ifdef HAVE_FENV_H
- fesetenv(&ctl->flt_env);
-#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));
-#endif
#elif defined(HAVE___CONTROL87_2)
int mode;
- __control87_2(ctl->state, _MCW_RC, &mode, NULL);
-#ifdef HAVE_SSE
- if((CPUCapFlags&CPU_CAP_SSE))
- __control87_2(ctl->sse_state, _MCW_RC|_MCW_DN, NULL, &mode);
-#endif
+ __control87_2(ctl->state, _MCW_DN, &mode, NULL);
+ __control87_2(ctl->sse_state, _MCW_DN, NULL, &mode);
#elif defined(HAVE__CONTROLFP)
- _controlfp(ctl->state, _MCW_RC);
+ _controlfp(ctl->state, _MCW_DN);
#endif
}