Allow using DepthOnly aspect on the depth-only formats in T2T copies

This patch allows the use of DepthOnly as the parameter 'aspect' in the
command CopyTextureToTexture() on the depth-only formats (Depth24Plus
and Depth32Float) to match the latest WebGPU SPEC.

BUG=dawn:439
TEST=dawn_unittests

Change-Id: I73c4055bb0a90bed2b5751ce9dff5b319787efca
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38340
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/CommandValidation.cpp b/src/dawn_native/CommandValidation.cpp
index 76dadff..6d33f0a 100644
--- a/src/dawn_native/CommandValidation.cpp
+++ b/src/dawn_native/CommandValidation.cpp
@@ -701,10 +701,15 @@
             return DAWN_VALIDATION_ERROR("Source and destination texture formats must match.");
         }
 
-        if (src.aspect != wgpu::TextureAspect::All || dst.aspect != wgpu::TextureAspect::All) {
-            // Metal cannot select a single aspect for texture-to-texture copies
+        // Metal cannot select a single aspect for texture-to-texture copies.
+        const Format& format = src.texture->GetFormat();
+        if (SelectFormatAspects(format, src.aspect) != format.aspects) {
             return DAWN_VALIDATION_ERROR(
-                "Texture aspect must be \"all\" for texture to texture copies");
+                "Source aspect doesn't select all the aspects of the source format.");
+        }
+        if (SelectFormatAspects(format, dst.aspect) != format.aspects) {
+            return DAWN_VALIDATION_ERROR(
+                "Destination aspect doesn't select all the aspects of the destination format.");
         }
 
         if (src.texture == dst.texture && src.mipLevel == dst.mipLevel) {
diff --git a/src/tests/unittests/validation/CopyCommandsValidationTests.cpp b/src/tests/unittests/validation/CopyCommandsValidationTests.cpp
index 4cdeb8c..c3accb2 100644
--- a/src/tests/unittests/validation/CopyCommandsValidationTests.cpp
+++ b/src/tests/unittests/validation/CopyCommandsValidationTests.cpp
@@ -1664,6 +1664,34 @@
                 {16, 16, 1}, wgpu::TextureAspect::StencilOnly);
 }
 
+TEST_F(CopyCommandTest_T2T, 2DTextureDepthOnly) {
+    constexpr std::array<wgpu::TextureFormat, 2> kDepthOnlyFormats = {
+        wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Depth32Float};
+
+    for (wgpu::TextureFormat format : kDepthOnlyFormats) {
+        wgpu::Texture source = Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopySrc);
+
+        wgpu::Texture destination =
+            Create2DTexture(16, 16, 1, 1, format, wgpu::TextureUsage::CopyDst);
+
+        // Success when entire subresource is copied
+        TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
+                    {16, 16, 1});
+
+        // Failure when depth subresource is partially copied
+        TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
+                    {15, 15, 1});
+
+        // Success when selecting the depth aspect (not all)
+        TestT2TCopy(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
+                    {16, 16, 1}, wgpu::TextureAspect::DepthOnly);
+
+        // Failure when selecting the stencil aspect (not all)
+        TestT2TCopy(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0, {0, 0, 0},
+                    {16, 16, 1}, wgpu::TextureAspect::StencilOnly);
+    }
+}
+
 TEST_F(CopyCommandTest_T2T, 2DTextureArrayDepthStencil) {
     {
         wgpu::Texture source = Create2DTexture(