From ed72d668d96970f89f903478b2d9f7998673c887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 30 Dec 2020 20:05:16 +0100 Subject: [PATCH] Shader: Add Discard node --- include/Nazara/Shader/GlslWriter.hpp | 1 + include/Nazara/Shader/ShaderAstCloner.hpp | 1 + .../Shader/ShaderAstRecursiveVisitor.hpp | 1 + include/Nazara/Shader/ShaderAstSerializer.hpp | 1 + include/Nazara/Shader/ShaderAstVisitor.hpp | 1 + .../Nazara/Shader/ShaderAstVisitorExcept.hpp | 1 + include/Nazara/Shader/ShaderBuilder.hpp | 1 + include/Nazara/Shader/ShaderEnums.hpp | 1 + include/Nazara/Shader/ShaderNodes.hpp | 9 +++ include/Nazara/Shader/ShaderNodes.inl | 11 ++++ include/Nazara/Shader/SpirvAstVisitor.hpp | 1 + src/Nazara/Shader/GlslWriter.cpp | 5 ++ src/Nazara/Shader/ShaderAstCloner.cpp | 5 ++ .../Shader/ShaderAstRecursiveVisitor.cpp | 5 ++ src/Nazara/Shader/ShaderAstSerializer.cpp | 11 ++++ src/Nazara/Shader/ShaderAstVisitorExcept.cpp | 5 ++ src/Nazara/Shader/ShaderNodes.cpp | 6 ++ src/Nazara/Shader/SpirvAstVisitor.cpp | 5 ++ src/ShaderNode/DataModels/Discard.cpp | 56 +++++++++++++++++++ src/ShaderNode/DataModels/Discard.hpp | 32 +++++++++++ src/ShaderNode/DataModels/Discard.inl | 1 + src/ShaderNode/ShaderGraph.cpp | 2 + 22 files changed, 162 insertions(+) create mode 100644 src/ShaderNode/DataModels/Discard.cpp create mode 100644 src/ShaderNode/DataModels/Discard.hpp create mode 100644 src/ShaderNode/DataModels/Discard.inl diff --git a/include/Nazara/Shader/GlslWriter.hpp b/include/Nazara/Shader/GlslWriter.hpp index e7b92505c..d7fb7000a 100644 --- a/include/Nazara/Shader/GlslWriter.hpp +++ b/include/Nazara/Shader/GlslWriter.hpp @@ -73,6 +73,7 @@ namespace Nz void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::DeclareVariable& node) override; + void Visit(ShaderNodes::Discard& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::InputVariable& var) override; diff --git a/include/Nazara/Shader/ShaderAstCloner.hpp b/include/Nazara/Shader/ShaderAstCloner.hpp index afa7cb5b2..1f5259b51 100644 --- a/include/Nazara/Shader/ShaderAstCloner.hpp +++ b/include/Nazara/Shader/ShaderAstCloner.hpp @@ -42,6 +42,7 @@ namespace Nz void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::DeclareVariable& node) override; + void Visit(ShaderNodes::Discard& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override; diff --git a/include/Nazara/Shader/ShaderAstRecursiveVisitor.hpp b/include/Nazara/Shader/ShaderAstRecursiveVisitor.hpp index 5dd1bc5fe..9e780e340 100644 --- a/include/Nazara/Shader/ShaderAstRecursiveVisitor.hpp +++ b/include/Nazara/Shader/ShaderAstRecursiveVisitor.hpp @@ -30,6 +30,7 @@ namespace Nz void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::DeclareVariable& node) override; + void Visit(ShaderNodes::Discard& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override; diff --git a/include/Nazara/Shader/ShaderAstSerializer.hpp b/include/Nazara/Shader/ShaderAstSerializer.hpp index e2db77fdf..5155a702e 100644 --- a/include/Nazara/Shader/ShaderAstSerializer.hpp +++ b/include/Nazara/Shader/ShaderAstSerializer.hpp @@ -35,6 +35,7 @@ namespace Nz void Serialize(ShaderNodes::ConditionalStatement& node); void Serialize(ShaderNodes::Constant& node); void Serialize(ShaderNodes::DeclareVariable& node); + void Serialize(ShaderNodes::Discard& node); void Serialize(ShaderNodes::ExpressionStatement& node); void Serialize(ShaderNodes::Identifier& node); void Serialize(ShaderNodes::IntrinsicCall& node); diff --git a/include/Nazara/Shader/ShaderAstVisitor.hpp b/include/Nazara/Shader/ShaderAstVisitor.hpp index 9ac8d764c..f3b0c5bdc 100644 --- a/include/Nazara/Shader/ShaderAstVisitor.hpp +++ b/include/Nazara/Shader/ShaderAstVisitor.hpp @@ -31,6 +31,7 @@ namespace Nz virtual void Visit(ShaderNodes::ConditionalStatement& node) = 0; virtual void Visit(ShaderNodes::Constant& node) = 0; virtual void Visit(ShaderNodes::DeclareVariable& node) = 0; + virtual void Visit(ShaderNodes::Discard& node) = 0; virtual void Visit(ShaderNodes::ExpressionStatement& node) = 0; virtual void Visit(ShaderNodes::Identifier& node) = 0; virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0; diff --git a/include/Nazara/Shader/ShaderAstVisitorExcept.hpp b/include/Nazara/Shader/ShaderAstVisitorExcept.hpp index 0c58c5472..3878d522d 100644 --- a/include/Nazara/Shader/ShaderAstVisitorExcept.hpp +++ b/include/Nazara/Shader/ShaderAstVisitorExcept.hpp @@ -26,6 +26,7 @@ namespace Nz void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::DeclareVariable& node) override; + void Visit(ShaderNodes::Discard& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override; diff --git a/include/Nazara/Shader/ShaderBuilder.hpp b/include/Nazara/Shader/ShaderBuilder.hpp index 0965c7f0c..d7c982eee 100644 --- a/include/Nazara/Shader/ShaderBuilder.hpp +++ b/include/Nazara/Shader/ShaderBuilder.hpp @@ -54,6 +54,7 @@ namespace Nz::ShaderBuilder constexpr GenBuilder ConditionalStatement; constexpr GenBuilder Constant; constexpr GenBuilder DeclareVariable; + constexpr GenBuilder Discard; constexpr BinOpBuilder Divide; constexpr BinOpBuilder Equal; constexpr GenBuilder ExprStatement; diff --git a/include/Nazara/Shader/ShaderEnums.hpp b/include/Nazara/Shader/ShaderEnums.hpp index 57f76d0f5..596292d9d 100644 --- a/include/Nazara/Shader/ShaderEnums.hpp +++ b/include/Nazara/Shader/ShaderEnums.hpp @@ -81,6 +81,7 @@ namespace Nz::ShaderNodes ConditionalExpression, ConditionalStatement, DeclareVariable, + Discard, ExpressionStatement, Identifier, IntrinsicCall, diff --git a/include/Nazara/Shader/ShaderNodes.hpp b/include/Nazara/Shader/ShaderNodes.hpp index 8639dbc99..e519a0b08 100644 --- a/include/Nazara/Shader/ShaderNodes.hpp +++ b/include/Nazara/Shader/ShaderNodes.hpp @@ -123,6 +123,15 @@ namespace Nz static inline std::shared_ptr Build(VariablePtr variable, ExpressionPtr expression = nullptr); }; + struct NAZARA_SHADER_API Discard : public Statement + { + inline Discard(); + + void Visit(ShaderAstVisitor& visitor) override; + + static inline std::shared_ptr Build(); + }; + struct NAZARA_SHADER_API Identifier : public Expression { inline Identifier(); diff --git a/include/Nazara/Shader/ShaderNodes.inl b/include/Nazara/Shader/ShaderNodes.inl index b61841430..fe0872a9d 100644 --- a/include/Nazara/Shader/ShaderNodes.inl +++ b/include/Nazara/Shader/ShaderNodes.inl @@ -148,6 +148,17 @@ namespace Nz::ShaderNodes } + inline Discard::Discard() : + Statement(NodeType::DeclareVariable) + { + } + + inline std::shared_ptr Discard::Build() + { + return std::make_shared(); + } + + inline Identifier::Identifier() : Expression(NodeType::Identifier) { diff --git a/include/Nazara/Shader/SpirvAstVisitor.hpp b/include/Nazara/Shader/SpirvAstVisitor.hpp index d7196950f..91ad031ad 100644 --- a/include/Nazara/Shader/SpirvAstVisitor.hpp +++ b/include/Nazara/Shader/SpirvAstVisitor.hpp @@ -36,6 +36,7 @@ namespace Nz void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::DeclareVariable& node) override; + void Visit(ShaderNodes::Discard& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override; diff --git a/src/Nazara/Shader/GlslWriter.cpp b/src/Nazara/Shader/GlslWriter.cpp index 248c92bb7..649f25072 100644 --- a/src/Nazara/Shader/GlslWriter.cpp +++ b/src/Nazara/Shader/GlslWriter.cpp @@ -519,6 +519,11 @@ namespace Nz AppendLine(";"); } + void GlslWriter::Visit(ShaderNodes::Discard& /*node*/) + { + Append("discard;"); + } + void GlslWriter::Visit(ShaderNodes::ExpressionStatement& node) { Visit(node.expression); diff --git a/src/Nazara/Shader/ShaderAstCloner.cpp b/src/Nazara/Shader/ShaderAstCloner.cpp index cef0ac694..8a07cf1a7 100644 --- a/src/Nazara/Shader/ShaderAstCloner.cpp +++ b/src/Nazara/Shader/ShaderAstCloner.cpp @@ -111,6 +111,11 @@ namespace Nz PushStatement(ShaderNodes::DeclareVariable::Build(CloneVariable(node.variable), CloneExpression(node.expression))); } + void ShaderAstCloner::Visit(ShaderNodes::Discard& /*node*/) + { + PushStatement(ShaderNodes::Discard::Build()); + } + void ShaderAstCloner::Visit(ShaderNodes::ExpressionStatement& node) { PushStatement(ShaderNodes::ExpressionStatement::Build(CloneExpression(node.expression))); diff --git a/src/Nazara/Shader/ShaderAstRecursiveVisitor.cpp b/src/Nazara/Shader/ShaderAstRecursiveVisitor.cpp index b68d5361a..bca595384 100644 --- a/src/Nazara/Shader/ShaderAstRecursiveVisitor.cpp +++ b/src/Nazara/Shader/ShaderAstRecursiveVisitor.cpp @@ -69,6 +69,11 @@ namespace Nz Visit(node.expression); } + void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Discard& /*node*/) + { + /* Nothing to do */ + } + void ShaderAstRecursiveVisitor::Visit(ShaderNodes::ExpressionStatement& node) { Visit(node.expression); diff --git a/src/Nazara/Shader/ShaderAstSerializer.cpp b/src/Nazara/Shader/ShaderAstSerializer.cpp index 5184d980d..a5e870713 100644 --- a/src/Nazara/Shader/ShaderAstSerializer.cpp +++ b/src/Nazara/Shader/ShaderAstSerializer.cpp @@ -67,6 +67,11 @@ namespace Nz Serialize(node); } + void Visit(ShaderNodes::Discard& node) override + { + Serialize(node); + } + void Visit(ShaderNodes::ExpressionStatement& node) override { Serialize(node); @@ -242,6 +247,11 @@ namespace Nz Node(node.expression); } + void ShaderAstSerializerBase::Serialize(ShaderNodes::Discard& /*node*/) + { + /* Nothing to do */ + } + void ShaderAstSerializerBase::Serialize(ShaderNodes::ExpressionStatement& node) { Node(node.expression); @@ -665,6 +675,7 @@ namespace Nz HandleType(ConditionalExpression); HandleType(ConditionalStatement); HandleType(DeclareVariable); + HandleType(Discard); HandleType(ExpressionStatement); HandleType(Identifier); HandleType(IntrinsicCall); diff --git a/src/Nazara/Shader/ShaderAstVisitorExcept.cpp b/src/Nazara/Shader/ShaderAstVisitorExcept.cpp index 85ae826d1..17671a42c 100644 --- a/src/Nazara/Shader/ShaderAstVisitorExcept.cpp +++ b/src/Nazara/Shader/ShaderAstVisitorExcept.cpp @@ -53,6 +53,11 @@ namespace Nz throw std::runtime_error("unhandled DeclareVariable node"); } + void ShaderAstVisitorExcept::Visit(ShaderNodes::Discard& /*node*/) + { + throw std::runtime_error("unhandled Discard node"); + } + void ShaderAstVisitorExcept::Visit(ShaderNodes::ExpressionStatement& /*node*/) { throw std::runtime_error("unhandled ExpressionStatement node"); diff --git a/src/Nazara/Shader/ShaderNodes.cpp b/src/Nazara/Shader/ShaderNodes.cpp index 6530c1713..c6aa7874a 100644 --- a/src/Nazara/Shader/ShaderNodes.cpp +++ b/src/Nazara/Shader/ShaderNodes.cpp @@ -42,6 +42,12 @@ namespace Nz::ShaderNodes } + void Discard::Visit(ShaderAstVisitor& visitor) + { + visitor.Visit(*this); + } + + ExpressionCategory Identifier::GetExpressionCategory() const { return ExpressionCategory::LValue; diff --git a/src/Nazara/Shader/SpirvAstVisitor.cpp b/src/Nazara/Shader/SpirvAstVisitor.cpp index 2cb244496..871f41b41 100644 --- a/src/Nazara/Shader/SpirvAstVisitor.cpp +++ b/src/Nazara/Shader/SpirvAstVisitor.cpp @@ -346,6 +346,11 @@ namespace Nz } } + void SpirvAstVisitor::Visit(ShaderNodes::Discard& /*node*/) + { + m_writer.GetInstructions().Append(SpirvOp::OpKill); + } + void SpirvAstVisitor::Visit(ShaderNodes::ExpressionStatement& node) { Visit(node.expression); diff --git a/src/ShaderNode/DataModels/Discard.cpp b/src/ShaderNode/DataModels/Discard.cpp new file mode 100644 index 000000000..968e8d53c --- /dev/null +++ b/src/ShaderNode/DataModels/Discard.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Discard::Discard(ShaderGraph& graph) : +ShaderNode(graph) +{ + DisablePreview(); + DisableCustomVariableName(); +} + +Nz::ShaderNodes::NodePtr Discard::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const +{ + using namespace Nz::ShaderBuilder; + + assert(count == 1); + assert(outputIndex == 0); + + return Branch(Equal(expressions[0], Constant(true)), Nz::ShaderBuilder::Discard(), nullptr); +} + +int Discard::GetOutputOrder() const +{ + return std::numeric_limits::lowest(); +} + +QtNodes::NodeDataType Discard::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const +{ + assert(portType == QtNodes::PortType::In); + assert(portIndex == 0); + + return BoolData::Type(); +} + +unsigned int Discard::nPorts(QtNodes::PortType portType) const +{ + switch (portType) + { + case QtNodes::PortType::In: return 1; + case QtNodes::PortType::Out: return 0; + } + + return 0; +} + +std::shared_ptr Discard::outData(QtNodes::PortIndex port) +{ + return {}; +} diff --git a/src/ShaderNode/DataModels/Discard.hpp b/src/ShaderNode/DataModels/Discard.hpp new file mode 100644 index 000000000..55f6be153 --- /dev/null +++ b/src/ShaderNode/DataModels/Discard.hpp @@ -0,0 +1,32 @@ +#pragma once + +#ifndef NAZARA_SHADERNODES_DISCARD_HPP +#define NAZARA_SHADERNODES_DISCARD_HPP + +#include +#include +#include + +class QFormLayout; + +class Discard : public ShaderNode +{ + public: + Discard(ShaderGraph& graph); + + Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override; + int GetOutputOrder() const; + + QString caption() const override { return "Discard"; } + QString name() const override { return "Discard"; } + + QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override; + + unsigned int nPorts(QtNodes::PortType portType) const override; + + std::shared_ptr outData(QtNodes::PortIndex port) override; +}; + +#include + +#endif diff --git a/src/ShaderNode/DataModels/Discard.inl b/src/ShaderNode/DataModels/Discard.inl new file mode 100644 index 000000000..61b5ba0de --- /dev/null +++ b/src/ShaderNode/DataModels/Discard.inl @@ -0,0 +1 @@ +#include diff --git a/src/ShaderNode/ShaderGraph.cpp b/src/ShaderNode/ShaderGraph.cpp index 9a93dcf8f..c0c575493 100644 --- a/src/ShaderNode/ShaderGraph.cpp +++ b/src/ShaderNode/ShaderGraph.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -742,6 +743,7 @@ std::shared_ptr ShaderGraph::BuildRegistry() RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Shader"); + RegisterShaderNode(*this, registry, "Outputs"); RegisterShaderNode(*this, registry, "Constants"); RegisterShaderNode(*this, registry, "Inputs"); RegisterShaderNode(*this, registry, "Outputs");