(Resamplers) Pass SIMD mask to resampler implementations

This commit is contained in:
twinaphex 2014-09-26 16:13:10 +02:00
parent 9abaa15873
commit 72ea0f5b13
5 changed files with 75 additions and 23 deletions

View File

@ -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;

View File

@ -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;

View File

@ -14,6 +14,9 @@
*/
#include "resampler.h"
#ifdef RARCH_INTERNAL
#include "../../performance.h"
#endif
#include <string.h>
#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;
}

View File

@ -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 <stddef.h>
@ -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

View File

@ -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