// Copyright 2026 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 <initializer_list>
#include <string>
#include <vector>

#include "dawn/common/Math.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

class BufferViewTest : public DawnTest {
  protected:
    void SetUp() override { DawnTest::SetUp(); }

    void BaseLengthTest(const std::string& wgsl,
                        uint32_t len,
                        uint32_t dynamicOffset,
                        const std::initializer_list<uint32_t>& uniforms,
                        const std::vector<uint32_t>& expected) {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, wgsl);

        wgpu::BindGroupLayout bgLayout = utils::MakeBindGroupLayout(
            device, {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::ReadOnlyStorage,
                      dynamicOffset != 0, len},
                     {1, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage},
                     {2, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform}});

        wgpu::PipelineLayout pipelineLayout = utils::MakePipelineLayout(device, {bgLayout});

        std::vector<wgpu::ConstantEntry> constants{{nullptr, "len", static_cast<double>(len)}};
        wgpu::ComputePipelineDescriptor desc;
        desc.layout = pipelineLayout;
        desc.compute.module = module;
        desc.compute.constants = constants.data();
        desc.compute.constantCount = constants.size();
        wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&desc);

        wgpu::BufferDescriptor srcDesc;
        srcDesc.size = len + dynamicOffset;
        srcDesc.usage =
            wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer src = device.CreateBuffer(&srcDesc);

        wgpu::BufferDescriptor outDesc;
        outDesc.size = sizeof(uint32_t) * expected.size();
        outDesc.usage =
            wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer out = device.CreateBuffer(&outDesc);

        wgpu::Buffer uni = utils::CreateBufferFromData<uint32_t>(
            device, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopySrc, uniforms);

        wgpu::BindGroup bg =
            utils::MakeBindGroup(device, bgLayout,
                                 {
                                     {0, src, 0, len},
                                     {1, out, 0, outDesc.size},
                                     {2, uni, 0, uniforms.size() * sizeof(uint32_t)},
                                 });

        std::vector<uint32_t> offsets;
        if (dynamicOffset != 0) {
            offsets.push_back(dynamicOffset);
        }
        wgpu::CommandBuffer commands;
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(pipeline);
            pass.SetBindGroup(0, bg, offsets.size(), offsets.data());
            pass.DispatchWorkgroups(1, 1, 1);
            pass.End();
            commands = encoder.Finish();
        }
        queue.Submit(1, &commands);

        EXPECT_BUFFER_U32_RANGE_EQ(&expected[0], out, 0, expected.size())
            << "Buffer length = " << len << "\n";
    }

    void TestBufferViewArrayLength(uint32_t len, uint32_t dynamicOffset) {
        const std::string src = R"(
          override len : u32;
          struct Offsets {
            a : u32,
            b : u32,
            c : u32,
          }

          @group(0) @binding(0) var<storage> in : buffer;
          @group(0) @binding(1) var<storage, read_write> out : array<u32>;
          @group(0) @binding(2) var<uniform> offsets : Offsets;

          struct S1 {
            a : vec4f,
            b : array<u32>,
          }
          struct S2 {
            a : vec4f,
            b : array<vec2u>,
          }
          struct S3 {
            a : vec4f,
            b : array<vec4u>,
          }

          @compute @workgroup_size(1)
          fn main() {
            out[0] = bufferLength(&in);

            out[1] = arrayLength(bufferView<array<u32>>(&in, offsets.a));
            out[2] = arrayLength(bufferView<array<u32>>(&in, offsets.b));
            out[3] = arrayLength(bufferView<array<u32>>(&in, offsets.c));

            out[4] = arrayLength(bufferView<array<vec2u>>(&in, offsets.a));
            out[5] = arrayLength(bufferView<array<vec2u>>(&in, offsets.b));
            out[6] = arrayLength(bufferView<array<vec2u>>(&in, offsets.c));

            out[7] = arrayLength(bufferView<array<vec3u>>(&in, offsets.a));
            out[8] = arrayLength(bufferView<array<vec3u>>(&in, offsets.b));
            out[9] = arrayLength(bufferView<array<vec3u>>(&in, offsets.c));

            out[10] = arrayLength(bufferView<array<vec4u>>(&in, offsets.a));
            out[11] = arrayLength(bufferView<array<vec4u>>(&in, offsets.b));
            out[12] = arrayLength(bufferView<array<vec4u>>(&in, offsets.c));

            out[13] = arrayLength(&bufferView<S1>(&in, offsets.a).b);
            out[14] = arrayLength(&bufferView<S1>(&in, offsets.b).b);
            out[15] = arrayLength(&bufferView<S1>(&in, offsets.c).b);

            out[16] = arrayLength(&bufferView<S2>(&in, offsets.a).b);
            out[17] = arrayLength(&bufferView<S2>(&in, offsets.b).b);
            out[18] = arrayLength(&bufferView<S2>(&in, offsets.c).b);

            out[19] = arrayLength(&bufferView<S3>(&in, offsets.a).b);
            out[20] = arrayLength(&bufferView<S3>(&in, offsets.b).b);
            out[21] = arrayLength(&bufferView<S3>(&in, offsets.c).b);
          }
        )";

        std::initializer_list<uint32_t> uniforms = {0u, 16u, 32u};

        std::vector<uint32_t> expected = {
            len,                   //
            len / 4,               //
            (len - 16) / 4,        //
            (len - 32) / 4,        //
            len / 8,               //
            (len - 16) / 8,        //
            (len - 32) / 8,        //
            len / 16,              //
            (len - 16) / 16,       //
            (len - 32) / 16,       //
            len / 16,              //
            (len - 16) / 16,       //
            (len - 32) / 16,       //
            (len - 16) / 4,        //
            (len - 16 - 16) / 4,   //
            (len - 16 - 32) / 4,   //
            (len - 16) / 8,        //
            (len - 16 - 16) / 8,   //
            (len - 16 - 32) / 8,   //
            (len - 16) / 16,       //
            (len - 16 - 16) / 16,  //
            (len - 16 - 32) / 16,  //
        };

        BaseLengthTest(src, len, dynamicOffset, uniforms, expected);
    }

    void TestBufferArrayViewArrayLength(uint32_t len, uint32_t dynamicOffset) {
        const std::string src = R"(
          override len : u32;
          @group(0) @binding(0) var<storage> in : buffer;
          @group(0) @binding(1) var<storage, read_write> out : array<u32>;
          @group(0) @binding(2) var<uniform> uniforms : array<vec4u, 2>;

          struct S1 {
            a : u32,
            b : array<u32>,
          }
          struct S2 {
            a : u32,
            b : array<vec2u>,
          }
          struct S3 {
            a : u32,
            b : array<vec4u>,
          }

          @compute @workgroup_size(1)
          fn main() {
            var i = 0u;
            out[i] = bufferLength(&in); i++;

            out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][0], uniforms[1][0])); i++;
            out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][1], uniforms[1][1])); i++;
            out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][0], uniforms[1][2])); i++;

            out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][0], uniforms[1][0])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][1], uniforms[1][1])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][0], uniforms[1][3])); i++;

            out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][0], uniforms[1][0])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][1], uniforms[1][1])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec3u>>(&in, uniforms[0][1], uniforms[1][3])); i++;

            out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][0], uniforms[1][0])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][1], uniforms[1][1])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec4u>>(&in, uniforms[0][0], uniforms[1][3])); i++;

            out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][0], uniforms[1][0]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][1], uniforms[1][1]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S1>(&in, uniforms[0][1], uniforms[1][3]).b); i++;

            out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][0], uniforms[1][0]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][1], uniforms[1][1]).b); i++;

            out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][0], uniforms[1][1]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][0], uniforms[1][3]).b); i++;
          }
        )";

        std::initializer_list<uint32_t> uniforms = {0u, 16u, 32u, 48u, 20u, 36u, 52u, len - 20u};
        std::vector<uint32_t> uniformData{uniforms};

        std::vector<uint32_t> expected = {
            len,                         //
            uniformData[4] / 4,          //
            uniformData[5] / 4,          //
            uniformData[6] / 4,          //
            uniformData[4] / 8,          //
            uniformData[5] / 8,          //
            uniformData[7] / 8,          //
            uniformData[4] / 16,         //
            uniformData[5] / 16,         //
            uniformData[7] / 16,         //
            uniformData[4] / 16,         //
            uniformData[5] / 16,         //
            uniformData[7] / 16,         //
            (uniformData[4] - 4) / 4,    //
            (uniformData[5] - 4) / 4,    //
            (uniformData[7] - 4) / 4,    //
            (uniformData[4] - 8) / 8,    //
            (uniformData[5] - 8) / 8,    //
            (uniformData[5] - 16) / 16,  //
            (uniformData[7] - 16) / 16,  //
        };

        BaseLengthTest(src, len, dynamicOffset, uniforms, expected);
    }

    void TestArrayLengthFunctions(uint32_t len) {
        const std::string wgsl = R"(
          override len : u32;
          @group(0) @binding(0) var<storage> in : buffer<)" +
                                 std::to_string(len) + R"(>;
          @group(0) @binding(1) var<storage, read_write> out : array<u32>;
          @group(0) @binding(2) var<uniform> uniforms : buffer<20>;

          var<workgroup> wg1 : buffer<64>;
          var<workgroup> wg2 : buffer<128>;
          var<workgroup> wg3 : buffer<len>;

          struct S {
            a : vec2u,
            b : array<u32>,
          }

          fn uniformLengthUnsized(p : ptr<uniform, buffer>, offset : u32) -> u32 {
            return arrayLength(bufferView<array<u32>>(p, offset));
          }

          fn uniformLengthSized(p : ptr<uniform, buffer<16>>, offset : u32) -> u32 {
            return uniformLengthUnsized(p, offset);
          }

          fn workgroupLengthUnsized(p : ptr<workgroup, buffer>, offset : u32, size : u32) -> u32 {
            return arrayLength(bufferArrayView<array<u32>>(p, offset, size));
          }

          fn workgroupLengthSmall(p : ptr<workgroup, buffer<64>>, offset : u32) -> u32 {
            return workgroupLengthUnsized(p, offset, 32);
          }

          fn workgroupLengthOverride(p : ptr<workgroup, buffer<len>>, offset : u32) -> u32 {
            return workgroupLengthUnsized(p, offset, 32);
          }

          fn storageLengthUnsized(p : ptr<storage, buffer>, offset : u32, size : u32) -> u32 {
            return arrayLength(&bufferArrayView<S>(p, offset, size).b);
          }

          fn storageLengthLarge(p : ptr<storage, buffer>, offset : u32) -> u32 {
            return arrayLength(&bufferView<S>(p, offset).b);
          }

          fn storageLengthSmall(p : ptr<storage, buffer<48>>, offset : u32) -> u32 {
            return storageLengthLarge(p, offset);
          }

          @compute @workgroup_size(1)
          fn main() {
            let offsets = bufferView<array<u32>>(&uniforms, 0u);
            var i = 0u;
            out[i] = uniformLengthUnsized(&uniforms, offsets[0]); i++;
            out[i] = uniformLengthUnsized(&uniforms, offsets[1]); i++;
            out[i] = uniformLengthUnsized(&uniforms, offsets[2]); i++;
            out[i] = uniformLengthSized(&uniforms, offsets[0]); i++;
            out[i] = uniformLengthSized(&uniforms, offsets[1]); i++;

            out[i] = workgroupLengthUnsized(&wg1, offsets[0], bufferLength(&wg1)); i++;
            out[i] = workgroupLengthUnsized(&wg1, offsets[1], offsets[2]); i++;
            out[i] = workgroupLengthUnsized(&wg1, offsets[3], offsets[3]); i++;
            out[i] = workgroupLengthUnsized(&wg2, offsets[0], bufferLength(&wg2)); i++;
            out[i] = workgroupLengthSmall(&wg2, offsets[1]); i++;
            out[i] = workgroupLengthSmall(&wg2, offsets[2]); i++;
            out[i] = workgroupLengthUnsized(&wg3, offsets[0], bufferLength(&wg3)); i++;
            out[i] = workgroupLengthOverride(&wg3, offsets[1]); i++;
            out[i] = workgroupLengthOverride(&wg3, offsets[2]); i++;

            out[i] = storageLengthUnsized(&in, offsets[0], bufferLength(&in)); i++;
            out[i] = storageLengthUnsized(&in, offsets[0], offsets[4]); i++;
            out[i] = storageLengthUnsized(&in, offsets[1], bufferLength(&in) - 8); i++;
            out[i] = storageLengthSmall(&in, 0); i++;
          }
        )";

        std::initializer_list<uint32_t> uniforms = {0, 8, 16, 32, 64};
        std::vector<uint32_t> uniformData{uniforms};

        uint32_t uniformSize = static_cast<uint32_t>(uniforms.size());
        std::vector<uint32_t> expected = {
            // Uniform sizes
            uniformSize,
            uniformSize - uniformData[1] / 4,
            uniformSize - uniformData[2] / 4,
            uniformSize - 1,
            uniformSize - 1 - uniformData[1] / 4,
            // Workgroup sizes
            64 / 4,
            uniformData[2] / 4,
            uniformData[3] / 4,
            128 / 4,
            32 / 4,
            32 / 4,
            len / 4,
            32 / 4,
            32 / 4,
            // Storage sizes
            (len - 8) / 4,
            (uniformData[4] - 8) / 4,
            (len - 8 - uniformData[1]) / 4,
            (48 - 8) / 4,
        };

        BaseLengthTest(wgsl, len, 0, uniforms, expected);
    }

    void BaseViewTest(const std::string& wgsl) {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, wgsl);

        std::initializer_list<uint32_t> uniforms = {0, 1, 2,  3,  4,  5,  6,  7,
                                                    8, 9, 10, 11, 12, 13, 14, 15};
        std::initializer_list<uint32_t> inputs = {
            1, 2, 3, 4, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 7, 8, 9, 10, 11, 12, 13, 14,
        };
        const std::vector<uint32_t> expected = {
            1, 2, 3, 4, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 7, 8, 9, 10, 11, 12, 13, 14,
        };

        wgpu::ComputePipelineDescriptor desc;
        desc.compute.module = module;
        wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&desc);

        wgpu::Buffer src = utils::CreateBufferFromData<uint32_t>(
            device, wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc, inputs);

        wgpu::BufferDescriptor outDesc;
        outDesc.size = sizeof(uint32_t) * expected.size();
        outDesc.usage =
            wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer out = device.CreateBuffer(&outDesc);

        wgpu::Buffer uni = utils::CreateBufferFromData<uint32_t>(
            device, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopySrc, uniforms);

        wgpu::BindGroup bg =
            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                 {
                                     {0, src, 0, inputs.size() * sizeof(uint32_t)},
                                     {1, out, 0, outDesc.size},
                                     {2, uni, 0, uniforms.size() * sizeof(uint32_t)},
                                 });

        wgpu::CommandBuffer commands;
        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(pipeline);
            pass.SetBindGroup(0, bg);
            pass.DispatchWorkgroups(1, 1, 1);
            pass.End();
            commands = encoder.Finish();
        }
        queue.Submit(1, &commands);

        EXPECT_BUFFER_U32_RANGE_EQ(&expected[0], out, 0, expected.size());
    }

    void TestBufferViewBasics() {
        const std::string wgsl = R"(
          @group(0) @binding(0) var<storage> in : buffer;
          @group(0) @binding(1) var<storage, read_write> out : buffer;
          @group(0) @binding(2) var<uniform> uniforms : buffer<64>;

          struct S {
            a : u32,
            b : vec4u,
          }

          @compute @workgroup_size(1)
          fn main() {
            let uniform_v1 = bufferView<array<u32>>(&uniforms, 0);

            let in1 = bufferView<array<u32, 4>>(&in, uniform_v1[0]);
            let out1 = bufferView<vec4u>(&out, uniform_v1[0]);
            out1.x = in1[0];
            out1.y = in1[1];
            out1.z = in1[2];
            out1.w = in1[3];

            let in2x = bufferView<f32>(&in, uniform_v1[4] * 4);
            let in2y = bufferView<f32>(&in, uniform_v1[5] * 4);
            let in2z = bufferView<f32>(&in, uniform_v1[6] * 4);
            let in2w = bufferView<f32>(&in, uniform_v1[7] * 4);
            let out2 = bufferView<array<f32, 4>>(&out, 16u);
            out2[0] = *in2x;
            out2[1] = *in2y;
            out2[2] = *in2z;
            out2[3] = *in2w;

            let in3 = bufferView<S>(&in, uniform_v1[8] * 4);
            let in3_sub = bufferView<array<u32, 3>>(&in, uniform_v1[9] * 4);
            let out3 = bufferView<S>(&out, uniform_v1[8] * 4);
            let out3_sub = bufferView<array<u32, 3>>(&out, uniform_v1[9] * 4);
            let in3_ld = *in3;
            *out3_sub = *in3_sub;
            *out3 = in3_ld;
          }
        )";

        BaseViewTest(wgsl);
    }

    void TestBufferArrayViewBasics() {
        const std::string wgsl = R"(
          @group(0) @binding(0) var<storage> in : buffer;
          @group(0) @binding(1) var<storage, read_write> out : buffer;
          @group(0) @binding(2) var<uniform> uniforms : buffer<64>;

          struct S {
            a : u32,
            b : vec4u,
          }

          @compute @workgroup_size(1)
          fn main() {
            let uniform_v1 = bufferArrayView<array<u32>>(&uniforms, 0, 16 * 4);

            let in1 = bufferArrayView<array<u32>>(&in, uniform_v1[0], uniform_v1[5] * 4);
            let out1 = bufferArrayView<array<vec4u>>(&out, uniform_v1[0], 16);
            out1[0].x = in1[0];
            out1[0].y = in1[1];
            out1[0].z = in1[2];
            out1[0].w = in1[3];

            let in2x = bufferArrayView<array<f32>>(&in, uniform_v1[4] * 4, 8);
            let in2y = bufferArrayView<array<f32>>(&in, uniform_v1[5] * 4, 8);
            let in2z = bufferArrayView<array<f32>>(&in, uniform_v1[6] * 4, 8);
            let in2w = bufferArrayView<array<f32>>(&in, uniform_v1[7] * 4, 8);
            let out2 = bufferArrayView<array<f32>>(&out, 16u, 16u);
            out2[0] = in2x[0];
            out2[1] = in2y[0];
            out2[2] = in2z[0];
            out2[3] = in2w[0];

            let in3 = bufferArrayView<array<S>>(&in, uniform_v1[8] * 4, 32);
            let in3_sub = bufferArrayView<array<array<u32, 3>>>(&in, uniform_v1[9] * 4, 12);
            let out3 = bufferArrayView<array<S>>(&out, uniform_v1[8] * 4, 32);
            let out3_sub = bufferArrayView<array<array<u32, 3>>>(&out, uniform_v1[9] * 4, 12);
            let in3_ld = in3[0];
            out3_sub[0] = in3_sub[0];
            out3[0] = in3_ld;
          }
        )";

        BaseViewTest(wgsl);
    }
};

TEST_P(BufferViewTest, BufferViewArrayLength) {
    // TODO(crbug.com/tint/512253562): Older WARP gets incorrect results, but newer WARP passes.
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    TestBufferViewArrayLength(128, 0);
    TestBufferViewArrayLength(256, 256);
    TestBufferViewArrayLength(512, 256);
    TestBufferViewArrayLength(1024, 256);
    TestBufferViewArrayLength(64, 0);
}

TEST_P(BufferViewTest, BufferArrayViewArrayLength) {
    TestBufferArrayViewArrayLength(128, 0);
    TestBufferArrayViewArrayLength(256, 256);
    TestBufferArrayViewArrayLength(512, 256);
    TestBufferArrayViewArrayLength(1024, 256);
    TestBufferArrayViewArrayLength(64, 0);
}

TEST_P(BufferViewTest, ArrayLengthFunctions) {
    TestArrayLengthFunctions(128);
    TestArrayLengthFunctions(256);
    TestArrayLengthFunctions(512);
    TestArrayLengthFunctions(1024);
    TestArrayLengthFunctions(64);
}

TEST_P(BufferViewTest, BufferViewBasics) {
    TestBufferViewBasics();
}

TEST_P(BufferViewTest, BufferArrayViewBasics) {
    TestBufferArrayViewBasics();
}

DAWN_INSTANTIATE_TEST(BufferViewTest,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend(),
                      WebGPUBackend());
}  // namespace
}  // namespace dawn
