[spirv-reader] Add requires for RW textures

Not strictly necessary, but signals intent more clearly in the
generated WGSL shaders.

Bug: tint:2088
Change-Id: I201ea48ffb3d6f754147aab646d1c418c7226366
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/159100
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
index 0bf7f61..9370817 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
@@ -2583,6 +2583,9 @@
         } else {
             const auto access =
                 usage.IsStorageReadWriteTexture() ? core::Access::kReadWrite : core::Access::kWrite;
+            if (access == core::Access::kReadWrite) {
+                Require(wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
+            }
             const auto format = enum_converter_.ToTexelFormat(image_type->format());
             if (format == core::TexelFormat::kUndefined) {
                 return nullptr;
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.h b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
index 59d3c02..ddd8ded1 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
@@ -759,6 +759,14 @@
         }
     }
 
+    /// Require a WGSL language feature, if not already required.
+    /// @param feature the language feature to require
+    void Require(wgsl::LanguageFeature feature) {
+        if (required_features_.Add(feature)) {
+            builder_.Require(feature);
+        }
+    }
+
   private:
     /// Converts a specific SPIR-V type to a Tint type. Integer case
     const Type* ConvertType(const spvtools::opt::analysis::Integer* int_ty);
@@ -948,6 +956,8 @@
 
     /// Set of WGSL extensions that have been enabled.
     Hashset<wgsl::Extension, 4> enabled_extensions_;
+    /// Set of WGSL language features that have been required.
+    Hashset<wgsl::LanguageFeature, 4> required_features_;
 };
 
 }  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function.cc b/src/tint/lang/spirv/reader/ast_parser/function.cc
index 198f58f..2ba5673 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function.cc
@@ -5325,6 +5325,7 @@
         if (memory != uint32_t(spv::Scope::Workgroup)) {
             return Fail() << "textureBarrier requires workgroup memory scope";
         }
+        parser_impl_.Require(wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
         AddStatement(builder_.CallStmt(builder_.Call("textureBarrier")));
         semantics &= ~static_cast<uint32_t>(spv::MemorySemanticsMask::ImageMemory);
     }
diff --git a/src/tint/lang/spirv/reader/ast_parser/handle_test.cc b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
index 154ccc2..dd05ded 100644
--- a/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
@@ -4234,7 +4234,9 @@
     EXPECT_TRUE(p->error().empty()) << p->error();
     const auto got = test::ToString(p->program());
     auto* expect =
-        R"(@group(0) @binding(0) var RWTexture2D : texture_storage_2d<rgba32float, read_write>;
+        R"(requires readonly_and_readwrite_storage_textures;
+
+@group(0) @binding(0) var RWTexture2D : texture_storage_2d<rgba32float, read_write>;
 
 const x_9 = vec2u(1u);