Shader: Fix shader serialization

This commit is contained in:
Jérôme Leclercq 2022-03-10 12:31:00 +01:00
parent 39a2992791
commit bf7f06ac4c
4 changed files with 48 additions and 12 deletions

View File

@ -74,6 +74,8 @@ namespace Nz::ShaderAst
virtual bool IsWriting() const = 0; virtual bool IsWriting() const = 0;
virtual void SerializeModule(ModulePtr& module) = 0;
virtual void Node(ExpressionPtr& node) = 0; virtual void Node(ExpressionPtr& node) = 0;
virtual void Node(StatementPtr& node) = 0; virtual void Node(StatementPtr& node) = 0;
@ -102,11 +104,13 @@ namespace Nz::ShaderAst
inline ShaderAstSerializer(ByteStream& stream); inline ShaderAstSerializer(ByteStream& stream);
~ShaderAstSerializer() = default; ~ShaderAstSerializer() = default;
void Serialize(Module& shader); void Serialize(ModulePtr& shader);
private: private:
using AstSerializerBase::Serialize; using AstSerializerBase::Serialize;
void SerializeModule(ModulePtr& module) override;
bool IsWriting() const override; bool IsWriting() const override;
void Node(ExpressionPtr& node) override; void Node(ExpressionPtr& node) override;
void Node(StatementPtr& node) override; void Node(StatementPtr& node) override;
@ -140,6 +144,8 @@ namespace Nz::ShaderAst
private: private:
using AstSerializerBase::Serialize; using AstSerializerBase::Serialize;
void SerializeModule(ModulePtr& module) override;
bool IsWriting() const override; bool IsWriting() const override;
void Node(ExpressionPtr& node) override; void Node(ExpressionPtr& node) override;
void Node(StatementPtr& node) override; void Node(StatementPtr& node) override;
@ -162,7 +168,7 @@ namespace Nz::ShaderAst
ByteStream& m_stream; ByteStream& m_stream;
}; };
NAZARA_SHADER_API ByteArray SerializeShader(Module& shader); NAZARA_SHADER_API ByteArray SerializeShader(ModulePtr& shader);
inline ModulePtr UnserializeShader(const void* data, std::size_t size); inline ModulePtr UnserializeShader(const void* data, std::size_t size);
NAZARA_SHADER_API ModulePtr UnserializeShader(ByteStream& stream); NAZARA_SHADER_API ModulePtr UnserializeShader(ByteStream& stream);
} }

View File

@ -376,17 +376,31 @@ namespace Nz::ShaderAst
Node(node.body); Node(node.body);
} }
void ShaderAstSerializer::Serialize(Module& module) void ShaderAstSerializer::Serialize(ModulePtr& module)
{ {
m_stream << s_magicNumber << s_currentVersion; m_stream << s_magicNumber << s_currentVersion;
m_stream << module.metadata->moduleId; SerializeModule(module);
m_stream << module.metadata->shaderLangVersion;
Serialize(*module.rootNode);
m_stream.FlushBits(); m_stream.FlushBits();
} }
void ShaderAstSerializer::SerializeModule(ModulePtr& module)
{
m_stream << module->metadata->moduleId;
m_stream << module->metadata->shaderLangVersion;
Container(module->importedModules);
for (auto& importedModule : module->importedModules)
{
Value(importedModule.identifier);
SerializeModule(importedModule.module);
}
ShaderSerializerVisitor visitor(*this);
module->rootNode->Visit(visitor);
}
bool ShaderAstSerializer::IsWriting() const bool ShaderAstSerializer::IsWriting() const
{ {
return true; return true;
@ -583,16 +597,32 @@ namespace Nz::ShaderAst
if (version > s_currentVersion) if (version > s_currentVersion)
throw std::runtime_error("unsupported version"); throw std::runtime_error("unsupported version");
ModulePtr module;
SerializeModule(module);
return module;
}
void ShaderAstUnserializer::SerializeModule(ModulePtr& module)
{
std::shared_ptr<Module::Metadata> metadata = std::make_shared<Module::Metadata>(); std::shared_ptr<Module::Metadata> metadata = std::make_shared<Module::Metadata>();
m_stream >> metadata->moduleId; m_stream >> metadata->moduleId;
m_stream >> metadata->shaderLangVersion; m_stream >> metadata->shaderLangVersion;
ModulePtr module = std::make_shared<Module>(std::move(metadata)); std::vector<Module::ImportedModule> importedModules;
Container(importedModules);
for (auto& importedModule : importedModules)
{
Value(const_cast<std::string&>(importedModule.identifier)); //< not used for writing
SerializeModule(importedModule.module);
}
MultiStatementPtr rootNode = std::make_unique<MultiStatement>();
ShaderSerializerVisitor visitor(*this); ShaderSerializerVisitor visitor(*this);
module->rootNode->Visit(visitor); rootNode->Visit(visitor);
return module; module = std::make_shared<Module>(std::move(metadata), std::move(rootNode), std::move(importedModules));
} }
bool ShaderAstUnserializer::IsWriting() const bool ShaderAstUnserializer::IsWriting() const
@ -903,7 +933,7 @@ namespace Nz::ShaderAst
} }
ByteArray SerializeShader(Module& module) ByteArray SerializeShader(ModulePtr& module)
{ {
ByteArray byteArray; ByteArray byteArray;
ByteStream stream(&byteArray, OpenModeFlags(OpenMode::WriteOnly)); ByteStream stream(&byteArray, OpenModeFlags(OpenMode::WriteOnly));

View File

@ -191,7 +191,7 @@ void MainWindow::OnCompile()
fileName += ".shader"; fileName += ".shader";
Nz::File file(fileName.toStdString(), Nz::OpenMode::WriteOnly); Nz::File file(fileName.toStdString(), Nz::OpenMode::WriteOnly);
file.Write(Nz::ShaderAst::SerializeShader(*shaderModule)); file.Write(Nz::ShaderAst::SerializeShader(shaderModule));
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {

View File

@ -18,7 +18,7 @@ void ParseSerializeUnserialize(std::string_view sourceCode, bool sanitize)
REQUIRE_NOTHROW(shaderModule = Nz::ShaderAst::Sanitize(*shaderModule)); REQUIRE_NOTHROW(shaderModule = Nz::ShaderAst::Sanitize(*shaderModule));
Nz::ByteArray serializedModule; Nz::ByteArray serializedModule;
REQUIRE_NOTHROW(serializedModule = Nz::ShaderAst::SerializeShader(*shaderModule)); REQUIRE_NOTHROW(serializedModule = Nz::ShaderAst::SerializeShader(shaderModule));
Nz::ByteStream byteStream(&serializedModule); Nz::ByteStream byteStream(&serializedModule);
Nz::ShaderAst::ModulePtr unserializedShader; Nz::ShaderAst::ModulePtr unserializedShader;