diff --git a/hecl/include/hecl/CVarManager.hpp b/hecl/include/hecl/CVarManager.hpp index b0637afcf..2bc0f6e64 100644 --- a/hecl/include/hecl/CVarManager.hpp +++ b/hecl/include/hecl/CVarManager.hpp @@ -12,6 +12,7 @@ class FileStoreManager; extern CVar* com_developer; extern CVar* com_configfile; extern CVar* com_enableCheats; +extern CVar* com_cubemaps; class CVarManager final { using CVarContainer = DNACVAR::CVarContainer; template diff --git a/hecl/include/hecl/Pipeline.hpp b/hecl/include/hecl/Pipeline.hpp index 48c12ee35..c1e99005d 100644 --- a/hecl/include/hecl/Pipeline.hpp +++ b/hecl/include/hecl/Pipeline.hpp @@ -295,8 +295,8 @@ public: template StageTargetTp convert(FactoryCtx& ctx, const FromTp& in) { - if (FromTp::HasHash) { - uint64_t hash = in.Hash(); + if constexpr (FromTp::HasStageHash) { + uint64_t hash = in.template StageHash(); auto search = m_stageCache.find(hash); if (search != m_stageCache.end()) return search->second; @@ -406,7 +406,7 @@ public: template PipelineTargetTp convert(FactoryCtx& ctx, const FromTp& in) { - if (FromTp::HasHash) { + if constexpr (FromTp::HasHash) { uint64_t hash = in.Hash(); auto search = m_pipelineCache.find(hash); if (search != m_pipelineCache.end()) diff --git a/hecl/lib/CVarManager.cpp b/hecl/lib/CVarManager.cpp index b0f8c457d..37241bfab 100644 --- a/hecl/lib/CVarManager.cpp +++ b/hecl/lib/CVarManager.cpp @@ -12,6 +12,7 @@ namespace hecl { CVar* com_developer = nullptr; CVar* com_configfile = nullptr; CVar* com_enableCheats = nullptr; +CVar* com_cubemaps = nullptr; static const std::regex cmdLineRegex("\\+([\\w\\.]+)=([\\w\\.\\-]+)"); CVarManager* CVarManager::m_instance = nullptr; @@ -26,6 +27,9 @@ CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary) com_enableCheats = newCVar("cheats", "Enable cheats", false, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::Hidden | CVar::EFlags::InternalArchivable)); + com_cubemaps = + newCVar("cubemaps", "Enable cubemaps", false, + (CVar::EFlags::Game | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable)); } CVarManager::~CVarManager() {} diff --git a/hecl/shaderc/shaderc.cpp b/hecl/shaderc/shaderc.cpp index 42a08028d..a2f149974 100644 --- a/hecl/shaderc/shaderc.cpp +++ b/hecl/shaderc/shaderc.cpp @@ -31,6 +31,14 @@ Format(const char* format, ...) { return std::string(resultBuf, printSz); } +static const char* StageNames[] = { + "hecl::PipelineStage::Vertex", + "hecl::PipelineStage::Fragment", + "hecl::PipelineStage::Geometry", + "hecl::PipelineStage::Control", + "hecl::PipelineStage::Evaluation" +}; + const std::string* Compiler::getFileContents(SystemStringView path) { auto search = m_fileContents.find(path.data()); if (search == m_fileContents.end()) { @@ -59,6 +67,9 @@ static const char* ShaderHeaderTemplate = " static const boo::AdditionalPipelineInfo PipelineInfo;\n" " static constexpr bool HasHash = true;\n" " static constexpr uint64_t Hash() { return 0x%016llX; }\n" + " static constexpr bool HasStageHash = true;\n" + " template \n" + " static constexpr uint64_t StageHash();\n" "};\n\n"; static const char* StageObjectHeaderTemplate = @@ -445,7 +456,12 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std StageType stageType; auto stageBegin = includesPass.cend(); auto stageEnd = includesPass.cend(); - std::unordered_map, std::set>> shaderStageUses; + struct ShaderStageUse { + std::bitset<6> stages; + std::array stageHashes = {}; + std::set platforms; + }; + std::unordered_map shaderStageUses; std::unordered_map shaderBases; auto _DoCompile = [&]() { @@ -465,9 +481,10 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std } } stageBegin = includesPass.end(); - std::pair, std::set>& uses = shaderStageUses[shaderName]; - uses.first.set(size_t(stageType)); - uses.second.insert(stagePlatforms); + ShaderStageUse& uses = shaderStageUses[shaderName]; + uses.stages.set(size_t(stageType)); + uses.stageHashes[size_t(stageType)] = XXH64(stage.c_str(), stage.size(), 0); + uses.platforms.insert(stagePlatforms); return StageAction(stagePlatforms, stageType, shaderName, shaderBase, stage, out.second); }; auto DoCompile = [&](std::string platform, StageType type, std::string::const_iterator end, @@ -482,8 +499,8 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std auto DoShader = [&]() { if (shaderBase.empty() && shaderStageUses.find(shaderName) == shaderStageUses.cend()) return true; - std::pair, std::set>& uses = shaderStageUses[shaderName]; - if (uses.first.test(5)) + ShaderStageUse& uses = shaderStageUses[shaderName]; + if (uses.stages.test(5)) return true; out.first += Format(ShaderHeaderTemplate, shaderName.c_str(), XXH64(shaderName.c_str(), shaderName.size(), 0)); @@ -494,22 +511,23 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std shaderBases[shaderName] = shaderBase; for (int i = 0; i < 5; ++i) { - if (uses.first.test(size_t(i))) + if (uses.stages.test(size_t(i))) continue; std::string useBase = shaderBase; - std::unordered_map, std::set>>::const_iterator baseUses = + std::unordered_map::const_iterator baseUses = shaderStageUses.find(useBase); - while (baseUses == shaderStageUses.cend() || !baseUses->second.first.test(size_t(i))) { + while (baseUses == shaderStageUses.cend() || !baseUses->second.stages.test(size_t(i))) { auto search = shaderBases.find(useBase); if (search == shaderBases.cend()) break; useBase = search->second; baseUses = shaderStageUses.find(useBase); } - if (baseUses == shaderStageUses.cend() || !baseUses->second.first.test(size_t(i))) + if (baseUses == shaderStageUses.cend() || !baseUses->second.stages.test(size_t(i))) continue; - for (const std::string& basePlatforms : baseUses->second.second) { + for (const std::string& basePlatforms : baseUses->second.platforms) { + uses.stageHashes[size_t(i)] = baseUses->second.stageHashes[size_t(i)]; StageAction(basePlatforms, StageType(i), shaderName, useBase, {}, out.second); } } @@ -587,7 +605,7 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std out.second += ", "; out.second += "};\n\n"; - uses.first.set(5); + uses.stages.set(5); return true; }; @@ -751,6 +769,17 @@ bool Compiler::compileFile(SystemStringView file, std::string_view baseName, std if (!_DoCompile() || !DoShader()) return false; + for (const auto& shader : shaderStageUses) { + for (int i = 0; i < 5; ++i) { + if (shader.second.stageHashes[i]) { + out.first += "template <> constexpr uint64_t Shader_"; + out.first += shader.first; + out.first += Format("::StageHash<%s>() { return 0x%016llX; }\n", StageNames[i], shader.second.stageHashes[i]); + } + } + } + out.first += "\n"; + out.first += "#define UNIVERSAL_PIPELINES_"; out.first += baseName; for (const auto& shader : shaderStageUses) {