Compat: Generate shader module error for rg formats as storage textures

The spec changed from this error at pipeline creation to
shader module creation

Change-Id: I2fb69eb6421976d60b5c697681d2f95694a9d607
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/195034
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Gregg Tavares <gman@chromium.org>
diff --git a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
index 0223370..16793d3 100644
--- a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
+++ b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
@@ -27,6 +27,8 @@
 
 #include <string>
 #include "src/tint/lang/core/number.h"
+#include "src/tint/lang/core/type/storage_texture.h"
+#include "src/tint/lang/core/type/texture_dimension.h"
 #include "src/tint/lang/wgsl/ast/expression.h"
 #include "src/tint/lang/wgsl/ast/type.h"
 #include "src/tint/lang/wgsl/common/validation_mode.h"
@@ -52,6 +54,47 @@
     }
 };
 
+template <typename T>
+class ResolverCompatibilityModeTestWithParam : public TestHelper, public testing::TestWithParam<T> {
+  protected:
+    ResolverCompatibilityModeTestWithParam() {
+        resolver_ = std::make_unique<Resolver>(this, wgsl::AllowedFeatures::Everything(),
+                                               wgsl::ValidationMode::kCompat);
+    }
+};
+
+using ResolverCompatibilityModeTest_StorageTexture = ResolverCompatibilityModeTestWithParam<
+    std::tuple<core::type::TextureDimension, core::TexelFormat>>;
+
+TEST_P(ResolverCompatibilityModeTest_StorageTexture, RGStorageTextures) {
+    // @group(2) @binding(1) var tex: texture_storage_xxx<formatxxx, read_write>
+    auto dim = std::get<0>(GetParam());
+    auto fmt = std::get<1>(GetParam());
+    auto t = ty.storage_texture(Source{{12, 34}}, dim, fmt, core::Access::kReadWrite);
+    GlobalVar("tex", t,
+              Vector{
+                  Group(2_a),
+                  Binding(1_a),
+              });
+
+    StringStream err;
+    err << "12:34 error: format " << fmt
+        << " is not supported as a storage texture in compatibility mode";
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(r()->error(), err.str());
+}
+
+INSTANTIATE_TEST_SUITE_P(ResolverCompatibilityModeTest,
+                         ResolverCompatibilityModeTest_StorageTexture,
+                         testing::Combine(testing::Values(core::type::TextureDimension::k1d,
+                                                          core::type::TextureDimension::k2d,
+                                                          core::type::TextureDimension::k2dArray,
+                                                          core::type::TextureDimension::k3d),
+                                          testing::Values(core::TexelFormat::kRg32Float,
+                                                          core::TexelFormat::kRg32Sint,
+                                                          core::TexelFormat::kRg32Uint)));
+
 TEST_F(ResolverCompatibilityModeTest, SampleMask_Parameter) {
     // @fragment
     // fn main(@builtin(sample_mask) mask : u32) {
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index d6bb9d9..d68f698 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -142,6 +142,17 @@
     }
 }
 
+bool IsInvalidStorageTextureTexelFormatInCompatibilityMode(core::TexelFormat format) {
+    switch (format) {
+        case core::TexelFormat::kRg32Float:
+        case core::TexelFormat::kRg32Sint:
+        case core::TexelFormat::kRg32Uint:
+            return true;
+        default:
+            return false;
+    }
+}
+
 template <typename CALLBACK>
 void TraverseCallChain(const sem::Function* from, const sem::Function* to, CALLBACK&& callback) {
     for (auto* f : from->TransitivelyCalledFunctions()) {
@@ -417,9 +428,17 @@
 
     if (!IsValidStorageTextureTexelFormat(t->texel_format())) {
         AddError(source) << "image format must be one of the texel formats specified for storage "
-                            "textues in https://gpuweb.github.io/gpuweb/wgsl/#texel-formats";
+                            "textures in https://gpuweb.github.io/gpuweb/wgsl/#texel-formats";
         return false;
     }
+
+    if (mode_ == wgsl::ValidationMode::kCompat &&
+        IsInvalidStorageTextureTexelFormatInCompatibilityMode(t->texel_format())) {
+        AddError(source) << "format " << t->texel_format()
+                         << " is not supported as a storage texture in compatibility mode";
+        return false;
+    }
+
     return true;
 }