Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/NZSL/Ast/Compare.inl
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,12 @@

bool Compare(const ScopedStatement& lhs, const ScopedStatement& rhs, const ComparisonParams& params)
{
if (!Compare(lhs.targetType, rhs.targetType, params))
return false;

Check warning on line 838 in include/NZSL/Ast/Compare.inl

View check run for this annotation

Codecov / codecov/patch

include/NZSL/Ast/Compare.inl#L838

Added line #L838 was not covered by tests

if (!Compare(lhs.targetVersion, rhs.targetVersion, params))
return false;

Check warning on line 841 in include/NZSL/Ast/Compare.inl

View check run for this annotation

Codecov / codecov/patch

include/NZSL/Ast/Compare.inl#L841

Added line #L841 was not covered by tests

if (!Compare(lhs.statement, rhs.statement, params))
return false;

Expand Down
10 changes: 9 additions & 1 deletion include/NZSL/Ast/Enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace nzsl::Ast

enum class AttributeType
{
// Next free ID: 20
// Next free ID: 21
AutoBinding = 17, //< Incremental binding index (external block only)
Author = 12, //< Module author (module statement only) - has argument version string
Binding = 0, //< Binding (external var only) - has argument index
Expand All @@ -47,6 +47,7 @@ namespace nzsl::Ast
Tag = 16, //< Tag (external block and external var only) - has argument string
Unroll = 11, //< Unroll (for/for each only) - has argument mode
Workgroup = 18, //< Work group size (function only) - has arguments X, Y, Z
Target = 20, //< Mark a scope as target specific - has arguments target string, version (optional)
};

enum class BinaryType
Expand Down Expand Up @@ -268,6 +269,13 @@ namespace nzsl::Ast
Minus = 1, //< -v
Plus = 2, //< +v
};

enum class TargetType
{
GLSL = 0,
GLES = 1,
SPIRV = 3,
};
}

#endif // NZSL_AST_ENUMS_HPP
2 changes: 2 additions & 0 deletions include/NZSL/Ast/Nodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,8 @@ namespace nzsl::Ast
NodeType GetType() const override;
void Visit(StatementVisitor& visitor) override;

ExpressionValue<TargetType> targetType;
ExpressionValue<std::uint32_t> targetVersion;
StatementPtr statement;
};

Expand Down
1 change: 1 addition & 0 deletions include/NZSL/Lang/ErrorList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ NZSL_SHADERLANG_PARSER_ERROR(AttributeInvalidParameter, "invalid parameter {} fo
NZSL_SHADERLANG_PARSER_ERROR(AttributeMultipleUnique, "attribute {} can only be present once", Ast::AttributeType)
NZSL_SHADERLANG_PARSER_ERROR(AttributeParameterIdentifier, "attribute {} parameter can only be an identifier", Ast::AttributeType)
NZSL_SHADERLANG_PARSER_ERROR(AttributeUnexpectedParameterCount, "attribute {} expects {} arguments, got {}", Ast::AttributeType, std::size_t, std::size_t)
NZSL_SHADERLANG_PARSER_ERROR(AttributeInvalidTargetVersion, "invalid target version {} for target {}", std::int32_t, std::string)
NZSL_SHADERLANG_PARSER_ERROR(ExpectedToken, "expected token {}, got {}", TokenType, TokenType)
NZSL_SHADERLANG_PARSER_ERROR(DuplicateIdentifier, "duplicate identifier")
NZSL_SHADERLANG_PARSER_ERROR(DuplicateModule, "duplicate module")
Expand Down
2 changes: 2 additions & 0 deletions include/NZSL/LangWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace nzsl
struct TagAttribute;
struct UnrollAttribute;
struct WorkgroupAttribute;
struct TargetAttribute;

void Append(const Ast::AliasType& type);
void Append(const Ast::ArrayType& type);
Expand Down Expand Up @@ -104,6 +105,7 @@ namespace nzsl
void AppendAttribute(TagAttribute attribute);
void AppendAttribute(UnrollAttribute attribute);
void AppendAttribute(WorkgroupAttribute attribute);
void AppendAttribute(TargetAttribute attribute);
void AppendComment(std::string_view section);
void AppendCommentSection(std::string_view section);
void AppendHeader();
Expand Down
3 changes: 2 additions & 1 deletion include/NZSL/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace nzsl
static std::string_view ToString(Ast::LoopUnroll loopUnroll);
static std::string_view ToString(Ast::MemoryLayout memoryLayout);
static std::string_view ToString(Ast::ModuleFeature moduleFeature);
static std::string_view ToString(Ast::TargetType targetType);
static std::string_view ToString(ShaderStageType shaderStage);

private:
Expand Down Expand Up @@ -74,7 +75,7 @@ namespace nzsl
Ast::StatementPtr ParseReturnStatement();
Ast::StatementPtr ParseRootStatement(std::vector<Attribute> attributes = {});
Ast::StatementPtr ParseSingleStatement();
Ast::StatementPtr ParseStatement();
Ast::StatementPtr ParseStatement(std::vector<Attribute> attributes = {});
std::vector<Ast::StatementPtr> ParseStatementList(SourceLocation* sourceLocation);
Ast::StatementPtr ParseStructDeclaration(std::vector<Attribute> attributes = {});
Ast::StatementPtr ParseVariableDeclaration();
Expand Down
2 changes: 2 additions & 0 deletions src/NZSL/Ast/AstSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,8 @@ namespace nzsl::Ast

void SerializerBase::Serialize(ScopedStatement& node)
{
ExprValue(node.targetType);
ExprValue(node.targetVersion);
Node(node.statement);
}

Expand Down
2 changes: 2 additions & 0 deletions src/NZSL/Ast/Cloner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ namespace nzsl::Ast
StatementPtr Cloner::Clone(ScopedStatement& node)
{
auto clone = std::make_unique<ScopedStatement>();
clone->targetType = Clone(node.targetType);
clone->targetVersion = Clone(node.targetVersion);
clone->statement = CloneStatement(node.statement);

clone->sourceLocation = node.sourceLocation;
Expand Down
14 changes: 14 additions & 0 deletions src/NZSL/GlslWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2703,6 +2703,20 @@

void GlslWriter::Visit(Ast::ScopedStatement& node)
{
if (node.targetType.IsResultingValue())
{
unsigned int glVersion = m_environment.glMajorVersion * 100 + m_environment.glMinorVersion * 10;
auto targetType = node.targetType.GetResultingValue();
std::uint32_t targetVersion = 0;

Check warning on line 2710 in src/NZSL/GlslWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/GlslWriter.cpp#L2708-L2710

Added lines #L2708 - L2710 were not covered by tests
if (node.targetVersion.IsResultingValue())
targetVersion = node.targetVersion.GetResultingValue();

Check warning on line 2712 in src/NZSL/GlslWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/GlslWriter.cpp#L2712

Added line #L2712 was not covered by tests

const auto isGLSL = !m_environment.glES && targetType == Ast::TargetType::GLSL;
const auto isGLES = m_environment.glES && targetType == Ast::TargetType::GLES;
if (!((isGLSL || isGLES) && targetVersion <= glVersion))
return;

Check warning on line 2717 in src/NZSL/GlslWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/GlslWriter.cpp#L2717

Added line #L2717 was not covered by tests
}

EnterScope();
node.statement->Visit(*this);
LeaveScope(true);
Expand Down
13 changes: 13 additions & 0 deletions src/NZSL/Lang/Errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ struct fmt::formatter<nzsl::TokenType> : formatter<string_view>
}
};

template<>
struct fmt::formatter<nzsl::Ast::TargetType> : formatter<string_view>
{
template<typename FormatContext>
auto format(const nzsl::Ast::TargetType& p, FormatContext& ctx) const -> decltype(ctx.out())
{
auto it = nzsl::LangData::s_targets.find(p);
assert(it != nzsl::LangData::s_targets.end());

return formatter<string_view>::format(it->second.identifier, ctx);
}
};

namespace nzsl
{
std::string_view ToString(ErrorCategory errorCategory)
Expand Down
14 changes: 13 additions & 1 deletion src/NZSL/Lang/LangData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ namespace nzsl::LangData
{ Ast::AttributeType::Set, { "set" } },
{ Ast::AttributeType::Tag, { "tag" } },
{ Ast::AttributeType::Unroll, { "unroll" } },
{ Ast::AttributeType::Workgroup, { "workgroup" } }
{ Ast::AttributeType::Workgroup, { "workgroup" } },
{ Ast::AttributeType::Target, { "target" } }
});

struct BuiltinData
Expand Down Expand Up @@ -259,6 +260,17 @@ namespace nzsl::LangData
{ Ast::LoopUnroll::Hint, { "hint" } },
{ Ast::LoopUnroll::Never, { "never" } }
});

struct TargetData
{
std::string_view identifier;
};

constexpr auto s_targets = frozen::make_unordered_map<Ast::TargetType, TargetData>({
{ Ast::TargetType::GLSL, { "glsl" } },
{ Ast::TargetType::GLES, { "gles" } },
{ Ast::TargetType::SPIRV, { "spirv" } },
});
}

#endif // NZSL_LANG_LANGDATA_HPP
37 changes: 37 additions & 0 deletions src/NZSL/LangWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,14 @@
bool HasValue() const { return workgroup.HasValue(); }
};

struct LangWriter::TargetAttribute
{
const Ast::ExpressionValue<Ast::TargetType>& target;
const Ast::ExpressionValue<std::uint32_t>& version;

bool HasValue() const { return target.HasValue(); }
};

struct LangWriter::State
{
struct Identifier
Expand Down Expand Up @@ -780,6 +788,32 @@
Append(")");
}

void LangWriter::AppendAttribute(TargetAttribute attribute)
{

Check warning on line 792 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L791-L792

Added lines #L791 - L792 were not covered by tests
if (!attribute.HasValue())
return;

Check warning on line 794 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L794

Added line #L794 was not covered by tests

Append("target(");

Check warning on line 796 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L796

Added line #L796 was not covered by tests

if (attribute.target.IsResultingValue())
Append(Parser::ToString(attribute.target.GetResultingValue()));
else
attribute.target.GetExpression()->Visit(*this);

Check warning on line 801 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L801

Added line #L801 was not covered by tests

if (attribute.version.HasValue())
{
if (attribute.version.IsResultingValue())
{
Append(", ");
Append(attribute.version.GetResultingValue());
}

Check warning on line 809 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L807-L809

Added lines #L807 - L809 were not covered by tests
else
attribute.version.GetExpression()->Visit(*this);

Check warning on line 811 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L811

Added line #L811 was not covered by tests
}

Append(")");
}

Check warning on line 815 in src/NZSL/LangWriter.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/LangWriter.cpp#L814-L815

Added lines #L814 - L815 were not covered by tests

void LangWriter::AppendComment(std::string_view section)
{
std::size_t lineFeed = section.find('\n');
Expand Down Expand Up @@ -1690,6 +1724,9 @@

void LangWriter::Visit(Ast::ScopedStatement& node)
{
AppendAttributes(true,
TargetAttribute{ node.targetType, node.targetVersion });

EnterScope();
node.statement->Visit(*this);
LeaveScope();
Expand Down
78 changes: 76 additions & 2 deletions src/NZSL/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
constexpr auto s_layoutMapping = BuildIdentifierMapping(LangData::s_memoryLayouts);
constexpr auto s_moduleFeatureMapping = BuildIdentifierMapping(LangData::s_moduleFeatures);
constexpr auto s_unrollModeMapping = BuildIdentifierMapping(LangData::s_unrollModes);
constexpr auto s_targetMapping = BuildIdentifierMapping(LangData::s_targets);
}

Ast::ModulePtr Parser::Parse(const std::vector<Token>& tokens)
Expand Down Expand Up @@ -177,6 +178,14 @@
return it->second.identifier;
}

std::string_view Parser::ToString(Ast::TargetType targetType)
{
auto it = LangData::s_targets.find(targetType);

Check warning on line 183 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L181-L183

Added lines #L181 - L183 were not covered by tests
assert(it != LangData::s_targets.end());

return it->second.identifier;
}

Check warning on line 187 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L186-L187

Added lines #L186 - L187 were not covered by tests

std::string_view Parser::ToString(ShaderStageType shaderStage)
{
auto it = LangData::s_entryPoints.find(shaderStage);
Expand Down Expand Up @@ -1294,6 +1303,13 @@
attributes.clear();
break;

case TokenType::OpenCurlyBracket:

Check warning on line 1306 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1306

Added line #L1306 was not covered by tests
if (attributes.empty())
throw ParserUnexpectedTokenError{ token.location, token.type };

statement = ParseStatement(std::move(attributes));
attributes.clear();
break;

Check warning on line 1312 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1311-L1312

Added lines #L1311 - L1312 were not covered by tests
default:
throw ParserUnexpectedTokenError{ token.location, token.type };
}
Expand All @@ -1303,14 +1319,72 @@
return statement;
}

Ast::StatementPtr Parser::ParseStatement()
Ast::StatementPtr Parser::ParseStatement(std::vector<Attribute> attributes)
{
NAZARA_USE_ANONYMOUS_NAMESPACE

if (Peek().type == TokenType::OpenCurlyBracket)
{
auto multiStatement = ShaderBuilder::MultiStatement();
multiStatement->statements = ParseStatementList(&multiStatement->sourceLocation);

return ShaderBuilder::Scoped(std::move(multiStatement));
auto scopedStatement = ShaderBuilder::Scoped(std::move(multiStatement));
for (auto&& attribute : attributes)
{
switch (attribute.type)
{
case Ast::AttributeType::Target:

Check warning on line 1336 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1336

Added line #L1336 was not covered by tests
{
if (scopedStatement->targetType.HasValue())
throw ParserAttributeMultipleUniqueError{ attribute.sourceLocation, attribute.type };

if (attribute.args.empty())
throw ParserAttributeUnexpectedParameterCountError{ attribute.sourceLocation, attribute.type, 1, attribute.args.size() };

const auto& targetTypeArg = attribute.args[0];

Check warning on line 1344 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1344

Added line #L1344 was not covered by tests

if (attribute.args[0]->GetType() != Ast::NodeType::IdentifierExpression)
throw ParserAttributeParameterIdentifierError{ targetTypeArg->sourceLocation, attribute.type };

Check warning on line 1347 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1347

Added line #L1347 was not covered by tests

bool hasExplicitTargetVersion = attribute.args.size() == 2;

Check warning on line 1349 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1349

Added line #L1349 was not covered by tests

auto targetTypeStr = static_cast<Ast::IdentifierExpression&>(*targetTypeArg).identifier;
auto it = s_targetMapping.find(targetTypeStr);
if (it == s_targetMapping.end())
throw ParserAttributeInvalidParameterError{ targetTypeArg->sourceLocation, targetTypeStr, attribute.type };

scopedStatement->targetType = it->second;

Check warning on line 1356 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1356

Added line #L1356 was not covered by tests

if (hasExplicitTargetVersion)
{
const auto& targetVersionArg = attribute.args[1];

Check warning on line 1360 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1360

Added line #L1360 was not covered by tests

if (targetVersionArg->GetType() != Ast::NodeType::ConstantValueExpression)
throw ParserAttributeParameterIdentifierError{ targetVersionArg->sourceLocation, attribute.type };

Check warning on line 1363 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1363

Added line #L1363 was not covered by tests

auto targetVersionValue = static_cast<Ast::ConstantValueExpression&>(*targetVersionArg).value;
if (std::holds_alternative<std::int32_t>(targetVersionValue))
{
auto targetVersion = std::get<std::int32_t>(targetVersionValue);
if (targetVersion < 0)
throw ParserAttributeInvalidTargetVersionError{ targetVersionArg->sourceLocation, targetVersion, targetTypeStr };

scopedStatement->targetVersion = Nz::SafeCast<std::uint32_t>(targetVersion);
}

Check warning on line 1373 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1372-L1373

Added lines #L1372 - L1373 were not covered by tests
else if (std::holds_alternative<std::uint32_t>(targetVersionValue))
scopedStatement->targetVersion = std::get<std::uint32_t>(targetVersionValue);
else
throw ParserAttributeInvalidTargetVersionError{ targetVersionArg->sourceLocation, 0, targetTypeStr };
}

Check warning on line 1378 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1378

Added line #L1378 was not covered by tests

break;
}
default:

Check warning on line 1382 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1380-L1382

Added lines #L1380 - L1382 were not covered by tests
throw ParserUnexpectedAttributeError{ attribute.sourceLocation, attribute.type, "scoped statement" };
}
}

Check warning on line 1385 in src/NZSL/Parser.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Parser.cpp#L1385

Added line #L1385 was not covered by tests

return scopedStatement;
}
else
return ParseSingleStatement();
Expand Down
13 changes: 13 additions & 0 deletions src/NZSL/SpirV/SpirvAstVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,19 @@

void SpirvAstVisitor::Visit(Ast::ScopedStatement& node)
{
if (node.targetType.IsResultingValue())
{
unsigned int spirvVersion = m_writer.m_environment.spvMajorVersion * 100 + m_writer.m_environment.spvMinorVersion * 10;
auto targetType = node.targetType.GetResultingValue();
std::uint32_t targetVersion = 0;

Check warning on line 1038 in src/NZSL/SpirV/SpirvAstVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/SpirV/SpirvAstVisitor.cpp#L1036-L1038

Added lines #L1036 - L1038 were not covered by tests
if (node.targetVersion.IsResultingValue())
targetVersion = node.targetVersion.GetResultingValue();

Check warning on line 1040 in src/NZSL/SpirV/SpirvAstVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/SpirV/SpirvAstVisitor.cpp#L1040

Added line #L1040 was not covered by tests

const auto isSPIRV = targetType == Ast::TargetType::SPIRV;

Check warning on line 1042 in src/NZSL/SpirV/SpirvAstVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/SpirV/SpirvAstVisitor.cpp#L1042

Added line #L1042 was not covered by tests
if (!(isSPIRV && targetVersion <= spirvVersion))
return;

Check warning on line 1044 in src/NZSL/SpirV/SpirvAstVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/SpirV/SpirvAstVisitor.cpp#L1044

Added line #L1044 was not covered by tests
}

node.statement->Visit(*this);
}

Expand Down
Loading