Files
CDAG/OctreeBuilder/main.cpp

282 lines
9.0 KiB
C++

#include <iostream>
#include "../Research/core/OctreeBuilder/OctreeBuilder.h"
#include "../Research/core/OctreeBuilder/OctreeLoader.h"
#include "../Research/core/OctreeBuilder/OctreeConverter.h"
#include "../Research/PropertyLoader.h"
#include "../Research/scene/Octree/BaseTree.h"
#include "../Research/core/Util/Stopwatch.h"
#include <fstream>
#ifdef _WIN32
#include <windows.h>
//#ifdef _DEBUG
//#include <vld.h>
//#endif
// Make sure NVidia GPU is used on laptops with Nvidia optimus
extern "C" {
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
#endif
int main() {
// Create the nodepool (OctreeBuilder will use it automatically when available)
//NodePoolSingleton::Create();
PropertyLoader::Create();
PropertyLoader* propertyLoader = PropertyLoader::Instance();
unsigned startLevel = propertyLoader->GetIntProperty("start_level");
unsigned endLevel = propertyLoader->GetIntProperty("end_level");
bool useCache = propertyLoader->GetBoolProperty("octreebuilder_usecache");
bool tryConvert = propertyLoader->GetBoolProperty("octreebuilder_tryconvert");
bool onlyCache = propertyLoader->GetBoolProperty("octreebuilder_onlycache");
bool writeStats = propertyLoader->GetBoolProperty("octreebuilder_writestats");
//std::vector<OctreeBuilderStatistics> stats;
std::string csvFilename = propertyLoader->GetProperty("stats_file");
csvFilename.append("_stats.csv");
std::vector<std::string> types = propertyLoader->GetListProperty("tree_type");
std::vector<std::string> poolTypes = propertyLoader->GetListProperty("pool_type");
std::vector<std::string> sceneFilenames = propertyLoader->GetListProperty("scene_file");
std::vector<std::string> dagFilenames = propertyLoader->GetListProperty("dag_file");
assert(dagFilenames.size() == sceneFilenames.size());
std::vector<std::pair<std::string, std::string>> scenes(dagFilenames.size());
for (size_t i = 0; i < dagFilenames.size(); i++)
scenes[i] = std::make_pair(sceneFilenames[i], dagFilenames[i]);
// std::string csvFilename = propertyLoader->GetProperty("dag_file");
// csvFilename.append("_stats.csv");
// std::vector<std::string> types = {
// //"s",
// //"c",
// //"m1",
// //"m2",
// //"m3",
// //"m4",
// //"m5",
// //"m6",
// //"m7",
// //"m8",
// //"mcc"
// //"m8b2",
// //"m8b4",
// //"m7b2",
// //"m7b3",
// //"c32",
// //"c64",
// //"c128",
// //"c256",
// //"c512",
// //"c1024",
// //"c2048",
// //"hc"
// //"hcde2.7",
// //"hcde5.4",
// //"hclab1024",
// //"hclab512",
// //"u4c",
// //"u8c",
// //"u16c",
// //"u32c",
// //"u4cde2.7",
// //"u8cde2.7",
// //"u16cde2.7",
// //"u32cde2.7",
// //"u4cde1.3",
// //"u8cde1.3",
// //"u16cde1.3",
// //"u32cde1.3",
// //"utcde2.7",
// //"utcde1.3".
// //"blc",
// //"clab4096",
// //"hclab4096",
// //"upc",
// "hc",
//// "upclab256",
// //"hclab256",
//// "upclab1024",
// //"hclab1024",
//// "upclab4096",
// //"hclab4096",
// };
//
// std::vector<std::string> poolTypes = {
// "s",
// //"o",
// //"al",
// };
//
// std::vector<std::pair<std::string, std::string>> scenes =
// {
//// std::make_pair("../Research/data/arena.ply", "../Research/data/arena"),
//// std::make_pair("../Research/data/city.obj", "../Research/data/city"),
//// std::make_pair("../Research/data/EpicCitadel/EpicCitadel.obj", "../Research/data/citadel"),
//// std::make_pair("../Research/data/SanMiguel/san-miguel.obj", "../Research/data/sanmiguel"),
// std::make_pair("../Research/data/statue.ply", "../Research/data/statue"),
// //std::make_pair("../Research/data/Sponza/sponza.obj", "../Research/data/sponza"),
// };
// std::vector<unsigned8> maxDepthPerScene =
// {
// 17, 17, 17, 17, 17, 17
// //17, 15,/* 14, 12,*/ 15
// };
std::ofstream output;
output.open(csvFilename);
output << "scene,type,pooltype,levels,buildTime,octreenodes,dagNodes,pointerCount,compression,gpuMemory,gpuMemoryMB,mainTreeGpuMemory,mainTreeGpuMemoryMB,additionalGpuMemory,additionalGpuMemoryMB,";
for (unsigned lvl = 0; lvl <= endLevel; lvl++)
output << "octreeNodesLevel" << lvl << ",";
for (unsigned lvl = 0; lvl <= endLevel; lvl++)
{
output << "dagNodesLevel" << lvl;
if (lvl < endLevel) output << ",";
else output << "\n";
}
bool builderCreated = false;
struct BuildOption
{
std::string type;
unsigned8 level;
std::string sceneFile;
std::string dagFile;
std::string sceneName;
};
std::vector<BuildOption> failed;
for (unsigned8 level = startLevel; level <= endLevel; level++)
{
for (auto type : types)
{
for (size_t sceneId = 0; sceneId < scenes.size(); sceneId++)
{
for (size_t count = 0; count < 1; count++) {
auto scene = scenes[sceneId];
std::string sceneName = scene.second;
const size_t last_slash_idx = sceneName.find_last_of("\\/");
if (std::string::npos != last_slash_idx) {
sceneName.erase(0, last_slash_idx + 1);
}
printf("Building scene %s, type %s up to %u levels\n", sceneName.c_str(), type.c_str(), level);
OctreeBuilderStatistics stat(level);
bool cacheVerified = false;
bool justBuild = false;
if (!onlyCache)
{
if (useCache)
cacheVerified = OctreeLoader::VerifyCache(type, level, scene.second);
if (!cacheVerified && useCache && tryConvert)
cacheVerified = OctreeConverter::ConvertTo(type, level, scene.second, true);
if (!useCache || !cacheVerified) {
if (!builderCreated) {
OctreeBuilder::Create();
builderCreated = true;
}
OctreeBuilder::SetTreeType(type);
stat = OctreeBuilder::BuildOctree(level, scene.first, scene.second);
justBuild = true;
}
}
// Verify the tree is build correctly (and saved)
if (!cacheVerified) cacheVerified = OctreeLoader::VerifyCache(type, level, scene.second);
// If the file is valid and we're instructed to build pools, build the pool and write stats
if (cacheVerified) {
if (writeStats)
{
//{
// unsigned poolSize, materialTextureSize, materialNodePoolTextureSize, blockPointerPoolSize, blockPoolSize;
// unsigned8 blockPointerPoolChannelsPerPixel, blockPoolChannelsPerPixel;
// std::vector<unsigned32> blockPointerPool;
// std::vector<unsigned8> nodePool, materialNodePool;
// std::vector<unsigned char> materialTexture, blockPool;
// std::map<std::string, std::string> additionalProperties;
// OctreeLoader::GetPool(type, level, scene.second, false, nodePool, poolSize, materialTexture, materialTextureSize, materialNodePool, materialNodePoolTextureSize, blockPointerPool, blockPointerPoolSize, blockPointerPoolChannelsPerPixel, blockPool, blockPoolSize, blockPoolChannelsPerPixel, additionalProperties, true);
//}
BaseTree *tree = OctreeLoader::ReadCache(type, level, scene.second, false);
size_t pointerCount = tree->GetPointerCount();
for (std::string poolType : poolTypes) {
double mbDivider = 1. / ((double)1024 * 1024);
size_t gpuMem = OctreeLoader::GetGPUMemoryRequirements(type, poolType, tree);
double gpuMemMB = (double)(gpuMem) * mbDivider;
size_t mainTreeGpuMem = OctreeLoader::GetMainTreeGPUMemoryRequirements(type, poolType, tree);
double mainTreeGpuMemMB = ((double)mainTreeGpuMem) * mbDivider;
size_t additionalGpuMem = gpuMem - mainTreeGpuMem;
double additionalGpuMemMB = ((double)additionalGpuMem) * mbDivider;
if (useCache && !justBuild) {
stat.type = type;
stat.octreeNodesPerLevel = tree->GetOctreeNodesPerLevel();
stat.dagNodesPerLevel = tree->GetNodesPerLevel();
}
// Write the stats to a CSV file
output << sceneName << "," << stat.type << "," << poolType << "," << (size_t)level <<
"," << stat.totalTime << "," << stat.GetOctreeNodeCount() <<
"," << stat.GetDAGNodeCount() << "," << pointerCount << "," << stat.GetCompression() << "," << gpuMem << "," <<
gpuMemMB << "," << mainTreeGpuMem << "," << mainTreeGpuMemMB << "," << additionalGpuMem << "," << additionalGpuMemMB << ",";
for (unsigned lvl = 0; lvl <= endLevel; lvl++) {
if (lvl <= level) output << stat.octreeNodesPerLevel[lvl];
else output << "0";
output << ",";
}
for (unsigned lvl = 0; lvl <= endLevel; lvl++) {
if (lvl < level) output << stat.dagNodesPerLevel[lvl];
else output << "0";
if (lvl < endLevel) output << ",";
else output << "\n";
}
}
delete tree;
}
}
else
{
printf("Failed...\n");
BuildOption f;
f.type = type;
f.level = level;
f.sceneFile = scene.first;
f.dagFile = scene.second;
f.sceneName = sceneName;
failed.push_back(f);
}
output.flush();
}
}
}
}
output.close();
if (!useCache)
OctreeBuilder::Destroy();
if (!failed.empty())
{
printf("Construction failed for the following options:\n");
for (BuildOption f : failed)
printf(" - %s, type %s, %u levels\n", f.sceneName.c_str(), f.type.c_str(), f.level);
}
//NodePoolSingleton::Destroy();
#ifdef _WIN32
system("pause");
#endif
return 0;
}