// 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.

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

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

namespace dawn {
namespace {

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

constexpr std::array<wgpu::TextureFormat, 3> kValidDepthCopyTextureFormats = {
    wgpu::TextureFormat::Depth16Unorm,
    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: {
            DAWN_ASSERT(aspect == wgpu::TextureAspect::StencilOnly);
            bytesPerPixel = 1;
            break;
        }
        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);

        // Skip formats other than Depth24PlusStencil8 if we're specifically testing with the packed
        // depth24_unorm_stencil8 toggle.
        DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("use_packed_depth24_unorm_stencil8_format") &&
                                 GetParam().mTextureFormat !=
                                     wgpu::TextureFormat::Depth24PlusStencil8);

        // 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;
        }
    }

    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::TextureBindingViewDimensionDescriptor 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::ImageCopyTexture srcView =
                utils::CreateImageCopyTexture(src, mipLevel, {0, 0, 0});
            wgpu::ImageCopyTexture dstView =
                utils::CreateImageCopyTexture(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"));

    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"));

    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"));

    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());

    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());

    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());

    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());

    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) {
        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::ImageCopyTexture imageCopyTexture =
            utils::CreateImageCopyTexture(texture, testLevel, {0, 0, 0}, aspect);
        wgpu::ImageCopyBuffer imageCopyBuffer = utils::CreateImageCopyBuffer(
            destinationBuffer, bufferCopyOffset, bytesPerRow, copyHeight);
        encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &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 {
                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_EQ(
                            expectedData.data() + copyWidth * y, destinationBuffer,
                            bufferCopyOffset + bufferOffsetPerArrayLayer + y * bytesPerRow,
                            copyWidth);
                    }
                }
            }
        }
    }
};

// Test copying the depth-only aspect into a buffer.
TEST_P(DepthCopyTests, FromDepthAspect) {
    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) {
    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) {
    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) {
    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());
    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());

    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::ImageCopyBuffer imageCopyBuffer =
            utils::CreateImageCopyBuffer(srcBuffer, bufferCopyOffset, kBytesPerRow, kHeight);
        wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(
            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(&imageCopyBuffer, &imageCopyTexture, &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(&imageCopyBuffer, &imageCopyTexture, &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::ImageCopyTexture imageCopyTexture =
            utils::CreateImageCopyTexture(depthStencilTexture, testLevel, {0, 0, 0}, aspect);
        wgpu::ImageCopyBuffer imageCopyBuffer = utils::CreateImageCopyBuffer(
            destinationBuffer, bufferCopyOffset, bytesPerRow, copyHeight);
        encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &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::ImageCopyBuffer imageCopyBuffer =
                utils::CreateImageCopyBuffer(srcBuffer, bufferCopyOffset, kBytesPerRow, kHeight);
            wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(
                depthStencilTexture, 0, {0, 0, 0}, wgpu::TextureAspect::StencilOnly);
            wgpu::Extent3D copySize = {kWidth, kHeight, 1};
            commandEncoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &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) {
    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) {
    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/dawn/2273): Failing on ANGLE/D3D11 for unknown reasons.
    DAWN_SUPPRESS_TEST_IF(IsANGLED3D11());

    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) {
    constexpr uint32_t kBufferCopyOffset = 0;
    DoCopyToStencilTest(kBufferCopyOffset);
}

// Test copying to the stencil-aspect of a texture at non-zero offset
TEST_P(StencilCopyTests, ToStencilAspectAtNonZeroOffset) {
    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) {
    // 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::TextureDataLayout dataLayout = {};
        dataLayout.bytesPerRow = kWidth >> kMipLevel;

        wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(
            depthStencilTexture, 1, {0, 0, 0}, wgpu::TextureAspect::StencilOnly);
        wgpu::Extent3D copySize = {kWidth >> kMipLevel, kHeight >> kMipLevel, 1};

        queue.WriteTexture(&imageCopyTexture, 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) {
    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) {
    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/dawn/2273): Failing on ANGLE/D3D11 for unknown reasons.
    DAWN_SUPPRESS_TEST_IF(IsANGLED3D11());
    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());

    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::ImageCopyTexture srcView =
                            utils::CreateImageCopyTexture(src, mipLevel, {0, 0, srcArrayLayer});
                        wgpu::ImageCopyTexture dstView =
                            utils::CreateImageCopyTexture(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"})},
    std::vector<wgpu::TextureFormat>(utils::kDepthAndStencilFormats.begin(),
                                     utils::kDepthAndStencilFormats.end()));

DAWN_INSTANTIATE_TEST_P(DepthCopyTests,
                        {D3D11Backend(), D3D12Backend(),
                         D3D12Backend({"d3d12_use_temp_buffer_in_depth_stencil_texture_and_buffer_"
                                       "copy_with_non_zero_buffer_offset"}),
                         MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
                        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()},
                        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(),
     // Test with the vulkan_use_s8 toggle forced on and off.
     VulkanBackend({"vulkan_use_s8"}, {}), VulkanBackend({}, {"vulkan_use_s8"})},
    std::vector<wgpu::TextureFormat>(utils::kStencilFormats.begin(), utils::kStencilFormats.end()));

DAWN_INSTANTIATE_TEST_P(StencilCopyTests_Compat,
                        {OpenGLBackend(), OpenGLESBackend()},
                        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()},
    std::vector<wgpu::TextureFormat>{wgpu::TextureFormat::Depth16Unorm,
                                     wgpu::TextureFormat::Depth32FloatStencil8,
                                     wgpu::TextureFormat::Depth24Plus});

}  // anonymous namespace
}  // namespace dawn
