From 72ea0f5b131e2845ceb24c95438fcb005a2c4c09 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 26 Sep 2014 16:13:10 +0200 Subject: [PATCH] (Resamplers) Pass SIMD mask to resampler implementations --- audio/resamplers/cc_resampler.c | 10 +++++++++- audio/resamplers/nearest.c | 6 +++++- audio/resamplers/resampler.c | 33 +++++++++++++++++++++++---------- audio/resamplers/resampler.h | 33 +++++++++++++++++++++++++++++---- audio/resamplers/sinc.c | 16 +++++++++------- 5 files changed, 75 insertions(+), 23 deletions(-) diff --git a/audio/resamplers/cc_resampler.c b/audio/resamplers/cc_resampler.c index bc26f62444..031414fee8 100644 --- a/audio/resamplers/cc_resampler.c +++ b/audio/resamplers/cc_resampler.c @@ -545,11 +545,19 @@ static void resampler_CC_free(void *re_) memalign_free__(re); } -static void *resampler_CC_init(double bandwidth_mod) +static void *resampler_CC_init(double bandwidth_mod, + resampler_simd_mask_t mask) { int i; rarch_CC_resampler_t *re = (rarch_CC_resampler_t*) memalign_alloc__(32, sizeof(rarch_CC_resampler_t)); + + /* TODO: lookup if NEON support can be detected at + * runtime and a funcptr set at runtime for either + * C codepath or NEON codepath. This will help out + * Android. */ + (void)mask; + if (!re) return NULL; diff --git a/audio/resamplers/nearest.c b/audio/resamplers/nearest.c index 525c1c9b01..b86b8b7bbd 100644 --- a/audio/resamplers/nearest.c +++ b/audio/resamplers/nearest.c @@ -52,10 +52,14 @@ static void resampler_nearest_free(void *re_) free(re); } -static void *resampler_nearest_init(double bandwidth_mod) +static void *resampler_nearest_init(double bandwidth_mod, + resampler_simd_mask_t mask) { rarch_nearest_resampler_t *re = (rarch_nearest_resampler_t*) calloc(1, sizeof(rarch_nearest_resampler_t)); + + (void)mask; + if (!re) return NULL; diff --git a/audio/resamplers/resampler.c b/audio/resamplers/resampler.c index c89096c0cb..bff5fbb2d2 100644 --- a/audio/resamplers/resampler.c +++ b/audio/resamplers/resampler.c @@ -14,6 +14,9 @@ */ #include "resampler.h" +#ifdef RARCH_INTERNAL +#include "../../performance.h" +#endif #include #ifdef HAVE_CONFIG_H @@ -86,6 +89,19 @@ static const rarch_resampler_t *find_resampler_driver(const char *ident) } } +static bool resampler_append_plugs(void **re, + const rarch_resampler_t **backend, + double bw_ratio) +{ + resampler_simd_mask_t mask = rarch_get_cpu_features(); + + *re = (*backend)->init(bw_ratio, mask); + + if (!*re) + return false; + return true; +} + bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio) { @@ -95,16 +111,13 @@ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, *re = NULL; *backend = find_resampler_driver(ident); - if (!*backend) - return false; - - *re = (*backend)->init(bw_ratio); - - if (!*re) - { - *backend = NULL; - return false; - } + if (!resampler_append_plugs(re, backend, bw_ratio)) + goto error; return true; + +error: + if (!*re) + *backend = NULL; + return false; } diff --git a/audio/resamplers/resampler.h b/audio/resamplers/resampler.h index e0f1db35c5..8ebdbc937d 100644 --- a/audio/resamplers/resampler.h +++ b/audio/resamplers/resampler.h @@ -18,8 +18,8 @@ #ifndef __RARCH_RESAMPLER_H #define __RARCH_RESAMPLER_H -#ifdef HAVE_CONFIG_H -#include "../../config.h" +#ifdef __cplusplus +extern "C" { #endif #include @@ -28,10 +28,31 @@ #include "../../boolean.h" #ifndef M_PI -/* M_PI is left out of ISO C99 */ #define M_PI 3.14159265358979323846264338327 #endif +#define RESAMPLER_SIMD_SSE (1 << 0) +#define RESAMPLER_SIMD_SSE2 (1 << 1) +#define RESAMPLER_SIMD_VMX (1 << 2) +#define RESAMPLER_SIMD_VMX128 (1 << 3) +#define RESAMPLER_SIMD_AVX (1 << 4) +#define RESAMPLER_SIMD_NEON (1 << 5) +#define RESAMPLER_SIMD_SSE3 (1 << 6) +#define RESAMPLER_SIMD_SSSE3 (1 << 7) +#define RESAMPLER_SIMD_MMX (1 << 8) +#define RESAMPLER_SIMD_MMXEXT (1 << 9) +#define RESAMPLER_SIMD_SSE4 (1 << 10) +#define RESAMPLER_SIMD_SSE42 (1 << 11) +#define RESAMPLER_SIMD_AVX2 (1 << 12) +#define RESAMPLER_SIMD_VFPU (1 << 13) +#define RESAMPLER_SIMD_PS (1 << 14) + +/* A bit-mask of all supported SIMD instruction sets. + * Allows an implementation to pick different + * dspfilter_implementation structs. + */ +typedef unsigned resampler_simd_mask_t; + struct resampler_data { const float *data_in; @@ -47,7 +68,7 @@ typedef struct rarch_resampler { /* Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsampling. * Corresponds to expected resampling ratio. */ - void *(*init)(double bandwidth_mod); + void *(*init)(double bandwidth_mod, resampler_simd_mask_t mask); void (*process)(void *re, struct resampler_data *data); void (*free)(void *re); const char *ident; @@ -82,5 +103,9 @@ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, (backend)->process(handle, data); \ } while(0) +#ifdef __cplusplus +} +#endif + #endif diff --git a/audio/resamplers/sinc.c b/audio/resamplers/sinc.c index 36e64cd4e9..ff73360ba9 100644 --- a/audio/resamplers/sinc.c +++ b/audio/resamplers/sinc.c @@ -484,8 +484,11 @@ static void resampler_sinc_free(void *re) free(resampler); } -static void *resampler_sinc_new(double bandwidth_mod) +static void *resampler_sinc_new(double bandwidth_mod, + resampler_simd_mask_t mask) { + size_t phase_elems, elems; + double cutoff; rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*) calloc(1, sizeof(*re)); if (!re) @@ -494,7 +497,7 @@ static void *resampler_sinc_new(double bandwidth_mod) memset(re, 0, sizeof(*re)); re->taps = TAPS; - double cutoff = CUTOFF; + cutoff = CUTOFF; /* Downsampling, must lower cutoff, and extend number of * taps accordingly to keep same stopband attenuation. */ @@ -511,11 +514,11 @@ static void *resampler_sinc_new(double bandwidth_mod) re->taps = (re->taps + 3) & ~3; #endif - size_t phase_elems = (1 << PHASE_BITS) * re->taps; + phase_elems = (1 << PHASE_BITS) * re->taps; #if SINC_COEFF_LERP phase_elems *= 2; #endif - size_t elems = phase_elems + 4 * re->taps; + elems = phase_elems + 4 * re->taps; re->main_buffer = (float*) aligned_alloc__(128, sizeof(float) * elems); @@ -534,11 +537,10 @@ static void *resampler_sinc_new(double bandwidth_mod) #elif defined(__SSE__) RARCH_LOG("Sinc resampler [SSE]\n"); #elif defined(__ARM_NEON__) - unsigned cpu = rarch_get_cpu_features(); - process_sinc_func = cpu & RETRO_SIMD_NEON + process_sinc_func = mask & RESAMPLER_SIMD_NEON ? process_sinc_neon : process_sinc_C; RARCH_LOG("Sinc resampler [%s]\n", - cpu & RETRO_SIMD_NEON ? "NEON" : "C"); + mask & RESAMPLER_SIMD_NEON ? "NEON" : "C"); #else RARCH_LOG("Sinc resampler [C]\n"); #endif