Handle shader options of any type
This commit is contained in:
@@ -116,7 +116,7 @@ namespace Nz::ShaderAst
|
||||
StatementPtr AstCloner::Clone(DeclareOptionStatement& node)
|
||||
{
|
||||
auto clone = std::make_unique<DeclareOptionStatement>();
|
||||
clone->initialValue = CloneExpression(node.initialValue);
|
||||
clone->defaultValue = CloneExpression(node.defaultValue);
|
||||
clone->optIndex = node.optIndex;
|
||||
clone->optName = node.optName;
|
||||
clone->optType = node.optType;
|
||||
|
||||
@@ -697,7 +697,9 @@ namespace Nz::ShaderAst
|
||||
{
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
|
||||
if constexpr (std::is_same_v<T, bool> || std::is_same_v<T, float> || std::is_same_v<T, Int32> || std::is_same_v<T, UInt32>)
|
||||
if constexpr (std::is_same_v<T, NoValue>)
|
||||
throw std::runtime_error("invalid type (value expected)");
|
||||
else if constexpr (std::is_same_v<T, bool> || std::is_same_v<T, float> || std::is_same_v<T, Int32> || std::is_same_v<T, UInt32>)
|
||||
constantValues.push_back(arg);
|
||||
else if constexpr (std::is_same_v<T, Vector2f> || std::is_same_v<T, Vector2i32>)
|
||||
{
|
||||
@@ -815,9 +817,6 @@ namespace Nz::ShaderAst
|
||||
|
||||
ExpressionPtr AstOptimizer::Clone(ConditionalExpression& node)
|
||||
{
|
||||
if (!m_options.enabledOptions)
|
||||
return AstCloner::Clone(node);
|
||||
|
||||
auto cond = CloneExpression(node.condition);
|
||||
if (cond->GetType() != NodeType::ConstantValueExpression)
|
||||
throw std::runtime_error("conditional expression condition must be a constant expression");
|
||||
@@ -884,9 +883,6 @@ namespace Nz::ShaderAst
|
||||
|
||||
StatementPtr AstOptimizer::Clone(ConditionalStatement& node)
|
||||
{
|
||||
if (!m_options.enabledOptions)
|
||||
return AstCloner::Clone(node);
|
||||
|
||||
auto cond = CloneExpression(node.condition);
|
||||
if (cond->GetType() != NodeType::ConstantValueExpression)
|
||||
throw std::runtime_error("conditional expression condition must be a constant expression");
|
||||
|
||||
@@ -134,8 +134,8 @@ namespace Nz::ShaderAst
|
||||
|
||||
void AstRecursiveVisitor::Visit(DeclareOptionStatement& node)
|
||||
{
|
||||
if (node.initialValue)
|
||||
node.initialValue->Visit(*this);
|
||||
if (node.defaultValue)
|
||||
node.defaultValue->Visit(*this);
|
||||
}
|
||||
|
||||
void AstRecursiveVisitor::Visit(DeclareStructStatement& /*node*/)
|
||||
|
||||
@@ -140,19 +140,20 @@ namespace Nz::ShaderAst
|
||||
Value(value);
|
||||
};
|
||||
|
||||
static_assert(std::variant_size_v<decltype(node.value)> == 10);
|
||||
static_assert(std::variant_size_v<decltype(node.value)> == 11);
|
||||
switch (typeIndex)
|
||||
{
|
||||
case 0: SerializeValue(bool()); break;
|
||||
case 1: SerializeValue(float()); break;
|
||||
case 2: SerializeValue(Int32()); break;
|
||||
case 3: SerializeValue(UInt32()); break;
|
||||
case 4: SerializeValue(Vector2f()); break;
|
||||
case 5: SerializeValue(Vector3f()); break;
|
||||
case 6: SerializeValue(Vector4f()); break;
|
||||
case 7: SerializeValue(Vector2i32()); break;
|
||||
case 8: SerializeValue(Vector3i32()); break;
|
||||
case 9: SerializeValue(Vector4i32()); break;
|
||||
case 0: break;
|
||||
case 1: SerializeValue(bool()); break;
|
||||
case 2: SerializeValue(float()); break;
|
||||
case 3: SerializeValue(Int32()); break;
|
||||
case 4: SerializeValue(UInt32()); break;
|
||||
case 5: SerializeValue(Vector2f()); break;
|
||||
case 6: SerializeValue(Vector3f()); break;
|
||||
case 7: SerializeValue(Vector4f()); break;
|
||||
case 8: SerializeValue(Vector2i32()); break;
|
||||
case 9: SerializeValue(Vector3i32()); break;
|
||||
case 10: SerializeValue(Vector4i32()); break;
|
||||
default: throw std::runtime_error("unexpected data type");
|
||||
}
|
||||
}
|
||||
@@ -261,7 +262,7 @@ namespace Nz::ShaderAst
|
||||
OptVal(node.optIndex);
|
||||
Value(node.optName);
|
||||
Type(node.optType);
|
||||
Node(node.initialValue);
|
||||
Node(node.defaultValue);
|
||||
}
|
||||
|
||||
void AstSerializerBase::Serialize(DeclareStructStatement& node)
|
||||
|
||||
@@ -13,7 +13,9 @@ namespace Nz::ShaderAst
|
||||
{
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
if constexpr (std::is_same_v<T, NoValue>)
|
||||
return NoType{};
|
||||
else if constexpr (std::is_same_v<T, bool>)
|
||||
return PrimitiveType::Boolean;
|
||||
else if constexpr (std::is_same_v<T, float>)
|
||||
return PrimitiveType::Float32;
|
||||
|
||||
@@ -583,6 +583,9 @@ namespace Nz::ShaderAst
|
||||
|
||||
ExpressionPtr SanitizeVisitor::Clone(ConstantValueExpression& node)
|
||||
{
|
||||
if (std::holds_alternative<NoValue>(node.value))
|
||||
throw std::runtime_error("expected a value");
|
||||
|
||||
auto clone = static_unique_pointer_cast<ConstantValueExpression>(AstCloner::Clone(node));
|
||||
clone->cachedExpressionType = GetExpressionType(clone->value);
|
||||
|
||||
@@ -980,12 +983,17 @@ namespace Nz::ShaderAst
|
||||
auto clone = static_unique_pointer_cast<DeclareOptionStatement>(AstCloner::Clone(node));
|
||||
clone->optType = ResolveType(clone->optType);
|
||||
|
||||
if (clone->initialValue && clone->optType != GetExpressionType(*clone->initialValue))
|
||||
throw AstError{ "option " + clone->optName + " initial expression must be of the same type than the option" };
|
||||
if (clone->defaultValue && clone->optType != GetExpressionType(*clone->defaultValue))
|
||||
throw AstError{ "option " + clone->optName + " default expression must be of the same type than the option" };
|
||||
|
||||
std::size_t optionIndex = m_context->nextOptionIndex++;
|
||||
|
||||
clone->optIndex = RegisterConstant(clone->optName, TestBit(m_context->options.enabledOptions, optionIndex));
|
||||
if (auto optionValueIt = m_context->options.optionValues.find(optionIndex); optionValueIt != m_context->options.optionValues.end())
|
||||
clone->optIndex = RegisterConstant(clone->optName, optionValueIt->second);
|
||||
else if (clone->defaultValue)
|
||||
clone->optIndex = RegisterConstant(clone->optName, ComputeConstantValue(*clone->defaultValue));
|
||||
else
|
||||
throw AstError{ "missing option " + clone->optName + " value (has no default value)" };
|
||||
|
||||
if (m_context->options.removeOptionDeclaration)
|
||||
return ShaderBuilder::NoOp();
|
||||
@@ -1186,8 +1194,6 @@ namespace Nz::ShaderAst
|
||||
return m_context->constantValues[constantId];
|
||||
};
|
||||
|
||||
optimizerOptions.enabledOptions = m_context->options.enabledOptions;
|
||||
|
||||
// Run optimizer on constant value to hopefully retrieve a single constant value
|
||||
return static_unique_pointer_cast<T>(ShaderAst::Optimize(node, optimizerOptions));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user