Added required flags to UberShaderPreprocessor
Former-commit-id: 1118fb08d1c0a7f6ebd18042f9a2044738bc4169
This commit is contained in:
parent
149ef145a3
commit
b413727a21
|
|
@ -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<nzUInt32, NzShaderStage> cache;
|
||||
std::unordered_map<NzString, nzUInt32> flags;
|
||||
nzUInt32 requiredFlags;
|
||||
NzString source;
|
||||
bool present = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<NzShader> 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<NzString> 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue