Compat: Validate out multisample copyT2T

GLES 3.1 does not support multisample texture copy

Bug: dawn:2208
Change-Id: I7570d7f718652dad30f936d52bc0ae6fbed12d2a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/173220
Reviewed-by: Brandon Jones <bajones@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Gregg Tavares <gman@chromium.org>
diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp
index 93baa52..76d836b 100644
--- a/src/dawn/native/CommandEncoder.cpp
+++ b/src/dawn/native/CommandEncoder.cpp
@@ -1795,7 +1795,8 @@
                 DAWN_TRY_CONTEXT(ValidateTextureCopyRange(GetDevice(), destination, *copySize),
                                  "validating source %s copy range.", destination.texture);
 
-                DAWN_TRY(ValidateTextureToTextureCopyRestrictions(source, destination, *copySize));
+                DAWN_TRY(ValidateTextureToTextureCopyRestrictions(GetDevice(), source, destination,
+                                                                  *copySize));
 
                 DAWN_TRY(ValidateCanUseAs(source.texture, wgpu::TextureUsage::CopySrc,
                                           mUsageValidationMode));
diff --git a/src/dawn/native/CommandValidation.cpp b/src/dawn/native/CommandValidation.cpp
index 60fb454..38af679 100644
--- a/src/dawn/native/CommandValidation.cpp
+++ b/src/dawn/native/CommandValidation.cpp
@@ -483,7 +483,8 @@
     return {};
 }
 
-MaybeError ValidateTextureToTextureCopyCommonRestrictions(const ImageCopyTexture& src,
+MaybeError ValidateTextureToTextureCopyCommonRestrictions(DeviceBase const* device,
+                                                          const ImageCopyTexture& src,
                                                           const ImageCopyTexture& dst,
                                                           const Extent3D& copySize) {
     const uint32_t srcSamples = src.texture->GetSampleCount();
@@ -494,6 +495,11 @@
         "Source %s sample count (%u) and destination %s sample count (%u) does not match.",
         src.texture, srcSamples, dst.texture, dstSamples);
 
+    DAWN_INVALID_IF(device->IsCompatibilityMode() && srcSamples != 1,
+                    "Source %s and destination %s with sample count (%u) > 1 cannot be copied in "
+                    "compatibility mode.",
+                    src.texture, dst.texture, srcSamples);
+
     // Metal cannot select a single aspect for texture-to-texture copies.
     const Format& format = src.texture->GetFormat();
     DAWN_INVALID_IF(
@@ -537,7 +543,8 @@
     return {};
 }
 
-MaybeError ValidateTextureToTextureCopyRestrictions(const ImageCopyTexture& src,
+MaybeError ValidateTextureToTextureCopyRestrictions(DeviceBase const* device,
+                                                    const ImageCopyTexture& src,
                                                     const ImageCopyTexture& dst,
                                                     const Extent3D& copySize) {
     // Metal requires texture-to-texture copies happens between texture formats that equal to
@@ -547,7 +554,7 @@
                     src.texture, src.texture->GetFormat().format, dst.texture,
                     dst.texture->GetFormat().format);
 
-    return ValidateTextureToTextureCopyCommonRestrictions(src, dst, copySize);
+    return ValidateTextureToTextureCopyCommonRestrictions(device, src, dst, copySize);
 }
 
 MaybeError ValidateCanUseAs(const TextureBase* texture,
diff --git a/src/dawn/native/CommandValidation.h b/src/dawn/native/CommandValidation.h
index 24e1b21..c9abed2 100644
--- a/src/dawn/native/CommandValidation.h
+++ b/src/dawn/native/CommandValidation.h
@@ -101,10 +101,12 @@
 
 bool IsRangeOverlapped(uint32_t startA, uint32_t startB, uint32_t length);
 
-MaybeError ValidateTextureToTextureCopyCommonRestrictions(const ImageCopyTexture& src,
+MaybeError ValidateTextureToTextureCopyCommonRestrictions(DeviceBase const* device,
+                                                          const ImageCopyTexture& src,
                                                           const ImageCopyTexture& dst,
                                                           const Extent3D& copySize);
-MaybeError ValidateTextureToTextureCopyRestrictions(const ImageCopyTexture& src,
+MaybeError ValidateTextureToTextureCopyRestrictions(DeviceBase const* device,
+                                                    const ImageCopyTexture& src,
                                                     const ImageCopyTexture& dst,
                                                     const Extent3D& copySize);
 
diff --git a/src/dawn/native/CopyTextureForBrowserHelper.cpp b/src/dawn/native/CopyTextureForBrowserHelper.cpp
index dba4ec4..4b07549 100644
--- a/src/dawn/native/CopyTextureForBrowserHelper.cpp
+++ b/src/dawn/native/CopyTextureForBrowserHelper.cpp
@@ -687,7 +687,8 @@
     // Validate copy common rules and copySize.
     DAWN_INVALID_IF(copySize->depthOrArrayLayers > 1, "Copy is for more than one array layer (%u)",
                     copySize->depthOrArrayLayers);
-    DAWN_TRY(ValidateTextureToTextureCopyCommonRestrictions(*source, *destination, *copySize));
+    DAWN_TRY(
+        ValidateTextureToTextureCopyCommonRestrictions(device, *source, *destination, *copySize));
 
     // Validate options
     DAWN_TRY(ValidateCopyForBrowserOptions(*options));
diff --git a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
index ea72185..74f0fb5 100644
--- a/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CompatValidationTests.cpp
@@ -1109,6 +1109,32 @@
                         testing::HasSubstr("not supported in compatibility mode"));
 }
 
+TEST_F(CompatValidationTest, CanNotCopyMultisampleTextureToTexture) {
+    wgpu::TextureDescriptor srcDescriptor;
+    srcDescriptor.size = {4, 4, 1};
+    srcDescriptor.dimension = wgpu::TextureDimension::e2D;
+    srcDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
+    srcDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;
+    srcDescriptor.sampleCount = 4;
+    wgpu::Texture srcTexture = device.CreateTexture(&srcDescriptor);
+
+    wgpu::TextureDescriptor dstDescriptor;
+    dstDescriptor.size = {4, 4, 1};
+    dstDescriptor.dimension = wgpu::TextureDimension::e2D;
+    dstDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
+    dstDescriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment;
+    dstDescriptor.sampleCount = 4;
+    wgpu::Texture dstTexture = device.CreateTexture(&dstDescriptor);
+
+    wgpu::ImageCopyTexture source = utils::CreateImageCopyTexture(srcTexture);
+    wgpu::ImageCopyTexture destination = utils::CreateImageCopyTexture(dstTexture);
+
+    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+    encoder.CopyTextureToTexture(&source, &destination, &srcDescriptor.size);
+    ASSERT_DEVICE_ERROR(encoder.Finish(),
+                        testing::HasSubstr("cannot be copied in compatibility mode"));
+}
+
 class CompatTextureViewDimensionValidationTests : public CompatValidationTest {
   protected:
     void TestBindingTextureViewDimensions(
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index 5cb7268..a0d58d1 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -550,6 +550,10 @@
 [ intel-0x9bc5 ] webgpu:shader,execution,expression,call,builtin,ldexp:f32:inputSource="uniform";vectorize=3 [ Failure ]
 [ intel-0x9bc5 ] webgpu:shader,execution,expression,call,builtin,ldexp:f32:inputSource="uniform";vectorize=4 [ Failure ]
 
+# Multisample textures are not copyable. Should be fixed in pendng cts roll.
+crbug.com/dawn/0000 webgpu:api,validation,encoding,cmds,copyTextureToTexture:multisampled_copy_restrictions:* [ Failure ]
+crbug.com/dawn/0000 webgpu:api,validation,encoding,cmds,copyTextureToTexture:sample_count:* [ Failure ]
+
 ################################################################################
 # New flakes. Please triage:
 ################################################################################