writer/msl: Only use [[invariant]] on MSL 2.1+

This is not supported on older versions.
This behavior was agreed by the WGSL core group:
https://github.com/gpuweb/gpuweb/issues/893#issuecomment-745537465

Bug: tint:1327
Change-Id: I1a0459068c438e625ae9d99fe4a044a96f2db57e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/71684
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2021-12-03 21:58:53 +00:00 committed by Tint LUCI CQ
parent cc05d89820
commit 05eedd81b0
5 changed files with 44 additions and 8 deletions

View File

@ -240,6 +240,18 @@ bool GeneratorImpl::Generate() {
line(); line();
} }
if (!invariant_define_name_.empty()) {
// 'invariant' attribute requires MSL 2.1 or higher.
// WGSL can ignore the invariant attribute on pre MSL 2.1 devices.
// See: https://github.com/gpuweb/gpuweb/issues/893#issuecomment-745537465
line(&helpers_) << "#if __METAL_VERSION__ >= 210";
line(&helpers_) << "#define " << invariant_define_name_ << " [[invariant]]";
line(&helpers_) << "#else";
line(&helpers_) << "#define " << invariant_define_name_;
line(&helpers_) << "#endif";
line(&helpers_);
}
if (!helpers_.lines.empty()) { if (!helpers_.lines.empty()) {
current_buffer_->Insert("", helpers_insertion_point++, 0); current_buffer_->Insert("", helpers_insertion_point++, 0);
current_buffer_->Insert(helpers_, helpers_insertion_point++, 0); current_buffer_->Insert(helpers_, helpers_insertion_point++, 0);
@ -2504,8 +2516,10 @@ bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
} }
out << " [[" << attr << "]]"; out << " [[" << attr << "]]";
} else if (deco->Is<ast::InvariantDecoration>()) { } else if (deco->Is<ast::InvariantDecoration>()) {
out << " [[invariant]]"; if (invariant_define_name_.empty()) {
has_invariant_ = true; invariant_define_name_ = UniqueIdentifier("TINT_INVARIANT");
}
out << " " << invariant_define_name_;
} else if (!deco->IsAnyOf<ast::StructMemberOffsetDecoration, } else if (!deco->IsAnyOf<ast::StructMemberOffsetDecoration,
ast::StructMemberAlignDecoration, ast::StructMemberAlignDecoration,
ast::StructMemberSizeDecoration>()) { ast::StructMemberSizeDecoration>()) {

View File

@ -98,7 +98,7 @@ class GeneratorImpl : public TextGenerator {
bool Generate(); bool Generate();
/// @returns true if an invariant attribute was generated /// @returns true if an invariant attribute was generated
bool HasInvariant() { return has_invariant_; } bool HasInvariant() { return !invariant_define_name_.empty(); }
/// @returns a map from entry point to list of required workgroup allocations /// @returns a map from entry point to list of required workgroup allocations
const std::unordered_map<std::string, std::vector<uint32_t>>& const std::unordered_map<std::string, std::vector<uint32_t>>&
@ -410,8 +410,9 @@ class GeneratorImpl : public TextGenerator {
/// class. /// class.
StorageClassToString atomicCompareExchangeWeak_; StorageClassToString atomicCompareExchangeWeak_;
/// True if an invariant attribute has been generated. /// Unique name of the 'TINT_INVARIANT' preprocessor define. Non-empty only if
bool has_invariant_ = false; /// an invariant attribute has been generated.
std::string invariant_define_name_;
/// True if matrix-packed_vector operator overloads have been generated. /// True if matrix-packed_vector operator overloads have been generated.
bool matrix_packed_vector_overloads_ = false; bool matrix_packed_vector_overloads_ = false;

View File

@ -95,8 +95,15 @@ TEST_F(MslGeneratorImplTest, HasInvariantAttribute_True) {
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib> EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal; using namespace metal;
#if __METAL_VERSION__ >= 210
#define TINT_INVARIANT [[invariant]]
#else
#define TINT_INVARIANT
#endif
struct Out { struct Out {
float4 pos [[position]] [[invariant]]; float4 pos [[position]] TINT_INVARIANT;
}; };
vertex Out vert_main() { vertex Out vert_main() {

View File

@ -1,8 +1,15 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
#if __METAL_VERSION__ >= 210
#define TINT_INVARIANT [[invariant]]
#else
#define TINT_INVARIANT
#endif
struct tint_symbol_1 { struct tint_symbol_1 {
float4 value [[position]] [[invariant]]; float4 value [[position]] TINT_INVARIANT;
}; };
float4 tint_symbol_inner() { float4 tint_symbol_inner() {

View File

@ -1,11 +1,18 @@
#include <metal_stdlib> #include <metal_stdlib>
using namespace metal; using namespace metal;
#if __METAL_VERSION__ >= 210
#define TINT_INVARIANT [[invariant]]
#else
#define TINT_INVARIANT
#endif
struct Out { struct Out {
float4 pos; float4 pos;
}; };
struct tint_symbol_1 { struct tint_symbol_1 {
float4 pos [[position]] [[invariant]]; float4 pos [[position]] TINT_INVARIANT;
}; };
Out tint_symbol_inner() { Out tint_symbol_inner() {