Skip to content

Commit

Permalink
Refactor: Common BVH class + its memory is now owned by an Array
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-van-bergen committed Jan 11, 2022
1 parent 9138920 commit 601be4d
Show file tree
Hide file tree
Showing 27 changed files with 476 additions and 480 deletions.
1 change: 0 additions & 1 deletion Pathtracer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@
<ClCompile Include="Src\Math\Mipmap.cpp" />
<ClCompile Include="Src\Pathtracer\Camera.cpp" />
<ClCompile Include="Src\Pathtracer\Mesh.cpp" />
<ClCompile Include="Src\Pathtracer\MeshData.cpp" />
<ClCompile Include="Src\Pathtracer\Pathtracer.cpp" />
<ClCompile Include="Src\Pathtracer\Scene.cpp" />
<ClCompile Include="Src\Pathtracer\Sky.cpp" />
Expand Down
3 changes: 0 additions & 3 deletions Pathtracer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,6 @@
<ClCompile Include="Src\Pathtracer\Texture.cpp">
<Filter>Pathtracer</Filter>
</ClCompile>
<ClCompile Include="Src\Pathtracer\MeshData.cpp">
<Filter>Pathtracer</Filter>
</ClCompile>
<ClCompile Include="Src\Device\CUDAMemory.cpp">
<Filter>Device</Filter>
</ClCompile>
Expand Down
10 changes: 5 additions & 5 deletions Src/Assets/AssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
#include "Util/ScopeTimer.h"
#include "Util/ThreadPool.h"

BVH AssetManager::build_bvh(const Array<Triangle> & triangles) {
BVH2 AssetManager::build_bvh(const Array<Triangle> & triangles) {
IO::print("Constructing BVH...\r"sv);
BVH bvh;
BVH2 bvh;

// Only the SBVH uses SBVH as its starting point,
// all other BVH types use the standard BVH as their starting point
Expand Down Expand Up @@ -70,11 +70,11 @@ MeshDataHandle AssetManager::add_mesh_data(const MeshData & mesh_data) {
}

MeshDataHandle AssetManager::add_mesh_data(Array<Triangle> triangles) {
BVH bvh = build_bvh(triangles);
BVH2 bvh = build_bvh(triangles);

MeshData mesh_data = { };
mesh_data.triangles = std::move(triangles);
mesh_data.init_bvh(bvh);
mesh_data.bvh = BVH::create_from_bvh2(std::move(bvh));

return add_mesh_data(mesh_data);
}
Expand Down Expand Up @@ -138,7 +138,7 @@ TextureHandle AssetManager::add_texture(const String & filename) {
}

textures_mutex.lock();
textures[texture_id.handle] = texture;
textures[texture_id.handle] = std::move(texture);
textures_mutex.unlock();
});

Expand Down
6 changes: 3 additions & 3 deletions Src/Assets/AssetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct AssetManager {

bool assets_loaded = false;

BVH build_bvh(const Array<Triangle> & triangles);
BVH2 build_bvh(const Array<Triangle> & triangles);

public:
void init();
Expand All @@ -50,7 +50,7 @@ struct AssetManager {

if (mesh_data_handle.handle != INVALID) return mesh_data_handle;

BVH bvh = { };
BVH2 bvh = { };
MeshData mesh_data = { };

bool bvh_loaded = BVHLoader::try_to_load(filename, bvh_filename, mesh_data, bvh);
Expand All @@ -69,7 +69,7 @@ struct AssetManager {
BVHCollapser::collapse(bvh);
}

mesh_data.init_bvh(bvh);
mesh_data.bvh = BVH::create_from_bvh2(std::move(bvh));

mesh_data_handle.handle = mesh_datas.size();
mesh_datas.push_back(mesh_data);
Expand Down
29 changes: 13 additions & 16 deletions Src/Assets/BVHLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct BVHFileHeader {
int num_indices;
};

bool BVHLoader::try_to_load(const String & filename, const String & bvh_filename, MeshData & mesh_data, BVH & bvh) {
bool BVHLoader::try_to_load(const String & filename, const String & bvh_filename, MeshData & mesh_data, BVH2 & bvh) {
if (config.bvh_force_rebuild || !IO::file_exists(bvh_filename.view()) || IO::file_is_newer(bvh_filename.view(), filename.view())) {
return false;
}
Expand Down Expand Up @@ -56,24 +56,21 @@ bool BVHLoader::try_to_load(const String & filename, const String & bvh_filename
return false;
}

bvh.node_count = header.num_nodes;
bvh.index_count = header.num_indices;

mesh_data.triangles.resize(header.num_triangles);
bvh.nodes._2 = new BVHNode2[bvh.node_count];
bvh.indices = new int [bvh.index_count];
bvh.nodes .resize(header.num_nodes);
bvh.indices .resize(header.num_indices);

for (int i = 0; i < mesh_data.triangles.size(); i++) mesh_data.triangles[i] = parser.parse_binary<Triangle>();
for (int i = 0; i < bvh.node_count; i++) bvh.nodes._2 [i] = parser.parse_binary<BVHNode2>();
for (int i = 0; i < bvh.index_count; i++) bvh.indices [i] = parser.parse_binary<int>();
for (int i = 0; i < bvh.nodes .size(); i++) bvh.nodes [i] = parser.parse_binary<BVHNode2>();
for (int i = 0; i < bvh.indices.size(); i++) bvh.indices[i] = parser.parse_binary<int>();

ASSERT(parser.reached_end());

IO::print("Loaded BVH '{}' from disk\n"sv, bvh_filename);
return true;
}

bool BVHLoader::save(const String & bvh_filename, const MeshData & mesh_data, const BVH & bvh) {
bool BVHLoader::save(const String & bvh_filename, const MeshData & mesh_data, const BVH2 & bvh) {
FILE * file = nullptr;
fopen_s(&file, bvh_filename.data(), "wb");

Expand All @@ -95,18 +92,18 @@ bool BVHLoader::save(const String & bvh_filename, const MeshData & mesh_data, co
header.sah_cost_leaf = config.sah_cost_leaf;

header.num_triangles = mesh_data.triangles.size();
header.num_nodes = bvh.node_count;
header.num_indices = bvh.index_count;
header.num_nodes = bvh.nodes .size();
header.num_indices = bvh.indices.size();

size_t header_written = fwrite(reinterpret_cast<const char *>(&header), sizeof(header), 1, file);
size_t header_written = fwrite(&header, sizeof(header), 1, file);

size_t num_triangles_written = fwrite(reinterpret_cast<const char *>(mesh_data.triangles.data()), sizeof(Triangle), mesh_data.triangles.size(), file);
size_t num_bvh_nodes_written = fwrite(reinterpret_cast<const char *>(bvh.nodes._2), sizeof(BVHNode2), bvh.node_count, file);
size_t num_indices_written = fwrite(reinterpret_cast<const char *>(bvh.indices), sizeof(int), bvh.index_count, file);
size_t num_triangles_written = fwrite(mesh_data.triangles.data(), sizeof(Triangle), mesh_data.triangles.size(), file);
size_t num_bvh_nodes_written = fwrite(bvh.nodes .data(), sizeof(BVHNode2), bvh.nodes .size(), file);
size_t num_indices_written = fwrite(bvh.indices.data(), sizeof(int), bvh.indices.size(), file);

fclose(file);

if (!header_written || num_triangles_written < mesh_data.triangles.size() || num_bvh_nodes_written < bvh.node_count || num_indices_written < bvh.index_count) {
if (!header_written || num_triangles_written < mesh_data.triangles.size() || num_bvh_nodes_written < bvh.nodes.size() || num_indices_written < bvh.indices.size()) {
IO::print("WARNING: Unable to successfully write to BVH file '{}'!\n"sv, bvh_filename);
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions Src/Assets/BVHLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ namespace BVHLoader {

String get_bvh_filename(StringView filename);

bool try_to_load(const String & filename, const String & bvh_filename, MeshData & mesh_data, BVH & bvh);
bool save(const String & bvh_filename, const MeshData & mesh_data, const BVH & bvh);
bool try_to_load(const String & filename, const String & bvh_filename, MeshData & mesh_data, BVH2 & bvh);
bool save(const String & bvh_filename, const MeshData & mesh_data, const BVH2 & bvh);
}
101 changes: 64 additions & 37 deletions Src/BVH/BVH.cpp
Original file line number Diff line number Diff line change
@@ -1,52 +1,79 @@
#include "BVH.h"

void BVH::aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const {
#include "BVH/Builders/QBVHBuilder.h"
#include "BVH/Builders/CWBVHBuilder.h"

BVH * BVH::create_from_bvh2(BVH2 bvh) {
switch (config.bvh_type) {
case BVHType::BVH:
case BVHType::SBVH: {
BVHNode2 * dst = aggregated_bvh_nodes._2 + bvh_offset;

for (int n = 0; n < node_count; n++) {
BVHNode2 & node = dst[n];
node = nodes._2[n];

if (node.is_leaf()) {
node.first += index_offset;
} else {
node.left += bvh_offset;
}
}
break;
return new BVH2(std::move(bvh));
}
case BVHType::QBVH: {
BVHNode4 * dst = aggregated_bvh_nodes._4 + bvh_offset;

for (int n = 0; n < node_count; n++) {
BVHNode4 & node = dst[n];
node = nodes._4[n];

int child_count = node.get_child_count();
for (int c = 0; c < child_count; c++) {
if (node.is_leaf(c)) {
node.get_index(c) += index_offset;
} else {
node.get_index(c) += bvh_offset;
}
}
}
break;
BVH4 * bvh4 = new BVH4();

// Collapse binary BVH into quaternary BVH
QBVHBuilder qbvh_builder = { };
qbvh_builder.init(bvh4, std::move(bvh));
qbvh_builder.build(bvh);

return bvh4;
}
case BVHType::CWBVH: {
BVHNode8 * dst = aggregated_bvh_nodes._8 + bvh_offset;
BVH8 * bvh8 = new BVH8();

// Collapse binary BVH into 8-way Compressed Wide BVH
CWBVHBuilder cwbvh_builder = { };
cwbvh_builder.init(bvh8, std::move(bvh));
cwbvh_builder.build(bvh);

return bvh8;
}
default: abort();
}
}

for (int n = 0; n < node_count; n++) {
BVHNode8 & node = dst[n];
node = nodes._8[n];
void BVH2::aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const {
BVHNode2 * dst = aggregated_bvh_nodes._2 + bvh_offset;

node.base_index_triangle += index_offset;
node.base_index_child += bvh_offset;
for (size_t n = 0; n < nodes.size(); n++) {
BVHNode2 & node = dst[n];
node = nodes[n];

if (node.is_leaf()) {
node.first += index_offset;
} else {
node.left += bvh_offset;
}
}
}

void BVH4::aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const {
BVHNode4 * dst = aggregated_bvh_nodes._4 + bvh_offset;

for (int n = 0; n < nodes.size(); n++) {
BVHNode4 & node = dst[n];
node = nodes[n];

int child_count = node.get_child_count();
for (int c = 0; c < child_count; c++) {
if (node.is_leaf(c)) {
node.get_index(c) += index_offset;
} else {
node.get_index(c) += bvh_offset;
}
break;
}
}
}

void BVH8::aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const {
BVHNode8 * dst = aggregated_bvh_nodes._8 + bvh_offset;

for (int n = 0; n < nodes.size(); n++) {
BVHNode8 & node = dst[n];
node = nodes[n];

node.base_index_triangle += index_offset;
node.base_index_child += bvh_offset;
}
}
50 changes: 44 additions & 6 deletions Src/BVH/BVH.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#pragma once
#include <stdlib.h>
#include <variant>

#include "Config.h"

#include "Pathtracer/Triangle.h"

#include "Util/Array.h"

typedef unsigned char byte;

struct BVHNode2 {
Expand Down Expand Up @@ -84,18 +87,29 @@ union BVHNodePtr {
BVHNode8 * _8;
};

struct BVH2;

struct BVH {
int index_count;
int * indices;
Array<int> indices;

//BVH() = default;

//BVH(const BVH & bvh) = delete;
//BVH & operator=(const BVH & bvh) = delete;

//BVH(BVH && bvh) = default;
//BVH & operator=(BVH && bvh) = default;

int node_count;
BVHNodePtr nodes;
//virtual ~BVH() = default;

// Each individual BVH needs to put its Nodes in a shared aggregated array of BVH Nodes before being upload to the GPU
// The procedure to do this is different for each BVH type
void aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const;
virtual void aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const = 0;

virtual size_t node_count() const = 0;

static BVH * create_from_bvh2(BVH2 bvh);

// Helper Methods
static BVHType underlying_bvh_type() {
// All BVH use standard BVH as underlying type, only SBVH uses SBVH
if (config.bvh_type == BVHType::SBVH) {
Expand All @@ -105,3 +119,27 @@ struct BVH {
}
}
};

struct BVH2 final : BVH {
Array<BVHNode2> nodes;

void aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const override;

size_t node_count() const override { return nodes.size(); }
};

struct BVH4 final : BVH {
Array<BVHNode4> nodes;

void aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const override;

size_t node_count() const override{ return nodes.size(); }
};

struct BVH8 final : BVH {
Array<BVHNode8> nodes;

void aggregate(BVHNodePtr aggregated_bvh_nodes, int index_offset, int bvh_offset) const override;

size_t node_count() const override { return nodes.size(); }
};
Loading

0 comments on commit 601be4d

Please sign in to comment.