Shader: Add Discard node

This commit is contained in:
Jérôme Leclercq 2020-12-30 20:05:16 +01:00
parent a1c15a8c16
commit ed72d668d9
22 changed files with 162 additions and 0 deletions

View File

@ -73,6 +73,7 @@ namespace Nz
void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override; void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::InputVariable& var) override; void Visit(ShaderNodes::InputVariable& var) override;

View File

@ -42,6 +42,7 @@ namespace Nz
void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override; void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override;

View File

@ -30,6 +30,7 @@ namespace Nz
void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override; void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override;

View File

@ -35,6 +35,7 @@ namespace Nz
void Serialize(ShaderNodes::ConditionalStatement& node); void Serialize(ShaderNodes::ConditionalStatement& node);
void Serialize(ShaderNodes::Constant& node); void Serialize(ShaderNodes::Constant& node);
void Serialize(ShaderNodes::DeclareVariable& node); void Serialize(ShaderNodes::DeclareVariable& node);
void Serialize(ShaderNodes::Discard& node);
void Serialize(ShaderNodes::ExpressionStatement& node); void Serialize(ShaderNodes::ExpressionStatement& node);
void Serialize(ShaderNodes::Identifier& node); void Serialize(ShaderNodes::Identifier& node);
void Serialize(ShaderNodes::IntrinsicCall& node); void Serialize(ShaderNodes::IntrinsicCall& node);

View File

@ -31,6 +31,7 @@ namespace Nz
virtual void Visit(ShaderNodes::ConditionalStatement& node) = 0; virtual void Visit(ShaderNodes::ConditionalStatement& node) = 0;
virtual void Visit(ShaderNodes::Constant& node) = 0; virtual void Visit(ShaderNodes::Constant& node) = 0;
virtual void Visit(ShaderNodes::DeclareVariable& 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::ExpressionStatement& node) = 0;
virtual void Visit(ShaderNodes::Identifier& node) = 0; virtual void Visit(ShaderNodes::Identifier& node) = 0;
virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0; virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0;

View File

@ -26,6 +26,7 @@ namespace Nz
void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override; void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override;

View File

@ -54,6 +54,7 @@ namespace Nz::ShaderBuilder
constexpr GenBuilder<ShaderNodes::ConditionalStatement> ConditionalStatement; constexpr GenBuilder<ShaderNodes::ConditionalStatement> ConditionalStatement;
constexpr GenBuilder<ShaderNodes::Constant> Constant; constexpr GenBuilder<ShaderNodes::Constant> Constant;
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable; constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
constexpr GenBuilder<ShaderNodes::Discard> Discard;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide; constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal; constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement; constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;

View File

@ -81,6 +81,7 @@ namespace Nz::ShaderNodes
ConditionalExpression, ConditionalExpression,
ConditionalStatement, ConditionalStatement,
DeclareVariable, DeclareVariable,
Discard,
ExpressionStatement, ExpressionStatement,
Identifier, Identifier,
IntrinsicCall, IntrinsicCall,

View File

@ -123,6 +123,15 @@ namespace Nz
static inline std::shared_ptr<DeclareVariable> Build(VariablePtr variable, ExpressionPtr expression = nullptr); static inline std::shared_ptr<DeclareVariable> Build(VariablePtr variable, ExpressionPtr expression = nullptr);
}; };
struct NAZARA_SHADER_API Discard : public Statement
{
inline Discard();
void Visit(ShaderAstVisitor& visitor) override;
static inline std::shared_ptr<Discard> Build();
};
struct NAZARA_SHADER_API Identifier : public Expression struct NAZARA_SHADER_API Identifier : public Expression
{ {
inline Identifier(); inline Identifier();

View File

@ -148,6 +148,17 @@ namespace Nz::ShaderNodes
} }
inline Discard::Discard() :
Statement(NodeType::DeclareVariable)
{
}
inline std::shared_ptr<Discard> Discard::Build()
{
return std::make_shared<Discard>();
}
inline Identifier::Identifier() : inline Identifier::Identifier() :
Expression(NodeType::Identifier) Expression(NodeType::Identifier)
{ {

View File

@ -36,6 +36,7 @@ namespace Nz
void Visit(ShaderNodes::ConditionalStatement& node) override; void Visit(ShaderNodes::ConditionalStatement& node) override;
void Visit(ShaderNodes::Constant& node) override; void Visit(ShaderNodes::Constant& node) override;
void Visit(ShaderNodes::DeclareVariable& node) override; void Visit(ShaderNodes::DeclareVariable& node) override;
void Visit(ShaderNodes::Discard& node) override;
void Visit(ShaderNodes::ExpressionStatement& node) override; void Visit(ShaderNodes::ExpressionStatement& node) override;
void Visit(ShaderNodes::Identifier& node) override; void Visit(ShaderNodes::Identifier& node) override;
void Visit(ShaderNodes::IntrinsicCall& node) override; void Visit(ShaderNodes::IntrinsicCall& node) override;

View File

@ -519,6 +519,11 @@ namespace Nz
AppendLine(";"); AppendLine(";");
} }
void GlslWriter::Visit(ShaderNodes::Discard& /*node*/)
{
Append("discard;");
}
void GlslWriter::Visit(ShaderNodes::ExpressionStatement& node) void GlslWriter::Visit(ShaderNodes::ExpressionStatement& node)
{ {
Visit(node.expression); Visit(node.expression);

View File

@ -111,6 +111,11 @@ namespace Nz
PushStatement(ShaderNodes::DeclareVariable::Build(CloneVariable(node.variable), CloneExpression(node.expression))); 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) void ShaderAstCloner::Visit(ShaderNodes::ExpressionStatement& node)
{ {
PushStatement(ShaderNodes::ExpressionStatement::Build(CloneExpression(node.expression))); PushStatement(ShaderNodes::ExpressionStatement::Build(CloneExpression(node.expression)));

View File

@ -69,6 +69,11 @@ namespace Nz
Visit(node.expression); Visit(node.expression);
} }
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Discard& /*node*/)
{
/* Nothing to do */
}
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::ExpressionStatement& node) void ShaderAstRecursiveVisitor::Visit(ShaderNodes::ExpressionStatement& node)
{ {
Visit(node.expression); Visit(node.expression);

View File

@ -67,6 +67,11 @@ namespace Nz
Serialize(node); Serialize(node);
} }
void Visit(ShaderNodes::Discard& node) override
{
Serialize(node);
}
void Visit(ShaderNodes::ExpressionStatement& node) override void Visit(ShaderNodes::ExpressionStatement& node) override
{ {
Serialize(node); Serialize(node);
@ -242,6 +247,11 @@ namespace Nz
Node(node.expression); Node(node.expression);
} }
void ShaderAstSerializerBase::Serialize(ShaderNodes::Discard& /*node*/)
{
/* Nothing to do */
}
void ShaderAstSerializerBase::Serialize(ShaderNodes::ExpressionStatement& node) void ShaderAstSerializerBase::Serialize(ShaderNodes::ExpressionStatement& node)
{ {
Node(node.expression); Node(node.expression);
@ -665,6 +675,7 @@ namespace Nz
HandleType(ConditionalExpression); HandleType(ConditionalExpression);
HandleType(ConditionalStatement); HandleType(ConditionalStatement);
HandleType(DeclareVariable); HandleType(DeclareVariable);
HandleType(Discard);
HandleType(ExpressionStatement); HandleType(ExpressionStatement);
HandleType(Identifier); HandleType(Identifier);
HandleType(IntrinsicCall); HandleType(IntrinsicCall);

View File

@ -53,6 +53,11 @@ namespace Nz
throw std::runtime_error("unhandled DeclareVariable node"); 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*/) void ShaderAstVisitorExcept::Visit(ShaderNodes::ExpressionStatement& /*node*/)
{ {
throw std::runtime_error("unhandled ExpressionStatement node"); throw std::runtime_error("unhandled ExpressionStatement node");

View File

@ -42,6 +42,12 @@ namespace Nz::ShaderNodes
} }
void Discard::Visit(ShaderAstVisitor& visitor)
{
visitor.Visit(*this);
}
ExpressionCategory Identifier::GetExpressionCategory() const ExpressionCategory Identifier::GetExpressionCategory() const
{ {
return ExpressionCategory::LValue; return ExpressionCategory::LValue;

View File

@ -346,6 +346,11 @@ namespace Nz
} }
} }
void SpirvAstVisitor::Visit(ShaderNodes::Discard& /*node*/)
{
m_writer.GetInstructions().Append(SpirvOp::OpKill);
}
void SpirvAstVisitor::Visit(ShaderNodes::ExpressionStatement& node) void SpirvAstVisitor::Visit(ShaderNodes::ExpressionStatement& node)
{ {
Visit(node.expression); Visit(node.expression);

View File

@ -0,0 +1,56 @@
#include <ShaderNode/DataModels/Discard.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <ShaderNode/ShaderGraph.hpp>
#include <ShaderNode/DataTypes/BoolData.hpp>
#include <ShaderNode/DataTypes/FloatData.hpp>
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
#include <ShaderNode/DataTypes/VecData.hpp>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QFormLayout>
#include <limits>
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<int>::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<QtNodes::NodeData> Discard::outData(QtNodes::PortIndex port)
{
return {};
}

View File

@ -0,0 +1,32 @@
#pragma once
#ifndef NAZARA_SHADERNODES_DISCARD_HPP
#define NAZARA_SHADERNODES_DISCARD_HPP
#include <ShaderNode/ShaderGraph.hpp>
#include <ShaderNode/DataModels/ShaderNode.hpp>
#include <ShaderNode/DataTypes/VecData.hpp>
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<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
};
#include <ShaderNode/DataModels/Discard.inl>
#endif

View File

@ -0,0 +1 @@
#include <ShaderNode/DataModels/Discard.hpp>

View File

@ -3,6 +3,7 @@
#include <ShaderNode/DataModels/BufferField.hpp> #include <ShaderNode/DataModels/BufferField.hpp>
#include <ShaderNode/DataModels/Cast.hpp> #include <ShaderNode/DataModels/Cast.hpp>
#include <ShaderNode/DataModels/ConditionalExpression.hpp> #include <ShaderNode/DataModels/ConditionalExpression.hpp>
#include <ShaderNode/DataModels/Discard.hpp>
#include <ShaderNode/DataModels/FloatValue.hpp> #include <ShaderNode/DataModels/FloatValue.hpp>
#include <ShaderNode/DataModels/InputValue.hpp> #include <ShaderNode/DataModels/InputValue.hpp>
#include <ShaderNode/DataModels/OutputValue.hpp> #include <ShaderNode/DataModels/OutputValue.hpp>
@ -742,6 +743,7 @@ std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
RegisterShaderNode<CastToVec3>(*this, registry, "Casts"); RegisterShaderNode<CastToVec3>(*this, registry, "Casts");
RegisterShaderNode<CastToVec4>(*this, registry, "Casts"); RegisterShaderNode<CastToVec4>(*this, registry, "Casts");
RegisterShaderNode<ConditionalExpression>(*this, registry, "Shader"); RegisterShaderNode<ConditionalExpression>(*this, registry, "Shader");
RegisterShaderNode<Discard>(*this, registry, "Outputs");
RegisterShaderNode<FloatValue>(*this, registry, "Constants"); RegisterShaderNode<FloatValue>(*this, registry, "Constants");
RegisterShaderNode<InputValue>(*this, registry, "Inputs"); RegisterShaderNode<InputValue>(*this, registry, "Inputs");
RegisterShaderNode<PositionOutputValue>(*this, registry, "Outputs"); RegisterShaderNode<PositionOutputValue>(*this, registry, "Outputs");