Shader: Add support for custom functions calls (and better handle intrinsics)

This commit is contained in:
Jérôme Leclercq
2021-05-22 13:37:54 +02:00
parent 8a6f0db034
commit f6fd996bf1
24 changed files with 777 additions and 356 deletions

View File

@@ -18,14 +18,6 @@ namespace Nz::ShaderLang
{ "f32", ShaderAst::PrimitiveType::Float32 },
{ "u32", ShaderAst::PrimitiveType::UInt32 }
};
std::unordered_map<std::string, ShaderAst::IntrinsicType> s_identifierToIntrinsic = {
{ "cross", ShaderAst::IntrinsicType::CrossProduct },
{ "dot", ShaderAst::IntrinsicType::DotProduct },
{ "max", ShaderAst::IntrinsicType::Max },
{ "min", ShaderAst::IntrinsicType::Min },
{ "length", ShaderAst::IntrinsicType::Length },
};
std::unordered_map<std::string, ShaderAst::AttributeType> s_identifierToAttributeType = {
{ "binding", ShaderAst::AttributeType::Binding },
@@ -137,14 +129,19 @@ namespace Nz::ShaderLang
m_context->tokenIndex += count;
}
ShaderAst::ExpressionType Parser::DecodeType(const std::string& identifier)
std::optional<ShaderAst::ExpressionType> Parser::DecodeType(const std::string& identifier)
{
if (auto it = s_identifierToBasicType.find(identifier); it != s_identifierToBasicType.end())
if (auto it = s_identifierToBasicType.find(identifier); it != s_identifierToBasicType.end())
{
Consume();
return it->second;
}
//FIXME: Handle this better
if (identifier == "mat4")
{
{
Consume();
ShaderAst::MatrixType matrixType;
matrixType.columnCount = 4;
matrixType.rowCount = 4;
@@ -156,7 +153,9 @@ namespace Nz::ShaderLang
return matrixType;
}
else if (identifier == "sampler2D")
{
{
Consume();
ShaderAst::SamplerType samplerType;
samplerType.dim = ImageType_2D;
@@ -167,7 +166,9 @@ namespace Nz::ShaderLang
return samplerType;
}
else if (identifier == "uniform")
{
{
Consume();
ShaderAst::UniformType uniformType;
Expect(Advance(), TokenType::LessThan); //< '<'
@@ -177,7 +178,9 @@ namespace Nz::ShaderLang
return uniformType;
}
else if (identifier == "vec2")
{
{
Consume();
ShaderAst::VectorType vectorType;
vectorType.componentCount = 2;
@@ -188,7 +191,9 @@ namespace Nz::ShaderLang
return vectorType;
}
else if (identifier == "vec3")
{
{
Consume();
ShaderAst::VectorType vectorType;
vectorType.componentCount = 3;
@@ -199,7 +204,9 @@ namespace Nz::ShaderLang
return vectorType;
}
else if (identifier == "vec4")
{
{
Consume();
ShaderAst::VectorType vectorType;
vectorType.componentCount = 4;
@@ -208,14 +215,9 @@ namespace Nz::ShaderLang
Expect(Advance(), TokenType::GreatherThan); //< '>'
return vectorType;
}
else
{
ShaderAst::IdentifierType identifierType;
identifierType.name = identifier;
return identifierType;
}
}
else
return std::nullopt;
}
void Parser::EnterScope()
@@ -873,23 +875,19 @@ namespace Nz::ShaderLang
case TokenType::Identifier:
{
const std::string& identifier = std::get<std::string>(token.data);
// Is it a cast?
std::optional<ShaderAst::ExpressionType> exprType = DecodeType(identifier);
if (exprType)
return ShaderBuilder::Cast(std::move(*exprType), ParseParameters());
if (Peek(1).type == TokenType::OpenParenthesis)
{
if (Peek(1).type == TokenType::OpenParenthesis)
{
Consume();
return ShaderBuilder::Intrinsic(it->second, ParseParameters());
{
// Function call
Consume();
return ShaderBuilder::CallFunction(identifier, ParseParameters());
}
if (IsVariableInScope(identifier))
return ParseIdentifier();
Consume();
ShaderAst::ExpressionType exprType = DecodeType(identifier);
}
else
return ParseIdentifier();
}
@@ -989,10 +987,17 @@ namespace Nz::ShaderLang
return ShaderAst::NoType{};
}
const Token& identifierToken = Expect(Peek(), TokenType::Identifier);
const std::string& identifier = std::get<std::string>(identifierToken.data);
auto type = DecodeType(identifier);
if (!type)
{
Consume();
return ShaderAst::IdentifierType{ identifier };
}
return *type;
}