From b413727a219b88d28bedfe29c621eb19f6d197e1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Aug 2014 09:43:19 +0200 Subject: [PATCH] Added required flags to UberShaderPreprocessor Former-commit-id: 1118fb08d1c0a7f6ebd18042f9a2044738bc4169 --- .../Renderer/UberShaderPreprocessor.hpp | 5 ++- .../Renderer/UberShaderPreprocessor.cpp | 43 +++++++++++++++---- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.hpp b/include/Nazara/Renderer/UberShaderPreprocessor.hpp index 3818c2154..0aa7679ac 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.hpp +++ b/include/Nazara/Renderer/UberShaderPreprocessor.hpp @@ -23,8 +23,8 @@ class NAZARA_API NzUberShaderPreprocessor : public NzUberShader NzUberShaderInstance* Get(const NzParameterList& parameters) const; - void SetShader(nzShaderStage stage, const NzString& source, const NzString& flags); - bool SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& flags); + void SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags = NzString()); + bool SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags = NzString()); static bool IsSupported(); @@ -33,6 +33,7 @@ class NAZARA_API NzUberShaderPreprocessor : public NzUberShader { mutable std::unordered_map cache; std::unordered_map flags; + nzUInt32 requiredFlags; NzString source; bool present = false; }; diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp index cffd8bc6b..5dd74bc32 100644 --- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp @@ -32,7 +32,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param { try { - NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException); + // Une exception sera lancée à la moindre erreur et celle-ci ne sera pas enregistrée dans le log (car traitée dans le bloc catch) + NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException, true); std::unique_ptr shader(new NzShader); shader->SetPersistent(false); @@ -42,7 +43,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param { const Shader& shaderStage = m_shaders[i]; - if (shaderStage.present) + // Le shader stage est-il activé dans cette version du shader ? + if (shaderStage.present && (flags & shaderStage.requiredFlags) == shaderStage.requiredFlags) { nzUInt32 stageFlags = 0; for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) @@ -73,7 +75,7 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n'; - code << "\n#line 1\n"; + code << "\n#line 1\n"; // Pour que les éventuelles erreurs du shader se réfèrent à la bonne ligne code << shaderStage.source; stage.SetSource(code); @@ -90,6 +92,7 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param shader->Link(); + // On construit l'instant auto pair = m_cache.emplace(flags, shader.get()); shader.release(); @@ -99,23 +102,23 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param { NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled); - NazaraError("Failed to build uber shader instance: " + NzError::GetLastError()); + NazaraError("Failed to build UberShader instance: " + NzError::GetLastError()); throw; } - } else return &shaderIt->second; } -void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& flagString) +void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags) { Shader& shader = m_shaders[stage]; shader.present = true; shader.source = source; + // On extrait les flags de la chaîne std::vector flags; - flagString.Split(flags, ' '); + shaderFlags.Split(flags, ' '); for (NzString& flag : flags) { @@ -127,9 +130,31 @@ void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& so if (it2 == shader.flags.end()) shader.flags[flag] = 1U << shader.flags.size(); } + + // On construit les flags requis pour l'activation du shader + shader.requiredFlags = 0; + + flags.clear(); + requiredFlags.Split(flags, ' '); + + for (NzString& flag : flags) + { + nzUInt32 flagVal; + + auto it = m_flags.find(flag); + if (it == m_flags.end()) + { + flagVal = 1U << m_flags.size(); + m_flags[flag] = flagVal; + } + else + flagVal = it->second; + + shader.requiredFlags |= flagVal; + } } -bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& flags) +bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags) { NzFile file(filePath); if (!file.Open(NzFile::ReadOnly | NzFile::Text)) @@ -150,7 +175,7 @@ bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzSt file.Close(); - SetShader(stage, source, flags); + SetShader(stage, source, shaderFlags, requiredFlags); return true; }