Compat: Switch interpolate params to pipeline errors

This turned into a bigger CL because the it removes the last
need for ValidationMode which causes an error that mode_ in
Validator was unused.

Fixed: 357042303,357047899
Bug: 357042303,357047899
Change-Id: I87812d183a054a7869d04bc281cb9ea75b637976
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/201434
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Gregg Tavares <gman@chromium.org>
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index 4361878..0f95190 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -812,6 +812,29 @@
             "different from the interpolation sampling (%s) of the fragment input at "
             "location %u.",
             vertexOutputInfo.interpolationSampling, i, fragmentInputInfo.interpolationSampling, i);
+
+        if (device->IsCompatibilityMode()) {
+            DAWN_INVALID_IF(
+                vertexOutputInfo.interpolationType == InterpolationType::Linear,
+                "The interpolation type (%s) of the vertex output at location %u is not "
+                "supported in compatibility mode",
+                vertexOutputInfo.interpolationType, i);
+
+            DAWN_INVALID_IF(
+                vertexOutputInfo.interpolationSampling == InterpolationSampling::Sample ||
+                    vertexOutputInfo.interpolationSampling == InterpolationSampling::First,
+                "The interpolation sampling (%s) of the vertex output at location %u is "
+                "not supported in compatibility mode",
+                vertexOutputInfo.interpolationSampling, i);
+
+            DAWN_INVALID_IF(
+                vertexOutputInfo.interpolationType == InterpolationType::Flat &&
+                    vertexOutputInfo.interpolationSampling == InterpolationSampling::None,
+                "The interpolation sampling (%s) of the vertex output at location %u when "
+                "interpolation type is (%s)"
+                "not supported in compatibility mode",
+                vertexOutputInfo.interpolationSampling, i, vertexOutputInfo.interpolationType);
+        }
     }
 
     return {};
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 31b7331..d7763f1 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -352,11 +352,9 @@
 
 ResultOrError<tint::Program> ParseWGSL(const tint::Source::File* file,
                                        const tint::wgsl::AllowedFeatures& allowedFeatures,
-                                       const tint::wgsl::ValidationMode mode,
                                        const std::vector<tint::wgsl::Extension>& internalExtensions,
                                        OwnedCompilationMessages* outMessages) {
     tint::wgsl::reader::Options options;
-    options.mode = mode;
     options.allowed_features = allowedFeatures;
     options.allowed_features.extensions.insert(internalExtensions.begin(),
                                                internalExtensions.end());
@@ -1204,10 +1202,8 @@
     }
 
     tint::Program program;
-    auto validationMode = device->IsCompatibilityMode() ? tint::wgsl::ValidationMode::kCompat
-                                                        : tint::wgsl::ValidationMode::kFull;
     DAWN_TRY_ASSIGN(program, ParseWGSL(tintFile.get(), device->GetWGSLAllowedFeatures(),
-                                       validationMode, internalExtensions, outMessages));
+                                       internalExtensions, outMessages));
 
     parseResult->tintProgram = AcquireRef(new TintProgram(std::move(program), std::move(tintFile)));
 
diff --git a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
index f33574a..c0efc2e 100644
--- a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
@@ -367,15 +367,44 @@
                 v.color = vec4f(1);
                 return v;
             }
+            @fragment fn fsWithoutBadInterpolationUsage() -> @location(0) vec4f {
+                return vec4f(1);
+            }
+            @fragment fn fsWithBadInterpolationUsage1(v: Vertex) -> @location(0) vec4f {
+                return vec4f(1);
+            }
+            @fragment fn fsWithBadInterpolationUsage2(v: Vertex) -> @location(0) vec4f {
+                return v.pos;
+            }
+            @fragment fn fsWithBadInterpolationUsage3(v: Vertex) -> @location(0) vec4f {
+                return v.color;
+            }
         )",
                                     interpolateParam);
-        if (strcmp(interpolateParam, "perspective") == 0) {
-            wgpu::ShaderModule moduleInterpolationLinear =
-                utils::CreateShaderModule(device, wgsl.c_str());
-        } else {
-            ASSERT_DEVICE_ERROR(wgpu::ShaderModule moduleInterpolationLinear =
-                                    utils::CreateShaderModule(device, wgsl.c_str()),
-                                testing::HasSubstr("in compatibility mode"));
+        wgpu::ShaderModule moduleInterpolationLinear =
+            utils::CreateShaderModule(device, wgsl.c_str());
+
+        static const char* entryPoints[] = {
+            "fsWithoutBadInterpolationUsage",
+            "fsWithBadInterpolationUsage1",
+            "fsWithBadInterpolationUsage2",
+            "fsWithBadInterpolationUsage3",
+        };
+        for (auto entryPoint : entryPoints) {
+            utils::ComboRenderPipelineDescriptor descriptor;
+            descriptor.vertex.module = moduleInterpolationLinear;
+            descriptor.cFragment.module = moduleInterpolationLinear;
+            descriptor.cFragment.entryPoint = entryPoint;
+
+            bool shouldSucceed =
+                entryPoint == entryPoints[0] || interpolateParam == interpolateParams[0];
+
+            if (shouldSucceed) {
+                device.CreateRenderPipeline(&descriptor);
+            } else {
+                ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor),
+                                    testing::HasSubstr("in compatibility mode"));
+            }
         }
     }
 }
diff --git a/src/tint/cmd/common/helper.cc b/src/tint/cmd/common/helper.cc
index 7c2a994..b0bffcd 100644
--- a/src/tint/cmd/common/helper.cc
+++ b/src/tint/cmd/common/helper.cc
@@ -190,7 +190,6 @@
 
                 tint::wgsl::reader::Options options;
                 options.allowed_features = tint::wgsl::AllowedFeatures::Everything();
-                options.mode = opts.mode;
 
                 auto file = std::make_unique<tint::Source::File>(
                     opts.filename, std::string(data.begin(), data.end()));
diff --git a/src/tint/cmd/common/helper.h b/src/tint/cmd/common/helper.h
index aaa068a..24327a9 100644
--- a/src/tint/cmd/common/helper.h
+++ b/src/tint/cmd/common/helper.h
@@ -33,7 +33,6 @@
 #include <string>
 #include <vector>
 
-#include "src/tint/lang/wgsl/common/validation_mode.h"
 #include "src/tint/lang/wgsl/inspector/inspector.h"
 #include "src/tint/utils/diagnostic/source.h"
 
@@ -78,8 +77,6 @@
 struct LoadProgramOptions {
     /// The file to be loaded
     std::string filename;
-    /// The WGSL validation mode to use.
-    tint::wgsl::ValidationMode mode = tint::wgsl::ValidationMode::kFull;
 #if TINT_BUILD_SPV_READER
     /// Spirv-reader options
     bool use_ir = false;
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index 66ba645..5831787 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -49,7 +49,6 @@
 #include "src/tint/lang/wgsl/ast/transform/renamer.h"
 #include "src/tint/lang/wgsl/ast/transform/single_entry_point.h"
 #include "src/tint/lang/wgsl/ast/transform/substitute_override.h"
-#include "src/tint/lang/wgsl/common/validation_mode.h"
 #include "src/tint/lang/wgsl/helpers/flatten_bindings.h"
 #include "src/tint/utils/cli/cli.h"
 #include "src/tint/utils/command/command.h"
@@ -181,7 +180,6 @@
     bool parse_only = false;
     bool disable_workgroup_init = false;
     bool validate = false;
-    bool compatibility_mode = false;
     bool print_hash = false;
     bool dump_inspector_bindings = false;
     bool enable_robustness = false;
@@ -362,11 +360,6 @@
         options.Add<BoolOption>("parse-only", "Stop after parsing the input", Default{false});
     TINT_DEFER(opts->parse_only = *parse_only.value);
 
-    auto& compatibility_mode = options.Add<BoolOption>(
-        "compatibility-mode", "Validate WGSL input using \"compatibility mode\"",
-        ShortName{"compat"}, Default{false});
-    TINT_DEFER(opts->compatibility_mode = *compatibility_mode.value);
-
 #if TINT_BUILD_SPV_READER
     auto& allow_nud =
         options.Add<BoolOption>("allow-non-uniform-derivatives",
@@ -1310,8 +1303,6 @@
 
     tint::cmd::LoadProgramOptions opts;
     opts.filename = options.input_filename;
-    opts.mode = options.compatibility_mode ? tint::wgsl::ValidationMode::kCompat
-                                           : tint::wgsl::ValidationMode::kFull;
     opts.printer = options.printer.get();
 #if TINT_BUILD_SPV_READER
     opts.use_ir = options.use_ir_reader;
diff --git a/src/tint/lang/wgsl/common/BUILD.bazel b/src/tint/lang/wgsl/common/BUILD.bazel
index fa2d40b..d8dc1a3 100644
--- a/src/tint/lang/wgsl/common/BUILD.bazel
+++ b/src/tint/lang/wgsl/common/BUILD.bazel
@@ -43,7 +43,6 @@
   ],
   hdrs = [
     "allowed_features.h",
-    "validation_mode.h",
   ],
   deps = [
     "//src/tint/lang/wgsl",
diff --git a/src/tint/lang/wgsl/common/BUILD.cmake b/src/tint/lang/wgsl/common/BUILD.cmake
index 9da9eb1..78917ad 100644
--- a/src/tint/lang/wgsl/common/BUILD.cmake
+++ b/src/tint/lang/wgsl/common/BUILD.cmake
@@ -41,7 +41,6 @@
 tint_add_target(tint_lang_wgsl_common lib
   lang/wgsl/common/allowed_features.h
   lang/wgsl/common/common.cc
-  lang/wgsl/common/validation_mode.h
 )
 
 tint_target_add_dependencies(tint_lang_wgsl_common lib
diff --git a/src/tint/lang/wgsl/common/BUILD.gn b/src/tint/lang/wgsl/common/BUILD.gn
index 55accf8..7cdd3d1 100644
--- a/src/tint/lang/wgsl/common/BUILD.gn
+++ b/src/tint/lang/wgsl/common/BUILD.gn
@@ -47,7 +47,6 @@
   sources = [
     "allowed_features.h",
     "common.cc",
-    "validation_mode.h",
   ]
   deps = [
     "${dawn_root}/src/utils:utils",
diff --git a/src/tint/lang/wgsl/common/validation_mode.h b/src/tint/lang/wgsl/common/validation_mode.h
deleted file mode 100644
index b08b6ae..0000000
--- a/src/tint/lang/wgsl/common/validation_mode.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2024 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-//    contributors may be used to endorse or promote products derived from
-//    this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef SRC_TINT_LANG_WGSL_COMMON_VALIDATION_MODE_H_
-#define SRC_TINT_LANG_WGSL_COMMON_VALIDATION_MODE_H_
-
-#include <cstdint>
-
-namespace tint::wgsl {
-
-/// The validation mode to use for WGSL validation.
-enum class ValidationMode : uint8_t {
-    // Validate against the full WebGPU standard.
-    kFull,
-    // Validate against WebGPU's "compatibility mode".
-    kCompat,
-};
-
-}  // namespace tint::wgsl
-
-#endif  // SRC_TINT_LANG_WGSL_COMMON_VALIDATION_MODE_H_
diff --git a/src/tint/lang/wgsl/reader/options.h b/src/tint/lang/wgsl/reader/options.h
index 04399cf..bf2208f 100644
--- a/src/tint/lang/wgsl/reader/options.h
+++ b/src/tint/lang/wgsl/reader/options.h
@@ -29,7 +29,6 @@
 #define SRC_TINT_LANG_WGSL_READER_OPTIONS_H_
 
 #include "src/tint/lang/wgsl/common/allowed_features.h"
-#include "src/tint/lang/wgsl/common/validation_mode.h"
 #include "src/tint/utils/reflection/reflection.h"
 
 namespace tint::wgsl::reader {
@@ -39,11 +38,8 @@
     /// The extensions and language features that are allowed to be used.
     AllowedFeatures allowed_features{};
 
-    /// The validation mode to use.
-    ValidationMode mode = ValidationMode::kFull;
-
     /// Reflect the fields of this class so that it can be used by tint::ForeachField().
-    TINT_REFLECT(Options, allowed_features, mode);
+    TINT_REFLECT(Options, allowed_features);
 };
 
 }  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/reader.cc b/src/tint/lang/wgsl/reader/reader.cc
index 186e1b6..ac8d967 100644
--- a/src/tint/lang/wgsl/reader/reader.cc
+++ b/src/tint/lang/wgsl/reader/reader.cc
@@ -46,7 +46,7 @@
     }
     Parser parser(file);
     parser.Parse();
-    return resolver::Resolve(parser.builder(), options.allowed_features, options.mode);
+    return resolver::Resolve(parser.builder(), options.allowed_features);
 }
 
 Result<core::ir::Module> WgslToIR(const Source::File* file, const Options& options) {
diff --git a/src/tint/lang/wgsl/resolver/BUILD.bazel b/src/tint/lang/wgsl/resolver/BUILD.bazel
index adcd99e..34d00b8 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.bazel
+++ b/src/tint/lang/wgsl/resolver/BUILD.bazel
@@ -110,7 +110,6 @@
     "call_test.cc",
     "call_validation_test.cc",
     "clip_distances_extension_test.cc",
-    "compatibility_mode_test.cc",
     "compound_assignment_validation_test.cc",
     "compound_statement_test.cc",
     "const_assert_test.cc",
diff --git a/src/tint/lang/wgsl/resolver/BUILD.cmake b/src/tint/lang/wgsl/resolver/BUILD.cmake
index b471d61..82dfdf4 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.cmake
+++ b/src/tint/lang/wgsl/resolver/BUILD.cmake
@@ -111,7 +111,6 @@
   lang/wgsl/resolver/call_test.cc
   lang/wgsl/resolver/call_validation_test.cc
   lang/wgsl/resolver/clip_distances_extension_test.cc
-  lang/wgsl/resolver/compatibility_mode_test.cc
   lang/wgsl/resolver/compound_assignment_validation_test.cc
   lang/wgsl/resolver/compound_statement_test.cc
   lang/wgsl/resolver/const_assert_test.cc
diff --git a/src/tint/lang/wgsl/resolver/BUILD.gn b/src/tint/lang/wgsl/resolver/BUILD.gn
index 4ffdff0..28096ea 100644
--- a/src/tint/lang/wgsl/resolver/BUILD.gn
+++ b/src/tint/lang/wgsl/resolver/BUILD.gn
@@ -111,7 +111,6 @@
       "call_test.cc",
       "call_validation_test.cc",
       "clip_distances_extension_test.cc",
-      "compatibility_mode_test.cc",
       "compound_assignment_validation_test.cc",
       "compound_statement_test.cc",
       "const_assert_test.cc",
diff --git a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
deleted file mode 100644
index 34ed0fe..0000000
--- a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2024 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-//    contributors may be used to endorse or promote products derived from
-//    this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#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"
-#include "src/tint/lang/wgsl/resolver/resolver.h"
-#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
-#include "src/tint/utils/text/string.h"
-
-#include "gmock/gmock.h"
-
-namespace tint::resolver {
-namespace {
-
-using namespace tint::core::fluent_types;     // NOLINT
-using namespace tint::core::number_suffixes;  // NOLINT
-
-using ExpressionList = Vector<const ast::Expression*, 8>;
-
-class ResolverCompatibilityModeTest : public ResolverTest {
-  protected:
-    ResolverCompatibilityModeTest() {
-        resolver_ = std::make_unique<Resolver>(this, wgsl::AllowedFeatures::Everything(),
-                                               wgsl::ValidationMode::kCompat);
-    }
-};
-
-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);
-    }
-};
-
-TEST_F(ResolverCompatibilityModeTest, LinearInterpolation_Parameter) {
-    // @fragment
-    // fn main(@location(1) @interpolate(linear) value : f32) {
-    // }
-
-    Func("main",
-         Vector{Param("value", ty.f32(),
-                      Vector{
-                          Location(1_i),
-                          Interpolate(Source{{12, 34}}, core::InterpolationType::kLinear,
-                                      core::InterpolationSampling::kCenter),
-                      })},
-         ty.void_(), Empty,
-         Vector{
-             Stage(ast::PipelineStage::kFragment),
-         },
-         Vector{
-             Builtin(core::BuiltinValue::kPosition),
-         });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(),
-              R"(12:34 error: use of '@interpolate(linear)' is not allowed in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, LinearInterpolation_StructMember) {
-    // struct S {
-    //   @location(1) @interpolate(linear) value : f32,
-    // }
-
-    Structure("S", Vector{
-                       Member("value", ty.f32(),
-                              Vector{
-                                  Location(1_i),
-                                  Interpolate(Source{{12, 34}}, core::InterpolationType::kLinear,
-                                              core::InterpolationSampling::kCenter),
-                              }),
-                   });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(r()->error(),
-              R"(12:34 error: use of '@interpolate(linear)' is not allowed in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, SampleInterpolation_Parameter) {
-    // @fragment
-    // fn main(@location(1) @interpolate(perspective, sample) value : f32) {
-    // }
-
-    Func("main",
-         Vector{Param("value", ty.f32(),
-                      Vector{
-                          Location(1_i),
-                          Interpolate(Source{{12, 34}}, core::InterpolationType::kPerspective,
-                                      core::InterpolationSampling::kSample),
-                      })},
-         ty.void_(), Empty,
-         Vector{
-             Stage(ast::PipelineStage::kFragment),
-         },
-         Vector{
-             Builtin(core::BuiltinValue::kPosition),
-         });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: use of '@interpolate(..., sample)' is not allowed in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, SampleInterpolation_StructMember) {
-    // struct S {
-    //   @location(1) @interpolate(perspective, sample) value : f32,
-    // }
-
-    Structure("S",
-              Vector{
-                  Member("value", ty.f32(),
-                         Vector{
-                             Location(1_i),
-                             Interpolate(Source{{12, 34}}, core::InterpolationType::kPerspective,
-                                         core::InterpolationSampling::kSample),
-                         }),
-              });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: use of '@interpolate(..., sample)' is not allowed in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, FirstInterpolation_Parameter) {
-    // @fragment
-    // fn main(@location(1) @interpolate(flat, first) value : f32) {
-    // }
-
-    Func("main",
-         Vector{Param("value", ty.f32(),
-                      Vector{
-                          Location(1_i),
-                          Interpolate(Source{{12, 34}}, core::InterpolationType::kFlat,
-                                      core::InterpolationSampling::kFirst),
-                      })},
-         ty.void_(), Empty,
-         Vector{
-             Stage(ast::PipelineStage::kFragment),
-         },
-         Vector{
-             Builtin(core::BuiltinValue::kPosition),
-         });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: flat interpolation must use 'either' sampling parameter in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, FirstInterpolation_StructMember) {
-    // struct S {
-    //   @location(1) @interpolate(flat, first) value : f32,
-    // }
-
-    Structure("S", Vector{
-                       Member("value", ty.f32(),
-                              Vector{
-                                  Location(1_i),
-                                  Interpolate(Source{{12, 34}}, core::InterpolationType::kFlat,
-                                              core::InterpolationSampling::kFirst),
-                              }),
-                   });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: flat interpolation must use 'either' sampling parameter in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, FlatNoneInterpolation_Parameter) {
-    // @fragment
-    // fn main(@location(1) @interpolate(flat) value : f32) {
-    // }
-
-    Func("main",
-         Vector{Param("value", ty.f32(),
-                      Vector{
-                          Location(1_i),
-                          Interpolate(Source{{12, 34}}, core::InterpolationType::kFlat,
-                                      core::InterpolationSampling::kUndefined),
-                      })},
-         ty.void_(), Empty,
-         Vector{
-             Stage(ast::PipelineStage::kFragment),
-         },
-         Vector{
-             Builtin(core::BuiltinValue::kPosition),
-         });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: flat interpolation must use 'either' sampling parameter in compatibility mode)");
-}
-
-TEST_F(ResolverCompatibilityModeTest, FlatNoneInterpolation_StructMember) {
-    // struct S {
-    //   @location(1) @interpolate(flat) value : f32,
-    // }
-
-    Structure("S", Vector{
-                       Member("value", ty.f32(),
-                              Vector{
-                                  Location(1_i),
-                                  Interpolate(Source{{12, 34}}, core::InterpolationType::kFlat,
-                                              core::InterpolationSampling::kUndefined),
-                              }),
-                   });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: flat interpolation must use 'either' sampling parameter in compatibility mode)");
-}
-
-}  // namespace
-}  // namespace tint::resolver
diff --git a/src/tint/lang/wgsl/resolver/resolve.cc b/src/tint/lang/wgsl/resolver/resolve.cc
index d9db3e8..3765013 100644
--- a/src/tint/lang/wgsl/resolver/resolve.cc
+++ b/src/tint/lang/wgsl/resolver/resolve.cc
@@ -33,10 +33,8 @@
 
 namespace tint::resolver {
 
-Program Resolve(ProgramBuilder& builder,
-                const wgsl::AllowedFeatures& allowed_features,
-                wgsl::ValidationMode mode) {
-    Resolver resolver(&builder, std::move(allowed_features), mode);
+Program Resolve(ProgramBuilder& builder, const wgsl::AllowedFeatures& allowed_features) {
+    Resolver resolver(&builder, std::move(allowed_features));
     resolver.Resolve();
     return Program(std::move(builder));
 }
diff --git a/src/tint/lang/wgsl/resolver/resolve.h b/src/tint/lang/wgsl/resolver/resolve.h
index 7c958e1..3e73d80 100644
--- a/src/tint/lang/wgsl/resolver/resolve.h
+++ b/src/tint/lang/wgsl/resolver/resolve.h
@@ -29,7 +29,6 @@
 #define SRC_TINT_LANG_WGSL_RESOLVER_RESOLVE_H_
 
 #include "src/tint/lang/wgsl/common/allowed_features.h"
-#include "src/tint/lang/wgsl/common/validation_mode.h"
 
 namespace tint {
 class Program;
@@ -40,11 +39,10 @@
 
 /// Performs semantic analysis and validation on the program builder @p builder
 /// @param allowed_features the extensions and features that are allowed to be used
-/// @param mode the validation mode to uses
 /// @returns the resolved Program. Program.Diagnostics() may contain validation errors.
-Program Resolve(ProgramBuilder& builder,
-                const wgsl::AllowedFeatures& allowed_features = wgsl::AllowedFeatures::Everything(),
-                wgsl::ValidationMode mode = wgsl::ValidationMode::kFull);
+Program Resolve(
+    ProgramBuilder& builder,
+    const wgsl::AllowedFeatures& allowed_features = wgsl::AllowedFeatures::Everything());
 
 }  // namespace tint::resolver
 
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 8fcc5ca..8e4b9b3 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -133,9 +133,7 @@
 
 }  // namespace
 
-Resolver::Resolver(ProgramBuilder* builder,
-                   const wgsl::AllowedFeatures& allowed_features,
-                   wgsl::ValidationMode mode)
+Resolver::Resolver(ProgramBuilder* builder, const wgsl::AllowedFeatures& allowed_features)
     : b(*builder),
       diagnostics_(builder->Diagnostics()),
       const_eval_(builder->constants, diagnostics_),
@@ -145,7 +143,6 @@
                  sem_,
                  enabled_extensions_,
                  allowed_features_,
-                 mode,
                  atomic_composite_info_,
                  valid_type_storage_layouts_),
       allowed_features_(allowed_features) {}
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index 6c47d06..9861931 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -42,7 +42,6 @@
 #include "src/tint/lang/core/intrinsic/table.h"
 #include "src/tint/lang/core/type/input_attachment.h"
 #include "src/tint/lang/wgsl/common/allowed_features.h"
-#include "src/tint/lang/wgsl/common/validation_mode.h"
 #include "src/tint/lang/wgsl/intrinsic/dialect.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
 #include "src/tint/lang/wgsl/resolver/dependency_graph.h"
@@ -101,10 +100,7 @@
     /// Constructor
     /// @param builder the program builder
     /// @param allowed_features the extensions and features that are allowed to be used
-    /// @param mode the validation mode to use
-    Resolver(ProgramBuilder* builder,
-             const wgsl::AllowedFeatures& allowed_features,
-             wgsl::ValidationMode mode = wgsl::ValidationMode::kFull);
+    Resolver(ProgramBuilder* builder, const wgsl::AllowedFeatures& allowed_features);
 
     /// Destructor
     ~Resolver();
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index 6ec74c9..dda482a 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -164,7 +164,6 @@
     SemHelper& sem,
     const wgsl::Extensions& enabled_extensions,
     const wgsl::AllowedFeatures& allowed_features,
-    const wgsl::ValidationMode mode,
     const Hashmap<const core::type::Type*, const Source*, 8>& atomic_composite_info,
     Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts)
     : symbols_(builder->Symbols()),
@@ -172,7 +171,6 @@
       sem_(sem),
       enabled_extensions_(enabled_extensions),
       allowed_features_(allowed_features),
-      mode_(mode),
       atomic_composite_info_(atomic_composite_info),
       valid_type_storage_layouts_(valid_type_storage_layouts) {
     // Set default severities for filterable diagnostic rules.
@@ -1161,38 +1159,13 @@
                     << "flat interpolation can only use 'first' and 'either' sampling parameters";
                 return false;
             }
-            if (mode_ == wgsl::ValidationMode::kCompat &&
-                i_sampling == core::InterpolationSampling::kFirst) {
-                AddError(attr->source) << "flat interpolation must use 'either' sampling parameter "
-                                          "in compatibility mode";
-                return false;
-            }
         } else {
             if (is_first_or_either) {
                 AddError(attr->source) << "'first' and 'either' sampling parameters can only be "
                                           "used with flat interpolation";
                 return false;
             }
-
-            if (mode_ == wgsl::ValidationMode::kCompat &&
-                i_sampling == core::InterpolationSampling::kSample) {
-                AddError(attr->source)
-                    << "use of '@interpolate(..., sample)' is not allowed in compatibility mode";
-                return false;
-            }
         }
-    } else {
-        if (mode_ == wgsl::ValidationMode::kCompat && i_type == core::InterpolationType::kFlat) {
-            AddError(attr->source)
-                << "flat interpolation must use 'either' sampling parameter in compatibility mode";
-            return false;
-        }
-    }
-
-    if (mode_ == wgsl::ValidationMode::kCompat && i_type == core::InterpolationType::kLinear) {
-        AddError(attr->source)
-            << "use of '@interpolate(linear)' is not allowed in compatibility mode";
-        return false;
     }
 
     return true;
diff --git a/src/tint/lang/wgsl/resolver/validator.h b/src/tint/lang/wgsl/resolver/validator.h
index 1db8f64..a46bb8c 100644
--- a/src/tint/lang/wgsl/resolver/validator.h
+++ b/src/tint/lang/wgsl/resolver/validator.h
@@ -38,7 +38,6 @@
 #include "src/tint/lang/wgsl/ast/input_attachment_index_attribute.h"
 #include "src/tint/lang/wgsl/ast/pipeline_stage.h"
 #include "src/tint/lang/wgsl/common/allowed_features.h"
-#include "src/tint/lang/wgsl/common/validation_mode.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
 #include "src/tint/lang/wgsl/resolver/sem_helper.h"
 #include "src/tint/utils/containers/hashmap.h"
@@ -128,14 +127,12 @@
     /// @param helper the SEM helper to validate with
     /// @param enabled_extensions all the extensions declared in current module
     /// @param allowed_features the allowed extensions and features
-    /// @param mode the validation mode to use
     /// @param atomic_composite_info atomic composite info of the module
     /// @param valid_type_storage_layouts a set of validated type layouts by address space
     Validator(ProgramBuilder* builder,
               SemHelper& helper,
               const wgsl::Extensions& enabled_extensions,
               const wgsl::AllowedFeatures& allowed_features,
-              wgsl::ValidationMode mode,
               const Hashmap<const core::type::Type*, const Source*, 8>& atomic_composite_info,
               Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts);
     ~Validator();
@@ -658,7 +655,6 @@
     DiagnosticFilterStack diagnostic_filters_;
     const wgsl::Extensions& enabled_extensions_;
     const wgsl::AllowedFeatures& allowed_features_;
-    const wgsl::ValidationMode mode_;
     const Hashmap<const core::type::Type*, const Source*, 8>& atomic_composite_info_;
     Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts_;
 };
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index f42d7ba..7a16b1a 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -314,6 +314,10 @@
 crbug.com/dawn/2319 [ nvidia-0x2184 ] webgpu:shader,execution,expression,call,builtin,clamp:i32:* [ Failure ]
 crbug.com/dawn/2319 [ nvidia-0x2184 ] webgpu:shader,execution,expression,call,builtin,clamp:u32:* [ Failure ]
 
+# flat issues - should clear up with cts roll
+crbug.com/357047899 webgpu:shader,validation,shader_io,interpolate:integral_types:* [ Failure ]
+crbug.com/357047899 webgpu:shader,validation,shader_io,interpolate:interpolation_validation:attr="trailing_comma_one_arg" [ Failure ]
+
 # alpha_to_coverage occlusion query tests failing on Intel
 crbug.com/dawn/2248 [ intel-0x9bc5 ] webgpu:api,operation,command_buffer,queries,occlusionQuery:occlusion_query,alpha_to_coverage:writeMask=0;renderMode="direct";bufferOffset="non-zero";querySetOffset="non-zero";alpha=0 [ Failure ]
 crbug.com/dawn/2248 [ intel-0x9bc5 ] webgpu:api,operation,command_buffer,queries,occlusionQuery:occlusion_query,alpha_to_coverage:writeMask=0;renderMode="direct";bufferOffset="non-zero";querySetOffset="non-zero";alpha=0.25 [ Failure ]