From f39e79efeda889b33e732549343f683c52e5b596 Mon Sep 17 00:00:00 2001 From: Steve Checkoway Date: Sun, 14 May 2006 07:04:28 +0000 Subject: [PATCH] The last of the changes, I hope. --- stepmania/src/RageSoundMixBuffer.cpp | 32 +++ .../arch/InputHandler/InputHandler_Carbon.cpp | 3 +- .../MemoryCardDriverThreaded_OSX.cpp | 13 +- .../src/archutils/Darwin/VectorHelper.cpp | 207 ++++++++++++++++++ stepmania/src/archutils/Darwin/VectorHelper.h | 40 ++++ 5 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 stepmania/src/archutils/Darwin/VectorHelper.cpp create mode 100644 stepmania/src/archutils/Darwin/VectorHelper.h diff --git a/stepmania/src/RageSoundMixBuffer.cpp b/stepmania/src/RageSoundMixBuffer.cpp index a476a37019..6b664c46c3 100644 --- a/stepmania/src/RageSoundMixBuffer.cpp +++ b/stepmania/src/RageSoundMixBuffer.cpp @@ -2,12 +2,21 @@ #include "RageSoundMixBuffer.h" #include "RageUtil.h" +#if defined(MACOSX) +#include "archutils/Darwin/VectorHelper.h" + +static bool g_bVector; +#endif + RageSoundMixBuffer::RageSoundMixBuffer() { m_iBufSize = m_iBufUsed = 0; m_pMixbuf = NULL; m_iOffset = 0; SetVolume( 1.0f ); +#ifdef USE_VEC + g_bVector = Vector::CheckForVector(); +#endif } RageSoundMixBuffer::~RageSoundMixBuffer() @@ -49,6 +58,13 @@ void RageSoundMixBuffer::write( const int16_t *buf, unsigned size ) /* Scale volume and add. */ int32_t *pBuf = m_pMixbuf+m_iOffset; +#ifdef USE_VEC + if( g_bVector ) + { + Vector::FastSoundWrite( pBuf, buf, size, m_iVolumeFactor ); + return; + } +#endif for( unsigned pos = 0; pos < size; ++pos ) { *pBuf += buf[pos] * m_iVolumeFactor; ++pBuf; @@ -57,6 +73,14 @@ void RageSoundMixBuffer::write( const int16_t *buf, unsigned size ) void RageSoundMixBuffer::read( int16_t *buf ) { +#ifdef USE_VEC + if( g_bVector ) + { + Vector::FastSoundRead( buf, m_pMixbuf, m_iBufUsed ); + m_iBufUsed = 0; + return; + } +#endif for( unsigned pos = 0; pos < m_iBufUsed; ++pos ) { int32_t out = (m_pMixbuf[pos]) / 256; @@ -67,6 +91,14 @@ void RageSoundMixBuffer::read( int16_t *buf ) void RageSoundMixBuffer::read( float *buf ) { +#ifdef USE_VEC + if( g_bVector ) + { + Vector::FastSoundRead( buf, m_pMixbuf, m_iBufUsed ); + m_iBufUsed = 0; + return; + } +#endif const int Minimum = -32768 * 256; const int Maximum = 32767 * 256; diff --git a/stepmania/src/arch/InputHandler/InputHandler_Carbon.cpp b/stepmania/src/arch/InputHandler/InputHandler_Carbon.cpp index fa2a393124..6857c0dbd8 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_Carbon.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_Carbon.cpp @@ -123,7 +123,7 @@ InputHandler_Carbon::~InputHandler_Carbon() CFRunLoopWakeUp( m_LoopRef ); m_InputThread.Wait(); CFRelease( m_SourceRef ); - // Don't release the loop ref. + CFRelease( m_LoopRef ); LOG->Trace( "Input handler thread shut down." ); } @@ -236,6 +236,7 @@ InputHandler_Carbon::InputHandler_Carbon() : m_Sem( "Input thread started" ), m_ else { m_LoopRef = CFRunLoopRef( GetCFRunLoopFromEventLoop(GetMainEventLoop()) ); + CFRetain( m_LoopRef ); StartDevices(); } } diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_OSX.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_OSX.cpp index d99b7a3463..26638ca06d 100644 --- a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_OSX.cpp +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_OSX.cpp @@ -169,11 +169,20 @@ void MemoryCardDriverThreaded_OSX::GetUSBStorageDevices( vectorTrace( "Device \"%s\" (%s) has IOServicePlane path: %s.", + fs[i].f_mntfromname, fs[i].f_mntonname, path ); + continue; + } // The path does not start with / so pos - 1 >= 0. pos = sRegistryPath.rfind( '/', pos - 1 ); if( pos == RString::npos ) - continue; // Something is horribly wrong at this point. + { + // Something is horribly wrong at this point. + LOG->Trace( "Device has unusual IOServicePlane path: %s", path ); + continue; + } path[pos] = '\0'; io_registry_entry_t device = IORegistryEntryFromPath( kIOMasterPortDefault, path ); diff --git a/stepmania/src/archutils/Darwin/VectorHelper.cpp b/stepmania/src/archutils/Darwin/VectorHelper.cpp new file mode 100644 index 0000000000..11ddee9c98 --- /dev/null +++ b/stepmania/src/archutils/Darwin/VectorHelper.cpp @@ -0,0 +1,207 @@ +#include "global.h" +#include "VectorHelper.h" +#include "RageUtil.h" + +#ifdef USE_VEC +#include +#ifndef __VECLIBTYPES__ +// Copy this from the header since it isn't in the 10.2.8 sdk +typedef vector unsigned char vUInt8; +typedef vector signed char vSInt8; +typedef vector unsigned short vUInt16; +typedef vector signed short vSInt16; +typedef vector unsigned int vUInt32; +typedef vector signed int vSInt32; +typedef vector float vFloat; +typedef vector bool int vBool32; +#endif + +bool Vector::CheckForVector() +{ + long cpuAttributes; + OSErr err = Gestalt( gestaltPowerPCProcessorFeatures, &cpuAttributes ); + + return err == noErr && ( cpuAttributes & (1 << gestaltPowerPCHasVectorInstructions) ); +} + +void Vector::FastSoundWrite( int32_t *dest, const int16_t *src, unsigned size, short volume ) +{ + if( unlikely(size == 0) ) + return; + ASSERT_M( (unsigned(dest) &0xF) == 0, ssprintf("dest = %p", dest) ); + + vUInt8 splat_mask = vec_lvsl( 0, &volume ); + vSInt16 vol = vec_lde( 0, &volume ); + + vol = vec_splat( vec_perm(vol, vol, splat_mask), 0 ); + + vSInt16 MSQ = vec_ld( 0, src ); + vSInt16 LSQ; + vUInt8 mask = vec_add( vec_lvsl(15, src), vec_splat_u8(1) ); + + while( size & ~0x7 ) + { + // Deal with unaligned data. + LSQ = vec_ld( 15, src ); + + vSInt16 data = vec_perm( MSQ, LSQ, mask ); + vSInt32 result1 = vec_ld( 0, dest ); + vSInt32 result2 = vec_ld( 16, dest ); + vSInt32 even = vec_mule( data, vol ); + vSInt32 odd = vec_mulo( data, vol ); + vSInt32 first = vec_mergeh( even, odd ); + vSInt32 second = vec_mergel( even, odd ); + + vec_st( vec_add(result1, first), 0, dest ); + vec_st( vec_add(result2, second), 16, dest ); + dest += 8; + src += 8; + size -= 8; + MSQ = LSQ; + } + if( size ) + { + // Deal with the remaining samples but be careful while storing. + // Deal with unaligned data. + LSQ = vec_ld( 15, src ); + + vSInt16 data = vec_perm( MSQ, LSQ, mask ); + vSInt32 result1 = vec_ld( 0, dest ); + vSInt32 result2 = vec_ld( 16, dest ); + vSInt32 even = vec_mule( data, vol ); + vSInt32 odd = vec_mulo( data, vol ); + vSInt32 first = vec_mergeh( even, odd ); + vSInt32 second = vec_mergel( even, odd ); + + result1 = vec_add( result1, first ); + result2 = vec_add( result2, second ); + if( size >= 4 ) + { + vec_st( result1, 0, dest ); + dest += 4; + size -= 4; + while( size-- ) + vec_ste( result2, 0, dest++ ); + } + else + { + while( size-- ) + vec_ste( result1, 0, dest++ ); + } + } +} + +void Vector::FastSoundRead( int16_t *dest, const int32_t *src, unsigned size ) +{ + ASSERT_M( (unsigned(dest) & 0xF) == 0, ssprintf("dest = %p", dest) ); + ASSERT_M( (unsigned(src) & 0xF) == 0, ssprintf("src = %p", src) ); + + vSInt32 zero = (vSInt32)( 0 ); + vUInt32 shift = (vUInt32)( 8 ); + + while( size & ~0x7 ) + { + vSInt32 first = vec_ldl( 0, src ); + vSInt32 second = vec_ldl( 16, src ); + vBool32 b1 = vec_cmplt( first, zero ); + vBool32 b2 = vec_cmplt( second, zero ); + + first = vec_abss( first ); + second = vec_abss( second ); + first = vec_sr( first, shift ); + second = vec_sr( second, shift ); + + vSInt32 temp1 = vec_and( first, (vSInt32)b1 ); + vSInt32 temp2 = vec_and( second, (vSInt32) b2 ); + + first = vec_subs( first, temp1 ); + second = vec_subs( second, temp2 ); + first = vec_subs( first, temp1 ); + second = vec_sub( second, temp2 ); + + vec_st( vec_packs(first, second), 0, dest ); + dest += 8; + src += 8; + size -= 8; + } + if( size ) + { + // Deal with the remaining samples but be careful while storing. + vSInt32 first = vec_ldl( 0, src ); + vSInt32 second = vec_ldl( 16, src ); + vBool32 b1 = vec_cmplt( first, zero ); + vBool32 b2 = vec_cmplt( second, zero ); + + first = vec_abss( first ); + second = vec_abss( second ); + first = vec_sr( first, shift ); + second = vec_sr( second, shift ); + + vSInt32 temp1 = vec_and( first, (vSInt32)b1 ); + vSInt32 temp2 = vec_and( second, (vSInt32) b2 ); + + first = vec_subs( first, temp1 ); + second = vec_subs( second, temp2 ); + first = vec_subs( first, temp1 ); + second = vec_sub( second, temp2 ); + + vSInt16 result = vec_packs( first, second ); + while( size-- ) + vec_ste( result, 0, dest++ ); + } + +} + +void Vector::FastSoundRead( float *dest, const int32_t *src, unsigned size ) +{ + ASSERT_M( (unsigned(dest) &0xF) == 0, ssprintf("dest = %p", dest) ); + ASSERT_M( (unsigned(src) & 0xF) == 0, ssprintf("src = %p", src) ); + + vFloat scale = (vFloat) ( 32767.5f ); + vSInt32 l1 = (vSInt32) ( -8388608 ); + vFloat l2 = (vFloat) ( -1.0f ); + + while( size & ~0x3 ) + { + vFloat result = vec_ctf( vec_subs(vec_ldl(0, src), l1), 8 ); + + vec_st( vec_madd(result, scale, l2), 0, dest ); + dest += 4; + src += 4; + size -= 4; + } + if( size ) + { + // Deal with the remaining samples but be careful while storing. + vFloat result = vec_madd( vec_ctf(vec_subs(vec_ldl(0, src), l1), 8), scale, l2 ); + + while( size-- ) + vec_ste( result, 0, dest++ ); + } +} +#endif + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/archutils/Darwin/VectorHelper.h b/stepmania/src/archutils/Darwin/VectorHelper.h new file mode 100644 index 0000000000..705e37eb63 --- /dev/null +++ b/stepmania/src/archutils/Darwin/VectorHelper.h @@ -0,0 +1,40 @@ +#ifndef VECTOR_HELPER_H +#define VECTOR_HELPER_H + +#if defined(__VEC__) +namespace Vector +{ + bool CheckForVector(); + void FastSoundWrite( int32_t *dest, const int16_t *src, unsigned size, short volume ); + void FastSoundRead( int16_t *dest, const int32_t *src, unsigned size ); + void FastSoundRead( float *dest, const int32_t *src, unsigned size ); +} +#define USE_VEC +#endif + +#endif + +/* + * (c) 2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */