all: Add multiple builds for different CPU feature sets and a wrapper DLL to go along with them

Closes: #46
pull/100/head
Josh Dowell 3 months ago committed by Joshie
parent b4ef78acea
commit 327a96ca54

@ -0,0 +1,12 @@
//-----------------------------------------------------------------------------
// JOLTPHYSICS_AVX2.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro PROJNAME "joltphysics_avx2"
$Conditional VOLT_AVX2 "1"
$Macro VOLTARCH "AVX2"
$Include "joltphysics_inc.vpc"

@ -5,7 +5,7 @@
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\.."
$Macro OUTLIBNAME "joltphysics"
$Macro OUTLIBNAME "$PROJNAME"
$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
@ -20,7 +20,25 @@ $Configuration
}
}
$Project "JoltPhysics"
$Configuration "Debug"
{
$General
{
//$OutputDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
$IntermediateDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
}
}
$Configuration "Release"
{
$General
{
//$OutputDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
$IntermediateDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
}
}
$Project "$PROJNAME"
{
$Folder "Precompiled Header"
{

@ -2,6 +2,8 @@
// Configuration settings for Jolt Physics
//
$MacroRequired "VOLTARCH"
$Configuration
{
$Compiler
@ -11,14 +13,18 @@ $Configuration
$PreprocessorDefinitions "$BASE;JPH_DISABLE_CUSTOM_ALLOCATOR;JPH_DEBUG_RENDERER"
$PreprocessorDefinitions "$BASE;JPH_ENABLE_ASSERTS" [$DEVELOPMENT_ONLY]
//$PreprocessorDefinitions "$BASE;JPH_PROFILE_ENABLED" [$DEVELOPMENT_ONLY]
// CPU feature macros, we may want to tune these before release.
$PreprocessorDefinitions "$BASE;JPH_USE_SSE4_1;JPH_USE_SSE4_2;JPH_USE_LZCNT;JPH_USE_TZCNT;JPH_USE_F16C;JPH_USE_FMADD"
$GCC_ExtraCompilerFlags "$BASE -msse4.1 -msse4.2 -mlzcnt -mf16c -mfma -mbmi"
// Feature test stuff for the AVX2 build
$PreprocessorDefinitions "$BASE;JPH_USE_SSE4_1;JPH_USE_SSE4_2;JPH_USE_AVX;JPH_USE_AVX2;JPH_USE_LZCNT;JPH_USE_TZCNT;JPH_USE_F16C;JPH_USE_FMADD" [$VOLT_AVX2]
$GCC_ExtraCompilerFlags "$BASE -msse4.1 -msse4.2 -mavx2 -mlzcnt -mf16c -mfma -mbmi" [$VOLT_AVX2]
$EnableEnhancedInstructionSet "Advanced Vector Extensions 2 (/arch:AVX2)" [$VOLT_AVX2]
// Feature test stuff for the SSE 4.2 build
$PreprocessorDefinitions "$BASE;JPH_USE_SSE4_1;JPH_USE_SSE4_2" [$VOLT_SSE42]
$GCC_ExtraCompilerFlags "$BASE -msse4.1 -msse4.2" [$VOLT_SSE42]
$EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [$WIN32 && $VOLT_SSE42] // Source 2013 doesn't enable this by default
// We DO want to comment this line out for release, AVX 1 & 2 adoption isn't reliable enough yet
// $EnableEnhancedInstructionSet "Advanced Vector Extensions 2 (/arch:AVX2)" [$DEVELOPMENT_ONLY]
// Feature test stuff for the SSE 2 build
$EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [$WIN32 && $VOLT_SSE2] // Source 2013 doesn't enable this by default
}
}

@ -0,0 +1,12 @@
//-----------------------------------------------------------------------------
// JOLTPHYSICS_SSE2.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro PROJNAME "joltphysics_sse2"
$Conditional VOLT_SSE2 "1"
$Macro VOLTARCH "SSE2"
$Include "joltphysics_inc.vpc"

@ -0,0 +1,12 @@
//-----------------------------------------------------------------------------
// JOLTPHYSICS_SSE42.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro PROJNAME "joltphysics_sse42"
$Conditional VOLT_SSE42 "1"
$Macro VOLTARCH "SSE42"
$Include "joltphysics_inc.vpc"

@ -8,11 +8,18 @@ $Group "jolt"
{
"appframework"
"interfaces"
"tier0_static"
"tier1"
"tier2"
"mathlib"
"joltphysics"
"vphysics_jolt"
"vstdlib_static"
"joltphysics_avx2"
"joltphysics_sse42"
"joltphysics_sse2"
"vphysics_jolt_avx2"
"vphysics_jolt_sse42"
"vphysics_jolt_sse2"
"vphysics_wrapper_external"
}
$Group "jolt_static"

@ -4,14 +4,44 @@
// Project configurations for VPhysics Jolt
//-----------------------------------------------------------------------------
$Project "joltphysics"
$Project "joltphysics_avx2"
{
"vphysics_jolt/joltphysics/joltphysics.vpc"
"vphysics_jolt/joltphysics/joltphysics_avx2.vpc"
}
$Project "vphysics_jolt"
$Project "joltphysics_sse42"
{
"vphysics_jolt/vphysics_jolt/vphysics_jolt.vpc"
"vphysics_jolt/joltphysics/joltphysics_sse42.vpc"
}
$Project "joltphysics_sse2"
{
"vphysics_jolt/joltphysics/joltphysics_sse2.vpc"
}
$Project "vphysics_jolt_avx2"
{
"vphysics_jolt/vphysics_jolt/vphysics_jolt_avx2.vpc"
}
$Project "vphysics_jolt_sse42"
{
"vphysics_jolt/vphysics_jolt/vphysics_jolt_sse42.vpc"
}
$Project "vphysics_jolt_sse2"
{
"vphysics_jolt/vphysics_jolt/vphysics_jolt_sse2.vpc"
}
$Project "vphysics_wrapper_internal"
{
"vphysics_jolt/vphysics_wrapper/vphysics_wrapper_internal.vpc"
}
$Project "vphysics_wrapper_external"
{
"vphysics_jolt/vphysics_wrapper/vphysics_wrapper_external.vpc"
}
$Project "vphysics_jolt_static"

@ -1,9 +1,12 @@
//-----------------------------------------------------------------------------
// VPHYSICS_JOLT_STATIC.VPC
// VPHYSICS_JOLT_AVX2.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro PROJNAME "vphysics_jolt_static"
$Macro PROJNAME "vphysics_jolt_avx2"
$Conditional VOLT_AVX2 "1"
$Macro VOLTARCH "AVX2"
$Include "vphysics_jolt_inc.vpc"

@ -1,5 +1,5 @@
//-----------------------------------------------------------------------------
// VPHYSICS_JOLT_INC.INC
// VPHYSICS_JOLT_INC.VPC
//
// Project Script
//-----------------------------------------------------------------------------
@ -30,6 +30,24 @@ $Configuration
}
}
$Configuration "Debug"
{
$General
{
$OutputDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
$IntermediateDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
}
}
$Configuration "Release"
{
$General
{
$OutputDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
$IntermediateDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS]
}
}
$Project "$PROJNAME"
{
$Folder "Precompiled Header"
@ -142,7 +160,9 @@ $Project "$PROJNAME"
$Folder "Link Libraries"
{
$Lib "joltphysics"
$Lib "joltphysics_avx2" [$VOLT_AVX2]
$Lib "joltphysics_sse42" [$VOLT_SSE42]
$Lib "joltphysics_sse2" [$VOLT_SSE2]
$Lib "mathlib"
$Lib "tier2"
}

@ -0,0 +1,12 @@
//-----------------------------------------------------------------------------
// VPHYSICS_JOLT_SSE2.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro PROJNAME "vphysics_jolt_sse2"
$Conditional VOLT_SSE2 "1"
$Macro VOLTARCH "SSE2"
$Include "vphysics_jolt_inc.vpc"

@ -4,6 +4,9 @@
// Project Script
//-----------------------------------------------------------------------------
$Macro PROJNAME "vphysics_jolt"
$Macro PROJNAME "vphysics_jolt_sse42"
$Conditional VOLT_SSE42 "1"
$Macro VOLTARCH "SSE42"
$Include "vphysics_jolt_inc.vpc"

@ -0,0 +1,208 @@
//=================================================================================================
//
// The base physics DLL interface
//
// This is a thin CPU-agnostic wrapper for the actual Volt DLLs which are named
// vphysics_jolt_sse2.dll, vphysics_jolt_sse42.dll and vphysics_jolt_avx2.dll
//
//=================================================================================================
#include "tier0/basetypes.h"
#include "tier1/interface.h"
#include "vphysics_interface.h"
#ifdef _WIN32
#include <intrin.h>
#else
#include <cpuid.h>
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-------------------------------------------------------------------------------------------------
class PhysicsWrapper final : public CBaseAppSystem<IPhysics>
{
public:
bool Connect( CreateInterfaceFn factory ) override;
void Disconnect() override;
InitReturnVal_t Init() override;
void Shutdown() override;
void *QueryInterface( const char *pInterfaceName ) override;
IPhysicsEnvironment *CreateEnvironment() override;
void DestroyEnvironment( IPhysicsEnvironment *pEnvironment ) override;
IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index ) override;
IPhysicsObjectPairHash *CreateObjectPairHash() override;
void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ) override;
IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount ) override;
IPhysicsCollisionSet *FindCollisionSet( unsigned int id ) override;
void DestroyAllCollisionSets() override;
public:
static PhysicsWrapper &GetInstance() { return s_PhysicsInterface; }
private:
bool InitWrapper();
CSysModule *m_pActualPhysicsModule;
IPhysics *m_pActualPhysicsInterface;
static PhysicsWrapper s_PhysicsInterface;
};
PhysicsWrapper PhysicsWrapper::s_PhysicsInterface;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( PhysicsWrapper, IPhysics, VPHYSICS_INTERFACE_VERSION, PhysicsWrapper::GetInstance() );
//-------------------------------------------------------------------------------------------------
enum CPULevel_t
{
CPU_HAS_SSE2,
CPU_HAS_SSE42,
CPU_HAS_AVX2,
};
static void GetCPUID( int *pInfo, int func, int subfunc )
{
#ifdef _WIN32
__cpuidex( pInfo, func, subfunc );
#else
__cpuid_count( func, subfunc, pInfo[0], pInfo[1], pInfo[2], pInfo[3] );
#endif
}
static CPULevel_t GetCPULevel()
{
int cpuInfo[4];
CPULevel_t cpuLevel = CPU_HAS_SSE2;
GetCPUID( cpuInfo, 0, 0 ); // Get the number of functions
const int numFuncs = cpuInfo[0];
if ( numFuncs >= 7 )
{
GetCPUID( cpuInfo, 7, 0 ); // Call function 7
bool hasAVX2 = cpuInfo[1] & ( 1 << 5 ); // 5 is the AVX2 bit
if ( hasAVX2 )
cpuLevel = CPU_HAS_AVX2;
}
else
{
GetCPUID( cpuInfo, 1, 0 ); // Call function 1
bool hasSSE42 = cpuInfo[2] & ( 1 << 20 ); // 20 is the SSE42 bit
if ( hasSSE42 )
cpuLevel = CPU_HAS_SSE42;
}
return cpuLevel;
}
static const char *GetModuleFromCPULevel( CPULevel_t level )
{
switch ( level )
{
case CPU_HAS_AVX2: return "vphysics_jolt_avx2" DLL_EXT_STRING;
case CPU_HAS_SSE42: return "vphysics_jolt_sse42" DLL_EXT_STRING;
default: return "vphysics_jolt_sse2" DLL_EXT_STRING;
}
}
// Tries to load the actual vphysics DLL
bool PhysicsWrapper::InitWrapper()
{
if ( m_pActualPhysicsInterface )
return true;
const char *pModuleName = GetModuleFromCPULevel( GetCPULevel() );
if ( !Sys_LoadInterface( pModuleName, VPHYSICS_INTERFACE_VERSION, &m_pActualPhysicsModule, (void **)&m_pActualPhysicsInterface ) )
return false;
return true;
}
bool PhysicsWrapper::Connect( CreateInterfaceFn factory )
{
if ( !InitWrapper() )
return false;
return m_pActualPhysicsInterface->Connect( factory );
}
void PhysicsWrapper::Disconnect()
{
m_pActualPhysicsInterface->Disconnect();
Sys_UnloadModule( m_pActualPhysicsModule );
}
//-------------------------------------------------------------------------------------------------
InitReturnVal_t PhysicsWrapper::Init()
{
return m_pActualPhysicsInterface->Init();
}
void PhysicsWrapper::Shutdown()
{
m_pActualPhysicsInterface->Shutdown();
}
void *PhysicsWrapper::QueryInterface( const char *pInterfaceName )
{
// This function can be called before Connect, so try and load the real DLL early
if ( !InitWrapper() )
return nullptr;
return m_pActualPhysicsInterface->QueryInterface( pInterfaceName );
}
//-------------------------------------------------------------------------------------------------
IPhysicsEnvironment *PhysicsWrapper::CreateEnvironment()
{
return m_pActualPhysicsInterface->CreateEnvironment();
}
void PhysicsWrapper::DestroyEnvironment( IPhysicsEnvironment *pEnvironment )
{
m_pActualPhysicsInterface->DestroyEnvironment( pEnvironment );
}
IPhysicsEnvironment *PhysicsWrapper::GetActiveEnvironmentByIndex( int index )
{
return m_pActualPhysicsInterface->GetActiveEnvironmentByIndex( index );
}
//-------------------------------------------------------------------------------------------------
IPhysicsObjectPairHash *PhysicsWrapper::CreateObjectPairHash()
{
return m_pActualPhysicsInterface->CreateObjectPairHash();
}
void PhysicsWrapper::DestroyObjectPairHash( IPhysicsObjectPairHash *pHash )
{
m_pActualPhysicsInterface->DestroyObjectPairHash( pHash );
}
//-------------------------------------------------------------------------------------------------
IPhysicsCollisionSet *PhysicsWrapper::FindOrCreateCollisionSet( unsigned int id, int maxElementCount )
{
return m_pActualPhysicsInterface->FindOrCreateCollisionSet( id, maxElementCount );
}
IPhysicsCollisionSet *PhysicsWrapper::FindCollisionSet( unsigned int id )
{
return m_pActualPhysicsInterface->FindCollisionSet( id );
}
void PhysicsWrapper::DestroyAllCollisionSets()
{
m_pActualPhysicsInterface->DestroyAllCollisionSets();
}

@ -0,0 +1,12 @@
//-----------------------------------------------------------------------------
// VPHYSICS_WRAPPER_EXTERNAL.VPC
//
// Project Script
//-----------------------------------------------------------------------------
// Existing Source engine games don't know about Volt, so public wrapper builds
// just output "vphysics.dll"
$Macro WRAPPER_NAME "vphysics"
$Include "vphysics_wrapper_inc.vpc"

@ -0,0 +1,53 @@
//-----------------------------------------------------------------------------
// VPHYSICS_WRAPPER.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$MacroRequired "WRAPPER_NAME"
$Macro SRCDIR "..\.."
$Macro OUTBINNAME "$WRAPPER_NAME"
$Macro OUTBINDIR "$SRCDIR\..\$GAMEDIR\bin"
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
$Configuration
{
$Linker
{
// For Alien Swarm, we don't get the ability to build our own tier1 or mathlib
// which means we need to be compatible with the .libs provided built for
// ancient Visual Studio.
$AdditionalDependencies "$BASE legacy_stdio_definitions.lib" [$GAME_ASW]
}
}
$Project "vphysics_wrapper"
{
$Folder "Source Files"
{
$File "vphysics_wrapper.cpp"
}
$Folder "Header Files"
{
}
$Folder "Interface"
{
$File "$SRCDIR\public\vphysics_interface.h"
$File "$SRCDIR\public\vphysics\collision_set.h"
$File "$SRCDIR\public\vphysics\constraints.h"
$File "$SRCDIR\public\vphysics\friction.h"
$File "$SRCDIR\public\vphysics\object_hash.h"
$File "$SRCDIR\public\vphysics\performance.h"
$File "$SRCDIR\public\vphysics\player_controller.h"
$File "$SRCDIR\public\vphysics\stats.h"
$File "$SRCDIR\public\vphysics\vehicles.h"
}
$Folder "Link Libraries"
{
}
}

@ -0,0 +1,11 @@
//-----------------------------------------------------------------------------
// VPHYSICS_WRAPPER_INTERNAL.VPC
//
// Project Script
//-----------------------------------------------------------------------------
// This file is used when building for an engine that is aware of vphysics_jolt
$Macro WRAPPER_NAME "vphysics_jolt"
$Include "vphysics_wrapper_inc.vpc"
Loading…
Cancel
Save