// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include <algorithm>
#include <array>
#include <string>
#include <vector>

#include "src/dawn/common/Constants.h"
#include "src/dawn/common/Math.h"
#include "src/dawn/tests/DawnTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/TestUtils.h"
#include "src/dawn/utils/TextureUtils.h"
#include "src/dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

using TextureFormat = wgpu::TextureFormat;
DAWN_TEST_PARAM_STRUCT(DepthStencilCopyTestParams, TextureFormat);

constexpr std::array<wgpu::TextureFormat, 5> kValidDepthCopyTextureFormats = {
    wgpu::TextureFormat::Depth16Unorm,         wgpu::TextureFormat::Depth24Plus,
    wgpu::TextureFormat::Depth24PlusStencil8,  wgpu::TextureFormat::Depth32Float,
    wgpu::TextureFormat::Depth32FloatStencil8,
};

constexpr std::array<wgpu::TextureFormat, 1> kValidDepthCopyFromBufferFormats = {
    wgpu::TextureFormat::Depth16Unorm,
};

uint32_t GetBytesPerPixel(wgpu::TextureFormat format, wgpu::TextureAspect aspect) {
    uint32_t bytesPerPixel = 0;
    switch (format) {
        case wgpu::TextureFormat::Depth24PlusStencil8:
        case wgpu::TextureFormat::Depth32FloatStencil8: {
            switch (aspect) {
                case wgpu::TextureAspect::DepthOnly:
                    bytesPerPixel = 4;
                    break;
                case wgpu::TextureAspect::StencilOnly:
                    bytesPerPixel = 1;
                    break;
                default:
                    DAWN_UNREACHABLE();
                    break;
            }
            break;
        }
        default:
            bytesPerPixel = utils::GetTexelBlockSizeInBytes(format);
            break;
    }
    return bytesPerPixel;
}

// Bytes of unorm 16 of 0.23 is 0x3AE1, of which the 2 bytes are different.
// This helps better test unorm 16 compute emulation path.
constexpr float kInitDepth = 0.23f;

// Bytes of unorm 16 of 0.23 is 0xB0A3.
// Use a non-zero clear depth to better test unorm16 compute emulation path.
constexpr float kClearDepth = 0.69f;

// Initialize other mip levels with differrent garbage values for better testing
constexpr float kGarbageDepth = 0.123456789f;

static_assert(kInitDepth != kGarbageDepth);
static_assert(kClearDepth != kGarbageDepth);

constexpr uint8_t kInitStencil = 1u;
constexpr uint8_t kClearStencil = 0u;
constexpr uint8_t kGarbageStencil = 99u;

static_assert(kInitStencil != kGarbageStencil);
static_assert(kClearStencil != kGarbageStencil);

class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestParams> {
  protected:
    void SetUp() override {
        DawnTestWithParams<DepthStencilCopyTestParams>::SetUp();

        DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);

        // TODO(crbug.com/473870505): [Capture] support depth/stencil and multi-planar textures.
        DAWN_SUPPRESS_TEST_IF(IsCaptureReplayCheckingEnabled());

        // Draw a square in the bottom left quarter of the screen.
        mVertexModule = utils::CreateShaderModule(device, R"(
            @vertex
            fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array(
                    vec2f(-1.0, -1.0),
                    vec2f( 0.0, -1.0),
                    vec2f(-1.0,  0.0),
                    vec2f(-1.0,  0.0),
                    vec2f( 0.0, -1.0),
                    vec2f( 0.0,  0.0));
                return vec4f(pos[VertexIndex], 0.0, 1.0);
            })");
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        switch (GetParam().mTextureFormat) {
            case wgpu::TextureFormat::Depth32FloatStencil8:
                if (SupportsFeatures({wgpu::FeatureName::Depth32FloatStencil8})) {
                    mIsFormatSupported = true;
                    return {wgpu::FeatureName::Depth32FloatStencil8};
                }
                return {};
            default:
                mIsFormatSupported = true;
                return {};
        }
    }

    bool IsValidDepthCopyTextureFormat() {
        switch (GetParam().mTextureFormat) {
            case wgpu::TextureFormat::Depth16Unorm:
            case wgpu::TextureFormat::Depth32Float:
            case wgpu::TextureFormat::Depth32FloatStencil8:
                return true;
            default:
                return false;
        }
    }

    // Can you use this the format as the source to T2T or T2B.
    bool IsValidDepthCopySourceTextureFormat() {
        switch (GetParam().mTextureFormat) {
            case wgpu::TextureFormat::Depth16Unorm:
            case wgpu::TextureFormat::Depth32Float:
            case wgpu::TextureFormat::Depth32FloatStencil8:
                return true;
            case wgpu::TextureFormat::Depth24Plus:
            case wgpu::TextureFormat::Depth24PlusStencil8:
                return HasToggleEnabled("use_blit_for_depth24plus_texture_to_buffer_copy");
            default:
                return false;
        }
    }

    wgpu::Texture CreateTexture(
        uint32_t width,
        uint32_t height,
        wgpu::TextureUsage usage,
        uint32_t mipLevelCount = 1,
        uint32_t arrayLayerCount = 1,
        wgpu::TextureViewDimension bindingViewDimension = wgpu::TextureViewDimension::Undefined) {
        wgpu::TextureDescriptor texDescriptor = {};
        texDescriptor.size = {width, height, arrayLayerCount};
        texDescriptor.format = GetParam().mTextureFormat;
        texDescriptor.usage = usage;
        texDescriptor.mipLevelCount = mipLevelCount;
        // Test cube texture copy for compat.
        wgpu::TextureBindingViewDimension textureBindingViewDimensionDesc;
        if (IsCompatibilityMode() &&
            bindingViewDimension != wgpu::TextureViewDimension::Undefined) {
            textureBindingViewDimensionDesc.textureBindingViewDimension = bindingViewDimension;
            texDescriptor.nextInChain = &textureBindingViewDimensionDesc;
        }
        return device.CreateTexture(&texDescriptor);
    }

    wgpu::Texture CreateDepthTexture(uint32_t width,
                                     uint32_t height,
                                     wgpu::TextureUsage usage,
                                     uint32_t mipLevelCount = 1) {
        wgpu::TextureDescriptor texDescriptor = {};
        texDescriptor.size = {width, height, 1};
        texDescriptor.format = GetParam().mTextureFormat;
        texDescriptor.usage = usage;
        texDescriptor.mipLevelCount = mipLevelCount;
        return device.CreateTexture(&texDescriptor);
    }

    // Initialize the depth/stencil values for the texture using a render pass.
    // The texture will be cleared to the "clear" values, and then bottom left corner will
    // be written with the "region" values.
    void InitializeDepthStencilTextureRegion(wgpu::Texture texture,
                                             float clearDepth,
                                             float regionDepth,
                                             uint8_t clearStencil,
                                             uint8_t regionStencil,
                                             uint32_t mipLevel = 0,
                                             uint32_t arrayLayer = 0,
                                             uint32_t arrayLayerCount = 1) {
        wgpu::TextureFormat format = GetParam().mTextureFormat;
        // Create the render pass used for the initialization.
        utils::ComboRenderPipelineDescriptor renderPipelineDesc;
        renderPipelineDesc.vertex.module = mVertexModule;
        renderPipelineDesc.cFragment.targetCount = 0;

        wgpu::DepthStencilState* depthStencil = renderPipelineDesc.EnableDepthStencil(format);

        if (utils::IsStencilOnlyFormat(format)) {
            depthStencil->depthCompare = wgpu::CompareFunction::Always;
            renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, R"(
                @fragment fn main() {}
            )");
        } else {
            depthStencil->depthWriteEnabled = wgpu::OptionalBool::True;
            renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, std::string(R"(
                @fragment fn main() -> @builtin(frag_depth) f32 {
                    return )" + std::to_string(regionDepth) + R"(;
                })")
                                                                                        .c_str());
        }
        if (!utils::IsDepthOnlyFormat(format)) {
            depthStencil->stencilFront.passOp = wgpu::StencilOperation::Replace;
        }

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

        for (uint32_t curArrayLayer = 0; curArrayLayer < arrayLayerCount; curArrayLayer++) {
            // Build the render pass used for initialization.
            wgpu::TextureViewDescriptor viewDesc = {};
            viewDesc.baseMipLevel = mipLevel;
            viewDesc.mipLevelCount = 1;
            viewDesc.baseArrayLayer = arrayLayer + curArrayLayer;
            viewDesc.arrayLayerCount = 1;

            utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc));
            renderPassDesc.UnsetDepthStencilLoadStoreOpsForFormat(format);
            // TODO(dawn:1782): use different clear values for each array layer.
            renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = clearDepth;
            renderPassDesc.cDepthStencilAttachmentInfo.stencilClearValue = clearStencil;

            // Draw the quad (two triangles)
            wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPassDesc);
            pass.SetPipeline(pipeline);
            pass.SetStencilReference(regionStencil);
            pass.Draw(6);
            pass.End();
        }

        wgpu::CommandBuffer commands = commandEncoder.Finish();
        queue.Submit(1, &commands);
    }

    wgpu::Texture CreateInitializeDepthStencilTextureAndCopyT2T(float clearDepth,
                                                                float regionDepth,
                                                                uint8_t clearStencil,
                                                                uint8_t regionStencil,
                                                                uint32_t width,
                                                                uint32_t height,
                                                                wgpu::TextureUsage usage,
                                                                uint32_t mipLevel = 0) {
        wgpu::Texture src = CreateTexture(
            width, height, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc,
            mipLevel + 1);

        wgpu::Texture dst =
            CreateTexture(width, height, usage | wgpu::TextureUsage::CopyDst, mipLevel + 1);

        InitializeDepthStencilTextureRegion(src, clearDepth, regionDepth, clearStencil,
                                            regionStencil, mipLevel);

        // Perform a T2T copy of all aspects
        {
            wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
            wgpu::TexelCopyTextureInfo srcView =
                utils::CreateTexelCopyTextureInfo(src, mipLevel, {0, 0, 0});
            wgpu::TexelCopyTextureInfo dstView =
                utils::CreateTexelCopyTextureInfo(dst, mipLevel, {0, 0, 0});
            wgpu::Extent3D copySize = {width >> mipLevel, height >> mipLevel, 1};
            commandEncoder.CopyTextureToTexture(&srcView, &dstView, &copySize);

            wgpu::CommandBuffer commands = commandEncoder.Finish();
            queue.Submit(1, &commands);
        }

        return dst;
    }

    uint32_t BufferSizeForTextureCopy(uint32_t width,
                                      uint32_t height,
                                      uint32_t depth,
                                      wgpu::TextureFormat format = wgpu::TextureFormat::RGBA8Unorm,
                                      wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                      bool alignForMultipleOf4Bytes = true) {
        uint32_t bytesPerPixel = GetBytesPerPixel(format, aspect);

        uint32_t bytesPerRow = Align(width * bytesPerPixel, kTextureBytesPerRowAlignment);

        // Bytes per image before last array layer
        uint32_t bytesPerImage = bytesPerRow * height;

        uint32_t result =
            bytesPerImage * (depth - 1) + (bytesPerRow * (height - 1) + width * bytesPerPixel);

        return alignForMultipleOf4Bytes ? Align(result, uint64_t(4)) : result;
    }

    wgpu::ShaderModule mVertexModule;

  private:
    bool mIsFormatSupported = false;
};

// Test copying both aspects in a T2T copy, then copying only stencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencil) {
    // TODO(crbug.com/344949343): Test fails on Intel D3D11 with packed depth24_unorm_stencil8.
    DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D11() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
                          HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kWidth = 4;
    constexpr uint32_t kHeight = 4;

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, kWidth, kHeight,
        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);

    // Check the stencil
    std::vector<uint8_t> expectedData = {
        1u, 1u, 1u, 1u,  //
        1u, 1u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
    };
    EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0,
                      wgpu::TextureAspect::StencilOnly);
}

// Test that part of a non-renderable stencil aspect can be copied. Notably,
// this test has different behavior on some platforms than T2TBothAspectsThenCopyStencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableStencil) {
    // Test fails on D3D11 with Intel when using packed depth24_unorm_stencil8 format.
    DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D11() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
                          HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kWidth = 4;
    constexpr uint32_t kHeight = 4;

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, kWidth, kHeight, wgpu::TextureUsage::CopySrc);

    // Check the stencil
    std::vector<uint8_t> expectedData = {
        1u, 1u, 1u, 1u,  //
        1u, 1u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
    };
    EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0,
                      wgpu::TextureAspect::StencilOnly);
}

// Test that part of a non-renderable, non-zero mip stencil aspect can be copied. Notably,
// this test has different behavior on some platforms than T2TBothAspectsThenCopyStencil.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableNonZeroMipStencil) {
    // Test fails on D3D11 with Intel when using packed depth24_unorm_stencil8 format.
    DAWN_SUPPRESS_TEST_IF(IsIntel() && IsD3D11() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
                          HasToggleEnabled("use_packed_depth24_unorm_stencil8_format"));

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, 9, 9, wgpu::TextureUsage::CopySrc, 1);

    // Check the stencil
    std::vector<uint8_t> expectedData = {
        1u, 1u, 1u, 1u,  //
        1u, 1u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
    };
    EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {4, 4}, 1,
                      wgpu::TextureAspect::StencilOnly);
}

// Test copying both aspects in a T2T copy, then copying only depth.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepth) {
    DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kWidth = 4;
    constexpr uint32_t kHeight = 4;

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, kWidth, kHeight, wgpu::TextureUsage::RenderAttachment);

    // Check the depth
    ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, kWidth, kHeight, 0, 0,
                                  {
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                  });
}

// Test copying both aspects in a T2T copy, then copying only depth at a nonzero mip.
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonZeroMipDepth) {
    DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, 8, 8, wgpu::TextureUsage::RenderAttachment, 1);

    // Check the depth
    ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, 4, 4, 0, 1,
                                  {
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                  });
}

// Test copying both aspects in a T2T copy, then copying stencil, then copying depth
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencilThenDepth) {
    DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kWidth = 4;
    constexpr uint32_t kHeight = 4;

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, kWidth, kHeight,
        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);

    // Check the stencil
    std::vector<uint8_t> expectedData = {
        1u, 1u, 1u, 1u,  //
        1u, 1u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
    };
    EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0,
                      wgpu::TextureAspect::StencilOnly);

    // Check the depth
    ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, kWidth, kHeight, 0, 0,
                                  {
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                  });
}

// Test copying both aspects in a T2T copy, then copying depth, then copying stencil
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepthThenStencil) {
    DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopyTextureFormat());

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kWidth = 4;
    constexpr uint32_t kHeight = 4;

    wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
        0.1f, 0.3f, 1u, 3u, kWidth, kHeight,
        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment);

    // Check the depth
    ExpectAttachmentDepthTestData(texture, GetParam().mTextureFormat, kWidth, kHeight, 0, 0,
                                  {
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.1, 0.1, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                      0.3, 0.3, 0.1, 0.1,  //
                                  });

    // Check the stencil
    std::vector<uint8_t> expectedData = {
        1u, 1u, 1u, 1u,  //
        1u, 1u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
        3u, 3u, 1u, 1u,  //
    };
    EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0,
                      wgpu::TextureAspect::StencilOnly);
}

class DepthCopyTests : public DepthStencilCopyTests {
  public:
    void DoCopyFromDepthTest(
        uint32_t bufferCopyOffset,
        uint32_t textureWidth,
        uint32_t textureHeight,
        uint32_t textureArrayLayerCount,
        uint32_t testLevel,
        // Test cube binding view dimension for compatibility mode
        wgpu::TextureViewDimension bindingViewDimension = wgpu::TextureViewDimension::Undefined) {
        uint32_t copyWidth = textureWidth >> testLevel;
        uint32_t copyHeight = textureHeight >> testLevel;
        wgpu::BufferDescriptor bufferDescriptor = {};
        bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        bufferDescriptor.size =
            bufferCopyOffset +
            BufferSizeForTextureCopy(copyWidth, copyHeight, textureArrayLayerCount,
                                     GetParam().mTextureFormat, wgpu::TextureAspect::DepthOnly);
        wgpu::Buffer destinationBuffer = device.CreateBuffer(&bufferDescriptor);

        DoCopyFromDepthTestWithBuffer(destinationBuffer, bufferCopyOffset, textureWidth,
                                      textureHeight, textureArrayLayerCount, testLevel, true,
                                      bindingViewDimension);
    }

    void DoCopyFromDepthTestWithBuffer(
        wgpu::Buffer destinationBuffer,
        uint32_t bufferCopyOffset,
        uint32_t textureWidth,
        uint32_t textureHeight,
        uint32_t textureArrayLayerCount,
        uint32_t testLevel,
        bool checkBufferContent,
        // Test cube binding view dimension for compatibility mode
        wgpu::TextureViewDimension bindingViewDimension = wgpu::TextureViewDimension::Undefined) {
        DAWN_TEST_UNSUPPORTED_IF(!IsValidDepthCopySourceTextureFormat());

        uint32_t mipLevelCount = testLevel + 1;
        wgpu::Texture texture =
            CreateTexture(textureWidth, textureHeight,
                          wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc,
                          mipLevelCount, textureArrayLayerCount, bindingViewDimension);

        for (uint32_t level = 0; level < mipLevelCount; level++) {
            float regionDepth = (level == testLevel) ? kInitDepth : kGarbageDepth;
            InitializeDepthStencilTextureRegion(texture, kClearDepth, regionDepth, 0, 0, level, 0,
                                                textureArrayLayerCount);
        }

        uint32_t copyWidth = textureWidth >> testLevel;
        uint32_t copyHeight = textureHeight >> testLevel;
        wgpu::Extent3D copySize = {copyWidth, copyHeight, textureArrayLayerCount};

        wgpu::TextureFormat format = GetParam().mTextureFormat;
        constexpr wgpu::TextureAspect aspect = wgpu::TextureAspect::DepthOnly;
        uint32_t bytesPerPixel = GetBytesPerPixel(format, aspect);
        uint32_t bytesPerRow = Align(copyWidth * bytesPerPixel, kTextureBytesPerRowAlignment);
        uint32_t bytesPerImage = bytesPerRow * copyHeight;

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::TexelCopyTextureInfo texelCopyTextureInfo =
            utils::CreateTexelCopyTextureInfo(texture, testLevel, {0, 0, 0}, aspect);
        wgpu::TexelCopyBufferInfo texelCopyBufferInfo = utils::CreateTexelCopyBufferInfo(
            destinationBuffer, bufferCopyOffset, bytesPerRow, copyHeight);
        encoder.CopyTextureToBuffer(&texelCopyTextureInfo, &texelCopyBufferInfo, &copySize);
        wgpu::CommandBuffer commandBuffer = encoder.Finish();
        queue.Submit(1, &commandBuffer);

        if (checkBufferContent) {
            // Expected data pattern is that kInitDepth value at bottom left corner, while other
            // region is kClearDepth. Data of each layer is the same.
            if (format == wgpu::TextureFormat::Depth16Unorm) {
                uint16_t expected = FloatToUnorm<uint16_t>(kInitDepth);
                uint16_t cleared = FloatToUnorm<uint16_t>(kClearDepth);
                std::vector<uint16_t> expectedData(copyWidth * copyHeight, cleared);
                for (uint32_t y = copyHeight / 2; y < copyHeight; y++) {
                    auto rowStart = expectedData.data() + y * copyWidth;
                    std::fill(rowStart, rowStart + copyWidth / 2, expected);
                }

                for (uint32_t z = 0; z < textureArrayLayerCount; ++z) {
                    uint32_t bufferOffsetPerArrayLayer = bytesPerImage * z;
                    for (uint32_t y = 0; y < copyHeight; ++y) {
                        EXPECT_BUFFER_U16_RANGE_EQ(
                            expectedData.data() + copyWidth * y, destinationBuffer,
                            bufferCopyOffset + bufferOffsetPerArrayLayer + y * bytesPerRow,
                            copyWidth);
                    }
                }
            } else {
                float tolerance = (format == wgpu::TextureFormat::Depth24Plus ||
                                   format == wgpu::TextureFormat::Depth24PlusStencil8)
                                      ? 3e-8f
                                      : 0.0f;
                std::vector<float> expectedData(copyWidth * copyHeight, kClearDepth);
                for (uint32_t y = copyHeight / 2; y < copyHeight; y++) {
                    auto rowStart = expectedData.data() + y * copyWidth;
                    std::fill(rowStart, rowStart + copyWidth / 2, kInitDepth);
                }

                for (uint32_t z = 0; z < textureArrayLayerCount; ++z) {
                    uint32_t bufferOffsetPerArrayLayer = bytesPerImage * z;
                    for (uint32_t y = 0; y < copyHeight; ++y) {
                        EXPECT_BUFFER_FLOAT_RANGE_TOLERANCE_EQ(
                            expectedData.data() + copyWidth * y, destinationBuffer,
                            bufferCopyOffset + bufferOffsetPerArrayLayer + y * bytesPerRow,
                            copyWidth, tolerance);
                    }
                }
            }
        }
    }
};

// Test copying the depth-only aspect into a buffer.
TEST_P(DepthCopyTests, FromDepthAspect) {
    // TODO(crbug.com/519251261): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr uint32_t kTestLevel = 0;
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Only 1 pixel at bottom left has value, test compute emulation path for unorm 16
        {2, 2},
        // Odd number texture width to test compute emulation path for unorm 16
        {3, 3},
        // float 32 needs bytesPerRow alignment
        {65, 1},
        // unorm 16 and float 32 need bytesPerRow alignment
        {129, 1},
    };
    constexpr uint32_t kTestTextureArrayLayerCounts[] = {
        1,
        2,
    };

    for (const uint32_t sizeZ : kTestTextureArrayLayerCounts) {
        for (const auto& size : kTestTextureSizes) {
            DoCopyFromDepthTest(kBufferCopyOffset, size[0], size[1], sizeZ, kTestLevel);
        }
    }
}

// Test copying the depth-only aspect into a buffer at a non-zero offset.
TEST_P(DepthCopyTests, FromDepthAspectToBufferAtNonZeroOffset) {
    // TODO(crbug.com/519251261): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kTestLevel = 0;
    constexpr uint32_t kBufferCopyOffsets[] = {4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Only 1 pixel at bottom left has value, test compute emulation path for unorm 16
        {2, 2},
        // Odd number texture width to test compute emulation path for unorm 16
        {3, 3},
        // float 32 needs bytesPerRow alignment
        {65, 1},
        // unorm 16 and float 32 need bytesPerRow alignment
        {129, 1},
    };
    constexpr uint32_t kTestTextureArrayLayerCounts[] = {
        1,
        2,
    };
    for (uint32_t offset : kBufferCopyOffsets) {
        for (const uint32_t sizeZ : kTestTextureArrayLayerCounts) {
            for (const auto& size : kTestTextureSizes) {
                DoCopyFromDepthTest(offset, size[0], size[1], sizeZ, kTestLevel);
            }
        }
    }
}

// Test copying the non-zero mip, depth-only aspect into a buffer.
TEST_P(DepthCopyTests, FromNonZeroMipDepthAspect) {
    // TODO(42242119): fail on Qualcomm Adreno X1.
    DAWN_SUPPRESS_TEST_IF(IsD3D11() && IsQualcomm());

    // TODO(477654109): This test fails for this one format on MacOS AMD 550X and 560X
    // though not on AMD Radeon Pro 5300M.
    DAWN_SUPPRESS_TEST_IF(IsMacOS() && IsAMD() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth24PlusStencil8);

    // TODO(crbug.com/519251261): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr uint32_t kWidth = 9;
    constexpr uint32_t kHeight = 9;
    DoCopyFromDepthTest(kBufferCopyOffset, kWidth, kHeight, 1, 1);
    DoCopyFromDepthTest(kBufferCopyOffset, kWidth, kHeight, 2, 2);
}

// Test buffer content outside of copy extent is preserved.
// This test is made specifially for compute blit for depth16unorm emulation path.
// The texel size is 2 byte, while in the compute shader we have to write 4 byte at a time.
// When the copy extent width is an odd number, buffer content outside of the copy range is
// inevitably written. So we need to make sure the original content of the buffer that's outside of
// the copy extent is still correctly preserved.
TEST_P(DepthCopyTests, PreserveBufferContent) {
    constexpr uint32_t kBufferCopyOffsets[] = {0u, 4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        {1, 1},
        {1, 2},
        {3, 3},
    };
    constexpr uint32_t kExtraBufferSize[] = {0u, 4u};
    const uint32_t kSizeZ = 1;
    constexpr uint32_t kTestLevel = 0;

    wgpu::TextureFormat format = GetParam().mTextureFormat;
    constexpr wgpu::TextureAspect aspect = wgpu::TextureAspect::DepthOnly;

    for (uint32_t extraBufferSize : kExtraBufferSize) {
        for (uint32_t offset : kBufferCopyOffsets) {
            for (const auto& size : kTestTextureSizes) {
                wgpu::BufferDescriptor bufferDescriptor = {};
                // Add wgpu::BufferUsage::MapRead to check the buffer content with mapAsync
                bufferDescriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
                bufferDescriptor.size =
                    extraBufferSize + offset +
                    BufferSizeForTextureCopy(size[0], size[1], kSizeZ, format, aspect);
                bufferDescriptor.mappedAtCreation = true;
                wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
                constexpr uint8_t kOriginalValue = 0xff;
                {
                    // Fill the buffer with an original value other than 0 to check they are
                    // incorrectly overwritten outside of the copy range.
                    uint8_t* ptr = static_cast<uint8_t*>(buffer.GetMappedRange());
                    std::fill(ptr, ptr + bufferDescriptor.size, kOriginalValue);
                    buffer.Unmap();
                }

                // Don't check copy region content because the buffer doesn't have
                // wgpu::BufferUsage::CopySrc usage.
                DoCopyFromDepthTestWithBuffer(buffer, offset, size[0], size[1], kSizeZ, kTestLevel,
                                              false);

                std::vector<uint8_t> expected(bufferDescriptor.size, kOriginalValue);
                // Get the offset of the end of the copy range (without aligning with 4 bytes)
                uint32_t bufferEndOffset =
                    offset +
                    BufferSizeForTextureCopy(size[0], size[1], kSizeZ, format, aspect, false);
                if (bufferDescriptor.size > bufferEndOffset) {
                    // Cannot use EXPECT_BUFFER_* helper here because it needs to align the copy
                    // size to a multiple of 4 bytes to call CopyBufferToBuffer. We are checking
                    // against format like Depth16Unorm so we need offset to be multiple of 2.
                    MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, wgpu::kWholeMapSize);
                    const uint8_t* ptr = static_cast<const uint8_t*>(buffer.GetConstMappedRange());

                    // Check the content before copy range.
                    for (uint32_t i = 0; i < offset; i++) {
                        EXPECT_EQ(ptr[i], kOriginalValue);
                    }

                    // Check the content after copy range.
                    uint32_t checkSize = bufferDescriptor.size - bufferEndOffset;
                    for (uint32_t i = 0; i < checkSize; i++) {
                        EXPECT_EQ(ptr[bufferEndOffset + i], kOriginalValue);
                    }
                    buffer.Unmap();
                }
            }
        }
    }
}

// Test compact buffer size edge case.
// This test is made specifially for compute blit for depth16unorm emulation path.
// When format is depth16unorm and width is an odd number, the size of the most compact buffer copy
// target can be something that's not a multiple of 4. We need to make sure access don't go out of
// bounds in the shader, when still writing to array<u32> in the compute shader.
TEST_P(DepthCopyTests, BufferCopySizeEdgeCase) {
    constexpr uint32_t kBufferCopyOffsets[] = {0u, 4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Cannot create compact copy buffer for {1, 1} here as storage buffer binding requires size
        // of at least 4 bytes.
        {3, 1},
        {1, 2},
        {3, 3},
    };
    const uint32_t kSizeZ = 1;
    constexpr uint32_t kTestLevel = 0;

    wgpu::TextureFormat format = GetParam().mTextureFormat;
    constexpr wgpu::TextureAspect aspect = wgpu::TextureAspect::DepthOnly;

    for (uint32_t offset : kBufferCopyOffsets) {
        for (const auto& size : kTestTextureSizes) {
            wgpu::BufferDescriptor bufferDescriptor = {};
            // Add wgpu::BufferUsage::MapRead to check the buffer content with mapAsync
            bufferDescriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
            bufferDescriptor.size =
                offset +
                // Don't align for 4 bytes to get the smallest possible buffer for depth16unorm.
                BufferSizeForTextureCopy(size[0], size[1], kSizeZ, format, aspect, false);
            wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);

            // Don't check copy region content because the buffer doesn't have
            // wgpu::BufferUsage::CopySrc usage.
            DoCopyFromDepthTestWithBuffer(buffer, offset, size[0], size[1], kSizeZ, kTestLevel,
                                          false);

            // Unable to check the result since either MapAsync and CopyBufferToBuffer requires size
            // to be multiple of 4 bytes.
            // Just run and don't crash on DAWN_ASSERT.
        }
    }
}

class DepthCopyTests_Compat : public DepthCopyTests {
    void SetUp() override {
        DepthCopyTests::SetUp();
        DAWN_SUPPRESS_TEST_IF(!IsCompatibilityMode());
    }

  public:
    static constexpr uint32_t kCubeTextureLayerCount = 6;
};

// Test copying the depth-only aspect into a buffer.
TEST_P(DepthCopyTests_Compat, FromDepthAspect_Cube) {
    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr uint32_t kTestLevel = 0;
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Only 1 pixel at bottom left has value, test compute emulation path for unorm 16
        {2, 2},
        // Odd number texture width to test compute emulation path for unorm 16
        {3, 3},
        // unorm 16 and float 32 need bytesPerRow alignment
        {129, 129},
    };

    for (const auto& size : kTestTextureSizes) {
        DoCopyFromDepthTest(kBufferCopyOffset, size[0], size[1], kCubeTextureLayerCount, kTestLevel,
                            wgpu::TextureViewDimension::Cube);
    }
}

// Test copying the depth-only aspect into a buffer at a non-zero offset.
TEST_P(DepthCopyTests_Compat, FromDepthAspectToBufferAtNonZeroOffset) {
    constexpr uint32_t kTestLevel = 0;
    constexpr uint32_t kBufferCopyOffsets[] = {4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Only 1 pixel at bottom left has value, test compute emulation path for unorm 16
        {2, 2},
        // Odd number texture width to test compute emulation path for unorm 16
        {3, 3},
        // unorm 16 and float 32 need bytesPerRow alignment
        {129, 129},
    };
    for (uint32_t offset : kBufferCopyOffsets) {
        for (const auto& size : kTestTextureSizes) {
            DoCopyFromDepthTest(offset, size[0], size[1], kCubeTextureLayerCount, kTestLevel,
                                wgpu::TextureViewDimension::Cube);
        }
    }
}

// Test copying the non-zero mip, depth-only aspect into a buffer.
TEST_P(DepthCopyTests_Compat, FromNonZeroMipDepthAspect) {
    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr uint32_t kWidth = 9;
    constexpr uint32_t kHeight = 9;
    DoCopyFromDepthTest(kBufferCopyOffset, kWidth, kHeight, kCubeTextureLayerCount, 1,
                        wgpu::TextureViewDimension::Cube);
    DoCopyFromDepthTest(kBufferCopyOffset, kWidth, kHeight, kCubeTextureLayerCount, 2,
                        wgpu::TextureViewDimension::Cube);
}

class DepthCopyFromBufferTests : public DepthStencilCopyTests {
  public:
    void DoTest(uint32_t bufferCopyOffset, bool hasRenderAttachmentUsage) {
        constexpr uint32_t kWidth = 8;
        constexpr uint32_t kHeight = 1;

        wgpu::TextureUsage textureUsage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc;
        // On D3D12 backend the resource flag D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL is set only
        // when wgpu::TextureUsage::RenderAttachment is set on the creation of a depth stencil
        // texture.
        if (hasRenderAttachmentUsage) {
            textureUsage |= wgpu::TextureUsage::RenderAttachment;
        }
        wgpu::Texture destTexture = CreateTexture(kWidth, kHeight, textureUsage);

        wgpu::BufferDescriptor descriptor;
        descriptor.size = bufferCopyOffset +
                          BufferSizeForTextureCopy(kWidth, kHeight, 1, GetParam().mTextureFormat);
        descriptor.usage = wgpu::BufferUsage::CopySrc;
        descriptor.mappedAtCreation = true;
        wgpu::Buffer srcBuffer = device.CreateBuffer(&descriptor);

        constexpr uint32_t kBytesPerRow = kTextureBytesPerRowAlignment;
        wgpu::TexelCopyBufferInfo texelCopyBufferInfo =
            utils::CreateTexelCopyBufferInfo(srcBuffer, bufferCopyOffset, kBytesPerRow, kHeight);
        wgpu::TexelCopyTextureInfo texelCopyTextureInfo = utils::CreateTexelCopyTextureInfo(
            destTexture, 0, {0, 0, 0}, wgpu::TextureAspect::DepthOnly);
        wgpu::Extent3D extent = {kWidth, kHeight, 1};

        // This expectation is the test as it performs the CopyTextureToBuffer.
        if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
            uint16_t expected = FloatToUnorm<uint16_t>(kInitDepth);
            std::vector<uint16_t> expectedData = {
                0, 0, expected, expected, 0, 0, expected, expected,
            };
            size_t expectedSize = expectedData.size() * sizeof(uint16_t);
            memcpy(srcBuffer.GetMappedRange(bufferCopyOffset, expectedSize), expectedData.data(),
                   expectedSize);
            srcBuffer.Unmap();

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyBufferToTexture(&texelCopyBufferInfo, &texelCopyTextureInfo, &extent);
            wgpu::CommandBuffer commands = encoder.Finish();
            queue.Submit(1, &commands);

            EXPECT_TEXTURE_EQ(expectedData.data(), destTexture, {0, 0}, {kWidth, kHeight}, 0,
                              wgpu::TextureAspect::DepthOnly);
        } else {
            std::vector<float> expectedData = {
                0.0, 0.0, kInitDepth, kInitDepth, 0.0, 0.0, kInitDepth, kInitDepth,
            };
            size_t expectedSize = expectedData.size() * sizeof(float);

            memcpy(srcBuffer.GetMappedRange(bufferCopyOffset, expectedSize), expectedData.data(),
                   expectedSize);
            srcBuffer.Unmap();

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyBufferToTexture(&texelCopyBufferInfo, &texelCopyTextureInfo, &extent);
            wgpu::CommandBuffer commands = encoder.Finish();
            queue.Submit(1, &commands);

            EXPECT_TEXTURE_EQ(expectedData.data(), destTexture, {0, 0}, {kWidth, kHeight}, 0,
                              wgpu::TextureAspect::DepthOnly);
        }
    }
};

// Test copying the depth-only aspect from a buffer.
TEST_P(DepthCopyFromBufferTests, BufferToDepthAspect) {
    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr bool kIsRenderable = false;
    DoTest(kBufferCopyOffset, kIsRenderable);
}

// Test copying the depth-only aspect from a buffer at a non-zero offset.
TEST_P(DepthCopyFromBufferTests, BufferToNonRenderableDepthAspectAtNonZeroOffset) {
    constexpr std::array<uint32_t, 2> kBufferCopyOffsets = {8, 512};
    constexpr bool kIsRenderable = false;
    for (uint32_t offset : kBufferCopyOffsets) {
        DoTest(offset, kIsRenderable);
    }
}

// Test copying the depth-only aspect from a buffer at a non-zero offset.
TEST_P(DepthCopyFromBufferTests, BufferToRenderableDepthAspectAtNonZeroOffset) {
    constexpr std::array<uint32_t, 2> kBufferCopyOffsets = {8, 512};
    constexpr bool kIsRenderable = true;
    for (uint32_t offset : kBufferCopyOffsets) {
        DoTest(offset, kIsRenderable);
    }
}

class StencilCopyTests : public DepthStencilCopyTests {
  public:
    void DoCopyFromStencilTest(
        uint32_t bufferCopyOffset,
        uint32_t textureWidth,
        uint32_t textureHeight,
        uint32_t textureArrayLayerCount,
        uint32_t testLevel,
        // Test cube binding view dimension for compatibility mode
        wgpu::TextureViewDimension bindingViewDimension = wgpu::TextureViewDimension::Undefined) {
        uint32_t copyWidth = textureWidth >> testLevel;
        uint32_t copyHeight = textureHeight >> testLevel;
        wgpu::BufferDescriptor bufferDescriptor = {};
        bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        bufferDescriptor.size =
            bufferCopyOffset +
            BufferSizeForTextureCopy(copyWidth, copyHeight, textureArrayLayerCount,
                                     GetParam().mTextureFormat, wgpu::TextureAspect::StencilOnly);
        wgpu::Buffer destinationBuffer = device.CreateBuffer(&bufferDescriptor);

        DoCopyFromStencilTestWithBuffer(destinationBuffer, bufferCopyOffset, textureWidth,
                                        textureHeight, textureArrayLayerCount, testLevel, true);
    }
    void DoCopyFromStencilTestWithBuffer(wgpu::Buffer destinationBuffer,
                                         uint32_t bufferCopyOffset,
                                         uint32_t textureWidth,
                                         uint32_t textureHeight,
                                         uint32_t textureArrayLayerCount,
                                         uint32_t testLevel,
                                         bool checkBufferContent) {
        uint32_t mipLevelCount = testLevel + 1;
        wgpu::Texture depthStencilTexture =
            CreateTexture(textureWidth, textureHeight,
                          wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc,
                          mipLevelCount, textureArrayLayerCount);

        for (uint32_t level = 0; level < mipLevelCount; level++) {
            uint8_t regionStencil = (level == testLevel) ? kInitStencil : kGarbageStencil;
            InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, kClearStencil,
                                                regionStencil, testLevel, 0,
                                                textureArrayLayerCount);
        }

        uint32_t copyWidth = textureWidth >> testLevel;
        uint32_t copyHeight = textureHeight >> testLevel;
        wgpu::Extent3D copySize = {copyWidth, copyHeight, textureArrayLayerCount};

        // Expected data pattern is that kInitStencil value at bottom left corner, while other
        // region is kClearStencil.

        wgpu::TextureFormat format = GetParam().mTextureFormat;
        constexpr wgpu::TextureAspect aspect = wgpu::TextureAspect::StencilOnly;
        uint32_t bytesPerPixel = GetBytesPerPixel(format, aspect);
        uint32_t bytesPerRow = Align(copyWidth * bytesPerPixel, kTextureBytesPerRowAlignment);
        uint32_t bytesPerImage = bytesPerRow * copyHeight;

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::TexelCopyTextureInfo texelCopyTextureInfo =
            utils::CreateTexelCopyTextureInfo(depthStencilTexture, testLevel, {0, 0, 0}, aspect);
        wgpu::TexelCopyBufferInfo texelCopyBufferInfo = utils::CreateTexelCopyBufferInfo(
            destinationBuffer, bufferCopyOffset, bytesPerRow, copyHeight);
        encoder.CopyTextureToBuffer(&texelCopyTextureInfo, &texelCopyBufferInfo, &copySize);
        wgpu::CommandBuffer commandBuffer = encoder.Finish();
        queue.Submit(1, &commandBuffer);

        if (checkBufferContent) {
            std::vector<uint8_t> expectedData(copyWidth * copyHeight, kClearStencil);
            // std::fill(expectedData.data(), expectedData.data() + expectedData.size(), 0x77);
            for (uint32_t y = copyHeight / 2; y < copyHeight; y++) {
                auto rowStart = expectedData.data() + y * copyWidth;
                std::fill(rowStart, rowStart + copyWidth / 2, kInitStencil);
            }

            for (uint32_t z = 0; z < textureArrayLayerCount; ++z) {
                uint32_t bufferOffsetPerArrayLayer = bytesPerImage * z;
                for (uint32_t y = 0; y < copyHeight; ++y) {
                    EXPECT_BUFFER_U8_RANGE_EQ(
                        expectedData.data() + copyWidth * y, destinationBuffer,
                        bufferCopyOffset + bufferOffsetPerArrayLayer + y * bytesPerRow, copyWidth);
                }
            }
        }
    }

    void DoCopyToStencilTest(uint32_t bufferCopyOffset) {
        // Create a stencil texture
        constexpr uint32_t kWidth = 4;
        constexpr uint32_t kHeight = 4;
        const bool hasDepth = !utils::IsStencilOnlyFormat(GetParam().mTextureFormat);

        wgpu::Texture depthStencilTexture =
            CreateTexture(kWidth, kHeight,
                          wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc |
                              wgpu::TextureUsage::CopyDst);

        if (hasDepth) {
            wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();

            // Clear depth to 0.7, so we can check that the stencil copy doesn't mutate the depth.
            utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
            passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(GetParam().mTextureFormat);
            passDescriptor.cDepthStencilAttachmentInfo.depthClearValue = 0.7;

            wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
            pass.End();

            wgpu::CommandBuffer commands = commandEncoder.Finish();
            queue.Submit(1, &commands);
        }

        std::vector<uint8_t> stencilData = {
            1u,  2u,  3u,  4u,   //
            5u,  6u,  7u,  8u,   //
            9u,  10u, 11u, 12u,  //
            13u, 14u, 15u, 16u,  //
        };

        // After copying stencil data in, we will decrement stencil values in the bottom left
        // of the screen. This is the expected result.
        std::vector<uint8_t> expectedStencilData = {
            1u,  2u,  3u,  4u,   //
            5u,  6u,  7u,  8u,   //
            8u,  9u,  11u, 12u,  //
            12u, 13u, 15u, 16u,  //
        };

        // Upload the stencil data.
        {
            wgpu::BufferDescriptor descriptor;
            descriptor.size = bufferCopyOffset + BufferSizeForTextureCopy(
                                                     kWidth, kHeight, 1, GetParam().mTextureFormat,
                                                     wgpu::TextureAspect::StencilOnly);
            descriptor.usage = wgpu::BufferUsage::CopySrc;
            descriptor.mappedAtCreation = true;
            wgpu::Buffer srcBuffer = device.CreateBuffer(&descriptor);
            uint8_t* mappedPtr = static_cast<uint8_t*>(srcBuffer.GetMappedRange(bufferCopyOffset));
            constexpr uint32_t kBytesPerRow = kTextureBytesPerRowAlignment;
            for (uint32_t y = 0; y < kHeight; ++y) {
                memcpy(mappedPtr + y * kBytesPerRow, stencilData.data() + y * kWidth, kWidth);
            }
            srcBuffer.Unmap();

            wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
            wgpu::TexelCopyBufferInfo texelCopyBufferInfo = utils::CreateTexelCopyBufferInfo(
                srcBuffer, bufferCopyOffset, kBytesPerRow, kHeight);
            wgpu::TexelCopyTextureInfo texelCopyTextureInfo = utils::CreateTexelCopyTextureInfo(
                depthStencilTexture, 0, {0, 0, 0}, wgpu::TextureAspect::StencilOnly);
            wgpu::Extent3D copySize = {kWidth, kHeight, 1};
            commandEncoder.CopyBufferToTexture(&texelCopyBufferInfo, &texelCopyTextureInfo,
                                               &copySize);
            wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
            queue.Submit(1, &commandBuffer);
        }

        // Decrement the stencil value in a render pass to ensure the data is visible to the
        // pipeline.
        {
            wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
            // Create a render pipline which decrements the stencil value for passing fragments.
            // A quad is drawn in the bottom left.
            utils::ComboRenderPipelineDescriptor renderPipelineDesc;
            renderPipelineDesc.vertex.module = mVertexModule;
            renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, R"(
            @fragment fn main() {
            })");
            renderPipelineDesc.cFragment.targetCount = 0;
            wgpu::DepthStencilState* depthStencil =
                renderPipelineDesc.EnableDepthStencil(GetParam().mTextureFormat);
            depthStencil->stencilFront.passOp = wgpu::StencilOperation::DecrementClamp;
            if (!hasDepth) {
                depthStencil->depthWriteEnabled = wgpu::OptionalBool::False;
                depthStencil->depthCompare = wgpu::CompareFunction::Always;
            }

            wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&renderPipelineDesc);

            // Create a render pass which loads the stencil. We want to load the values we
            // copied in. Also load the canary depth values so they're not lost.
            utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView());
            passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
            passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
            passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(GetParam().mTextureFormat);

            // Draw the quad in the bottom left (two triangles).
            wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
            pass.SetPipeline(pipeline);
            pass.Draw(6);
            pass.End();

            wgpu::CommandBuffer commands = commandEncoder.Finish();
            queue.Submit(1, &commands);
        }

        // Copy back the stencil data and check it is correct.
        EXPECT_TEXTURE_EQ(expectedStencilData.data(), depthStencilTexture, {0, 0},
                          {kWidth, kHeight}, 0, wgpu::TextureAspect::StencilOnly);

        if (hasDepth) {
            ExpectAttachmentDepthTestData(depthStencilTexture, GetParam().mTextureFormat, kWidth,
                                          kHeight, 0, 0,
                                          {
                                              0.7, 0.7, 0.7, 0.7,  //
                                              0.7, 0.7, 0.7, 0.7,  //
                                              0.7, 0.7, 0.7, 0.7,  //
                                              0.7, 0.7, 0.7, 0.7,  //
                                          });
        }
    }
};

// Test copying the stencil-only aspect into a buffer.
TEST_P(StencilCopyTests, FromStencilAspect) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // TODO(42242119): hang/crash on Qualcomm Adreno X1.
    DAWN_SUPPRESS_TEST_IF(IsD3D11() && IsQualcomm());

    constexpr uint32_t kTestLevel = 0;
    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Test compute emulation path for stencil 8
        {2, 2},
        {3, 3},
        // stencil 8 needs bytesPerRow alignment
        {257, 1},
    };
    constexpr uint32_t kTestTextureArrayLayerCounts[] = {
        1,
        2,
    };
    for (const uint32_t sizeZ : kTestTextureArrayLayerCounts) {
        for (const auto& size : kTestTextureSizes) {
            DoCopyFromStencilTest(kBufferCopyOffset, size[0], size[1], sizeZ, kTestLevel);
        }
    }
}

// Test copying the stencil-only aspect into a buffer at a non-zero offset
TEST_P(StencilCopyTests, FromStencilAspectAtNonZeroOffset) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // TODO(42242119): hang/crash on Qualcomm Adreno X1.
    DAWN_SUPPRESS_TEST_IF(IsD3D11() && IsQualcomm());

    constexpr uint32_t kTestLevel = 0;
    constexpr std::array<uint32_t, 2> kBufferCopyOffsets = {4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Test compute emulation path for stencil 8
        {2, 2},
        {3, 3},
        // stencil 8 needs bytesPerRow alignment
        {257, 1},
    };
    constexpr uint32_t kTestTextureArrayLayerCounts[] = {
        1,
        2,
    };
    for (uint32_t offset : kBufferCopyOffsets) {
        for (const uint32_t sizeZ : kTestTextureArrayLayerCounts) {
            for (const auto& size : kTestTextureSizes) {
                DoCopyFromStencilTest(offset, size[0], size[1], sizeZ, kTestLevel);
            }
        }
    }
}

// Test copying the non-zero mip, stencil-only aspect into a buffer.
TEST_P(StencilCopyTests, FromNonZeroMipStencilAspect) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // TODO(42242119): hang/crash on Qualcomm Adreno X1.
    DAWN_SUPPRESS_TEST_IF(IsD3D11() && IsQualcomm());

    constexpr uint32_t kWidth = 9;
    constexpr uint32_t kHeight = 9;
    constexpr uint32_t kBufferCopyOffset = 0;
    DoCopyFromStencilTest(kBufferCopyOffset, kWidth, kHeight, 1, 1);
    DoCopyFromStencilTest(kBufferCopyOffset, kWidth, kHeight, 2, 2);
}

// Test buffer content outside of copy extent is preserved.
// This test is made specifially for compute blit for stencil8 emulation path.
// The texel size is 1 byte, while in the compute shader we have to write 4 byte at a time.
// When the texture width % 4 != 0, buffer content outside of the copy range is
// inevitably written. So we need to make sure the original content of the buffer that's outside of
// the copy extent is still correctly preserved.
TEST_P(StencilCopyTests, PreserveBufferContent) {
    constexpr uint32_t kBufferCopyOffsets[] = {0u, 4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        {1, 1},
        {1, 2},
        {3, 3},
    };
    constexpr uint32_t kExtraBufferSize[] = {0u, 4u};
    const uint32_t kSizeZ = 1;
    constexpr uint32_t kTestLevel = 0;

    wgpu::TextureFormat format = GetParam().mTextureFormat;
    constexpr wgpu::TextureAspect aspect = wgpu::TextureAspect::StencilOnly;

    for (uint32_t extraBufferSize : kExtraBufferSize) {
        for (uint32_t offset : kBufferCopyOffsets) {
            for (const auto& size : kTestTextureSizes) {
                wgpu::BufferDescriptor bufferDescriptor = {};
                // Add wgpu::BufferUsage::MapRead to check the buffer content with mapAsync
                bufferDescriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
                bufferDescriptor.size =
                    extraBufferSize + offset +
                    BufferSizeForTextureCopy(size[0], size[1], kSizeZ, format, aspect);
                bufferDescriptor.mappedAtCreation = true;
                wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
                constexpr uint8_t kOriginalValue = 0xff;
                {
                    // Fill the buffer with an original value other than 0 to check they are
                    // incorrectly overwritten outside of the copy range.
                    uint8_t* ptr = static_cast<uint8_t*>(buffer.GetMappedRange());
                    std::fill(ptr, ptr + bufferDescriptor.size, kOriginalValue);
                    buffer.Unmap();
                }

                // Don't check copy region content because the buffer doesn't have
                // wgpu::BufferUsage::CopySrc usage.
                DoCopyFromStencilTestWithBuffer(buffer, offset, size[0], size[1], kSizeZ,
                                                kTestLevel, false);

                std::vector<uint8_t> expected(bufferDescriptor.size, kOriginalValue);
                // Get the offset of the end of the copy range (without aligning with 4 bytes)
                uint32_t bufferEndOffset =
                    offset +
                    BufferSizeForTextureCopy(size[0], size[1], kSizeZ, format, aspect, false);
                if (bufferDescriptor.size > bufferEndOffset) {
                    // Cannot use EXPECT_BUFFER_* helper here because it needs to align the copy
                    // size to a multiple of 4 bytes to call CopyBufferToBuffer. We are checking
                    // stencil8.
                    MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, wgpu::kWholeMapSize);
                    const uint8_t* ptr = static_cast<const uint8_t*>(buffer.GetConstMappedRange());

                    // Check the content before copy range.
                    for (uint32_t i = 0; i < offset; i++) {
                        EXPECT_EQ(ptr[i], kOriginalValue);
                    }

                    // Check the content after copy range.
                    uint32_t checkSize = bufferDescriptor.size - bufferEndOffset;
                    for (uint32_t i = 0; i < checkSize; i++) {
                        EXPECT_EQ(ptr[bufferEndOffset + i], kOriginalValue);
                    }
                    buffer.Unmap();
                }
            }
        }
    }
}

// Test compact buffer size edge case.
// This test is made specifially for compute blit for stencil8 emulation path.
// When texture width % 4 != 0, the size of the most compact buffer copy
// target can be something that's not a multiple of 4. We need to make sure access don't go out of
// bounds in the shader, when still writing to array<u32> in the compute shader.
TEST_P(StencilCopyTests, BufferCopySizeEdgeCase) {
    constexpr uint32_t kBufferCopyOffsets[] = {0u, 4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Storage buffer binding requires size of at least 4 bytes.
        {5, 1}, {6, 1}, {7, 1}, {1, 2}, {2, 2}, {3, 3},
    };
    const uint32_t kSizeZ = 1;
    constexpr uint32_t kTestLevel = 0;

    wgpu::TextureFormat format = GetParam().mTextureFormat;
    constexpr wgpu::TextureAspect aspect = wgpu::TextureAspect::StencilOnly;

    for (uint32_t offset : kBufferCopyOffsets) {
        for (const auto& size : kTestTextureSizes) {
            wgpu::BufferDescriptor bufferDescriptor = {};
            // Add wgpu::BufferUsage::MapRead to check the buffer content with mapAsync
            bufferDescriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
            bufferDescriptor.size =
                offset +
                // Don't align for 4 bytes to get the smallest possible buffer for depth16unorm.
                BufferSizeForTextureCopy(size[0], size[1], kSizeZ, format, aspect, false);
            wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);

            // Don't check copy region content because the buffer doesn't have
            // wgpu::BufferUsage::CopySrc usage.
            DoCopyFromStencilTestWithBuffer(buffer, offset, size[0], size[1], kSizeZ, kTestLevel,
                                            false);

            // Unable to check the result since either MapAsync and CopyBufferToBuffer requires size
            // to be multiple of 4 bytes.
            // Just run and don't crash on DAWN_ASSERT.
        }
    }
}

// Test copying to the stencil-aspect of a texture
TEST_P(StencilCopyTests, ToStencilAspect) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    constexpr uint32_t kBufferCopyOffset = 0;
    DoCopyToStencilTest(kBufferCopyOffset);
}

// Test copying to the stencil-aspect of a texture at non-zero offset
TEST_P(StencilCopyTests, ToStencilAspectAtNonZeroOffset) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    constexpr std::array<uint32_t, 2> kBufferCopyOffsets = {8, 512};
    for (uint32_t offset : kBufferCopyOffsets) {
        DoCopyToStencilTest(offset);
    }
}

// Test uploading to the non-zero mip, stencil-only aspect of a texture,
// and then checking the contents with a stencil test.
TEST_P(StencilCopyTests, CopyNonzeroMipThenReadWithStencilTest) {
    // TODO(crbug.com/523272956): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    // Copies to a single aspect are unsupported on OpenGL.
    DAWN_TEST_UNSUPPORTED_IF(IsOpenGL());

    // Create a stencil texture
    constexpr uint32_t kWidth = 4;
    constexpr uint32_t kHeight = 4;
    constexpr uint32_t kMipLevel = 1;

    wgpu::Texture depthStencilTexture =
        CreateTexture(kWidth, kHeight,
                      wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc |
                          wgpu::TextureUsage::CopyDst,
                      kMipLevel + 1);

    std::vector<uint8_t> stencilData = {
        7u, 7u,  //
        7u, 7u,  //
    };

    // Upload the stencil data.
    {
        wgpu::TexelCopyBufferLayout dataLayout = {};
        dataLayout.bytesPerRow = kWidth >> kMipLevel;

        wgpu::TexelCopyTextureInfo texelCopyTextureInfo = utils::CreateTexelCopyTextureInfo(
            depthStencilTexture, 1, {0, 0, 0}, wgpu::TextureAspect::StencilOnly);
        wgpu::Extent3D copySize = {kWidth >> kMipLevel, kHeight >> kMipLevel, 1};

        queue.WriteTexture(&texelCopyTextureInfo, stencilData.data(), stencilData.size(),
                           &dataLayout, &copySize);
    }

    // Check the stencil contents.
    ExpectAttachmentStencilTestData(depthStencilTexture, GetParam().mTextureFormat,
                                    kWidth >> kMipLevel, kWidth >> kMipLevel, 0u, kMipLevel, 7u);
}

class StencilCopyTests_Compat : public StencilCopyTests {
    void SetUp() override {
        StencilCopyTests::SetUp();
        DAWN_SUPPRESS_TEST_IF(!IsCompatibilityMode());
    }

  public:
    static constexpr uint32_t kCubeTextureLayerCount = 6;
};

TEST_P(StencilCopyTests_Compat, FromStencilAspect) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    constexpr uint32_t kTestLevel = 0;
    constexpr uint32_t kBufferCopyOffset = 0;
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Test compute emulation path for stencil 8
        {2, 2},
        {3, 3},
        // stencil 8 needs bytesPerRow alignment
        {257, 257},
    };
    for (const auto& size : kTestTextureSizes) {
        DoCopyFromStencilTest(kBufferCopyOffset, size[0], size[1], kCubeTextureLayerCount,
                              kTestLevel);
    }
}

// Test copying the stencil-only aspect into a buffer at a non-zero offset
TEST_P(StencilCopyTests_Compat, FromStencilAspectAtNonZeroOffset) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    constexpr uint32_t kTestLevel = 0;
    constexpr std::array<uint32_t, 2> kBufferCopyOffsets = {4u, 512u};
    constexpr uint32_t kTestTextureSizes[][2] = {
        // Original test parameter
        {4, 4},
        // Test compute emulation path for stencil 8
        {2, 2},
        {3, 3},
        // stencil 8 needs bytesPerRow alignment
        {257, 257},
    };
    for (uint32_t offset : kBufferCopyOffsets) {
        for (const auto& size : kTestTextureSizes) {
            DoCopyFromStencilTest(offset, size[0], size[1], kCubeTextureLayerCount, kTestLevel);
        }
    }
}

// Test copying the non-zero mip, stencil-only aspect into a buffer.
TEST_P(StencilCopyTests_Compat, FromNonZeroMipStencilAspect) {
    // TODO(crbug.com/40238674): Fails on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    constexpr uint32_t kWidth = 9;
    constexpr uint32_t kHeight = 9;
    constexpr uint32_t kBufferCopyOffset = 0;
    DoCopyFromStencilTest(kBufferCopyOffset, kWidth, kHeight, kCubeTextureLayerCount, 1);
    DoCopyFromStencilTest(kBufferCopyOffset, kWidth, kHeight, kCubeTextureLayerCount, 2);
}

class DepthStencilCopyTests_RegressionDawn1083 : public DepthStencilCopyTests {};

// Regression test for crbug.com/dawn/1083. Checks that T2T copies with
// various mip/layer counts/offsets works.
TEST_P(DepthStencilCopyTests_RegressionDawn1083, Run) {
    // TODO(crbug.com/dawn/1648): Diagnose failure on NVIDIA GLES.
    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsNvidia());

    // TODO(crbug.com/dawn/1651): Failing on Mac AMD.
    DAWN_SUPPRESS_TEST_IF(IsAMD() && IsMetal() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth32FloatStencil8);

    // TODO(crbug.com/dawn/1828): depth16unorm broken on Apple GPUs.
    DAWN_SUPPRESS_TEST_IF(IsApple() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm);

    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());

    // TODO(crbug.com/500766618): Fails on Windows 11/AMD RX 5500 XT w/ Vulkan.
    DAWN_SUPPRESS_TEST_IF(IsWindows11() && IsAMD() && IsVulkan() &&
                          GetParam().mTextureFormat == wgpu::TextureFormat::Depth32FloatStencil8);

    // TODO(crbug.com/519296891): Produces incorrect result on Pixel 10.
    DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());

    uint32_t mipLevelCount = 3;
    uint32_t arrayLayerCount = 3;
    wgpu::TextureDescriptor texDesc = {};
    texDesc.size = {8, 8, arrayLayerCount};
    texDesc.format = GetParam().mTextureFormat;
    texDesc.mipLevelCount = mipLevelCount;

    for (uint32_t mipLevel = 0; mipLevel < mipLevelCount; ++mipLevel) {
        uint32_t mipWidth = texDesc.size.width >> mipLevel;
        uint32_t mipHeight = texDesc.size.height >> mipLevel;
        for (uint32_t srcArrayLayer = 0; srcArrayLayer < arrayLayerCount; ++srcArrayLayer) {
            for (uint32_t dstArrayLayer = 0; dstArrayLayer < arrayLayerCount; ++dstArrayLayer) {
                // Test copying 1 layer, and all possible layers.
                for (uint32_t layerCount :
                     {1u, arrayLayerCount - std::max(srcArrayLayer, dstArrayLayer)}) {
                    texDesc.usage =
                        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
                    wgpu::Texture src = device.CreateTexture(&texDesc);

                    texDesc.usage =
                        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopyDst;
                    wgpu::Texture dst = device.CreateTexture(&texDesc);

                    // Initialize texture data.
                    uint8_t stencilValue = 42;
                    float d1 = 0.1;
                    float d2 = 0.01;
                    for (uint32_t z = 0; z < layerCount; ++z) {
                        InitializeDepthStencilTextureRegion(src, d1, d2, stencilValue, stencilValue,
                                                            mipLevel, srcArrayLayer + z);
                    }

                    // Perform a T2T copy
                    {
                        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
                        wgpu::TexelCopyTextureInfo srcView =
                            utils::CreateTexelCopyTextureInfo(src, mipLevel, {0, 0, srcArrayLayer});
                        wgpu::TexelCopyTextureInfo dstView =
                            utils::CreateTexelCopyTextureInfo(dst, mipLevel, {0, 0, dstArrayLayer});
                        wgpu::Extent3D copySize = {mipWidth, mipHeight, layerCount};
                        commandEncoder.CopyTextureToTexture(&srcView, &dstView, &copySize);

                        wgpu::CommandBuffer commands = commandEncoder.Finish();
                        queue.Submit(1, &commands);
                    }

                    // Helper to compute expected depth data.
                    auto GetExpectedDepthData = [&](uint32_t mipLevel) -> std::vector<float> {
                        if (mipLevel == 0) {
                            return {
                                d1, d1, d1, d1, d1, d1, d1, d1,  //
                                d1, d1, d1, d1, d1, d1, d1, d1,  //
                                d1, d1, d1, d1, d1, d1, d1, d1,  //
                                d1, d1, d1, d1, d1, d1, d1, d1,  //
                                d2, d2, d2, d2, d1, d1, d1, d1,  //
                                d2, d2, d2, d2, d1, d1, d1, d1,  //
                                d2, d2, d2, d2, d1, d1, d1, d1,  //
                                d2, d2, d2, d2, d1, d1, d1, d1,  //
                            };
                        } else if (mipLevel == 1) {
                            return {
                                d1, d1, d1, d1,  //
                                d1, d1, d1, d1,  //
                                d2, d2, d1, d1,  //
                                d2, d2, d1, d1,  //
                            };
                        } else if (mipLevel == 2) {
                            return {
                                d1, d1,  //
                                d2, d1,  //
                            };
                        }
                        DAWN_UNREACHABLE();
                    };

                    // Check the depth
                    for (uint32_t z = 0; z < layerCount; ++z) {
                        ExpectAttachmentDepthTestData(dst, GetParam().mTextureFormat, mipWidth,
                                                      mipHeight, dstArrayLayer + z, mipLevel,
                                                      GetExpectedDepthData(mipLevel))
                            << "depth aspect" << "\nmipLevelCount: " << mipLevelCount
                            << "\narrayLayerCount: " << arrayLayerCount
                            << "\nmipLevel: " << mipLevel
                            << "\nsrcArrayLayer: " << srcArrayLayer + z
                            << "\ndstArrayLayer: " << dstArrayLayer + z;

                        // Check the stencil
                        if (!utils::IsDepthOnlyFormat(GetParam().mTextureFormat)) {
                            ExpectAttachmentStencilTestData(dst, GetParam().mTextureFormat,
                                                            mipWidth, mipHeight, dstArrayLayer + z,
                                                            mipLevel, stencilValue)
                                << "stencil aspect" << "\nmipLevelCount: " << mipLevelCount
                                << "\narrayLayerCount: " << arrayLayerCount
                                << "\nmipLevel: " << mipLevel
                                << "\nsrcArrayLayer: " << srcArrayLayer + z
                                << "\ndstArrayLayer: " << dstArrayLayer + z;
                        }
                    }
                }
            }
        }
    }
}

DAWN_INSTANTIATE_TEST_P(
    DepthStencilCopyTests,
    {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}), D3D12Backend(),
     D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
     D3D12Backend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
     MetalBackend(),
     MetalBackend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
     MetalBackend({"use_blit_for_buffer_to_depth_texture_copy",
                   "use_blit_for_buffer_to_stencil_texture_copy"}),
     OpenGLBackend(), OpenGLESBackend(),
     // Test with the vulkan_use_s8 toggle forced on and off.
     VulkanBackend({"vulkan_use_s8"}, {}), VulkanBackend({}, {"vulkan_use_s8"}), WebGPUBackend()},
    std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
                                     utils::kDepthAndStencilFormats.end()));

DAWN_INSTANTIATE_TEST_P(
    DepthCopyTests,
    {D3D11Backend(), D3D11Backend({"use_blit_for_depth24plus_texture_to_buffer_copy"}),
     D3D12Backend(),
     D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
                   "copy_with_non_zero_buffer_offset"}),
     D3D12Backend({"use_blit_for_depth24plus_texture_to_buffer_copy"}), MetalBackend(),
     MetalBackend({"use_blit_for_depth24plus_texture_to_buffer_copy"}), OpenGLBackend(),
     OpenGLBackend({"use_blit_for_depth24plus_texture_to_buffer_copy"}),

     OpenGLESBackend(), OpenGLESBackend({"use_blit_for_depth24plus_texture_to_buffer_copy"}),

     VulkanBackend(), VulkanBackend({"use_blit_for_depth24plus_texture_to_buffer_copy"}),
     WebGPUBackend()},
    std::vector<wgpu::TextureFormat>(kValidDepthCopyTextureFormats.begin(),
                                     kValidDepthCopyTextureFormats.end()));

DAWN_INSTANTIATE_TEST_P(DepthCopyTests_Compat,
                        {OpenGLBackend(), OpenGLESBackend()},
                        std::vector<wgpu::TextureFormat>(kValidDepthCopyFromBufferFormats.begin(),
                                                         kValidDepthCopyFromBufferFormats.end()));

DAWN_INSTANTIATE_TEST_P(DepthCopyFromBufferTests,
                        {D3D11Backend(), D3D12Backend(),
                         D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
                                       "copy_with_non_zero_buffer_offset"}),
                         MetalBackend(),
                         MetalBackend({"use_blit_for_buffer_to_depth_texture_copy"}),
                         OpenGLBackend(), OpenGLESBackend(), VulkanBackend(), WebGPUBackend()},
                        std::vector<wgpu::TextureFormat>(kValidDepthCopyFromBufferFormats.begin(),
                                                         kValidDepthCopyFromBufferFormats.end()));

DAWN_INSTANTIATE_TEST_P(
    StencilCopyTests,
    {D3D11Backend(), D3D11Backend({"use_packed_depth24_unorm_stencil8_format"}), D3D12Backend(),
     D3D12Backend({"use_packed_depth24_unorm_stencil8_format"}),
     D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
                   "copy_with_non_zero_buffer_offset"}),
     MetalBackend(), MetalBackend({"metal_use_combined_depth_stencil_format_for_stencil8"}),
     MetalBackend(
         {"metal_use_both_depth_and_stencil_attachments_for_combined_depth_stencil_formats"}),
     MetalBackend({"use_blit_for_buffer_to_stencil_texture_copy"}), OpenGLBackend(),
     OpenGLESBackend(), OpenGLESBackend({"gl_force_es_31_and_no_extensions"}),
     // Test with the vulkan_use_s8 toggle forced on and off.
     VulkanBackend({"vulkan_use_s8"}, {}), VulkanBackend({}, {"vulkan_use_s8"}), WebGPUBackend()},
    std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(), utils::kStencilFormats.end()));

DAWN_INSTANTIATE_TEST_P(StencilCopyTests_Compat,
                        {OpenGLBackend(), OpenGLESBackend(),
                         OpenGLESBackend({"gl_force_es_31_and_no_extensions"})},
                        std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(),
                                                         utils::kStencilFormats.end()));

DAWN_INSTANTIATE_TEST_P(
    DepthStencilCopyTests_RegressionDawn1083,
    {D3D11Backend(), D3D12Backend(),
     D3D12Backend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
     MetalBackend(),
     MetalBackend({"use_blit_for_depth_texture_to_texture_copy_to_nonzero_subresource"}),
     OpenGLBackend(), OpenGLESBackend(), VulkanBackend(), WebGPUBackend()},
    std::vector<wgpu::TextureFormat>{wgpu::TextureFormat::Depth16Unorm,
                                     wgpu::TextureFormat::Depth32FloatStencil8,
                                     wgpu::TextureFormat::Depth24Plus});

}  // anonymous namespace
}  // namespace dawn
