Commit current work

Reworked conditions, added uber-shaders, comparison nodes, fixed Discard
This commit is contained in:
Jérôme Leclercq
2021-01-02 21:15:59 +01:00
parent ed72d668d9
commit f327932738
103 changed files with 3248 additions and 790 deletions

View File

@@ -5,6 +5,7 @@
#include <Nazara/Shader/GlslWriter.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderAstCloner.hpp>
#include <Nazara/Shader/ShaderAstValidator.hpp>
@@ -418,21 +419,17 @@ namespace Nz
switch (node.op)
{
case ShaderNodes::BinaryType::Add:
Append(" + ");
break;
case ShaderNodes::BinaryType::Substract:
Append(" - ");
break;
case ShaderNodes::BinaryType::Multiply:
Append(" * ");
break;
case ShaderNodes::BinaryType::Divide:
Append(" / ");
break;
case ShaderNodes::BinaryType::Equality:
Append(" == ");
break;
case ShaderNodes::BinaryType::Add: Append(" + "); break;
case ShaderNodes::BinaryType::Substract: Append(" - "); break;
case ShaderNodes::BinaryType::Multiply: Append(" * "); break;
case ShaderNodes::BinaryType::Divide: Append(" / "); break;
case ShaderNodes::BinaryType::CompEq: Append(" == "); break;
case ShaderNodes::BinaryType::CompGe: Append(" >= "); break;
case ShaderNodes::BinaryType::CompGt: Append(" > "); break;
case ShaderNodes::BinaryType::CompLe: Append(" <= "); break;
case ShaderNodes::BinaryType::CompLt: Append(" < "); break;
case ShaderNodes::BinaryType::CompNe: Append(" != "); break;
}
Visit(node.right, true);
@@ -448,15 +445,17 @@ namespace Nz
Append(node.exprType);
Append("(");
for (std::size_t i = 0; node.expressions[i]; ++i)
bool first = true;
for (const auto& exprPtr : node.expressions)
{
if (i != 0)
if (!exprPtr)
break;
if (!first)
m_currentState->stream << ", ";
const auto& exprPtr = node.expressions[i];
NazaraAssert(exprPtr, "Invalid expression");
Visit(exprPtr);
first = false;
}
Append(")");
@@ -465,7 +464,10 @@ namespace Nz
void GlslWriter::Visit(ShaderNodes::ConditionalExpression& node)
{
if (m_context.states->enabledConditions.count(node.conditionName) != 0)
std::size_t conditionIndex = m_context.shader->FindConditionByName(node.conditionName);
assert(conditionIndex != ShaderAst::InvalidCondition);
if (TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex))
Visit(node.truePath);
else
Visit(node.falsePath);
@@ -473,7 +475,10 @@ namespace Nz
void GlslWriter::Visit(ShaderNodes::ConditionalStatement& node)
{
if (m_context.states->enabledConditions.count(node.conditionName) != 0)
std::size_t conditionIndex = m_context.shader->FindConditionByName(node.conditionName);
assert(conditionIndex != ShaderAst::InvalidCondition);
if (TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex))
Visit(node.statement);
}
@@ -604,7 +609,7 @@ namespace Nz
void GlslWriter::Visit(ShaderNodes::SwizzleOp& node)
{
Visit(node.expression);
Visit(node.expression, true);
Append(".");
for (std::size_t i = 0; i < node.componentCount; ++i)

View File

@@ -659,6 +659,9 @@ namespace Nz
Int32 nodeTypeInt;
m_stream >> nodeTypeInt;
if (nodeTypeInt < static_cast<Int32>(ShaderNodes::NodeType::None) || nodeTypeInt > static_cast<Int32>(ShaderNodes::NodeType::Max))
throw std::runtime_error("invalid node type");
ShaderNodes::NodeType nodeType = static_cast<ShaderNodes::NodeType>(nodeTypeInt);
#define HandleType(Type) case ShaderNodes::NodeType:: Type : node = std::make_shared<ShaderNodes:: Type>(); break

View File

@@ -150,8 +150,17 @@ namespace Nz
switch (node.op)
{
case ShaderNodes::BinaryType::CompGe:
case ShaderNodes::BinaryType::CompGt:
case ShaderNodes::BinaryType::CompLe:
case ShaderNodes::BinaryType::CompLt:
if (leftType == ShaderNodes::BasicType::Boolean)
throw AstError{ "this operation is not supported for booleans" };
[[fallthrough]];
case ShaderNodes::BinaryType::Add:
case ShaderNodes::BinaryType::Equality:
case ShaderNodes::BinaryType::CompEq:
case ShaderNodes::BinaryType::CompNe:
case ShaderNodes::BinaryType::Substract:
TypeMustMatch(node.left, node.right);
break;
@@ -236,7 +245,7 @@ namespace Nz
}
if (componentCount != requiredComponents)
throw AstError{ "Component count doesn't match required component count" };
throw AstError{ "component count doesn't match required component count" };
ShaderAstRecursiveVisitor::Visit(node);
}
@@ -246,28 +255,16 @@ namespace Nz
MandatoryNode(node.truePath);
MandatoryNode(node.falsePath);
for (std::size_t i = 0; i < m_shader.GetConditionCount(); ++i)
{
const auto& condition = m_shader.GetCondition(i);
if (condition.name == node.conditionName)
return;
}
throw AstError{ "Condition not found" };
if (m_shader.FindConditionByName(node.conditionName) == ShaderAst::InvalidCondition)
throw AstError{ "condition not found" };
}
void ShaderAstValidator::Visit(ShaderNodes::ConditionalStatement& node)
{
MandatoryNode(node.statement);
for (std::size_t i = 0; i < m_shader.GetConditionCount(); ++i)
{
const auto& condition = m_shader.GetCondition(i);
if (condition.name == node.conditionName)
return;
}
throw AstError{ "Condition not found" };
if (m_shader.FindConditionByName(node.conditionName) == ShaderAst::InvalidCondition)
throw AstError{ "condition not found" };
}
void ShaderAstValidator::Visit(ShaderNodes::Constant& /*node*/)

View File

@@ -140,7 +140,12 @@ namespace Nz::ShaderNodes
break;
}
case BinaryType::Equality:
case BinaryType::CompEq:
case BinaryType::CompGe:
case BinaryType::CompGt:
case BinaryType::CompLe:
case BinaryType::CompLt:
case BinaryType::CompNe:
exprType = BasicType::Boolean;
break;
}

View File

@@ -154,7 +154,7 @@ namespace Nz
break;
}
case ShaderNodes::BinaryType::Equality:
case ShaderNodes::BinaryType::CompEq:
{
switch (leftType)
{
@@ -185,6 +185,166 @@ namespace Nz
break;
}
case ShaderNodes::BinaryType::CompGe:
{
switch (leftType)
{
case ShaderNodes::BasicType::Float1:
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Mat4x4:
return SpirvOp::OpFOrdGreaterThan;
case ShaderNodes::BasicType::Int1:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
return SpirvOp::OpSGreaterThan;
case ShaderNodes::BasicType::UInt1:
case ShaderNodes::BasicType::UInt2:
case ShaderNodes::BasicType::UInt3:
case ShaderNodes::BasicType::UInt4:
return SpirvOp::OpUGreaterThan;
case ShaderNodes::BasicType::Boolean:
case ShaderNodes::BasicType::Sampler2D:
case ShaderNodes::BasicType::Void:
break;
}
break;
}
case ShaderNodes::BinaryType::CompGt:
{
switch (leftType)
{
case ShaderNodes::BasicType::Float1:
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Mat4x4:
return SpirvOp::OpFOrdGreaterThanEqual;
case ShaderNodes::BasicType::Int1:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
return SpirvOp::OpSGreaterThanEqual;
case ShaderNodes::BasicType::UInt1:
case ShaderNodes::BasicType::UInt2:
case ShaderNodes::BasicType::UInt3:
case ShaderNodes::BasicType::UInt4:
return SpirvOp::OpUGreaterThanEqual;
case ShaderNodes::BasicType::Boolean:
case ShaderNodes::BasicType::Sampler2D:
case ShaderNodes::BasicType::Void:
break;
}
break;
}
case ShaderNodes::BinaryType::CompLe:
{
switch (leftType)
{
case ShaderNodes::BasicType::Float1:
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Mat4x4:
return SpirvOp::OpFOrdLessThanEqual;
case ShaderNodes::BasicType::Int1:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
return SpirvOp::OpSLessThanEqual;
case ShaderNodes::BasicType::UInt1:
case ShaderNodes::BasicType::UInt2:
case ShaderNodes::BasicType::UInt3:
case ShaderNodes::BasicType::UInt4:
return SpirvOp::OpULessThanEqual;
case ShaderNodes::BasicType::Boolean:
case ShaderNodes::BasicType::Sampler2D:
case ShaderNodes::BasicType::Void:
break;
}
break;
}
case ShaderNodes::BinaryType::CompLt:
{
switch (leftType)
{
case ShaderNodes::BasicType::Float1:
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Mat4x4:
return SpirvOp::OpFOrdLessThan;
case ShaderNodes::BasicType::Int1:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
return SpirvOp::OpSLessThan;
case ShaderNodes::BasicType::UInt1:
case ShaderNodes::BasicType::UInt2:
case ShaderNodes::BasicType::UInt3:
case ShaderNodes::BasicType::UInt4:
return SpirvOp::OpULessThan;
case ShaderNodes::BasicType::Boolean:
case ShaderNodes::BasicType::Sampler2D:
case ShaderNodes::BasicType::Void:
break;
}
break;
}
case ShaderNodes::BinaryType::CompNe:
{
switch (leftType)
{
case ShaderNodes::BasicType::Boolean:
return SpirvOp::OpLogicalNotEqual;
case ShaderNodes::BasicType::Float1:
case ShaderNodes::BasicType::Float2:
case ShaderNodes::BasicType::Float3:
case ShaderNodes::BasicType::Float4:
case ShaderNodes::BasicType::Mat4x4:
return SpirvOp::OpFOrdNotEqual;
case ShaderNodes::BasicType::Int1:
case ShaderNodes::BasicType::Int2:
case ShaderNodes::BasicType::Int3:
case ShaderNodes::BasicType::Int4:
case ShaderNodes::BasicType::UInt1:
case ShaderNodes::BasicType::UInt2:
case ShaderNodes::BasicType::UInt3:
case ShaderNodes::BasicType::UInt4:
return SpirvOp::OpINotEqual;
case ShaderNodes::BasicType::Sampler2D:
case ShaderNodes::BasicType::Void:
break;
}
break;
}
case ShaderNodes::BinaryType::Multiply:
{

View File

@@ -33,7 +33,8 @@ namespace Nz
using LocalContainer = std::unordered_set<std::shared_ptr<const ShaderNodes::LocalVariable>>;
using ParameterContainer = std::unordered_set< std::shared_ptr<const ShaderNodes::ParameterVariable>>;
PreVisitor(const SpirvWriter::States& conditions, SpirvConstantCache& constantCache) :
PreVisitor(const ShaderAst& shader, const SpirvWriter::States& conditions, SpirvConstantCache& constantCache) :
m_shader(shader),
m_conditions(conditions),
m_constantCache(constantCache)
{
@@ -52,7 +53,10 @@ namespace Nz
void Visit(ShaderNodes::ConditionalExpression& node) override
{
if (m_conditions.enabledConditions.count(node.conditionName) != 0)
std::size_t conditionIndex = m_shader.FindConditionByName(node.conditionName);
assert(conditionIndex != ShaderAst::InvalidCondition);
if (TestBit<Nz::UInt64>(m_conditions.enabledConditions, conditionIndex))
Visit(node.truePath);
else
Visit(node.falsePath);
@@ -60,7 +64,10 @@ namespace Nz
void Visit(ShaderNodes::ConditionalStatement& node) override
{
if (m_conditions.enabledConditions.count(node.conditionName) != 0)
std::size_t conditionIndex = m_shader.FindConditionByName(node.conditionName);
assert(conditionIndex != ShaderAst::InvalidCondition);
if (TestBit<Nz::UInt64>(m_conditions.enabledConditions, conditionIndex))
Visit(node.statement);
}
@@ -141,6 +148,7 @@ namespace Nz
ParameterContainer paramVars;
private:
const ShaderAst& m_shader;
const SpirvWriter::States& m_conditions;
SpirvConstantCache& m_constantCache;
};
@@ -229,7 +237,7 @@ namespace Nz
ShaderAstCloner cloner;
PreVisitor preVisitor(conditions, state.constantTypeCache);
PreVisitor preVisitor(shader, conditions, state.constantTypeCache);
for (const auto& func : shader.GetFunctions())
{
functionStatements.emplace_back(cloner.Clone(func.statement));