Split shader generation to a new module

This commit is contained in:
Jérôme Leclercq
2020-08-11 00:00:36 +02:00
parent 0313f2d0a6
commit 837a6585a1
86 changed files with 564 additions and 312 deletions

View File

@@ -53,24 +53,6 @@ namespace Nz
SpirV
};
enum class ShaderStageType
{
Fragment,
Vertex,
Max = Vertex
};
template<>
struct EnumAsFlags<ShaderStageType>
{
static constexpr ShaderStageType max = ShaderStageType::Max;
};
using ShaderStageTypeFlags = Flags<ShaderStageType>;
constexpr ShaderStageTypeFlags ShaderStageType_All = ShaderStageType::Fragment | ShaderStageType::Vertex;
enum class QueueType
{
Compute,

View File

@@ -1,109 +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_GLSLWRITER_HPP
#define NAZARA_GLSLWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderVarVisitor.hpp>
#include <Nazara/Renderer/ShaderAstVisitor.hpp>
#include <Nazara/Renderer/ShaderWriter.hpp>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
namespace Nz
{
class NAZARA_RENDERER_API GlslWriter : public ShaderWriter, public ShaderVarVisitor, public ShaderAstVisitor
{
public:
struct Environment;
using ExtSupportCallback = std::function<bool(const std::string_view& name)>;
GlslWriter();
GlslWriter(const GlslWriter&) = delete;
GlslWriter(GlslWriter&&) = delete;
~GlslWriter() = default;
std::string Generate(const ShaderAst& shader) override;
void SetEnv(Environment environment);
struct Environment
{
ExtSupportCallback extCallback;
unsigned int glMajorVersion = 3;
unsigned int glMinorVersion = 0;
bool glES = false;
bool flipYPosition = false;
};
private:
void Append(ShaderExpressionType type);
void Append(ShaderNodes::BuiltinEntry builtin);
void Append(ShaderNodes::BasicType type);
void Append(ShaderNodes::MemoryLayout layout);
template<typename T> void Append(const T& param);
void AppendCommentSection(const std::string& section);
void AppendFunction(const ShaderAst::Function& func);
void AppendFunctionPrototype(const ShaderAst::Function& func);
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::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& 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::ParameterVariable& var) 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;
static bool HasExplicitBinding(const ShaderAst& shader);
static bool HasExplicitLocation(const ShaderAst& shader);
struct Context
{
const ShaderAst* shader = nullptr;
const ShaderAst::Function* currentFunction = nullptr;
};
struct State
{
std::stringstream stream;
unsigned int indentLevel = 0;
};
Context m_context;
Environment m_environment;
State* m_currentState;
};
}
#include <Nazara/Renderer/GlslWriter.inl>
#endif // NAZARA_GLSLWRITER_HPP

View File

@@ -1,132 +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
#include <Nazara/Renderer/GlslWriter.hpp>
#include <type_traits>
#include <Nazara/Renderer/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 T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ShaderNodes::BasicType>)
{
Append(arg);
Append(" ");
Append(var.name);
}
else if constexpr (std::is_same_v<T, 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<T>::value, "non-exhaustive visitor");
}, var.type);
AppendLine(";");
AppendLine();
}
}
AppendLine();
}
}
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -10,6 +10,7 @@
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <memory>
#include <string>
#include <vector>

View File

@@ -1,115 +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/Renderer/Enums.hpp>
#include <Nazara/Renderer/ShaderExpressionType.hpp>
#include <Nazara/Renderer/ShaderNodes.hpp>
#include <optional>
#include <unordered_map>
#include <vector>
namespace Nz
{
class NAZARA_RENDERER_API ShaderAst
{
public:
struct Function;
struct FunctionParameter;
struct InputOutput;
struct Struct;
struct StructMember;
struct Uniform;
struct VariableBase;
inline ShaderAst(ShaderStageType shaderStage);
ShaderAst(const ShaderAst&) = default;
ShaderAst(ShaderAst&&) = default;
~ShaderAst() = default;
void AddFunction(std::string name, ShaderNodes::StatementPtr statement, std::vector<FunctionParameter> parameters = {}, ShaderNodes::BasicType 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 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&&) = default;
struct VariableBase
{
std::string name;
ShaderExpressionType type;
};
struct FunctionParameter : VariableBase
{
};
struct Function
{
std::string name;
std::vector<FunctionParameter> parameters;
ShaderNodes::BasicType 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;
};
private:
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/Renderer/ShaderAst.inl>
#endif // NAZARA_SHADER_AST_HPP

View File

@@ -1,101 +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
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
inline ShaderAst::ShaderAst(ShaderStageType shaderStage) :
m_stage(shaderStage)
{
}
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/Renderer/DebugOff.hpp>

View File

@@ -1,74 +0,0 @@
// Copyright (C) 2015 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_SHADERASTCLONER_HPP
#define NAZARA_SHADERASTCLONER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAstVisitor.hpp>
#include <Nazara/Renderer/ShaderVarVisitor.hpp>
#include <vector>
namespace Nz
{
class NAZARA_RENDERER_API ShaderAstCloner : public ShaderAstVisitor, public ShaderVarVisitor
{
public:
ShaderAstCloner() = default;
ShaderAstCloner(const ShaderAstCloner&) = default;
ShaderAstCloner(ShaderAstCloner&&) = default;
~ShaderAstCloner() = default;
ShaderNodes::StatementPtr Clone(const ShaderNodes::StatementPtr& statement);
ShaderAstCloner& operator=(const ShaderAstCloner&) = default;
ShaderAstCloner& operator=(ShaderAstCloner&&) = default;
protected:
ShaderNodes::ExpressionPtr CloneExpression(const ShaderNodes::ExpressionPtr& expr);
ShaderNodes::StatementPtr CloneStatement(const ShaderNodes::StatementPtr& statement);
ShaderNodes::VariablePtr CloneVariable(const ShaderNodes::VariablePtr& statement);
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::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::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
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 PushExpression(ShaderNodes::ExpressionPtr expression);
void PushStatement(ShaderNodes::StatementPtr statement);
void PushVariable(ShaderNodes::VariablePtr variable);
ShaderNodes::ExpressionPtr PopExpression();
ShaderNodes::StatementPtr PopStatement();
ShaderNodes::VariablePtr PopVariable();
private:
std::vector<ShaderNodes::ExpressionPtr> m_expressionStack;
std::vector<ShaderNodes::StatementPtr> m_statementStack;
std::vector<ShaderNodes::VariablePtr> m_variableStack;
};
}
#include <Nazara/Renderer/ShaderAstCloner.inl>
#endif

View File

@@ -1,12 +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
#include <Nazara/Renderer/ShaderAstCloner.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -1,42 +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_RECURSIVE_VISITOR_HPP
#define NAZARA_SHADER_RECURSIVE_VISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAstVisitor.hpp>
namespace Nz
{
class NAZARA_RENDERER_API ShaderAstRecursiveVisitor : public ShaderAstVisitor
{
public:
ShaderAstRecursiveVisitor() = default;
~ShaderAstRecursiveVisitor() = default;
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::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::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
};
}
#include <Nazara/Renderer/ShaderAstRecursiveVisitor.inl>
#endif

View File

@@ -1,12 +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
#include <Nazara/Renderer/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -1,143 +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_SHADERSERIALIZER_HPP
#define NAZARA_SHADERSERIALIZER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderNodes.hpp>
#include <Nazara/Renderer/ShaderVariables.hpp>
namespace Nz
{
class NAZARA_RENDERER_API ShaderAstSerializerBase
{
public:
ShaderAstSerializerBase() = default;
ShaderAstSerializerBase(const ShaderAstSerializerBase&) = delete;
ShaderAstSerializerBase(ShaderAstSerializerBase&&) = delete;
~ShaderAstSerializerBase() = 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::Constant& node);
void Serialize(ShaderNodes::DeclareVariable& node);
void Serialize(ShaderNodes::ExpressionStatement& node);
void Serialize(ShaderNodes::Identifier& node);
void Serialize(ShaderNodes::IntrinsicCall& node);
void Serialize(ShaderNodes::NamedVariable& var);
void Serialize(ShaderNodes::Sample2D& node);
void Serialize(ShaderNodes::StatementBlock& node);
void Serialize(ShaderNodes::SwizzleOp& node);
protected:
template<typename T> void Container(T& container);
template<typename T> void Enum(T& enumVal);
template<typename T> void OptEnum(std::optional<T>& optVal);
template<typename T> void OptVal(std::optional<T>& optVal);
virtual bool IsWriting() const = 0;
virtual void Node(ShaderNodes::NodePtr& node) = 0;
template<typename T> void Node(std::shared_ptr<T>& node);
virtual void Type(ShaderExpressionType& type) = 0;
virtual void Value(bool& val) = 0;
virtual void Value(float& val) = 0;
virtual void Value(std::string& val) = 0;
virtual void Value(Int32& val) = 0;
virtual void Value(Vector2f& val) = 0;
virtual void Value(Vector3f& val) = 0;
virtual void Value(Vector4f& val) = 0;
virtual void Value(Vector2i32& val) = 0;
virtual void Value(Vector3i32& val) = 0;
virtual void Value(Vector4i32& val) = 0;
virtual void Value(UInt8& val) = 0;
virtual void Value(UInt16& val) = 0;
virtual void Value(UInt32& val) = 0;
inline void Value(std::size_t& val);
virtual void Variable(ShaderNodes::VariablePtr& var) = 0;
template<typename T> void Variable(std::shared_ptr<T>& var);
};
class NAZARA_RENDERER_API ShaderAstSerializer final : public ShaderAstSerializerBase
{
public:
inline ShaderAstSerializer(ByteStream& stream);
~ShaderAstSerializer() = default;
void Serialize(const ShaderAst& shader);
private:
bool IsWriting() const override;
void Node(const ShaderNodes::NodePtr& node);
void Node(ShaderNodes::NodePtr& node) override;
void Type(ShaderExpressionType& type) override;
void Value(bool& val) override;
void Value(float& val) override;
void Value(std::string& val) override;
void Value(Int32& val) override;
void Value(Vector2f& val) override;
void Value(Vector3f& val) override;
void Value(Vector4f& val) override;
void Value(Vector2i32& val) override;
void Value(Vector3i32& val) override;
void Value(Vector4i32& val) override;
void Value(UInt8& val) override;
void Value(UInt16& val) override;
void Value(UInt32& val) override;
void Variable(ShaderNodes::VariablePtr& var) override;
ByteStream& m_stream;
};
class NAZARA_RENDERER_API ShaderAstUnserializer final : public ShaderAstSerializerBase
{
public:
ShaderAstUnserializer(ByteStream& stream);
~ShaderAstUnserializer() = default;
ShaderAst Unserialize();
private:
bool IsWriting() const override;
void Node(ShaderNodes::NodePtr& node) override;
void Type(ShaderExpressionType& type) override;
void Value(bool& val) override;
void Value(float& val) override;
void Value(std::string& val) override;
void Value(Int32& val) override;
void Value(Vector2f& val) override;
void Value(Vector3f& val) override;
void Value(Vector4f& val) override;
void Value(Vector2i32& val) override;
void Value(Vector3i32& val) override;
void Value(Vector4i32& val) override;
void Value(UInt8& val) override;
void Value(UInt16& val) override;
void Value(UInt32& val) override;
void Variable(ShaderNodes::VariablePtr& var) override;
ByteStream& m_stream;
};
NAZARA_RENDERER_API ByteArray SerializeShader(const ShaderAst& shader);
NAZARA_RENDERER_API ShaderAst UnserializeShader(ByteStream& stream);
}
#include <Nazara/Renderer/ShaderAstSerializer.inl>
#endif

View File

@@ -1,127 +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
#include <Nazara/Renderer/ShaderAstSerializer.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
template<typename T>
void ShaderAstSerializerBase::Container(T& container)
{
bool isWriting = IsWriting();
UInt32 size;
if (isWriting)
size = UInt32(container.size());
Value(size);
if (!isWriting)
container.resize(size);
}
template<typename T>
void ShaderAstSerializerBase::Enum(T& enumVal)
{
bool isWriting = IsWriting();
UInt32 value;
if (isWriting)
value = static_cast<UInt32>(enumVal);
Value(value);
if (!isWriting)
enumVal = static_cast<T>(value);
}
template<typename T>
void ShaderAstSerializerBase::OptEnum(std::optional<T>& optVal)
{
bool isWriting = IsWriting();
bool hasValue;
if (isWriting)
hasValue = optVal.has_value();
Value(hasValue);
if (!isWriting && hasValue)
optVal.emplace();
if (optVal.has_value())
Enum(optVal.value());
}
template<typename T>
void ShaderAstSerializerBase::OptVal(std::optional<T>& optVal)
{
bool isWriting = IsWriting();
bool hasValue;
if (isWriting)
hasValue = optVal.has_value();
Value(hasValue);
if (!isWriting && hasValue)
optVal.emplace();
if (optVal.has_value())
Value(optVal.value());
}
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);
}
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 void ShaderAstSerializerBase::Value(std::size_t& val)
{
bool isWriting = IsWriting();
UInt32 value;
if (isWriting)
value = static_cast<UInt32>(val);
Value(value);
if (!isWriting)
val = static_cast<std::size_t>(value);
}
inline ShaderAstSerializer::ShaderAstSerializer(ByteStream& stream) :
m_stream(stream)
{
}
inline ShaderAstUnserializer::ShaderAstUnserializer(ByteStream& stream) :
m_stream(stream)
{
}
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -1,70 +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_SHADERVALIDATOR_HPP
#define NAZARA_SHADERVALIDATOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderAstRecursiveVisitor.hpp>
#include <Nazara/Renderer/ShaderVarVisitor.hpp>
namespace Nz
{
class NAZARA_RENDERER_API ShaderAstValidator : public ShaderAstRecursiveVisitor, public ShaderVarVisitor
{
public:
inline ShaderAstValidator(const ShaderAst& shader);
ShaderAstValidator(const ShaderAstValidator&) = delete;
ShaderAstValidator(ShaderAstValidator&&) = delete;
~ShaderAstValidator() = default;
bool Validate(std::string* error = 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);
void TypeMustMatch(const ShaderExpressionType& left, const ShaderExpressionType& right);
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::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::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
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;
struct Context;
const ShaderAst& m_shader;
Context* m_context;
};
NAZARA_RENDERER_API bool ValidateShader(const ShaderAst& shader, std::string* error = nullptr);
}
#include <Nazara/Renderer/ShaderAstValidator.inl>
#endif

View File

@@ -1,16 +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
#include <Nazara/Renderer/ShaderAstValidator.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
ShaderAstValidator::ShaderAstValidator(const ShaderAst& shader) :
m_shader(shader)
{
}
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -1,50 +0,0 @@
// Copyright (C) 2015 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_SHADERVISITOR_HPP
#define NAZARA_SHADERVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderNodes.hpp>
#include <string>
#include <unordered_set>
namespace Nz
{
class NAZARA_RENDERER_API ShaderAstVisitor
{
public:
ShaderAstVisitor() = default;
ShaderAstVisitor(const ShaderAstVisitor&) = delete;
ShaderAstVisitor(ShaderAstVisitor&&) = delete;
virtual ~ShaderAstVisitor();
void EnableCondition(const std::string& name, bool cond);
bool IsConditionEnabled(const std::string& name) const;
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::Constant& node) = 0;
virtual void Visit(ShaderNodes::DeclareVariable& 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::Sample2D& node) = 0;
virtual void Visit(ShaderNodes::StatementBlock& node) = 0;
virtual void Visit(ShaderNodes::SwizzleOp& node) = 0;
private:
std::unordered_set<std::string> m_conditions;
};
}
#endif

View File

@@ -1,76 +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_BUILDER_HPP
#define NAZARA_SHADER_BUILDER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/ShaderNodes.hpp>
#include <memory>
namespace Nz::ShaderBuilder
{
template<ShaderNodes::AssignType op>
struct AssignOpBuilder
{
constexpr AssignOpBuilder() = default;
std::shared_ptr<ShaderNodes::AssignOp> operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const;
};
template<ShaderNodes::BinaryType op>
struct BinOpBuilder
{
constexpr BinOpBuilder() = default;
std::shared_ptr<ShaderNodes::BinaryOp> operator()(const ShaderNodes::ExpressionPtr& left, const ShaderNodes::ExpressionPtr& right) const;
};
struct BuiltinBuilder
{
constexpr BuiltinBuilder() = default;
inline std::shared_ptr<ShaderNodes::Variable> operator()(ShaderNodes::BuiltinEntry builtin) const;
};
template<typename T>
struct GenBuilder
{
constexpr GenBuilder() = default;
template<typename... Args> std::shared_ptr<T> operator()(Args&&... args) 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::ConditionalStatement> ConditionalStatement;
constexpr GenBuilder<ShaderNodes::Constant> Constant;
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
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::SwizzleOp> Swizzle;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Substract> Substract;
constexpr GenBuilder<ShaderNodes::UniformVariable> Uniform;
template<ShaderNodes::BasicType Type, typename... Args> std::shared_ptr<ShaderNodes::Cast> Cast(Args&&... args);
}
#include <Nazara/Renderer/ShaderBuilder.inl>
#endif // NAZARA_SHADER_BUILDER_HPP

View File

@@ -1,52 +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
#include <Nazara/Renderer/ShaderBuilder.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz::ShaderBuilder
{
template<typename T>
template<typename... Args>
std::shared_ptr<T> GenBuilder<T>::operator()(Args&&... args) 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)...);
}
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -1,118 +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_ENUMS_HPP
#define NAZARA_SHADER_ENUMS_HPP
#include <Nazara/Prerequisites.hpp>
namespace Nz::ShaderNodes
{
enum class AssignType
{
Simple //< =
};
enum class BasicType
{
Boolean, //< bool
Float1, //< float
Float2, //< vec2
Float3, //< vec3
Float4, //< vec4
Int1, //< int
Int2, //< ivec2
Int3, //< ivec3
Int4, //< ivec4
Mat4x4, //< mat4
Sampler2D, //< sampler2D
Void //< void
};
enum class BinaryType
{
Add, //< +
Substract, //< -
Multiply, //< *
Divide, //< /
Equality //< ==
};
enum class BuiltinEntry
{
VertexPosition, // gl_Position
};
enum class ExpressionCategory
{
LValue,
RValue
};
enum class IntrinsicType
{
CrossProduct,
DotProduct
};
enum class MemoryLayout
{
Std140
};
enum class NodeType
{
None = -1,
AccessMember,
AssignOp,
BinaryOp,
Branch,
Cast,
Constant,
ConditionalStatement,
DeclareVariable,
ExpressionStatement,
Identifier,
IntrinsicCall,
Sample2D,
SwizzleOp,
StatementBlock
};
enum class SsaInstruction
{
OpAdd,
OpDiv,
OpMul,
OpSub,
OpSample
};
enum class SwizzleComponent
{
First,
Second,
Third,
Fourth
};
enum class VariableType
{
None = -1,
BuiltinVariable,
InputVariable,
LocalVariable,
OutputVariable,
ParameterVariable,
UniformVariable
};
}
#endif // NAZARA_SHADER_ENUMS_HPP

View File

@@ -1,20 +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_EXPRESSIONTYPE_HPP
#define NAZARA_SHADER_EXPRESSIONTYPE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/ShaderEnums.hpp>
#include <string>
#include <variant>
namespace Nz
{
using ShaderExpressionType = std::variant<ShaderNodes::BasicType, std::string>;
}
#endif // NAZARA_SHADER_EXPRESSIONTYPE_HPP

View File

@@ -1,292 +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_NODES_HPP
#define NAZARA_SHADER_NODES_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderEnums.hpp>
#include <Nazara/Renderer/ShaderExpressionType.hpp>
#include <Nazara/Renderer/ShaderVariables.hpp>
#include <array>
#include <optional>
#include <string>
namespace Nz
{
class ShaderAstVisitor;
namespace ShaderNodes
{
class Node;
using NodePtr = std::shared_ptr<Node>;
class NAZARA_RENDERER_API Node
{
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_RENDERER_API Expression : public Node
{
public:
inline Expression(NodeType type);
virtual ExpressionCategory GetExpressionCategory() const;
virtual ShaderExpressionType GetExpressionType() const = 0;
};
class Statement;
using StatementPtr = std::shared_ptr<Statement>;
class NAZARA_RENDERER_API Statement : public Node
{
public:
inline Statement(NodeType type);
};
struct NAZARA_RENDERER_API ExpressionStatement : public Statement
{
inline ExpressionStatement();
void Visit(ShaderAstVisitor& visitor) override;
ExpressionPtr expression;
static inline std::shared_ptr<ExpressionStatement> Build(ExpressionPtr expr);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_RENDERER_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_RENDERER_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_RENDERER_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_RENDERER_API Identifier : public Expression
{
inline Identifier();
ExpressionCategory GetExpressionCategory() const override;
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
VariablePtr var;
static inline std::shared_ptr<Identifier> Build(VariablePtr variable);
};
struct NAZARA_RENDERER_API AccessMember : public Expression
{
inline AccessMember();
ExpressionCategory GetExpressionCategory() const override;
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
std::size_t memberIndex;
ExpressionPtr structExpr;
ShaderExpressionType exprType;
static inline std::shared_ptr<AccessMember> Build(ExpressionPtr structExpr, std::size_t memberIndex, ShaderExpressionType exprType);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_RENDERER_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_RENDERER_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_RENDERER_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_RENDERER_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_RENDERER_API Constant : public Expression
{
inline Constant();
ShaderExpressionType GetExpressionType() const override;
void Visit(ShaderAstVisitor& visitor) override;
using Variant = std::variant<
bool,
float,
Int32,
Vector2f,
Vector3f,
Vector4f,
Vector2i32,
Vector3i32,
Vector4i32
>;
Variant value;
template<typename T> static std::shared_ptr<Constant> Build(const T& value);
};
struct NAZARA_RENDERER_API SwizzleOp : public Expression
{
inline SwizzleOp();
ExpressionCategory GetExpressionCategory() const override;
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, std::initializer_list<SwizzleComponent> swizzleComponents);
static inline std::shared_ptr<SwizzleOp> Build(ExpressionPtr expressionPtr, const SwizzleComponent* components, std::size_t componentCount);
};
//////////////////////////////////////////////////////////////////////////
struct NAZARA_RENDERER_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_RENDERER_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);
};
}
}
#include <Nazara/Renderer/ShaderNodes.inl>
#endif

View File

@@ -1,338 +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
#include <Nazara/Renderer/ShaderNodes.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz::ShaderNodes
{
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 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)
{
auto node = std::make_shared<AccessMember>();
node->exprType = std::move(exprType);
node->memberIndex = memberIndex;
node->structExpr = std::move(structExpr);
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 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, 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/Renderer/DebugOff.hpp>

View File

@@ -1,35 +0,0 @@
// Copyright (C) 2015 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_SHADERVARVISITOR_HPP
#define NAZARA_SHADERVARVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderVariables.hpp>
namespace Nz
{
class NAZARA_RENDERER_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;
};
}
#endif

View File

@@ -1,128 +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_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/Renderer/Config.hpp>
#include <Nazara/Renderer/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_RENDERER_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_RENDERER_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_RENDERER_API NamedVariable : public Variable
{
std::string name;
};
struct InputVariable;
using InputVariablePtr = std::shared_ptr<InputVariable>;
struct NAZARA_RENDERER_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_RENDERER_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_RENDERER_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_RENDERER_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_RENDERER_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/Renderer/ShaderVariables.inl>
#endif

View File

@@ -1,65 +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
#include <Nazara/Renderer/ShaderVariables.hpp>
#include <Nazara/Renderer/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/Renderer/DebugOff.hpp>

View File

@@ -1,30 +0,0 @@
// Copyright (C) 2015 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_SHADERWRITER_HPP
#define NAZARA_SHADERWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <string>
namespace Nz
{
class ShaderAst;
class NAZARA_RENDERER_API ShaderWriter
{
public:
ShaderWriter() = default;
ShaderWriter(const ShaderWriter&) = default;
ShaderWriter(ShaderWriter&&) = default;
virtual ~ShaderWriter();
virtual std::string Generate(const ShaderAst& shader) = 0;
};
}
#endif // NAZARA_SHADERWRITER_HPP

View File

@@ -1,132 +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_SPIRVWRITER_HPP
#define NAZARA_SPIRVWRITER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderAstVisitor.hpp>
#include <Nazara/Renderer/ShaderVarVisitor.hpp>
#include <Nazara/Renderer/ShaderWriter.hpp>
#include <Nazara/Utility/FieldOffsets.hpp>
#include <string>
#include <string_view>
#include <unordered_map>
namespace Nz
{
class NAZARA_RENDERER_API SpirvWriter : public ShaderAstVisitor, public ShaderVarVisitor
{
public:
struct Environment;
SpirvWriter();
SpirvWriter(const SpirvWriter&) = delete;
SpirvWriter(SpirvWriter&&) = delete;
~SpirvWriter() = default;
std::vector<UInt32> Generate(const ShaderAst& shader);
void SetEnv(Environment environment);
struct Environment
{
UInt32 spvMajorVersion = 1;
UInt32 spvMinorVersion = 0;
};
private:
struct ExtVar;
struct Opcode;
struct Raw;
struct WordCount;
struct Section
{
inline std::size_t Append(const char* str);
inline std::size_t Append(const std::string_view& str);
inline std::size_t Append(const std::string& str);
inline std::size_t Append(UInt32 value);
std::size_t Append(const Opcode& opcode, const WordCount& wordCount);
std::size_t Append(const Raw& raw);
inline std::size_t Append(std::initializer_list<UInt32> codepoints);
template<typename... Args> std::size_t Append(Opcode opcode, const Args&... args);
template<typename T> std::size_t Append(T value);
inline unsigned int CountWord(const char* str);
inline unsigned int CountWord(const std::string_view& str);
inline unsigned int CountWord(const std::string& str);
unsigned int CountWord(const Raw& raw);
template<typename T> unsigned int CountWord(const T& value);
template<typename T1, typename T2, typename... Args> unsigned int CountWord(const T1& value, const T2& value2, const Args&... rest);
inline std::size_t GetOutputOffset() const;
std::vector<UInt32> data;
};
UInt32 AllocateResultId();
void AppendConstants();
void AppendHeader();
void AppendStructType(std::size_t structIndex, UInt32 resultId);
void AppendTypes();
UInt32 EvaluateExpression(const ShaderNodes::ExpressionPtr& expr);
UInt32 GetConstantId(const ShaderNodes::Constant::Variant& value) const;
UInt32 GetTypeId(const ShaderExpressionType& type) const;
void PushResultId(UInt32 value);
UInt32 PopResultId();
UInt32 ReadVariable(ExtVar& var);
UInt32 RegisterType(ShaderExpressionType type);
using ShaderAstVisitor::Visit;
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::Cast& 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::Sample2D& node) override;
void Visit(ShaderNodes::StatementBlock& node) override;
void Visit(ShaderNodes::SwizzleOp& node) override;
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;
static void MergeBlocks(std::vector<UInt32>& output, const Section& from);
struct Context
{
const ShaderAst* shader = nullptr;
const ShaderAst::Function* currentFunction = nullptr;
};
struct State;
Context m_context;
Environment m_environment;
State* m_currentState;
};
}
#include <Nazara/Renderer/SpirvWriter.inl>
#endif

View File

@@ -1,111 +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
#include <Nazara/Renderer/SpirvWriter.hpp>
#include <cassert>
#include <type_traits>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
inline std::size_t SpirvWriter::Section::Append(const char* str)
{
return Append(std::string_view(str));
}
inline std::size_t SpirvWriter::Section::Append(const std::string_view& str)
{
std::size_t offset = GetOutputOffset();
std::size_t size4 = CountWord(str);
for (std::size_t i = 0; i < size4; ++i)
{
UInt32 codepoint = 0;
for (std::size_t j = 0; j < 4; ++j)
{
std::size_t pos = i * 4 + j;
if (pos < str.size())
codepoint |= UInt32(str[pos]) << (j * 8);
}
Append(codepoint);
}
return offset;
}
inline std::size_t SpirvWriter::Section::Append(const std::string& str)
{
return Append(std::string_view(str));
}
inline std::size_t SpirvWriter::Section::Append(UInt32 value)
{
std::size_t offset = GetOutputOffset();
data.push_back(value);
return offset;
}
inline std::size_t SpirvWriter::Section::Append(std::initializer_list<UInt32> codepoints)
{
std::size_t offset = GetOutputOffset();
for (UInt32 cp : codepoints)
Append(cp);
return offset;
}
template<typename ...Args>
std::size_t SpirvWriter::Section::Append(Opcode opcode, const Args&... args)
{
unsigned int wordCount = 1 + (CountWord(args) + ... + 0);
std::size_t offset = Append(opcode, WordCount{ wordCount });
if constexpr (sizeof...(args) > 0)
(Append(args), ...);
return offset;
}
template<typename T>
std::size_t SpirvWriter::Section::Append(T value)
{
return Append(static_cast<UInt32>(value));
}
template<typename T>
unsigned int SpirvWriter::Section::CountWord(const T& value)
{
return 1;
}
template<typename T1, typename T2, typename ...Args>
unsigned int SpirvWriter::Section::CountWord(const T1& value, const T2& value2, const Args&... rest)
{
return CountWord(value) + CountWord(value2) + (CountWord(rest) + ...);
}
inline unsigned int SpirvWriter::Section::CountWord(const char* str)
{
return CountWord(std::string_view(str));
}
inline unsigned int Nz::SpirvWriter::Section::CountWord(const std::string& str)
{
return CountWord(std::string_view(str));
}
inline unsigned int SpirvWriter::Section::CountWord(const std::string_view& str)
{
return (static_cast<unsigned int>(str.size() + 1) + sizeof(UInt32) - 1) / sizeof(UInt32); //< + 1 for null character
}
std::size_t SpirvWriter::Section::GetOutputOffset() const
{
return data.size();
}
}
#include <Nazara/Renderer/DebugOff.hpp>