[spirv-reader] Handle UBO variable decorations

Bug: tint:1907
Change-Id: I82269354e32aa2f121e6165fea683871bfd23985
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/168681
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index a8f6a56..56a3d47 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -473,6 +473,32 @@
         if (inst.NumOperands() > 3) {
             var->SetInitializer(Value(inst.GetSingleWordOperand(3)));
         }
+
+        // Handle decorations.
+        std::optional<uint32_t> group;
+        std::optional<uint32_t> binding;
+        for (auto* deco :
+             spirv_context_->get_decoration_mgr()->GetDecorationsFor(inst.result_id(), false)) {
+            auto d = deco->GetSingleWordOperand(1);
+            switch (spv::Decoration(d)) {
+                case spv::Decoration::NonWritable:
+                    break;
+                case spv::Decoration::DescriptorSet:
+                    group = deco->GetSingleWordOperand(2);
+                    break;
+                case spv::Decoration::Binding:
+                    binding = deco->GetSingleWordOperand(2);
+                    break;
+                default:
+                    TINT_UNIMPLEMENTED() << "unhandled decoration " << d;
+                    break;
+            }
+        }
+        if (group || binding) {
+            TINT_ASSERT(group && binding);
+            var->SetBindingPoint(group.value(), binding.value());
+        }
+
         Emit(var, inst.result_id());
     }
 
diff --git a/src/tint/lang/spirv/reader/parser/var_test.cc b/src/tint/lang/spirv/reader/parser/var_test.cc
index 28d2a66..b2963dd 100644
--- a/src/tint/lang/spirv/reader/parser/var_test.cc
+++ b/src/tint/lang/spirv/reader/parser/var_test.cc
@@ -150,6 +150,9 @@
                OpExecutionMode %1 LocalSize 1 1 1
                OpDecorate %str Block
                OpMemberDecorate %str 0 Offset 0
+               OpDecorate %6 NonWritable
+               OpDecorate %6 DescriptorSet 1
+               OpDecorate %6 Binding 2
        %void = OpTypeVoid
        %uint = OpTypeInt 32 0
         %str = OpTypeStruct %uint
@@ -167,7 +170,7 @@
 }
 
 %b1 = block {  # root
-  %1:ptr<uniform, tint_symbol_1, read_write> = var
+  %1:ptr<uniform, tint_symbol_1, read_write> = var @binding_point(1, 2)
 }
 
 %main = @compute @workgroup_size(1, 1, 1) func():void -> %b2 {