Shader: Add module statement

This commit is contained in:
Jérôme Leclercq
2022-03-01 19:36:18 +01:00
parent ad892dfb43
commit 99e07e6e1e
56 changed files with 418 additions and 123 deletions

View File

@@ -12,7 +12,7 @@
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <unordered_map>
namespace Nz
@@ -26,7 +26,7 @@ namespace Nz
struct Option;
using ConfigCallback = std::function<void(Config& config, const std::vector<RenderPipelineInfo::VertexBufferData>& vertexBuffers)>;
UberShader(ShaderStageTypeFlags shaderStages, const ShaderAst::StatementPtr& shaderAst);
UberShader(ShaderStageTypeFlags shaderStages, ShaderAst::ModulePtr shaderModule);
~UberShader() = default;
inline ShaderStageTypeFlags GetSupportedStages() const;
@@ -63,7 +63,7 @@ namespace Nz
private:
std::unordered_map<Config, std::shared_ptr<ShaderModule>, ConfigHasher, ConfigEqual> m_combinations;
std::unordered_map<std::string, Option> m_optionIndexByName;
ShaderAst::StatementPtr m_shaderAst;
ShaderAst::ModulePtr m_shaderModule;
ConfigCallback m_configCallback;
ShaderStageTypeFlags m_shaderStages;
};

View File

@@ -41,7 +41,7 @@ namespace Nz
std::shared_ptr<RenderPass> InstantiateRenderPass(std::vector<RenderPass::Attachment> attachments, std::vector<RenderPass::SubpassDescription> subpassDescriptions, std::vector<RenderPass::SubpassDependency> subpassDependencies) override;
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderAst::Module& shaderModule, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;

View File

@@ -14,7 +14,7 @@
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderModule.hpp>
#include <Nazara/Shader/GlslWriter.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <vector>
namespace Nz
@@ -22,7 +22,7 @@ namespace Nz
class NAZARA_OPENGLRENDERER_API OpenGLShaderModule : public ShaderModule
{
public:
OpenGLShaderModule(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states = {});
OpenGLShaderModule(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::Module& shaderModule, const ShaderWriter::States& states = {});
OpenGLShaderModule(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states = {});
OpenGLShaderModule(const OpenGLShaderModule&) = delete;
OpenGLShaderModule(OpenGLShaderModule&&) noexcept = default;
@@ -34,7 +34,7 @@ namespace Nz
OpenGLShaderModule& operator=(OpenGLShaderModule&&) noexcept = default;
private:
void Create(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states);
void Create(OpenGLDevice& device, ShaderStageTypeFlags shaderStages, ShaderAst::Module& shaderModule, const ShaderWriter::States& states);
static void CheckCompilationStatus(GL::Shader& shader);
@@ -45,7 +45,7 @@ namespace Nz
struct ShaderStatement
{
std::shared_ptr<ShaderAst::Statement> ast;
ShaderAst::ModulePtr ast;
};
struct Shader

View File

@@ -19,7 +19,7 @@
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <memory>
#include <string>
@@ -44,7 +44,7 @@ namespace Nz
virtual std::shared_ptr<RenderPass> InstantiateRenderPass(std::vector<RenderPass::Attachment> attachments, std::vector<RenderPass::SubpassDescription> subpassDescriptions, std::vector<RenderPass::SubpassDependency> subpassDependencies) = 0;
virtual std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
virtual std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) = 0;
virtual std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states) = 0;
virtual std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderAst::Module& shaderModule, const ShaderWriter::States& states) = 0;
virtual std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states) = 0;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const std::filesystem::path& sourcePath, const ShaderWriter::States& states);
virtual std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) = 0;

View File

@@ -11,7 +11,7 @@
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
namespace Nz::ShaderAst
{
@@ -94,9 +94,11 @@ namespace Nz::ShaderAst
inline ShaderAstSerializer(ByteStream& stream);
~ShaderAstSerializer() = default;
void Serialize(StatementPtr& shader);
void Serialize(Module& shader);
private:
using AstSerializerBase::Serialize;
bool IsWriting() const override;
void Node(ExpressionPtr& node) override;
void Node(StatementPtr& node) override;
@@ -125,9 +127,11 @@ namespace Nz::ShaderAst
ShaderAstUnserializer(ByteStream& stream);
~ShaderAstUnserializer() = default;
StatementPtr Unserialize();
ModulePtr Unserialize();
private:
using AstSerializerBase::Serialize;
bool IsWriting() const override;
void Node(ExpressionPtr& node) override;
void Node(StatementPtr& node) override;
@@ -150,9 +154,9 @@ namespace Nz::ShaderAst
ByteStream& m_stream;
};
NAZARA_SHADER_API ByteArray SerializeShader(StatementPtr& shader);
inline StatementPtr UnserializeShader(const void* data, std::size_t size);
NAZARA_SHADER_API StatementPtr UnserializeShader(ByteStream& stream);
NAZARA_SHADER_API ByteArray SerializeShader(Module& shader);
inline ModulePtr UnserializeShader(const void* data, std::size_t size);
NAZARA_SHADER_API ModulePtr UnserializeShader(ByteStream& stream);
}
#include <Nazara/Shader/Ast/AstSerializer.inl>

View File

@@ -173,7 +173,7 @@ namespace Nz::ShaderAst
{
}
inline StatementPtr UnserializeShader(const void* data, std::size_t size)
inline ModulePtr UnserializeShader(const void* data, std::size_t size)
{
ByteStream byteStream(data, size);
return UnserializeShader(byteStream);

View File

@@ -31,7 +31,8 @@ namespace Nz::ShaderAst
Vector4f,
Vector2i32,
Vector3i32,
Vector4i32
Vector4i32,
std::string
>;
using ConstantValue = TypeListInstantiate<ConstantTypes, std::variant>;

View File

@@ -35,6 +35,7 @@ namespace Nz
Entry, //< Entry point (function only) - has argument type
Layout, //< Struct layout (struct only) - has argument style
Location, //< Location (struct member only) - has argument index
LangVersion, //< NZSL version - has argument version string
Set, //< Binding set (external var only) - has argument index
Unroll, //< Unroll (for/for each only) - has argument mode
};
@@ -136,6 +137,7 @@ namespace Nz
Float32, //< f32
Int32, //< i32
UInt32, //< ui32
String //< str
};
enum class UnaryType

View File

@@ -0,0 +1,28 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Shader module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_AST_MODULE_HPP
#define NAZARA_SHADER_AST_MODULE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <memory>
namespace Nz::ShaderAst
{
struct Module;
using ModulePtr = std::shared_ptr<Module>;
struct Module
{
MultiStatementPtr rootNode;
UInt32 shaderLangVersion;
};
}
#endif // NAZARA_SHADER_AST_MODULE_HPP

View File

@@ -12,6 +12,7 @@
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/Ast/AstCloner.hpp>
#include <Nazara/Shader/Ast/AstTypes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -30,8 +31,8 @@ namespace Nz::ShaderAst
SanitizeVisitor(SanitizeVisitor&&) = delete;
~SanitizeVisitor() = default;
inline StatementPtr Sanitize(Statement& statement, std::string* error = nullptr);
StatementPtr Sanitize(Statement& statement, const Options& options, std::string* error = nullptr);
inline ModulePtr Sanitize(Module& module, std::string* error = nullptr);
ModulePtr Sanitize(Module& module, const Options& options, std::string* error = nullptr);
SanitizeVisitor& operator=(const SanitizeVisitor&) = delete;
SanitizeVisitor& operator=(SanitizeVisitor&&) = delete;
@@ -177,8 +178,8 @@ namespace Nz::ShaderAst
Context* m_context;
};
inline StatementPtr Sanitize(Statement& ast, std::string* error = nullptr);
inline StatementPtr Sanitize(Statement& ast, const SanitizeVisitor::Options& options, std::string* error = nullptr);
inline ModulePtr Sanitize(Module& module, std::string* error = nullptr);
inline ModulePtr Sanitize(Module& module, const SanitizeVisitor::Options& options, std::string* error = nullptr);
}
#include <Nazara/Shader/Ast/SanitizeVisitor.inl>

View File

@@ -7,21 +7,21 @@
namespace Nz::ShaderAst
{
inline StatementPtr SanitizeVisitor::Sanitize(Statement& statement, std::string* error)
inline ModulePtr SanitizeVisitor::Sanitize(Module& module, std::string* error)
{
return Sanitize(statement, {}, error);
return Sanitize(module, {}, error);
}
inline StatementPtr Sanitize(Statement& ast, std::string* error)
inline ModulePtr Sanitize(Module& module, std::string* error)
{
SanitizeVisitor sanitizer;
return sanitizer.Sanitize(ast, error);
return sanitizer.Sanitize(module, error);
}
inline StatementPtr Sanitize(Statement& ast, const SanitizeVisitor::Options& options, std::string* error)
inline ModulePtr Sanitize(Module& module, const SanitizeVisitor::Options& options, std::string* error)
{
SanitizeVisitor sanitizer;
return sanitizer.Sanitize(ast, options, error);
return sanitizer.Sanitize(module, options, error);
}
}

View File

@@ -12,6 +12,7 @@
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/Ast/AstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/Ast/AstStatementVisitorExcept.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <set>
#include <sstream>
#include <string>
@@ -31,8 +32,8 @@ namespace Nz
GlslWriter(GlslWriter&&) = delete;
~GlslWriter() = default;
inline std::string Generate(ShaderAst::Statement& shader, const BindingMapping& bindingMapping = {}, const States& states = {});
std::string Generate(std::optional<ShaderStageType> shaderStage, ShaderAst::Statement& shader, const BindingMapping& bindingMapping = {}, const States& states = {});
inline std::string Generate(ShaderAst::Module& module, const BindingMapping& bindingMapping = {}, const States& states = {});
std::string Generate(std::optional<ShaderStageType> shaderStage, ShaderAst::Module& module, const BindingMapping& bindingMapping = {}, const States& states = {});
void SetEnv(Environment environment);
@@ -47,7 +48,7 @@ namespace Nz
};
static const char* GetFlipYUniformName();
static ShaderAst::StatementPtr Sanitize(ShaderAst::Statement& ast, std::unordered_map<std::size_t, ShaderAst::ConstantValue> optionValues, std::string* error = nullptr);
static ShaderAst::ModulePtr Sanitize(ShaderAst::Module& module, std::unordered_map<std::size_t, ShaderAst::ConstantValue> optionValues, std::string* error = nullptr);
private:
void Append(const ShaderAst::ArrayType& type);

View File

@@ -12,7 +12,7 @@ namespace Nz
{
}
inline std::string GlslWriter::Generate(ShaderAst::Statement& shader, const BindingMapping& bindingMapping, const States& states)
inline std::string GlslWriter::Generate(ShaderAst::Module& shader, const BindingMapping& bindingMapping, const States& states)
{
return Generate(std::nullopt, shader, bindingMapping, states);
}

View File

@@ -12,6 +12,7 @@
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/Ast/AstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/Ast/AstStatementVisitorExcept.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <set>
#include <sstream>
#include <string>
@@ -28,7 +29,7 @@ namespace Nz
LangWriter(LangWriter&&) = delete;
~LangWriter() = default;
std::string Generate(ShaderAst::Statement& shader, const States& conditions = {});
std::string Generate(ShaderAst::Module& module, const States& conditions = {});
void SetEnv(Environment environment);
@@ -44,6 +45,7 @@ namespace Nz
struct EntryAttribute;
struct LayoutAttribute;
struct LocationAttribute;
struct NzslAttribute;
struct SetAttribute;
struct UnrollAttribute;
@@ -74,6 +76,7 @@ namespace Nz
void AppendAttribute(EntryAttribute entry);
void AppendAttribute(LayoutAttribute layout);
void AppendAttribute(LocationAttribute location);
void AppendAttribute(NzslAttribute nzslVersion);
void AppendAttribute(SetAttribute set);
void AppendAttribute(UnrollAttribute unroll);
void AppendCommentSection(const std::string& section);

View File

@@ -41,6 +41,16 @@ namespace Nz::ShaderLang
using exception::exception;
};
class UnfinishedString : public std::exception
{
using exception::exception;
};
class UnrecognizedChar : public std::exception
{
using exception::exception;
};
class UnrecognizedToken : public std::exception
{
using exception::exception;

View File

@@ -10,7 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderLangLexer.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <filesystem>
#include <optional>
@@ -34,6 +34,12 @@ namespace Nz::ShaderLang
using runtime_error::runtime_error;
};
class DuplicateModule : public std::runtime_error
{
public:
using runtime_error::runtime_error;
};
class ReservedKeyword : public std::exception
{
public:
@@ -64,7 +70,7 @@ namespace Nz::ShaderLang
inline Parser();
~Parser() = default;
ShaderAst::StatementPtr Parse(const std::vector<Token>& tokens);
ShaderAst::ModulePtr Parse(const std::vector<Token>& tokens);
private:
// Flow control
@@ -87,6 +93,7 @@ namespace Nz::ShaderLang
std::vector<ShaderAst::StatementPtr> ParseFunctionBody();
ShaderAst::StatementPtr ParseFunctionDeclaration(std::vector<ShaderAst::ExprValue> attributes = {});
ShaderAst::DeclareFunctionStatement::Parameter ParseFunctionParameter();
void ParseModuleStatement(std::vector<ShaderAst::ExprValue> attributes);
ShaderAst::StatementPtr ParseOptionDeclaration();
ShaderAst::StatementPtr ParseReturnStatement();
ShaderAst::StatementPtr ParseSingleStatement();
@@ -106,6 +113,7 @@ namespace Nz::ShaderLang
std::vector<ShaderAst::ExpressionPtr> ParseParameters();
ShaderAst::ExpressionPtr ParseParenthesisExpression();
ShaderAst::ExpressionPtr ParsePrimaryExpression();
ShaderAst::ExpressionPtr ParseStringExpression();
ShaderAst::ExpressionPtr ParseVariableAssignation();
ShaderAst::AttributeType ParseIdentifierAsAttributeType();
@@ -118,16 +126,16 @@ namespace Nz::ShaderLang
{
std::size_t tokenCount;
std::size_t tokenIndex = 0;
std::unique_ptr<ShaderAst::MultiStatement> root;
ShaderAst::ModulePtr module;
const Token* tokens;
};
Context* m_context;
};
inline ShaderAst::StatementPtr Parse(const std::string_view& source);
inline ShaderAst::StatementPtr Parse(const std::vector<Token>& tokens);
NAZARA_SHADER_API ShaderAst::StatementPtr ParseFromFile(const std::filesystem::path& sourcePath);
inline ShaderAst::ModulePtr Parse(const std::string_view& source);
inline ShaderAst::ModulePtr Parse(const std::vector<Token>& tokens);
NAZARA_SHADER_API ShaderAst::ModulePtr ParseFromFile(const std::filesystem::path& sourcePath);
}
#include <Nazara/Shader/ShaderLangParser.inl>

View File

@@ -12,12 +12,12 @@ namespace Nz::ShaderLang
{
}
inline ShaderAst::StatementPtr Parse(const std::string_view& source)
inline ShaderAst::ModulePtr Parse(const std::string_view& source)
{
return Parse(Tokenize(source));
}
inline ShaderAst::StatementPtr Parse(const std::vector<Token>& tokens)
inline ShaderAst::ModulePtr Parse(const std::vector<Token>& tokens)
{
Parser parser;
return parser.Parse(tokens);

View File

@@ -51,6 +51,7 @@ NAZARA_SHADERLANG_TOKEN(Multiply)
NAZARA_SHADERLANG_TOKEN(MultiplyAssign)
NAZARA_SHADERLANG_TOKEN(Minus)
NAZARA_SHADERLANG_TOKEN(MinusAssign)
NAZARA_SHADERLANG_TOKEN(Module)
NAZARA_SHADERLANG_TOKEN(Not)
NAZARA_SHADERLANG_TOKEN(NotEqual)
NAZARA_SHADERLANG_TOKEN(Plus)
@@ -61,6 +62,7 @@ NAZARA_SHADERLANG_TOKEN(OpenParenthesis)
NAZARA_SHADERLANG_TOKEN(Option)
NAZARA_SHADERLANG_TOKEN(Return)
NAZARA_SHADERLANG_TOKEN(Semicolon)
NAZARA_SHADERLANG_TOKEN(StringValue)
NAZARA_SHADERLANG_TOKEN(Struct)
NAZARA_SHADERLANG_TOKEN(While)

View File

@@ -12,7 +12,7 @@
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <Nazara/Shader/Ast/ConstantValue.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <string>
#include <string_view>
#include <unordered_map>
@@ -36,7 +36,7 @@ namespace Nz
SpirvWriter(SpirvWriter&&) = delete;
~SpirvWriter() = default;
std::vector<UInt32> Generate(ShaderAst::Statement& shader, const States& states = {});
std::vector<UInt32> Generate(ShaderAst::Module& module, const States& states = {});
void SetEnv(Environment environment);

View File

@@ -32,7 +32,7 @@ namespace Nz
std::shared_ptr<RenderPass> InstantiateRenderPass(std::vector<RenderPass::Attachment> attachments, std::vector<RenderPass::SubpassDescription> subpassDescriptions, std::vector<RenderPass::SubpassDependency> subpassDependencies) override;
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags stages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags stages, ShaderAst::Module& shaderModule, const ShaderWriter::States& states) override;
std::shared_ptr<ShaderModule> InstantiateShaderModule(ShaderStageTypeFlags stages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states) override;
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;

View File

@@ -11,7 +11,7 @@
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderModule.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/Ast/Nodes.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
#include <vector>
@@ -27,7 +27,7 @@ namespace Nz
VulkanShaderModule(VulkanShaderModule&&) = delete;
~VulkanShaderModule() = default;
bool Create(Vk::Device& device, ShaderStageTypeFlags shaderStages, ShaderAst::Statement& shaderAst, const ShaderWriter::States& states);
bool Create(Vk::Device& device, ShaderStageTypeFlags shaderStages, ShaderAst::Module& shaderModule, const ShaderWriter::States& states);
bool Create(Vk::Device& device, ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const ShaderWriter::States& states);
inline const Vk::ShaderModule& GetHandle() const;