Fixing a deprecated arrayLayer value inside Queue::WriteTexture

Chromium always sends arrayLayer instead of origin.depth since
the migration hasn't been finished yet. This wasn't caught
in Dawn's testing since we are using origin.depth everywhere.

Bug: dawn:483
Change-Id: I13b1ccfb016eea01a3291ca439457db09966e9a3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/26160
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Tomek Ponitka <tommek@google.com>
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 71a66fc..1d049b5 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -442,25 +442,6 @@
             return {};
         }
 
-        ResultOrError<TextureCopyView> FixTextureCopyView(DeviceBase* device,
-                                                          const TextureCopyView* view) {
-            TextureCopyView fixedView = *view;
-
-            if (view->arrayLayer != 0) {
-                if (view->origin.z != 0) {
-                    return DAWN_VALIDATION_ERROR("arrayLayer and origin.z cannot both be != 0");
-                } else {
-                    fixedView.origin.z = fixedView.arrayLayer;
-                    fixedView.arrayLayer = 1;
-                    device->EmitDeprecationWarning(
-                        "wgpu::TextureCopyView::arrayLayer is deprecated in favor of "
-                        "::origin::z");
-                }
-            }
-
-            return fixedView;
-        }
-
         ResultOrError<BufferCopyView> FixBufferCopyView(DeviceBase* device,
                                                         const BufferCopyView* view) {
             BufferCopyView fixedView = *view;
diff --git a/src/dawn_native/Queue.cpp b/src/dawn_native/Queue.cpp
index 900b92a..9799842 100644
--- a/src/dawn_native/Queue.cpp
+++ b/src/dawn_native/Queue.cpp
@@ -146,6 +146,12 @@
                                                size_t dataSize,
                                                const TextureDataLayout* dataLayout,
                                                const Extent3D* writeSize) {
+        // TODO(crbug.com/dawn/22): Remove once migration from GPUTextureCopyView.arrayLayer to
+        // GPUTextureCopyView.origin.z is done.
+        TextureCopyView fixedDest;
+        DAWN_TRY_ASSIGN(fixedDest, FixTextureCopyView(GetDevice(), destination));
+        destination = &fixedDest;
+
         DAWN_TRY(ValidateWriteTexture(destination, dataSize, dataLayout, writeSize));
 
         if (writeSize->width == 0 || writeSize->height == 0 || writeSize->depth == 0) {
diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp
index faddc5b..df46321 100644
--- a/src/dawn_native/Texture.cpp
+++ b/src/dawn_native/Texture.cpp
@@ -649,4 +649,24 @@
         ASSERT(!IsError());
         return mRange;
     }
+
+    ResultOrError<TextureCopyView> FixTextureCopyView(DeviceBase* device,
+                                                      const TextureCopyView* view) {
+        TextureCopyView fixedView = *view;
+
+        if (view->arrayLayer != 0) {
+            if (view->origin.z != 0) {
+                return DAWN_VALIDATION_ERROR("arrayLayer and origin.z cannot both be != 0");
+            } else {
+                fixedView.origin.z = fixedView.arrayLayer;
+                fixedView.arrayLayer = 1;
+                device->EmitDeprecationWarning(
+                    "wgpu::TextureCopyView::arrayLayer is deprecated in favor of "
+                    "::origin::z");
+            }
+        }
+
+        return fixedView;
+    }
+
 }  // namespace dawn_native
diff --git a/src/dawn_native/Texture.h b/src/dawn_native/Texture.h
index 300b370..6c027e1 100644
--- a/src/dawn_native/Texture.h
+++ b/src/dawn_native/Texture.h
@@ -177,6 +177,9 @@
         SubresourceRange mRange;
     };
 
+    ResultOrError<TextureCopyView> FixTextureCopyView(DeviceBase* device,
+                                                      const TextureCopyView* view);
+
 }  // namespace dawn_native
 
 #endif  // DAWNNATIVE_TEXTURE_H_
diff --git a/src/tests/end2end/DeprecatedAPITests.cpp b/src/tests/end2end/DeprecatedAPITests.cpp
index f0783cf..6542c54 100644
--- a/src/tests/end2end/DeprecatedAPITests.cpp
+++ b/src/tests/end2end/DeprecatedAPITests.cpp
@@ -207,9 +207,17 @@
     EXPECT_DEPRECATION_WARNING(encoder.CopyTextureToTexture(&texNewCopy, &texOldCopy, &copySize));
     EXPECT_DEPRECATION_WARNING(encoder.CopyTextureToBuffer(&texOldCopy, &bufCopy, &copySize));
     EXPECT_DEPRECATION_WARNING(encoder.CopyTextureToTexture(&texOldCopy, &texNewCopy, &copySize));
+
     wgpu::CommandBuffer command = encoder.Finish();
 
     queue.Submit(1, &command);
+
+    // TODO(dawn:483): Add other backends after implementing WriteTexture in them.
+    if (IsMetal() || IsVulkan()) {
+        std::vector<uint32_t> data = {1};
+        EXPECT_DEPRECATION_WARNING(
+            queue.WriteTexture(&texOldCopy, data.data(), 4, &bufCopy.layout, &copySize));
+    }
 }
 
 // Test that using both TextureCopyView::arrayLayer and origin.z is an error.
@@ -233,30 +241,44 @@
     encoder = device.CreateCommandEncoder();
     encoder.CopyTextureToTexture(&texErrorCopy, &texNewCopy, &copySize);
     ASSERT_DEVICE_ERROR(encoder.Finish());
+
+    // TODO(dawn:483): Add other backends after implementing WriteTexture in them.
+    if (IsMetal() || IsVulkan()) {
+        std::vector<uint32_t> data = {1};
+        ASSERT_DEVICE_ERROR(
+            queue.WriteTexture(&texErrorCopy, data.data(), 4, &bufCopy.layout, &copySize));
+    }
 }
 
 // Test that using TextureCopyView::arrayLayer is correctly taken into account
 TEST_P(TextureCopyViewArrayLayerDeprecationTests, StateTracking) {
-    wgpu::TextureCopyView texOOBCopy = MakeErrorTextureCopyView();
+    wgpu::TextureCopyView texOOBCopy = MakeOldTextureCopyView();
     texOOBCopy.arrayLayer = 2;  // Oh no, it is OOB!
     wgpu::TextureCopyView texNewCopy = MakeNewTextureCopyView();
     wgpu::BufferCopyView bufCopy = MakeBufferCopyView();
 
     wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
-    encoder.CopyBufferToTexture(&bufCopy, &texOOBCopy, &copySize);
+    EXPECT_DEPRECATION_WARNING(encoder.CopyBufferToTexture(&bufCopy, &texOOBCopy, &copySize));
     ASSERT_DEVICE_ERROR(encoder.Finish());
 
     encoder = device.CreateCommandEncoder();
-    encoder.CopyTextureToTexture(&texNewCopy, &texOOBCopy, &copySize);
+    EXPECT_DEPRECATION_WARNING(encoder.CopyTextureToTexture(&texNewCopy, &texOOBCopy, &copySize));
     ASSERT_DEVICE_ERROR(encoder.Finish());
 
     encoder = device.CreateCommandEncoder();
-    encoder.CopyTextureToBuffer(&texOOBCopy, &bufCopy, &copySize);
+    EXPECT_DEPRECATION_WARNING(encoder.CopyTextureToBuffer(&texOOBCopy, &bufCopy, &copySize));
     ASSERT_DEVICE_ERROR(encoder.Finish());
 
     encoder = device.CreateCommandEncoder();
-    encoder.CopyTextureToTexture(&texOOBCopy, &texNewCopy, &copySize);
+    EXPECT_DEPRECATION_WARNING(encoder.CopyTextureToTexture(&texOOBCopy, &texNewCopy, &copySize));
     ASSERT_DEVICE_ERROR(encoder.Finish());
+
+    // TODO(dawn:483): Add other backends after implementing WriteTexture in them.
+    if (IsMetal() || IsVulkan()) {
+        std::vector<uint32_t> data = {1};
+        EXPECT_DEPRECATION_WARNING(ASSERT_DEVICE_ERROR(
+            queue.WriteTexture(&texOOBCopy, data.data(), 4, &bufCopy.layout, &copySize)));
+    }
 }
 
 DAWN_INSTANTIATE_TEST(TextureCopyViewArrayLayerDeprecationTests,