Shader: Implement const if and const values

This commit is contained in:
Jérôme Leclercq
2021-07-07 21:38:23 +02:00
parent d679eccb43
commit 1f6937ab1b
28 changed files with 315 additions and 60 deletions

View File

@@ -57,6 +57,7 @@ namespace Nz::ShaderAst
virtual StatementPtr Clone(BranchStatement& node);
virtual StatementPtr Clone(ConditionalStatement& node);
virtual StatementPtr Clone(DeclareConstStatement& node);
virtual StatementPtr Clone(DeclareExternalStatement& node);
virtual StatementPtr Clone(DeclareFunctionStatement& node);
virtual StatementPtr Clone(DeclareOptionStatement& node);

View File

@@ -44,6 +44,7 @@ NAZARA_SHADERAST_EXPRESSION(VariableExpression)
NAZARA_SHADERAST_EXPRESSION(UnaryExpression)
NAZARA_SHADERAST_STATEMENT(BranchStatement)
NAZARA_SHADERAST_STATEMENT(ConditionalStatement)
NAZARA_SHADERAST_STATEMENT(DeclareConstStatement)
NAZARA_SHADERAST_STATEMENT(DeclareExternalStatement)
NAZARA_SHADERAST_STATEMENT(DeclareFunctionStatement)
NAZARA_SHADERAST_STATEMENT(DeclareOptionStatement)

View File

@@ -39,6 +39,7 @@ namespace Nz::ShaderAst
void Visit(BranchStatement& node) override;
void Visit(ConditionalStatement& node) override;
void Visit(DeclareConstStatement& node) override;
void Visit(DeclareExternalStatement& node) override;
void Visit(DeclareFunctionStatement& node) override;
void Visit(DeclareOptionStatement& node) override;

View File

@@ -42,6 +42,7 @@ namespace Nz::ShaderAst
void Serialize(BranchStatement& node);
void Serialize(ConditionalStatement& node);
void Serialize(DeclareConstStatement& node);
void Serialize(DeclareExternalStatement& node);
void Serialize(DeclareFunctionStatement& node);
void Serialize(DeclareOptionStatement& node);

View File

@@ -242,6 +242,7 @@ namespace Nz::ShaderAst
std::vector<ConditionalStatement> condStatements;
StatementPtr elseStatement;
bool isConst = false;
};
struct NAZARA_SHADER_API ConditionalStatement : Statement
@@ -253,6 +254,17 @@ namespace Nz::ShaderAst
StatementPtr statement;
};
struct NAZARA_SHADER_API DeclareConstStatement : Statement
{
NodeType GetType() const override;
void Visit(AstStatementVisitor& visitor) override;
std::optional<std::size_t> constIndex;
std::string name;
ExpressionPtr expression;
ExpressionType type;
};
struct NAZARA_SHADER_API DeclareExternalStatement : Statement
{
NodeType GetType() const override;

View File

@@ -55,14 +55,17 @@ namespace Nz::ShaderAst
ExpressionPtr Clone(CastExpression& node) override;
ExpressionPtr Clone(ConditionalExpression& node) override;
ExpressionPtr Clone(ConstantExpression& node) override;
ExpressionPtr Clone(ConstantIndexExpression& node) override;
ExpressionPtr Clone(IdentifierExpression& node) override;
ExpressionPtr Clone(IntrinsicExpression& node) override;
ExpressionPtr Clone(SelectOptionExpression& node) override;
ExpressionPtr Clone(SwizzleExpression& node) override;
ExpressionPtr Clone(UnaryExpression& node) override;
ExpressionPtr Clone(VariableExpression& node) override;
StatementPtr Clone(BranchStatement& node) override;
StatementPtr Clone(ConditionalStatement& node) override;
StatementPtr Clone(DeclareConstStatement& node) override;
StatementPtr Clone(DeclareExternalStatement& node) override;
StatementPtr Clone(DeclareFunctionStatement& node) override;
StatementPtr Clone(DeclareOptionStatement& node) override;
@@ -84,6 +87,7 @@ namespace Nz::ShaderAst
template<typename T> const T& ComputeAttributeValue(AttributeValue<T>& attribute);
ConstantValue ComputeConstantValue(Expression& expr);
template<typename T> std::unique_ptr<T> Optimize(T& node);
std::size_t DeclareFunction(DeclareFunctionStatement& funcDecl);

View File

@@ -93,6 +93,7 @@ namespace Nz
void Visit(ShaderAst::UnaryExpression& node) override;
void Visit(ShaderAst::BranchStatement& node) override;
void Visit(ShaderAst::DeclareConstStatement& node) override;
void Visit(ShaderAst::DeclareExternalStatement& node) override;
void Visit(ShaderAst::DeclareFunctionStatement& node) override;
void Visit(ShaderAst::DeclareOptionStatement& node) override;

View File

@@ -38,6 +38,7 @@ namespace Nz::ShaderBuilder
inline std::unique_ptr<ShaderAst::BinaryExpression> operator()(ShaderAst::BinaryType op, ShaderAst::ExpressionPtr left, ShaderAst::ExpressionPtr right) const;
};
template<bool Const>
struct Branch
{
inline std::unique_ptr<ShaderAst::BranchStatement> operator()(ShaderAst::ExpressionPtr condition, ShaderAst::StatementPtr truePath, ShaderAst::StatementPtr falsePath = nullptr) const;
@@ -70,6 +71,12 @@ namespace Nz::ShaderBuilder
inline std::unique_ptr<ShaderAst::ConstantExpression> operator()(ShaderAst::ConstantValue value) const;
};
struct DeclareConst
{
inline std::unique_ptr<ShaderAst::DeclareConstStatement> operator()(std::string name, ShaderAst::ExpressionPtr initialValue) const;
inline std::unique_ptr<ShaderAst::DeclareConstStatement> operator()(std::string name, ShaderAst::ExpressionType type, ShaderAst::ExpressionPtr initialValue = nullptr) const;
};
struct DeclareFunction
{
inline std::unique_ptr<ShaderAst::DeclareFunctionStatement> operator()(std::string name, ShaderAst::StatementPtr statement) const;
@@ -144,12 +151,14 @@ namespace Nz::ShaderBuilder
constexpr Impl::AccessMember AccessMember;
constexpr Impl::Assign Assign;
constexpr Impl::Binary Binary;
constexpr Impl::Branch Branch;
constexpr Impl::Branch<false> Branch;
constexpr Impl::CallFunction CallFunction;
constexpr Impl::Cast Cast;
constexpr Impl::ConditionalExpression ConditionalExpression;
constexpr Impl::ConditionalStatement ConditionalStatement;
constexpr Impl::Constant Constant;
constexpr Impl::Branch<true> ConstBranch;
constexpr Impl::DeclareConst DeclareConst;
constexpr Impl::DeclareFunction DeclareFunction;
constexpr Impl::DeclareOption DeclareOption;
constexpr Impl::DeclareStruct DeclareStruct;

View File

@@ -57,7 +57,8 @@ namespace Nz::ShaderBuilder
return binaryNode;
}
inline std::unique_ptr<ShaderAst::BranchStatement> Impl::Branch::operator()(ShaderAst::ExpressionPtr condition, ShaderAst::StatementPtr truePath, ShaderAst::StatementPtr falsePath) const
template<bool Const>
std::unique_ptr<ShaderAst::BranchStatement> Impl::Branch<Const>::operator()(ShaderAst::ExpressionPtr condition, ShaderAst::StatementPtr truePath, ShaderAst::StatementPtr falsePath) const
{
auto branchNode = std::make_unique<ShaderAst::BranchStatement>();
@@ -66,15 +67,18 @@ namespace Nz::ShaderBuilder
condStatement.statement = std::move(truePath);
branchNode->elseStatement = std::move(falsePath);
branchNode->isConst = Const;
return branchNode;
}
inline std::unique_ptr<ShaderAst::BranchStatement> Impl::Branch::operator()(std::vector<ShaderAst::BranchStatement::ConditionalStatement> condStatements, ShaderAst::StatementPtr elseStatement) const
template<bool Const>
std::unique_ptr<ShaderAst::BranchStatement> Impl::Branch<Const>::operator()(std::vector<ShaderAst::BranchStatement::ConditionalStatement> condStatements, ShaderAst::StatementPtr elseStatement) const
{
auto branchNode = std::make_unique<ShaderAst::BranchStatement>();
branchNode->condStatements = std::move(condStatements);
branchNode->elseStatement = std::move(elseStatement);
branchNode->isConst = Const;
return branchNode;
}
@@ -136,6 +140,25 @@ namespace Nz::ShaderBuilder
return constantNode;
}
inline std::unique_ptr<ShaderAst::DeclareConstStatement> Impl::DeclareConst::operator()(std::string name, ShaderAst::ExpressionPtr initialValue) const
{
auto declareConstNode = std::make_unique<ShaderAst::DeclareConstStatement>();
declareConstNode->name = std::move(name);
declareConstNode->expression = std::move(initialValue);
return declareConstNode;
}
inline std::unique_ptr<ShaderAst::DeclareConstStatement> Impl::DeclareConst::operator()(std::string name, ShaderAst::ExpressionType type, ShaderAst::ExpressionPtr initialValue) const
{
auto declareConstNode = std::make_unique<ShaderAst::DeclareConstStatement>();
declareConstNode->name = std::move(name);
declareConstNode->type = std::move(type);
declareConstNode->expression = std::move(initialValue);
return declareConstNode;
}
inline std::unique_ptr<ShaderAst::DeclareFunctionStatement> Impl::DeclareFunction::operator()(std::string name, ShaderAst::StatementPtr statement) const
{
auto declareFunctionNode = std::make_unique<ShaderAst::DeclareFunctionStatement>();

View File

@@ -81,9 +81,11 @@ namespace Nz::ShaderLang
const Token& Peek(std::size_t advance = 0);
std::vector<ShaderAst::Attribute> ParseAttributes();
void ParseVariableDeclaration(std::string& name, ShaderAst::ExpressionType& type, ShaderAst::ExpressionPtr& initialValue);
// Statements
ShaderAst::StatementPtr ParseBranchStatement();
ShaderAst::StatementPtr ParseConstStatement();
ShaderAst::StatementPtr ParseDiscardStatement();
ShaderAst::StatementPtr ParseExternalBlock(std::vector<ShaderAst::Attribute> attributes = {});
std::vector<ShaderAst::StatementPtr> ParseFunctionBody();

View File

@@ -18,6 +18,7 @@ NAZARA_SHADERLANG_TOKEN(ClosingCurlyBracket)
NAZARA_SHADERLANG_TOKEN(ClosingSquareBracket)
NAZARA_SHADERLANG_TOKEN(Colon)
NAZARA_SHADERLANG_TOKEN(Comma)
NAZARA_SHADERLANG_TOKEN(Const)
NAZARA_SHADERLANG_TOKEN(Discard)
NAZARA_SHADERLANG_TOKEN(Divide)
NAZARA_SHADERLANG_TOKEN(Dot)

View File

@@ -48,6 +48,7 @@ namespace Nz
void Visit(ShaderAst::CallFunctionExpression& node) override;
void Visit(ShaderAst::CastExpression& node) override;
void Visit(ShaderAst::ConstantExpression& node) override;
void Visit(ShaderAst::DeclareConstStatement& node) override;
void Visit(ShaderAst::DeclareExternalStatement& node) override;
void Visit(ShaderAst::DeclareFunctionStatement& node) override;
void Visit(ShaderAst::DeclareOptionStatement& node) override;