Shader: First working version on both Vulkan & OpenGL (ES)

This commit is contained in:
Jérôme Leclercq
2021-04-12 15:38:20 +02:00
parent f93a5bbdc1
commit ea99c6a19e
42 changed files with 1803 additions and 1053 deletions

View File

@@ -140,6 +140,7 @@ namespace Nz
HLSL,
MSL,
NazaraBinary,
NazaraShader,
SpirV
};

View File

@@ -43,7 +43,6 @@
#include <Nazara/Shader/ShaderAstUtils.hpp>
#include <Nazara/Shader/ShaderAstValidator.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/ShaderLangLexer.hpp>
#include <Nazara/Shader/ShaderLangParser.hpp>

View File

@@ -13,9 +13,9 @@
#include <Nazara/Math/Vector4.hpp>
#include <variant>
namespace Nz
namespace Nz::ShaderAst
{
using ShaderConstantValue = std::variant<
using ConstantValue = std::variant<
bool,
float,
Int32,

View File

@@ -50,9 +50,17 @@ namespace Nz::ShaderAst
inline bool operator!=(const SamplerType& rhs) const;
};
struct StructType
{
std::size_t structIndex;
inline bool operator==(const StructType& rhs) const;
inline bool operator!=(const StructType& rhs) const;
};
struct UniformType
{
IdentifierType containedType;
std::variant<IdentifierType, StructType> containedType;
inline bool operator==(const UniformType& rhs) const;
inline bool operator!=(const UniformType& rhs) const;
@@ -67,7 +75,7 @@ namespace Nz::ShaderAst
inline bool operator!=(const VectorType& rhs) const;
};
using ExpressionType = std::variant<NoType, IdentifierType, PrimitiveType, MatrixType, SamplerType, UniformType, VectorType>;
using ExpressionType = std::variant<NoType, IdentifierType, PrimitiveType, MatrixType, SamplerType, StructType, UniformType, VectorType>;
struct StructDescription
{

View File

@@ -51,6 +51,17 @@ namespace Nz::ShaderAst
return !operator==(rhs);
}
inline bool StructType::operator==(const StructType& rhs) const
{
return structIndex == rhs.structIndex;
}
inline bool StructType::operator!=(const StructType& rhs) const
{
return !operator==(rhs);
}
inline bool UniformType::operator==(const UniformType& rhs) const
{
return containedType == rhs.containedType;
@@ -61,6 +72,7 @@ namespace Nz::ShaderAst
return !operator==(rhs);
}
inline bool VectorType::operator==(const VectorType& rhs) const
{
return componentCount == rhs.componentCount && type == rhs.type;

View File

@@ -0,0 +1,90 @@
// 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_SHADERAST_TRANSFORMVISITOR_HPP
#define NAZARA_SHADERAST_TRANSFORMVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstCloner.hpp>
#include <vector>
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API TransformVisitor : AstCloner
{
public:
inline TransformVisitor();
TransformVisitor(const TransformVisitor&) = delete;
TransformVisitor(TransformVisitor&&) = delete;
~TransformVisitor() = default;
StatementPtr Transform(StatementPtr& statement);
TransformVisitor& operator=(const TransformVisitor&) = delete;
TransformVisitor& operator=(TransformVisitor&&) = delete;
private:
struct Identifier;
ExpressionPtr Clone(AccessMemberIdentifierExpression& node) override;
ExpressionPtr Clone(CastExpression& node) override;
ExpressionPtr Clone(IdentifierExpression& node) override;
ExpressionPtr CloneExpression(ExpressionPtr& expr) override;
inline const Identifier* FindIdentifier(const std::string_view& identifierName) const;
void PushScope();
void PopScope();
inline std::size_t RegisterFunction(std::string name);
inline std::size_t RegisterStruct(std::string name, StructDescription description);
inline std::size_t RegisterVariable(std::string name);
ExpressionType ResolveType(const ExpressionType& exprType);
using AstCloner::Visit;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;
void Visit(DeclareExternalStatement& node) override;
void Visit(DeclareFunctionStatement& node) override;
void Visit(DeclareStructStatement& node) override;
void Visit(DeclareVariableStatement& node) override;
void Visit(MultiStatement& node) override;
struct Alias
{
std::variant<ExpressionType> value;
};
struct Struct
{
std::size_t structIndex;
};
struct Variable
{
std::size_t varIndex;
};
struct Identifier
{
std::string name;
std::variant<Alias, Struct, Variable> value;
};
private:
std::size_t m_nextFuncIndex;
std::size_t m_nextVarIndex;
std::vector<Identifier> m_identifiersInScope;
std::vector<StructDescription> m_structs;
std::vector<std::size_t> m_scopeSizes;
};
}
#include <Nazara/Shader/Ast/TransformVisitor.inl>
#endif

View File

@@ -0,0 +1,62 @@
// 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/Ast/TransformVisitor.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderAst
{
inline TransformVisitor::TransformVisitor() :
m_nextFuncIndex(0),
m_nextVarIndex(0)
{
}
inline auto TransformVisitor::FindIdentifier(const std::string_view& identifierName) const -> const Identifier*
{
auto it = std::find_if(m_identifiersInScope.rbegin(), m_identifiersInScope.rend(), [&](const Identifier& identifier) { return identifier.name == identifierName; });
if (it == m_identifiersInScope.rend())
return nullptr;
return &*it;
}
inline std::size_t TransformVisitor::RegisterFunction(std::string name)
{
std::size_t funcIndex = m_nextFuncIndex++;
return funcIndex;
}
inline std::size_t TransformVisitor::RegisterStruct(std::string name, StructDescription description)
{
std::size_t structIndex = m_structs.size();
m_structs.emplace_back(std::move(description));
m_identifiersInScope.push_back({
std::move(name),
Struct {
structIndex
}
});
return structIndex;
}
inline std::size_t TransformVisitor::RegisterVariable(std::string name)
{
std::size_t varIndex = m_nextVarIndex++;
m_identifiersInScope.push_back({
std::move(name),
Variable {
varIndex
}
});
return varIndex;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -52,6 +52,7 @@ namespace Nz
void Append(ShaderAst::NoType);
void Append(ShaderAst::PrimitiveType type);
void Append(const ShaderAst::SamplerType& samplerType);
void Append(const ShaderAst::StructType& structType);
void Append(const ShaderAst::UniformType& uniformType);
void Append(const ShaderAst::VectorType& vecType);
template<typename T> void Append(const T& param);
@@ -67,7 +68,7 @@ namespace Nz
void Visit(ShaderAst::ExpressionPtr& expr, bool encloseIfRequired = false);
void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::AccessMemberIdentifierExpression& node) override;
void Visit(ShaderAst::AssignExpression& node) override;
void Visit(ShaderAst::BinaryExpression& node) override;
void Visit(ShaderAst::CastExpression& node) override;

View File

@@ -30,15 +30,25 @@ namespace Nz::ShaderAst
AstCloner& operator=(AstCloner&&) = delete;
protected:
ExpressionPtr CloneExpression(ExpressionPtr& expr);
StatementPtr CloneStatement(StatementPtr& statement);
virtual ExpressionPtr CloneExpression(ExpressionPtr& expr);
virtual StatementPtr CloneStatement(StatementPtr& statement);
virtual StatementPtr Clone(DeclareExternalStatement& node);
virtual StatementPtr Clone(DeclareFunctionStatement& node);
virtual StatementPtr Clone(DeclareStructStatement& node);
virtual StatementPtr Clone(DeclareVariableStatement& node);
virtual ExpressionPtr Clone(AccessMemberIdentifierExpression& node);
virtual ExpressionPtr Clone(AccessMemberIndexExpression& node);
virtual ExpressionPtr Clone(CastExpression& node);
virtual ExpressionPtr Clone(IdentifierExpression& node);
virtual ExpressionPtr Clone(VariableExpression& node);
using AstExpressionVisitor::Visit;
using AstStatementVisitor::Visit;
void Visit(AccessMemberExpression& node) override;
void Visit(AccessMemberIdentifierExpression& node) override;
void Visit(AccessMemberIndexExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
@@ -47,6 +57,7 @@ namespace Nz::ShaderAst
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
void Visit(VariableExpression& node) override;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;

View File

@@ -26,7 +26,8 @@
#define NAZARA_SHADERAST_STATEMENT_LAST(X) NAZARA_SHADERAST_STATEMENT(X)
#endif
NAZARA_SHADERAST_EXPRESSION(AccessMemberExpression)
NAZARA_SHADERAST_EXPRESSION(AccessMemberIdentifierExpression)
NAZARA_SHADERAST_EXPRESSION(AccessMemberIndexExpression)
NAZARA_SHADERAST_EXPRESSION(AssignExpression)
NAZARA_SHADERAST_EXPRESSION(BinaryExpression)
NAZARA_SHADERAST_EXPRESSION(CastExpression)
@@ -35,6 +36,7 @@ NAZARA_SHADERAST_EXPRESSION(ConstantExpression)
NAZARA_SHADERAST_EXPRESSION(IdentifierExpression)
NAZARA_SHADERAST_EXPRESSION(IntrinsicExpression)
NAZARA_SHADERAST_EXPRESSION(SwizzleExpression)
NAZARA_SHADERAST_EXPRESSION(VariableExpression)
NAZARA_SHADERAST_STATEMENT(BranchStatement)
NAZARA_SHADERAST_STATEMENT(ConditionalStatement)
NAZARA_SHADERAST_STATEMENT(DeclareExternalStatement)

View File

@@ -20,7 +20,8 @@ namespace Nz::ShaderAst
AstRecursiveVisitor() = default;
~AstRecursiveVisitor() = default;
void Visit(AccessMemberExpression& node) override;
void Visit(AccessMemberIdentifierExpression& node) override;
void Visit(AccessMemberIndexExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
@@ -29,6 +30,7 @@ namespace Nz::ShaderAst
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
void Visit(VariableExpression& node) override;
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;

View File

@@ -23,7 +23,8 @@ namespace Nz::ShaderAst
AstSerializerBase(AstSerializerBase&&) = delete;
~AstSerializerBase() = default;
void Serialize(AccessMemberExpression& node);
void Serialize(AccessMemberIdentifierExpression& node);
void Serialize(AccessMemberIndexExpression& node);
void Serialize(AssignExpression& node);
void Serialize(BinaryExpression& node);
void Serialize(CastExpression& node);
@@ -32,6 +33,7 @@ namespace Nz::ShaderAst
void Serialize(IdentifierExpression& node);
void Serialize(IntrinsicExpression& node);
void Serialize(SwizzleExpression& node);
void Serialize(VariableExpression& node);
void Serialize(BranchStatement& node);
void Serialize(ConditionalStatement& node);

View File

@@ -31,7 +31,8 @@ namespace Nz::ShaderAst
private:
using AstExpressionVisitor::Visit;
void Visit(AccessMemberExpression& node) override;
void Visit(AccessMemberIdentifierExpression& node) override;
void Visit(AccessMemberIndexExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;
@@ -40,6 +41,7 @@ namespace Nz::ShaderAst
void Visit(IdentifierExpression& node) override;
void Visit(IntrinsicExpression& node) override;
void Visit(SwizzleExpression& node) override;
void Visit(VariableExpression& node) override;
ExpressionCategory m_expressionCategory;
};

View File

@@ -34,7 +34,7 @@ namespace Nz::ShaderAst
ExpressionType CheckField(const std::string& structName, const std::string* memberIdentifier, std::size_t remainingMembers);
const ExpressionType& ResolveAlias(const ExpressionType& expressionType);
void Visit(AccessMemberExpression& node) override;
void Visit(AccessMemberIdentifierExpression& node) override;
void Visit(AssignExpression& node) override;
void Visit(BinaryExpression& node) override;
void Visit(CastExpression& node) override;

View File

@@ -15,6 +15,11 @@ namespace Nz::ShaderBuilder
{
namespace Impl
{
struct AccessMember
{
inline std::unique_ptr<ShaderAst::AccessMemberIdentifierExpression> operator()(ShaderAst::ExpressionPtr structExpr, std::vector<std::string> memberIdentifiers) const;
};
struct Assign
{
inline std::unique_ptr<ShaderAst::AssignExpression> operator()(ShaderAst::AssignType op, ShaderAst::ExpressionPtr left, ShaderAst::ExpressionPtr right) const;
@@ -36,9 +41,19 @@ namespace Nz::ShaderBuilder
inline std::unique_ptr<ShaderAst::CastExpression> operator()(ShaderAst::ExpressionType targetType, std::vector<ShaderAst::ExpressionPtr> expressions) const;
};
struct ConditionalExpression
{
inline std::unique_ptr<ShaderAst::ConditionalExpression> operator()(std::string conditionName, ShaderAst::ExpressionPtr truePath, ShaderAst::ExpressionPtr falsePath) const;
};
struct ConditionalStatement
{
inline std::unique_ptr<ShaderAst::ConditionalStatement> operator()(std::string conditionName, ShaderAst::StatementPtr statement) const;
};
struct Constant
{
inline std::unique_ptr<ShaderAst::ConstantExpression> operator()(ShaderConstantValue value) const;
inline std::unique_ptr<ShaderAst::ConstantExpression> operator()(ShaderAst::ConstantValue value) const;
};
struct DeclareFunction
@@ -83,12 +98,20 @@ namespace Nz::ShaderBuilder
{
inline std::unique_ptr<ShaderAst::ReturnStatement> operator()(ShaderAst::ExpressionPtr expr = nullptr) const;
};
struct Swizzle
{
inline std::unique_ptr<ShaderAst::SwizzleExpression> operator()(ShaderAst::ExpressionPtr expression, std::vector<ShaderAst::SwizzleComponent> swizzleComponents) const;
};
}
constexpr Impl::AccessMember AccessMember;
constexpr Impl::Assign Assign;
constexpr Impl::Binary Binary;
constexpr Impl::Branch Branch;
constexpr Impl::Cast Cast;
constexpr Impl::ConditionalExpression ConditionalExpression;
constexpr Impl::ConditionalStatement ConditionalStatement;
constexpr Impl::Constant Constant;
constexpr Impl::DeclareFunction DeclareFunction;
constexpr Impl::DeclareStruct DeclareStruct;
@@ -99,6 +122,7 @@ namespace Nz::ShaderBuilder
constexpr Impl::Intrinsic Intrinsic;
constexpr Impl::NoParam<ShaderAst::NoOpStatement> NoOp;
constexpr Impl::Return Return;
constexpr Impl::Swizzle Swizzle;
}
#include <Nazara/Shader/ShaderBuilder.inl>

View File

@@ -7,6 +7,15 @@
namespace Nz::ShaderBuilder
{
inline std::unique_ptr<ShaderAst::AccessMemberIdentifierExpression> Impl::AccessMember::operator()(ShaderAst::ExpressionPtr structExpr, std::vector<std::string> memberIdentifiers) const
{
auto accessMemberNode = std::make_unique<ShaderAst::AccessMemberIdentifierExpression>();
accessMemberNode->structExpr = std::move(structExpr);
accessMemberNode->memberIdentifiers = std::move(memberIdentifiers);
return accessMemberNode;
}
inline std::unique_ptr<ShaderAst::AssignExpression> Impl::Assign::operator()(ShaderAst::AssignType op, ShaderAst::ExpressionPtr left, ShaderAst::ExpressionPtr right) const
{
auto assignNode = std::make_unique<ShaderAst::AssignExpression>();
@@ -61,7 +70,26 @@ namespace Nz::ShaderBuilder
return castNode;
}
inline std::unique_ptr<ShaderAst::ConstantExpression> Impl::Constant::operator()(ShaderConstantValue value) const
inline std::unique_ptr<ShaderAst::ConditionalExpression> Impl::ConditionalExpression::operator()(std::string conditionName, ShaderAst::ExpressionPtr truePath, ShaderAst::ExpressionPtr falsePath) const
{
auto condExprNode = std::make_unique<ShaderAst::ConditionalExpression>();
condExprNode->conditionName = std::move(conditionName);
condExprNode->falsePath = std::move(falsePath);
condExprNode->truePath = std::move(truePath);
return condExprNode;
}
inline std::unique_ptr<ShaderAst::ConditionalStatement> Impl::ConditionalStatement::operator()(std::string conditionName, ShaderAst::StatementPtr statement) const
{
auto condStatementNode = std::make_unique<ShaderAst::ConditionalStatement>();
condStatementNode->conditionName = std::move(conditionName);
condStatementNode->statement = std::move(statement);
return condStatementNode;
}
inline std::unique_ptr<ShaderAst::ConstantExpression> Impl::Constant::operator()(ShaderAst::ConstantValue value) const
{
auto constantNode = std::make_unique<ShaderAst::ConstantExpression>();
constantNode->value = std::move(value);
@@ -157,6 +185,18 @@ namespace Nz::ShaderBuilder
{
return std::make_unique<T>();
}
inline std::unique_ptr<ShaderAst::SwizzleExpression> Impl::Swizzle::operator()(ShaderAst::ExpressionPtr expression, std::vector<ShaderAst::SwizzleComponent> swizzleComponents) const
{
auto swizzleNode = std::make_unique<ShaderAst::SwizzleExpression>();
swizzleNode->expression = std::move(expression);
assert(swizzleComponents.size() <= swizzleNode->components.size());
for (std::size_t i = 0; i < swizzleComponents.size(); ++i)
swizzleNode->components[i] = swizzleComponents[i];
return swizzleNode;
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -12,7 +12,7 @@
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/Ast/ConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/Ast/Attribute.hpp>
#include <Nazara/Shader/Ast/ExpressionType.hpp>
@@ -60,7 +60,7 @@ namespace Nz::ShaderAst
std::optional<ExpressionType> cachedExpressionType;
};
struct NAZARA_SHADER_API AccessMemberExpression : public Expression
struct NAZARA_SHADER_API AccessMemberIdentifierExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
@@ -69,6 +69,15 @@ namespace Nz::ShaderAst
std::vector<std::string> memberIdentifiers;
};
struct NAZARA_SHADER_API AccessMemberIndexExpression : public Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
ExpressionPtr structExpr;
std::vector<std::size_t> memberIndices;
};
struct NAZARA_SHADER_API AssignExpression : public Expression
{
NodeType GetType() const override;
@@ -113,7 +122,7 @@ namespace Nz::ShaderAst
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
ShaderConstantValue value;
ShaderAst::ConstantValue value;
};
struct NAZARA_SHADER_API IdentifierExpression : public Expression
@@ -143,6 +152,14 @@ namespace Nz::ShaderAst
ExpressionPtr expression;
};
struct NAZARA_SHADER_API VariableExpression : Expression
{
NodeType GetType() const override;
void Visit(AstExpressionVisitor& visitor) override;
std::size_t variableId;
};
// Statements
struct Statement;
@@ -193,11 +210,12 @@ namespace Nz::ShaderAst
struct ExternalVar
{
std::vector<Attribute> attributes;
std::string name;
std::vector<Attribute> attributes;
ExpressionType type;
};
std::optional<std::size_t> varIndex;
std::vector<Attribute> attributes;
std::vector<ExternalVar> externalVars;
};
@@ -213,6 +231,8 @@ namespace Nz::ShaderAst
ExpressionType type;
};
std::optional<std::size_t> funcIndex;
std::optional<std::size_t> varIndex;
std::string name;
std::vector<Attribute> attributes;
std::vector<Parameter> parameters;
@@ -225,6 +245,7 @@ namespace Nz::ShaderAst
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
std::optional<std::size_t> structIndex;
std::vector<Attribute> attributes;
StructDescription description;
};
@@ -234,6 +255,7 @@ namespace Nz::ShaderAst
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
std::optional<std::size_t> varIndex;
std::string varName;
ExpressionPtr initialExpression;
ExpressionType varType;
@@ -274,6 +296,8 @@ namespace Nz::ShaderAst
ExpressionPtr returnExpr;
};
inline const ShaderAst::ExpressionType& GetExpressionType(ShaderAst::Expression& expr);
}
#include <Nazara/Shader/ShaderNodes.inl>

View File

@@ -7,6 +7,11 @@
namespace Nz::ShaderAst
{
const ShaderAst::ExpressionType& GetExpressionType(ShaderAst::Expression& expr)
{
assert(expr.cachedExpressionType);
return expr.cachedExpressionType.value();
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@@ -11,7 +11,9 @@
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderAstExpressionVisitorExcept.hpp>
#include <Nazara/Shader/ShaderAstStatementVisitorExcept.hpp>
#include <Nazara/Shader/Ast/ExpressionType.hpp>
#include <Nazara/Shader/SpirvBlock.hpp>
#include <unordered_map>
#include <vector>
namespace Nz
@@ -21,17 +23,25 @@ namespace Nz
class NAZARA_SHADER_API SpirvAstVisitor : public ShaderAst::ExpressionVisitorExcept, public ShaderAst::StatementVisitorExcept
{
public:
inline SpirvAstVisitor(SpirvWriter& writer, std::vector<SpirvBlock>& blocks);
struct EntryPoint;
struct FuncData;
struct Variable;
inline SpirvAstVisitor(SpirvWriter& writer, SpirvSection& instructions, std::vector<FuncData>& funcData);
SpirvAstVisitor(const SpirvAstVisitor&) = delete;
SpirvAstVisitor(SpirvAstVisitor&&) = delete;
~SpirvAstVisitor() = default;
UInt32 AllocateResultId();
UInt32 EvaluateExpression(ShaderAst::ExpressionPtr& expr);
const Variable& GetVariable(std::size_t varIndex) const;
using ExpressionVisitorExcept::Visit;
using StatementVisitorExcept::Visit;
void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::AccessMemberIndexExpression& node) override;
void Visit(ShaderAst::AssignExpression& node) override;
void Visit(ShaderAst::BinaryExpression& node) override;
void Visit(ShaderAst::BranchStatement& node) override;
@@ -39,27 +49,102 @@ namespace Nz
void Visit(ShaderAst::ConditionalExpression& node) override;
void Visit(ShaderAst::ConditionalStatement& node) override;
void Visit(ShaderAst::ConstantExpression& node) override;
void Visit(ShaderAst::DeclareExternalStatement& node) override;
void Visit(ShaderAst::DeclareFunctionStatement& node) override;
void Visit(ShaderAst::DeclareStructStatement& 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;
void Visit(ShaderAst::VariableExpression& node) override;
SpirvAstVisitor& operator=(const SpirvAstVisitor&) = delete;
SpirvAstVisitor& operator=(SpirvAstVisitor&&) = delete;
struct EntryPoint
{
struct Input
{
UInt32 memberIndexConstantId;
UInt32 memberPointerId;
UInt32 varId;
};
struct Output
{
Int32 memberIndex;
UInt32 typeId;
UInt32 varId;
};
struct InputStruct
{
UInt32 pointerId;
UInt32 typeId;
};
ShaderStageType stageType;
std::optional<InputStruct> inputStruct;
std::optional<UInt32> outputStructTypeId;
std::size_t funcIndex;
std::vector<Input> inputs;
std::vector<Output> outputs;
};
struct FuncData
{
std::optional<EntryPoint> entryPointData;
struct Parameter
{
UInt32 pointerTypeId;
UInt32 typeId;
};
struct Variable
{
UInt32 typeId;
UInt32 varId;
};
std::string name;
std::vector<Parameter> parameters;
std::vector<Variable> variables;
std::unordered_map<std::size_t, std::size_t> varIndexToVarId;
UInt32 funcId;
UInt32 funcTypeId;
UInt32 returnTypeId;
};
struct Variable
{
SpirvStorageClass storage;
UInt32 pointerId;
UInt32 pointedTypeId;
};
private:
inline const ShaderAst::ExpressionType& GetExpressionType(ShaderAst::Expression& expr) const;
void PushResultId(UInt32 value);
UInt32 PopResultId();
std::vector<SpirvBlock>& m_blocks;
inline void RegisterExternalVariable(std::size_t varIndex, const ShaderAst::ExpressionType& type);
inline void RegisterStruct(std::size_t structIndex, ShaderAst::StructDescription structDesc);
inline void RegisterVariable(std::size_t varIndex, UInt32 typeId, UInt32 pointerId, SpirvStorageClass storageClass);
std::size_t m_extVarIndex;
std::size_t m_funcIndex;
std::vector<std::size_t> m_scopeSizes;
std::vector<FuncData>& m_funcData;
std::vector<ShaderAst::StructDescription> m_structs;
std::vector<std::optional<Variable>> m_variables;
std::vector<SpirvBlock> m_functionBlocks;
std::vector<UInt32> m_resultIds;
SpirvBlock* m_currentBlock;
SpirvSection& m_instructions;
SpirvWriter& m_writer;
};
}

View File

@@ -7,17 +7,42 @@
namespace Nz
{
inline SpirvAstVisitor::SpirvAstVisitor(SpirvWriter& writer, std::vector<SpirvBlock>& blocks) :
m_blocks(blocks),
inline SpirvAstVisitor::SpirvAstVisitor(SpirvWriter& writer, SpirvSection& instructions, std::vector<FuncData>& funcData) :
m_extVarIndex(0),
m_funcIndex(0),
m_funcData(funcData),
m_currentBlock(nullptr),
m_instructions(instructions),
m_writer(writer)
{
m_currentBlock = &m_blocks.back();
}
inline const ShaderAst::ExpressionType& SpirvAstVisitor::GetExpressionType(ShaderAst::Expression& expr) const
void SpirvAstVisitor::RegisterExternalVariable(std::size_t varIndex, const ShaderAst::ExpressionType& type)
{
assert(expr.cachedExpressionType);
return expr.cachedExpressionType.value();
UInt32 pointerId = m_writer.GetExtVarPointerId(varIndex);
SpirvStorageClass storageClass = (IsSamplerType(type)) ? SpirvStorageClass::UniformConstant : SpirvStorageClass::Uniform;
RegisterVariable(varIndex, m_writer.GetTypeId(type), pointerId, storageClass);
}
inline void SpirvAstVisitor::RegisterStruct(std::size_t structIndex, ShaderAst::StructDescription structDesc)
{
if (structIndex >= m_structs.size())
m_structs.resize(structIndex + 1);
m_structs[structIndex] = std::move(structDesc);
}
inline void SpirvAstVisitor::RegisterVariable(std::size_t varIndex, UInt32 typeId, UInt32 pointerId, SpirvStorageClass storageClass)
{
if (varIndex >= m_variables.size())
m_variables.resize(varIndex + 1);
m_variables[varIndex] = Variable{
storageClass,
pointerId,
typeId
};
}
}

View File

@@ -8,8 +8,8 @@
#define NAZARA_SPIRVCONSTANTCACHE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/ShaderEnums.hpp>
#include <Nazara/Shader/Ast/ConstantValue.hpp>
#include <Nazara/Shader/Ast/ExpressionType.hpp>
#include <Nazara/Shader/SpirvData.hpp>
#include <memory>
@@ -25,6 +25,8 @@ namespace Nz
class NAZARA_SHADER_API SpirvConstantCache
{
public:
using StructCallback = std::function<const ShaderAst::StructDescription&(std::size_t structIndex)>;
SpirvConstantCache(UInt32& resultId);
SpirvConstantCache(const SpirvConstantCache& cache) = delete;
SpirvConstantCache(SpirvConstantCache&& cache) noexcept;
@@ -37,8 +39,6 @@ namespace Nz
using ConstantPtr = std::shared_ptr<Constant>;
using TypePtr = std::shared_ptr<Type>;
using IdentifierCallback = std::function<TypePtr(const std::string& identifier)>;
struct Bool {};
struct Float
@@ -66,11 +66,6 @@ namespace Nz
UInt32 columnCount;
};
struct Identifier
{
std::string name;
};
struct Image
{
std::optional<SpirvAccessQualifier> qualifier;
@@ -112,7 +107,7 @@ namespace Nz
std::vector<Member> members;
};
using AnyType = std::variant<Bool, Float, Function, Identifier, Image, Integer, Matrix, Pointer, SampledImage, Structure, Vector, Void>;
using AnyType = std::variant<Bool, Float, Function, Image, Integer, Matrix, Pointer, SampledImage, Structure, Vector, Void>;
struct ConstantBool
{
@@ -134,10 +129,11 @@ namespace Nz
struct Variable
{
std::optional<std::size_t> funcId; //< For inputs/outputs
std::optional<ConstantPtr> initializer;
std::string debugName;
TypePtr type;
SpirvStorageClass storageClass;
std::optional<ConstantPtr> initializer;
};
using BaseType = std::variant<Bool, Float, Integer, Vector, Matrix, Image>;
@@ -166,6 +162,21 @@ namespace Nz
AnyType type;
};
ConstantPtr BuildConstant(const ShaderAst::ConstantValue& value) const;
TypePtr BuildFunctionType(const ShaderAst::ExpressionType& retType, const std::vector<ShaderAst::ExpressionType>& parameters) const;
TypePtr BuildPointerType(const ShaderAst::PrimitiveType& type, SpirvStorageClass storageClass) const;
TypePtr BuildPointerType(const ShaderAst::ExpressionType& type, SpirvStorageClass storageClass) const;
TypePtr BuildType(const ShaderAst::ExpressionType& type) const;
TypePtr BuildType(const ShaderAst::IdentifierType& type) const;
TypePtr BuildType(const ShaderAst::MatrixType& type) const;
TypePtr BuildType(const ShaderAst::NoType& type) const;
TypePtr BuildType(const ShaderAst::PrimitiveType& type) const;
TypePtr BuildType(const ShaderAst::SamplerType& type) const;
TypePtr BuildType(const ShaderAst::StructType& type) const;
TypePtr BuildType(const ShaderAst::StructDescription& structDesc) const;
TypePtr BuildType(const ShaderAst::VectorType& type) const;
TypePtr BuildType(const ShaderAst::UniformType& type) const;
UInt32 GetId(const Constant& c);
UInt32 GetId(const Type& t);
UInt32 GetId(const Variable& v);
@@ -174,26 +185,13 @@ namespace Nz
UInt32 Register(Type t);
UInt32 Register(Variable v);
void SetIdentifierCallback(IdentifierCallback callback);
void SetStructCallback(StructCallback callback);
void Write(SpirvSection& annotations, SpirvSection& constants, SpirvSection& debugInfos);
SpirvConstantCache& operator=(const SpirvConstantCache& cache) = delete;
SpirvConstantCache& operator=(SpirvConstantCache&& cache) noexcept;
static ConstantPtr BuildConstant(const ShaderConstantValue& value);
static TypePtr BuildFunctionType(const ShaderAst::ExpressionType& retType, const std::vector<ShaderAst::ExpressionType>& parameters);
static TypePtr BuildPointerType(const ShaderAst::PrimitiveType& type, SpirvStorageClass storageClass);
static TypePtr BuildPointerType(const ShaderAst::ExpressionType& type, SpirvStorageClass storageClass);
static TypePtr BuildType(const ShaderAst::ExpressionType& type);
static TypePtr BuildType(const ShaderAst::IdentifierType& type);
static TypePtr BuildType(const ShaderAst::MatrixType& type);
static TypePtr BuildType(const ShaderAst::NoType& type);
static TypePtr BuildType(const ShaderAst::PrimitiveType& type);
static TypePtr BuildType(const ShaderAst::SamplerType& type);
static TypePtr BuildType(const ShaderAst::StructDescription& structDesc);
static TypePtr BuildType(const ShaderAst::VectorType& type);
private:
struct DepRegisterer;
struct Eq;
@@ -204,7 +202,6 @@ namespace Nz
void WriteStruct(const Structure& structData, UInt32 resultId, SpirvSection& annotations, SpirvSection& constants, SpirvSection& debugInfos);
IdentifierCallback m_identifierCallback;
std::unique_ptr<Internal> m_internal;
};
}

View File

@@ -15,13 +15,14 @@
namespace Nz
{
class SpirvAstVisitor;
class SpirvBlock;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionLoad : public ShaderAst::ExpressionVisitorExcept
{
public:
inline SpirvExpressionLoad(SpirvWriter& writer, SpirvBlock& block);
inline SpirvExpressionLoad(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block);
SpirvExpressionLoad(const SpirvExpressionLoad&) = delete;
SpirvExpressionLoad(SpirvExpressionLoad&&) = delete;
~SpirvExpressionLoad() = default;
@@ -29,8 +30,8 @@ namespace Nz
UInt32 Evaluate(ShaderAst::Expression& node);
using ExpressionVisitorExcept::Visit;
//void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::IdentifierExpression& node) override;
void Visit(ShaderAst::AccessMemberIndexExpression& node) override;
void Visit(ShaderAst::VariableExpression& node) override;
SpirvExpressionLoad& operator=(const SpirvExpressionLoad&) = delete;
SpirvExpressionLoad& operator=(SpirvExpressionLoad&&) = delete;
@@ -39,7 +40,7 @@ namespace Nz
struct Pointer
{
SpirvStorageClass storage;
UInt32 resultId;
UInt32 pointerId;
UInt32 pointedTypeId;
};
@@ -48,6 +49,7 @@ namespace Nz
UInt32 resultId;
};
SpirvAstVisitor& m_visitor;
SpirvBlock& m_block;
SpirvWriter& m_writer;
std::variant<std::monostate, Pointer, Value> m_value;

View File

@@ -7,9 +7,10 @@
namespace Nz
{
inline SpirvExpressionLoad::SpirvExpressionLoad(SpirvWriter& writer, SpirvBlock& block) :
inline SpirvExpressionLoad::SpirvExpressionLoad(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block) :
m_block(block),
m_writer(writer)
m_writer(writer),
m_visitor(visitor)
{
}
}

View File

@@ -14,13 +14,14 @@
namespace Nz
{
class SpirvAstVisitor;
class SpirvBlock;
class SpirvWriter;
class NAZARA_SHADER_API SpirvExpressionStore : public ShaderAst::ExpressionVisitorExcept
{
public:
inline SpirvExpressionStore(SpirvWriter& writer, SpirvBlock& block);
inline SpirvExpressionStore(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block);
SpirvExpressionStore(const SpirvExpressionStore&) = delete;
SpirvExpressionStore(SpirvExpressionStore&&) = delete;
~SpirvExpressionStore() = default;
@@ -28,9 +29,9 @@ namespace Nz
void Store(ShaderAst::ExpressionPtr& node, UInt32 resultId);
using ExpressionVisitorExcept::Visit;
//void Visit(ShaderAst::AccessMemberExpression& node) override;
void Visit(ShaderAst::IdentifierExpression& node) override;
void Visit(ShaderAst::AccessMemberIndexExpression& node) override;
void Visit(ShaderAst::SwizzleExpression& node) override;
void Visit(ShaderAst::VariableExpression& node) override;
SpirvExpressionStore& operator=(const SpirvExpressionStore&) = delete;
SpirvExpressionStore& operator=(SpirvExpressionStore&&) = delete;
@@ -44,9 +45,10 @@ namespace Nz
struct Pointer
{
SpirvStorageClass storage;
UInt32 resultId;
UInt32 pointerId;
};
SpirvAstVisitor& m_visitor;
SpirvBlock& m_block;
SpirvWriter& m_writer;
std::variant<std::monostate, LocalVar, Pointer> m_value;

View File

@@ -7,9 +7,10 @@
namespace Nz
{
inline SpirvExpressionStore::SpirvExpressionStore(SpirvWriter& writer, SpirvBlock& block) :
inline SpirvExpressionStore::SpirvExpressionStore(SpirvWriter& writer, SpirvAstVisitor& visitor, SpirvBlock& block) :
m_block(block),
m_writer(writer)
m_writer(writer),
m_visitor(visitor)
{
}
}

View File

@@ -9,7 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
#include <Nazara/Shader/ShaderConstantValue.hpp>
#include <Nazara/Shader/Ast/ConstantValue.hpp>
#include <Nazara/Shader/ShaderNodes.hpp>
#include <Nazara/Shader/ShaderWriter.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
@@ -27,7 +27,6 @@ namespace Nz
friend class SpirvBlock;
friend class SpirvExpressionLoad;
friend class SpirvExpressionStore;
friend class SpirvVisitor;
public:
struct Environment;
@@ -48,7 +47,6 @@ namespace Nz
};
private:
struct ExtVar;
struct FunctionParameter;
struct OnlyCache {};
@@ -56,36 +54,21 @@ namespace Nz
void AppendHeader();
UInt32 GetConstantId(const ShaderConstantValue& value) const;
SpirvConstantCache::TypePtr BuildFunctionType(const ShaderAst::DeclareFunctionStatement& functionNode);
UInt32 GetConstantId(const ShaderAst::ConstantValue& value) const;
UInt32 GetExtVarPointerId(std::size_t varIndex) const;
UInt32 GetFunctionTypeId(const ShaderAst::DeclareFunctionStatement& functionNode);
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 ShaderAst::ExpressionType& type, SpirvStorageClass storageClass) const;
UInt32 GetTypeId(const ShaderAst::ExpressionType& type) const;
inline bool IsConditionEnabled(const std::string& condition) const;
UInt32 ReadInputVariable(const std::string& name);
std::optional<UInt32> ReadInputVariable(const std::string& name, OnlyCache);
UInt32 ReadLocalVariable(const std::string& name);
std::optional<UInt32> ReadLocalVariable(const std::string& name, OnlyCache);
UInt32 ReadParameterVariable(const std::string& name);
std::optional<UInt32> ReadParameterVariable(const std::string& name, OnlyCache);
UInt32 ReadUniformVariable(const std::string& name);
std::optional<UInt32> ReadUniformVariable(const std::string& name, OnlyCache);
UInt32 ReadVariable(ExtVar& var);
std::optional<UInt32> ReadVariable(const ExtVar& var, OnlyCache);
UInt32 RegisterConstant(const ShaderConstantValue& value);
UInt32 RegisterConstant(const ShaderAst::ConstantValue& value);
UInt32 RegisterFunctionType(const ShaderAst::DeclareFunctionStatement& functionNode);
UInt32 RegisterPointerType(ShaderAst::ExpressionType type, SpirvStorageClass storageClass);
UInt32 RegisterType(ShaderAst::ExpressionType type);
void WriteLocalVariable(std::string name, UInt32 resultId);
static SpirvConstantCache::TypePtr BuildFunctionType(const ShaderAst::DeclareFunctionStatement& functionNode);
static void MergeSections(std::vector<UInt32>& output, const SpirvSection& from);
struct Context
@@ -93,20 +76,6 @@ namespace Nz
const States* states = nullptr;
};
struct ExtVar
{
UInt32 pointerTypeId;
UInt32 typeId;
UInt32 varId;
std::optional<UInt32> valueId;
};
struct FunctionParameter
{
std::string name;
ShaderAst::ExpressionType type;
};
struct State;
Context m_context;