diff --git a/include/Nazara/Shader/Ast/AstOptimizer.hpp b/include/Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp similarity index 59% rename from include/Nazara/Shader/Ast/AstOptimizer.hpp rename to include/Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp index 476fffc9b..151fa7fca 100644 --- a/include/Nazara/Shader/Ast/AstOptimizer.hpp +++ b/include/Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp @@ -4,8 +4,8 @@ #pragma once -#ifndef NAZARA_SHADER_AST_ASTOPTIMIZER_HPP -#define NAZARA_SHADER_AST_ASTOPTIMIZER_HPP +#ifndef NAZARA_SHADER_AST_ASTCONSTANTPROPAGATIONVISITOR_HPP +#define NAZARA_SHADER_AST_ASTCONSTANTPROPAGATIONVISITOR_HPP #include #include @@ -16,23 +16,23 @@ namespace Nz::ShaderAst { - class NAZARA_SHADER_API AstOptimizer : public AstCloner + class NAZARA_SHADER_API AstConstantPropagationVisitor : public AstCloner { public: struct Options; - AstOptimizer() = default; - AstOptimizer(const AstOptimizer&) = delete; - AstOptimizer(AstOptimizer&&) = delete; - ~AstOptimizer() = default; + AstConstantPropagationVisitor() = default; + AstConstantPropagationVisitor(const AstConstantPropagationVisitor&) = delete; + AstConstantPropagationVisitor(AstConstantPropagationVisitor&&) = delete; + ~AstConstantPropagationVisitor() = default; - inline ExpressionPtr Optimise(Expression& expression); - inline ExpressionPtr Optimise(Expression& expression, const Options& options); - inline StatementPtr Optimise(Statement& statement); - inline StatementPtr Optimise(Statement& statement, const Options& options); + inline ExpressionPtr Process(Expression& expression); + inline ExpressionPtr Process(Expression& expression, const Options& options); + inline StatementPtr Process(Statement& statement); + inline StatementPtr Process(Statement& statement, const Options& options); - AstOptimizer& operator=(const AstOptimizer&) = delete; - AstOptimizer& operator=(AstOptimizer&&) = delete; + AstConstantPropagationVisitor& operator=(const AstConstantPropagationVisitor&) = delete; + AstConstantPropagationVisitor& operator=(AstConstantPropagationVisitor&&) = delete; struct Options { @@ -63,12 +63,12 @@ namespace Nz::ShaderAst Options m_options; }; - inline ExpressionPtr Optimize(Expression& expr); - inline ExpressionPtr Optimize(Expression& expr, const AstOptimizer::Options& options); - inline StatementPtr Optimize(Statement& ast); - inline StatementPtr Optimize(Statement& ast, const AstOptimizer::Options& options); + inline ExpressionPtr PropagateConstants(Expression& expr); + inline ExpressionPtr PropagateConstants(Expression& expr, const AstConstantPropagationVisitor::Options& options); + inline StatementPtr PropagateConstants(Statement& ast); + inline StatementPtr PropagateConstants(Statement& ast, const AstConstantPropagationVisitor::Options& options); } -#include +#include -#endif // NAZARA_SHADER_AST_ASTOPTIMIZER_HPP +#endif // NAZARA_SHADER_AST_ASTCONSTANTPROPAGATIONVISITOR_HPP diff --git a/include/Nazara/Shader/Ast/AstConstantPropagationVisitor.inl b/include/Nazara/Shader/Ast/AstConstantPropagationVisitor.inl new file mode 100644 index 000000000..97c9ba014 --- /dev/null +++ b/include/Nazara/Shader/Ast/AstConstantPropagationVisitor.inl @@ -0,0 +1,59 @@ +// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - Shader module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz::ShaderAst +{ + inline ExpressionPtr AstConstantPropagationVisitor::Process(Expression& expression) + { + m_options = {}; + return CloneExpression(expression); + } + + inline ExpressionPtr AstConstantPropagationVisitor::Process(Expression& expression, const Options& options) + { + m_options = options; + return CloneExpression(expression); + } + + inline StatementPtr AstConstantPropagationVisitor::Process(Statement& statement) + { + m_options = {}; + return CloneStatement(statement); + } + + inline StatementPtr AstConstantPropagationVisitor::Process(Statement& statement, const Options& options) + { + m_options = options; + return CloneStatement(statement); + } + + inline ExpressionPtr PropagateConstants(Expression& ast) + { + AstConstantPropagationVisitor optimize; + return optimize.Process(ast); + } + + inline ExpressionPtr PropagateConstants(Expression& ast, const AstConstantPropagationVisitor::Options& options) + { + AstConstantPropagationVisitor optimize; + return optimize.Process(ast, options); + } + + inline StatementPtr PropagateConstants(Statement& ast) + { + AstConstantPropagationVisitor optimize; + return optimize.Process(ast); + } + + inline StatementPtr PropagateConstants(Statement& ast, const AstConstantPropagationVisitor::Options& options) + { + AstConstantPropagationVisitor optimize; + return optimize.Process(ast, options); + } +} + +#include diff --git a/include/Nazara/Shader/Ast/AstOptimizer.inl b/include/Nazara/Shader/Ast/AstOptimizer.inl deleted file mode 100644 index cbd7d40ae..000000000 --- a/include/Nazara/Shader/Ast/AstOptimizer.inl +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) -// This file is part of the "Nazara Engine - Shader module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include - -namespace Nz::ShaderAst -{ - inline ExpressionPtr AstOptimizer::Optimise(Expression& expression) - { - m_options = {}; - return CloneExpression(expression); - } - - inline ExpressionPtr AstOptimizer::Optimise(Expression& expression, const Options& options) - { - m_options = options; - return CloneExpression(expression); - } - - inline StatementPtr AstOptimizer::Optimise(Statement& statement) - { - m_options = {}; - return CloneStatement(statement); - } - - inline StatementPtr AstOptimizer::Optimise(Statement& statement, const Options& options) - { - m_options = options; - return CloneStatement(statement); - } - - inline ExpressionPtr Optimize(Expression& ast) - { - AstOptimizer optimize; - return optimize.Optimise(ast); - } - - inline ExpressionPtr Optimize(Expression& ast, const AstOptimizer::Options& options) - { - AstOptimizer optimize; - return optimize.Optimise(ast, options); - } - - inline StatementPtr Optimize(Statement& ast) - { - AstOptimizer optimize; - return optimize.Optimise(ast); - } - - inline StatementPtr Optimize(Statement& ast, const AstOptimizer::Options& options) - { - AstOptimizer optimize; - return optimize.Optimise(ast, options); - } -} - -#include diff --git a/include/Nazara/Shader/Ast/SanitizeVisitor.hpp b/include/Nazara/Shader/Ast/SanitizeVisitor.hpp index caec552f6..0a1ad1695 100644 --- a/include/Nazara/Shader/Ast/SanitizeVisitor.hpp +++ b/include/Nazara/Shader/Ast/SanitizeVisitor.hpp @@ -105,7 +105,7 @@ namespace Nz::ShaderAst ConstantValue ComputeConstantValue(Expression& expr) const; template const T& ComputeExprValue(ExpressionValue& attribute) const; - template std::unique_ptr Optimize(T& node) const; + template std::unique_ptr PropagateConstants(T& node) const; void PropagateFunctionFlags(std::size_t funcIndex, FunctionFlags flags, Bitset<>& seen); diff --git a/src/Nazara/Shader/Ast/AstOptimizer.cpp b/src/Nazara/Shader/Ast/AstConstantPropagationVisitor.cpp similarity index 95% rename from src/Nazara/Shader/Ast/AstOptimizer.cpp rename to src/Nazara/Shader/Ast/AstConstantPropagationVisitor.cpp index b6bf8bff7..d648c7596 100644 --- a/src/Nazara/Shader/Ast/AstOptimizer.cpp +++ b/src/Nazara/Shader/Ast/AstConstantPropagationVisitor.cpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Shader module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include @@ -21,10 +21,14 @@ namespace Nz::ShaderAst template struct is_complete_helper { - template static auto test(U*)->std::integral_constant; + // SFINAE: sizeof in an incomplete type is an error, but since there's another specialization it won't result in a compilation error + template + static auto test(U*) -> std::bool_constant; + + // less specialized overload static auto test(...) -> std::false_type; - using type = decltype(test((T*)0)); + using type = decltype(test(static_cast(nullptr))); }; template @@ -731,7 +735,7 @@ namespace Nz::ShaderAst #undef EnableOptimisation } - ExpressionPtr AstOptimizer::Clone(BinaryExpression& node) + ExpressionPtr AstConstantPropagationVisitor::Clone(BinaryExpression& node) { auto lhs = CloneExpression(node.left); auto rhs = CloneExpression(node.right); @@ -803,7 +807,7 @@ namespace Nz::ShaderAst return binary; } - ExpressionPtr AstOptimizer::Clone(CastExpression& node) + ExpressionPtr AstConstantPropagationVisitor::Clone(CastExpression& node) { std::array expressions; @@ -922,7 +926,7 @@ namespace Nz::ShaderAst return cast; } - StatementPtr AstOptimizer::Clone(BranchStatement& node) + StatementPtr AstConstantPropagationVisitor::Clone(BranchStatement& node) { std::vector statements; StatementPtr elseStatement; @@ -978,7 +982,7 @@ namespace Nz::ShaderAst return ShaderBuilder::Branch(std::move(statements), std::move(elseStatement)); } - ExpressionPtr AstOptimizer::Clone(ConditionalExpression& node) + ExpressionPtr AstConstantPropagationVisitor::Clone(ConditionalExpression& node) { auto cond = CloneExpression(node.condition); if (cond->GetType() != NodeType::ConstantValueExpression) @@ -999,7 +1003,7 @@ namespace Nz::ShaderAst return AstCloner::Clone(*node.falsePath); } - ExpressionPtr AstOptimizer::Clone(ConstantExpression& node) + ExpressionPtr AstConstantPropagationVisitor::Clone(ConstantExpression& node) { if (!m_options.constantQueryCallback) return AstCloner::Clone(node); @@ -1010,7 +1014,7 @@ namespace Nz::ShaderAst return constant; } - ExpressionPtr AstOptimizer::Clone(SwizzleExpression& node) + ExpressionPtr AstConstantPropagationVisitor::Clone(SwizzleExpression& node) { auto expr = CloneExpression(node.expression); @@ -1061,7 +1065,7 @@ namespace Nz::ShaderAst return swizzle; } - ExpressionPtr AstOptimizer::Clone(UnaryExpression& node) + ExpressionPtr AstConstantPropagationVisitor::Clone(UnaryExpression& node) { auto expr = CloneExpression(node.expression); @@ -1095,7 +1099,7 @@ namespace Nz::ShaderAst return unary; } - StatementPtr AstOptimizer::Clone(ConditionalStatement& node) + StatementPtr AstConstantPropagationVisitor::Clone(ConditionalStatement& node) { auto cond = CloneExpression(node.condition); if (cond->GetType() != NodeType::ConstantValueExpression) @@ -1117,7 +1121,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateBinaryConstant(const ConstantValueExpression& lhs, const ConstantValueExpression& rhs) + ExpressionPtr AstConstantPropagationVisitor::PropagateBinaryConstant(const ConstantValueExpression& lhs, const ConstantValueExpression& rhs) { std::unique_ptr optimized; std::visit([&](auto&& arg1) @@ -1146,7 +1150,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateSingleValueCast(const ConstantValueExpression& operand) + ExpressionPtr AstConstantPropagationVisitor::PropagateSingleValueCast(const ConstantValueExpression& operand) { std::unique_ptr optimized; @@ -1163,7 +1167,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateConstantSwizzle(const std::array& components, const ConstantValueExpression& operand) + ExpressionPtr AstConstantPropagationVisitor::PropagateConstantSwizzle(const std::array& components, const ConstantValueExpression& operand) { std::unique_ptr optimized; std::visit([&](auto&& arg) @@ -1183,7 +1187,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateUnaryConstant(const ConstantValueExpression& operand) + ExpressionPtr AstConstantPropagationVisitor::PropagateUnaryConstant(const ConstantValueExpression& operand) { std::unique_ptr optimized; std::visit([&](auto&& arg) @@ -1206,7 +1210,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateVec2Cast(TargetType v1, TargetType v2) + ExpressionPtr AstConstantPropagationVisitor::PropagateVec2Cast(TargetType v1, TargetType v2) { std::unique_ptr optimized; @@ -1219,7 +1223,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateVec3Cast(TargetType v1, TargetType v2, TargetType v3) + ExpressionPtr AstConstantPropagationVisitor::PropagateVec3Cast(TargetType v1, TargetType v2, TargetType v3) { std::unique_ptr optimized; @@ -1232,7 +1236,7 @@ namespace Nz::ShaderAst } template - ExpressionPtr AstOptimizer::PropagateVec4Cast(TargetType v1, TargetType v2, TargetType v3, TargetType v4) + ExpressionPtr AstConstantPropagationVisitor::PropagateVec4Cast(TargetType v1, TargetType v2, TargetType v3, TargetType v4) { std::unique_ptr optimized; @@ -1245,7 +1249,7 @@ namespace Nz::ShaderAst } - StatementPtr AstOptimizer::Unscope(StatementPtr node) + StatementPtr AstConstantPropagationVisitor::Unscope(StatementPtr node) { assert(node); diff --git a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp index 9c54ddefd..e4fb16e56 100644 --- a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp +++ b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -719,7 +719,7 @@ namespace Nz::ShaderAst if (!clone->expression) throw AstError{ "const variables must have an expression" }; - clone->expression = Optimize(*clone->expression); + clone->expression = PropagateConstants(*clone->expression); if (clone->expression->GetType() != NodeType::ConstantValueExpression) throw AstError{ "const variable must have constant expressions " }; @@ -1426,7 +1426,7 @@ namespace Nz::ShaderAst ConstantValue SanitizeVisitor::ComputeConstantValue(Expression& expr) const { // Run optimizer on constant value to hopefully retrieve a single constant value - ExpressionPtr optimizedExpr = Optimize(expr); + ExpressionPtr optimizedExpr = PropagateConstants(expr); if (optimizedExpr->GetType() != NodeType::ConstantValueExpression) throw AstError{"expected a constant expression"}; @@ -1464,9 +1464,9 @@ namespace Nz::ShaderAst } template - std::unique_ptr SanitizeVisitor::Optimize(T& node) const + std::unique_ptr SanitizeVisitor::PropagateConstants(T& node) const { - AstOptimizer::Options optimizerOptions; + AstConstantPropagationVisitor::Options optimizerOptions; optimizerOptions.constantQueryCallback = [this](std::size_t constantId) -> const ConstantValue& { assert(constantId < m_context->constantValues.size()); @@ -1474,7 +1474,7 @@ namespace Nz::ShaderAst }; // Run optimizer on constant value to hopefully retrieve a single constant value - return static_unique_pointer_cast(ShaderAst::Optimize(node, optimizerOptions)); + return static_unique_pointer_cast(ShaderAst::PropagateConstants(node, optimizerOptions)); } void SanitizeVisitor::PropagateFunctionFlags(std::size_t funcIndex, FunctionFlags flags, Bitset<>& seen) diff --git a/src/Nazara/Shader/GlslWriter.cpp b/src/Nazara/Shader/GlslWriter.cpp index 4cd4c969a..5b05f1f09 100644 --- a/src/Nazara/Shader/GlslWriter.cpp +++ b/src/Nazara/Shader/GlslWriter.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -180,7 +180,7 @@ namespace Nz { ShaderAst::StatementPtr tempAst; - tempAst = ShaderAst::Optimize(*targetAst); + tempAst = ShaderAst::PropagateConstants(*targetAst); optimizedAst = ShaderAst::EliminateUnusedPass(*tempAst); targetAst = optimizedAst.get(); diff --git a/src/Nazara/Shader/SpirvWriter.cpp b/src/Nazara/Shader/SpirvWriter.cpp index 6a62f384b..5416240e4 100644 --- a/src/Nazara/Shader/SpirvWriter.cpp +++ b/src/Nazara/Shader/SpirvWriter.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -521,7 +521,7 @@ namespace Nz { ShaderAst::StatementPtr tempAst; - tempAst = ShaderAst::Optimize(*targetAst); + tempAst = ShaderAst::PropagateConstants(*targetAst); optimizedAst = ShaderAst::EliminateUnusedPass(*tempAst); targetAst = optimizedAst.get(); diff --git a/src/ShaderNode/Widgets/CodeOutputWidget.cpp b/src/ShaderNode/Widgets/CodeOutputWidget.cpp index bdc7c11c4..04a788b3f 100644 --- a/src/ShaderNode/Widgets/CodeOutputWidget.cpp +++ b/src/ShaderNode/Widgets/CodeOutputWidget.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -70,8 +70,8 @@ void CodeOutputWidget::Refresh() shaderAst = Nz::ShaderAst::Sanitize(*shaderAst, sanitizeOptions); - Nz::ShaderAst::AstOptimizer optimiser; - shaderAst = Nz::ShaderAst::Optimize(*shaderAst); + Nz::ShaderAst::AstConstantPropagationVisitor optimiser; + shaderAst = Nz::ShaderAst::PropagateConstants(*shaderAst); shaderAst = Nz::ShaderAst::EliminateUnusedPass(*shaderAst); } diff --git a/tests/Engine/Shader/Const.cpp b/tests/Engine/Shader/Const.cpp index 4bee938d3..df99b2e31 100644 --- a/tests/Engine/Shader/Const.cpp +++ b/tests/Engine/Shader/Const.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/Engine/Shader/Optimizations.cpp b/tests/Engine/Shader/Optimizations.cpp index 2ed7446ba..c47803b41 100644 --- a/tests/Engine/Shader/Optimizations.cpp +++ b/tests/Engine/Shader/Optimizations.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include @@ -13,7 +13,7 @@ void ExpectOptimization(std::string_view sourceCode, std::string_view expectedOp Nz::ShaderAst::StatementPtr shader; REQUIRE_NOTHROW(shader = Nz::ShaderLang::Parse(sourceCode)); REQUIRE_NOTHROW(shader = Nz::ShaderAst::Sanitize(*shader)); - REQUIRE_NOTHROW(shader = Nz::ShaderAst::Optimize(*shader)); + REQUIRE_NOTHROW(shader = Nz::ShaderAst::PropagateConstants(*shader)); ExpectNZSL(*shader, expectedOptimizedResult); }