[msl] Emit binding point attributes on parameters

Bug: 42251016
Change-Id: I00232294d753b80b1656b4e7ea5845677c3f48a0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/188343
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/msl/writer/printer/function_test.cc b/src/tint/lang/msl/writer/printer/function_test.cc
index 42956a6..0513a48 100644
--- a/src/tint/lang/msl/writer/printer/function_test.cc
+++ b/src/tint/lang/msl/writer/printer/function_test.cc
@@ -41,5 +41,21 @@
 )");
 }
 
+TEST_F(MslPrinterTest, EntryPointParameterBindingPoint) {
+    auto* func = b.Function("foo", ty.void_(), core::ir::Function::PipelineStage::kFragment);
+    auto* storage = b.FunctionParam("storage", ty.ptr(core::AddressSpace::kStorage, ty.i32()));
+    auto* uniform = b.FunctionParam("uniform", ty.ptr(core::AddressSpace::kUniform, ty.i32()));
+    storage->SetBindingPoint(0, 1);
+    uniform->SetBindingPoint(0, 2);
+    func->SetParams({storage, uniform});
+    func->Block()->Append(b.Return(func));
+
+    ASSERT_TRUE(Generate()) << err_ << output_;
+    EXPECT_EQ(output_, MetalHeader() + R"(
+fragment void foo(device int* storage [[buffer(1)]], const constant int* uniform [[buffer(2)]]) {
+}
+)");
+}
+
 }  // namespace
 }  // namespace tint::msl::writer
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 40ffcdf..5b46f4b 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -304,6 +304,20 @@
                     }
                     out << "]]";
                 }
+
+                if (auto binding_point = param->BindingPoint()) {
+                    auto ptr = param->Type()->As<core::type::Pointer>();
+                    TINT_ASSERT(binding_point->group == 0);
+                    switch (ptr->AddressSpace()) {
+                        case core::AddressSpace::kStorage:
+                        case core::AddressSpace::kUniform:
+                            out << " [[buffer(" << binding_point->binding << ")]]";
+                            break;
+                        default:
+                            TINT_UNREACHABLE() << "invalid address space with binding point: "
+                                               << ptr->AddressSpace();
+                    }
+                }
             }
 
             out << ") {";