Add 3D Texture T2T copy tests on non-zero mip levels

After adding some e2e tests for 3D texture T2T copy on non-zero mip
levels, it turns out that there is a bug in the e2e test itself.
The 3D texture copy splitter works well.

Bug: dawn:547

Change-Id: I51aef7aaca4caf9c86bfb0590eb0288d17731ba5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/55144
Commit-Queue: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/tests/end2end/CopyTests.cpp b/src/tests/end2end/CopyTests.cpp
index fd690fe..fe958b7 100644
--- a/src/tests/end2end/CopyTests.cpp
+++ b/src/tests/end2end/CopyTests.cpp
@@ -364,13 +364,15 @@
             dstTexture = device.CreateTexture(&dstDescriptor);
         }
 
-        // Create an upload buffer and use it to populate the current slice of the texture in
-        // `level` mip level
+        // Create an upload buffer and use it to completely populate the subresources of the src
+        // texture that will be copied from at the given mip level.
         const utils::TextureDataCopyLayout srcDataCopyLayout =
             utils::GetTextureDataCopyLayoutForTextureAtLevel(
                 format,
                 {srcSpec.textureSize.width, srcSpec.textureSize.height,
-                 copySize.depthOrArrayLayers},
+                 srcDimension == wgpu::TextureDimension::e3D
+                     ? srcSpec.textureSize.depthOrArrayLayers
+                     : copySize.depthOrArrayLayers},
                 srcSpec.copyLevel, srcDimension);
 
         // Initialize the source texture
@@ -394,13 +396,15 @@
             utils::CreateImageCopyTexture(dstTexture, dstSpec.copyLevel, dstSpec.copyOrigin);
         encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &copySize);
 
-        // Copy the data from the srcSpec.copyOrigin.z-th layer to (srcSpec.copyOrigin.z +
-        // copySize.depthOrArrayLayers)-th layer of dstTexture to outputBuffer
+        // Create an output buffer and use it to completely populate the subresources of the dst
+        // texture that will be copied to at the given mip level.
         const utils::TextureDataCopyLayout dstDataCopyLayout =
             utils::GetTextureDataCopyLayoutForTextureAtLevel(
                 format,
                 {dstSpec.textureSize.width, dstSpec.textureSize.height,
-                 copySize.depthOrArrayLayers},
+                 dstDimension == wgpu::TextureDimension::e3D
+                     ? dstSpec.textureSize.depthOrArrayLayers
+                     : copySize.depthOrArrayLayers},
                 dstSpec.copyLevel, dstDimension);
         wgpu::BufferDescriptor outputBufferDescriptor;
         outputBufferDescriptor.size = dstDataCopyLayout.byteLength;
@@ -1193,9 +1197,6 @@
     }
 }
 
-// TODO(yunchao.he@intel.com): add T2B tests for 3D textures, like RowPitch,
-// RowsPerImage, buffer offset, partial depth range, non-zero level, etc.
-
 DAWN_INSTANTIATE_TEST(CopyTests_T2B,
                       D3D12Backend(),
                       MetalBackend(),
@@ -1804,9 +1805,6 @@
     }
 }
 
-// TODO(yunchao.he@intel.com): add more tests like RowPitch, RowsPerImage, buffer offset, partial
-// depth range, non-zero level, etc.
-
 DAWN_INSTANTIATE_TEST(CopyTests_B2T,
                       D3D12Backend(),
                       MetalBackend(),
@@ -2201,8 +2199,43 @@
            wgpu::TextureDimension::e2D, wgpu::TextureDimension::e3D);
 }
 
-// TODO(yunchao.he@intel.com): add T2T tests for 3D textures, like RowPitch,
-// RowsPerImage, buffer offset, partial depth range, non-zero level, etc.
+// Test that copying texture 3D array mips in one texture-to-texture-copy works
+TEST_P(CopyTests_T2T, Texture3DMipAligned) {
+    constexpr uint32_t kWidth = 256;
+    constexpr uint32_t kHeight = 128;
+    constexpr uint32_t kDepth = 64u;
+
+    TextureSpec defaultTextureSpec;
+    defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
+
+    for (unsigned int i = 1; i < 6; ++i) {
+        TextureSpec textureSpec = defaultTextureSpec;
+        textureSpec.copyLevel = i;
+        textureSpec.levelCount = i + 1;
+
+        DoTest(textureSpec, textureSpec, {kWidth >> i, kHeight >> i, kDepth >> i},
+               wgpu::TextureDimension::e3D, wgpu::TextureDimension::e3D);
+    }
+}
+
+// Test that copying texture 3D array mips in one texture-to-texture-copy works
+TEST_P(CopyTests_T2T, Texture3DMipUnaligned) {
+    constexpr uint32_t kWidth = 261;
+    constexpr uint32_t kHeight = 123;
+    constexpr uint32_t kDepth = 69u;
+
+    TextureSpec defaultTextureSpec;
+    defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
+
+    for (unsigned int i = 1; i < 6; ++i) {
+        TextureSpec textureSpec = defaultTextureSpec;
+        textureSpec.copyLevel = i;
+        textureSpec.levelCount = i + 1;
+
+        DoTest(textureSpec, textureSpec, {kWidth >> i, kHeight >> i, kDepth >> i},
+               wgpu::TextureDimension::e3D, wgpu::TextureDimension::e3D);
+    }
+}
 
 DAWN_INSTANTIATE_TEST(
     CopyTests_T2T,