(DSP Filters) Add SIMD detection to DSP Filter API

This commit is contained in:
twinaphex 2014-04-29 18:38:23 +02:00
parent 669ebbabf6
commit 1bf9a43db6
9 changed files with 70 additions and 22 deletions

View File

@ -180,8 +180,9 @@ static const struct dspfilter_implementation generic_echo_dsp = {
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
(void)simd;
return &generic_echo_dsp;
}

View File

@ -412,8 +412,9 @@ const struct dspfilter_implementation generic_eq_dsp = {
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
(void)simd;
return &generic_eq_dsp;
}

View File

@ -293,7 +293,8 @@ static void iir_process_batch(void *data, float *out, const float *in, unsigned
iir->fir_buf[1] = fir_buf[1];
iir->iir_buf = iir_buf;
}
#else
#endif
static float iir_process(void *data, float samp)
{
struct iir_filter *iir = (struct iir_filter*)data;
@ -307,7 +308,6 @@ static float iir_process(void *data, float samp)
iir->yn1 = out;
return out;
}
#endif
static void * iir_dsp_init(const rarch_dsp_info_t *info)
{
@ -337,9 +337,6 @@ static void iir_dsp_process(void *data, rarch_dsp_output_t *output,
output->samples = iir->buf;
#ifdef __SSE2__
iir_process_batch(&iir->iir_l, iir->buf, input->samples, input->frames);
#else
int num_samples = input->frames * 2;
for (int i = 0; i<num_samples;)
{
@ -348,11 +345,22 @@ static void iir_dsp_process(void *data, rarch_dsp_output_t *output,
iir->buf[i] = iir_process(&iir->iir_r, input->samples[i]);
i++;
}
#endif
output->frames = input->frames;
}
#ifdef __SSE2__
static void iir_dsp_process_sse2(void *data, rarch_dsp_output_t *output,
const rarch_dsp_input_t *input)
{
struct iir_filter_data *iir = (struct iir_filter_data*)data;
output->samples = iir->buf;
iir_process_batch(&iir->iir_l, iir->buf, input->samples, input->frames);
output->frames = input->frames;
}
#endif
static void iir_dsp_free(void *data)
{
struct iir_filter_data *iir = (struct iir_filter_data*)data;
@ -371,16 +379,28 @@ const struct dspfilter_implementation generic_iir_dsp = {
iir_dsp_free,
RARCH_DSP_API_VERSION,
iir_dsp_config,
#ifdef __SSE2__
"IIR (SSE2)",
#else
"IIR",
#endif
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
#ifdef __SSE2__
const struct dspfilter_implementation sse2_iir_dsp = {
iir_dsp_init,
iir_dsp_process_sse2,
iir_dsp_free,
RARCH_DSP_API_VERSION,
iir_dsp_config,
"IIR (SSE2)",
NULL
};
#endif
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
#ifdef __SSE2__
if (simd & DSPFILTER_SIMD_SSE2)
return &sse2_iir_dsp;
#endif
return &generic_iir_dsp;
}

View File

@ -182,8 +182,9 @@ const struct dspfilter_implementation generic_phaser_dsp = {
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
(void)simd;
return &generic_phaser_dsp;
}

View File

@ -22,11 +22,30 @@
extern "C" {
#endif
#define DSPFILTER_SIMD_SSE (1 << 0)
#define DSPFILTER_SIMD_SSE2 (1 << 1)
#define DSPFILTER_SIMD_VMX (1 << 2)
#define DSPFILTER_SIMD_VMX128 (1 << 3)
#define DSPFILTER_SIMD_AVX (1 << 4)
#define DSPFILTER_SIMD_NEON (1 << 5)
#define DSPFILTER_SIMD_SSE3 (1 << 6)
#define DSPFILTER_SIMD_SSSE3 (1 << 7)
#define DSPFILTER_SIMD_MMX (1 << 8)
#define DSPFILTER_SIMD_MMXEXT (1 << 9)
#define DSPFILTER_SIMD_SSE4 (1 << 10)
#define DSPFILTER_SIMD_SSE42 (1 << 11)
#define DSPFILTER_SIMD_AVX2 (1 << 12)
#define DSPFILTER_SIMD_VFPU (1 << 13)
#define DSPFILTER_SIMD_PS (1 << 14)
// A bit-mask of all supported SIMD instruction sets.
// Allows an implementation to pick different dspfilter_implementation structs.
typedef unsigned dspfilter_simd_mask_t;
// Dynamic library endpoint.
typedef const struct dspfilter_implementation *(*dspfilter_get_implementation_t)(void);
// Called at startup to get the callback struct.
// This is NOT dynamically allocated!
const struct dspfilter_implementation *rarch_dsp_plugin_init(void);
typedef const struct dspfilter_implementation *(*dspfilter_get_implementation_t)(dspfilter_simd_mask_t);
// The same SIMD mask argument is forwarded to create() callback as well to avoid having to keep lots of state around.
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t);
#define RARCH_DSP_API_VERSION 6

View File

@ -386,8 +386,9 @@ const struct dspfilter_implementation generic_reverb_dsp = {
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
(void)simd;
return &generic_reverb_dsp;
}

View File

@ -120,8 +120,9 @@ const struct dspfilter_implementation generic_volume_dsp = {
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
(void)simd;
return &generic_volume_dsp;
}

View File

@ -175,8 +175,9 @@ const struct dspfilter_implementation generic_wah_dsp = {
NULL
};
const struct dspfilter_implementation *rarch_dsp_plugin_init(void)
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
{
(void)simd;
return &generic_wah_dsp;
}

View File

@ -969,6 +969,7 @@ void uninit_drivers(void)
void rarch_init_dsp_filter(void)
{
unsigned cpu_features;
dspfilter_get_implementation_t cb;
rarch_dsp_info_t info = {0};
@ -994,7 +995,9 @@ void rarch_init_dsp_filter(void)
goto error;
}
g_extern.audio_data.dsp_plugin = cb();
cpu_features = rarch_get_cpu_features();
g_extern.audio_data.dsp_plugin = cb(cpu_features);
if (!g_extern.audio_data.dsp_plugin)
{
RARCH_ERR("Failed to get a valid DSP plugin.\n");