Commit current work
Reworked conditions, added uber-shaders, comparison nodes, fixed Discard
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*/)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user