// 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,
                        const std::initializer_list<uint32_t>& uniforms,
                        const std::vector<uint32_t>& expected) {
        wgpu::ShaderModule module = utils::CreateShaderModule(device, wgsl);

        std::vector<wgpu::ConstantEntry> constants{{nullptr, "len", static_cast<double>(len)}};
        wgpu::ComputePipelineDescriptor desc;
        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;
        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, pipeline.GetBindGroupLayout(0),
                                 {
                                     {0, src, 0, srcDesc.size},
                                     {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())
            << "Buffer length = " << len << "\n";
    }

    void TestBufferViewArrayLength(uint32_t len) {
        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, uniforms, expected);
    }

    void TestBufferArrayViewArrayLength(uint32_t len) {
        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][2], uniforms[1][2])); i++;
            out[i] = arrayLength(bufferArrayView<array<u32>>(&in, uniforms[0][3], uniforms[1][3])); 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][2], uniforms[1][2])); i++;
            out[i] = arrayLength(bufferArrayView<array<vec2u>>(&in, uniforms[0][2], 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][2], uniforms[1][2])); 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][2], uniforms[1][2])); 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][2], uniforms[1][2]).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<S2>(&in, uniforms[0][2], uniforms[1][2]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S2>(&in, uniforms[0][1], uniforms[1][3]).b); i++;

            out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][0], uniforms[1][0]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][1], uniforms[1][1]).b); i++;
            out[i] = arrayLength(&bufferArrayView<S3>(&in, uniforms[0][2], uniforms[1][2]).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};

        auto InBounds = [&](uint32_t offset_idx, uint32_t size_idx, uint32_t size,
                            uint32_t str_offset = 0) {
            auto req_size = uniformData[size_idx];
            auto used_size = std::max(((req_size - str_offset) / size) * size, size);
            if (len < str_offset + uniformData[offset_idx] + used_size) {
                return 1u;
            }
            return used_size / size;
        };

        std::vector<uint32_t> expected = {
            len,                         //
            InBounds(0, 4 + 0, 4),       //
            InBounds(1, 4 + 1, 4),       //
            InBounds(2, 4 + 2, 4),       //
            InBounds(3, 4 + 3, 4),       //
            InBounds(0, 4 + 0, 8),       //
            InBounds(1, 4 + 1, 8),       //
            InBounds(2, 4 + 2, 8),       //
            InBounds(2, 4 + 3, 8),       //
            InBounds(0, 4 + 0, 16),      //
            InBounds(1, 4 + 1, 16),      //
            InBounds(2, 4 + 2, 16),      //
            InBounds(1, 4 + 3, 16),      //
            InBounds(0, 4 + 0, 16),      //
            InBounds(1, 4 + 1, 16),      //
            InBounds(2, 4 + 2, 16),      //
            InBounds(0, 4 + 3, 16),      //
            InBounds(0, 4 + 0, 4, 4),    //
            InBounds(1, 4 + 1, 4, 4),    //
            InBounds(2, 4 + 2, 4, 4),    //
            InBounds(1, 4 + 3, 4, 4),    //
            InBounds(0, 4 + 0, 8, 8),    //
            InBounds(1, 4 + 1, 8, 8),    //
            InBounds(2, 4 + 2, 8, 8),    //
            InBounds(1, 4 + 3, 8, 8),    //
            InBounds(0, 4 + 0, 16, 16),  //
            InBounds(1, 4 + 1, 16, 16),  //
            InBounds(2, 4 + 2, 16, 16),  //
            InBounds(0, 4 + 3, 16, 16),  //
        };

        BaseLengthTest(src, len, 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, 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) {
    DAWN_SUPPRESS_TEST_IF(IsD3D11());
    DAWN_SUPPRESS_TEST_IF(IsD3D12());

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

TEST_P(BufferViewTest, BufferArrayViewArrayLength) {
    DAWN_SUPPRESS_TEST_IF(IsD3D11());
    DAWN_SUPPRESS_TEST_IF(IsD3D12());

    TestBufferArrayViewArrayLength(128);
    TestBufferArrayViewArrayLength(256);
    TestBufferArrayViewArrayLength(512);
    TestBufferArrayViewArrayLength(1024);
    TestBufferArrayViewArrayLength(64);
}

TEST_P(BufferViewTest, ArrayLengthFunctions) {
    DAWN_SUPPRESS_TEST_IF(IsD3D11());
    DAWN_SUPPRESS_TEST_IF(IsD3D12());

    TestArrayLengthFunctions(128);
    TestArrayLengthFunctions(256);
    TestArrayLengthFunctions(512);
    TestArrayLengthFunctions(1024);
    TestArrayLengthFunctions(64);
}

TEST_P(BufferViewTest, BufferViewBasics) {
    DAWN_SUPPRESS_TEST_IF(IsD3D11());
    DAWN_SUPPRESS_TEST_IF(IsD3D12());

    TestBufferViewBasics();
}

TEST_P(BufferViewTest, BufferArrayViewBasics) {
    DAWN_SUPPRESS_TEST_IF(IsD3D11());
    DAWN_SUPPRESS_TEST_IF(IsD3D12());

    TestBufferArrayViewBasics();
}

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