diff options
Diffstat (limited to 'vphysics/traceperf/traceperf.cpp')
| -rw-r--r-- | vphysics/traceperf/traceperf.cpp | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/vphysics/traceperf/traceperf.cpp b/vphysics/traceperf/traceperf.cpp new file mode 100644 index 0000000..9d0a705 --- /dev/null +++ b/vphysics/traceperf/traceperf.cpp @@ -0,0 +1,406 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// traceperf.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "gametrace.h" +#include "fmtstr.h" +#include "appframework/appframework.h" +#include "filesystem.h" +#include "filesystem_init.h" +#include "tier1/tier1.h" +#include "tier2/tier2.h" +#include "tier3/tier3.h" + +IPhysicsCollision *physcollision = NULL; + +#define NUM_COLLISION_TESTS 2500 + +void ReadPHYFile(const char *name, vcollide_t &collide ) +{ + FileHandle_t fp = g_pFullFileSystem->Open(name, "rb"); + if (!fp) + Error ("Couldn't open %s", name); + + phyheader_t header; + + g_pFullFileSystem->Read( &header, sizeof(header), fp ); + if ( header.size != sizeof(header) || header.solidCount <= 0 ) + return; + + int fileSize = g_pFullFileSystem->Size(fp); + + char *buf = (char *)_alloca( fileSize ); + g_pFullFileSystem->Read( buf, fileSize, fp ); + g_pFullFileSystem->Close( fp ); + + physcollision->VCollideLoad( &collide, header.solidCount, (const char *)buf, fileSize ); +} + + +struct testlist_t +{ + Vector start; + Vector end; + Vector normal; + bool hit; +}; + +struct benchresults_t +{ + int collisionTests; + int collisionHits; + float totalTime; + float rayTime; + float boxTime; +}; + +testlist_t g_Traces[NUM_COLLISION_TESTS]; +void Benchmark_PHY( const CPhysCollide *pCollide, benchresults_t *pOut ) +{ + int i; + Vector start = vec3_origin; + static Vector *targets = NULL; + static bool first = true; + static float test[2] = {1,1}; + if ( first ) + { + float radius = 0; + float theta = 0; + float phi = 0; + for ( int i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + radius += NUM_COLLISION_TESTS * 123.123f; + radius = fabs(fmod(radius, 128)); + theta += NUM_COLLISION_TESTS * 0.76f; + theta = fabs(fmod(theta, DEG2RAD(360))); + phi += NUM_COLLISION_TESTS * 0.16666666f; + phi = fabs(fmod(phi, DEG2RAD(180))); + + float st, ct, sp, cp; + SinCos( theta, &st, &ct ); + SinCos( phi, &sp, &cp ); + st = sin(theta); + ct = cos(theta); + sp = sin(phi); + cp = cos(phi); + + g_Traces[i].start.x = radius * ct * sp; + g_Traces[i].start.y = radius * st * sp; + g_Traces[i].start.z = radius * cp; + } + first = false; + } + + float duration = 0; + Vector size[2]; + size[0].Init(0,0,0); + size[1].Init(16,16,16); + +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.Reset(); + g_VProfCurrentProfile.ResetPeaks(); + g_VProfCurrentProfile.Start(); +#endif + +#if TEST_BBOX + Vector mins, maxs; + physcollision->CollideGetAABB( &mins, &maxs, pCollide, Vector(-500, 200, -100), vec3_angle ); + Vector extents = maxs - mins; + Vector center = 0.5f * (maxs+mins); + Msg("bbox: %.2f,%.2f, %.2f @ %.2f, %.2f, %.2f\n", extents.x, extents.y, extents.z, center.x, center.y, center.z ); +#endif + unsigned int hitCount = 0; + double startTime = Plat_FloatTime(); + trace_t tr; + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr ); + if ( tr.DidHit() ) + { + g_Traces[i].end = tr.endpos; + g_Traces[i].normal = tr.plane.normal; + g_Traces[i].hit = true; + hitCount++; + } + else + { + g_Traces[i].hit = false; + } + } + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr ); + } + duration = Plat_FloatTime() - startTime; + +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.MarkFrame(); + g_VProfCurrentProfile.Stop(); + g_VProfCurrentProfile.Reset(); + g_VProfCurrentProfile.ResetPeaks(); + g_VProfCurrentProfile.Start(); +#endif + hitCount = 0; + startTime = Plat_FloatTime(); + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[0], size[0], pCollide, vec3_origin, vec3_angle, &tr ); + if ( tr.DidHit() ) + { + g_Traces[i].end = tr.endpos; + g_Traces[i].normal = tr.plane.normal; + g_Traces[i].hit = true; + hitCount++; + } + else + { + g_Traces[i].hit = false; + } +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.MarkFrame(); +#endif + } + double midTime = Plat_FloatTime(); + for ( i = 0; i < NUM_COLLISION_TESTS; i++ ) + { + physcollision->TraceBox( g_Traces[i].start, start, -size[1], size[1], pCollide, vec3_origin, vec3_angle, &tr ); +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.MarkFrame(); +#endif + } + double endTime = Plat_FloatTime(); + duration = endTime - startTime; + pOut->collisionTests = NUM_COLLISION_TESTS; + pOut->collisionHits = hitCount; + pOut->totalTime = duration * 1000.0f; + pOut->rayTime = (midTime - startTime) * 1000.0f; + pOut->boxTime = (endTime - midTime)*1000.0f; + +#if VPROF_LEVEL > 0 + g_VProfCurrentProfile.Stop(); + g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL ); +#endif +} + +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + + +//----------------------------------------------------------------------------- +// The application object +//----------------------------------------------------------------------------- +class CBenchmarkApp : public CDefaultAppSystemGroup< CSteamAppSystemGroup > +{ + typedef CDefaultAppSystemGroup< CSteamAppSystemGroup > BaseClass; + +public: + // Methods of IApplication + virtual bool Create(); + virtual bool PreInit( ); + virtual int Main(); + virtual void PostShutdown(); + bool SetupSearchPaths(); + +private: + bool ParseArguments(); +}; + +DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT( CBenchmarkApp ); + + +//----------------------------------------------------------------------------- +// The application object +//----------------------------------------------------------------------------- +bool CBenchmarkApp::Create() +{ + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false ); + + // Add in the cvar factory + //AppModule_t cvarModule = LoadModule( VStdLib_GetICVarFactory() ); + //AddSystem( cvarModule, VENGINE_CVAR_INTERFACE_VERSION ); + + AppSystemInfo_t appSystems[] = + { + { "vphysics.dll", VPHYSICS_INTERFACE_VERSION }, + { "", "" } // Required to terminate the list + }; + + bool bRet = AddSystems( appSystems ); + if ( bRet ) + { + physcollision = (IPhysicsCollision*)FindSystem( VPHYSICS_COLLISION_INTERFACE_VERSION ); + if ( !physcollision ) + return false; + } + return bRet; +} + +bool CBenchmarkApp::SetupSearchPaths() +{ + CFSSteamSetupInfo steamInfo; + steamInfo.m_pDirectoryName = NULL; + steamInfo.m_bOnlyUseDirectoryName = false; + steamInfo.m_bToolsMode = true; + steamInfo.m_bSetSteamDLLPath = true; + steamInfo.m_bSteam = g_pFullFileSystem->IsSteam(); + + if ( FileSystem_SetupSteamEnvironment( steamInfo ) != FS_OK ) + return false; + + CFSMountContentInfo fsInfo; + fsInfo.m_pFileSystem = g_pFullFileSystem; + fsInfo.m_bToolsMode = true; + fsInfo.m_pDirectoryName = steamInfo.m_GameInfoPath; + + if ( FileSystem_MountContent( fsInfo ) != FS_OK ) + return false; + + // Finally, load the search paths for the "GAME" path. + CFSSearchPathsInit searchPathsInit; + searchPathsInit.m_pDirectoryName = steamInfo.m_GameInfoPath; + searchPathsInit.m_pFileSystem = g_pFullFileSystem; + if ( FileSystem_LoadSearchPaths( searchPathsInit ) != FS_OK ) + return false; + + g_pFullFileSystem->AddSearchPath( steamInfo.m_GameInfoPath, "SKIN", PATH_ADD_TO_HEAD ); + + FileSystem_AddSearchPath_Platform( g_pFullFileSystem, steamInfo.m_GameInfoPath ); + + return true; +} + +bool CBenchmarkApp::PreInit( ) +{ + CreateInterfaceFn factory = GetFactory(); + ConnectTier1Libraries( &factory, 1 ); + ConnectTier2Libraries( &factory, 1 ); + ConnectTier3Libraries( &factory, 1 ); + + if ( !g_pFullFileSystem || !physcollision ) + { + Warning( "benchmark is missing a required interface!\n" ); + return false; + } + + return SetupSearchPaths();//( NULL, false, true ); +} + + +void CBenchmarkApp::PostShutdown() +{ + DisconnectTier3Libraries(); + DisconnectTier2Libraries(); + DisconnectTier1Libraries(); +} + +struct baseline_t +{ + float total; + float ray; + float box; +}; + +// current baseline measured on Core2DuoE6600 +baseline_t g_Baselines[] = +{ + { 40.56f, 10.64f, 29.92f}, // bench01a.phy + { 38.13f, 10.76f, 27.37f }, // bicycle01a.phy + { 25.46f, 8.34f, 17.13f }, // furnituretable001a.phy + { 12.65f, 6.02f, 6.62f }, // gravestone003a.phy + { 40.58f, 16.49f, 24.10f }, // combineinnerwall001a.phy +}; + +const float g_TotalBaseline = 157.38f; + +/* +Benchmark models\props_c17\bench01a.phy! + +33.90 ms [1.20 X] 2500/2500 hits +8.95 ms rays [1.19 X] 24.95 ms boxes [1.20 X] +Benchmark models\props_junk\bicycle01a.phy! + +30.55 ms [1.25 X] 803/2500 hits +8.96 ms rays [1.20 X] 21.59 ms boxes [1.27 X] +Benchmark models\props_c17\furnituretable001a.phy! + +20.61 ms [1.24 X] 755/2500 hits +6.88 ms rays [1.21 X] 13.73 ms boxes [1.25 X] +Benchmark models\props_c17\gravestone003a.phy! + +9.13 ms [1.39 X] 2500/2500 hits +4.34 ms rays [1.39 X] 4.79 ms boxes [1.38 X] +Benchmark models\props_combine\combineinnerwall001a.phy! + +33.04 ms [1.23 X] 985/2500 hits +13.37 ms rays [1.23 X] 19.67 ms boxes [1.23 X] + +127.22s total [1.24 X]! +*/ + +#define IMPROVEMENT_FACTOR(x,baseline) (baseline/(x)) +#define IMPROVEMENT_PERCENT(x,baseline) (((baseline-(x)) / baseline) * 100.0f) +#include <windows.h> +//----------------------------------------------------------------------------- +// The application object +//----------------------------------------------------------------------------- +int CBenchmarkApp::Main() +{ + const char *pFileNames[] = + { + "models\\props_c17\\bench01a.phy", + "models\\props_junk\\bicycle01a.phy", + "models\\props_c17\\furnituretable001a.phy", + "models\\props_c17\\gravestone003a.phy", + "models\\props_combine\\combineinnerwall001a.phy", + }; + vcollide_t testModels[ARRAYSIZE(pFileNames)]; + for ( int i = 0; i < ARRAYSIZE(pFileNames); i++ ) + { + ReadPHYFile( pFileNames[i], testModels[i] ); + } + SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); + SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST ); + float totalTime = 0.0f; + int loopCount = ARRAYSIZE(pFileNames); +#if VPROF_LEVEL > 0 +// loopCount = 3; +#endif + for ( int i = 0; i < loopCount; i++ ) + { + if ( testModels[i].solidCount < 1 ) + { + Msg("Failed to load %s, skipping test!\n", pFileNames[i] ); + continue; + } + Msg("Benchmark %s!\n\n", pFileNames[i] ); + + benchresults_t results; + memset( &results, 0, sizeof(results)); + int numRepeats = 3; +#if VPROF_LEVEL > 0 + numRepeats = 1; +#endif + for ( int j = 0; j < numRepeats; j++ ) + { + Benchmark_PHY( testModels[i].solids[0], &results ); + } + Msg("%.2f ms [%.2f X] %d/%d hits\n", results.totalTime, IMPROVEMENT_FACTOR(results.totalTime, g_Baselines[i].total), results.collisionHits, results.collisionTests); + Msg("%.2f ms rays \t[%.2f X] \t%.2f ms boxes [%.2f X]\n", + results.rayTime, IMPROVEMENT_FACTOR(results.rayTime, g_Baselines[i].ray), + results.boxTime, IMPROVEMENT_FACTOR(results.boxTime, g_Baselines[i].box)); + totalTime += results.totalTime; + } + SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS ); + + Msg("\n%.2fs total \t[%.2f X]!\n", totalTime, IMPROVEMENT_FACTOR(totalTime, g_TotalBaseline) ); + return 0; +} + + + |