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;
|
NzUberShaderInstance* Get(const NzParameterList& parameters) const;
|
||||||
|
|
||||||
void SetShader(nzShaderStage stage, const NzString& source, 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& flags);
|
bool SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags = NzString());
|
||||||
|
|
||||||
static bool IsSupported();
|
static bool IsSupported();
|
||||||
|
|
||||||
|
|
@ -33,6 +33,7 @@ class NAZARA_API NzUberShaderPreprocessor : public NzUberShader
|
||||||
{
|
{
|
||||||
mutable std::unordered_map<nzUInt32, NzShaderStage> cache;
|
mutable std::unordered_map<nzUInt32, NzShaderStage> cache;
|
||||||
std::unordered_map<NzString, nzUInt32> flags;
|
std::unordered_map<NzString, nzUInt32> flags;
|
||||||
|
nzUInt32 requiredFlags;
|
||||||
NzString source;
|
NzString source;
|
||||||
bool present = false;
|
bool present = false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
|
||||||
{
|
{
|
||||||
try
|
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);
|
std::unique_ptr<NzShader> shader(new NzShader);
|
||||||
shader->SetPersistent(false);
|
shader->SetPersistent(false);
|
||||||
|
|
@ -42,7 +43,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
|
||||||
{
|
{
|
||||||
const Shader& shaderStage = m_shaders[i];
|
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;
|
nzUInt32 stageFlags = 0;
|
||||||
for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it)
|
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)
|
for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it)
|
||||||
code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n';
|
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;
|
code << shaderStage.source;
|
||||||
|
|
||||||
stage.SetSource(code);
|
stage.SetSource(code);
|
||||||
|
|
@ -90,6 +92,7 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
|
||||||
|
|
||||||
shader->Link();
|
shader->Link();
|
||||||
|
|
||||||
|
// On construit l'instant
|
||||||
auto pair = m_cache.emplace(flags, shader.get());
|
auto pair = m_cache.emplace(flags, shader.get());
|
||||||
shader.release();
|
shader.release();
|
||||||
|
|
||||||
|
|
@ -99,23 +102,23 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
|
||||||
{
|
{
|
||||||
NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled);
|
NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled);
|
||||||
|
|
||||||
NazaraError("Failed to build uber shader instance: " + NzError::GetLastError());
|
NazaraError("Failed to build UberShader instance: " + NzError::GetLastError());
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return &shaderIt->second;
|
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& shader = m_shaders[stage];
|
||||||
shader.present = true;
|
shader.present = true;
|
||||||
shader.source = source;
|
shader.source = source;
|
||||||
|
|
||||||
|
// On extrait les flags de la chaîne
|
||||||
std::vector<NzString> flags;
|
std::vector<NzString> flags;
|
||||||
flagString.Split(flags, ' ');
|
shaderFlags.Split(flags, ' ');
|
||||||
|
|
||||||
for (NzString& flag : flags)
|
for (NzString& flag : flags)
|
||||||
{
|
{
|
||||||
|
|
@ -127,9 +130,31 @@ void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& so
|
||||||
if (it2 == shader.flags.end())
|
if (it2 == shader.flags.end())
|
||||||
shader.flags[flag] = 1U << shader.flags.size();
|
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);
|
NzFile file(filePath);
|
||||||
if (!file.Open(NzFile::ReadOnly | NzFile::Text))
|
if (!file.Open(NzFile::ReadOnly | NzFile::Text))
|
||||||
|
|
@ -150,7 +175,7 @@ bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzSt
|
||||||
|
|
||||||
file.Close();
|
file.Close();
|
||||||
|
|
||||||
SetShader(stage, source, flags);
|
SetShader(stage, source, shaderFlags, requiredFlags);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue