diff --git a/include/Nazara/Shader/Ast/Enums.hpp b/include/Nazara/Shader/Ast/Enums.hpp index ad4775475..3a9a91f91 100644 --- a/include/Nazara/Shader/Ast/Enums.hpp +++ b/include/Nazara/Shader/Ast/Enums.hpp @@ -98,6 +98,7 @@ namespace Nz { CrossProduct = 0, DotProduct = 1, + Exp = 7, Length = 3, Max = 4, Min = 5, diff --git a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp index fecfd5211..b099fa69a 100644 --- a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp +++ b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp @@ -68,6 +68,7 @@ namespace Nz::ShaderAst { RegisterIntrinsic("cross", IntrinsicType::CrossProduct); RegisterIntrinsic("dot", IntrinsicType::DotProduct); + RegisterIntrinsic("exp", IntrinsicType::Exp); RegisterIntrinsic("length", IntrinsicType::Length); RegisterIntrinsic("max", IntrinsicType::Max); RegisterIntrinsic("min", IntrinsicType::Min); @@ -1389,15 +1390,21 @@ namespace Nz::ShaderAst break; } + case IntrinsicType::Exp: + { + if (node.parameters.size() != 1) + throw AstError{ "Expected only one parameters" }; + + MandatoryExpr(node.parameters.front()); + break; + } + case IntrinsicType::Length: { if (node.parameters.size() != 1) throw AstError{ "Expected only one parameters" }; - for (auto& param : node.parameters) - MandatoryExpr(param); - - const ExpressionType& type = GetExpressionType(*node.parameters.front()); + const ExpressionType& type = GetExpressionType(MandatoryExpr(node.parameters.front())); if (!IsVectorType(type)) throw AstError{ "Expected a vector" }; @@ -1438,7 +1445,7 @@ namespace Nz::ShaderAst case IntrinsicType::DotProduct: case IntrinsicType::Length: { - ExpressionType type = GetExpressionType(*node.parameters.front()); + const ExpressionType& type = GetExpressionType(*node.parameters.front()); if (!IsVectorType(type)) throw AstError{ "DotProduct expects vector types" }; @@ -1461,6 +1468,7 @@ namespace Nz::ShaderAst break; } + case IntrinsicType::Exp: case IntrinsicType::Pow: { const ExpressionType& type = GetExpressionType(*node.parameters.front()); diff --git a/src/Nazara/Shader/GlslWriter.cpp b/src/Nazara/Shader/GlslWriter.cpp index c7672365c..7602c0da1 100644 --- a/src/Nazara/Shader/GlslWriter.cpp +++ b/src/Nazara/Shader/GlslWriter.cpp @@ -1076,6 +1076,10 @@ namespace Nz Append("dot"); break; + case ShaderAst::IntrinsicType::Exp: + Append("exp"); + break; + case ShaderAst::IntrinsicType::Length: Append("length"); break; diff --git a/src/Nazara/Shader/LangWriter.cpp b/src/Nazara/Shader/LangWriter.cpp index c5395ab59..356b035bd 100644 --- a/src/Nazara/Shader/LangWriter.cpp +++ b/src/Nazara/Shader/LangWriter.cpp @@ -812,6 +812,10 @@ namespace Nz Append("dot"); break; + case ShaderAst::IntrinsicType::Exp: + Append("exp"); + break; + case ShaderAst::IntrinsicType::Length: Append("length"); break; diff --git a/src/Nazara/Shader/SpirvAstVisitor.cpp b/src/Nazara/Shader/SpirvAstVisitor.cpp index e8f30c291..74a075a87 100644 --- a/src/Nazara/Shader/SpirvAstVisitor.cpp +++ b/src/Nazara/Shader/SpirvAstVisitor.cpp @@ -743,6 +743,22 @@ namespace Nz break; } + case ShaderAst::IntrinsicType::Exp: + { + UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450"); + + const ShaderAst::ExpressionType& parameterType = GetExpressionType(*node.parameters[0]); + assert(IsPrimitiveType(parameterType) || IsVectorType(parameterType)); + UInt32 typeId = m_writer.GetTypeId(parameterType); + + UInt32 param = EvaluateExpression(node.parameters[0]); + UInt32 resultId = m_writer.AllocateResultId(); + + m_currentBlock->Append(SpirvOp::OpExtInst, typeId, resultId, glslInstructionSet, GLSLstd450Exp, param); + PushResultId(resultId); + break; + } + case ShaderAst::IntrinsicType::Length: { UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450"); @@ -815,14 +831,6 @@ namespace Nz assert(IsPrimitiveType(parameterType) || IsVectorType(parameterType)); UInt32 typeId = m_writer.GetTypeId(parameterType); - ShaderAst::PrimitiveType basicType; - if (IsPrimitiveType(parameterType)) - basicType = std::get(parameterType); - else if (IsVectorType(parameterType)) - basicType = std::get(parameterType).type; - else - throw std::runtime_error("unexpected expression type"); - UInt32 firstParam = EvaluateExpression(node.parameters[0]); UInt32 secondParam = EvaluateExpression(node.parameters[1]); UInt32 resultId = m_writer.AllocateResultId(); diff --git a/src/Nazara/Shader/SpirvWriter.cpp b/src/Nazara/Shader/SpirvWriter.cpp index d0eb79ae9..a26a71843 100644 --- a/src/Nazara/Shader/SpirvWriter.cpp +++ b/src/Nazara/Shader/SpirvWriter.cpp @@ -336,6 +336,7 @@ namespace Nz { // Require GLSL.std.450 case ShaderAst::IntrinsicType::CrossProduct: + case ShaderAst::IntrinsicType::Exp: case ShaderAst::IntrinsicType::Length: case ShaderAst::IntrinsicType::Max: case ShaderAst::IntrinsicType::Min: