// Copyright 2020 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 "dawn/tests/unittests/validation/ValidationTest.h"

#include "dawn/common/Assert.h"
#include "dawn/common/Constants.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace {
    // Helper for describing bindings throughout the tests
    struct BindingDescriptor {
        uint32_t group;
        uint32_t binding;
        std::string decl;
        std::string ref_type;
        std::string ref_mem;
        uint64_t size;
        wgpu::BufferBindingType type = wgpu::BufferBindingType::Storage;
        wgpu::ShaderStage visibility = wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment;
    };

    // Runs |func| with a modified version of |originalSizes| as an argument, adding |offset| to
    // each element one at a time This is useful to verify some behavior happens if any element is
    // offset from original
    template <typename F>
    void WithEachSizeOffsetBy(int64_t offset, const std::vector<uint64_t>& originalSizes, F func) {
        std::vector<uint64_t> modifiedSizes = originalSizes;
        for (size_t i = 0; i < originalSizes.size(); ++i) {
            if (offset < 0) {
                ASSERT(originalSizes[i] >= static_cast<uint64_t>(-offset));
            }
            // Run the function with an element offset, and restore element afterwards
            modifiedSizes[i] += offset;
            func(modifiedSizes);
            modifiedSizes[i] -= offset;
        }
    }

    // Runs |func| with |correctSizes|, and an expectation of success and failure
    template <typename F>
    void CheckSizeBounds(const std::vector<uint64_t>& correctSizes, F func) {
        // To validate size:
        // Check invalid with bind group with one less
        // Check valid with bind group with correct size

        // Make sure (every size - 1) produces an error
        WithEachSizeOffsetBy(-1, correctSizes,
                             [&](const std::vector<uint64_t>& sizes) { func(sizes, false); });

        // Make sure correct sizes work
        func(correctSizes, true);

        // Make sure (every size + 1) works
        WithEachSizeOffsetBy(1, correctSizes,
                             [&](const std::vector<uint64_t>& sizes) { func(sizes, true); });
    }

    // Creates a bind group with given bindings for shader text
    std::string GenerateBindingString(const std::vector<BindingDescriptor>& bindings) {
        std::ostringstream ostream;
        size_t index = 0;
        for (const BindingDescriptor& b : bindings) {
            ostream << "struct S" << index << " { " << b.decl << "}\n";
            ostream << "@group(" << b.group << ") @binding(" << b.binding << ") ";
            switch (b.type) {
                case wgpu::BufferBindingType::Uniform:
                    ostream << "var<uniform> b" << index << " : S" << index << ";\n";
                    break;
                case wgpu::BufferBindingType::Storage:
                    ostream << "var<storage, read_write> b" << index << " : S" << index << ";\n";
                    break;
                case wgpu::BufferBindingType::ReadOnlyStorage:
                    ostream << "var<storage, read> b" << index << " : S" << index << ";\n";
                    break;
                default:
                    UNREACHABLE();
            }
            index++;
        }
        return ostream.str();
    }

    std::string GenerateReferenceString(const std::vector<BindingDescriptor>& bindings,
                                        wgpu::ShaderStage stage) {
        std::ostringstream ostream;
        size_t index = 0;
        for (const BindingDescriptor& b : bindings) {
            if (b.visibility & stage) {
                if (!b.ref_type.empty() && !b.ref_mem.empty()) {
                    ostream << "var r" << index << " : " << b.ref_type << " = b" << index << "."
                            << b.ref_mem << ";\n";
                }
            }
            index++;
        }
        return ostream.str();
    }

    // Used for adding custom types available throughout the tests
    static const std::string kStructs = "struct ThreeFloats {f1 : f32, f2 : f32, f3 : f32,}\n";

    // Creates a compute shader with given bindings
    std::string CreateComputeShaderWithBindings(const std::vector<BindingDescriptor>& bindings) {
        return kStructs + GenerateBindingString(bindings) +
               "@stage(compute) @workgroup_size(1,1,1) fn main() {\n" +
               GenerateReferenceString(bindings, wgpu::ShaderStage::Compute) + "}";
    }

    // Creates a vertex shader with given bindings
    std::string CreateVertexShaderWithBindings(const std::vector<BindingDescriptor>& bindings) {
        return kStructs + GenerateBindingString(bindings) +
               "@stage(vertex) fn main() -> @builtin(position) vec4<f32> {\n" +
               GenerateReferenceString(bindings, wgpu::ShaderStage::Vertex) +
               "\n   return vec4<f32>(); " + "}";
    }

    // Creates a fragment shader with given bindings
    std::string CreateFragmentShaderWithBindings(const std::vector<BindingDescriptor>& bindings) {
        return kStructs + GenerateBindingString(bindings) + "@stage(fragment) fn main() {\n" +
               GenerateReferenceString(bindings, wgpu::ShaderStage::Fragment) + "}";
    }

    // Concatenates vectors containing BindingDescriptor
    std::vector<BindingDescriptor> CombineBindings(
        std::initializer_list<std::vector<BindingDescriptor>> bindings) {
        std::vector<BindingDescriptor> result;
        for (const std::vector<BindingDescriptor>& b : bindings) {
            result.insert(result.end(), b.begin(), b.end());
        }
        return result;
    }
}  // namespace

class MinBufferSizeTestsBase : public ValidationTest {
  public:
    void SetUp() override {
        ValidationTest::SetUp();
    }

    wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) {
        wgpu::BufferDescriptor bufferDescriptor;
        bufferDescriptor.size = bufferSize;
        bufferDescriptor.usage = usage;

        return device.CreateBuffer(&bufferDescriptor);
    }

    // Creates compute pipeline given a layout and shader
    wgpu::ComputePipeline CreateComputePipeline(const std::vector<wgpu::BindGroupLayout>& layouts,
                                                const std::string& shader) {
        wgpu::ShaderModule csModule = utils::CreateShaderModule(device, shader.c_str());

        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.layout = nullptr;
        if (!layouts.empty()) {
            wgpu::PipelineLayoutDescriptor descriptor;
            descriptor.bindGroupLayoutCount = layouts.size();
            descriptor.bindGroupLayouts = layouts.data();
            csDesc.layout = device.CreatePipelineLayout(&descriptor);
        }
        csDesc.compute.module = csModule;
        csDesc.compute.entryPoint = "main";

        return device.CreateComputePipeline(&csDesc);
    }

    // Creates compute pipeline with default layout
    wgpu::ComputePipeline CreateComputePipelineWithDefaultLayout(const std::string& shader) {
        return CreateComputePipeline({}, shader);
    }

    // Creates render pipeline give na layout and shaders
    wgpu::RenderPipeline CreateRenderPipeline(const std::vector<wgpu::BindGroupLayout>& layouts,
                                              const std::string& vertexShader,
                                              const std::string& fragShader) {
        wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, vertexShader.c_str());

        wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, fragShader.c_str());

        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.vertex.module = vsModule;
        pipelineDescriptor.cFragment.module = fsModule;
        pipelineDescriptor.cTargets[0].writeMask = wgpu::ColorWriteMask::None;
        pipelineDescriptor.layout = nullptr;
        if (!layouts.empty()) {
            wgpu::PipelineLayoutDescriptor descriptor;
            descriptor.bindGroupLayoutCount = layouts.size();
            descriptor.bindGroupLayouts = layouts.data();
            pipelineDescriptor.layout = device.CreatePipelineLayout(&descriptor);
        }

        return device.CreateRenderPipeline(&pipelineDescriptor);
    }

    // Creates render pipeline with default layout
    wgpu::RenderPipeline CreateRenderPipelineWithDefaultLayout(const std::string& vertexShader,
                                                               const std::string& fragShader) {
        return CreateRenderPipeline({}, vertexShader, fragShader);
    }

    // Creates bind group layout with given minimum sizes for each binding
    wgpu::BindGroupLayout CreateBindGroupLayout(const std::vector<BindingDescriptor>& bindings,
                                                const std::vector<uint64_t>& minimumSizes) {
        ASSERT(bindings.size() == minimumSizes.size());
        std::vector<wgpu::BindGroupLayoutEntry> entries;

        for (size_t i = 0; i < bindings.size(); ++i) {
            const BindingDescriptor& b = bindings[i];
            wgpu::BindGroupLayoutEntry e = {};
            e.binding = b.binding;
            e.visibility = b.visibility;
            e.buffer.type = b.type;
            e.buffer.minBindingSize = minimumSizes[i];
            entries.push_back(e);
        }

        wgpu::BindGroupLayoutDescriptor descriptor;
        descriptor.entryCount = static_cast<uint32_t>(entries.size());
        descriptor.entries = entries.data();
        return device.CreateBindGroupLayout(&descriptor);
    }

    // Extract the first bind group from a compute shader
    wgpu::BindGroupLayout GetBGLFromComputeShader(const std::string& shader, uint32_t index) {
        wgpu::ComputePipeline pipeline = CreateComputePipelineWithDefaultLayout(shader);
        return pipeline.GetBindGroupLayout(index);
    }

    // Extract the first bind group from a render pass
    wgpu::BindGroupLayout GetBGLFromRenderShaders(const std::string& vertexShader,
                                                  const std::string& fragShader,
                                                  uint32_t index) {
        wgpu::RenderPipeline pipeline =
            CreateRenderPipelineWithDefaultLayout(vertexShader, fragShader);
        return pipeline.GetBindGroupLayout(index);
    }

    // Create a bind group with given binding sizes for each entry (backed by the same buffer)
    wgpu::BindGroup CreateBindGroup(wgpu::BindGroupLayout layout,
                                    const std::vector<BindingDescriptor>& bindings,
                                    const std::vector<uint64_t>& bindingSizes) {
        ASSERT(bindings.size() == bindingSizes.size());
        wgpu::Buffer buffer =
            CreateBuffer(1024, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage);

        std::vector<wgpu::BindGroupEntry> entries;
        entries.reserve(bindingSizes.size());

        for (uint32_t i = 0; i < bindingSizes.size(); ++i) {
            wgpu::BindGroupEntry entry = {};
            entry.binding = bindings[i].binding;
            entry.buffer = buffer;
            ASSERT(bindingSizes[i] < 1024);
            entry.size = bindingSizes[i];
            entries.push_back(entry);
        }

        wgpu::BindGroupDescriptor descriptor;
        descriptor.layout = layout;
        descriptor.entryCount = entries.size();
        descriptor.entries = entries.data();

        return device.CreateBindGroup(&descriptor);
    }

    // Runs a single dispatch with given pipeline and bind group (to test lazy validation during
    // dispatch)
    void TestDispatch(const wgpu::ComputePipeline& computePipeline,
                      const std::vector<wgpu::BindGroup>& bindGroups,
                      bool expectation) {
        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::ComputePassEncoder computePassEncoder = commandEncoder.BeginComputePass();
        computePassEncoder.SetPipeline(computePipeline);
        for (size_t i = 0; i < bindGroups.size(); ++i) {
            computePassEncoder.SetBindGroup(i, bindGroups[i]);
        }
        computePassEncoder.Dispatch(1);
        computePassEncoder.End();
        if (!expectation) {
            ASSERT_DEVICE_ERROR(commandEncoder.Finish());
        } else {
            commandEncoder.Finish();
        }
    }

    // Runs a single draw with given pipeline and bind group (to test lazy validation during draw)
    void TestDraw(const wgpu::RenderPipeline& renderPipeline,
                  const std::vector<wgpu::BindGroup>& bindGroups,
                  bool expectation) {
        DummyRenderPass renderPass(device);

        wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
        renderPassEncoder.SetPipeline(renderPipeline);
        for (size_t i = 0; i < bindGroups.size(); ++i) {
            renderPassEncoder.SetBindGroup(i, bindGroups[i]);
        }
        renderPassEncoder.Draw(3);
        renderPassEncoder.End();
        if (!expectation) {
            ASSERT_DEVICE_ERROR(commandEncoder.Finish());
        } else {
            commandEncoder.Finish();
        }
    }
};

// The check between BGL and pipeline at pipeline creation time
class MinBufferSizePipelineCreationTests : public MinBufferSizeTestsBase {};

// Pipeline can be created if minimum buffer size in layout is specified as 0
TEST_F(MinBufferSizePipelineCreationTests, ZeroMinBufferSize) {
    std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
                                               {0, 1, "c : f32,", "f32", "c", 4}};

    std::string computeShader = CreateComputeShaderWithBindings(bindings);
    std::string vertexShader = CreateVertexShaderWithBindings({});
    std::string fragShader = CreateFragmentShaderWithBindings(bindings);

    wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, {0, 0});
    CreateRenderPipeline({layout}, vertexShader, fragShader);
    CreateComputePipeline({layout}, computeShader);
}

// Fail if layout given has non-zero minimum sizes smaller than shader requirements
TEST_F(MinBufferSizePipelineCreationTests, LayoutSizesTooSmall) {
    std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
                                               {0, 1, "c : f32,", "f32", "c", 4}};

    std::string computeShader = CreateComputeShaderWithBindings(bindings);
    std::string vertexShader = CreateVertexShaderWithBindings({});
    std::string fragShader = CreateFragmentShaderWithBindings(bindings);

    CheckSizeBounds({8, 4}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
        wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, sizes);
        if (expectation) {
            CreateRenderPipeline({layout}, vertexShader, fragShader);
            CreateComputePipeline({layout}, computeShader);
        } else {
            ASSERT_DEVICE_ERROR(CreateRenderPipeline({layout}, vertexShader, fragShader));
            ASSERT_DEVICE_ERROR(CreateComputePipeline({layout}, computeShader));
        }
    });
}

// Fail if layout given has non-zero minimum sizes smaller than shader requirements
TEST_F(MinBufferSizePipelineCreationTests, LayoutSizesTooSmallMultipleGroups) {
    std::vector<BindingDescriptor> bg0Bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
                                                  {0, 1, "c : f32,", "f32", "c", 4}};
    std::vector<BindingDescriptor> bg1Bindings = {
        {1, 0, "d : f32, e : f32, f : f32,", "f32", "e", 12},
        {1, 1, "g : mat2x2<f32>,", "mat2x2<f32>", "g", 16}};
    std::vector<BindingDescriptor> bindings = CombineBindings({bg0Bindings, bg1Bindings});

    std::string computeShader = CreateComputeShaderWithBindings(bindings);
    std::string vertexShader = CreateVertexShaderWithBindings({});
    std::string fragShader = CreateFragmentShaderWithBindings(bindings);

    CheckSizeBounds({8, 4, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
        wgpu::BindGroupLayout layout0 = CreateBindGroupLayout(bg0Bindings, {sizes[0], sizes[1]});
        wgpu::BindGroupLayout layout1 = CreateBindGroupLayout(bg1Bindings, {sizes[2], sizes[3]});
        if (expectation) {
            CreateRenderPipeline({layout0, layout1}, vertexShader, fragShader);
            CreateComputePipeline({layout0, layout1}, computeShader);
        } else {
            ASSERT_DEVICE_ERROR(CreateRenderPipeline({layout0, layout1}, vertexShader, fragShader));
            ASSERT_DEVICE_ERROR(CreateComputePipeline({layout0, layout1}, computeShader));
        }
    });
}

// The check between the BGL and the bindings at bindgroup creation time
class MinBufferSizeBindGroupCreationTests : public MinBufferSizeTestsBase {};

// Fail if a binding is smaller than minimum buffer size
TEST_F(MinBufferSizeBindGroupCreationTests, BindingTooSmall) {
    std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
                                               {0, 1, "c : f32,", "f32", "c", 4}};
    wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, {8, 4});

    CheckSizeBounds({8, 4}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
        if (expectation) {
            CreateBindGroup(layout, bindings, sizes);
        } else {
            ASSERT_DEVICE_ERROR(CreateBindGroup(layout, bindings, sizes));
        }
    });
}

// Check two layouts with different minimum size are unequal
TEST_F(MinBufferSizeBindGroupCreationTests, LayoutEquality) {
    // Returning the same pointer is an implementation detail of Dawn Native.
    // It is not the same semantic with the Wire.
    DAWN_SKIP_TEST_IF(UsesWire());

    auto MakeLayout = [&](uint64_t size) {
        return utils::MakeBindGroupLayout(
            device,
            {{0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform, false, size}});
    };

    EXPECT_EQ(MakeLayout(0).Get(), MakeLayout(0).Get());
    EXPECT_NE(MakeLayout(0).Get(), MakeLayout(4).Get());
}

// The check between the bindgroup binding sizes and the required pipeline sizes at draw time
class MinBufferSizeDrawTimeValidationTests : public MinBufferSizeTestsBase {};

// Fail if binding sizes are too small at draw time
TEST_F(MinBufferSizeDrawTimeValidationTests, ZeroMinSizeAndTooSmallBinding) {
    std::vector<BindingDescriptor> bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
                                               {0, 1, "c : f32,", "f32", "c", 4}};

    std::string computeShader = CreateComputeShaderWithBindings(bindings);
    std::string vertexShader = CreateVertexShaderWithBindings({});
    std::string fragShader = CreateFragmentShaderWithBindings(bindings);

    wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, {0, 0});

    wgpu::ComputePipeline computePipeline = CreateComputePipeline({layout}, computeShader);
    wgpu::RenderPipeline renderPipeline = CreateRenderPipeline({layout}, vertexShader, fragShader);

    CheckSizeBounds({8, 4}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
        wgpu::BindGroup bindGroup = CreateBindGroup(layout, bindings, sizes);
        TestDispatch(computePipeline, {bindGroup}, expectation);
        TestDraw(renderPipeline, {bindGroup}, expectation);
    });
}

// Draw time validation works for non-contiguous bindings
TEST_F(MinBufferSizeDrawTimeValidationTests, UnorderedBindings) {
    std::vector<BindingDescriptor> bindings = {
        {0, 2, "a : f32, b : f32,", "f32", "a", 8},
        {0, 0, "c : f32,", "f32", "c", 4},
        {0, 4, "d : f32, e : f32, f : f32,", "f32", "e", 12}};

    std::string computeShader = CreateComputeShaderWithBindings(bindings);
    std::string vertexShader = CreateVertexShaderWithBindings({});
    std::string fragShader = CreateFragmentShaderWithBindings(bindings);

    wgpu::BindGroupLayout layout = CreateBindGroupLayout(bindings, {0, 0, 0});

    wgpu::ComputePipeline computePipeline = CreateComputePipeline({layout}, computeShader);
    wgpu::RenderPipeline renderPipeline = CreateRenderPipeline({layout}, vertexShader, fragShader);

    CheckSizeBounds({8, 4, 12}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
        wgpu::BindGroup bindGroup = CreateBindGroup(layout, bindings, sizes);
        TestDispatch(computePipeline, {bindGroup}, expectation);
        TestDraw(renderPipeline, {bindGroup}, expectation);
    });
}

// Draw time validation works for multiple bind groups
TEST_F(MinBufferSizeDrawTimeValidationTests, MultipleGroups) {
    std::vector<BindingDescriptor> bg0Bindings = {{0, 0, "a : f32, b : f32,", "f32", "a", 8},
                                                  {0, 1, "c : f32,", "f32", "c", 4}};
    std::vector<BindingDescriptor> bg1Bindings = {
        {1, 0, "d : f32, e : f32, f : f32,", "f32", "e", 12},
        {1, 1, "g : mat2x2<f32>,", "mat2x2<f32>", "g", 16}};
    std::vector<BindingDescriptor> bindings = CombineBindings({bg0Bindings, bg1Bindings});

    std::string computeShader = CreateComputeShaderWithBindings(bindings);
    std::string vertexShader = CreateVertexShaderWithBindings({});
    std::string fragShader = CreateFragmentShaderWithBindings(bindings);

    wgpu::BindGroupLayout layout0 = CreateBindGroupLayout(bg0Bindings, {0, 0});
    wgpu::BindGroupLayout layout1 = CreateBindGroupLayout(bg1Bindings, {0, 0});

    wgpu::ComputePipeline computePipeline =
        CreateComputePipeline({layout0, layout1}, computeShader);
    wgpu::RenderPipeline renderPipeline =
        CreateRenderPipeline({layout0, layout1}, vertexShader, fragShader);

    CheckSizeBounds({8, 4, 12, 16}, [&](const std::vector<uint64_t>& sizes, bool expectation) {
        wgpu::BindGroup bindGroup0 = CreateBindGroup(layout0, bg0Bindings, {sizes[0], sizes[1]});
        wgpu::BindGroup bindGroup1 = CreateBindGroup(layout0, bg0Bindings, {sizes[2], sizes[3]});
        TestDispatch(computePipeline, {bindGroup0, bindGroup1}, expectation);
        TestDraw(renderPipeline, {bindGroup0, bindGroup1}, expectation);
    });
}

// The correctness of minimum buffer size for the defaulted layout for a pipeline
class MinBufferSizeDefaultLayoutTests : public MinBufferSizeTestsBase {
  public:
    // Checks BGL |layout| has minimum buffer sizes equal to sizes in |bindings|
    void CheckLayoutBindingSizeValidation(const wgpu::BindGroupLayout& layout,
                                          const std::vector<BindingDescriptor>& bindings) {
        std::vector<uint64_t> correctSizes;
        correctSizes.reserve(bindings.size());
        for (const BindingDescriptor& b : bindings) {
            correctSizes.push_back(b.size);
        }

        CheckSizeBounds(correctSizes, [&](const std::vector<uint64_t>& sizes, bool expectation) {
            if (expectation) {
                CreateBindGroup(layout, bindings, sizes);
            } else {
                ASSERT_DEVICE_ERROR(CreateBindGroup(layout, bindings, sizes));
            }
        });
    }

    // Constructs shaders with given layout type and bindings, checking defaulted sizes match sizes
    // in |bindings|
    void CheckShaderBindingSizeReflection(
        std::initializer_list<std::vector<BindingDescriptor>> bindings) {
        std::vector<BindingDescriptor> combinedBindings = CombineBindings(bindings);
        std::string computeShader = CreateComputeShaderWithBindings(combinedBindings);
        std::string vertexShader = CreateVertexShaderWithBindings({});
        std::string fragShader = CreateFragmentShaderWithBindings(combinedBindings);

        size_t i = 0;
        for (const std::vector<BindingDescriptor>& b : bindings) {
            wgpu::BindGroupLayout computeLayout = GetBGLFromComputeShader(computeShader, i);
            wgpu::BindGroupLayout renderLayout =
                GetBGLFromRenderShaders(vertexShader, fragShader, i);

            CheckLayoutBindingSizeValidation(computeLayout, b);
            CheckLayoutBindingSizeValidation(renderLayout, b);
            ++i;
        }
    }
};

// Test the minimum size computations for various WGSL types.
TEST_F(MinBufferSizeDefaultLayoutTests, DefaultLayoutVariousWGSLTypes) {
    CheckShaderBindingSizeReflection({{{0, 0, "a : f32,", "f32", "a", 4},
                                       {0, 1, "b : array<f32>,", "f32", "b[0]", 4},
                                       {0, 2, "c : mat2x2<f32>,", "mat2x2<f32>", "c", 16}}});
    CheckShaderBindingSizeReflection({{{0, 3, "d : u32; e : array<f32>,", "u32", "d", 8},
                                       {0, 4, "f : ThreeFloats,", "f32", "f.f1", 12},
                                       {0, 5, "g : array<ThreeFloats>,", "f32", "g[0].f1", 12}}});
}

// Test the minimum size computations for various buffer binding types.
TEST_F(MinBufferSizeDefaultLayoutTests, DefaultLayoutVariousBindingTypes) {
    CheckShaderBindingSizeReflection(
        {{{0, 0, "a : f32,", "f32", "a", 4, wgpu::BufferBindingType::Uniform},
          {0, 1, "a : f32, b : f32,", "f32", "a", 8, wgpu::BufferBindingType::Storage},
          {0, 2, "a : f32, b : f32, c: f32,", "f32", "a", 12,
           wgpu::BufferBindingType::ReadOnlyStorage}}});
}

// Test the minimum size computations works with multiple bind groups.
TEST_F(MinBufferSizeDefaultLayoutTests, MultipleBindGroups) {
    CheckShaderBindingSizeReflection(
        {{{0, 0, "a : f32,", "f32", "a", 4, wgpu::BufferBindingType::Uniform}},
         {{1, 0, "a : f32, b : f32,", "f32", "a", 8, wgpu::BufferBindingType::Storage}},
         {{2, 0, "a : f32, b : f32, c : f32,", "f32", "a", 12,
           wgpu::BufferBindingType::ReadOnlyStorage}}});
}

// Test the minimum size computations with manual size/align attributes.
TEST_F(MinBufferSizeDefaultLayoutTests, NonDefaultLayout) {
    CheckShaderBindingSizeReflection(
        {{{0, 0, "@size(256) a : u32, b : u32,", "u32", "a", 260},
          {0, 1, "c : u32, @align(16) d : u32,", "u32", "c", 20},
          {0, 2, "d : array<array<u32, 10>, 3>,", "u32", "d[0][0]", 120},
          {0, 3, "e : array<array<u32, 10>>,", "u32", "e[0][0]", 40}}});
}

// Minimum size should be the max requirement of both vertex and fragment stages.
TEST_F(MinBufferSizeDefaultLayoutTests, RenderPassConsidersBothStages) {
    std::string vertexShader = CreateVertexShaderWithBindings(
        {{0, 0, "a : f32, b : f32,", "f32", "a", 8, wgpu::BufferBindingType::Uniform,
          wgpu::ShaderStage::Vertex},
         {0, 1, "c : vec4<f32>,", "vec4<f32>", "c", 16, wgpu::BufferBindingType::Uniform,
          wgpu::ShaderStage::Vertex}});
    std::string fragShader = CreateFragmentShaderWithBindings(
        {{0, 0, "a : f32,", "f32", "a", 4, wgpu::BufferBindingType::Uniform,
          wgpu::ShaderStage::Fragment},
         {0, 1, "b : f32, c : f32,", "f32", "b", 8, wgpu::BufferBindingType::Uniform,
          wgpu::ShaderStage::Fragment}});

    wgpu::BindGroupLayout renderLayout = GetBGLFromRenderShaders(vertexShader, fragShader, 0);

    CheckLayoutBindingSizeValidation(renderLayout, {{0, 0, "", "", "", 8}, {0, 1, "", "", "", 16}});
}
