Replace TextureCopyView::arrayLayer -> origin.z in backends

Also fix a misuse of VkBufferImageCopy that caused some Swiftshader
failures.

Bug: dawn:22
Change-Id: Ie812a590d70c7561dfcf2f78ce6c530187610e65
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23200
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn_native/CommandBuffer.cpp b/src/dawn_native/CommandBuffer.cpp
index 401451d..177e93e 100644
--- a/src/dawn_native/CommandBuffer.cpp
+++ b/src/dawn_native/CommandBuffer.cpp
@@ -51,6 +51,17 @@
         return false;
     }
 
+    SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy,
+                                                   const Extent3D& copySize) {
+        switch (copy.texture->GetDimension()) {
+            case wgpu::TextureDimension::e2D:
+                return {copy.mipLevel, 1, copy.origin.z, copySize.depth};
+            default:
+                UNREACHABLE();
+                return {};
+        }
+    }
+
     void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass) {
         for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
             auto& attachmentInfo = renderPass->colorAttachments[i];
diff --git a/src/dawn_native/CommandBuffer.h b/src/dawn_native/CommandBuffer.h
index c1d2597..ba9e409 100644
--- a/src/dawn_native/CommandBuffer.h
+++ b/src/dawn_native/CommandBuffer.h
@@ -20,10 +20,12 @@
 #include "dawn_native/Forward.h"
 #include "dawn_native/ObjectBase.h"
 #include "dawn_native/PassResourceUsage.h"
+#include "dawn_native/Texture.h"
 
 namespace dawn_native {
 
     struct BeginRenderPassCmd;
+    struct TextureCopy;
 
     class CommandBufferBase : public ObjectBase {
       public:
@@ -37,9 +39,12 @@
 
         CommandBufferResourceUsage mResourceUsages;
     };
+
     bool IsCompleteSubresourceCopiedTo(const TextureBase* texture,
                                        const Extent3D copySize,
                                        const uint32_t mipLevel);
+    SubresourceRange GetSubresourcesAffectedByCopy(const TextureCopy& copy,
+                                                   const Extent3D& copySize);
 
     void LazyClearRenderPassAttachments(BeginRenderPassCmd* renderPass);
 
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 5b8bc64..b282dc8 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -737,13 +737,8 @@
             copy->source.rowsPerImage = defaultedRowsPerImage;
             copy->destination.texture = destination->texture;
             copy->destination.origin = destination->origin;
-            copy->copySize = *copySize;
             copy->destination.mipLevel = destination->mipLevel;
-            copy->destination.arrayLayer = destination->arrayLayer;
-
-            // TODO(cwallez@chromium.org): Make backends use origin.z instead of arrayLayer
-            copy->destination.arrayLayer = copy->destination.origin.z;
-            copy->destination.origin.z = 0;
+            copy->copySize = *copySize;
 
             return {};
         });
@@ -803,17 +798,12 @@
                 allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
             copy->source.texture = source->texture;
             copy->source.origin = source->origin;
-            copy->copySize = *copySize;
             copy->source.mipLevel = source->mipLevel;
-            copy->source.arrayLayer = source->arrayLayer;
             copy->destination.buffer = destination->buffer;
             copy->destination.offset = destination->offset;
             copy->destination.bytesPerRow = destination->bytesPerRow;
             copy->destination.rowsPerImage = defaultedRowsPerImage;
-
-            // TODO(cwallez@chromium.org): Make backends use origin.z instead of arrayLayer
-            copy->source.arrayLayer = copy->source.origin.z;
-            copy->source.origin.z = 0;
+            copy->copySize = *copySize;
 
             return {};
         });
@@ -860,19 +850,11 @@
             copy->source.texture = source->texture;
             copy->source.origin = source->origin;
             copy->source.mipLevel = source->mipLevel;
-            copy->source.arrayLayer = source->arrayLayer;
             copy->destination.texture = destination->texture;
             copy->destination.origin = destination->origin;
             copy->destination.mipLevel = destination->mipLevel;
-            copy->destination.arrayLayer = destination->arrayLayer;
             copy->copySize = *copySize;
 
-            // TODO(cwallez@chromium.org): Make backends use origin.z instead of arrayLayer
-            copy->source.arrayLayer = copy->source.origin.z;
-            copy->source.origin.z = 0;
-            copy->destination.arrayLayer = copy->destination.origin.z;
-            copy->destination.origin.z = 0;
-
             return {};
         });
     }
diff --git a/src/dawn_native/Commands.h b/src/dawn_native/Commands.h
index 155a21d..0c2c8f0 100644
--- a/src/dawn_native/Commands.h
+++ b/src/dawn_native/Commands.h
@@ -102,8 +102,7 @@
     struct TextureCopy {
         Ref<TextureBase> texture;
         uint32_t mipLevel;
-        uint32_t arrayLayer;
-        Origin3D origin;  // Texels
+        Origin3D origin;  // Texels / array layer
     };
 
     struct CopyBufferToBufferCmd {
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
index a0df3b6..2867ffe 100644
--- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -577,11 +577,8 @@
                     Texture* texture = ToBackend(copy->destination.texture.Get());
 
                     ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
-                    // TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of
-                    // copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
-                    // GPUTextureCopyView.origin.z is done.
                     SubresourceRange subresources = {copy->destination.mipLevel, 1,
-                                                     copy->destination.arrayLayer,
+                                                     copy->destination.origin.z,
                                                      copy->copySize.depth};
                     if (IsCompleteSubresourceCopiedTo(texture, copy->copySize,
                                                       copy->destination.mipLevel)) {
@@ -600,13 +597,15 @@
                     const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width,
                                                                     copy->copySize.height, 1};
                     uint64_t bufferOffsetForNextSlice = 0;
-                    for (uint32_t copySlice = copy->destination.arrayLayer;
-                         copySlice < copy->destination.arrayLayer + copy->copySize.depth;
+                    for (uint32_t copySlice = copy->destination.origin.z;
+                         copySlice < copy->destination.origin.z + copy->copySize.depth;
                          ++copySlice) {
                         // TODO(jiawei.shao@intel.com): compute copySplit once for all texture array
                         // layers when possible.
+                        Origin3D destinationOriginInSubresource = copy->destination.origin;
+                        destinationOriginInSubresource.z = 0;
                         auto copySplit = ComputeTextureCopySplit(
-                            copy->destination.origin, copyOneLayerSize, texture->GetFormat(),
+                            destinationOriginInSubresource, copyOneLayerSize, texture->GetFormat(),
                             bufferOffsetForNextSlice + copy->source.offset,
                             copy->source.bytesPerRow, copy->source.rowsPerImage);
 
@@ -640,11 +639,8 @@
                     Buffer* buffer = ToBackend(copy->destination.buffer.Get());
 
                     ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
-                    // TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of
-                    // copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
-                    // GPUTextureCopyView.origin.z is done.
                     SubresourceRange subresources = {copy->source.mipLevel, 1,
-                                                     copy->source.arrayLayer, copy->copySize.depth};
+                                                     copy->source.origin.z, copy->copySize.depth};
                     texture->EnsureSubresourceContentInitialized(commandContext, subresources);
 
                     texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
@@ -657,12 +653,14 @@
                     const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width,
                                                                     copy->copySize.height, 1};
                     uint64_t bufferOffsetForNextSlice = 0;
-                    for (uint32_t copySlice = copy->source.arrayLayer;
-                         copySlice < copy->source.arrayLayer + copy->copySize.depth; ++copySlice) {
+                    for (uint32_t copySlice = copy->source.origin.z;
+                         copySlice < copy->source.origin.z + copy->copySize.depth; ++copySlice) {
                         // TODO(jiawei.shao@intel.com): compute copySplit once for all texture array
                         // layers when possible.
+                        Origin3D sourceOriginInSubresource = copy->source.origin;
+                        sourceOriginInSubresource.z = 0;
                         TextureCopySplit copySplit = ComputeTextureCopySplit(
-                            copy->source.origin, copyOneLayerSize, texture->GetFormat(),
+                            sourceOriginInSubresource, copyOneLayerSize, texture->GetFormat(),
                             bufferOffsetForNextSlice + copy->destination.offset,
                             copy->destination.bytesPerRow, copy->destination.rowsPerImage);
 
@@ -697,11 +695,10 @@
 
                     Texture* source = ToBackend(copy->source.texture.Get());
                     Texture* destination = ToBackend(copy->destination.texture.Get());
-                    SubresourceRange srcRange = {copy->source.mipLevel, 1, copy->source.arrayLayer,
+                    SubresourceRange srcRange = {copy->source.mipLevel, 1, copy->source.origin.z,
                                                  copy->copySize.depth};
                     SubresourceRange dstRange = {copy->destination.mipLevel, 1,
-                                                 copy->destination.arrayLayer,
-                                                 copy->copySize.depth};
+                                                 copy->destination.origin.z, copy->copySize.depth};
 
                     source->EnsureSubresourceContentInitialized(commandContext, srcRange);
                     if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
@@ -717,8 +714,7 @@
                         // subresources should all be COMMON instead of what we set now. Currently
                         // it is not allowed to copy with overlapped subresources, but we still
                         // add the ASSERT here as a reminder for this possible misuse.
-                        ASSERT(!IsRangeOverlapped(copy->source.arrayLayer,
-                                                  copy->destination.arrayLayer,
+                        ASSERT(!IsRangeOverlapped(copy->source.origin.z, copy->destination.origin.z,
                                                   copy->copySize.depth));
                     }
                     source->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
@@ -737,21 +733,22 @@
                             copy->copySize.width, copy->copySize.height, 1u};
                         for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) {
                             D3D12_TEXTURE_COPY_LOCATION srcLocation =
-                                ComputeTextureCopyLocationForTexture(
-                                    source, copy->source.mipLevel, copy->source.arrayLayer + slice);
+                                ComputeTextureCopyLocationForTexture(source, copy->source.mipLevel,
+                                                                     copy->source.origin.z + slice);
 
                             D3D12_TEXTURE_COPY_LOCATION dstLocation =
                                 ComputeTextureCopyLocationForTexture(
                                     destination, copy->destination.mipLevel,
-                                    copy->destination.arrayLayer + slice);
+                                    copy->destination.origin.z + slice);
 
+                            Origin3D sourceOriginInSubresource = copy->source.origin;
+                            sourceOriginInSubresource.z = 0;
                             D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize(
-                                copy->source.origin, copyExtentOneSlice);
+                                sourceOriginInSubresource, copyExtentOneSlice);
 
                             commandList->CopyTextureRegion(&dstLocation, copy->destination.origin.x,
-                                                           copy->destination.origin.y,
-                                                           copy->destination.origin.z, &srcLocation,
-                                                           &sourceRegion);
+                                                           copy->destination.origin.y, 0,
+                                                           &srcLocation, &sourceRegion);
                         }
                     }
                     break;
diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm
index 64c098d..bd2b8f3 100644
--- a/src/dawn_native/metal/CommandBufferMTL.mm
+++ b/src/dawn_native/metal/CommandBufferMTL.mm
@@ -324,10 +324,6 @@
             std::array<CopyInfo, kMaxTextureBufferCopyRegions> copies;
         };
 
-        MTLOrigin MakeMTLOrigin(Origin3D origin) {
-            return MTLOriginMake(origin.x, origin.y, origin.z);
-        }
-
         TextureBufferCopySplit ComputeTextureBufferCopySplit(wgpu::TextureDimension dimension,
                                                              Origin3D origin,
                                                              Extent3D copyExtent,
@@ -444,18 +440,12 @@
             return copy;
         }
 
-        void EnsureSourceTextureInitialized(Texture* texture,
-                                            const Extent3D& size,
-                                            const TextureCopy& src) {
-            texture->EnsureSubresourceContentInitialized(
-                {src.mipLevel, 1, src.arrayLayer, size.depth});
-        }
-
         void EnsureDestinationTextureInitialized(Texture* texture,
-                                                 const Extent3D& size,
-                                                 const TextureCopy& dst) {
-            SubresourceRange range = {dst.mipLevel, 1, dst.arrayLayer, size.depth};
-            if (IsCompleteSubresourceCopiedTo(texture, size, dst.mipLevel)) {
+                                                 const TextureCopy& dst,
+                                                 const Extent3D& size) {
+            ASSERT(texture == dst.texture.Get());
+            SubresourceRange range = GetSubresourcesAffectedByCopy(dst, size);
+            if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), size, dst.mipLevel)) {
                 texture->SetIsSubresourceContentInitialized(true, range);
             } else {
                 texture->EnsureSubresourceContentInitialized(range);
@@ -748,15 +738,13 @@
                     Buffer* buffer = ToBackend(src.buffer.Get());
                     Texture* texture = ToBackend(dst.texture.Get());
 
-                    EnsureDestinationTextureInitialized(texture, copy->copySize, copy->destination);
+                    EnsureDestinationTextureInitialized(texture, copy->destination, copy->copySize);
 
                     const Extent3D virtualSizeAtLevel =
                         texture->GetMipLevelVirtualSize(dst.mipLevel);
 
-                    Origin3D copyOrigin = dst.origin;
-                    copyOrigin.z = dst.arrayLayer;
                     TextureBufferCopySplit splitCopies = ComputeTextureBufferCopySplit(
-                        texture->GetDimension(), copyOrigin, copySize, texture->GetFormat(),
+                        texture->GetDimension(), dst.origin, copySize, texture->GetFormat(),
                         virtualSizeAtLevel, buffer->GetSize(), src.offset, src.bytesPerRow,
                         src.rowsPerImage);
 
@@ -797,13 +785,12 @@
                     Texture* texture = ToBackend(src.texture.Get());
                     Buffer* buffer = ToBackend(dst.buffer.Get());
 
-                    EnsureSourceTextureInitialized(texture, copy->copySize, copy->source);
+                    texture->EnsureSubresourceContentInitialized(
+                        GetSubresourcesAffectedByCopy(src, copySize));
 
                     Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(src.mipLevel);
-                    Origin3D copyOrigin = src.origin;
-                    copyOrigin.z = src.arrayLayer;
                     TextureBufferCopySplit splitCopies = ComputeTextureBufferCopySplit(
-                        texture->GetDimension(), copyOrigin, copySize, texture->GetFormat(),
+                        texture->GetDimension(), src.origin, copySize, texture->GetFormat(),
                         virtualSizeAtLevel, buffer->GetSize(), dst.offset, dst.bytesPerRow,
                         dst.rowsPerImage);
 
@@ -842,28 +829,33 @@
                     Texture* srcTexture = ToBackend(copy->source.texture.Get());
                     Texture* dstTexture = ToBackend(copy->destination.texture.Get());
 
-                    EnsureSourceTextureInitialized(srcTexture, copy->copySize, copy->source);
-                    EnsureDestinationTextureInitialized(dstTexture, copy->copySize,
-                                                        copy->destination);
+                    srcTexture->EnsureSubresourceContentInitialized(
+                        GetSubresourcesAffectedByCopy(copy->source, copy->copySize));
+                    EnsureDestinationTextureInitialized(dstTexture, copy->destination,
+                                                        copy->copySize);
 
                     // TODO(jiawei.shao@intel.com): support copies with 1D and 3D textures.
                     ASSERT(srcTexture->GetDimension() == wgpu::TextureDimension::e2D &&
                            dstTexture->GetDimension() == wgpu::TextureDimension::e2D);
-                    const MTLSize mtlSizeOneLayer =
+                    const MTLSize sizeOneLayer =
                         MTLSizeMake(copy->copySize.width, copy->copySize.height, 1);
+                    const MTLOrigin sourceOriginNoLayer =
+                        MTLOriginMake(copy->source.origin.x, copy->source.origin.y, 0);
+                    const MTLOrigin destinationOriginNoLayer =
+                        MTLOriginMake(copy->destination.origin.x, copy->destination.origin.y, 0);
+
                     for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) {
                         [commandContext->EnsureBlit()
                               copyFromTexture:srcTexture->GetMTLTexture()
-                                  sourceSlice:copy->source.arrayLayer + slice
+                                  sourceSlice:copy->source.origin.z + slice
                                   sourceLevel:copy->source.mipLevel
-                                 sourceOrigin:MakeMTLOrigin(copy->source.origin)
-                                   sourceSize:mtlSizeOneLayer
+                                 sourceOrigin:sourceOriginNoLayer
+                                   sourceSize:sizeOneLayer
                                     toTexture:dstTexture->GetMTLTexture()
-                             destinationSlice:copy->destination.arrayLayer + slice
+                             destinationSlice:copy->destination.origin.z + slice
                              destinationLevel:copy->destination.mipLevel
-                            destinationOrigin:MakeMTLOrigin(copy->destination.origin)];
+                            destinationOrigin:destinationOriginNoLayer];
                     }
-
                     break;
                 }
 
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp
index 28c606a..f3fcd5c 100644
--- a/src/dawn_native/opengl/CommandBufferGL.cpp
+++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -515,10 +515,7 @@
                     const GLFormat& format = texture->GetGLFormat();
 
                     ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
-                    // TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of
-                    // copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
-                    // GPUTextureCopyView.origin.z is done.
-                    SubresourceRange subresources = {dst.mipLevel, 1, dst.arrayLayer,
+                    SubresourceRange subresources = {dst.mipLevel, 1, dst.origin.z,
                                                      copy->copySize.depth};
                     if (IsCompleteSubresourceCopiedTo(texture, copySize, dst.mipLevel)) {
                         texture->SetIsSubresourceContentInitialized(true, subresources);
@@ -550,7 +547,7 @@
 
                         if (texture->GetArrayLayers() > 1) {
                             gl.CompressedTexSubImage3D(
-                                target, dst.mipLevel, dst.origin.x, dst.origin.y, dst.arrayLayer,
+                                target, dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z,
                                 copyExtent.width, copyExtent.height, copyExtent.depth,
                                 format.internalFormat, copyDataSize,
                                 reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
@@ -565,7 +562,7 @@
                             case wgpu::TextureDimension::e2D:
                                 if (texture->GetArrayLayers() > 1) {
                                     gl.TexSubImage3D(target, dst.mipLevel, dst.origin.x,
-                                                     dst.origin.y, dst.arrayLayer, copySize.width,
+                                                     dst.origin.y, dst.origin.z, copySize.width,
                                                      copySize.height, copySize.depth, format.format,
                                                      format.type,
                                                      reinterpret_cast<void*>(
@@ -609,7 +606,7 @@
                     }
 
                     ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
-                    SubresourceRange subresources = {src.mipLevel, 1, src.arrayLayer,
+                    SubresourceRange subresources = {src.mipLevel, 1, src.origin.z,
                                                      copy->copySize.depth};
                     texture->EnsureSubresourceContentInitialized(subresources);
                     // The only way to move data from a texture to a buffer in GL is via
@@ -660,7 +657,7 @@
                             for (uint32_t layer = 0; layer < copySize.depth; ++layer) {
                                 gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
                                                            texture->GetHandle(), src.mipLevel,
-                                                           src.arrayLayer + layer);
+                                                           src.origin.z + layer);
                                 gl.ReadPixels(src.origin.x, src.origin.y, copySize.width,
                                               copySize.height, glFormat.format, glFormat.type,
                                               offset);
@@ -696,9 +693,9 @@
                     Extent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize);
                     Texture* srcTexture = ToBackend(src.texture.Get());
                     Texture* dstTexture = ToBackend(dst.texture.Get());
-                    SubresourceRange srcRange = {src.mipLevel, 1, src.arrayLayer,
+                    SubresourceRange srcRange = {src.mipLevel, 1, src.origin.z,
                                                  copy->copySize.depth};
-                    SubresourceRange dstRange = {dst.mipLevel, 1, dst.arrayLayer,
+                    SubresourceRange dstRange = {dst.mipLevel, 1, dst.origin.z,
                                                  copy->copySize.depth};
 
                     srcTexture->EnsureSubresourceContentInitialized(srcRange);
@@ -708,9 +705,9 @@
                         dstTexture->EnsureSubresourceContentInitialized(dstRange);
                     }
                     gl.CopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(),
-                                        src.mipLevel, src.origin.x, src.origin.y, src.arrayLayer,
+                                        src.mipLevel, src.origin.x, src.origin.y, src.origin.z,
                                         dstTexture->GetHandle(), dstTexture->GetGLTarget(),
-                                        dst.mipLevel, dst.origin.x, dst.origin.y, dst.arrayLayer,
+                                        dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z,
                                         copySize.width, copySize.height, copy->copySize.depth);
                     break;
                 }
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp
index 575f66f..ae0e792 100644
--- a/src/dawn_native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -70,21 +70,21 @@
                    dstTexture->GetDimension() == wgpu::TextureDimension::e2D);
             region.srcSubresource.aspectMask = srcTexture->GetVkAspectMask();
             region.srcSubresource.mipLevel = srcCopy.mipLevel;
-            region.srcSubresource.baseArrayLayer = srcCopy.arrayLayer;
+            region.srcSubresource.baseArrayLayer = srcCopy.origin.z;
             region.srcSubresource.layerCount = copySize.depth;
 
             region.srcOffset.x = srcCopy.origin.x;
             region.srcOffset.y = srcCopy.origin.y;
-            region.srcOffset.z = srcCopy.origin.z;
+            region.srcOffset.z = 0;
 
             region.dstSubresource.aspectMask = dstTexture->GetVkAspectMask();
             region.dstSubresource.mipLevel = dstCopy.mipLevel;
-            region.dstSubresource.baseArrayLayer = dstCopy.arrayLayer;
+            region.dstSubresource.baseArrayLayer = dstCopy.origin.z;
             region.dstSubresource.layerCount = copySize.depth;
 
             region.dstOffset.x = dstCopy.origin.x;
             region.dstOffset.y = dstCopy.origin.y;
-            region.dstOffset.z = dstCopy.origin.z;
+            region.dstOffset.z = 0;
 
             ASSERT(HasSameTextureCopyExtent(srcCopy, dstCopy, copySize));
             Extent3D imageExtent = ComputeTextureCopyExtent(dstCopy, copySize);
@@ -507,10 +507,8 @@
                         mCommands.NextCommand<CopyTextureToTextureCmd>();
                     TextureCopy& src = copy->source;
                     TextureCopy& dst = copy->destination;
-                    SubresourceRange srcRange = {src.mipLevel, 1, src.arrayLayer,
-                                                 copy->copySize.depth};
-                    SubresourceRange dstRange = {dst.mipLevel, 1, dst.arrayLayer,
-                                                 copy->copySize.depth};
+                    SubresourceRange srcRange = GetSubresourcesAffectedByCopy(src, copy->copySize);
+                    SubresourceRange dstRange = GetSubresourcesAffectedByCopy(dst, copy->copySize);
 
                     ToBackend(src.texture)
                         ->EnsureSubresourceContentInitialized(recordingContext, srcRange);
@@ -528,10 +526,11 @@
                         // subresources should all be GENERAL instead of what we set now. Currently
                         // it is not allowed to copy with overlapped subresources, but we still
                         // add the ASSERT here as a reminder for this possible misuse.
-                        ASSERT(!IsRangeOverlapped(src.arrayLayer, dst.arrayLayer,
-                                                  copy->copySize.depth));
+                        ASSERT(
+                            !IsRangeOverlapped(src.origin.z, dst.origin.z, copy->copySize.depth));
                     }
 
+                    // TODO after Yunchao's CL
                     ToBackend(src.texture)
                         ->TransitionUsageNow(recordingContext, wgpu::TextureUsage::CopySrc,
                                              srcRange);
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp
index eb502f8..d710c95 100644
--- a/src/dawn_native/vulkan/TextureVk.cpp
+++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -939,9 +939,8 @@
 
                     dawn_native::TextureCopy textureCopy;
                     textureCopy.texture = this;
-                    textureCopy.origin = {0, 0, 0};
+                    textureCopy.origin = {0, 0, layer};
                     textureCopy.mipLevel = level;
-                    textureCopy.arrayLayer = layer;
 
                     VkBufferImageCopy region =
                         ComputeBufferImageCopyRegion(bufferCopy, textureCopy, copySize);
diff --git a/src/dawn_native/vulkan/UtilsVulkan.cpp b/src/dawn_native/vulkan/UtilsVulkan.cpp
index 4ce513f..74e825b 100644
--- a/src/dawn_native/vulkan/UtilsVulkan.cpp
+++ b/src/dawn_native/vulkan/UtilsVulkan.cpp
@@ -81,19 +81,27 @@
 
         region.imageSubresource.aspectMask = texture->GetVkAspectMask();
         region.imageSubresource.mipLevel = textureCopy.mipLevel;
-        region.imageSubresource.baseArrayLayer = textureCopy.arrayLayer;
 
-        region.imageOffset.x = textureCopy.origin.x;
-        region.imageOffset.y = textureCopy.origin.y;
-        region.imageOffset.z = textureCopy.origin.z;
+        switch (textureCopy.texture->GetDimension()) {
+            case wgpu::TextureDimension::e2D: {
+                region.imageOffset.x = textureCopy.origin.x;
+                region.imageOffset.y = textureCopy.origin.y;
+                region.imageOffset.z = 0;
 
-        Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
-        region.imageExtent.width = imageExtent.width;
-        region.imageExtent.height = imageExtent.height;
+                region.imageSubresource.baseArrayLayer = textureCopy.origin.z;
+                region.imageSubresource.layerCount = copySize.depth;
 
-        ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
-        region.imageSubresource.layerCount = copySize.depth;
-        region.imageExtent.depth = 1;
+                Extent3D imageExtent = ComputeTextureCopyExtent(textureCopy, copySize);
+                region.imageExtent.width = imageExtent.width;
+                region.imageExtent.height = imageExtent.height;
+                region.imageExtent.depth = 1;
+                break;
+            }
+
+            default:
+                UNREACHABLE();
+                break;
+        }
 
         return region;
     }
diff --git a/src/tests/end2end/CopyTests.cpp b/src/tests/end2end/CopyTests.cpp
index d447f3e..5d592a1 100644
--- a/src/tests/end2end/CopyTests.cpp
+++ b/src/tests/end2end/CopyTests.cpp
@@ -669,10 +669,6 @@
 
 // Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
 TEST_P(CopyTests_T2B, Texture2DArrayRegion) {
-    // TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layer fail
-    // with swiftshader.
-    DAWN_SKIP_TEST_IF(IsSwiftshader());
-
     constexpr uint32_t kWidth = 256;
     constexpr uint32_t kHeight = 128;
     constexpr uint32_t kLayers = 6u;
@@ -687,10 +683,6 @@
 
 // Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
 TEST_P(CopyTests_T2B, Texture2DArraySubRegion) {
-    // TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layer fail
-    // with swiftshader.
-    DAWN_SKIP_TEST_IF(IsSwiftshader());
-
     constexpr uint32_t kWidth = 256;
     constexpr uint32_t kHeight = 128;
     constexpr uint32_t kLayers = 6u;
@@ -1044,10 +1036,6 @@
 
 // Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
 TEST_P(CopyTests_B2T, Texture2DArrayRegion) {
-    // TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layers fail
-    // with swiftshader.
-    DAWN_SKIP_TEST_IF(IsSwiftshader());
-
     constexpr uint32_t kWidth = 256;
     constexpr uint32_t kHeight = 128;
     constexpr uint32_t kLayers = 6u;
@@ -1062,10 +1050,6 @@
 
 // Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
 TEST_P(CopyTests_B2T, Texture2DArraySubRegion) {
-    // TODO(jiawei.shao@intel.com): investigate why copies with multiple texture array layers fail
-    // with swiftshader.
-    DAWN_SKIP_TEST_IF(IsSwiftshader());
-
     constexpr uint32_t kWidth = 256;
     constexpr uint32_t kHeight = 128;
     constexpr uint32_t kLayers = 6u;