// Copyright 2017 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>

#include "dawn/common/Assert.h"
#include "dawn/common/Constants.h"
#include "dawn/common/Math.h"
#include "dawn/native/Format.h"
#include "dawn/native/d3d12/TextureCopySplitter.h"
#include "dawn/native/d3d12/d3d12_platform.h"
#include "dawn/utils/TestUtils.h"
#include "dawn/webgpu_cpp_print.h"
#include "gtest/gtest.h"

namespace dawn::native::d3d12 {
namespace {

struct TextureSpec {
    uint32_t x;
    uint32_t y;
    uint32_t z;
    uint32_t width;
    uint32_t height;
    uint32_t depthOrArrayLayers;
    uint32_t texelBlockSizeInBytes;
    uint32_t blockWidth = 1;
    uint32_t blockHeight = 1;
};

struct BufferSpec {
    uint64_t offset;
    uint32_t bytesPerRow;
    uint32_t rowsPerImage;
};

// Check that each copy region fits inside the buffer footprint
void ValidateFootprints(const TextureSpec& textureSpec,
                        const BufferSpec& bufferSpec,
                        const TextureCopySubresource& copySplit,
                        wgpu::TextureDimension dimension) {
    for (uint32_t i = 0; i < copySplit.count; ++i) {
        const auto& copy = copySplit.copies[i];
        ASSERT_LE(copy.bufferOffset.x + copy.copySize.width, copy.bufferSize.width);
        ASSERT_LE(copy.bufferOffset.y + copy.copySize.height, copy.bufferSize.height);
        ASSERT_LE(copy.bufferOffset.z + copy.copySize.depthOrArrayLayers,
                  copy.bufferSize.depthOrArrayLayers);

        // If there are multiple layers, 2D texture splitter actually splits each layer
        // independently. See the details in Compute2DTextureCopySplits(). As a result,
        // if we simply expand a copy region generated by 2D texture splitter to all
        // layers, the copy region might be OOB. But that is not the approach that the
        // current 2D texture splitter is doing, although Compute2DTextureCopySubresource
        // forwards "copySize.depthOrArrayLayers" to the copy region it generated. So skip
        // the test below for 2D textures with multiple layers.
        if (textureSpec.depthOrArrayLayers <= 1 || dimension == wgpu::TextureDimension::e3D) {
            uint32_t widthInBlocks = textureSpec.width / textureSpec.blockWidth;
            uint32_t heightInBlocks = textureSpec.height / textureSpec.blockHeight;
            uint64_t minimumRequiredBufferSize =
                bufferSpec.offset +
                utils::RequiredBytesInCopy(
                    bufferSpec.bytesPerRow, bufferSpec.rowsPerImage, widthInBlocks, heightInBlocks,
                    textureSpec.depthOrArrayLayers, textureSpec.texelBlockSizeInBytes);

            // The last pixel (buffer footprint) of each copy region depends on its
            // bufferOffset and copySize. It is not the last pixel where the bufferSize
            // ends.
            ASSERT_EQ(copy.bufferOffset.x % textureSpec.blockWidth, 0u);
            ASSERT_EQ(copy.copySize.width % textureSpec.blockWidth, 0u);
            uint32_t footprintWidth = copy.bufferOffset.x + copy.copySize.width;
            ASSERT_EQ(footprintWidth % textureSpec.blockWidth, 0u);
            uint32_t footprintWidthInBlocks = footprintWidth / textureSpec.blockWidth;

            ASSERT_EQ(copy.bufferOffset.y % textureSpec.blockHeight, 0u);
            ASSERT_EQ(copy.copySize.height % textureSpec.blockHeight, 0u);
            uint32_t footprintHeight = copy.bufferOffset.y + copy.copySize.height;
            ASSERT_EQ(footprintHeight % textureSpec.blockHeight, 0u);
            uint32_t footprintHeightInBlocks = footprintHeight / textureSpec.blockHeight;

            uint64_t bufferSizeForFootprint =
                copy.alignedOffset +
                utils::RequiredBytesInCopy(bufferSpec.bytesPerRow, copy.bufferSize.height,
                                           footprintWidthInBlocks, footprintHeightInBlocks,
                                           copy.bufferSize.depthOrArrayLayers,
                                           textureSpec.texelBlockSizeInBytes);

            // The buffer footprint of each copy region should not exceed the minimum
            // required buffer size. Otherwise, pixels accessed by copy may be OOB.
            ASSERT_LE(bufferSizeForFootprint, minimumRequiredBufferSize);
        }
    }
}

// Check that the offset is aligned
void ValidateOffset(const TextureCopySubresource& copySplit) {
    for (uint32_t i = 0; i < copySplit.count; ++i) {
        ASSERT_TRUE(
            Align(copySplit.copies[i].alignedOffset, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT) ==
            copySplit.copies[i].alignedOffset);
    }
}

bool InclusiveRangesOverlap(uint32_t minA, uint32_t maxA, uint32_t minB, uint32_t maxB) {
    return (minA <= minB && minB <= maxA) || (minB <= minA && minA <= maxB);
}

// Check that no pair of copy regions intersect each other
void ValidateDisjoint(const TextureCopySubresource& copySplit) {
    for (uint32_t i = 0; i < copySplit.count; ++i) {
        const auto& a = copySplit.copies[i];
        for (uint32_t j = i + 1; j < copySplit.count; ++j) {
            const auto& b = copySplit.copies[j];
            // If textureOffset.x is 0, and copySize.width is 2, we are copying pixel 0 and
            // 1. We never touch pixel 2 on x-axis. So the copied range on x-axis should be
            // [textureOffset.x, textureOffset.x + copySize.width - 1] and both ends are
            // included.
            bool overlapX =
                InclusiveRangesOverlap(a.textureOffset.x, a.textureOffset.x + a.copySize.width - 1,
                                       b.textureOffset.x, b.textureOffset.x + b.copySize.width - 1);
            bool overlapY = InclusiveRangesOverlap(
                a.textureOffset.y, a.textureOffset.y + a.copySize.height - 1, b.textureOffset.y,
                b.textureOffset.y + b.copySize.height - 1);
            bool overlapZ = InclusiveRangesOverlap(
                a.textureOffset.z, a.textureOffset.z + a.copySize.depthOrArrayLayers - 1,
                b.textureOffset.z, b.textureOffset.z + b.copySize.depthOrArrayLayers - 1);
            ASSERT_TRUE(!overlapX || !overlapY || !overlapZ);
        }
    }
}

// Check that the union of the copy regions exactly covers the texture region
void ValidateTextureBounds(const TextureSpec& textureSpec,
                           const TextureCopySubresource& copySplit) {
    ASSERT_GT(copySplit.count, 0u);

    uint32_t minX = copySplit.copies[0].textureOffset.x;
    uint32_t minY = copySplit.copies[0].textureOffset.y;
    uint32_t minZ = copySplit.copies[0].textureOffset.z;
    uint32_t maxX = copySplit.copies[0].textureOffset.x + copySplit.copies[0].copySize.width;
    uint32_t maxY = copySplit.copies[0].textureOffset.y + copySplit.copies[0].copySize.height;
    uint32_t maxZ =
        copySplit.copies[0].textureOffset.z + copySplit.copies[0].copySize.depthOrArrayLayers;

    for (uint32_t i = 1; i < copySplit.count; ++i) {
        const auto& copy = copySplit.copies[i];
        minX = std::min(minX, copy.textureOffset.x);
        minY = std::min(minY, copy.textureOffset.y);
        minZ = std::min(minZ, copy.textureOffset.z);
        maxX = std::max(maxX, copy.textureOffset.x + copy.copySize.width);
        maxY = std::max(maxY, copy.textureOffset.y + copy.copySize.height);
        maxZ = std::max(maxZ, copy.textureOffset.z + copy.copySize.depthOrArrayLayers);
    }

    ASSERT_EQ(minX, textureSpec.x);
    ASSERT_EQ(minY, textureSpec.y);
    ASSERT_EQ(minZ, textureSpec.z);
    ASSERT_EQ(maxX, textureSpec.x + textureSpec.width);
    ASSERT_EQ(maxY, textureSpec.y + textureSpec.height);
    ASSERT_EQ(maxZ, textureSpec.z + textureSpec.depthOrArrayLayers);
}

// Validate that the number of pixels copied is exactly equal to the number of pixels in the
// texture region
void ValidatePixelCount(const TextureSpec& textureSpec, const TextureCopySubresource& copySplit) {
    uint32_t count = 0;
    for (uint32_t i = 0; i < copySplit.count; ++i) {
        const auto& copy = copySplit.copies[i];
        uint32_t copiedPixels =
            copy.copySize.width * copy.copySize.height * copy.copySize.depthOrArrayLayers;
        ASSERT_GT(copiedPixels, 0u);
        count += copiedPixels;
    }
    ASSERT_EQ(count, textureSpec.width * textureSpec.height * textureSpec.depthOrArrayLayers);
}

// Check that every buffer offset is at the correct pixel location
void ValidateBufferOffset(const TextureSpec& textureSpec,
                          const BufferSpec& bufferSpec,
                          const TextureCopySubresource& copySplit,
                          wgpu::TextureDimension dimension) {
    ASSERT_GT(copySplit.count, 0u);

    uint32_t texelsPerBlock = textureSpec.blockWidth * textureSpec.blockHeight;
    for (uint32_t i = 0; i < copySplit.count; ++i) {
        const auto& copy = copySplit.copies[i];

        uint32_t bytesPerRowInTexels =
            bufferSpec.bytesPerRow / textureSpec.texelBlockSizeInBytes * texelsPerBlock;
        uint32_t slicePitchInTexels =
            bytesPerRowInTexels * (bufferSpec.rowsPerImage / textureSpec.blockHeight);
        uint32_t absoluteTexelOffset =
            copy.alignedOffset / textureSpec.texelBlockSizeInBytes * texelsPerBlock +
            copy.bufferOffset.x / textureSpec.blockWidth * texelsPerBlock +
            copy.bufferOffset.y / textureSpec.blockHeight * bytesPerRowInTexels;

        // There is one empty row at most in a 2D copy region. However, it is not true for
        // a 3D texture copy region when we are copying the last row of each slice. We may
        // need to offset a lot rows and copy.bufferOffset.y may be big.
        if (dimension == wgpu::TextureDimension::e2D) {
            ASSERT_LE(copy.bufferOffset.y, textureSpec.blockHeight);
        }
        ASSERT_EQ(copy.bufferOffset.z, 0u);

        ASSERT_GE(absoluteTexelOffset,
                  bufferSpec.offset / textureSpec.texelBlockSizeInBytes * texelsPerBlock);
        uint32_t relativeTexelOffset = absoluteTexelOffset - bufferSpec.offset /
                                                                 textureSpec.texelBlockSizeInBytes *
                                                                 texelsPerBlock;

        uint32_t z = relativeTexelOffset / slicePitchInTexels;
        uint32_t y = (relativeTexelOffset % slicePitchInTexels) / bytesPerRowInTexels;
        uint32_t x = relativeTexelOffset % bytesPerRowInTexels;

        ASSERT_EQ(copy.textureOffset.x - textureSpec.x, x);
        ASSERT_EQ(copy.textureOffset.y - textureSpec.y, y);
        ASSERT_EQ(copy.textureOffset.z - textureSpec.z, z);
    }
}

void ValidateCopySplit(const TextureSpec& textureSpec,
                       const BufferSpec& bufferSpec,
                       const TextureCopySubresource& copySplit,
                       wgpu::TextureDimension dimension) {
    ValidateFootprints(textureSpec, bufferSpec, copySplit, dimension);
    ValidateOffset(copySplit);
    ValidateDisjoint(copySplit);
    ValidateTextureBounds(textureSpec, copySplit);
    ValidatePixelCount(textureSpec, copySplit);
    ValidateBufferOffset(textureSpec, bufferSpec, copySplit, dimension);
}

std::ostream& operator<<(std::ostream& os, const TextureSpec& textureSpec) {
    os << "TextureSpec("
       << "[(" << textureSpec.x << ", " << textureSpec.y << ", " << textureSpec.z << "), ("
       << textureSpec.width << ", " << textureSpec.height << ", " << textureSpec.depthOrArrayLayers
       << ")], " << textureSpec.texelBlockSizeInBytes << ")";
    return os;
}

std::ostream& operator<<(std::ostream& os, const BufferSpec& bufferSpec) {
    os << "BufferSpec(" << bufferSpec.offset << ", " << bufferSpec.bytesPerRow << ", "
       << bufferSpec.rowsPerImage << ")";
    return os;
}

std::ostream& operator<<(std::ostream& os, const TextureCopySubresource& copySplit) {
    os << "CopySplit" << std::endl;
    for (uint32_t i = 0; i < copySplit.count; ++i) {
        const auto& copy = copySplit.copies[i];
        os << "  " << i << ": Texture at (" << copy.textureOffset.x << ", " << copy.textureOffset.y
           << ", " << copy.textureOffset.z << "), size (" << copy.copySize.width << ", "
           << copy.copySize.height << ", " << copy.copySize.depthOrArrayLayers << ")" << std::endl;
        os << "  " << i << ": Buffer at (" << copy.bufferOffset.x << ", " << copy.bufferOffset.y
           << ", " << copy.bufferOffset.z << "), footprint (" << copy.bufferSize.width << ", "
           << copy.bufferSize.height << ", " << copy.bufferSize.depthOrArrayLayers << ")"
           << std::endl;
    }
    return os;
}

// Define base texture sizes and offsets to test with: some aligned, some unaligned
constexpr TextureSpec kBaseTextureSpecs[] = {
    {0, 0, 0, 1, 1, 1, 4},
    {0, 0, 0, 64, 1, 1, 4},
    {0, 0, 0, 128, 1, 1, 4},
    {0, 0, 0, 192, 1, 1, 4},
    {31, 16, 0, 1, 1, 1, 4},
    {64, 16, 0, 1, 1, 1, 4},
    {64, 16, 8, 1, 1, 1, 4},

    {0, 0, 0, 64, 2, 1, 4},
    {0, 0, 0, 64, 1, 2, 4},
    {0, 0, 0, 64, 2, 2, 4},
    {0, 0, 0, 128, 2, 1, 4},
    {0, 0, 0, 128, 1, 2, 4},
    {0, 0, 0, 128, 2, 2, 4},
    {0, 0, 0, 192, 2, 1, 4},
    {0, 0, 0, 192, 1, 2, 4},
    {0, 0, 0, 192, 2, 2, 4},

    {0, 0, 0, 1024, 1024, 1, 4},
    {256, 512, 0, 1024, 1024, 1, 4},
    {64, 48, 0, 1024, 1024, 1, 4},
    {64, 48, 16, 1024, 1024, 1024, 4},

    {0, 0, 0, 257, 31, 1, 4},
    {0, 0, 0, 17, 93, 1, 4},
    {59, 13, 0, 257, 31, 1, 4},
    {17, 73, 0, 17, 93, 1, 4},
    {17, 73, 59, 17, 93, 99, 4},

    {0, 0, 0, 4, 4, 1, 8, 4, 4},
    {64, 16, 0, 4, 4, 1, 8, 4, 4},
    {64, 16, 8, 4, 4, 1, 8, 4, 4},
    {0, 0, 0, 4, 4, 1, 16, 4, 4},
    {64, 16, 0, 4, 4, 1, 16, 4, 4},
    {64, 16, 8, 4, 4, 1, 16, 4, 4},

    {0, 0, 0, 1024, 1024, 1, 8, 4, 4},
    {256, 512, 0, 1024, 1024, 1, 8, 4, 4},
    {64, 48, 0, 1024, 1024, 1, 8, 4, 4},
    {64, 48, 16, 1024, 1024, 1, 8, 4, 4},
    {0, 0, 0, 1024, 1024, 1, 16, 4, 4},
    {256, 512, 0, 1024, 1024, 1, 16, 4, 4},
    {64, 48, 0, 1024, 1024, 1, 4, 16, 4},
    {64, 48, 16, 1024, 1024, 1, 16, 4, 4},
};

// Define base buffer sizes to work with: some offsets aligned, some unaligned. bytesPerRow
// is the minimum required
std::array<BufferSpec, 15> BaseBufferSpecs(const TextureSpec& textureSpec) {
    uint32_t bytesPerRow =
        Align(textureSpec.texelBlockSizeInBytes * textureSpec.width, kTextureBytesPerRowAlignment);

    auto alignNonPow2 = [](uint32_t value, uint32_t size) -> uint32_t {
        return value == 0 ? 0 : ((value - 1) / size + 1) * size;
    };

    return {
        BufferSpec{alignNonPow2(0, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(256, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(512, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(1024, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height * 2},

        BufferSpec{alignNonPow2(32, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(64, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height * 2},

        BufferSpec{alignNonPow2(31, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(257, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(384, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(511, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(513, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height},
        BufferSpec{alignNonPow2(1023, textureSpec.texelBlockSizeInBytes), bytesPerRow,
                   textureSpec.height * 2},
    };
}

// Define a list of values to set properties in the spec structs
constexpr uint32_t kCheckValues[] = {1,  2,  3,  4,   5,   6,   7,    8,     // small values
                                     16, 32, 64, 128, 256, 512, 1024, 2048,  // powers of 2
                                     15, 31, 63, 127, 257, 511, 1023, 2047,  // misalignments
                                     17, 33, 65, 129, 257, 513, 1025, 2049};

}  // namespace

class CopySplitTest : public testing::TestWithParam<wgpu::TextureDimension> {
  protected:
    void DoTest(const TextureSpec& textureSpec, const BufferSpec& bufferSpec) {
        ASSERT(textureSpec.width % textureSpec.blockWidth == 0 &&
               textureSpec.height % textureSpec.blockHeight == 0);

        wgpu::TextureDimension dimension = GetParam();
        TextureCopySubresource copySplit;
        switch (dimension) {
            case wgpu::TextureDimension::e2D: {
                copySplit = Compute2DTextureCopySubresource(
                    {textureSpec.x, textureSpec.y, textureSpec.z},
                    {textureSpec.width, textureSpec.height, textureSpec.depthOrArrayLayers},
                    {textureSpec.texelBlockSizeInBytes, textureSpec.blockWidth,
                     textureSpec.blockHeight},
                    bufferSpec.offset, bufferSpec.bytesPerRow);
                break;
            }
            case wgpu::TextureDimension::e3D: {
                copySplit = Compute3DTextureCopySplits(
                    {textureSpec.x, textureSpec.y, textureSpec.z},
                    {textureSpec.width, textureSpec.height, textureSpec.depthOrArrayLayers},
                    {textureSpec.texelBlockSizeInBytes, textureSpec.blockWidth,
                     textureSpec.blockHeight},
                    bufferSpec.offset, bufferSpec.bytesPerRow, bufferSpec.rowsPerImage);
                break;
            }
            default:
                UNREACHABLE();
                break;
        }

        ValidateCopySplit(textureSpec, bufferSpec, copySplit, dimension);

        if (HasFatalFailure()) {
            std::ostringstream message;
            message << "Failed generating splits: " << textureSpec << ", " << bufferSpec
                    << std::endl
                    << dimension << " " << copySplit << std::endl;
            FAIL() << message.str();
        }
    }
};

TEST_P(CopySplitTest, General) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
            DoTest(textureSpec, bufferSpec);
        }
    }
}

TEST_P(CopySplitTest, TextureWidth) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (uint32_t val : kCheckValues) {
            if (val % textureSpec.blockWidth != 0) {
                continue;
            }
            textureSpec.width = val;
            for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, TextureHeight) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (uint32_t val : kCheckValues) {
            if (val % textureSpec.blockHeight != 0) {
                continue;
            }
            textureSpec.height = val;
            for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, TextureX) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (uint32_t val : kCheckValues) {
            textureSpec.x = val;
            for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, TextureY) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (uint32_t val : kCheckValues) {
            textureSpec.y = val;
            for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, TexelSize) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (uint32_t texelSize : {4, 8, 16, 32, 64}) {
            textureSpec.texelBlockSizeInBytes = texelSize;
            for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, BufferOffset) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
            for (uint32_t val : kCheckValues) {
                bufferSpec.offset = textureSpec.texelBlockSizeInBytes * val;

                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, RowPitch) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
            uint32_t baseRowPitch = bufferSpec.bytesPerRow;
            for (uint32_t i = 0; i < 5; ++i) {
                bufferSpec.bytesPerRow = baseRowPitch + i * 256;

                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

TEST_P(CopySplitTest, ImageHeight) {
    for (TextureSpec textureSpec : kBaseTextureSpecs) {
        for (BufferSpec bufferSpec : BaseBufferSpecs(textureSpec)) {
            uint32_t baseImageHeight = bufferSpec.rowsPerImage;
            for (uint32_t i = 0; i < 5; ++i) {
                bufferSpec.rowsPerImage = baseImageHeight + i * 256;

                DoTest(textureSpec, bufferSpec);
            }
        }
    }
}

INSTANTIATE_TEST_SUITE_P(,
                         CopySplitTest,
                         testing::Values(wgpu::TextureDimension::e2D, wgpu::TextureDimension::e3D));

}  // namespace dawn::native::d3d12
