Rework shader AST (WIP)

This commit is contained in:
Jérôme Leclercq
2021-03-10 11:18:13 +01:00
parent b320b5b44e
commit fed7370e77
73 changed files with 2721 additions and 4312 deletions

View File

@@ -16,6 +16,7 @@
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Utility/AbstractBuffer.hpp>
#include <memory>
@@ -24,7 +25,6 @@
namespace Nz
{
class CommandPool;
class ShaderAst;
class ShaderStage;
class NAZARA_RENDERER_API RenderDevice
@@ -39,7 +39,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<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) = 0;
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst::StatementPtr& shaderAst, const ShaderWriter::States& states) = 0;
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath);
virtual std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) = 0;

View File

@@ -32,23 +32,25 @@
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/GlslWriter.hpp>
#include <Nazara/Shader/Shader.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderAstCache.hpp>
#include <Nazara/Shader/ShaderAstCloner.hpp>
#include <Nazara/Shader/ShaderAstExpressionType.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitor.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstOptimizer.hpp>
#include <Nazara/Shader/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Shader/ShaderAstSerializer.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitor.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstTypes.hpp>
#include <Nazara/Shader/ShaderAstUtils.hpp>
#include <Nazara/Shader/ShaderAstValidator.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderLangLexer.hpp>
#include <Nazara/Shader/ShaderLangParser.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/SpirvAstVisitor.hpp>
#include <Nazara/Shader/SpirvBlock.hpp>
@@ -58,6 +60,7 @@
#include <Nazara/Shader/SpirvExpressionStore.hpp>
#include <Nazara/Shader/SpirvPrinter.hpp>
#include <Nazara/Shader/SpirvSection.hpp>
#include <Nazara/Shader/SpirvSectionBase.hpp>
#include <Nazara/Shader/SpirvWriter.hpp>
#endif // NAZARA_GLOBAL_SHADER_HPP

View File

@@ -9,9 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <set>
#include <sstream>
@@ -19,7 +17,7 @@
namespace Nz
{
class NAZARA_SHADER_API GlslWriter : public ShaderWriter, public ShaderVarVisitor, public ShaderAstVisitor
class NAZARA_SHADER_API GlslWriter : public ShaderWriter, public ShaderAst::AstRecursiveVisitor
{
public:
struct Environment;
@@ -30,7 +28,7 @@ namespace Nz
GlslWriter(GlslWriter&&) = delete;
~GlslWriter() = default;
std::string Generate(const ShaderAst& shader, const States& conditions = {});
std::string Generate(ShaderAst::StatementPtr& shader, const States& conditions = {});
void SetEnv(Environment environment);
@@ -46,67 +44,45 @@ namespace Nz
static const char* GetFlipYUniformName();
private:
void Append(ShaderExpressionType type);
void Append(ShaderNodes::BuiltinEntry builtin);
void Append(ShaderNodes::BasicType type);
void Append(ShaderNodes::MemoryLayout layout);
void Append(ShaderAst::ShaderExpressionType type);
void Append(ShaderAst::BuiltinEntry builtin);
void Append(ShaderAst::BasicType type);
void Append(ShaderAst::MemoryLayout layout);
template<typename T> void Append(const T& param);
void AppendCommentSection(const std::string& section);
void AppendField(const std::string& structName, std::size_t* memberIndex, std::size_t remainingMembers);
void AppendFunction(const ShaderAst::Function& func);
void AppendFunctionPrototype(const ShaderAst::Function& func);
void AppendField(std::size_t scopeId, const std::string& structName, const std::string* memberIdentifier, std::size_t remainingMembers);
void AppendLine(const std::string& txt = {});
template<typename T> void DeclareVariables(const ShaderAst& shader, const std::vector<T>& variables, const std::string& keyword = {}, const std::string& section = {});
void EnterScope();
void LeaveScope();
using ShaderVarVisitor::Visit;
using ShaderAstVisitor::Visit;
void Visit(ShaderNodes::ExpressionPtr& expr, bool encloseIfRequired = false);
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::NoOp& node) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::ReturnStatement& node) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
void Visit(ShaderNodes::UniformVariable& var) override;
void Visit(ShaderAst::ExpressionPtr& expr, bool encloseIfRequired = false);
static bool HasExplicitBinding(const ShaderAst& shader);
static bool HasExplicitLocation(const ShaderAst& shader);
void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::AssignExpression& node) override;
void Visit(ShaderAst::BinaryExpression& node) override;
void Visit(ShaderAst::CastExpression& node) override;
void Visit(ShaderAst::ConditionalExpression& node) override;
void Visit(ShaderAst::ConstantExpression& node) override;
void Visit(ShaderAst::IdentifierExpression& node) override;
void Visit(ShaderAst::IntrinsicExpression& node) override;
void Visit(ShaderAst::SwizzleExpression& node) override;
struct Context
{
const ShaderAst* shader = nullptr;
const ShaderAst::Function* currentFunction = nullptr;
const States* states = nullptr;
};
void Visit(ShaderAst::BranchStatement& node) override;
void Visit(ShaderAst::ConditionalStatement& node) override;
void Visit(ShaderAst::DeclareFunctionStatement& node) override;
void Visit(ShaderAst::DeclareVariableStatement& node) override;
void Visit(ShaderAst::DiscardStatement& node) override;
void Visit(ShaderAst::ExpressionStatement& node) override;
void Visit(ShaderAst::MultiStatement& node) override;
void Visit(ShaderAst::NoOpStatement& node) override;
void Visit(ShaderAst::ReturnStatement& node) override;
struct State
{
std::stringstream stream;
unsigned int indentLevel = 0;
};
static bool HasExplicitBinding(ShaderAst::StatementPtr& shader);
static bool HasExplicitLocation(ShaderAst::StatementPtr& shader);
struct State;
Context m_context;
Environment m_environment;
State* m_currentState;
};

View File

@@ -3,130 +3,10 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/GlslWriter.hpp>
#include <type_traits>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
template<typename T>
void GlslWriter::Append(const T& param)
{
NazaraAssert(m_currentState, "This function should only be called while processing an AST");
m_currentState->stream << param;
}
template<typename T>
void GlslWriter::DeclareVariables(const ShaderAst& shader, const std::vector<T>& variables, const std::string& keyword, const std::string& section)
{
if (!variables.empty())
{
if (!section.empty())
AppendCommentSection(section);
for (const auto& var : variables)
{
if constexpr (std::is_same_v<T, ShaderAst::InputOutput>)
{
if (var.locationIndex)
{
Append("layout(location = ");
Append(*var.locationIndex);
Append(") ");
}
if (!keyword.empty())
{
Append(keyword);
Append(" ");
}
Append(var.type);
Append(" ");
Append(var.name);
AppendLine(";");
}
else if constexpr (std::is_same_v<T, ShaderAst::Uniform>)
{
if (var.bindingIndex || var.memoryLayout)
{
Append("layout(");
bool first = true;
if (var.bindingIndex)
{
if (!first)
Append(", ");
Append("binding = ");
Append(*var.bindingIndex);
first = false;
}
if (var.memoryLayout)
{
if (!first)
Append(", ");
Append(*var.memoryLayout);
first = false;
}
Append(") ");
}
if (!keyword.empty())
{
Append(keyword);
Append(" ");
}
std::visit([&](auto&& arg)
{
using U = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<U, ShaderNodes::BasicType>)
{
Append(arg);
Append(" ");
Append(var.name);
}
else if constexpr (std::is_same_v<U, std::string>)
{
const auto& structs = shader.GetStructs();
auto it = std::find_if(structs.begin(), structs.end(), [&](const auto& s) { return s.name == arg; });
if (it == structs.end())
throw std::runtime_error("struct " + arg + " has not been defined");
const auto& s = *it;
AppendLine(var.name + "_interface");
AppendLine("{");
for (const auto& m : s.members)
{
Append("\t");
Append(m.type);
Append(" ");
Append(m.name);
AppendLine(";");
}
Append("} ");
Append(var.name);
}
else
static_assert(AlwaysFalse<U>::value, "non-exhaustive visitor");
}, var.type);
AppendLine(";");
AppendLine();
}
}
AppendLine();
}
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -1,130 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_AST_HPP
#define NAZARA_SHADER_AST_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <optional>
#include <unordered_map>
#include <vector>
namespace Nz
{
class NAZARA_SHADER_API ShaderAst
{
public:
struct Condition;
struct Function;
struct FunctionParameter;
struct InputOutput;
struct Struct;
struct StructMember;
struct Uniform;
struct VariableBase;
inline ShaderAst(ShaderStageType shaderStage);
ShaderAst(const ShaderAst&) = default;
ShaderAst(ShaderAst&&) noexcept = default;
~ShaderAst() = default;
void AddCondition(std::string name);
void AddFunction(std::string name, ShaderNodes::StatementPtr statement, std::vector<FunctionParameter> parameters = {}, ShaderExpressionType returnType = ShaderNodes::BasicType::Void);
void AddInput(std::string name, ShaderExpressionType type, std::optional<std::size_t> locationIndex = {});
void AddOutput(std::string name, ShaderExpressionType type, std::optional<std::size_t> locationIndex = {});
void AddStruct(std::string name, std::vector<StructMember> members);
void AddUniform(std::string name, ShaderExpressionType type, std::optional<std::size_t> bindingIndex = {}, std::optional<ShaderNodes::MemoryLayout> memoryLayout = {});
inline std::size_t FindConditionByName(const std::string_view& conditionName) const;
inline const Condition& GetCondition(std::size_t i) const;
inline std::size_t GetConditionCount() const;
inline const std::vector<Condition>& GetConditions() const;
inline const Function& GetFunction(std::size_t i) const;
inline std::size_t GetFunctionCount() const;
inline const std::vector<Function>& GetFunctions() const;
inline const InputOutput& GetInput(std::size_t i) const;
inline std::size_t GetInputCount() const;
inline const std::vector<InputOutput>& GetInputs() const;
inline const InputOutput& GetOutput(std::size_t i) const;
inline std::size_t GetOutputCount() const;
inline const std::vector<InputOutput>& GetOutputs() const;
inline ShaderStageType GetStage() const;
inline const Struct& GetStruct(std::size_t i) const;
inline std::size_t GetStructCount() const;
inline const std::vector<Struct>& GetStructs() const;
inline const Uniform& GetUniform(std::size_t i) const;
inline std::size_t GetUniformCount() const;
inline const std::vector<Uniform>& GetUniforms() const;
ShaderAst& operator=(const ShaderAst&) = default;
ShaderAst& operator=(ShaderAst&&) noexcept = default;
struct Condition
{
std::string name;
};
struct VariableBase
{
std::string name;
ShaderExpressionType type;
};
struct FunctionParameter : VariableBase
{
};
struct Function
{
std::string name;
std::vector<FunctionParameter> parameters;
ShaderExpressionType returnType;
ShaderNodes::StatementPtr statement;
};
struct InputOutput : VariableBase
{
std::optional<std::size_t> locationIndex;
};
struct Uniform : VariableBase
{
std::optional<std::size_t> bindingIndex;
std::optional<ShaderNodes::MemoryLayout> memoryLayout;
};
struct Struct
{
std::string name;
std::vector<StructMember> members;
};
struct StructMember
{
std::string name;
ShaderExpressionType type;
};
static constexpr std::size_t InvalidCondition = std::numeric_limits<std::size_t>::max();
private:
std::vector<Condition> m_conditions;
std::vector<Function> m_functions;
std::vector<InputOutput> m_inputs;
std::vector<InputOutput> m_outputs;
std::vector<Struct> m_structs;
std::vector<Uniform> m_uniforms;
ShaderStageType m_stage;
};
}
#include <Nazara/Shader/ShaderAst.inl>
#endif // NAZARA_SHADER_AST_HPP

View File

@@ -1,128 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
{
inline ShaderAst::ShaderAst(ShaderStageType shaderStage) :
m_stage(shaderStage)
{
}
inline std::size_t ShaderAst::FindConditionByName(const std::string_view& conditionName) const
{
for (std::size_t i = 0; i < m_conditions.size(); ++i)
{
if (m_conditions[i].name == conditionName)
return i;
}
return InvalidCondition;
}
inline auto Nz::ShaderAst::GetCondition(std::size_t i) const -> const Condition&
{
assert(i < m_functions.size());
return m_conditions[i];
}
inline std::size_t ShaderAst::GetConditionCount() const
{
return m_conditions.size();
}
inline auto ShaderAst::GetConditions() const -> const std::vector<Condition>&
{
return m_conditions;
}
inline auto ShaderAst::GetFunction(std::size_t i) const -> const Function&
{
assert(i < m_functions.size());
return m_functions[i];
}
inline std::size_t ShaderAst::GetFunctionCount() const
{
return m_functions.size();
}
inline auto ShaderAst::GetFunctions() const -> const std::vector<Function>&
{
return m_functions;
}
inline auto ShaderAst::GetInput(std::size_t i) const -> const InputOutput&
{
assert(i < m_inputs.size());
return m_inputs[i];
}
inline std::size_t ShaderAst::GetInputCount() const
{
return m_inputs.size();
}
inline auto ShaderAst::GetInputs() const -> const std::vector<InputOutput>&
{
return m_inputs;
}
inline auto ShaderAst::GetOutput(std::size_t i) const -> const InputOutput&
{
assert(i < m_outputs.size());
return m_outputs[i];
}
inline std::size_t ShaderAst::GetOutputCount() const
{
return m_outputs.size();
}
inline auto ShaderAst::GetOutputs() const -> const std::vector<InputOutput>&
{
return m_outputs;
}
inline ShaderStageType ShaderAst::GetStage() const
{
return m_stage;
}
inline auto ShaderAst::GetStruct(std::size_t i) const -> const Struct&
{
assert(i < m_structs.size());
return m_structs[i];
}
inline std::size_t ShaderAst::GetStructCount() const
{
return m_structs.size();
}
inline auto ShaderAst::GetStructs() const -> const std::vector<Struct>&
{
return m_structs;
}
inline auto ShaderAst::GetUniform(std::size_t i) const -> const Uniform&
{
assert(i < m_uniforms.size());
return m_uniforms[i];
}
inline std::size_t ShaderAst::GetUniformCount() const
{
return m_uniforms.size();
}
inline auto ShaderAst::GetUniforms() const -> const std::vector<Uniform>&
{
return m_uniforms;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTCACHE_HPP
#define NAZARA_SHADERASTCACHE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstExpressionType.hpp>
#include <Nazara/Utility/Enums.hpp>
namespace Nz::ShaderAst
{
struct AstCache
{
struct Variable
{
ShaderExpressionType type;
};
struct Identifier
{
std::string name;
std::variant<Variable, StructDescription> value;
};
struct Scope
{
std::optional<std::size_t> parentScopeIndex;
std::vector<Identifier> identifiers;
};
inline const Identifier* FindIdentifier(std::size_t startingScopeId, const std::string& identifierName) const;
inline std::size_t GetScopeId(const Node* node) const;
ShaderStageType stageType = ShaderStageType::Undefined;
std::unordered_map<const Expression*, ShaderExpressionType> nodeExpressionType;
std::unordered_map<const Node*, std::size_t> scopeIdByNode;
std::vector<Scope> scopes;
};
}
#include <Nazara/Shader/ShaderAstCache.inl>
#endif

View File

@@ -0,0 +1,37 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderAstCache.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderAst
{
inline auto AstCache::FindIdentifier(std::size_t startingScopeId, const std::string& identifierName) const -> const Identifier*
{
assert(startingScopeId < scopes.size());
std::optional<std::size_t> scopeId = startingScopeId;
do
{
const auto& scope = scopes[*scopeId];
auto it = std::find_if(scope.identifiers.rbegin(), scope.identifiers.rend(), [&](const auto& identifier) { return identifier.name == identifierName; });
if (it != scope.identifiers.rend())
return &*it;
scopeId = scope.parentScopeIndex;
} while (scopeId);
return nullptr;
}
inline std::size_t AstCache::GetScopeId(const Node* node) const
{
auto it = scopeIdByNode.find(node);
assert(it == scopeIdByNode.end());
return it->second;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -9,70 +9,62 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitor.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitor.hpp>
#include <vector>
namespace Nz
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API ShaderAstCloner : public ShaderAstVisitor, public ShaderVarVisitor
class NAZARA_SHADER_API AstCloner : public AstExpressionVisitor, public AstStatementVisitor
{
public:
ShaderAstCloner() = default;
ShaderAstCloner(const ShaderAstCloner&) = delete;
ShaderAstCloner(ShaderAstCloner&&) = delete;
~ShaderAstCloner() = default;
AstCloner() = default;
AstCloner(const AstCloner&) = delete;
AstCloner(AstCloner&&) = delete;
~AstCloner() = default;
ShaderNodes::StatementPtr Clone(const ShaderNodes::StatementPtr& statement);
ExpressionPtr Clone(ExpressionPtr& statement);
StatementPtr Clone(StatementPtr& statement);
ShaderAstCloner& operator=(const ShaderAstCloner&) = delete;
ShaderAstCloner& operator=(ShaderAstCloner&&) = delete;
AstCloner& operator=(const AstCloner&) = delete;
AstCloner& operator=(AstCloner&&) = delete;
protected:
ShaderNodes::ExpressionPtr CloneExpression(const ShaderNodes::ExpressionPtr& expr);
ShaderNodes::StatementPtr CloneStatement(const ShaderNodes::StatementPtr& statement);
ShaderNodes::VariablePtr CloneVariable(const ShaderNodes::VariablePtr& statement);
ExpressionPtr CloneExpression(ExpressionPtr& expr);
StatementPtr CloneStatement(StatementPtr& statement);
using ShaderAstVisitor::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::NoOp& node) override;
void Visit(ShaderNodes::ReturnStatement& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
using AstExpressionVisitor::Visit;
using AstStatementVisitor::Visit;
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
void Visit(AccessMemberExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
void Visit(ConditionalExpression& node) override;
void Visit(ConstantExpression& node) override;
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;
void Visit(DeclareFunctionStatement& node) override;
void Visit(DeclareStructStatement& node) override;
void Visit(DeclareVariableStatement& node) override;
void Visit(DiscardStatement& node) override;
void Visit(ExpressionStatement& node) override;
void Visit(MultiStatement& node) override;
void Visit(NoOpStatement& node) override;
void Visit(ReturnStatement& node) override;
void PushExpression(ShaderNodes::ExpressionPtr expression);
void PushStatement(ShaderNodes::StatementPtr statement);
void PushVariable(ShaderNodes::VariablePtr variable);
void PushExpression(ExpressionPtr expression);
void PushStatement(StatementPtr statement);
ShaderNodes::ExpressionPtr PopExpression();
ShaderNodes::StatementPtr PopStatement();
ShaderNodes::VariablePtr PopVariable();
ExpressionPtr PopExpression();
StatementPtr PopStatement();
private:
std::vector<ShaderNodes::ExpressionPtr> m_expressionStack;
std::vector<ShaderNodes::StatementPtr> m_statementStack;
std::vector<ShaderNodes::VariablePtr> m_variableStack;
std::vector<ExpressionPtr> m_expressionStack;
std::vector<StatementPtr> m_statementStack;
};
}

View File

@@ -0,0 +1,57 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTEXPRESSIONTYPE_HPP
#define NAZARA_SHADERASTEXPRESSIONTYPE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitor.hpp>
#include <Nazara/Shader/ShaderAstTypes.hpp>
#include <vector>
namespace Nz::ShaderAst
{
struct AstCache;
class NAZARA_SHADER_API ExpressionTypeVisitor : public AstExpressionVisitor
{
public:
ExpressionTypeVisitor() = default;
ExpressionTypeVisitor(const ExpressionTypeVisitor&) = delete;
ExpressionTypeVisitor(ExpressionTypeVisitor&&) = delete;
~ExpressionTypeVisitor() = default;
ShaderExpressionType GetExpressionType(Expression& expression, AstCache* cache);
ExpressionTypeVisitor& operator=(const ExpressionTypeVisitor&) = delete;
ExpressionTypeVisitor& operator=(ExpressionTypeVisitor&&) = delete;
private:
ShaderExpressionType GetExpressionTypeInternal(Expression& expression);
void Visit(Expression& expression);
void Visit(AccessMemberExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
void Visit(ConditionalExpression& node) override;
void Visit(ConstantExpression& node) override;
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
AstCache* m_cache;
std::optional<ShaderExpressionType> m_lastExpressionType;
};
inline ShaderExpressionType GetExpressionType(Expression& expression, AstCache* cache = nullptr);
}
#include <Nazara/Shader/ShaderAstExpressionType.inl>
#endif

View File

@@ -0,0 +1,17 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderAstExpressionType.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderAst
{
inline ShaderExpressionType GetExpressionType(Expression& expression, AstCache* cache)
{
ExpressionTypeVisitor visitor;
return visitor.GetExpressionType(expression, cache);
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTEXPRESSIONVISITOR_HPP
#define NAZARA_SHADERASTEXPRESSIONVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API AstExpressionVisitor
{
public:
AstExpressionVisitor() = default;
AstExpressionVisitor(const AstExpressionVisitor&) = delete;
AstExpressionVisitor(AstExpressionVisitor&&) = delete;
virtual ~AstExpressionVisitor();
#define NAZARA_SHADERAST_EXPRESSION(NodeType) virtual void Visit(NodeType& node) = 0;
#include <Nazara/Shader/ShaderAstNodes.hpp>
AstExpressionVisitor& operator=(const AstExpressionVisitor&) = delete;
AstExpressionVisitor& operator=(AstExpressionVisitor&&) = delete;
};
}
#endif

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTEXPRESSIONVISITOREXCEPT_HPP
#define NAZARA_SHADERASTEXPRESSIONVISITOREXCEPT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitor.hpp>
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API ExpressionVisitorExcept : public AstExpressionVisitor
{
public:
using AstExpressionVisitor::Visit;
#define NAZARA_SHADERAST_EXPRESSION(Node) void Visit(ShaderAst::Node& node) override;
#include <Nazara/Shader/ShaderAstNodes.hpp>
};
}
#endif

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#if !defined(NAZARA_SHADERAST_NODE) && !defined(NAZARA_SHADERAST_EXPRESSION) && !defined(NAZARA_SHADERAST_STATEMENT)
#error You must define NAZARA_SHADERAST_NODE or NAZARA_SHADERAST_EXPRESSION or NAZARA_SHADERAST_STATEMENT before including this file
#endif
#ifndef NAZARA_SHADERAST_NODE
#define NAZARA_SHADERAST_NODE(X)
#endif
#ifndef NAZARA_SHADERAST_NODE_LAST
#define NAZARA_SHADERAST_NODE_LAST(X)
#endif
#ifndef NAZARA_SHADERAST_EXPRESSION
#define NAZARA_SHADERAST_EXPRESSION(X) NAZARA_SHADERAST_NODE(X)
#endif
#ifndef NAZARA_SHADERAST_STATEMENT
#define NAZARA_SHADERAST_STATEMENT(X) NAZARA_SHADERAST_NODE(X)
#endif
#ifndef NAZARA_SHADERAST_STATEMENT_LAST
#define NAZARA_SHADERAST_STATEMENT_LAST(X) NAZARA_SHADERAST_STATEMENT(X)
#endif
NAZARA_SHADERAST_EXPRESSION(AccessMemberExpression)
NAZARA_SHADERAST_EXPRESSION(AssignExpression)
NAZARA_SHADERAST_EXPRESSION(BinaryExpression)
NAZARA_SHADERAST_EXPRESSION(CastExpression)
NAZARA_SHADERAST_EXPRESSION(ConditionalExpression)
NAZARA_SHADERAST_EXPRESSION(ConstantExpression)
NAZARA_SHADERAST_EXPRESSION(IdentifierExpression)
NAZARA_SHADERAST_EXPRESSION(IntrinsicExpression)
NAZARA_SHADERAST_EXPRESSION(SwizzleExpression)
NAZARA_SHADERAST_STATEMENT(BranchStatement)
NAZARA_SHADERAST_STATEMENT(ConditionalStatement)
NAZARA_SHADERAST_STATEMENT(DeclareFunctionStatement)
NAZARA_SHADERAST_STATEMENT(DeclareStructStatement)
NAZARA_SHADERAST_STATEMENT(DeclareVariableStatement)
NAZARA_SHADERAST_STATEMENT(DiscardStatement)
NAZARA_SHADERAST_STATEMENT(ExpressionStatement)
NAZARA_SHADERAST_STATEMENT(MultiStatement)
NAZARA_SHADERAST_STATEMENT(NoOpStatement)
NAZARA_SHADERAST_STATEMENT_LAST(ReturnStatement)
#undef NAZARA_SHADERAST_EXPRESSION
#undef NAZARA_SHADERAST_NODE
#undef NAZARA_SHADERAST_NODE_LAST
#undef NAZARA_SHADERAST_STATEMENT
#undef NAZARA_SHADERAST_STATEMENT_LAST

View File

@@ -12,35 +12,32 @@
#include <Nazara/Shader/ShaderAstCloner.hpp>
#include <vector>
namespace Nz
namespace Nz::ShaderAst
{
class ShaderAst;
class NAZARA_SHADER_API ShaderAstOptimizer : public ShaderAstCloner
class NAZARA_SHADER_API AstOptimizer : public AstCloner
{
public:
ShaderAstOptimizer() = default;
ShaderAstOptimizer(const ShaderAstOptimizer&) = delete;
ShaderAstOptimizer(ShaderAstOptimizer&&) = delete;
~ShaderAstOptimizer() = default;
AstOptimizer() = default;
AstOptimizer(const AstOptimizer&) = delete;
AstOptimizer(AstOptimizer&&) = delete;
~AstOptimizer() = default;
ShaderNodes::StatementPtr Optimise(const ShaderNodes::StatementPtr& statement);
ShaderNodes::StatementPtr Optimise(const ShaderNodes::StatementPtr& statement, const ShaderAst& shader, UInt64 enabledConditions);
StatementPtr Optimise(StatementPtr& statement);
StatementPtr Optimise(StatementPtr& statement, UInt64 enabledConditions);
ShaderAstOptimizer& operator=(const ShaderAstOptimizer&) = delete;
ShaderAstOptimizer& operator=(ShaderAstOptimizer&&) = delete;
AstOptimizer& operator=(const AstOptimizer&) = delete;
AstOptimizer& operator=(AstOptimizer&&) = delete;
protected:
using ShaderAstCloner::Visit;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
using AstCloner::Visit;
void Visit(BinaryExpression& node) override;
void Visit(ConditionalExpression& node) override;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;
template<ShaderNodes::BinaryType Type> void PropagateConstant(const std::shared_ptr<ShaderNodes::Constant>& lhs, const std::shared_ptr<ShaderNodes::Constant>& rhs);
template<BinaryType Type> void PropagateConstant(std::unique_ptr<ConstantExpression>&& lhs, std::unique_ptr<ConstantExpression>&& rhs);
private:
const ShaderAst* m_shaderAst;
UInt64 m_enabledConditions;
};
}

View File

@@ -9,36 +9,37 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitor.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitor.hpp>
namespace Nz
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API ShaderAstRecursiveVisitor : public ShaderAstVisitor
class NAZARA_SHADER_API AstRecursiveVisitor : public AstExpressionVisitor, public AstStatementVisitor
{
public:
ShaderAstRecursiveVisitor() = default;
~ShaderAstRecursiveVisitor() = default;
AstRecursiveVisitor() = default;
~AstRecursiveVisitor() = default;
using ShaderAstVisitor::Visit;
void Visit(AccessMemberExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
void Visit(ConditionalExpression& node) override;
void Visit(ConstantExpression& node) override;
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::NoOp& node) override;
void Visit(ShaderNodes::ReturnStatement& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;
void Visit(DeclareFunctionStatement& node) override;
void Visit(DeclareStructStatement& node) override;
void Visit(DeclareVariableStatement& node) override;
void Visit(DiscardStatement& node) override;
void Visit(ExpressionStatement& node) override;
void Visit(MultiStatement& node) override;
void Visit(NoOpStatement& node) override;
void Visit(ReturnStatement& node) override;
};
}

View File

@@ -11,40 +11,38 @@
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
namespace Nz
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API ShaderAstSerializerBase
class NAZARA_SHADER_API AstSerializerBase
{
public:
ShaderAstSerializerBase() = default;
ShaderAstSerializerBase(const ShaderAstSerializerBase&) = delete;
ShaderAstSerializerBase(ShaderAstSerializerBase&&) = delete;
~ShaderAstSerializerBase() = default;
AstSerializerBase() = default;
AstSerializerBase(const AstSerializerBase&) = delete;
AstSerializerBase(AstSerializerBase&&) = delete;
~AstSerializerBase() = default;
void Serialize(ShaderNodes::AccessMember& node);
void Serialize(ShaderNodes::AssignOp& node);
void Serialize(ShaderNodes::BinaryOp& node);
void Serialize(ShaderNodes::BuiltinVariable& var);
void Serialize(ShaderNodes::Branch& node);
void Serialize(ShaderNodes::Cast& node);
void Serialize(ShaderNodes::ConditionalExpression& node);
void Serialize(ShaderNodes::ConditionalStatement& node);
void Serialize(ShaderNodes::Constant& node);
void Serialize(ShaderNodes::DeclareVariable& node);
void Serialize(ShaderNodes::Discard& node);
void Serialize(ShaderNodes::ExpressionStatement& node);
void Serialize(ShaderNodes::Identifier& node);
void Serialize(ShaderNodes::IntrinsicCall& node);
void Serialize(ShaderNodes::NamedVariable& var);
void Serialize(ShaderNodes::NoOp& node);
void Serialize(ShaderNodes::ReturnStatement& node);
void Serialize(ShaderNodes::Sample2D& node);
void Serialize(ShaderNodes::StatementBlock& node);
void Serialize(ShaderNodes::SwizzleOp& node);
void Serialize(AccessMemberExpression& node);
void Serialize(AssignExpression& node);
void Serialize(BinaryExpression& node);
void Serialize(CastExpression& node);
void Serialize(ConditionalExpression& node);
void Serialize(ConstantExpression& node);
void Serialize(IdentifierExpression& node);
void Serialize(IntrinsicExpression& node);
void Serialize(SwizzleExpression& node);
void Serialize(BranchStatement& node);
void Serialize(ConditionalStatement& node);
void Serialize(DeclareFunctionStatement& node);
void Serialize(DeclareStructStatement& node);
void Serialize(DeclareVariableStatement& node);
void Serialize(DiscardStatement& node);
void Serialize(ExpressionStatement& node);
void Serialize(MultiStatement& node);
void Serialize(NoOpStatement& node);
void Serialize(ReturnStatement& node);
protected:
template<typename T> void Container(T& container);
@@ -54,8 +52,8 @@ namespace Nz
virtual bool IsWriting() const = 0;
virtual void Node(ShaderNodes::NodePtr& node) = 0;
template<typename T> void Node(std::shared_ptr<T>& node);
virtual void Node(ExpressionPtr& node) = 0;
virtual void Node(StatementPtr& node) = 0;
virtual void Type(ShaderExpressionType& type) = 0;
@@ -74,23 +72,20 @@ namespace Nz
virtual void Value(UInt32& val) = 0;
virtual void Value(UInt64& val) = 0;
inline void SizeT(std::size_t& val);
virtual void Variable(ShaderNodes::VariablePtr& var) = 0;
template<typename T> void Variable(std::shared_ptr<T>& var);
};
class NAZARA_SHADER_API ShaderAstSerializer final : public ShaderAstSerializerBase
class NAZARA_SHADER_API ShaderAstSerializer final : public AstSerializerBase
{
public:
inline ShaderAstSerializer(ByteStream& stream);
~ShaderAstSerializer() = default;
void Serialize(const ShaderAst& shader);
void Serialize(StatementPtr& shader);
private:
bool IsWriting() const override;
void Node(const ShaderNodes::NodePtr& node);
void Node(ShaderNodes::NodePtr& node) override;
void Node(ExpressionPtr& node) override;
void Node(StatementPtr& node) override;
void Type(ShaderExpressionType& type) override;
void Value(bool& val) override;
void Value(float& val) override;
@@ -106,22 +101,22 @@ namespace Nz
void Value(UInt16& val) override;
void Value(UInt32& val) override;
void Value(UInt64& val) override;
void Variable(ShaderNodes::VariablePtr& var) override;
ByteStream& m_stream;
};
class NAZARA_SHADER_API ShaderAstUnserializer final : public ShaderAstSerializerBase
class NAZARA_SHADER_API ShaderAstUnserializer final : public AstSerializerBase
{
public:
ShaderAstUnserializer(ByteStream& stream);
~ShaderAstUnserializer() = default;
ShaderAst Unserialize();
StatementPtr Unserialize();
private:
bool IsWriting() const override;
void Node(ShaderNodes::NodePtr& node) override;
void Node(ExpressionPtr& node) override;
void Node(StatementPtr& node) override;
void Type(ShaderExpressionType& type) override;
void Value(bool& val) override;
void Value(float& val) override;
@@ -137,14 +132,13 @@ namespace Nz
void Value(UInt16& val) override;
void Value(UInt32& val) override;
void Value(UInt64& val) override;
void Variable(ShaderNodes::VariablePtr& var) override;
ByteStream& m_stream;
};
NAZARA_SHADER_API ByteArray SerializeShader(const ShaderAst& shader);
inline ShaderAst UnserializeShader(const void* data, std::size_t size);
NAZARA_SHADER_API ShaderAst UnserializeShader(ByteStream& 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);
}
#include <Nazara/Shader/ShaderAstSerializer.inl>

View File

@@ -5,10 +5,10 @@
#include <Nazara/Shader/ShaderAstSerializer.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
namespace Nz::ShaderAst
{
template<typename T>
void ShaderAstSerializerBase::Container(T& container)
void AstSerializerBase::Container(T& container)
{
bool isWriting = IsWriting();
@@ -23,7 +23,7 @@ namespace Nz
template<typename T>
void ShaderAstSerializerBase::Enum(T& enumVal)
void AstSerializerBase::Enum(T& enumVal)
{
bool isWriting = IsWriting();
@@ -37,7 +37,7 @@ namespace Nz
}
template<typename T>
void ShaderAstSerializerBase::OptEnum(std::optional<T>& optVal)
void AstSerializerBase::OptEnum(std::optional<T>& optVal)
{
bool isWriting = IsWriting();
@@ -55,7 +55,7 @@ namespace Nz
}
template<typename T>
void ShaderAstSerializerBase::OptVal(std::optional<T>& optVal)
void AstSerializerBase::OptVal(std::optional<T>& optVal)
{
bool isWriting = IsWriting();
@@ -77,21 +77,7 @@ namespace Nz
}
}
template<typename T>
void ShaderAstSerializerBase::Node(std::shared_ptr<T>& node)
{
bool isWriting = IsWriting();
ShaderNodes::NodePtr value;
if (isWriting)
value = node;
Node(value);
if (!isWriting)
node = std::static_pointer_cast<T>(value);
}
inline void ShaderAstSerializerBase::SizeT(std::size_t& val)
inline void AstSerializerBase::SizeT(std::size_t& val)
{
bool isWriting = IsWriting();
@@ -105,20 +91,6 @@ namespace Nz
val = static_cast<std::size_t>(fixedVal);
}
template<typename T>
void ShaderAstSerializerBase::Variable(std::shared_ptr<T>& var)
{
bool isWriting = IsWriting();
ShaderNodes::VariablePtr value;
if (isWriting)
value = var;
Variable(value);
if (!isWriting)
var = std::static_pointer_cast<T>(value);
}
inline ShaderAstSerializer::ShaderAstSerializer(ByteStream& stream) :
m_stream(stream)
{
@@ -129,7 +101,7 @@ namespace Nz
{
}
inline ShaderAst UnserializeShader(const void* data, std::size_t size)
inline StatementPtr UnserializeShader(const void* data, std::size_t size)
{
ByteStream byteStream(data, size);
return UnserializeShader(byteStream);

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTSTATEMENTVISITOR_HPP
#define NAZARA_SHADERASTSTATEMENTVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API AstStatementVisitor
{
public:
AstStatementVisitor() = default;
AstStatementVisitor(const AstStatementVisitor&) = delete;
AstStatementVisitor(AstStatementVisitor&&) = delete;
virtual ~AstStatementVisitor();
#define NAZARA_SHADERAST_STATEMENT(NodeType) virtual void Visit(ShaderAst::NodeType& node) = 0;
#include <Nazara/Shader/ShaderAstNodes.hpp>
AstStatementVisitor& operator=(const AstStatementVisitor&) = delete;
AstStatementVisitor& operator=(AstStatementVisitor&&) = delete;
};
}
#endif

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTSTATEMENTVISITOREXCEPT_HPP
#define NAZARA_SHADERASTSTATEMENTVISITOREXCEPT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitor.hpp>
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API StatementVisitorExcept : public AstStatementVisitor
{
public:
using AstStatementVisitor::Visit;
#define NAZARA_SHADERAST_STATEMENT(Node) void Visit(ShaderAst::Node& node) override;
#include <Nazara/Shader/ShaderAstNodes.hpp>
};
}
#endif

View File

@@ -4,17 +4,30 @@
#pragma once
#ifndef NAZARA_SHADER_EXPRESSIONTYPE_HPP
#define NAZARA_SHADER_EXPRESSIONTYPE_HPP
#ifndef NAZARA_SHADER_ASTTYPES_HPP
#define NAZARA_SHADER_ASTTYPES_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <string>
#include <variant>
#include <vector>
namespace Nz
namespace Nz::ShaderAst
{
using ShaderExpressionType = std::variant<ShaderNodes::BasicType, std::string>;
using ShaderExpressionType = std::variant<BasicType, std::string>;
struct StructDescription
{
struct StructMember
{
std::string name;
ShaderExpressionType type;
};
std::string name;
std::vector<StructMember> members;
};
inline bool IsBasicType(const ShaderExpressionType& type);
inline bool IsMatrixType(const ShaderExpressionType& type);
@@ -22,6 +35,6 @@ namespace Nz
inline bool IsStructType(const ShaderExpressionType& type);
}
#include <Nazara/Shader/ShaderExpressionType.inl>
#include <Nazara/Shader/ShaderAstTypes.inl>
#endif // NAZARA_SHADER_EXPRESSIONTYPE_HPP
#endif // NAZARA_SHADER_ASTTYPES_HPP

View File

@@ -2,18 +2,18 @@
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderAstTypes.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
namespace Nz::ShaderAst
{
inline bool IsBasicType(const ShaderExpressionType& type)
{
return std::visit([&](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ShaderNodes::BasicType>)
if constexpr (std::is_same_v<T, BasicType>)
return true;
else if constexpr (std::is_same_v<T, std::string>)
return false;
@@ -25,8 +25,6 @@ namespace Nz
inline bool IsMatrixType(const ShaderExpressionType& type)
{
using namespace ShaderNodes;
if (!IsBasicType(type))
return false;
@@ -58,8 +56,6 @@ namespace Nz
inline bool IsSamplerType(const ShaderExpressionType& type)
{
using namespace ShaderNodes;
if (!IsBasicType(type))
return false;
@@ -94,7 +90,7 @@ namespace Nz
return std::visit([&](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ShaderNodes::BasicType>)
if constexpr (std::is_same_v<T, BasicType>)
return false;
else if constexpr (std::is_same_v<T, std::string>)
return true;

View File

@@ -10,14 +10,12 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitor.hpp>
#include <vector>
namespace Nz
namespace Nz::ShaderAst
{
class ShaderAst;
class NAZARA_SHADER_API ShaderAstValueCategory final : public ShaderAstVisitorExcept
class NAZARA_SHADER_API ShaderAstValueCategory final : public AstExpressionVisitor
{
public:
ShaderAstValueCategory() = default;
@@ -25,28 +23,28 @@ namespace Nz
ShaderAstValueCategory(ShaderAstValueCategory&&) = delete;
~ShaderAstValueCategory() = default;
ShaderNodes::ExpressionCategory GetExpressionCategory(const ShaderNodes::ExpressionPtr& expression);
ExpressionCategory GetExpressionCategory(Expression& expression);
ShaderAstValueCategory& operator=(const ShaderAstValueCategory&) = delete;
ShaderAstValueCategory& operator=(ShaderAstValueCategory&&) = delete;
private:
using ShaderAstVisitorExcept::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
using AstExpressionVisitor::Visit;
ShaderNodes::ExpressionCategory m_expressionCategory;
void Visit(AccessMemberExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
void Visit(ConditionalExpression& node) override;
void Visit(ConstantExpression& node) override;
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
ExpressionCategory m_expressionCategory;
};
inline ShaderNodes::ExpressionCategory GetExpressionCategory(const ShaderNodes::ExpressionPtr& expression);
inline ExpressionCategory GetExpressionCategory(Expression& expression);
}
#include <Nazara/Shader/ShaderAstUtils.inl>

View File

@@ -5,9 +5,9 @@
#include <Nazara/Shader/ShaderAstUtils.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
namespace Nz::ShaderAst
{
ShaderNodes::ExpressionCategory GetExpressionCategory(const ShaderNodes::ExpressionPtr& expression)
ExpressionCategory GetExpressionCategory(Expression& expression)
{
ShaderAstValueCategory visitor;
return visitor.GetExpressionCategory(expression);

View File

@@ -8,66 +8,62 @@
#define NAZARA_SHADERVALIDATOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderAstCache.hpp>
#include <Nazara/Shader/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Utility/Enums.hpp>
namespace Nz
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API ShaderAstValidator : public ShaderAstRecursiveVisitor, public ShaderVarVisitor
class NAZARA_SHADER_API AstValidator : public AstRecursiveVisitor
{
public:
inline ShaderAstValidator(const ShaderAst& shader);
ShaderAstValidator(const ShaderAstValidator&) = delete;
ShaderAstValidator(ShaderAstValidator&&) = delete;
~ShaderAstValidator() = default;
inline AstValidator();
AstValidator(const AstValidator&) = delete;
AstValidator(AstValidator&&) = delete;
~AstValidator() = default;
bool Validate(std::string* error = nullptr);
bool Validate(StatementPtr& node, std::string* error = nullptr, AstCache* cache = nullptr);
private:
const ShaderNodes::ExpressionPtr& MandatoryExpr(const ShaderNodes::ExpressionPtr& node);
const ShaderNodes::NodePtr& MandatoryNode(const ShaderNodes::NodePtr& node);
void TypeMustMatch(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right);
Expression& MandatoryExpr(ExpressionPtr& node);
Statement& MandatoryStatement(StatementPtr& node);
void TypeMustMatch(ExpressionPtr& left, ExpressionPtr& right);
void TypeMustMatch(const ShaderExpressionType& left, const ShaderExpressionType& right);
const ShaderAst::StructMember& CheckField(const std::string& structName, std::size_t* memberIndex, std::size_t remainingMembers);
ShaderExpressionType CheckField(const std::string& structName, const std::string* memberIdentifier, std::size_t remainingMembers);
using ShaderAstRecursiveVisitor::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::ReturnStatement& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
AstCache::Scope& EnterScope();
void ExitScope();
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
void RegisterExpressionType(Expression& node, ShaderExpressionType expressionType);
void RegisterScope(Node& node);
void Visit(AccessMemberExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
void Visit(ConditionalExpression& node) override;
void Visit(ConstantExpression& node) override;
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;
void Visit(DeclareFunctionStatement& node) override;
void Visit(DeclareStructStatement& node) override;
void Visit(DeclareVariableStatement& node) override;
void Visit(ExpressionStatement& node) override;
void Visit(MultiStatement& node) override;
void Visit(ReturnStatement& node) override;
struct Context;
const ShaderAst& m_shader;
Context* m_context;
};
NAZARA_SHADER_API bool ValidateShader(const ShaderAst& shader, std::string* error = nullptr);
NAZARA_SHADER_API bool ValidateAst(StatementPtr& node, std::string* error = nullptr, AstCache* cache = nullptr);
}
#include <Nazara/Shader/ShaderAstValidator.inl>

View File

@@ -5,10 +5,10 @@
#include <Nazara/Shader/ShaderAstValidator.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz
namespace Nz::ShaderAst
{
ShaderAstValidator::ShaderAstValidator(const ShaderAst& shader) :
m_shader(shader)
AstValidator::AstValidator() :
m_context(nullptr)
{
}
}

View File

@@ -1,49 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTVISITOR_HPP
#define NAZARA_SHADERASTVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstVisitor
{
public:
ShaderAstVisitor() = default;
ShaderAstVisitor(const ShaderAstVisitor&) = delete;
ShaderAstVisitor(ShaderAstVisitor&&) = delete;
virtual ~ShaderAstVisitor();
void Visit(const ShaderNodes::NodePtr& node);
virtual void Visit(ShaderNodes::AccessMember& node) = 0;
virtual void Visit(ShaderNodes::AssignOp& node) = 0;
virtual void Visit(ShaderNodes::BinaryOp& node) = 0;
virtual void Visit(ShaderNodes::Branch& node) = 0;
virtual void Visit(ShaderNodes::Cast& node) = 0;
virtual void Visit(ShaderNodes::ConditionalExpression& node) = 0;
virtual void Visit(ShaderNodes::ConditionalStatement& node) = 0;
virtual void Visit(ShaderNodes::Constant& node) = 0;
virtual void Visit(ShaderNodes::DeclareVariable& node) = 0;
virtual void Visit(ShaderNodes::Discard& node) = 0;
virtual void Visit(ShaderNodes::ExpressionStatement& node) = 0;
virtual void Visit(ShaderNodes::Identifier& node) = 0;
virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0;
virtual void Visit(ShaderNodes::NoOp& node) = 0;
virtual void Visit(ShaderNodes::ReturnStatement& node) = 0;
virtual void Visit(ShaderNodes::Sample2D& node) = 0;
virtual void Visit(ShaderNodes::StatementBlock& node) = 0;
virtual void Visit(ShaderNodes::SwizzleOp& node) = 0;
ShaderAstVisitor& operator=(const ShaderAstVisitor&) = delete;
ShaderAstVisitor& operator=(ShaderAstVisitor&&) = delete;
};
}
#endif

View File

@@ -1,41 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERASTVISITOREXCEPT_HPP
#define NAZARA_SHADERASTVISITOREXCEPT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderAstVisitorExcept : public ShaderAstVisitor
{
public:
using ShaderAstVisitor::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::NoOp& node) override;
void Visit(ShaderNodes::ReturnStatement& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
};
}
#endif

View File

@@ -13,70 +13,60 @@
namespace Nz::ShaderBuilder
{
template<ShaderNodes::AssignType op>
struct AssignOpBuilder
namespace Impl
{
constexpr AssignOpBuilder() = default;
struct Binary
{
inline std::unique_ptr<ShaderAst::BinaryExpression> operator()(ShaderAst::BinaryType op, ShaderAst::ExpressionPtr left, ShaderAst::ExpressionPtr right) const;
};
std::shared_ptr<ShaderNodes::AssignOp> operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const;
};
struct Branch
{
inline std::unique_ptr<ShaderAst::BranchStatement> operator()(ShaderAst::ExpressionPtr condition, ShaderAst::StatementPtr truePath, ShaderAst::StatementPtr falsePath = nullptr) const;
inline std::unique_ptr<ShaderAst::BranchStatement> operator()(std::vector<ShaderAst::BranchStatement::ConditionalStatement> condStatements, ShaderAst::StatementPtr elseStatement = nullptr) const;
};
template<ShaderNodes::BinaryType op>
struct BinOpBuilder
{
constexpr BinOpBuilder() = default;
struct Constant
{
inline std::unique_ptr<ShaderAst::ConstantExpression> operator()(ShaderConstantValue value) const;
};
std::shared_ptr<ShaderNodes::BinaryOp> operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const;
};
struct DeclareFunction
{
inline std::unique_ptr<ShaderAst::DeclareFunctionStatement> operator()(std::string name, std::vector<ShaderAst::DeclareFunctionStatement::Parameter> parameters, std::vector<ShaderAst::StatementPtr> statements, ShaderAst::ShaderExpressionType returnType = ShaderAst::BasicType::Void) const;
};
struct BuiltinBuilder
{
constexpr BuiltinBuilder() = default;
struct DeclareVariable
{
inline std::unique_ptr<ShaderAst::DeclareVariableStatement> operator()(std::string name, ShaderAst::ShaderExpressionType type, ShaderAst::ExpressionPtr initialValue = nullptr) const;
};
inline std::shared_ptr<ShaderNodes::Variable> operator()(ShaderNodes::BuiltinEntry builtin) const;
};
struct Identifier
{
inline std::unique_ptr<ShaderAst::IdentifierExpression> operator()(std::string name) const;
};
template<typename T>
struct GenBuilder
{
constexpr GenBuilder() = default;
struct Return
{
inline std::unique_ptr<ShaderAst::ReturnStatement> operator()(ShaderAst::ExpressionPtr expr = nullptr) const;
};
template<typename... Args> std::shared_ptr<T> operator()(Args&&... args) const;
};
template<typename T>
struct NoParam
{
std::unique_ptr<T> operator()() const;
};
}
constexpr GenBuilder<ShaderNodes::AccessMember> AccessMember;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Add> Add;
constexpr AssignOpBuilder<ShaderNodes::AssignType::Simple> Assign;
constexpr BuiltinBuilder Builtin;
constexpr GenBuilder<ShaderNodes::StatementBlock> Block;
constexpr GenBuilder<ShaderNodes::Branch> Branch;
constexpr GenBuilder<ShaderNodes::ConditionalExpression> ConditionalExpression;
constexpr GenBuilder<ShaderNodes::ConditionalStatement> ConditionalStatement;
constexpr GenBuilder<ShaderNodes::Constant> Constant;
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
constexpr GenBuilder<ShaderNodes::Discard> Discard;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Division;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompEq> Equal;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompGt> GreaterThan;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompGe> GreaterThanOrEqual;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompLt> LessThan;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompLe> LessThanOrEqual;
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompNe> NotEqual;
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
constexpr GenBuilder<ShaderNodes::Identifier> Identifier;
constexpr GenBuilder<ShaderNodes::IntrinsicCall> IntrinsicCall;
constexpr GenBuilder<ShaderNodes::InputVariable> Input;
constexpr GenBuilder<ShaderNodes::LocalVariable> Local;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Multiply> Multiply;
constexpr GenBuilder<ShaderNodes::OutputVariable> Output;
constexpr GenBuilder<ShaderNodes::ParameterVariable> Parameter;
constexpr GenBuilder<ShaderNodes::Sample2D> Sample2D;
constexpr GenBuilder<ShaderNodes::StatementBlock> StatementBlock;
constexpr GenBuilder<ShaderNodes::SwizzleOp> Swizzle;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Subtract> Subtract;
constexpr GenBuilder<ShaderNodes::UniformVariable> Uniform;
template<ShaderNodes::BasicType Type, typename... Args> std::shared_ptr<ShaderNodes::Cast> Cast(Args&&... args);
constexpr Impl::Binary Binary;
constexpr Impl::Branch Branch;
constexpr Impl::Constant Constant;
constexpr Impl::DeclareFunction DeclareFunction;
constexpr Impl::DeclareVariable DeclareVariable;
constexpr Impl::NoParam<ShaderAst::DiscardStatement> Discard;
constexpr Impl::Identifier Identifier;
constexpr Impl::NoParam<ShaderAst::NoOpStatement> NoOp;
constexpr Impl::Return Return;
}
#include <Nazara/Shader/ShaderBuilder.inl>

View File

@@ -7,45 +7,87 @@
namespace Nz::ShaderBuilder
{
inline std::unique_ptr<ShaderAst::BinaryExpression> Impl::Binary::operator()(ShaderAst::BinaryType op, ShaderAst::ExpressionPtr left, ShaderAst::ExpressionPtr right) const
{
auto constantNode = std::make_unique<ShaderAst::BinaryExpression>();
constantNode->op = op;
constantNode->left = std::move(left);
constantNode->right = std::move(right);
return constantNode;
}
inline std::unique_ptr<ShaderAst::BranchStatement> Impl::Branch::operator()(ShaderAst::ExpressionPtr condition, ShaderAst::StatementPtr truePath, ShaderAst::StatementPtr falsePath) const
{
auto branchNode = std::make_unique<ShaderAst::BranchStatement>();
auto& condStatement = branchNode->condStatements.emplace_back();
condStatement.condition = std::move(condition);
condStatement.statement = std::move(truePath);
branchNode->elseStatement = std::move(falsePath);
return branchNode;
}
inline std::unique_ptr<ShaderAst::BranchStatement> Impl::Branch::operator()(std::vector<ShaderAst::BranchStatement::ConditionalStatement> condStatements, ShaderAst::StatementPtr elseStatement) const
{
auto branchNode = std::make_unique<ShaderAst::BranchStatement>();
branchNode->condStatements = std::move(condStatements);
branchNode->elseStatement = std::move(elseStatement);
return branchNode;
}
inline std::unique_ptr<ShaderAst::ConstantExpression> Impl::Constant::operator()(ShaderConstantValue value) const
{
auto constantNode = std::make_unique<ShaderAst::ConstantExpression>();
constantNode->value = std::move(value);
return constantNode;
}
inline std::unique_ptr<ShaderAst::DeclareFunctionStatement> Impl::DeclareFunction::operator()(std::string name, std::vector<ShaderAst::DeclareFunctionStatement::Parameter> parameters, std::vector<ShaderAst::StatementPtr> statements, ShaderAst::ShaderExpressionType returnType) const
{
auto declareFunctionNode = std::make_unique<ShaderAst::DeclareFunctionStatement>();
declareFunctionNode->name = std::move(name);
declareFunctionNode->parameters = std::move(parameters);
declareFunctionNode->returnType = std::move(returnType);
declareFunctionNode->statements = std::move(statements);
return declareFunctionNode;
}
inline std::unique_ptr<ShaderAst::DeclareVariableStatement> Nz::ShaderBuilder::Impl::DeclareVariable::operator()(std::string name, ShaderAst::ShaderExpressionType type, ShaderAst::ExpressionPtr initialValue) const
{
auto declareVariableNode = std::make_unique<ShaderAst::DeclareVariableStatement>();
declareVariableNode->varName = std::move(name);
declareVariableNode->varType = std::move(type);
declareVariableNode->initialExpression = std::move(initialValue);
return declareVariableNode;
}
inline std::unique_ptr<ShaderAst::IdentifierExpression> Impl::Identifier::operator()(std::string name) const
{
auto identifierNode = std::make_unique<ShaderAst::IdentifierExpression>();
identifierNode->identifier = std::move(name);
return identifierNode;
}
inline std::unique_ptr<ShaderAst::ReturnStatement> Impl::Return::operator()(ShaderAst::ExpressionPtr expr) const
{
auto returnNode = std::make_unique<ShaderAst::ReturnStatement>();
returnNode->returnExpr = std::move(expr);
return returnNode;
}
template<typename T>
template<typename... Args>
std::shared_ptr<T> GenBuilder<T>::operator()(Args&&... args) const
std::unique_ptr<T> Impl::NoParam<T>::operator()() const
{
return T::Build(std::forward<Args>(args)...);
}
template<ShaderNodes::AssignType op>
std::shared_ptr<ShaderNodes::AssignOp> AssignOpBuilder<op>::operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const
{
return ShaderNodes::AssignOp::Build(op, left, right);
}
template<ShaderNodes::BinaryType op>
std::shared_ptr<ShaderNodes::BinaryOp> BinOpBuilder<op>::operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const
{
return ShaderNodes::BinaryOp::Build(op, left, right);
}
inline std::shared_ptr<ShaderNodes::Variable> BuiltinBuilder::operator()(ShaderNodes::BuiltinEntry builtin) const
{
ShaderNodes::BasicType exprType = ShaderNodes::BasicType::Void;
switch (builtin)
{
case ShaderNodes::BuiltinEntry::VertexPosition:
exprType = ShaderNodes::BasicType::Float4;
break;
}
NazaraAssert(exprType != ShaderNodes::BasicType::Void, "Unhandled builtin");
return ShaderNodes::BuiltinVariable::Build(builtin, exprType);
}
template<ShaderNodes::BasicType Type, typename... Args>
std::shared_ptr<ShaderNodes::Cast> Cast(Args&&... args)
{
return ShaderNodes::Cast::Build(Type, std::forward<Args>(args)...);
return std::make_unique<T>();
}
}

View File

@@ -9,7 +9,7 @@
#include <Nazara/Prerequisites.hpp>
namespace Nz::ShaderNodes
namespace Nz::ShaderAst
{
enum class AssignType
{
@@ -77,35 +77,9 @@ namespace Nz::ShaderNodes
{
None = -1,
AccessMember,
AssignOp,
BinaryOp,
Branch,
Cast,
Constant,
ConditionalExpression,
ConditionalStatement,
DeclareVariable,
Discard,
ExpressionStatement,
Identifier,
IntrinsicCall,
NoOp,
ReturnStatement,
Sample2D,
SwizzleOp,
StatementBlock,
Max = StatementBlock
};
enum class SsaInstruction
{
OpAdd,
OpDiv,
OpMul,
OpSub,
OpSample
#define NAZARA_SHADERAST_NODE(Node) Node,
#define NAZARA_SHADERAST_STATEMENT_LAST(Node) Node, Max = Node
#include <Nazara/Shader/ShaderAstNodes.hpp>
};
enum class SwizzleComponent
@@ -127,6 +101,11 @@ namespace Nz::ShaderNodes
ParameterVariable,
UniformVariable
};
inline std::size_t GetComponentCount(BasicType type);
inline BasicType GetComponentType(BasicType type);
}
#include <Nazara/Shader/ShaderEnums.inl>
#endif // NAZARA_SHADER_ENUMS_HPP

View File

@@ -0,0 +1,57 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderAst
{
inline std::size_t GetComponentCount(BasicType type)
{
switch (type)
{
case BasicType::Float2:
case BasicType::Int2:
return 2;
case BasicType::Float3:
case BasicType::Int3:
return 3;
case BasicType::Float4:
case BasicType::Int4:
return 4;
case BasicType::Mat4x4:
return 4;
default:
return 1;
}
}
inline BasicType GetComponentType(BasicType type)
{
switch (type)
{
case BasicType::Float2:
case BasicType::Float3:
case BasicType::Float4:
return BasicType::Float1;
case BasicType::Int2:
case BasicType::Int3:
case BasicType::Int4:
return BasicType::Int1;
case BasicType::Mat4x4:
return BasicType::Float4;
default:
return type;
}
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -10,7 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderLangLexer.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
namespace Nz::ShaderLang
{
@@ -44,7 +44,7 @@ namespace Nz::ShaderLang
inline Parser();
~Parser() = default;
ShaderAst Parse(const std::vector<Token>& tokens);
ShaderAst::StatementPtr Parse(const std::vector<Token>& tokens);
private:
// Flow control
@@ -54,29 +54,30 @@ namespace Nz::ShaderLang
const Token& PeekNext();
// Statements
ShaderNodes::StatementPtr ParseFunctionBody();
void ParseFunctionDeclaration();
ShaderAst::FunctionParameter ParseFunctionParameter();
ShaderNodes::StatementPtr ParseReturnStatement();
ShaderNodes::StatementPtr ParseStatement();
ShaderNodes::StatementPtr ParseStatementList();
std::vector<ShaderAst::StatementPtr> ParseFunctionBody();
ShaderAst::StatementPtr ParseFunctionDeclaration();
ShaderAst::DeclareFunctionStatement::Parameter ParseFunctionParameter();
ShaderAst::StatementPtr ParseReturnStatement();
ShaderAst::StatementPtr ParseStatement();
std::vector<ShaderAst::StatementPtr> ParseStatementList();
ShaderAst::StatementPtr ParseVariableDeclaration();
// Expressions
ShaderNodes::ExpressionPtr ParseBinOpRhs(int exprPrecedence, ShaderNodes::ExpressionPtr lhs);
ShaderNodes::ExpressionPtr ParseExpression();
ShaderNodes::ExpressionPtr ParseIdentifier();
ShaderNodes::ExpressionPtr ParseIntegerExpression();
ShaderNodes::ExpressionPtr ParseParenthesisExpression();
ShaderNodes::ExpressionPtr ParsePrimaryExpression();
ShaderAst::ExpressionPtr ParseBinOpRhs(int exprPrecedence, ShaderAst::ExpressionPtr lhs);
ShaderAst::ExpressionPtr ParseExpression();
ShaderAst::ExpressionPtr ParseIdentifier();
ShaderAst::ExpressionPtr ParseIntegerExpression();
ShaderAst::ExpressionPtr ParseParenthesisExpression();
ShaderAst::ExpressionPtr ParsePrimaryExpression();
std::string ParseIdentifierAsName();
ShaderExpressionType ParseIdentifierAsType();
ShaderAst::ShaderExpressionType ParseIdentifierAsType();
static int GetTokenPrecedence(TokenType token);
struct Context
{
ShaderAst result;
std::unique_ptr<ShaderAst::MultiStatement> root;
std::size_t tokenCount;
std::size_t tokenIndex = 0;
const Token* tokens;

View File

@@ -6,10 +6,11 @@
#error You must define NAZARA_SHADERLANG_TOKEN before including this file
#endif
#ifndef NAZARA_SHADERLANG_TOKENT_LAST
#ifndef NAZARA_SHADERLANG_TOKEN_LAST
#define NAZARA_SHADERLANG_TOKEN_LAST(X) NAZARA_SHADERLANG_TOKEN(X)
#endif
NAZARA_SHADERLANG_TOKEN(Assign)
NAZARA_SHADERLANG_TOKEN(BoolFalse)
NAZARA_SHADERLANG_TOKEN(BoolTrue)
NAZARA_SHADERLANG_TOKEN(ClosingParenthesis)
@@ -24,6 +25,7 @@ NAZARA_SHADERLANG_TOKEN(FunctionDeclaration)
NAZARA_SHADERLANG_TOKEN(FunctionReturn)
NAZARA_SHADERLANG_TOKEN(IntegerValue)
NAZARA_SHADERLANG_TOKEN(Identifier)
NAZARA_SHADERLANG_TOKEN(Let)
NAZARA_SHADERLANG_TOKEN(Multiply)
NAZARA_SHADERLANG_TOKEN(Minus)
NAZARA_SHADERLANG_TOKEN(Plus)

View File

@@ -14,308 +14,245 @@
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
#include <Nazara/Shader/ShaderAstTypes.hpp>
#include <array>
#include <memory>
#include <optional>
#include <string>
namespace Nz
namespace Nz::ShaderAst
{
class ShaderAstVisitor;
class AstExpressionVisitor;
class AstStatementVisitor;
namespace ShaderNodes
struct NAZARA_SHADER_API Node
{
class Node;
Node() = default;
Node(const Node&) = delete;
Node(Node&&) noexcept = default;
virtual ~Node();
using NodePtr = std::shared_ptr<Node>;
virtual NodeType GetType() const = 0;
class NAZARA_SHADER_API Node
Node& operator=(const Node&) = delete;
Node& operator=(Node&&) noexcept = default;
};
// Expressions
struct Expression;
using ExpressionPtr = std::unique_ptr<Expression>;
struct NAZARA_SHADER_API Expression : Node
{
Expression() = default;
Expression(const Expression&) = delete;
Expression(Expression&&) noexcept = default;
~Expression() = default;
virtual void Visit(AstExpressionVisitor& visitor) = 0;
Expression& operator=(const Expression&) = delete;
Expression& operator=(Expression&&) noexcept = default;
};
struct NAZARA_SHADER_API AccessMemberExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
ExpressionPtr structExpr;
std::vector<std::string> memberIdentifiers;
};
struct NAZARA_SHADER_API AssignExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
AssignType op;
ExpressionPtr left;
ExpressionPtr right;
};
struct NAZARA_SHADER_API BinaryExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
BinaryType op;
ExpressionPtr left;
ExpressionPtr right;
};
struct NAZARA_SHADER_API CastExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
BasicType targetType;
std::array<ExpressionPtr, 4> expressions;
};
struct NAZARA_SHADER_API ConditionalExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
std::string conditionName;
ExpressionPtr falsePath;
ExpressionPtr truePath;
};
struct NAZARA_SHADER_API ConstantExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
ShaderConstantValue value;
};
struct NAZARA_SHADER_API IdentifierExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
std::string identifier;
};
struct NAZARA_SHADER_API IntrinsicExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
IntrinsicType intrinsic;
std::vector<ExpressionPtr> parameters;
};
struct NAZARA_SHADER_API SwizzleExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
std::array<SwizzleComponent, 4> components;
std::size_t componentCount;
ExpressionPtr expression;
};
// Statements
struct Statement;
using StatementPtr = std::unique_ptr<Statement>;
struct NAZARA_SHADER_API Statement : Node
{
Statement() = default;
Statement(const Statement&) = delete;
Statement(Statement&&) noexcept = default;
~Statement() = default;
virtual void Visit(AstStatementVisitor& visitor) = 0;
Statement& operator=(const Statement&) = delete;
Statement& operator=(Statement&&) noexcept = default;
};
struct NAZARA_SHADER_API BranchStatement : public Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
struct ConditionalStatement
{
public:
virtual ~Node();
inline NodeType GetType() const;
inline bool IsStatement() const;
virtual void Visit(ShaderAstVisitor& visitor) = 0;
static inline unsigned int GetComponentCount(BasicType type);
static inline BasicType GetComponentType(BasicType type);
protected:
inline Node(NodeType type, bool isStatement);
private:
NodeType m_type;
bool m_isStatement;
};
class Expression;
using ExpressionPtr = std::shared_ptr<Expression>;
class NAZARA_SHADER_API Expression : public Node, public std::enable_shared_from_this<Expression>
{
public:
inline Expression(NodeType type);
virtual ShaderExpressionType GetExpressionType() const = 0;
ExpressionPtr condition;
StatementPtr statement;
};
class Statement;
std::vector<ConditionalStatement> condStatements;
StatementPtr elseStatement;
};
using StatementPtr = std::shared_ptr<Statement>;
struct NAZARA_SHADER_API ConditionalStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
class NAZARA_SHADER_API Statement : public Node, public std::enable_shared_from_this<Statement>
std::string conditionName;
StatementPtr statement;
};
struct NAZARA_SHADER_API DeclareFunctionStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
struct Parameter
{
public:
inline Statement(NodeType type);
std::string name;
ShaderExpressionType type;
};
struct NAZARA_SHADER_API ExpressionStatement : public Statement
{
inline ExpressionStatement();
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr expression;
static inline std::shared_ptr<ExpressionStatement> Build(ExpressionPtr expr);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API ConditionalStatement : public Statement
{
inline ConditionalStatement();
void Visit(ShaderAstVisitor& visitor) override;
std::string conditionName;
StatementPtr statement;
static inline std::shared_ptr<ConditionalStatement> Build(std::string condition, StatementPtr statementPtr);
};
struct NAZARA_SHADER_API StatementBlock : public Statement
{
inline StatementBlock();
void Visit(ShaderAstVisitor& visitor) override;
std::vector<StatementPtr> statements;
static inline std::shared_ptr<StatementBlock> Build(std::vector<StatementPtr> statements);
template<typename... Args> static std::shared_ptr<StatementBlock> Build(Args&&... args);
};
struct NAZARA_SHADER_API DeclareVariable : public Statement
{
inline DeclareVariable();
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr expression;
VariablePtr variable;
static inline std::shared_ptr<DeclareVariable> Build(VariablePtr variable, ExpressionPtr expression = nullptr);
};
struct NAZARA_SHADER_API Discard : public Statement
{
inline Discard();
void Visit(ShaderAstVisitor& visitor) override;
static inline std::shared_ptr<Discard> Build();
};
struct NAZARA_SHADER_API Identifier : public Expression
{
inline Identifier();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
VariablePtr var;
static inline std::shared_ptr<Identifier> Build(VariablePtr variable);
};
struct NAZARA_SHADER_API AccessMember : public Expression
{
inline AccessMember();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr structExpr;
ShaderExpressionType exprType;
std::vector<std::size_t> memberIndices;
static inline std::shared_ptr<AccessMember> Build(ExpressionPtr structExpr, std::size_t memberIndex, ShaderExpressionType exprType);
static inline std::shared_ptr<AccessMember> Build(ExpressionPtr structExpr, std::vector<std::size_t> memberIndices, ShaderExpressionType exprType);
};
struct NAZARA_SHADER_API NoOp : public Statement
{
inline NoOp();
void Visit(ShaderAstVisitor& visitor) override;
static inline std::shared_ptr<NoOp> Build();
};
struct NAZARA_SHADER_API ReturnStatement : public Statement
{
inline ReturnStatement();
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr returnExpr;
static inline std::shared_ptr<ReturnStatement> Build(ExpressionPtr expr = nullptr);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API AssignOp : public Expression
{
inline AssignOp();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
AssignType op;
ExpressionPtr left;
ExpressionPtr right;
static inline std::shared_ptr<AssignOp> Build(AssignType op, ExpressionPtr left, ExpressionPtr right);
};
struct NAZARA_SHADER_API BinaryOp : public Expression
{
inline BinaryOp();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
BinaryType op;
ExpressionPtr left;
ExpressionPtr right;
static inline std::shared_ptr<BinaryOp> Build(BinaryType op, ExpressionPtr left, ExpressionPtr right);
};
struct NAZARA_SHADER_API Branch : public Statement
{
struct ConditionalStatement;
inline Branch();
void Visit(ShaderAstVisitor& visitor) override;
std::vector<ConditionalStatement> condStatements;
StatementPtr elseStatement;
struct ConditionalStatement
{
ExpressionPtr condition;
StatementPtr statement;
};
static inline std::shared_ptr<Branch> Build(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement = nullptr);
static inline std::shared_ptr<Branch> Build(std::vector<ConditionalStatement> statements, StatementPtr elseStatement = nullptr);
};
struct NAZARA_SHADER_API Cast : public Expression
{
inline Cast();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
BasicType exprType;
std::array<ExpressionPtr, 4> expressions;
static inline std::shared_ptr<Cast> Build(BasicType castTo, ExpressionPtr first, ExpressionPtr second = nullptr, ExpressionPtr third = nullptr, ExpressionPtr fourth = nullptr);
static inline std::shared_ptr<Cast> Build(BasicType castTo, ExpressionPtr* expressions, std::size_t expressionCount);
};
struct NAZARA_SHADER_API ConditionalExpression : public Expression
{
inline ConditionalExpression();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
std::string conditionName;
ExpressionPtr falsePath;
ExpressionPtr truePath;
static inline std::shared_ptr<ConditionalExpression> Build(std::string condition, ExpressionPtr truePath, ExpressionPtr falsePath);
};
struct NAZARA_SHADER_API Constant : public Expression
{
inline Constant();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
ShaderConstantValue value;
template<typename T> static std::shared_ptr<Constant> Build(const T& value);
};
struct NAZARA_SHADER_API SwizzleOp : public Expression
{
inline SwizzleOp();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
std::array<SwizzleComponent, 4> components;
std::size_t componentCount;
ExpressionPtr expression;
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, SwizzleComponent swizzleComponent);
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, std::initializer_list<SwizzleComponent> swizzleComponents);
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, const SwizzleComponent* components, std::size_t componentCount);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API Sample2D : public Expression
{
inline Sample2D();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr sampler;
ExpressionPtr coordinates;
static inline std::shared_ptr<Sample2D> Build(ExpressionPtr samplerPtr, ExpressionPtr coordinatesPtr);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_SHADER_API IntrinsicCall : public Expression
{
inline IntrinsicCall();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
IntrinsicType intrinsic;
std::vector<ExpressionPtr> parameters;
static inline std::shared_ptr<IntrinsicCall> Build(IntrinsicType intrinsic, std::vector<ExpressionPtr> parameters);
};
}
std::string name;
std::vector<Parameter> parameters;
std::vector<StatementPtr> statements;
ShaderExpressionType returnType = BasicType::Void;
};
struct NAZARA_SHADER_API DeclareStructStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
StructDescription description;
};
struct NAZARA_SHADER_API DeclareVariableStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
std::string varName;
ExpressionPtr initialExpression;
ShaderExpressionType varType;
};
struct NAZARA_SHADER_API DiscardStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
};
struct NAZARA_SHADER_API ExpressionStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
ExpressionPtr expression;
};
struct NAZARA_SHADER_API MultiStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
std::vector<StatementPtr> statements;
};
struct NAZARA_SHADER_API NoOpStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
};
struct NAZARA_SHADER_API ReturnStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
ExpressionPtr returnExpr;
};
}
#include <Nazara/Shader/ShaderNodes.inl>

View File

@@ -5,394 +5,8 @@
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderNodes
namespace Nz::ShaderAst
{
inline Node::Node(NodeType type, bool isStatement) :
m_type(type),
m_isStatement(isStatement)
{
}
inline NodeType ShaderNodes::Node::GetType() const
{
return m_type;
}
inline bool Node::IsStatement() const
{
return m_isStatement;
}
inline unsigned int Node::GetComponentCount(BasicType type)
{
switch (type)
{
case BasicType::Float2:
case BasicType::Int2:
return 2;
case BasicType::Float3:
case BasicType::Int3:
return 3;
case BasicType::Float4:
case BasicType::Int4:
return 4;
case BasicType::Mat4x4:
return 4;
default:
return 1;
}
}
inline BasicType Node::GetComponentType(BasicType type)
{
switch (type)
{
case BasicType::Float2:
case BasicType::Float3:
case BasicType::Float4:
return BasicType::Float1;
case BasicType::Int2:
case BasicType::Int3:
case BasicType::Int4:
return BasicType::Int1;
case BasicType::Mat4x4:
return BasicType::Float4;
default:
return type;
}
}
inline Expression::Expression(NodeType type) :
Node(type, false)
{
}
inline Statement::Statement(NodeType type) :
Node(type, true)
{
}
inline ExpressionStatement::ExpressionStatement() :
Statement(NodeType::ExpressionStatement)
{
}
inline std::shared_ptr<ExpressionStatement> ExpressionStatement::Build(ExpressionPtr expr)
{
auto node = std::make_shared<ExpressionStatement>();
node->expression = std::move(expr);
return node;
}
inline ConditionalStatement::ConditionalStatement() :
Statement(NodeType::ConditionalStatement)
{
}
inline std::shared_ptr<ConditionalStatement> ConditionalStatement::Build(std::string condition, StatementPtr statementPtr)
{
auto node = std::make_shared<ConditionalStatement>();
node->conditionName = std::move(condition);
node->statement = std::move(statementPtr);
return node;
}
inline StatementBlock::StatementBlock() :
Statement(NodeType::StatementBlock)
{
}
inline std::shared_ptr<StatementBlock> StatementBlock::Build(std::vector<StatementPtr> statements)
{
auto node = std::make_shared<StatementBlock>();
node->statements = std::move(statements);
return node;
}
template<typename... Args>
std::shared_ptr<StatementBlock> StatementBlock::Build(Args&&... args)
{
auto node = std::make_shared<StatementBlock>();
node->statements = std::vector<StatementPtr>({ std::forward<Args>(args)... });
return node;
}
inline DeclareVariable::DeclareVariable() :
Statement(NodeType::DeclareVariable)
{
}
inline std::shared_ptr<DeclareVariable> DeclareVariable::Build(VariablePtr variable, ExpressionPtr expression)
{
auto node = std::make_shared<DeclareVariable>();
node->expression = std::move(expression);
node->variable = std::move(variable);
return node;
}
inline Discard::Discard() :
Statement(NodeType::Discard)
{
}
inline std::shared_ptr<Discard> Discard::Build()
{
return std::make_shared<Discard>();
}
inline Identifier::Identifier() :
Expression(NodeType::Identifier)
{
}
inline std::shared_ptr<Identifier> Identifier::Build(VariablePtr variable)
{
auto node = std::make_shared<Identifier>();
node->var = std::move(variable);
return node;
}
inline AccessMember::AccessMember() :
Expression(NodeType::AccessMember)
{
}
inline std::shared_ptr<AccessMember> AccessMember::Build(ExpressionPtr structExpr, std::size_t memberIndex, ShaderExpressionType exprType)
{
return Build(std::move(structExpr), std::vector<std::size_t>{ memberIndex }, exprType);
}
inline std::shared_ptr<AccessMember> AccessMember::Build(ExpressionPtr structExpr, std::vector<std::size_t> memberIndices, ShaderExpressionType exprType)
{
auto node = std::make_shared<AccessMember>();
node->exprType = std::move(exprType);
node->memberIndices = std::move(memberIndices);
node->structExpr = std::move(structExpr);
return node;
}
inline NoOp::NoOp() :
Statement(NodeType::NoOp)
{
}
inline std::shared_ptr<NoOp> NoOp::Build()
{
return std::make_shared<NoOp>();
}
inline ReturnStatement::ReturnStatement() :
Statement(NodeType::ReturnStatement)
{
}
inline std::shared_ptr<ReturnStatement> ShaderNodes::ReturnStatement::Build(ExpressionPtr expr)
{
auto node = std::make_shared<ReturnStatement>();
node->returnExpr = std::move(expr);
return node;
}
inline AssignOp::AssignOp() :
Expression(NodeType::AssignOp)
{
}
inline std::shared_ptr<AssignOp> AssignOp::Build(AssignType op, ExpressionPtr left, ExpressionPtr right)
{
auto node = std::make_shared<AssignOp>();
node->op = op;
node->left = std::move(left);
node->right = std::move(right);
return node;
}
inline BinaryOp::BinaryOp() :
Expression(NodeType::BinaryOp)
{
}
inline std::shared_ptr<BinaryOp> BinaryOp::Build(BinaryType op, ExpressionPtr left, ExpressionPtr right)
{
auto node = std::make_shared<BinaryOp>();
node->op = op;
node->left = std::move(left);
node->right = std::move(right);
return node;
}
inline Branch::Branch() :
Statement(NodeType::Branch)
{
}
inline std::shared_ptr<Branch> Branch::Build(ExpressionPtr condition, StatementPtr trueStatement, StatementPtr falseStatement)
{
auto node = std::make_shared<Branch>();
node->condStatements.emplace_back(ConditionalStatement{ std::move(condition), std::move(trueStatement) });
node->elseStatement = std::move(falseStatement);
return node;
}
inline std::shared_ptr<Branch> Branch::Build(std::vector<ConditionalStatement> statements, StatementPtr elseStatement)
{
auto node = std::make_shared<Branch>();
node->condStatements = std::move(statements);
node->elseStatement = std::move(elseStatement);
return node;
}
inline Cast::Cast() :
Expression(NodeType::Cast)
{
}
inline std::shared_ptr<Cast> Cast::Build(BasicType castTo, ExpressionPtr first, ExpressionPtr second, ExpressionPtr third, ExpressionPtr fourth)
{
auto node = std::make_shared<Cast>();
node->exprType = castTo;
node->expressions = { {first, second, third, fourth} };
return node;
}
inline std::shared_ptr<Cast> Cast::Build(BasicType castTo, ExpressionPtr* Expressions, std::size_t expressionCount)
{
auto node = std::make_shared<Cast>();
node->exprType = castTo;
for (std::size_t i = 0; i < expressionCount; ++i)
node->expressions[i] = Expressions[i];
return node;
}
inline ConditionalExpression::ConditionalExpression() :
Expression(NodeType::ConditionalExpression)
{
}
inline std::shared_ptr<ConditionalExpression> ShaderNodes::ConditionalExpression::Build(std::string condition, ExpressionPtr truePath, ExpressionPtr falsePath)
{
auto node = std::make_shared<ConditionalExpression>();
node->conditionName = std::move(condition);
node->falsePath = std::move(falsePath);
node->truePath = std::move(truePath);
return node;
}
inline Constant::Constant() :
Expression(NodeType::Constant)
{
}
template<typename T>
std::shared_ptr<Constant> Nz::ShaderNodes::Constant::Build(const T& value)
{
auto node = std::make_shared<Constant>();
node->value = value;
return node;
}
inline SwizzleOp::SwizzleOp() :
Expression(NodeType::SwizzleOp)
{
}
inline std::shared_ptr<SwizzleOp> SwizzleOp::Build(ExpressionPtr expressionPtr, SwizzleComponent swizzleComponent)
{
return Build(std::move(expressionPtr), { swizzleComponent });
}
inline std::shared_ptr<SwizzleOp> SwizzleOp::Build(ExpressionPtr expressionPtr, std::initializer_list<SwizzleComponent> swizzleComponents)
{
auto node = std::make_shared<SwizzleOp>();
node->componentCount = swizzleComponents.size();
node->expression = std::move(expressionPtr);
std::copy(swizzleComponents.begin(), swizzleComponents.end(), node->components.begin());
return node;
}
inline std::shared_ptr<SwizzleOp> SwizzleOp::Build(ExpressionPtr expressionPtr, const SwizzleComponent* components, std::size_t componentCount)
{
auto node = std::make_shared<SwizzleOp>();
assert(componentCount < node->components.size());
node->componentCount = componentCount;
node->expression = std::move(expressionPtr);
std::copy(components, components + componentCount, node->components.begin());
return node;
}
inline Sample2D::Sample2D() :
Expression(NodeType::Sample2D)
{
}
inline std::shared_ptr<Sample2D> Sample2D::Build(ExpressionPtr samplerPtr, ExpressionPtr coordinatesPtr)
{
auto node = std::make_shared<Sample2D>();
node->coordinates = std::move(coordinatesPtr);
node->sampler = std::move(samplerPtr);
return node;
}
inline IntrinsicCall::IntrinsicCall() :
Expression(NodeType::IntrinsicCall)
{
}
inline std::shared_ptr<IntrinsicCall> IntrinsicCall::Build(IntrinsicType intrinsic, std::vector<ExpressionPtr> parameters)
{
auto node = std::make_shared<IntrinsicCall>();
node->intrinsic = intrinsic;
node->parameters = std::move(parameters);
return node;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -1,38 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERVARVISITOR_HPP
#define NAZARA_SHADERVARVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderVariables.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderVarVisitor
{
public:
ShaderVarVisitor() = default;
ShaderVarVisitor(const ShaderVarVisitor&) = delete;
ShaderVarVisitor(ShaderVarVisitor&&) = delete;
virtual ~ShaderVarVisitor();
void Visit(const ShaderNodes::VariablePtr& node);
virtual void Visit(ShaderNodes::BuiltinVariable& var) = 0;
virtual void Visit(ShaderNodes::InputVariable& var) = 0;
virtual void Visit(ShaderNodes::LocalVariable& var) = 0;
virtual void Visit(ShaderNodes::OutputVariable& var) = 0;
virtual void Visit(ShaderNodes::ParameterVariable& var) = 0;
virtual void Visit(ShaderNodes::UniformVariable& var) = 0;
ShaderVarVisitor& operator=(const ShaderVarVisitor&) = delete;
ShaderVarVisitor& operator=(ShaderVarVisitor&&) = delete;
};
}
#endif

View File

@@ -1,28 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADERVARVISITOREXCEPT_HPP
#define NAZARA_SHADERVARVISITOREXCEPT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
namespace Nz
{
class NAZARA_SHADER_API ShaderVarVisitorExcept : public ShaderVarVisitor
{
public:
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
};
}
#endif

View File

@@ -1,128 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SHADER_VARIABLES_HPP
#define NAZARA_SHADER_VARIABLES_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <array>
#include <memory>
#include <optional>
#include <string>
namespace Nz
{
class ShaderVarVisitor;
namespace ShaderNodes
{
struct Variable;
using VariablePtr = std::shared_ptr<Variable>;
struct NAZARA_SHADER_API Variable : std::enable_shared_from_this<Variable>
{
virtual ~Variable();
virtual VariableType GetType() const = 0;
virtual void Visit(ShaderVarVisitor& visitor) = 0;
ShaderExpressionType type;
};
struct BuiltinVariable;
using BuiltinVariablePtr = std::shared_ptr<BuiltinVariable>;
struct NAZARA_SHADER_API BuiltinVariable : public Variable
{
BuiltinEntry entry;
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<BuiltinVariable> Build(BuiltinEntry entry, ShaderExpressionType varType);
};
struct NamedVariable;
using NamedVariablePtr = std::shared_ptr<NamedVariable>;
struct NAZARA_SHADER_API NamedVariable : public Variable
{
std::string name;
};
struct InputVariable;
using InputVariablePtr = std::shared_ptr<InputVariable>;
struct NAZARA_SHADER_API InputVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<InputVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct LocalVariable;
using LocalVariablePtr = std::shared_ptr<LocalVariable>;
struct NAZARA_SHADER_API LocalVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<LocalVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct OutputVariable;
using OutputVariablePtr = std::shared_ptr<OutputVariable>;
struct NAZARA_SHADER_API OutputVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<OutputVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct ParameterVariable;
using ParameterVariablePtr = std::shared_ptr<ParameterVariable>;
struct NAZARA_SHADER_API ParameterVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<ParameterVariable> Build(std::string varName, ShaderExpressionType varType);
};
struct UniformVariable;
using UniformVariablePtr = std::shared_ptr<UniformVariable>;
struct NAZARA_SHADER_API UniformVariable : public NamedVariable
{
VariableType GetType() const override;
void Visit(ShaderVarVisitor& visitor) override;
static inline std::shared_ptr<UniformVariable> Build(std::string varName, ShaderExpressionType varType);
};
}
}
#include <Nazara/Shader/ShaderVariables.inl>
#endif

View File

@@ -1,65 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Shader generator"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/ShaderVariables.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderNodes
{
inline std::shared_ptr<BuiltinVariable> BuiltinVariable::Build(BuiltinEntry variable, ShaderExpressionType varType)
{
auto node = std::make_shared<BuiltinVariable>();
node->entry = variable;
node->type = varType;
return node;
}
inline std::shared_ptr<InputVariable> InputVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<InputVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<LocalVariable> LocalVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<LocalVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<OutputVariable> OutputVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<OutputVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<ParameterVariable> ParameterVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<ParameterVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
inline std::shared_ptr<UniformVariable> UniformVariable::Build(std::string varName, ShaderExpressionType varType)
{
auto node = std::make_shared<UniformVariable>();
node->name = std::move(varName);
node->type = varType;
return node;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -14,8 +14,6 @@
namespace Nz
{
class ShaderAst;
class NAZARA_SHADER_API ShaderWriter
{
public:

View File

@@ -9,8 +9,8 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitorExcept.hpp>
#include <Nazara/Shader/SpirvBlock.hpp>
#include <vector>
@@ -18,7 +18,7 @@ namespace Nz
{
class SpirvWriter;
class NAZARA_SHADER_API SpirvAstVisitor : public ShaderAstVisitorExcept
class NAZARA_SHADER_API SpirvAstVisitor : public ShaderAst::ExpressionVisitorExcept, public ShaderAst::StatementVisitorExcept
{
public:
inline SpirvAstVisitor(SpirvWriter& writer, std::vector<SpirvBlock>& blocks);
@@ -26,27 +26,28 @@ namespace Nz
SpirvAstVisitor(SpirvAstVisitor&&) = delete;
~SpirvAstVisitor() = default;
UInt32 EvaluateExpression(const ShaderNodes::ExpressionPtr& expr);
UInt32 EvaluateExpression(ShaderAst::ExpressionPtr& expr);
using ShaderAstVisitorExcept::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::AssignOp& node) override;
void Visit(ShaderNodes::BinaryOp& node) override;
void Visit(ShaderNodes::Branch& node) override;
void Visit(ShaderNodes::Cast& node) override;
void Visit(ShaderNodes::ConditionalExpression& node) override;
void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override;
void Visit(ShaderNodes::NoOp& node) override;
void Visit(ShaderNodes::ReturnStatement& node) override;
void Visit(ShaderNodes::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
using ExpressionVisitorExcept::Visit;
using StatementVisitorExcept::Visit;
void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::AssignExpression& node) override;
void Visit(ShaderAst::BinaryExpression& node) override;
void Visit(ShaderAst::BranchStatement& node) override;
void Visit(ShaderAst::CastExpression& node) override;
void Visit(ShaderAst::ConditionalExpression& node) override;
void Visit(ShaderAst::ConditionalStatement& node) override;
void Visit(ShaderAst::ConstantExpression& node) override;
void Visit(ShaderAst::DeclareVariableStatement& node) override;
void Visit(ShaderAst::DiscardStatement& node) override;
void Visit(ShaderAst::ExpressionStatement& node) override;
void Visit(ShaderAst::IdentifierExpression& node) override;
void Visit(ShaderAst::IntrinsicExpression& node) override;
void Visit(ShaderAst::MultiStatement& node) override;
void Visit(ShaderAst::NoOpStatement& node) override;
void Visit(ShaderAst::ReturnStatement& node) override;
void Visit(ShaderAst::SwizzleExpression& node) override;
SpirvAstVisitor& operator=(const SpirvAstVisitor&) = delete;
SpirvAstVisitor& operator=(SpirvAstVisitor&&) = delete;

View File

@@ -10,7 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderExpressionType.hpp>
#include <Nazara/Shader/ShaderAstTypes.hpp>
#include <Nazara/Shader/SpirvData.hpp>
#include <memory>
#include <optional>
@@ -20,7 +20,6 @@
namespace Nz
{
class ShaderAst;
class SpirvSection;
class NAZARA_SHADER_API SpirvConstantCache
@@ -173,10 +172,10 @@ namespace Nz
SpirvConstantCache& operator=(SpirvConstantCache&& cache) noexcept;
static ConstantPtr BuildConstant(const ShaderConstantValue& value);
static TypePtr BuildPointerType(const ShaderNodes::BasicType& type, SpirvStorageClass storageClass);
static TypePtr BuildPointerType(const ShaderAst& shader, const ShaderExpressionType& type, SpirvStorageClass storageClass);
static TypePtr BuildType(const ShaderNodes::BasicType& type);
static TypePtr BuildType(const ShaderAst& shader, const ShaderExpressionType& type);
static TypePtr BuildPointerType(const ShaderAst::BasicType& type, SpirvStorageClass storageClass);
static TypePtr BuildPointerType(const ShaderAst::ShaderExpressionType& type, SpirvStorageClass storageClass);
static TypePtr BuildType(const ShaderAst::BasicType& type);
static TypePtr BuildType(const ShaderAst::ShaderExpressionType& type);
private:
struct DepRegisterer;

View File

@@ -9,8 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/SpirvData.hpp>
#include <vector>
@@ -19,7 +18,7 @@ namespace Nz
class SpirvBlock;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionLoad : public ShaderAstVisitorExcept, public ShaderVarVisitorExcept
class NAZARA_SHADER_API SpirvExpressionLoad : public ShaderAst::ExpressionVisitorExcept
{
public:
inline SpirvExpressionLoad(SpirvWriter& writer, SpirvBlock& block);
@@ -27,17 +26,11 @@ namespace Nz
SpirvExpressionLoad(SpirvExpressionLoad&&) = delete;
~SpirvExpressionLoad() = default;
UInt32 Evaluate(ShaderNodes::Expression& node);
UInt32 Evaluate(ShaderAst::Expression& node);
using ShaderAstVisitor::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::Identifier& node) override;
using ShaderVarVisitor::Visit;
void Visit(ShaderNodes::InputVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::ParameterVariable& var) override;
void Visit(ShaderNodes::UniformVariable& var) override;
using ExpressionVisitorExcept::Visit;
//void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::IdentifierExpression& node) override;
SpirvExpressionLoad& operator=(const SpirvExpressionLoad&) = delete;
SpirvExpressionLoad& operator=(SpirvExpressionLoad&&) = delete;

View File

@@ -9,8 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstVisitorExcept.hpp>
#include <Nazara/Shader/ShaderVarVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/SpirvData.hpp>
namespace Nz
@@ -18,7 +17,7 @@ namespace Nz
class SpirvBlock;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionStore : public ShaderAstVisitorExcept, public ShaderVarVisitorExcept
class NAZARA_SHADER_API SpirvExpressionStore : public ShaderAst::ExpressionVisitorExcept
{
public:
inline SpirvExpressionStore(SpirvWriter& writer, SpirvBlock& block);
@@ -26,17 +25,12 @@ namespace Nz
SpirvExpressionStore(SpirvExpressionStore&&) = delete;
~SpirvExpressionStore() = default;
void Store(const ShaderNodes::ExpressionPtr& node, UInt32 resultId);
void Store(ShaderAst::ExpressionPtr& node, UInt32 resultId);
using ShaderAstVisitorExcept::Visit;
void Visit(ShaderNodes::AccessMember& node) override;
void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
using ShaderVarVisitorExcept::Visit;
void Visit(ShaderNodes::BuiltinVariable& var) override;
void Visit(ShaderNodes::LocalVariable& var) override;
void Visit(ShaderNodes::OutputVariable& var) override;
using ExpressionVisitorExcept::Visit;
//void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::IdentifierExpression& node) override;
void Visit(ShaderAst::SwizzleExpression& node) override;
SpirvExpressionStore& operator=(const SpirvExpressionStore&) = delete;
SpirvExpressionStore& operator=(SpirvExpressionStore&&) = delete;

View File

@@ -9,10 +9,8 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAst.hpp>
#include <Nazara/Shader/ShaderAstVisitor.hpp>
#include <Nazara/Shader/ShaderAstCache.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderVarVisitor.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <string>
@@ -39,7 +37,7 @@ namespace Nz
SpirvWriter(SpirvWriter&&) = delete;
~SpirvWriter() = default;
std::vector<UInt32> Generate(const ShaderAst& shader, const States& conditions = {});
std::vector<UInt32> Generate(ShaderAst::StatementPtr& shader, const States& conditions = {});
void SetEnv(Environment environment);
@@ -51,22 +49,23 @@ namespace Nz
private:
struct ExtVar;
struct FunctionParameter;
struct OnlyCache {};
UInt32 AllocateResultId();
void AppendHeader();
SpirvConstantCache::Function BuildFunctionType(ShaderExpressionType retType, const std::vector<ShaderAst::FunctionParameter>& parameters);
SpirvConstantCache::Function BuildFunctionType(ShaderAst::ShaderExpressionType retType, const std::vector<FunctionParameter>& parameters);
UInt32 GetConstantId(const ShaderConstantValue& value) const;
UInt32 GetFunctionTypeId(ShaderExpressionType retType, const std::vector<ShaderAst::FunctionParameter>& parameters);
const ExtVar& GetBuiltinVariable(ShaderNodes::BuiltinEntry builtin) const;
UInt32 GetFunctionTypeId(ShaderAst::ShaderExpressionType retType, const std::vector<FunctionParameter>& parameters);
const ExtVar& GetBuiltinVariable(ShaderAst::BuiltinEntry builtin) const;
const ExtVar& GetInputVariable(const std::string& name) const;
const ExtVar& GetOutputVariable(const std::string& name) const;
const ExtVar& GetUniformVariable(const std::string& name) const;
UInt32 GetPointerTypeId(const ShaderExpressionType& type, SpirvStorageClass storageClass) const;
UInt32 GetTypeId(const ShaderExpressionType& type) const;
UInt32 GetPointerTypeId(const ShaderAst::ShaderExpressionType& type, SpirvStorageClass storageClass) const;
UInt32 GetTypeId(const ShaderAst::ShaderExpressionType& type) const;
inline bool IsConditionEnabled(const std::string& condition) const;
@@ -82,9 +81,9 @@ namespace Nz
std::optional<UInt32> ReadVariable(const ExtVar& var, OnlyCache);
UInt32 RegisterConstant(const ShaderConstantValue& value);
UInt32 RegisterFunctionType(ShaderExpressionType retType, const std::vector<ShaderAst::FunctionParameter>& parameters);
UInt32 RegisterPointerType(ShaderExpressionType type, SpirvStorageClass storageClass);
UInt32 RegisterType(ShaderExpressionType type);
UInt32 RegisterFunctionType(ShaderAst::ShaderExpressionType retType, const std::vector<FunctionParameter>& parameters);
UInt32 RegisterPointerType(ShaderAst::ShaderExpressionType type, SpirvStorageClass storageClass);
UInt32 RegisterType(ShaderAst::ShaderExpressionType type);
void WriteLocalVariable(std::string name, UInt32 resultId);
@@ -92,7 +91,7 @@ namespace Nz
struct Context
{
const ShaderAst* shader = nullptr;
ShaderAst::AstCache cache;
const States* states = nullptr;
std::vector<SpirvBlock> functionBlocks;
};
@@ -105,6 +104,12 @@ namespace Nz
std::optional<UInt32> valueId;
};
struct FunctionParameter
{
std::string name;
ShaderAst::ShaderExpressionType type;
};
struct State;
Context m_context;

View File

@@ -10,10 +10,11 @@ namespace Nz
{
inline bool SpirvWriter::IsConditionEnabled(const std::string& condition) const
{
std::size_t conditionIndex = m_context.shader->FindConditionByName(condition);
/*std::size_t conditionIndex = m_context.shader->FindConditionByName(condition);
assert(conditionIndex != ShaderAst::InvalidCondition);
return TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex);
return TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex);*/
return false;
}
}