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

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

using 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_TRUE(copySplit.count > 0);

        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_TRUE(copySplit.count > 0);

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