diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp index 921d5f4176..97f7320e14 100644 --- a/src/dawn_native/CommandEncoder.cpp +++ b/src/dawn_native/CommandEncoder.cpp @@ -179,17 +179,13 @@ namespace dawn_native { 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 07cbaab68c..e16c424a9e 100644 --- a/src/tests/end2end/CopyTests.cpp +++ b/src/tests/end2end/CopyTests.cpp @@ -671,6 +671,27 @@ TEST_P(CopyTests_T2B, TextureMipAligned) { } } +// 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 673ad78732..acae87e3d6 100644 --- a/src/utils/TestUtils.cpp +++ b/src/utils/TestUtils.cpp @@ -39,8 +39,8 @@ namespace utils { 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);