[msl] Emit TINT_INVARIANT macro
Set the has_invariant_attribute field of the MSL writer result.
Bug: 42251016
Change-Id: If5e48a217b98e2d005f2933bcdd9ac82f89b4368
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196357
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 9d45b9b..3a232f5 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -1379,7 +1379,22 @@
}
if (attributes.invariant) {
- invariant_define_name_ = UniqueIdentifier("TINT_INVARIANT");
+ if (invariant_define_name_.empty()) {
+ invariant_define_name_ = UniqueIdentifier("TINT_INVARIANT");
+ result_.has_invariant_attribute = true;
+
+ // '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(&preamble_buffer_);
+ Line(&preamble_buffer_) << "#if __METAL_VERSION__ >= 210";
+ Line(&preamble_buffer_)
+ << "#define " << invariant_define_name_ << " [[invariant]]";
+ Line(&preamble_buffer_) << "#else";
+ Line(&preamble_buffer_) << "#define " << invariant_define_name_;
+ Line(&preamble_buffer_) << "#endif";
+ Line(&preamble_buffer_);
+ }
out << " " << invariant_define_name_;
}
diff --git a/src/tint/lang/msl/writer/printer/printer.h b/src/tint/lang/msl/writer/printer/printer.h
index bba5c8c..0448671 100644
--- a/src/tint/lang/msl/writer/printer/printer.h
+++ b/src/tint/lang/msl/writer/printer/printer.h
@@ -59,6 +59,9 @@
/// The generated MSL.
std::string msl = "";
+ /// `true` if an invariant attribute was generated.
+ bool has_invariant_attribute = false;
+
/// A map from entry point name to a list of dynamic workgroup allocations.
/// Each element of the vector is the size of the workgroup allocation that should be created
/// for that index.
diff --git a/src/tint/lang/msl/writer/writer.cc b/src/tint/lang/msl/writer/writer.cc
index e9ae23c..6d05098 100644
--- a/src/tint/lang/msl/writer/writer.cc
+++ b/src/tint/lang/msl/writer/writer.cc
@@ -61,7 +61,7 @@
output.msl = result->msl;
output.workgroup_allocations = std::move(result->workgroup_allocations);
output.needs_storage_buffer_sizes = raise_result->needs_storage_buffer_sizes;
- // TODO(crbug.com/42251016): Set has_invariant.
+ output.has_invariant_attribute = result->has_invariant_attribute;
// TODO(crbug.com/42251016): Set used_array_length_from_uniform_indices.
return output;
}
diff --git a/test/tint/types/functions/shader_io/invariant.wgsl.expected.ir.msl b/test/tint/types/functions/shader_io/invariant.wgsl.expected.ir.msl
index c9652ff..bc3ee97 100644
--- a/test/tint/types/functions/shader_io/invariant.wgsl.expected.ir.msl
+++ b/test/tint/types/functions/shader_io/invariant.wgsl.expected.ir.msl
@@ -1,8 +1,13 @@
-SKIP: FAILED
-
#include <metal_stdlib>
using namespace metal;
+#if __METAL_VERSION__ >= 210
+#define TINT_INVARIANT [[invariant]]
+#else
+#define TINT_INVARIANT
+#endif
+
+
struct tint_symbol_outputs {
float4 tint_symbol_1 [[position]] TINT_INVARIANT;
};
@@ -14,8 +19,3 @@
vertex tint_symbol_outputs tint_symbol() {
return tint_symbol_outputs{.tint_symbol_1=tint_symbol_inner()};
}
-program_source:5:36: error: expected ';' at end of declaration list
- float4 tint_symbol_1 [[position]] TINT_INVARIANT;
- ^
- ;
-
diff --git a/test/tint/types/functions/shader_io/invariant_struct_member.wgsl.expected.ir.msl b/test/tint/types/functions/shader_io/invariant_struct_member.wgsl.expected.ir.msl
index e7922f6..021eccc 100644
--- a/test/tint/types/functions/shader_io/invariant_struct_member.wgsl.expected.ir.msl
+++ b/test/tint/types/functions/shader_io/invariant_struct_member.wgsl.expected.ir.msl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#include <metal_stdlib>
using namespace metal;
@@ -7,6 +5,13 @@
float4 pos;
};
+#if __METAL_VERSION__ >= 210
+#define TINT_INVARIANT [[invariant]]
+#else
+#define TINT_INVARIANT
+#endif
+
+
struct tint_symbol_outputs {
float4 Out_pos [[position]] TINT_INVARIANT;
};
@@ -18,8 +23,3 @@
vertex tint_symbol_outputs tint_symbol() {
return tint_symbol_outputs{.Out_pos=tint_symbol_inner().pos};
}
-program_source:9:30: error: expected ';' at end of declaration list
- float4 Out_pos [[position]] TINT_INVARIANT;
- ^
- ;
-