mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
Merge branch 'master' into 'master'
core: Add RISC-V V optimized sconv pa_sconv_s16le_from_float32ne See merge request pulseaudio/pulseaudio!833
This commit is contained in:
commit
d64cfc70fd
8 changed files with 210 additions and 0 deletions
13
meson.build
13
meson.build
|
|
@ -293,6 +293,7 @@ endif
|
|||
|
||||
check_usable_headers = [
|
||||
'cpuid.h',
|
||||
'sys/auxv.h',
|
||||
]
|
||||
|
||||
foreach h : check_usable_headers
|
||||
|
|
@ -594,6 +595,18 @@ if host_machine.cpu_family() == 'arm'
|
|||
endif
|
||||
# NEON checks are automatically done by the unstable-simd module
|
||||
|
||||
if host_machine.cpu_family() == 'riscv64'
|
||||
if cc.compiles('''
|
||||
int main() {
|
||||
__asm__ __volatile__ (
|
||||
".option arch, +v\nvsetivli zero, 0, e8, m1, ta, ma"
|
||||
);
|
||||
}
|
||||
''', name : 'rvv code')
|
||||
cdata.set('HAVE_RVV', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Dependencies common to client, daemon and modules
|
||||
|
||||
if get_option('ipv6')
|
||||
|
|
|
|||
57
src/pulsecore/cpu-riscv.c
Normal file
57
src/pulsecore/cpu-riscv.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright (c) 2024 Institue of Software Chinese Academy of Sciences (ISCAS).
|
||||
|
||||
PulseAudio is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
PulseAudio is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if HAVE_SYS_AUXV_H
|
||||
#include <sys/auxv.h>
|
||||
#define HWCAP_RV(letter) (1ul << ((letter) - 'A'))
|
||||
#endif
|
||||
|
||||
#include <pulsecore/log.h>
|
||||
|
||||
#include "cpu-riscv.h"
|
||||
|
||||
void pa_cpu_get_riscv_flags(pa_cpu_riscv_flag_t *flags) {
|
||||
#if HAVE_SYS_AUXV_H
|
||||
const unsigned long hwcap = getauxval(AT_HWCAP);
|
||||
|
||||
if (hwcap & HWCAP_RV('V'))
|
||||
*flags |= PA_CPU_RISCV_V;
|
||||
|
||||
pa_log_info("CPU flags: %s", (*flags & PA_CPU_RISCV_V) ? "V" : "");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool pa_cpu_init_riscv(pa_cpu_riscv_flag_t *flags) {
|
||||
pa_cpu_get_riscv_flags(flags);
|
||||
|
||||
#if HAVE_RVV
|
||||
if (*flags & PA_CPU_RISCV_V) {
|
||||
pa_convert_func_init_rvv(*flags);
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
41
src/pulsecore/cpu-riscv.h
Normal file
41
src/pulsecore/cpu-riscv.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef foocpuriscvhfoo
|
||||
#define foocpuriscvhfoo
|
||||
|
||||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright (c) 2024 Institue of Software Chinese Academy of Sciences (ISCAS).
|
||||
|
||||
PulseAudio is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
PulseAudio is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pulsecore/macro.h>
|
||||
|
||||
#ifndef PACKAGE
|
||||
#error "Please include config.h before including this file!"
|
||||
#endif
|
||||
|
||||
typedef enum pa_cpu_riscv_flag {
|
||||
PA_CPU_RISCV_V = (1 << 0),
|
||||
} pa_cpu_riscv_flag_t;
|
||||
|
||||
void pa_cpu_get_riscv_flags(pa_cpu_riscv_flag_t *flags);
|
||||
bool pa_cpu_init_riscv (pa_cpu_riscv_flag_t *flags);
|
||||
|
||||
#ifdef HAVE_RVV
|
||||
void pa_convert_func_init_rvv(pa_cpu_riscv_flag_t flags);
|
||||
#endif
|
||||
|
||||
#endif /* foocpuxriscvhfoo */
|
||||
|
|
@ -30,6 +30,8 @@ void pa_cpu_init(pa_cpu_info *cpu_info) {
|
|||
cpu_info->cpu_type = PA_CPU_X86;
|
||||
else if (pa_cpu_init_arm(&cpu_info->flags.arm))
|
||||
cpu_info->cpu_type = PA_CPU_ARM;
|
||||
else if (pa_cpu_init_riscv(&cpu_info->flags.riscv))
|
||||
cpu_info->cpu_type = PA_CPU_RISCV;
|
||||
pa_cpu_init_orc(*cpu_info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,13 @@
|
|||
|
||||
#include <pulsecore/cpu-x86.h>
|
||||
#include <pulsecore/cpu-arm.h>
|
||||
#include <pulsecore/cpu-riscv.h>
|
||||
|
||||
typedef enum {
|
||||
PA_CPU_UNDEFINED = 0,
|
||||
PA_CPU_X86,
|
||||
PA_CPU_ARM,
|
||||
PA_CPU_RISCV,
|
||||
} pa_cpu_type_t;
|
||||
|
||||
typedef struct pa_cpu_info pa_cpu_info;
|
||||
|
|
@ -37,6 +39,7 @@ struct pa_cpu_info {
|
|||
union {
|
||||
pa_cpu_x86_flag_t x86;
|
||||
pa_cpu_arm_flag_t arm;
|
||||
pa_cpu_riscv_flag_t riscv;
|
||||
} flags;
|
||||
bool force_generic_code;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ libpulsecore_sources = [
|
|||
'cpu-arm.c',
|
||||
'cpu-orc.c',
|
||||
'cpu-x86.c',
|
||||
'cpu-riscv.c',
|
||||
'device-port.c',
|
||||
'database.c',
|
||||
'ffmpeg/resample2.c',
|
||||
|
|
@ -40,6 +41,7 @@ libpulsecore_sources = [
|
|||
'sconv-s16be.c',
|
||||
'sconv-s16le.c',
|
||||
'sconv.c',
|
||||
'sconv_rvv.c',
|
||||
'shared.c',
|
||||
'sink.c',
|
||||
'sink-input.c',
|
||||
|
|
|
|||
58
src/pulsecore/sconv_rvv.c
Normal file
58
src/pulsecore/sconv_rvv.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
Copyright (c) 2024 Institue of Software Chinese Academy of Sciences (ISCAS).
|
||||
|
||||
PulseAudio is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
PulseAudio is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/endianmacros.h>
|
||||
|
||||
#include "cpu-riscv.h"
|
||||
#include "sconv.h"
|
||||
|
||||
#if HAVE_RVV
|
||||
static void pa_sconv_s16le_from_f32ne_rvv(unsigned n, const float *src, int16_t *dst) {
|
||||
__asm__ __volatile__ (
|
||||
".option arch, +v \n\t"
|
||||
"li t0, 1191182336 \n\t"
|
||||
"fmv.w.x fa5, t0 \n\t"
|
||||
"1: \n\t"
|
||||
"vsetvli t0, a0, e32, m8, ta, ma \n\t"
|
||||
"vle32.v v8, (a1) \n\t"
|
||||
"sub a0, a0, t0 \n\t"
|
||||
"vfmul.vf v8, v8, fa5 \n\t"
|
||||
"vsetvli zero, zero, e16, m4, ta, ma \n\t"
|
||||
"vfncvt.x.f.w v8, v8 \n\t"
|
||||
"slli t0, t0, 1 \n\t"
|
||||
"vse16.v v8, (a2) \n\t"
|
||||
"add a1, a1, t0 \n\t"
|
||||
"add a1, a1, t0 \n\t"
|
||||
"add a2, a2, t0 \n\t"
|
||||
"bnez a0, 1b \n\t"
|
||||
|
||||
:
|
||||
:
|
||||
: "cc", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
void pa_convert_func_init_rvv(pa_cpu_riscv_flag_t flags) {
|
||||
pa_log_info("Initialising RVV optimized conversions.");
|
||||
|
||||
pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_rvv);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <pulsecore/cpu-arm.h>
|
||||
#include <pulsecore/cpu-x86.h>
|
||||
#include <pulsecore/cpu-riscv.h>
|
||||
#include <pulsecore/random.h>
|
||||
#include <pulsecore/macro.h>
|
||||
#include <pulsecore/sconv.h>
|
||||
|
|
@ -190,6 +191,35 @@ START_TEST (sconv_sse_test) {
|
|||
END_TEST
|
||||
#endif /* (defined (__i386__) || defined (__amd64__)) && defined (HAVE_SSE) */
|
||||
|
||||
#if HAVE_RVV
|
||||
START_TEST (sconv_rvv_test) {
|
||||
pa_cpu_riscv_flag_t flags = 0;
|
||||
pa_convert_func_t orig_func, rvv_func;
|
||||
|
||||
pa_cpu_get_riscv_flags(&flags);
|
||||
|
||||
if (!(flags & PA_CPU_RISCV_V)) {
|
||||
pa_log_info("RVV not supported. Skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
|
||||
pa_convert_func_init_rvv(PA_CPU_RISCV_V);
|
||||
rvv_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
|
||||
|
||||
pa_log_debug("Checking RVV sconv (float -> s16)");
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 0, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 1, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 2, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 3, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 4, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 5, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 6, true, false);
|
||||
run_conv_test_float_to_s16(rvv_func, orig_func, 7, true, true);
|
||||
}
|
||||
END_TEST
|
||||
#endif /* (defined () */
|
||||
|
||||
#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
|
||||
START_TEST (sconv_neon_test) {
|
||||
pa_cpu_arm_flag_t flags = 0;
|
||||
|
|
@ -250,6 +280,10 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON)
|
||||
tcase_add_test(tc, sconv_neon_test);
|
||||
#endif
|
||||
#if HAVE_RVV
|
||||
tcase_set_timeout(tc, 0);
|
||||
tcase_add_test(tc, sconv_rvv_test);
|
||||
#endif
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue