282 lines
9.0 KiB
C++
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;
|
|
} |