Fix a bug about mip dimension calculation

Mip dimension should be greater than or equal to 1, while width >> level
may lead to 0.

Bug: dawn:547

Change-Id: Ib3dfb9fbdbed0e922df6efa366598eff0ca10df2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/49506
Commit-Queue: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 921d5f4..97f7320 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -179,17 +179,13 @@
                 return DAWN_VALIDATION_ERROR("The mip level count of the resolve target must be 1");
             }
 
-            uint32_t colorAttachmentBaseMipLevel = attachment->GetBaseMipLevel();
-            const Extent3D& colorTextureSize = attachment->GetTexture()->GetSize();
-            uint32_t colorAttachmentWidth = colorTextureSize.width >> colorAttachmentBaseMipLevel;
-            uint32_t colorAttachmentHeight = colorTextureSize.height >> colorAttachmentBaseMipLevel;
-
-            uint32_t resolveTargetBaseMipLevel = resolveTarget->GetBaseMipLevel();
-            const Extent3D& resolveTextureSize = resolveTarget->GetTexture()->GetSize();
-            uint32_t resolveTargetWidth = resolveTextureSize.width >> resolveTargetBaseMipLevel;
-            uint32_t resolveTargetHeight = resolveTextureSize.height >> resolveTargetBaseMipLevel;
-            if (colorAttachmentWidth != resolveTargetWidth ||
-                colorAttachmentHeight != resolveTargetHeight) {
+            const Extent3D& colorTextureSize =
+                attachment->GetTexture()->GetMipLevelVirtualSize(attachment->GetBaseMipLevel());
+            const Extent3D& resolveTextureSize =
+                resolveTarget->GetTexture()->GetMipLevelVirtualSize(
+                    resolveTarget->GetBaseMipLevel());
+            if (colorTextureSize.width != resolveTextureSize.width ||
+                colorTextureSize.height != resolveTextureSize.height) {
                 return DAWN_VALIDATION_ERROR(
                     "The size of the resolve target must be the same as the color attachment");
             }
diff --git a/src/tests/end2end/CopyTests.cpp b/src/tests/end2end/CopyTests.cpp
index 07cbaab..e16c424 100644
--- a/src/tests/end2end/CopyTests.cpp
+++ b/src/tests/end2end/CopyTests.cpp
@@ -671,6 +671,27 @@
     }
 }
 
+// Test that copying mips when one dimension is 256-byte aligned and another dimension reach one
+// works
+TEST_P(CopyTests_T2B, TextureMipDimensionReachOne) {
+    constexpr uint32_t mipLevelCount = 4;
+    constexpr uint32_t kWidth = 256 << mipLevelCount;
+    constexpr uint32_t kHeight = 2;
+
+    TextureSpec defaultTextureSpec;
+    defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
+
+    TextureSpec textureSpec = defaultTextureSpec;
+    textureSpec.levelCount = mipLevelCount;
+
+    for (unsigned int i = 0; i < 4; ++i) {
+        textureSpec.copyLevel = i;
+        DoTest(textureSpec,
+               MinimumBufferSpec(std::max(kWidth >> i, 1u), std::max(kHeight >> i, 1u)),
+               {std::max(kWidth >> i, 1u), std::max(kHeight >> i, 1u), 1});
+    }
+}
+
 // Test that copying mips without 256-byte aligned sizes works
 TEST_P(CopyTests_T2B, TextureMipUnaligned) {
     constexpr uint32_t kWidth = 259;
diff --git a/src/utils/TestUtils.cpp b/src/utils/TestUtils.cpp
index 673ad78..acae87e 100644
--- a/src/utils/TestUtils.cpp
+++ b/src/utils/TestUtils.cpp
@@ -39,8 +39,8 @@
 
         TextureDataCopyLayout layout;
 
-        layout.mipSize = {textureSizeAtLevel0.width >> mipmapLevel,
-                          textureSizeAtLevel0.height >> mipmapLevel,
+        layout.mipSize = {std::max(textureSizeAtLevel0.width >> mipmapLevel, 1u),
+                          std::max(textureSizeAtLevel0.height >> mipmapLevel, 1u),
                           textureSizeAtLevel0.depthOrArrayLayers};
 
         layout.bytesPerRow = GetMinimumBytesPerRow(format, layout.mipSize.width);