Shader: Add support for exp intrinsic

This commit is contained in:
Jérôme Leclercq 2021-12-05 17:02:46 +01:00
parent 7e4a058d41
commit 0aec863300
6 changed files with 39 additions and 13 deletions

View File

@ -98,6 +98,7 @@ namespace Nz
{ {
CrossProduct = 0, CrossProduct = 0,
DotProduct = 1, DotProduct = 1,
Exp = 7,
Length = 3, Length = 3,
Max = 4, Max = 4,
Min = 5, Min = 5,

View File

@ -68,6 +68,7 @@ namespace Nz::ShaderAst
{ {
RegisterIntrinsic("cross", IntrinsicType::CrossProduct); RegisterIntrinsic("cross", IntrinsicType::CrossProduct);
RegisterIntrinsic("dot", IntrinsicType::DotProduct); RegisterIntrinsic("dot", IntrinsicType::DotProduct);
RegisterIntrinsic("exp", IntrinsicType::Exp);
RegisterIntrinsic("length", IntrinsicType::Length); RegisterIntrinsic("length", IntrinsicType::Length);
RegisterIntrinsic("max", IntrinsicType::Max); RegisterIntrinsic("max", IntrinsicType::Max);
RegisterIntrinsic("min", IntrinsicType::Min); RegisterIntrinsic("min", IntrinsicType::Min);
@ -1389,15 +1390,21 @@ namespace Nz::ShaderAst
break; break;
} }
case IntrinsicType::Exp:
{
if (node.parameters.size() != 1)
throw AstError{ "Expected only one parameters" };
MandatoryExpr(node.parameters.front());
break;
}
case IntrinsicType::Length: case IntrinsicType::Length:
{ {
if (node.parameters.size() != 1) if (node.parameters.size() != 1)
throw AstError{ "Expected only one parameters" }; throw AstError{ "Expected only one parameters" };
for (auto& param : node.parameters) const ExpressionType& type = GetExpressionType(MandatoryExpr(node.parameters.front()));
MandatoryExpr(param);
const ExpressionType& type = GetExpressionType(*node.parameters.front());
if (!IsVectorType(type)) if (!IsVectorType(type))
throw AstError{ "Expected a vector" }; throw AstError{ "Expected a vector" };
@ -1438,7 +1445,7 @@ namespace Nz::ShaderAst
case IntrinsicType::DotProduct: case IntrinsicType::DotProduct:
case IntrinsicType::Length: case IntrinsicType::Length:
{ {
ExpressionType type = GetExpressionType(*node.parameters.front()); const ExpressionType& type = GetExpressionType(*node.parameters.front());
if (!IsVectorType(type)) if (!IsVectorType(type))
throw AstError{ "DotProduct expects vector types" }; throw AstError{ "DotProduct expects vector types" };
@ -1461,6 +1468,7 @@ namespace Nz::ShaderAst
break; break;
} }
case IntrinsicType::Exp:
case IntrinsicType::Pow: case IntrinsicType::Pow:
{ {
const ExpressionType& type = GetExpressionType(*node.parameters.front()); const ExpressionType& type = GetExpressionType(*node.parameters.front());

View File

@ -1076,6 +1076,10 @@ namespace Nz
Append("dot"); Append("dot");
break; break;
case ShaderAst::IntrinsicType::Exp:
Append("exp");
break;
case ShaderAst::IntrinsicType::Length: case ShaderAst::IntrinsicType::Length:
Append("length"); Append("length");
break; break;

View File

@ -812,6 +812,10 @@ namespace Nz
Append("dot"); Append("dot");
break; break;
case ShaderAst::IntrinsicType::Exp:
Append("exp");
break;
case ShaderAst::IntrinsicType::Length: case ShaderAst::IntrinsicType::Length:
Append("length"); Append("length");
break; break;

View File

@ -743,6 +743,22 @@ namespace Nz
break; 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: case ShaderAst::IntrinsicType::Length:
{ {
UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450"); UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450");
@ -815,14 +831,6 @@ namespace Nz
assert(IsPrimitiveType(parameterType) || IsVectorType(parameterType)); assert(IsPrimitiveType(parameterType) || IsVectorType(parameterType));
UInt32 typeId = m_writer.GetTypeId(parameterType); UInt32 typeId = m_writer.GetTypeId(parameterType);
ShaderAst::PrimitiveType basicType;
if (IsPrimitiveType(parameterType))
basicType = std::get<ShaderAst::PrimitiveType>(parameterType);
else if (IsVectorType(parameterType))
basicType = std::get<ShaderAst::VectorType>(parameterType).type;
else
throw std::runtime_error("unexpected expression type");
UInt32 firstParam = EvaluateExpression(node.parameters[0]); UInt32 firstParam = EvaluateExpression(node.parameters[0]);
UInt32 secondParam = EvaluateExpression(node.parameters[1]); UInt32 secondParam = EvaluateExpression(node.parameters[1]);
UInt32 resultId = m_writer.AllocateResultId(); UInt32 resultId = m_writer.AllocateResultId();

View File

@ -336,6 +336,7 @@ namespace Nz
{ {
// Require GLSL.std.450 // Require GLSL.std.450
case ShaderAst::IntrinsicType::CrossProduct: case ShaderAst::IntrinsicType::CrossProduct:
case ShaderAst::IntrinsicType::Exp:
case ShaderAst::IntrinsicType::Length: case ShaderAst::IntrinsicType::Length:
case ShaderAst::IntrinsicType::Max: case ShaderAst::IntrinsicType::Max:
case ShaderAst::IntrinsicType::Min: case ShaderAst::IntrinsicType::Min: