First rendering using Spir-V generated shaders \o/

This commit is contained in:
Jérôme Leclercq
2020-08-09 00:24:07 +02:00
parent 3829f0a002
commit 0da2ee6c99
25 changed files with 1117 additions and 373 deletions

View File

@@ -188,30 +188,18 @@ namespace Nz
{
switch (type)
{
case ShaderNodes::BasicType::Boolean:
Append("bool");
break;
case ShaderNodes::BasicType::Float1:
Append("float");
break;
case ShaderNodes::BasicType::Float2:
Append("vec2");
break;
case ShaderNodes::BasicType::Float3:
Append("vec3");
break;
case ShaderNodes::BasicType::Float4:
Append("vec4");
break;
case ShaderNodes::BasicType::Mat4x4:
Append("mat4");
break;
case ShaderNodes::BasicType::Sampler2D:
Append("sampler2D");
break;
case ShaderNodes::BasicType::Void:
Append("void");
break;
case ShaderNodes::BasicType::Boolean: return Append("bool");
case ShaderNodes::BasicType::Float1: return Append("float");
case ShaderNodes::BasicType::Float2: return Append("vec2");
case ShaderNodes::BasicType::Float3: return Append("vec3");
case ShaderNodes::BasicType::Float4: return Append("vec4");
case ShaderNodes::BasicType::Int1: return Append("int");
case ShaderNodes::BasicType::Int2: return Append("ivec2");
case ShaderNodes::BasicType::Int3: return Append("ivec3");
case ShaderNodes::BasicType::Int4: return Append("ivec4");
case ShaderNodes::BasicType::Mat4x4: return Append("mat4");
case ShaderNodes::BasicType::Sampler2D: return Append("sampler2D");
case ShaderNodes::BasicType::Void: return Append("void");
}
}
@@ -298,7 +286,7 @@ namespace Nz
AppendLine("}");
}
void GlslWriter::Visit(const ShaderNodes::ExpressionPtr& expr, bool encloseIfRequired)
void GlslWriter::Visit(ShaderNodes::ExpressionPtr& expr, bool encloseIfRequired)
{
bool enclose = encloseIfRequired && (expr->GetExpressionCategory() != ShaderNodes::ExpressionCategory::LValue);
@@ -311,7 +299,7 @@ namespace Nz
Append(")");
}
void GlslWriter::Visit(const ShaderNodes::AccessMember& node)
void GlslWriter::Visit(ShaderNodes::AccessMember& node)
{
Visit(node.structExpr, true);
@@ -332,7 +320,7 @@ namespace Nz
Append(member.name);
}
void GlslWriter::Visit(const ShaderNodes::AssignOp& node)
void GlslWriter::Visit(ShaderNodes::AssignOp& node)
{
Visit(node.left);
@@ -346,7 +334,7 @@ namespace Nz
Visit(node.right);
}
void GlslWriter::Visit(const ShaderNodes::Branch& node)
void GlslWriter::Visit(ShaderNodes::Branch& node)
{
bool first = true;
for (const auto& statement : node.condStatements)
@@ -375,7 +363,7 @@ namespace Nz
}
}
void GlslWriter::Visit(const ShaderNodes::BinaryOp& node)
void GlslWriter::Visit(ShaderNodes::BinaryOp& node)
{
Visit(node.left, true);
@@ -401,12 +389,12 @@ namespace Nz
Visit(node.right, true);
}
void GlslWriter::Visit(const ShaderNodes::BuiltinVariable& var)
void GlslWriter::Visit(ShaderNodes::BuiltinVariable& var)
{
Append(var.entry);
}
void GlslWriter::Visit(const ShaderNodes::Cast& node)
void GlslWriter::Visit(ShaderNodes::Cast& node)
{
Append(node.exprType);
Append("(");
@@ -425,28 +413,31 @@ namespace Nz
Append(")");
}
void GlslWriter::Visit(const ShaderNodes::Constant& node)
void GlslWriter::Visit(ShaderNodes::Constant& node)
{
std::visit([&](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, Vector2i32> || std::is_same_v<T, Vector3i32> || std::is_same_v<T, Vector4i32>)
Append("i"); //< for ivec
if constexpr (std::is_same_v<T, bool>)
Append((arg) ? "true" : "false");
else if constexpr (std::is_same_v<T, float>)
else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, Int32>)
Append(std::to_string(arg));
else if constexpr (std::is_same_v<T, Vector2f>)
else if constexpr (std::is_same_v<T, Vector2f> || std::is_same_v<T, Vector2i32>)
Append("vec2(" + std::to_string(arg.x) + ", " + std::to_string(arg.y) + ")");
else if constexpr (std::is_same_v<T, Vector3f>)
else if constexpr (std::is_same_v<T, Vector3f> || std::is_same_v<T, Vector3i32>)
Append("vec3(" + std::to_string(arg.x) + ", " + std::to_string(arg.y) + ", " + std::to_string(arg.z) + ")");
else if constexpr (std::is_same_v<T, Vector4f>)
else if constexpr (std::is_same_v<T, Vector4f> || std::is_same_v<T, Vector4i32>)
Append("vec4(" + std::to_string(arg.x) + ", " + std::to_string(arg.y) + ", " + std::to_string(arg.z) + ", " + std::to_string(arg.w) + ")");
else
static_assert(AlwaysFalse<T>::value, "non-exhaustive visitor");
}, node.value);
}
void GlslWriter::Visit(const ShaderNodes::DeclareVariable& node)
void GlslWriter::Visit(ShaderNodes::DeclareVariable& node)
{
assert(node.variable->GetType() == ShaderNodes::VariableType::LocalVariable);
@@ -464,23 +455,23 @@ namespace Nz
AppendLine(";");
}
void GlslWriter::Visit(const ShaderNodes::ExpressionStatement& node)
void GlslWriter::Visit(ShaderNodes::ExpressionStatement& node)
{
Visit(node.expression);
Append(";");
}
void GlslWriter::Visit(const ShaderNodes::Identifier& node)
void GlslWriter::Visit(ShaderNodes::Identifier& node)
{
Visit(node.var);
}
void GlslWriter::Visit(const ShaderNodes::InputVariable& var)
void GlslWriter::Visit(ShaderNodes::InputVariable& var)
{
Append(var.name);
}
void GlslWriter::Visit(const ShaderNodes::IntrinsicCall& node)
void GlslWriter::Visit(ShaderNodes::IntrinsicCall& node)
{
switch (node.intrinsic)
{
@@ -504,22 +495,22 @@ namespace Nz
Append(")");
}
void GlslWriter::Visit(const ShaderNodes::LocalVariable& var)
void GlslWriter::Visit(ShaderNodes::LocalVariable& var)
{
Append(var.name);
}
void GlslWriter::Visit(const ShaderNodes::ParameterVariable& var)
void GlslWriter::Visit(ShaderNodes::ParameterVariable& var)
{
Append(var.name);
}
void GlslWriter::Visit(const ShaderNodes::OutputVariable& var)
void GlslWriter::Visit(ShaderNodes::OutputVariable& var)
{
Append(var.name);
}
void GlslWriter::Visit(const ShaderNodes::Sample2D& node)
void GlslWriter::Visit(ShaderNodes::Sample2D& node)
{
Append("texture(");
Visit(node.sampler);
@@ -528,7 +519,7 @@ namespace Nz
Append(")");
}
void GlslWriter::Visit(const ShaderNodes::StatementBlock& node)
void GlslWriter::Visit(ShaderNodes::StatementBlock& node)
{
bool first = true;
for (const ShaderNodes::StatementPtr& statement : node.statements)
@@ -542,7 +533,7 @@ namespace Nz
}
}
void GlslWriter::Visit(const ShaderNodes::SwizzleOp& node)
void GlslWriter::Visit(ShaderNodes::SwizzleOp& node)
{
Visit(node.expression);
Append(".");
@@ -570,7 +561,7 @@ namespace Nz
}
}
void GlslWriter::Visit(const ShaderNodes::UniformVariable& var)
void GlslWriter::Visit(ShaderNodes::UniformVariable& var)
{
Append(var.name);
}

View File

@@ -69,7 +69,7 @@ namespace Nz
};
RegisterImpl("NazaraOpenGLRenderer" NazaraRendererDebugSuffix, [] { return 50; });
//RegisterImpl("NazaraVulkanRenderer" NazaraRendererDebugSuffix, [] { return 100; });
RegisterImpl("NazaraVulkanRenderer" NazaraRendererDebugSuffix, [] { return 100; });
std::sort(implementations.begin(), implementations.end(), [](const auto& lhs, const auto& rhs) { return lhs.score > rhs.score; });

View File

@@ -45,22 +45,22 @@ namespace Nz
return PopVariable();
}
void ShaderAstCloner::Visit(const ShaderNodes::AccessMember& node)
void ShaderAstCloner::Visit(ShaderNodes::AccessMember& node)
{
PushExpression(ShaderNodes::AccessMember::Build(CloneExpression(node.structExpr), node.memberIndex, node.exprType));
}
void ShaderAstCloner::Visit(const ShaderNodes::AssignOp& node)
void ShaderAstCloner::Visit(ShaderNodes::AssignOp& node)
{
PushExpression(ShaderNodes::AssignOp::Build(node.op, CloneExpression(node.left), CloneExpression(node.right)));
}
void ShaderAstCloner::Visit(const ShaderNodes::BinaryOp& node)
void ShaderAstCloner::Visit(ShaderNodes::BinaryOp& node)
{
PushExpression(ShaderNodes::BinaryOp::Build(node.op, CloneExpression(node.left), CloneExpression(node.right)));
}
void ShaderAstCloner::Visit(const ShaderNodes::Branch& node)
void ShaderAstCloner::Visit(ShaderNodes::Branch& node)
{
std::vector<ShaderNodes::Branch::ConditionalStatement> condStatements;
condStatements.reserve(node.condStatements.size());
@@ -75,7 +75,7 @@ namespace Nz
PushStatement(ShaderNodes::Branch::Build(std::move(condStatements), CloneStatement(node.elseStatement)));
}
void ShaderAstCloner::Visit(const ShaderNodes::Cast& node)
void ShaderAstCloner::Visit(ShaderNodes::Cast& node)
{
std::size_t expressionCount = 0;
std::array<ShaderNodes::ExpressionPtr, 4> expressions;
@@ -91,27 +91,27 @@ namespace Nz
PushExpression(ShaderNodes::Cast::Build(node.exprType, expressions.data(), expressionCount));
}
void ShaderAstCloner::Visit(const ShaderNodes::Constant& node)
void ShaderAstCloner::Visit(ShaderNodes::Constant& node)
{
PushExpression(ShaderNodes::Constant::Build(node.value));
}
void ShaderAstCloner::Visit(const ShaderNodes::DeclareVariable& node)
void ShaderAstCloner::Visit(ShaderNodes::DeclareVariable& node)
{
PushStatement(ShaderNodes::DeclareVariable::Build(CloneVariable(node.variable), CloneExpression(node.expression)));
}
void ShaderAstCloner::Visit(const ShaderNodes::ExpressionStatement& node)
void ShaderAstCloner::Visit(ShaderNodes::ExpressionStatement& node)
{
PushStatement(ShaderNodes::ExpressionStatement::Build(CloneExpression(node.expression)));
}
void ShaderAstCloner::Visit(const ShaderNodes::Identifier& node)
void ShaderAstCloner::Visit(ShaderNodes::Identifier& node)
{
PushExpression(ShaderNodes::Identifier::Build(CloneVariable(node.var)));
}
void ShaderAstCloner::Visit(const ShaderNodes::IntrinsicCall& node)
void ShaderAstCloner::Visit(ShaderNodes::IntrinsicCall& node)
{
std::vector<ShaderNodes::ExpressionPtr> parameters;
parameters.reserve(node.parameters.size());
@@ -122,12 +122,12 @@ namespace Nz
PushExpression(ShaderNodes::IntrinsicCall::Build(node.intrinsic, std::move(parameters)));
}
void ShaderAstCloner::Visit(const ShaderNodes::Sample2D& node)
void ShaderAstCloner::Visit(ShaderNodes::Sample2D& node)
{
PushExpression(ShaderNodes::Sample2D::Build(CloneExpression(node.sampler), CloneExpression(node.coordinates)));
}
void ShaderAstCloner::Visit(const ShaderNodes::StatementBlock& node)
void ShaderAstCloner::Visit(ShaderNodes::StatementBlock& node)
{
std::vector<ShaderNodes::StatementPtr> statements;
statements.reserve(node.statements.size());
@@ -138,37 +138,37 @@ namespace Nz
PushStatement(ShaderNodes::StatementBlock::Build(std::move(statements)));
}
void ShaderAstCloner::Visit(const ShaderNodes::SwizzleOp& node)
void ShaderAstCloner::Visit(ShaderNodes::SwizzleOp& node)
{
PushExpression(ShaderNodes::SwizzleOp::Build(PopExpression(), node.components.data(), node.componentCount));
}
void ShaderAstCloner::Visit(const ShaderNodes::BuiltinVariable& var)
void ShaderAstCloner::Visit(ShaderNodes::BuiltinVariable& var)
{
PushVariable(ShaderNodes::BuiltinVariable::Build(var.entry, var.type));
}
void ShaderAstCloner::Visit(const ShaderNodes::InputVariable& var)
void ShaderAstCloner::Visit(ShaderNodes::InputVariable& var)
{
PushVariable(ShaderNodes::InputVariable::Build(var.name, var.type));
}
void ShaderAstCloner::Visit(const ShaderNodes::LocalVariable& var)
void ShaderAstCloner::Visit(ShaderNodes::LocalVariable& var)
{
PushVariable(ShaderNodes::LocalVariable::Build(var.name, var.type));
}
void ShaderAstCloner::Visit(const ShaderNodes::OutputVariable& var)
void ShaderAstCloner::Visit(ShaderNodes::OutputVariable& var)
{
PushVariable(ShaderNodes::OutputVariable::Build(var.name, var.type));
}
void ShaderAstCloner::Visit(const ShaderNodes::ParameterVariable& var)
void ShaderAstCloner::Visit(ShaderNodes::ParameterVariable& var)
{
PushVariable(ShaderNodes::ParameterVariable::Build(var.name, var.type));
}
void ShaderAstCloner::Visit(const ShaderNodes::UniformVariable& var)
void ShaderAstCloner::Visit(ShaderNodes::UniformVariable& var)
{
PushVariable(ShaderNodes::UniformVariable::Build(var.name, var.type));
}

View File

@@ -7,24 +7,24 @@
namespace Nz
{
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::AccessMember& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::AccessMember& node)
{
Visit(node.structExpr);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::AssignOp& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::AssignOp& node)
{
Visit(node.left);
Visit(node.right);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::BinaryOp& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::BinaryOp& node)
{
Visit(node.left);
Visit(node.right);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::Branch& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Branch& node)
{
for (auto& cond : node.condStatements)
{
@@ -36,7 +36,7 @@ namespace Nz
Visit(node.elseStatement);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::Cast& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Cast& node)
{
for (auto& expr : node.expressions)
{
@@ -47,46 +47,46 @@ namespace Nz
}
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::Constant& /*node*/)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Constant& /*node*/)
{
/* Nothing to do */
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::DeclareVariable& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::DeclareVariable& node)
{
if (node.expression)
Visit(node.expression);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::ExpressionStatement& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::ExpressionStatement& node)
{
Visit(node.expression);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::Identifier& /*node*/)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Identifier& /*node*/)
{
/* Nothing to do */
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::IntrinsicCall& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::IntrinsicCall& node)
{
for (auto& param : node.parameters)
Visit(param);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::Sample2D& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Sample2D& node)
{
Visit(node.sampler);
Visit(node.coordinates);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::StatementBlock& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::StatementBlock& node)
{
for (auto& statement : node.statements)
Visit(statement);
}
void ShaderAstRecursiveVisitor::Visit(const ShaderNodes::SwizzleOp& node)
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::SwizzleOp& node)
{
Visit(node.expression);
}

View File

@@ -22,98 +22,98 @@ namespace Nz
{
}
void Visit(const ShaderNodes::AccessMember& node) override
void Visit(ShaderNodes::AccessMember& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::AssignOp& node) override
void Visit(ShaderNodes::AssignOp& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::BinaryOp& node) override
void Visit(ShaderNodes::BinaryOp& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::Branch& node) override
void Visit(ShaderNodes::Branch& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::Cast& node) override
void Visit(ShaderNodes::Cast& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::Constant& node) override
void Visit(ShaderNodes::Constant& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::DeclareVariable& node) override
void Visit(ShaderNodes::DeclareVariable& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::ExpressionStatement& node) override
void Visit(ShaderNodes::ExpressionStatement& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::Identifier& node) override
void Visit(ShaderNodes::Identifier& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::IntrinsicCall& node) override
void Visit(ShaderNodes::IntrinsicCall& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::Sample2D& node) override
void Visit(ShaderNodes::Sample2D& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::StatementBlock& node) override
void Visit(ShaderNodes::StatementBlock& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::SwizzleOp& node) override
void Visit(ShaderNodes::SwizzleOp& node) override
{
Serialize(node);
}
void Visit(const ShaderNodes::BuiltinVariable& var) override
void Visit(ShaderNodes::BuiltinVariable& var) override
{
Serialize(var);
}
void Visit(const ShaderNodes::InputVariable& var) override
void Visit(ShaderNodes::InputVariable& var) override
{
Serialize(var);
}
void Visit(const ShaderNodes::LocalVariable& var) override
void Visit(ShaderNodes::LocalVariable& var) override
{
Serialize(var);
}
void Visit(const ShaderNodes::OutputVariable& var) override
void Visit(ShaderNodes::OutputVariable& var) override
{
Serialize(var);
}
void Visit(const ShaderNodes::ParameterVariable& var) override
void Visit(ShaderNodes::ParameterVariable& var) override
{
Serialize(var);
}
void Visit(const ShaderNodes::UniformVariable& var) override
void Visit(ShaderNodes::UniformVariable& var) override
{
Serialize(var);
}
@@ -193,14 +193,18 @@ namespace Nz
Value(value);
};
static_assert(std::variant_size_v<decltype(node.value)> == 5);
static_assert(std::variant_size_v<decltype(node.value)> == 9);
switch (typeIndex)
{
case 0: SerializeValue(bool()); break;
case 1: SerializeValue(float()); break;
case 2: SerializeValue(Vector2f()); break;
case 3: SerializeValue(Vector3f()); break;
case 4: SerializeValue(Vector4f()); break;
case 2: SerializeValue(Int32()); break;
case 3: SerializeValue(Vector2f()); break;
case 4: SerializeValue(Vector3f()); break;
case 5: SerializeValue(Vector4f()); break;
case 6: SerializeValue(Vector2i32()); break;
case 7: SerializeValue(Vector3i32()); break;
case 8: SerializeValue(Vector4i32()); break;
default: throw std::runtime_error("unexpected data type");
}
}
@@ -403,6 +407,11 @@ namespace Nz
m_stream << val;
}
void ShaderAstSerializer::Value(Int32& val)
{
m_stream << val;
}
void ShaderAstSerializer::Value(Vector2f& val)
{
m_stream << val;
@@ -418,6 +427,21 @@ namespace Nz
m_stream << val;
}
void ShaderAstSerializer::Value(Vector2i32& val)
{
m_stream << val;
}
void ShaderAstSerializer::Value(Vector3i32& val)
{
m_stream << val;
}
void ShaderAstSerializer::Value(Vector4i32& val)
{
m_stream << val;
}
void ShaderAstSerializer::Value(UInt8& val)
{
m_stream << val;
@@ -644,6 +668,11 @@ namespace Nz
m_stream >> val;
}
void ShaderAstUnserializer::Value(Int32& val)
{
m_stream >> val;
}
void ShaderAstUnserializer::Value(Vector2f& val)
{
m_stream >> val;
@@ -659,6 +688,21 @@ namespace Nz
m_stream >> val;
}
void ShaderAstUnserializer::Value(Vector2i32& val)
{
m_stream >> val;
}
void ShaderAstUnserializer::Value(Vector3i32& val)
{
m_stream >> val;
}
void ShaderAstUnserializer::Value(Vector4i32& val)
{
m_stream >> val;
}
void ShaderAstUnserializer::Value(UInt8& val)
{
m_stream >> val;
@@ -689,6 +733,7 @@ namespace Nz
HandleType(BuiltinVariable);
HandleType(InputVariable);
HandleType(LocalVariable);
HandleType(ParameterVariable);
HandleType(OutputVariable);
HandleType(UniformVariable);
}

View File

@@ -83,7 +83,7 @@ namespace Nz
throw AstError{ "Left expression type must match right expression type" };
}
void ShaderAstValidator::Visit(const ShaderNodes::AccessMember& node)
void ShaderAstValidator::Visit(ShaderNodes::AccessMember& node)
{
const ShaderExpressionType& exprType = MandatoryExpr(node.structExpr)->GetExpressionType();
if (!std::holds_alternative<std::string>(exprType))
@@ -105,7 +105,7 @@ namespace Nz
throw AstError{ "member type does not match node type" };
}
void ShaderAstValidator::Visit(const ShaderNodes::AssignOp& node)
void ShaderAstValidator::Visit(ShaderNodes::AssignOp& node)
{
MandatoryNode(node.left);
MandatoryNode(node.right);
@@ -117,7 +117,7 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::BinaryOp& node)
void ShaderAstValidator::Visit(ShaderNodes::BinaryOp& node)
{
MandatoryNode(node.left);
MandatoryNode(node.right);
@@ -147,8 +147,9 @@ namespace Nz
switch (leftType)
{
case ShaderNodes::BasicType::Float1:
case ShaderNodes::BasicType::Int1:
{
if (ShaderNodes::Node::GetComponentType(rightType) != ShaderNodes::BasicType::Float1)
if (ShaderNodes::Node::GetComponentType(rightType) != leftType)
throw AstError{ "Left expression type is not compatible with right expression type" };
break;
@@ -157,8 +158,11 @@ namespace Nz
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
{
if (leftType != rightType && rightType != ShaderNodes::BasicType::Float1)
if (leftType != rightType && rightType != ShaderNodes::Node::GetComponentType(leftType))
throw AstError{ "Left expression type is not compatible with right expression type" };
break;
@@ -189,7 +193,7 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::Branch& node)
void ShaderAstValidator::Visit(ShaderNodes::Branch& node)
{
for (const auto& condStatement : node.condStatements)
{
@@ -200,7 +204,7 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::Cast& node)
void ShaderAstValidator::Visit(ShaderNodes::Cast& node)
{
unsigned int componentCount = 0;
unsigned int requiredComponents = node.GetComponentCount(node.exprType);
@@ -222,11 +226,11 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::Constant& /*node*/)
void ShaderAstValidator::Visit(ShaderNodes::Constant& /*node*/)
{
}
void ShaderAstValidator::Visit(const ShaderNodes::DeclareVariable& node)
void ShaderAstValidator::Visit(ShaderNodes::DeclareVariable& node)
{
assert(m_context);
@@ -242,14 +246,14 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::ExpressionStatement& node)
void ShaderAstValidator::Visit(ShaderNodes::ExpressionStatement& node)
{
MandatoryNode(node.expression);
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::Identifier& node)
void ShaderAstValidator::Visit(ShaderNodes::Identifier& node)
{
assert(m_context);
@@ -259,7 +263,7 @@ namespace Nz
Visit(node.var);
}
void ShaderAstValidator::Visit(const ShaderNodes::IntrinsicCall& node)
void ShaderAstValidator::Visit(ShaderNodes::IntrinsicCall& node)
{
switch (node.intrinsic)
{
@@ -300,7 +304,7 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::Sample2D& node)
void ShaderAstValidator::Visit(ShaderNodes::Sample2D& node)
{
if (MandatoryExpr(node.sampler)->GetExpressionType() != ShaderExpressionType{ ShaderNodes::BasicType::Sampler2D })
throw AstError{ "Sampler must be a Sampler2D" };
@@ -311,7 +315,7 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::StatementBlock& node)
void ShaderAstValidator::Visit(ShaderNodes::StatementBlock& node)
{
assert(m_context);
@@ -327,7 +331,7 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::SwizzleOp& node)
void ShaderAstValidator::Visit(ShaderNodes::SwizzleOp& node)
{
if (node.componentCount > 4)
throw AstError{ "Cannot swizzle more than four elements" };
@@ -342,6 +346,10 @@ namespace Nz
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Int1:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
break;
default:
@@ -351,12 +359,23 @@ namespace Nz
ShaderAstRecursiveVisitor::Visit(node);
}
void ShaderAstValidator::Visit(const ShaderNodes::BuiltinVariable& /*var*/)
void ShaderAstValidator::Visit(ShaderNodes::BuiltinVariable& var)
{
/* Nothing to do */
switch (var.entry)
{
case ShaderNodes::BuiltinEntry::VertexPosition:
if (!std::holds_alternative<ShaderNodes::BasicType>(var.type) ||
std::get<ShaderNodes::BasicType>(var.type) != ShaderNodes::BasicType::Float4)
throw AstError{ "Builtin is not of the expected type" };
break;
default:
break;
}
}
void ShaderAstValidator::Visit(const ShaderNodes::InputVariable& var)
void ShaderAstValidator::Visit(ShaderNodes::InputVariable& var)
{
for (std::size_t i = 0; i < m_shader.GetInputCount(); ++i)
{
@@ -371,7 +390,7 @@ namespace Nz
throw AstError{ "Input not found" };
}
void ShaderAstValidator::Visit(const ShaderNodes::LocalVariable& var)
void ShaderAstValidator::Visit(ShaderNodes::LocalVariable& var)
{
const auto& vars = m_context->declaredLocals;
@@ -382,7 +401,7 @@ namespace Nz
TypeMustMatch(it->type, var.type);
}
void ShaderAstValidator::Visit(const ShaderNodes::OutputVariable& var)
void ShaderAstValidator::Visit(ShaderNodes::OutputVariable& var)
{
for (std::size_t i = 0; i < m_shader.GetOutputCount(); ++i)
{
@@ -397,7 +416,7 @@ namespace Nz
throw AstError{ "Output not found" };
}
void ShaderAstValidator::Visit(const ShaderNodes::ParameterVariable& var)
void ShaderAstValidator::Visit(ShaderNodes::ParameterVariable& var)
{
assert(m_context->currentFunction);
@@ -410,7 +429,7 @@ namespace Nz
TypeMustMatch(it->type, var.type);
}
void ShaderAstValidator::Visit(const ShaderNodes::UniformVariable& var)
void ShaderAstValidator::Visit(ShaderNodes::UniformVariable& var)
{
for (std::size_t i = 0; i < m_shader.GetUniformCount(); ++i)
{

View File

@@ -59,7 +59,7 @@ namespace Nz::ShaderNodes
visitor.Visit(*this);
}
ExpressionCategory ShaderNodes::AccessMember::GetExpressionCategory() const
ExpressionCategory AccessMember::GetExpressionCategory() const
{
return ExpressionCategory::LValue;
}
@@ -111,10 +111,14 @@ namespace Nz::ShaderNodes
case BasicType::Float2:
case BasicType::Float3:
case BasicType::Float4:
case BasicType::Int2:
case BasicType::Int3:
case BasicType::Int4:
exprType = leftExprType;
break;
case BasicType::Float1:
case BasicType::Int1:
case BasicType::Mat4x4:
exprType = rightExprType;
break;
@@ -159,12 +163,20 @@ namespace Nz::ShaderNodes
return ShaderNodes::BasicType::Boolean;
else if constexpr (std::is_same_v<T, float>)
return ShaderNodes::BasicType::Float1;
else if constexpr (std::is_same_v<T, Int32>)
return ShaderNodes::BasicType::Int1;
else if constexpr (std::is_same_v<T, Vector2f>)
return ShaderNodes::BasicType::Float2;
else if constexpr (std::is_same_v<T, Vector3f>)
return ShaderNodes::BasicType::Float3;
else if constexpr (std::is_same_v<T, Vector4f>)
return ShaderNodes::BasicType::Float4;
else if constexpr (std::is_same_v<T, Vector2i32>)
return ShaderNodes::BasicType::Int2;
else if constexpr (std::is_same_v<T, Vector3i32>)
return ShaderNodes::BasicType::Int3;
else if constexpr (std::is_same_v<T, Vector4i32>)
return ShaderNodes::BasicType::Int4;
else
static_assert(AlwaysFalse<T>::value, "non-exhaustive visitor");
}, value);

File diff suppressed because it is too large Load Diff

View File

@@ -57,7 +57,7 @@ namespace Nz
String appName = "Another application made with Nazara Engine";
String engineName = "Nazara Engine - Vulkan Renderer";
constexpr UInt32 appVersion = VK_MAKE_VERSION(1, 0, 0);
UInt32 appVersion = VK_MAKE_VERSION(1, 0, 0);
UInt32 engineVersion = VK_MAKE_VERSION(1, 0, 0);
parameters.GetStringParameter("VkAppInfo_OverrideApplicationName", &appName);

View File

@@ -3,25 +3,61 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/VulkanRenderer/VulkanShaderStage.hpp>
#include <Nazara/Renderer/ShaderAst.hpp>
#include <Nazara/Renderer/ShaderAstSerializer.hpp>
#include <Nazara/Renderer/SpirvWriter.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
bool VulkanShaderStage::Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
{
if (lang != ShaderLanguage::SpirV)
{
NazaraError("Only Spir-V is supported for now");
return false;
}
if (!m_shaderModule.Create(device, reinterpret_cast<const Nz::UInt32*>(source), sourceSize))
{
NazaraError("Failed to create shader module");
return false;
}
m_stage = type;
switch (lang)
{
case ShaderLanguage::NazaraBinary:
{
ByteStream byteStream(source, sourceSize);
auto shader = Nz::UnserializeShader(byteStream);
if (shader.GetStage() != type)
throw std::runtime_error("incompatible shader stage");
SpirvWriter::Environment env;
SpirvWriter writer;
writer.SetEnv(env);
std::vector<UInt32> code = writer.Generate(shader);
if (!m_shaderModule.Create(device, code.data(), code.size() * sizeof(UInt32)))
{
NazaraError("Failed to create shader module");
return false;
}
break;
}
case ShaderLanguage::SpirV:
{
if (!m_shaderModule.Create(device, reinterpret_cast<const Nz::UInt32*>(source), sourceSize))
{
NazaraError("Failed to create shader module");
return false;
}
break;
}
default:
{
NazaraError("this language is not supported");
return false;
}
}
return true;
}
}