mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-20 05:36:31 +01:00
2nd stage of denormal handling (from trunk); fix to avoid FLAC support when using a too-new FLAC library
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@1940 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
2291d59bc8
commit
7777d54887
8 changed files with 181 additions and 58 deletions
|
|
@ -36,7 +36,6 @@ opts.AddOptions(
|
|||
BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
|
||||
BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
|
||||
BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
|
||||
BoolOption('USE_XMMINTRIN', 'Use gcc XMM intrinsics where possible', 1),
|
||||
BoolOption('LIBLO', 'Compile with support for liblo library', 1),
|
||||
BoolOption('NLS', 'Set to turn on i18n support', 1),
|
||||
PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
|
||||
|
|
@ -736,8 +735,14 @@ libraries['flac'] = LibraryInfo ()
|
|||
prep_libcheck(env, libraries['flac'])
|
||||
libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
|
||||
|
||||
#
|
||||
# june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
|
||||
# since the version of libsndfile we have internally does not support
|
||||
# the new API that libFLAC has adopted
|
||||
#
|
||||
|
||||
conf = Configure (libraries['flac'])
|
||||
if conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX'):
|
||||
if conf.CheckLib ('FLAC', 'FLAC__seekable_stream_decoder_set_read_callback', language='CXX'):
|
||||
conf.env.Append(CCFLAGS='-DHAVE_FLAC')
|
||||
libraries['flac'] = conf.Finish ()
|
||||
|
||||
|
|
|
|||
|
|
@ -337,6 +337,14 @@
|
|||
<menuitem action='LayerMoveAddHigher'/>
|
||||
<menuitem action='LayerAddHigher'/>
|
||||
</menu>
|
||||
<menu name='Denormals' action='Denormals'>
|
||||
<menuitem action='DenormalProtection'/>
|
||||
<separator/>
|
||||
<menuitem action='DenormalNone'/>
|
||||
<menuitem action='DenormalFTZ'/>
|
||||
<menuitem action='DenormalDAZ'/>
|
||||
<menuitem action='DenormalFTZDAZ'/>
|
||||
</menu>
|
||||
<separator/>
|
||||
<menuitem action='SendMTC'/>
|
||||
<menuitem action='SendMMC'/>
|
||||
|
|
@ -353,13 +361,8 @@
|
|||
<menuitem action='StopRecordingOnXrun'/>
|
||||
<menuitem action='StopTransportAtEndOfSession'/>
|
||||
<menuitem action='GainReduceFastTransport'/>
|
||||
<menu name='Denormals' action='Denormals'>
|
||||
<menuitem action='DenormalProtection'/>
|
||||
<menuitem action='DenormalNone'/>
|
||||
<menuitem action='DenormalFTZ'/>
|
||||
<menuitem action='DenormalDAZ'/>
|
||||
<menuitem action='DenormalFTZDAZ'/>
|
||||
</menu>
|
||||
<menuitem action='PrimaryClockDeltaEditCursor'/>
|
||||
<menuitem action='SecondaryClockDeltaEditCursor'/>
|
||||
</menu>
|
||||
<menu name='Help' action='Help'>
|
||||
<menuitem action='About'/>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#include <pbd/pathscanner.h>
|
||||
#include <pbd/fpu.h>
|
||||
|
||||
#include <glibmm/miscutils.h>
|
||||
|
||||
|
|
@ -414,10 +415,22 @@ ARDOUR_UI::install_actions ()
|
|||
|
||||
ActionManager::register_toggle_action (option_actions, X_("DenormalProtection"), _("Use DC bias"), mem_fun (*this, &ARDOUR_UI::toggle_denormal_protection));
|
||||
|
||||
FPU fpu;
|
||||
|
||||
ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalNone"), _("No processor handling"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalNone));
|
||||
ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZ"), _("Use FlushToZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZ));
|
||||
ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalDAZ"), _("Use DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalDAZ));
|
||||
ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZDAZ"), _("Use FlushToZero & DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZDAZ));
|
||||
|
||||
act = ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZ"), _("Use FlushToZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZ));
|
||||
if (!fpu.has_flush_to_zero()) {
|
||||
act->set_sensitive (false);
|
||||
}
|
||||
act = ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalDAZ"), _("Use DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalDAZ));
|
||||
if (!fpu.has_denormals_are_zero()) {
|
||||
act->set_sensitive (false);
|
||||
}
|
||||
act = ActionManager::register_radio_action (option_actions, denormal_group, X_("DenormalFTZDAZ"), _("Use FlushToZero & DenormalsAreZero"), bind (mem_fun (*this, &ARDOUR_UI::set_denormal_model), DenormalFTZDAZ));
|
||||
if (!fpu.has_flush_to_zero() || !fpu.has_denormals_are_zero()) {
|
||||
act->set_sensitive (false);
|
||||
}
|
||||
|
||||
act = ActionManager::register_toggle_action (option_actions, X_("DoNotRunPluginsWhileRecording"), _("Do not run plugins while recording"), mem_fun (*this, &ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <pbd/error.h>
|
||||
#include <pbd/id.h>
|
||||
#include <pbd/strsplit.h>
|
||||
#include <pbd/fpu.h>
|
||||
|
||||
#include <midi++/port.h>
|
||||
#include <midi++/port_request.h>
|
||||
|
|
@ -200,42 +201,14 @@ void
|
|||
setup_hardware_optimization (bool try_optimization)
|
||||
{
|
||||
bool generic_mix_functions = true;
|
||||
|
||||
FPU fpu;
|
||||
|
||||
if (try_optimization) {
|
||||
|
||||
#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
|
||||
|
||||
unsigned long use_sse = 0;
|
||||
if (fpu.has_sse()) {
|
||||
|
||||
#ifndef USE_X86_64_ASM
|
||||
asm (
|
||||
"mov $1, %%eax\n"
|
||||
"pushl %%ebx\n"
|
||||
"cpuid\n"
|
||||
"movl %%edx, %0\n"
|
||||
"popl %%ebx\n"
|
||||
: "=r" (use_sse)
|
||||
:
|
||||
: "%eax", "%ecx", "%edx", "memory");
|
||||
|
||||
#else
|
||||
|
||||
asm (
|
||||
"pushq %%rbx\n"
|
||||
"movq $1, %%rax\n"
|
||||
"cpuid\n"
|
||||
"movq %%rdx, %0\n"
|
||||
"popq %%rbx\n"
|
||||
: "=r" (use_sse)
|
||||
:
|
||||
: "%rax", "%rcx", "%rdx", "memory");
|
||||
|
||||
#endif /* USE_X86_64_ASM */
|
||||
|
||||
use_sse &= (1 << 25); // bit 25 = SSE support
|
||||
|
||||
if (use_sse) {
|
||||
info << "Using SSE optimized routines" << endmsg;
|
||||
|
||||
// SSE SET
|
||||
|
|
@ -538,17 +511,16 @@ ARDOUR::LocaleGuard::~LocaleGuard ()
|
|||
void
|
||||
ARDOUR::setup_fpu ()
|
||||
{
|
||||
#ifdef USE_XMMINTRIN
|
||||
#if defined(ARCH_X86) && defined(USE_XMMINTRIN)
|
||||
|
||||
int MXCSR;
|
||||
FPU fpu;
|
||||
|
||||
/* XXX use real code to determine if the processor supports
|
||||
DenormalsAreZero and FlushToZero
|
||||
*/
|
||||
|
||||
bool has_daz = false;
|
||||
bool can_ftz = true;
|
||||
|
||||
if (!can_ftz && !has_daz) {
|
||||
if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -556,26 +528,30 @@ ARDOUR::setup_fpu ()
|
|||
|
||||
switch (Config->get_denormal_model()) {
|
||||
case DenormalNone:
|
||||
MXCSR &= ~_MM_FLUSH_ZERO_ON;
|
||||
MXCSR &= ~(_MM_FLUSH_ZERO_ON|0x8000);
|
||||
break;
|
||||
|
||||
case DenormalFTZ:
|
||||
if (fpu.has_flush_to_zero()) {
|
||||
MXCSR |= _MM_FLUSH_ZERO_ON;
|
||||
}
|
||||
break;
|
||||
|
||||
case DenormalDAZ:
|
||||
MXCSR &= ~_MM_FLUSH_ZERO_ON;
|
||||
if (has_daz) {
|
||||
if (fpu.has_denormals_are_zero()) {
|
||||
MXCSR |= 0x8000;
|
||||
}
|
||||
break;
|
||||
|
||||
case DenormalFTZDAZ:
|
||||
if (has_daz) {
|
||||
if (fpu.has_flush_to_zero()) {
|
||||
if (fpu.has_denormals_are_zero()) {
|
||||
MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000;
|
||||
} else {
|
||||
MXCSR |= _MM_FLUSH_ZERO_ON;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3278,6 +3278,8 @@ Session::config_changed (const char* parameter_name)
|
|||
set_slave_source (Config->get_slave_source());
|
||||
} else if (PARAM_IS ("remote-model")) {
|
||||
set_remote_control_ids ();
|
||||
} else if (PARAM_IS ("denormal-model")) {
|
||||
setup_fpu ();
|
||||
}
|
||||
|
||||
set_dirty ();
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ controllable.cc
|
|||
enumwriter.cc
|
||||
dmalloc.cc
|
||||
error.cc
|
||||
fpu.cc
|
||||
id.cc
|
||||
mountpoint.cc
|
||||
path.cc
|
||||
|
|
|
|||
92
libs/pbd/fpu.cc
Normal file
92
libs/pbd/fpu.cc
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#define _XOPEN_SOURCE 600
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <pbd/fpu.h>
|
||||
#include <pbd/error.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace PBD;
|
||||
using namespace std;
|
||||
|
||||
FPU::FPU ()
|
||||
{
|
||||
unsigned long cpuflags = 0;
|
||||
|
||||
_flags = Flags (0);
|
||||
|
||||
#ifndef ARCH_X86
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifndef USE_X86_64_ASM
|
||||
asm volatile (
|
||||
"mov $1, %%eax\n"
|
||||
"pushl %%ebx\n"
|
||||
"cpuid\n"
|
||||
"movl %%edx, %0\n"
|
||||
"popl %%ebx\n"
|
||||
: "=r" (cpuflags)
|
||||
:
|
||||
: "%eax", "%ecx", "%edx", "memory"
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
asm volatile (
|
||||
"pushq %%rbx\n"
|
||||
"movq $1, %%rax\n"
|
||||
"cpuid\n"
|
||||
"movq %%rdx, %0\n"
|
||||
"popq %%rbx\n"
|
||||
: "=r" (cpuflags)
|
||||
:
|
||||
: "%rax", "%rcx", "%rdx", "memory"
|
||||
);
|
||||
|
||||
#endif /* USE_X86_64_ASM */
|
||||
|
||||
if (cpuflags & (1<<25)) {
|
||||
_flags = Flags (_flags | (HasSSE|HasFlushToZero));
|
||||
}
|
||||
|
||||
if (cpuflags & (1<<26)) {
|
||||
_flags = Flags (_flags | HasSSE2);
|
||||
}
|
||||
|
||||
if (cpuflags & (1 << 24)) {
|
||||
|
||||
char* fxbuf = 0;
|
||||
|
||||
if (posix_memalign ((void**)&fxbuf, 16, 512)) {
|
||||
error << _("cannot allocate 16 byte aligned buffer for h/w feature detection") << endmsg;
|
||||
} else {
|
||||
|
||||
asm volatile (
|
||||
"fxsave (%0)"
|
||||
:
|
||||
: "r" (fxbuf)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]);
|
||||
|
||||
/* if the mask is zero, set its default value (from intel specs) */
|
||||
|
||||
if (mxcsr_mask == 0) {
|
||||
mxcsr_mask = 0xffbf;
|
||||
}
|
||||
|
||||
if (mxcsr_mask & (1<<6)) {
|
||||
_flags = Flags (_flags | HasDenormalsAreZero);
|
||||
}
|
||||
|
||||
free (fxbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FPU::~FPU ()
|
||||
{
|
||||
}
|
||||
31
libs/pbd/pbd/fpu.h
Normal file
31
libs/pbd/pbd/fpu.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __pbd_fpu_h__
|
||||
#define __pbd_fpu_h__
|
||||
|
||||
namespace PBD {
|
||||
|
||||
|
||||
class FPU {
|
||||
private:
|
||||
enum Flags {
|
||||
HasFlushToZero = 0x1,
|
||||
HasDenormalsAreZero = 0x2,
|
||||
HasSSE = 0x4,
|
||||
HasSSE2 = 0x8
|
||||
};
|
||||
|
||||
public:
|
||||
FPU ();
|
||||
~FPU ();
|
||||
|
||||
bool has_flush_to_zero () const { return _flags & HasFlushToZero; }
|
||||
bool has_denormals_are_zero () const { return _flags & HasDenormalsAreZero; }
|
||||
bool has_sse () const { return _flags & HasSSE; }
|
||||
bool has_sse2 () const { return _flags & HasSSE2; }
|
||||
|
||||
private:
|
||||
Flags _flags;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __pbd_fpu_h__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue