Skip to content

Commit

Permalink
Speedtest now uses Crytek Sponza.
Browse files Browse the repository at this point in the history
  • Loading branch information
jbikker committed Nov 15, 2024
1 parent a8d1536 commit 5456c45
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 51 deletions.
13 changes: 6 additions & 7 deletions tiny_bvh.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ THE SOFTWARE.
#define BVHBINS 8

// SAH BVH building: Heuristic parameters
// CPU builds: C_INT = 1, C_TRAV = 0.001 seems optimal.
// CPU builds: C_INT = 1, C_TRAV = 0.01 seems optimal.
#define C_INT 1
#define C_TRAV 0.001f
#define C_TRAV 0.01f

// include fast AVX BVH builder
#if defined(__x86_64__) || defined(_M_X64) || defined(__wasm_simd128__) || defined(__wasm_relaxed_simd__)
Expand Down Expand Up @@ -1080,7 +1080,7 @@ void BVH::Convert( BVHLayout from, BVHLayout to, const bool deleteOriginal )
else if (from == WALD_32BYTE && to == VERBOSE)
{
// allocate space
unsigned spaceNeeded = triCount * 2; // this one needs space to grow to 2N
unsigned spaceNeeded = triCount * (refittable ? 2 : 3); // this one needs space to grow to 2N
if (allocatedVerbose < spaceNeeded)
{
ALIGNED_FREE( verbose );
Expand Down Expand Up @@ -2495,14 +2495,13 @@ void BVH::BuildAVX( const bvhvec4* vertices, const unsigned primCount )
for (unsigned i = 0; i < node.triCount - 1; i++)
{
unsigned fid = *ti++;
#if defined __GNUC__ || _MSC_VER < 1920
if (fid > triCount) fid = triCount - 1; // never happens but g++ *and* vs2017 need this to not crash...
#endif
const __m256 b0 = binbox[i0], b1 = binbox[BVHBINS + i1], b2 = binbox[2 * BVHBINS + i2];
const __m128 fmin = frag4[fid].bmin4, fmax = frag4[fid].bmax4;
r0 = _mm256_max_ps( b0, f ), r1 = _mm256_max_ps( b1, f ), r2 = _mm256_max_ps( b2, f );
const __m128i b4 = _mm_cvtps_epi32( _mm_sub_ps( _mm_mul_ps( _mm_sub_ps( _mm_sub_ps( fmax, fmin ), nmin4 ), rpd4 ), half4 ) );
#if _MSC_VER < 1920
// VS2017 needs a random check on fid to produce correct code... The condition is never true.
if (fid > triCount) fid = triCount - 1;
#endif
f = frag8[fid], count[0][i0]++, count[1][i1]++, count[2][i2]++;
binbox[i0] = r0, i0 = ILANE( b4, 0 );
binbox[BVHBINS + i1] = r1, i1 = ILANE( b4, 1 );
Expand Down
27 changes: 18 additions & 9 deletions tiny_bvh_fenster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ BVH bvh;
#endif

#ifdef LOADSPONZA
bvhvec4* triangles;
bvhvec4* triangles = 0;
#include <fstream>
#else
bvhvec4 triangles[259 /* level 3 */ * 6 * 2 * 49 * 3]{};
ALIGNED( 16 ) bvhvec4 triangles[259 /* level 3 */ * 6 * 2 * 49 * 3]{};
#endif
int verts = 0;

Expand Down Expand Up @@ -52,12 +53,20 @@ void Init()
{
#ifdef LOADSPONZA
// load raw vertex data for Crytek's Sponza
FILE* f;
fopen_s( &f, "../testdata/cryteksponza.bin", "rb" );
fread( &verts, 1, 4, f );
verts *= 3, triangles = new bvhvec4[verts];
fread( triangles, sizeof( bvhvec4 ), verts, f );
fclose( f );
std::string filename{ "../testdata/cryteksponza.bin" };
std::fstream s{ filename, s.binary | s.in };
if (!s.is_open())
{
// try again, look in .\testdata
std::string filename{ "./testdata/cryteksponza.bin" };
s = std::fstream{ filename, s.binary | s.in };
assert( s.is_open() );
}
s.seekp( 0 );
s.read( (char*)&verts, 4 );
printf( "Loading triangle data (%i tris).\n", verts );
verts *= 3, triangles = (bvhvec4*)ALIGNED_MALLOC( verts * 16 );
s.read( (char*)triangles, verts * 16 );
#else
// generate a sphere flake scene
sphere_flake( 0, 0, 0, 1.5f );
Expand Down Expand Up @@ -87,7 +96,7 @@ void Init()
#if defined(BVH_USEAVX)
bvh.BuildAVX( triangles, verts / 3 );
#elif defined(BVH_USENEON)
bvh.BuildNEON( triangles, verts / 3 );
bvh.BuildNEON( triangles, verts / 3 );
#else
// bvh.Build( triangles, verts / 3 );
#endif
Expand Down
101 changes: 66 additions & 35 deletions tiny_bvh_speedtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,32 @@
#define SCRWIDTH 800
#define SCRHEIGHT 600

// scene selection
#define LOADSPONZA

// tests to perform
// #define BUILD_REFERENCE
#define BUILD_REFERENCE
#define BUILD_AVX
#define BUILD_NEON
// #define BUILD_SBVH
#define BUILD_SBVH
#define TRAVERSE_2WAY_ST
#define TRAVERSE_ALT2WAY_ST
#define TRAVERSE_SOA2WAY_ST
// #define TRAVERSE_2WAY_MT
// #define TRAVERSE_2WAY_MT_PACKET
// #define TRAVERSE_2WAY_MT_DIVERGENT
// #define TRAVERSE_OPTIMIZED_ST
#define TRAVERSE_2WAY_MT
#define TRAVERSE_2WAY_MT_PACKET
#define TRAVERSE_2WAY_MT_DIVERGENT
#define TRAVERSE_OPTIMIZED_ST
// #define EMBREE_BUILD // win64-only for now.
// #define EMBREE_TRAVERSE // win64-only for now.

using namespace tinybvh;

bvhvec4 triangles[259 /* level 3 */ * 6 * 2 * 49 * 3]{};
#ifdef LOADSPONZA
bvhvec4* triangles = 0;
#include <fstream>
#else
ALIGNED( 16 ) bvhvec4 triangles[259 /* level 3 */ * 6 * 2 * 49 * 3]{};
#endif
int verts = 0;
BVH bvh;

Expand Down Expand Up @@ -87,12 +95,62 @@ void sphere_flake( float x, float y, float z, float s, int d = 0 )

int main()
{
int minor = TINY_BVH_VERSION_MINOR;
int major = TINY_BVH_VERSION_MAJOR;
int sub = TINY_BVH_VERSION_SUB;
printf( "tiny_bvh version %i.%i.%i performance statistics ", major, minor, sub );

// determine compiler
#ifdef _MSC_VER
printf( "(MSVC %i build)\n", _MSC_VER );
#elif defined __EMSCRIPTEN__
// EMSCRIPTEN needs to be before clang or gcc
printf( "(emcc %i.%i build)\n", __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__ );
#elif defined __clang__
printf( "(clang %i.%i build)\n", __clang_major__, __clang_minor__ );
#elif defined __GNUC__
printf( "(gcc %i.%i build)\n", __GNUC__, __GNUC_MINOR__ );
#else
printf( "\n" );
#endif

// determine what CPU is running the tests.
#ifdef _WIN32
char model[256]{};
for (unsigned i = 0; i < 3; ++i) __cpuidex( (int*)(model + i * 16), i + 0x80000002, 0 );
printf( "running on %s\n", model );
#endif
printf( "----------------------------------------------------------------\n" );

#ifdef LOADSPONZA
// load raw vertex data for Crytek's Sponza
std::string filename{ "../testdata/cryteksponza.bin" };
std::fstream s{ filename, s.binary | s.in };
if (!s.is_open())
{
// try again, look in .\testdata
filename = std::string{ "./testdata/cryteksponza.bin" };
s = std::fstream{ filename, s.binary | s.in };
assert( s.is_open() );
}
s.seekp( 0 );
s.read( (char*)&verts, 4 );
printf( "Loading triangle data (%i tris).\n", verts );
verts *= 3, triangles = (bvhvec4*)ALIGNED_MALLOC( verts * 16 );
s.read( (char*)triangles, verts * 16 );
#else
// generate a sphere flake scene
printf( "Creating sphere flake (%i tris).\n", verts / 3 );
sphere_flake( 0, 0, 0, 1.5f );
#endif

// setup view pyramid for a pinhole camera:
// eye, p1 (top-left), p2 (top-right) and p3 (bottom-left)
#ifdef LOADSPONZA
bvhvec3 eye( 0, 30, 0 ), view = normalize( bvhvec3( -8, 2, -1.7f ) );
#else
bvhvec3 eye( -3.5f, -1.5f, -6.5f ), view = normalize( bvhvec3( 3, 1.5f, 5 ) );
#endif
bvhvec3 right = normalize( cross( bvhvec3( 0, 1, 0 ), view ) );
bvhvec3 up = 0.8f * cross( view, right ), C = eye + 2 * view;
bvhvec3 p1 = C - right + up, p2 = C + right + up, p3 = C - right - up;
Expand All @@ -119,40 +177,13 @@ int main()

// T I N Y _ B V H P E R F O R M A N C E M E A S U R E M E N T S

int minor = TINY_BVH_VERSION_MINOR;
int major = TINY_BVH_VERSION_MAJOR;
int sub = TINY_BVH_VERSION_SUB;
printf( "tiny_bvh version %i.%i.%i performance statistics ", major, minor, sub );

// determine compiler
#ifdef _MSC_VER
printf( "(MSVC %i build)\n", _MSC_VER );
#elif defined __EMSCRIPTEN__
// EMSCRIPTEN needs to be before clang or gcc
printf( "(emcc %i.%i build)\n", __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__ );
#elif defined __clang__
printf( "(clang %i.%i build)\n", __clang_major__, __clang_minor__ );
#elif defined __GNUC__
printf( "(gcc %i.%i build)\n", __GNUC__, __GNUC_MINOR__ );
#else
printf( "\n" );
#endif

// determine what CPU is running the tests.
#ifdef _WIN32
char model[256]{};
for (unsigned i = 0; i < 3; ++i) __cpuidex( (int*)(model + i * 16), i + 0x80000002, 0 );
printf( "running on %s\n", model );
#endif
printf( "----------------------------------------------------------------\n" );

Timer t;
float mrays;

// measure single-core bvh construction time - warming caches
printf( "BVH construction speed\n" );
printf( "warming caches...\n" );
bvh.Build( (bvhvec4*)triangles, verts / 3 );
bvh.Build( triangles, verts / 3 );

#ifdef BUILD_REFERENCE

Expand Down

0 comments on commit 5456c45

Please sign in to comment.