[msl] Emit @index for blend_src attributes

Bug: 42251016
Change-Id: I04fddc5f98b280d9ec8a21e7087da29e8f34c9b1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/194996
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: James Price <jrprice@google.com>
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 2db5617..768ece5 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -1353,16 +1353,19 @@
                 }
 
                 if (pipeline_stage_uses.Contains(core::type::PipelineStageUsage::kVertexInput)) {
-                    out << " [[attribute(" + std::to_string(location.value()) + ")]]";
+                    out << " [[attribute(" << location.value() << ")]]";
                 } else if (pipeline_stage_uses.Contains(
                                core::type::PipelineStageUsage::kVertexOutput)) {
-                    out << " [[user(locn" + std::to_string(location.value()) + ")]]";
+                    out << " [[user(locn" << location.value() << ")]]";
                 } else if (pipeline_stage_uses.Contains(
                                core::type::PipelineStageUsage::kFragmentInput)) {
-                    out << " [[user(locn" + std::to_string(location.value()) + ")]]";
+                    out << " [[user(locn" << location.value() << ")]]";
                 } else if (TINT_LIKELY(pipeline_stage_uses.Contains(
                                core::type::PipelineStageUsage::kFragmentOutput))) {
-                    out << " [[color(" + std::to_string(location.value()) + ")]]";
+                    out << " [[color(" << location.value() << ")]]";
+                    if (auto blend_src = attributes.blend_src) {
+                        out << " [[index(" << blend_src.value() << ")]]";
+                    }
                 } else {
                     TINT_IR_ICE(ir_) << "invalid use of location decoration";
                 }
diff --git a/test/tint/bug/tint/1776.spvasm.expected.ir.msl b/test/tint/bug/tint/1776.spvasm.expected.ir.msl
index 1951f90..dfd67d0 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/1776.spvasm.expected.ir.msl
@@ -23,14 +23,14 @@
 };
 
 struct tint_module_vars_struct {
-  device sb_block* sb;
+  const device sb_block* sb;
 };
 
 void main_1(tint_module_vars_struct tint_module_vars) {
   S const x_18 = (*tint_module_vars.sb).inner[1];
 }
 
-kernel void tint_symbol(device sb_block* sb [[buffer(0)]]) {
+kernel void tint_symbol(const device sb_block* sb [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb};
   main_1(tint_module_vars);
 }
diff --git a/test/tint/extensions/dual_source_blending/input_output.wgsl.expected.ir.msl b/test/tint/extensions/dual_source_blending/input_output.wgsl.expected.ir.msl
index aec4537..966a1f7 100644
--- a/test/tint/extensions/dual_source_blending/input_output.wgsl.expected.ir.msl
+++ b/test/tint/extensions/dual_source_blending/input_output.wgsl.expected.ir.msl
@@ -1,33 +1,34 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-../../src/tint/lang/msl/writer/printer/printer.cc:1257 internal compiler error: FragOutput = struct @align(16) {
-  color:vec4<f32> @offset(0), @location(0)
-  blend:vec4<f32> @offset(16), @location(0)
+struct FragOutput {
+  float4 color;
+  float4 blend;
+};
+
+struct FragInput {
+  float4 a;
+  float4 b;
+};
+
+struct frag_main_outputs {
+  float4 FragOutput_color [[color(0)]] [[index(0)]];
+  float4 FragOutput_blend [[color(0)]] [[index(1)]];
+};
+
+struct frag_main_inputs {
+  float4 FragInput_a [[user(locn0)]];
+  float4 FragInput_b [[user(locn1)]];
+};
+
+FragOutput frag_main_inner(FragInput in) {
+  FragOutput output = {};
+  output.color = in.a;
+  output.blend = in.b;
+  return output;
 }
 
-FragInput = struct @align(16) {
-  a:vec4<f32> @offset(0), @location(0)
-  b:vec4<f32> @offset(16), @location(1)
+fragment frag_main_outputs frag_main(frag_main_inputs inputs [[stage_in]]) {
+  FragOutput const v = frag_main_inner(FragInput{.a=inputs.FragInput_a, .b=inputs.FragInput_b});
+  return frag_main_outputs{.FragOutput_color=v.color, .FragOutput_blend=v.blend};
 }
-
-%frag_main = @fragment func(%in:FragInput):FragOutput {
-  $B1: {
-    %output:ptr<function, FragOutput, read_write> = var
-    %4:ptr<function, vec4<f32>, read_write> = access %output, 0u
-    %5:vec4<f32> = access %in, 0u
-    store %4, %5
-    %6:ptr<function, vec4<f32>, read_write> = access %output, 1u
-    %7:vec4<f32> = access %in, 1u
-    store %6, %7
-    %8:FragOutput = load %output
-    ret %8
-  }
-}
-
-invalid entry point IO struct uses
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************
diff --git a/test/tint/extensions/dual_source_blending/output.wgsl.expected.ir.msl b/test/tint/extensions/dual_source_blending/output.wgsl.expected.ir.msl
index fbf0e25..9b4a86b 100644
--- a/test/tint/extensions/dual_source_blending/output.wgsl.expected.ir.msl
+++ b/test/tint/extensions/dual_source_blending/output.wgsl.expected.ir.msl
@@ -1,26 +1,24 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
 
-../../src/tint/lang/msl/writer/printer/printer.cc:1257 internal compiler error: FragOutput = struct @align(16) {
-  color:vec4<f32> @offset(0), @location(0)
-  blend:vec4<f32> @offset(16), @location(0)
+struct FragOutput {
+  float4 color;
+  float4 blend;
+};
+
+struct frag_main_outputs {
+  float4 FragOutput_color [[color(0)]] [[index(0)]];
+  float4 FragOutput_blend [[color(0)]] [[index(1)]];
+};
+
+FragOutput frag_main_inner() {
+  FragOutput output = {};
+  output.color = float4(0.5f, 0.5f, 0.5f, 1.0f);
+  output.blend = float4(0.5f, 0.5f, 0.5f, 1.0f);
+  return output;
 }
 
-%frag_main = @fragment func():FragOutput {
-  $B1: {
-    %output:ptr<function, FragOutput, read_write> = var
-    %3:ptr<function, vec4<f32>, read_write> = access %output, 0u
-    store %3, vec4<f32>(0.5f, 0.5f, 0.5f, 1.0f)
-    %4:ptr<function, vec4<f32>, read_write> = access %output, 1u
-    store %4, vec4<f32>(0.5f, 0.5f, 0.5f, 1.0f)
-    %5:FragOutput = load %output
-    ret %5
-  }
+fragment frag_main_outputs frag_main() {
+  FragOutput const v = frag_main_inner();
+  return frag_main_outputs{.FragOutput_color=v.color, .FragOutput_blend=v.blend};
 }
-
-invalid entry point IO struct uses
-********************************************************************
-*  The tint shader compiler has encountered an unexpected error.   *
-*                                                                  *
-*  Please help us fix this issue by submitting a bug report at     *
-*  crbug.com/tint with the source program that triggered the bug.  *
-********************************************************************