Compat: make textureLoad with texture_depth_xxx emit error

Bug: 42241437
Change-Id: I9bb1c4bd958f20a41efd0b79f3aeee9b0e77a058
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/194442
Commit-Queue: Gregg Tavares <gman@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp b/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
index 52fde9d..63b0da9 100644
--- a/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilLoadOpTests.cpp
@@ -131,6 +131,8 @@
         switch (GetParam().mCheck) {
             case Check::SampleDepth: {
                 DAWN_TEST_UNSUPPORTED_IF(utils::IsStencilOnlyFormat(GetParam().mFormat));
+                // textureLoad with texture_depth_xxx is not supported in compat mode.
+                DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());
 
                 std::vector<float> expectedDepth(mipSize * mipSize, kDepthValues[mipLevel]);
                 ExpectSampledDepthData(
diff --git a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
index c62f7ba..0f7835d 100644
--- a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
@@ -896,6 +896,9 @@
 
 // Test that sampling a depth texture with a render/compute pipeline works
 TEST_P(DepthSamplingTest, SampleDepthOnly) {
+    // textureLoad with texture_depth_xxx is not supported in compat mode.
+    DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());
+
     // TODO(crbug.com/dawn/2552): diagnose this flake on Pixel 6 OpenGLES
     DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
 
diff --git a/src/dawn/tests/end2end/MultisampledSamplingTests.cpp b/src/dawn/tests/end2end/MultisampledSamplingTests.cpp
index 3f3771e..39b60b3 100644
--- a/src/dawn/tests/end2end/MultisampledSamplingTests.cpp
+++ b/src/dawn/tests/end2end/MultisampledSamplingTests.cpp
@@ -61,9 +61,9 @@
     // A compute pipeline to texelFetch the sample locations and output the results to a buffer.
     wgpu::ComputePipeline checkSamplePipeline;
 
-    void SetUp() override {
-        DawnTest::SetUp();
+    void SetUp() override { DawnTest::SetUp(); }
 
+    void CreatePipelines() {
         {
             utils::ComboRenderPipelineDescriptor desc;
 
@@ -136,6 +136,11 @@
 // must cover both the X and Y coordinates of the sample position (no false positives if
 // it covers the X position but not the Y, or vice versa).
 TEST_P(MultisampledSamplingTest, SamplePositions) {
+    // textureLoad with texture_depth_xxx is not supported in compat mode.
+    DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode());
+
+    CreatePipelines();
+
     static constexpr wgpu::Extent3D kTextureSize = {1, 1, 1};
 
     wgpu::Texture colorTexture;
diff --git a/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp b/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp
index 71be710..1124f56 100644
--- a/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp
+++ b/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp
@@ -121,6 +121,11 @@
         DAWN_TEST_UNSUPPORTED_IF(utils::IsCompressedTextureFormat(GetParam().mFormat) &&
                                  IsCompatibilityMode());
 
+        // TODO(crbug.com/dawn/667): Workaround the fact that you can't use textureLoad with
+        // texture_depth_xxx in compat mode.
+        DAWN_TEST_UNSUPPORTED_IF(utils::IsDepthOrStencilFormat(GetParam().mFormat) &&
+                                 IsCompatibilityMode());
+
         // TODO(crbug.com/dawn/1637): Failures with ANGLE only with some format/aspect
         DAWN_SUPPRESS_TEST_IF(IsWindows() && IsANGLE() &&
                               GetParam().mAspect == wgpu::TextureAspect::All &&
diff --git a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
index 758fa8d..0223370 100644
--- a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
+++ b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
@@ -25,9 +25,14 @@
 // 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/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"
 
@@ -37,6 +42,8 @@
 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() {
@@ -270,5 +277,79 @@
         R"(12:34 error: use of '@interpolate(..., sample)' is not allowed in compatibility mode)");
 }
 
+class ResolverCompatibilityModeTest_TextureLoad : public ResolverCompatibilityModeTest {
+  protected:
+    void add_call_param(std::string name, ast::Type type, ExpressionList* call_params) {
+        const std::string type_name = type->identifier->symbol.Name();
+        if (tint::HasPrefix(type_name, "texture")) {
+            GlobalVar(name, type, Binding(0_a), Group(0_a));
+        } else {
+            GlobalVar(name, type, core::AddressSpace::kPrivate);
+        }
+        call_params->Push(Expr(Source{{12, 34}}, name));
+    }
+};
+
+TEST_F(ResolverCompatibilityModeTest_TextureLoad, TextureDepth2D) {
+    // textureLoad(someDepthTexture2D, coords, level)
+    const ast::Type coords_type = ty.vec2(ty.i32());
+    auto texture_type = ty.depth_texture(core::type::TextureDimension::k2d);
+
+    ExpressionList call_params;
+
+    add_call_param("texture", texture_type, &call_params);
+    add_call_param("coords", coords_type, &call_params);
+    add_call_param("level", ty.i32(), &call_params);
+
+    auto* expr = Call("textureLoad", call_params);
+    WrapInFunction(expr);
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(
+        r()->error(),
+        R"(12:34 error: use of texture_depth_2d with textureLoad is not allowed in compatibility mode)");
+}
+
+TEST_F(ResolverCompatibilityModeTest_TextureLoad, TextureDepth2DArray) {
+    // textureLoad(someDepthTexture2DArray, coords, layer, level)
+    const ast::Type coords_type = ty.vec2(ty.i32());
+    auto texture_type = ty.depth_texture(core::type::TextureDimension::k2dArray);
+
+    ExpressionList call_params;
+
+    add_call_param("texture", texture_type, &call_params);
+    add_call_param("coords", coords_type, &call_params);
+    add_call_param("array_index", ty.i32(), &call_params);
+    add_call_param("level", ty.i32(), &call_params);
+
+    auto* expr = Call("textureLoad", call_params);
+    WrapInFunction(expr);
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(
+        r()->error(),
+        R"(12:34 error: use of texture_depth_2d_array with textureLoad is not allowed in compatibility mode)");
+}
+
+TEST_F(ResolverCompatibilityModeTest_TextureLoad, TextureDepthMultisampled2D) {
+    // textureLoad(someDepthTextureMultisampled2D, coords, sample_index)
+    const ast::Type coords_type = ty.vec2(ty.i32());
+    auto texture_type = ty.depth_multisampled_texture(core::type::TextureDimension::k2d);
+
+    ExpressionList call_params;
+
+    add_call_param("texture", texture_type, &call_params);
+    add_call_param("coords", coords_type, &call_params);
+    add_call_param("sample_index", ty.i32(), &call_params);
+
+    auto* expr = Call("textureLoad", call_params);
+    WrapInFunction(expr);
+
+    EXPECT_FALSE(r()->Resolve());
+    EXPECT_EQ(
+        r()->error(),
+        R"(12:34 error: use of texture_depth_multisampled_2d with textureLoad is not allowed in compatibility mode)");
+}
+
 }  // namespace
 }  // namespace tint::resolver
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index a2177af..d6bb9d9 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -35,6 +35,7 @@
 #include <utility>
 
 #include "src/tint/lang/core/fluent_types.h"
+#include "src/tint/lang/core/parameter_usage.h"
 #include "src/tint/lang/core/type/abstract_numeric.h"
 #include "src/tint/lang/core/type/atomic.h"
 #include "src/tint/lang/core/type/depth_multisampled_texture.h"
@@ -67,6 +68,7 @@
 #include "src/tint/lang/wgsl/ast/unary_op_expression.h"
 #include "src/tint/lang/wgsl/ast/variable_decl_statement.h"
 #include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
+#include "src/tint/lang/wgsl/builtin_fn.h"
 #include "src/tint/lang/wgsl/sem/array.h"
 #include "src/tint/lang/wgsl/sem/break_if_statement.h"
 #include "src/tint/lang/wgsl/sem/call.h"
@@ -1802,6 +1804,19 @@
     std::string func_name = builtin->str();
     auto& signature = builtin->Signature();
 
+    if (mode_ == wgsl::ValidationMode::kCompat) {
+        if (builtin->Fn() == wgsl::BuiltinFn::kTextureLoad) {
+            auto* arg = call->Arguments()[0];
+            if (arg->Type()
+                    ->IsAnyOf<core::type::DepthTexture, core::type::DepthMultisampledTexture>()) {
+                AddError(arg->Declaration()->source)
+                    << "use of " << arg->Type()->FriendlyName()
+                    << " with textureLoad is not allowed in compatibility mode";
+                return false;
+            }
+        }
+    }
+
     auto check_arg_is_constexpr = [&](core::ParameterUsage usage, int min, int max) {
         auto signed_index = signature.IndexOf(usage);
         if (signed_index < 0) {