// Copyright 2021 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 <vector>

#include "src/dawn/common/Constants.h"
#include "src/dawn/tests/unittests/validation/ValidationTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

constexpr uint32_t kRTSize = 4;
constexpr uint32_t kFloat32x2Stride = 2 * sizeof(float);
constexpr uint32_t kFloat32x4Stride = 4 * sizeof(float);

class DrawVertexAndIndexBufferOOBValidationTests : public ValidationTest {
  public:
    // Parameters for testing index buffer
    struct IndexBufferParams {
        wgpu::IndexFormat indexFormat;
        uint64_t indexBufferSize;              // Size for creating index buffer
        uint64_t indexBufferOffsetForEncoder;  // Offset for SetIndexBuffer in encoder
        uint64_t indexBufferSizeForEncoder;    // Size for SetIndexBuffer in encoder
        uint32_t maxValidIndexNumber;  // max number of {indexCount + firstIndex} for this set
                                       // of parameters
    };

    // Parameters for testing vertex-step-mode and instance-step-mode vertex buffer
    struct VertexBufferParams {
        uint32_t bufferStride;
        uint64_t bufferSize;              // Size for creating vertex buffer
        uint64_t bufferOffsetForEncoder;  // Offset for SetVertexBuffer in encoder
        uint64_t bufferSizeForEncoder;    // Size for SetVertexBuffer in encoder
        uint32_t maxValidAccessNumber;    // max number of valid access time for this set of
                                          // parameters, i.e. {vertexCount + firstVertex} for
        // vertex-step-mode, and {instanceCount + firstInstance}
        // for instance-step-mode
    };

    // Parameters for setIndexBuffer
    struct IndexBufferDesc {
        const wgpu::Buffer buffer;
        wgpu::IndexFormat indexFormat;
        uint64_t offset = 0;
        uint64_t size = wgpu::kWholeSize;
    };

    // Parameters for setVertexBuffer
    struct VertexBufferSpec {
        uint32_t slot;
        const wgpu::Buffer buffer;
        uint64_t offset = 0;
        uint64_t size = wgpu::kWholeSize;
    };
    using VertexBufferList = std::vector<VertexBufferSpec>;

    // Buffer layout parameters for creating pipeline
    struct PipelineVertexBufferAttributeDesc {
        uint32_t shaderLocation;
        wgpu::VertexFormat format;
        uint64_t offset = 0;
    };
    struct PipelineVertexBufferDesc {
        uint64_t arrayStride;
        wgpu::VertexStepMode stepMode;
        std::vector<PipelineVertexBufferAttributeDesc> attributes = {};
    };

    void SetUp() override {
        ValidationTest::SetUp();

        renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);

        fsModule = utils::CreateShaderModule(device, R"(
            @fragment fn main() -> @location(0) vec4f {
                return vec4f(0.0, 1.0, 0.0, 1.0);
            })");
    }

    const wgpu::RenderPassDescriptor* GetBasicRenderPassDescriptor() const {
        return &renderPass.renderPassInfo;
    }

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

        return device.CreateBuffer(&descriptor);
    }

    wgpu::ShaderModule CreateVertexShaderModuleWithBuffer(
        std::vector<PipelineVertexBufferDesc> bufferDescList) {
        uint32_t attributeCount = 0;
        std::stringstream inputStringStream;

        for (auto buffer : bufferDescList) {
            for (auto attr : buffer.attributes) {
                // @location({shaderLocation}) var_{id} : {typeString},
                inputStringStream << "@location(" << attr.shaderLocation << ") var_"
                                  << attributeCount << " : vec4f,";
                attributeCount++;
            }
        }

        std::stringstream shaderStringStream;

        shaderStringStream << R"(
            @vertex
            fn main()" << inputStringStream.str()
                           << R"() -> @builtin(position) vec4f {
                return vec4f(0.0, 1.0, 0.0, 1.0);
            })";

        return utils::CreateShaderModule(device, shaderStringStream.str().c_str());
    }

    // Create a render pipeline with given buffer layout description, using a vertex shader
    // module automatically generated from the buffer description.
    wgpu::RenderPipeline CreateRenderPipelineWithBufferDesc(
        std::vector<PipelineVertexBufferDesc> bufferDescList) {
        utils::ComboRenderPipelineDescriptor descriptor;

        descriptor.vertex.module = CreateVertexShaderModuleWithBuffer(bufferDescList);
        descriptor.cFragment.module = fsModule;
        descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList;

        descriptor.vertex.bufferCount = bufferDescList.size();

        size_t attributeCount = 0;

        for (size_t bufferCount = 0; bufferCount < bufferDescList.size(); bufferCount++) {
            auto bufferDesc = bufferDescList[bufferCount];
            descriptor.cBuffers[bufferCount].arrayStride = bufferDesc.arrayStride;
            descriptor.cBuffers[bufferCount].stepMode = bufferDesc.stepMode;
            if (bufferDesc.attributes.size() > 0) {
                descriptor.cBuffers[bufferCount].attributeCount = bufferDesc.attributes.size();
                descriptor.cBuffers[bufferCount].attributes =
                    &descriptor.cAttributes[attributeCount];
                for (auto attribute : bufferDesc.attributes) {
                    descriptor.cAttributes[attributeCount].shaderLocation =
                        attribute.shaderLocation;
                    descriptor.cAttributes[attributeCount].format = attribute.format;
                    descriptor.cAttributes[attributeCount].offset = attribute.offset;
                    attributeCount++;
                }
            } else {
                descriptor.cBuffers[bufferCount].attributeCount = 0;
                descriptor.cBuffers[bufferCount].attributes = nullptr;
            }
        }

        descriptor.cTargets[0].format = renderPass.colorFormat;

        return device.CreateRenderPipeline(&descriptor);
    }

    // Create a render pipeline using only one vertex-step-mode Float32x4 buffer
    wgpu::RenderPipeline CreateBasicRenderPipeline(uint32_t bufferStride = kFloat32x4Stride) {
        DAWN_ASSERT(bufferStride >= kFloat32x4Stride);

        std::vector<PipelineVertexBufferDesc> bufferDescList = {
            {bufferStride, wgpu::VertexStepMode::Vertex, {{0, wgpu::VertexFormat::Float32x4}}},
        };

        return CreateRenderPipelineWithBufferDesc(bufferDescList);
    }

    // Create a render pipeline using one vertex-step-mode Float32x4 buffer and one
    // instance-step-mode Float32x2 buffer
    wgpu::RenderPipeline CreateBasicRenderPipelineWithInstance(
        uint32_t bufferStride1 = kFloat32x4Stride,
        uint32_t bufferStride2 = kFloat32x2Stride) {
        DAWN_ASSERT(bufferStride1 >= kFloat32x4Stride);
        DAWN_ASSERT(bufferStride2 >= kFloat32x2Stride);

        std::vector<PipelineVertexBufferDesc> bufferDescList = {
            {bufferStride1, wgpu::VertexStepMode::Vertex, {{0, wgpu::VertexFormat::Float32x4}}},
            {bufferStride2, wgpu::VertexStepMode::Instance, {{3, wgpu::VertexFormat::Float32x2}}},
        };

        return CreateRenderPipelineWithBufferDesc(bufferDescList);
    }

    // Create a render pipeline using one vertex-step-mode and one instance-step-mode buffer,
    // both with a zero array stride. The minimal size of vertex step mode buffer should be 28,
    // and the minimal size of instance step mode buffer should be 20.
    wgpu::RenderPipeline CreateBasicRenderPipelineWithZeroArrayStride() {
        std::vector<PipelineVertexBufferDesc> bufferDescList = {
            {0,
             wgpu::VertexStepMode::Vertex,
             {{0, wgpu::VertexFormat::Float32x4, 0}, {1, wgpu::VertexFormat::Float32x2, 20}}},
            {0,
             wgpu::VertexStepMode::Instance,
             // Two attributes are overlapped within this instance step mode vertex buffer
             {{3, wgpu::VertexFormat::Float32x4, 4}, {7, wgpu::VertexFormat::Float32x3, 0}}},
        };

        return CreateRenderPipelineWithBufferDesc(bufferDescList);
    }

    void TestRenderPassDraw(const wgpu::RenderPipeline& pipeline,
                            VertexBufferList vertexBufferList,
                            uint32_t vertexCount,
                            uint32_t instanceCount,
                            uint32_t firstVertex,
                            uint32_t firstInstance,
                            bool isSuccess) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder =
            encoder.BeginRenderPass(GetBasicRenderPassDescriptor());
        renderPassEncoder.SetPipeline(pipeline);

        for (auto vertexBufferParam : vertexBufferList) {
            renderPassEncoder.SetVertexBuffer(vertexBufferParam.slot, vertexBufferParam.buffer,
                                              vertexBufferParam.offset, vertexBufferParam.size);
        }
        renderPassEncoder.Draw(vertexCount, instanceCount, firstVertex, firstInstance);
        renderPassEncoder.End();

        if (isSuccess) {
            encoder.Finish();
        } else {
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    void TestRenderPassDrawIndexed(const wgpu::RenderPipeline& pipeline,
                                   IndexBufferDesc indexBuffer,
                                   VertexBufferList vertexBufferList,
                                   uint32_t indexCount,
                                   uint32_t instanceCount,
                                   uint32_t firstIndex,
                                   int32_t baseVertex,
                                   uint32_t firstInstance,
                                   bool isSuccess) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder renderPassEncoder =
            encoder.BeginRenderPass(GetBasicRenderPassDescriptor());
        renderPassEncoder.SetPipeline(pipeline);

        renderPassEncoder.SetIndexBuffer(indexBuffer.buffer, indexBuffer.indexFormat,
                                         indexBuffer.offset, indexBuffer.size);

        for (auto vertexBufferParam : vertexBufferList) {
            renderPassEncoder.SetVertexBuffer(vertexBufferParam.slot, vertexBufferParam.buffer,
                                              vertexBufferParam.offset, vertexBufferParam.size);
        }
        renderPassEncoder.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex,
                                      firstInstance);
        renderPassEncoder.End();

        if (isSuccess) {
            encoder.Finish();
        } else {
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }

    // Parameters list for index buffer. Should cover all IndexFormat, and the zero/non-zero
    // offset and size case in SetIndexBuffer
    const std::vector<IndexBufferParams> kIndexParamsList = {
        {wgpu::IndexFormat::Uint32, 12 * sizeof(uint32_t), 0, wgpu::kWholeSize, 12},
        {wgpu::IndexFormat::Uint32, 13 * sizeof(uint32_t), sizeof(uint32_t), wgpu::kWholeSize, 12},
        {wgpu::IndexFormat::Uint32, 13 * sizeof(uint32_t), 0, 12 * sizeof(uint32_t), 12},
        {wgpu::IndexFormat::Uint32, 14 * sizeof(uint32_t), sizeof(uint32_t), 12 * sizeof(uint32_t),
         12},

        {wgpu::IndexFormat::Uint16, 12 * sizeof(uint16_t), 0, wgpu::kWholeSize, 12},
        {wgpu::IndexFormat::Uint16, 13 * sizeof(uint16_t), sizeof(uint16_t), wgpu::kWholeSize, 12},
        {wgpu::IndexFormat::Uint16, 13 * sizeof(uint16_t), 0, 12 * sizeof(uint16_t), 12},
        {wgpu::IndexFormat::Uint16, 14 * sizeof(uint16_t), sizeof(uint16_t), 12 * sizeof(uint16_t),
         12},
    };
    // Parameters list for vertex-step-mode buffer. These parameters should cover different
    // stride, buffer size, SetVertexBuffer size and offset.
    const std::vector<VertexBufferParams> kVertexParamsList = {
        // For stride = kFloat32x4Stride
        {kFloat32x4Stride, 3 * kFloat32x4Stride, 0, wgpu::kWholeSize, 3},
        // Non-zero offset
        {kFloat32x4Stride, 4 * kFloat32x4Stride, kFloat32x4Stride, wgpu::kWholeSize, 3},
        // Non-default size
        {kFloat32x4Stride, 4 * kFloat32x4Stride, 0, 3 * kFloat32x4Stride, 3},
        // Non-zero offset and size
        {kFloat32x4Stride, 5 * kFloat32x4Stride, kFloat32x4Stride, 3 * kFloat32x4Stride, 3},
        // For stride = 2 * kFloat32x4Stride
        {(2 * kFloat32x4Stride), 3 * (2 * kFloat32x4Stride), 0, wgpu::kWholeSize, 3},
        // Non-zero offset
        {(2 * kFloat32x4Stride), 4 * (2 * kFloat32x4Stride), (2 * kFloat32x4Stride),
         wgpu::kWholeSize, 3},
        // Non-default size
        {(2 * kFloat32x4Stride), 4 * (2 * kFloat32x4Stride), 0, 3 * (2 * kFloat32x4Stride), 3},
        // Non-zero offset and size
        {(2 * kFloat32x4Stride), 5 * (2 * kFloat32x4Stride), (2 * kFloat32x4Stride),
         3 * (2 * kFloat32x4Stride), 3},
        // For (strideCount - 1) * arrayStride + lastStride <= bound buffer size < strideCount *
        // arrayStride
        {(kFloat32x4Stride + 4), 2 * (kFloat32x4Stride + 4) + kFloat32x4Stride, 0, wgpu::kWholeSize,
         3},
        {(kFloat32x4Stride + 4), 2 * (kFloat32x4Stride + 4) + kFloat32x4Stride - 1, 0,
         wgpu::kWholeSize, 2},
    };
    // Parameters list for instance-step-mode buffer.
    const std::vector<VertexBufferParams> kInstanceParamsList = {
        // For stride = kFloat32x2Stride
        {kFloat32x2Stride, 5 * kFloat32x2Stride, 0, wgpu::kWholeSize, 5},
        // Non-zero offset
        {kFloat32x2Stride, 6 * kFloat32x2Stride, kFloat32x2Stride, wgpu::kWholeSize, 5},
        // Non-default size
        {kFloat32x2Stride, 6 * kFloat32x2Stride, 0, 5 * kFloat32x2Stride, 5},
        // Non-zero offset and size
        {kFloat32x2Stride, 7 * kFloat32x2Stride, kFloat32x2Stride, 5 * kFloat32x2Stride, 5},
        // For stride = 3 * kFloat32x2Stride
        {(3 * kFloat32x2Stride), 5 * (3 * kFloat32x2Stride), 0, wgpu::kWholeSize, 5},
        // Non-zero offset
        {(3 * kFloat32x2Stride), 6 * (3 * kFloat32x2Stride), (3 * kFloat32x2Stride),
         wgpu::kWholeSize, 5},
        // Non-default size
        {(3 * kFloat32x2Stride), 6 * (3 * kFloat32x2Stride), 0, 5 * (3 * kFloat32x2Stride), 5},
        // Non-zero offset and size
        {(3 * kFloat32x2Stride), 7 * (3 * kFloat32x2Stride), (3 * kFloat32x2Stride),
         5 * (3 * kFloat32x2Stride), 5},
        // For (strideCount - 1) * arrayStride + lastStride <= bound buffer size < strideCount *
        // arrayStride
        {(kFloat32x2Stride + 4), 2 * (kFloat32x2Stride + 4) + kFloat32x2Stride, 0, wgpu::kWholeSize,
         3},
        {(kFloat32x2Stride + 4), 2 * (kFloat32x2Stride + 4) + kFloat32x2Stride - 1, 0,
         wgpu::kWholeSize, 2},
    };

  private:
    wgpu::ShaderModule fsModule;
    utils::BasicRenderPass renderPass;
};

// Control case for Draw
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawBasic) {
    wgpu::RenderPipeline pipeline = CreateBasicRenderPipeline();

    wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);

    {
        // Implicit size
        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, wgpu::kWholeSize}};
        TestRenderPassDraw(pipeline, vertexBufferList, /* vertexCount */ 3,
                           /* instanceCount */ 1, /* firstVertex */ 0,
                           /* firstInstance */ 0, /* isSuccess */ true);
    }

    {
        // Explicit zero size
        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, 0}};
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 1, 0, 0, false);
    }
}

// Verify vertex buffer OOB for non-instanced Draw are caught in command encoder
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawVertexBufferOutOfBoundWithoutInstance) {
    for (VertexBufferParams params : kVertexParamsList) {
        // Create a render pipeline without instance step mode buffer
        wgpu::RenderPipeline pipeline = CreateBasicRenderPipeline(params.bufferStride);

        // Build vertex buffer for 3 vertices
        wgpu::Buffer vertexBuffer = CreateBuffer(params.bufferSize);
        VertexBufferList vertexBufferList = {
            {0, vertexBuffer, params.bufferOffsetForEncoder, params.bufferSizeForEncoder}};

        DAWN_ASSERT(params.maxValidAccessNumber > 0);
        uint32_t n = params.maxValidAccessNumber;
        // It is ok to draw n vertices with vertex buffer
        TestRenderPassDraw(pipeline, vertexBufferList, /* vertexCount */ n,
                           /* instanceCount */ 1, /* firstVertex */ 0,
                           /* firstInstance */ 0, /* isSuccess */ true);
        // It is ok to draw n-1 vertices with offset 1
        TestRenderPassDraw(pipeline, vertexBufferList, n - 1, 1, 1, 0, true);
        // Drawing more vertices will cause OOB, even if not enough for another primitive
        TestRenderPassDraw(pipeline, vertexBufferList, n + 1, 1, 0, 0, false);
        // Drawing n vertices will non-zero offset will cause OOB
        TestRenderPassDraw(pipeline, vertexBufferList, n, 1, 1, 0, false);
        // It is ok to draw any number of instances, as we have no instance-mode buffer
        TestRenderPassDraw(pipeline, vertexBufferList, n, 5, 0, 0, true);
        TestRenderPassDraw(pipeline, vertexBufferList, n, 5, 0, 5, true);
    }
}

// Verify vertex buffer OOB for instanced Draw are caught in command encoder
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawVertexBufferOutOfBoundWithInstance) {
    for (VertexBufferParams vertexParams : kVertexParamsList) {
        for (VertexBufferParams instanceParams : kInstanceParamsList) {
            // Create pipeline with given buffer stride
            wgpu::RenderPipeline pipeline = CreateBasicRenderPipelineWithInstance(
                vertexParams.bufferStride, instanceParams.bufferStride);

            // Build vertex buffer
            wgpu::Buffer vertexBuffer = CreateBuffer(vertexParams.bufferSize);
            wgpu::Buffer instanceBuffer = CreateBuffer(instanceParams.bufferSize);

            VertexBufferList vertexBufferList = {
                {0, vertexBuffer, vertexParams.bufferOffsetForEncoder,
                 vertexParams.bufferSizeForEncoder},
                {1, instanceBuffer, instanceParams.bufferOffsetForEncoder,
                 instanceParams.bufferSizeForEncoder},
            };

            DAWN_ASSERT(vertexParams.maxValidAccessNumber > 0);
            DAWN_ASSERT(instanceParams.maxValidAccessNumber > 0);
            uint32_t vert = vertexParams.maxValidAccessNumber;
            uint32_t inst = instanceParams.maxValidAccessNumber;
            // It is ok to draw vert vertices
            TestRenderPassDraw(pipeline, vertexBufferList, /* vertexCount */ vert,
                               /* instanceCount */ 1, /* firstVertex */ 0,
                               /* firstInstance */ 0, /* isSuccess */ true);
            TestRenderPassDraw(pipeline, vertexBufferList, vert - 1, 1, 1, 0, true);
            // It is ok to draw vert vertices and inst instences
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst, 0, 0, true);
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst - 1, 0, 1, true);
            // more vertices causing OOB
            TestRenderPassDraw(pipeline, vertexBufferList, vert + 1, 1, 0, 0, false);
            TestRenderPassDraw(pipeline, vertexBufferList, vert, 1, 1, 0, false);
            TestRenderPassDraw(pipeline, vertexBufferList, vert + 1, inst, 0, 0, false);
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst, 1, 0, false);
            // more instances causing OOB
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst + 1, 0, 0, false);
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst, 0, 1, false);
            // Both OOB
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst + 1, 0, 0, false);
            TestRenderPassDraw(pipeline, vertexBufferList, vert, inst, 1, 1, false);
        }
    }
}

// Verify zero-attribute vertex buffer OOB for non-instanced Draw are caught in command encoder
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, ZeroAttribute) {
    // Create a render pipeline with zero-attribute vertex buffer description
    wgpu::RenderPipeline pipeline =
        CreateRenderPipelineWithBufferDesc({{kFloat32x4Stride, wgpu::VertexStepMode::Vertex, {}}});

    wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);

    {
        // Valid
        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, wgpu::kWholeSize}};
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 1, 0, 0, true);
    }

    {
        // OOB
        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, 0}};
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 1, 0, 0, false);
    }
}

// Verify vertex buffers don't need to be set to unused (hole) slots for Draw
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, UnusedSlots) {
    // Set vertex buffer only to the second slot
    wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);
    VertexBufferList vertexBufferList = {{1, vertexBuffer, 0, wgpu::kWholeSize}};

    {
        // The first slot it unused so valid even if vertex buffer is not set to it.
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithBufferDesc(
            {{0, wgpu::VertexStepMode::Undefined, {}},
             {kFloat32x4Stride, wgpu::VertexStepMode::Vertex, {}}});
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 1, 0, 0, true);
    }

    {
        // The first slot it used so invalid if vertex buffer is not set to it.
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithBufferDesc(
            {{0, wgpu::VertexStepMode::Vertex, {}},
             {kFloat32x4Stride, wgpu::VertexStepMode::Vertex, {}}});
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 1, 0, 0, false);
    }
}

// Control case for DrawIndexed
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawIndexedBasic) {
    wgpu::RenderPipeline pipeline = CreateBasicRenderPipeline();

    // Build index buffer for 12 indexes
    wgpu::Buffer indexBuffer = CreateBuffer(12 * sizeof(uint32_t), wgpu::BufferUsage::Index);

    // Build vertex buffer for 3 vertices
    wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);
    VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, wgpu::kWholeSize}};

    IndexBufferDesc indexBufferDesc = {indexBuffer, wgpu::IndexFormat::Uint32};

    TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, /* indexCount */ 12,
                              /* instanceCount */ 1, /* firstIndex */ 0, /* baseVertex */ 0,
                              /* firstInstance */ 0, /* isSuccess */ true);
}

// Verify index buffer OOB for DrawIndexed are caught in command encoder
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawIndexedIndexBufferOOB) {
    wgpu::RenderPipeline pipeline = CreateBasicRenderPipelineWithInstance();

    for (IndexBufferParams params : kIndexParamsList) {
        // Build index buffer use given params
        wgpu::Buffer indexBuffer = CreateBuffer(params.indexBufferSize, wgpu::BufferUsage::Index);
        // Build vertex buffer for 3 vertices
        wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);
        // Build vertex buffer for 5 instances
        wgpu::Buffer instanceBuffer = CreateBuffer(5 * kFloat32x2Stride);

        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, wgpu::kWholeSize},
                                             {1, instanceBuffer, 0, wgpu::kWholeSize}};

        IndexBufferDesc indexBufferDesc = {indexBuffer, params.indexFormat,
                                           params.indexBufferOffsetForEncoder,
                                           params.indexBufferSizeForEncoder};

        DAWN_ASSERT(params.maxValidIndexNumber > 0);
        uint32_t n = params.maxValidIndexNumber;

        // Control case
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, /* indexCount */ n,
                                  /* instanceCount */ 5, /* firstIndex */ 0, /* baseVertex */ 0,
                                  /* firstInstance */ 0, /* isSuccess */ true);
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, n - 1, 5, 1, 0, 0,
                                  true);
        // Index buffer OOB, indexCount too large
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, n + 1, 5, 0, 0, 0,
                                  false);
        // Index buffer OOB, indexCount + firstIndex too large
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, n, 5, 1, 0, 0,
                                  false);

        if (!HasToggleEnabled("disable_base_vertex")) {
            // baseVertex is not considered in CPU validation and has no effect on validation
            // Although baseVertex is too large, it will still pass
            TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, n, 5, 0, 100, 0,
                                      true);
            // Index buffer OOB, indexCount too large
            TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, n + 1, 5, 0, 100,
                                      0, false);
        }
    }
}

// Verify instance mode vertex buffer OOB for DrawIndexed are caught in command encoder
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawIndexedVertexBufferOOB) {
    for (VertexBufferParams vertexParams : kVertexParamsList) {
        for (VertexBufferParams instanceParams : kInstanceParamsList) {
            // Create pipeline with given buffer stride
            wgpu::RenderPipeline pipeline = CreateBasicRenderPipelineWithInstance(
                vertexParams.bufferStride, instanceParams.bufferStride);

            constexpr wgpu::IndexFormat indexFormat = wgpu::IndexFormat::Uint32;
            constexpr uint64_t indexStride = sizeof(uint32_t);

            // Build index buffer for 12 indexes
            wgpu::Buffer indexBuffer = CreateBuffer(12 * indexStride, wgpu::BufferUsage::Index);
            // Build vertex buffer for vertices
            wgpu::Buffer vertexBuffer = CreateBuffer(vertexParams.bufferSize);
            // Build vertex buffer for instances
            wgpu::Buffer instanceBuffer = CreateBuffer(instanceParams.bufferSize);

            VertexBufferList vertexBufferList = {
                {0, vertexBuffer, vertexParams.bufferOffsetForEncoder,
                 vertexParams.bufferSizeForEncoder},
                {1, instanceBuffer, instanceParams.bufferOffsetForEncoder,
                 instanceParams.bufferSizeForEncoder}};

            IndexBufferDesc indexBufferDesc = {indexBuffer, indexFormat};

            DAWN_ASSERT(instanceParams.maxValidAccessNumber > 0);
            uint32_t inst = instanceParams.maxValidAccessNumber;
            // Control case
            TestRenderPassDrawIndexed(
                pipeline, indexBufferDesc, vertexBufferList, /* indexCount */ 12,
                /* instanceCount */ inst, /* firstIndex */ 0, /* baseVertex */ 0,
                /* firstInstance */ 0, /* isSuccess */ true);
            // Vertex buffer (stepMode = instance) OOB, instanceCount too large
            TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, inst + 1, 0,
                                      0, 0, false);

            if (!HasToggleEnabled("disable_base_instance")) {
                // firstInstance is considered in CPU validation
                // Vertex buffer (stepMode = instance) in bound
                TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, inst - 1,
                                          0, 0, 1, true);
                // Vertex buffer (stepMode = instance) OOB, instanceCount + firstInstance too
                // large
                TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, inst, 0,
                                          0, 1, false);
            }
        }
    }
}

// Verify zero-attribute instance step mode vertex buffer OOB for instanced DrawIndex
// are caught in command encoder
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawIndexedZeroAttribute) {
    // Create a render pipeline with a vertex step mode and a zero-attribute
    // instance step mode vertex buffer description
    wgpu::RenderPipeline pipeline = CreateRenderPipelineWithBufferDesc(
        {{kFloat32x4Stride, wgpu::VertexStepMode::Vertex, {{0, wgpu::VertexFormat::Float32x4}}},
         {kFloat32x2Stride, wgpu::VertexStepMode::Instance, {}}});

    // Build index buffer for 12 indexes
    wgpu::Buffer indexBuffer = CreateBuffer(12 * sizeof(uint32_t), wgpu::BufferUsage::Index);
    IndexBufferDesc indexBufferDesc = {indexBuffer, wgpu::IndexFormat::Uint32};

    // Build vertex buffer for 3 vertices
    wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);

    // Build vertex buffer for 3 instances
    wgpu::Buffer instanceBuffer = CreateBuffer(3 * kFloat32x2Stride);

    {
        // Valid
        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, wgpu::kWholeSize},
                                             {1, vertexBuffer, 0, wgpu::kWholeSize}};
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, 3, 0, 0, 0,
                                  true);
    }

    {
        // OOB
        VertexBufferList vertexBufferList = {{0, vertexBuffer, 0, wgpu::kWholeSize},
                                             {1, vertexBuffer, 0, 0}};
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, 3, 0, 0, 0,
                                  false);
    }
}

// Verify vertex buffers don't need to be set to unused (hole) slots for DrawIndexed
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, DrawIndexedUnusedSlots) {
    // Build index buffer
    wgpu::Buffer indexBuffer = CreateBuffer(12 * sizeof(uint32_t), wgpu::BufferUsage::Index);
    IndexBufferDesc indexBufferDesc = {indexBuffer, wgpu::IndexFormat::Uint32};

    // Set vertex buffers only to the second and third slots
    wgpu::Buffer vertexBuffer = CreateBuffer(3 * kFloat32x4Stride);
    wgpu::Buffer instanceBuffer = CreateBuffer(3 * kFloat32x2Stride);
    VertexBufferList vertexBufferList = {{1, vertexBuffer, 0, wgpu::kWholeSize},
                                         {2, instanceBuffer, 0, wgpu::kWholeSize}};

    {
        // The first slot it unused so valid even if vertex buffer is not set to it.
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithBufferDesc(
            {{0, wgpu::VertexStepMode::Undefined, {}},
             {kFloat32x4Stride, wgpu::VertexStepMode::Vertex, {}},
             {kFloat32x2Stride, wgpu::VertexStepMode::Instance, {}}});
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, 3, 0, 0, 0,
                                  true);
    }

    {
        // The first slot it used so invalid if vertex buffer is not set to it.
        wgpu::RenderPipeline pipeline = CreateRenderPipelineWithBufferDesc(
            {{0, wgpu::VertexStepMode::Vertex, {}},
             {kFloat32x4Stride, wgpu::VertexStepMode::Vertex, {}},
             {kFloat32x2Stride, wgpu::VertexStepMode::Instance, {}}});
        TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, 3, 0, 0, 0,
                                  false);
    }
}

// Verify zero array stride vertex buffer OOB for Draw and DrawIndexed are caught in command encoder
// This test only test cases that strideCount > 0. Cases of strideCount == 0 are tested in
// ZeroStrideCountVertexBufferNeverOOB.
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, ZeroArrayStrideVertexBuffer) {
    // In this test, we use VertexBufferParams.maxValidAccessNumber > 0 to indicate that such
    // buffer parameter meet the requirement of pipeline, and maxValidAccessNumber == 0 to
    // indicate that such buffer parameter will cause OOB.
    const std::vector<VertexBufferParams> kVertexParamsListForZeroStride = {
        // Control case
        {0, 28, 0, wgpu::kWholeSize, 1},
        // Non-zero offset
        {0, 28, 4, wgpu::kWholeSize, 0},
        {0, 28, 28, wgpu::kWholeSize, 0},
        // Non-default size
        {0, 28, 0, 28, 1},
        {0, 28, 0, 27, 0},
        // Non-zero offset and size
        {0, 32, 4, 28, 1},
        {0, 31, 4, 27, 0},
        {0, 31, 4, wgpu::kWholeSize, 0},
    };

    const std::vector<VertexBufferParams> kInstanceParamsListForZeroStride = {
        // Control case
        {0, 20, 0, wgpu::kWholeSize, 1},
        // Non-zero offset
        {0, 24, 4, wgpu::kWholeSize, 1},
        {0, 23, 4, wgpu::kWholeSize, 0},
        {0, 20, 4, wgpu::kWholeSize, 0},
        {0, 20, 20, wgpu::kWholeSize, 0},
        // Non-default size
        {0, 21, 0, 20, 1},
        {0, 20, 0, 19, 0},
        // Non-zero offset and size
        {0, 30, 4, 20, 1},
        {0, 30, 4, 19, 0},
    };

    // Build a pipeline that require a vertex step mode vertex buffer no smaller than 28 bytes
    // and an instance step mode buffer no smaller than 20 bytes
    wgpu::RenderPipeline pipeline = CreateBasicRenderPipelineWithZeroArrayStride();

    for (VertexBufferParams vertexParams : kVertexParamsListForZeroStride) {
        for (VertexBufferParams instanceParams : kInstanceParamsListForZeroStride) {
            constexpr wgpu::IndexFormat indexFormat = wgpu::IndexFormat::Uint32;
            constexpr uint64_t indexStride = sizeof(uint32_t);

            // Build index buffer for 12 indexes
            wgpu::Buffer indexBuffer = CreateBuffer(12 * indexStride, wgpu::BufferUsage::Index);
            // Build vertex buffer for vertices
            wgpu::Buffer vertexBuffer = CreateBuffer(vertexParams.bufferSize);
            // Build vertex buffer for instances
            wgpu::Buffer instanceBuffer = CreateBuffer(instanceParams.bufferSize);

            VertexBufferList vertexBufferList = {
                {0, vertexBuffer, vertexParams.bufferOffsetForEncoder,
                 vertexParams.bufferSizeForEncoder},
                {1, instanceBuffer, instanceParams.bufferOffsetForEncoder,
                 instanceParams.bufferSizeForEncoder}};

            IndexBufferDesc indexBufferDesc = {indexBuffer, indexFormat};

            const bool vertexModeBufferOOB = vertexParams.maxValidAccessNumber == 0;
            const bool instanceModeBufferOOB = instanceParams.maxValidAccessNumber == 0;

            // Draw validate both vertex and instance step mode buffer OOB.
            // vertexCount and instanceCount doesn't matter, as array stride is zero and all
            // vertex/instance access the same space of buffer, as long as both (vertexCount +
            // firstVertex) and (instanceCount + firstInstance) are larger than zero.
            TestRenderPassDraw(pipeline, vertexBufferList, /* vertexCount */ 100,
                               /* instanceCount */ 100, /* firstVertex */ 0,
                               /* firstInstance */ 0,
                               /* isSuccess */ !vertexModeBufferOOB && !instanceModeBufferOOB);
            TestRenderPassDraw(pipeline, vertexBufferList, 100, 100, 100, 100,
                               !vertexModeBufferOOB && !instanceModeBufferOOB);
            TestRenderPassDraw(pipeline, vertexBufferList, 0, 0, 100, 100,
                               !vertexModeBufferOOB && !instanceModeBufferOOB);

            // DrawIndexed only validate instance step mode buffer OOB.
            // indexCount doesn't matter as long as no index buffer OOB happened, and instanceCount
            // doesn't matter as long as (instanceCount + firstInstance) are larger than zero.
            TestRenderPassDrawIndexed(
                pipeline, indexBufferDesc, vertexBufferList, /* indexCount */ 12,
                /* instanceCount */ 100, /* firstIndex */ 0, /* baseVertex */ 0,
                /* firstInstance */ 0, /* isSuccess */ !instanceModeBufferOOB);
            TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 12, 0, 0, 0, 100,
                                      !instanceModeBufferOOB);
        }
    }
}

// Verify all vertex buffer never OOB for Draw and DrawIndexed with zero stride count
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, ZeroStrideCountVertexBufferNeverOOB) {
    // In this test we use a render pipeline with non-zero array stride and a render pipeline with
    // zero array stride, both use a vertex step mode vertex buffer with lastStride = 16 and a
    // instance step mode vertex buffer with lastStride = 8. Binding a buffer with size less than
    // lastStride to corresponding buffer slot will result in a OOB validation error is strideCount
    // is larger than 0, but shall not result in validation error if strideCount == 0.

    // Create the render pipeline with non-zero array stride (larger than lastStride)
    std::vector<PipelineVertexBufferDesc> bufferDescListNonZeroArrayStride = {
        {20u, wgpu::VertexStepMode::Vertex, {{0, wgpu::VertexFormat::Float32x4}}},
        {12u, wgpu::VertexStepMode::Instance, {{3, wgpu::VertexFormat::Float32x2}}},
    };
    wgpu::RenderPipeline pipelineWithNonZeroArrayStride =
        CreateRenderPipelineWithBufferDesc(bufferDescListNonZeroArrayStride);

    // Create the render pipeline with zero array stride
    std::vector<PipelineVertexBufferDesc> bufferDescListZeroArrayStride = {
        {0u, wgpu::VertexStepMode::Vertex, {{0, wgpu::VertexFormat::Float32x4}}},
        {0u, wgpu::VertexStepMode::Instance, {{3, wgpu::VertexFormat::Float32x2}}},
    };
    wgpu::RenderPipeline pipelineWithZeroArrayStride =
        CreateRenderPipelineWithBufferDesc(bufferDescListZeroArrayStride);

    const std::vector<VertexBufferParams> kVertexParamsListForZeroStride = {
        // Size enough for 1 vertex
        {kFloat32x4Stride, 16, 0, wgpu::kWholeSize, 1},
        // No enough size for 1 vertex
        {kFloat32x4Stride, 19, 4, wgpu::kWholeSize, 0},
        {kFloat32x4Stride, 16, 16, wgpu::kWholeSize, 0},
    };

    const std::vector<VertexBufferParams> kInstanceParamsListForZeroStride = {
        // Size enough for 1 instance
        {kFloat32x2Stride, 8, 0, wgpu::kWholeSize, 1},
        // No enough size for 1 instance
        {kFloat32x2Stride, 11, 4, wgpu::kWholeSize, 0},
        {kFloat32x2Stride, 8, 8, wgpu::kWholeSize, 0},
    };

    for (VertexBufferParams vertexParams : kVertexParamsListForZeroStride) {
        for (VertexBufferParams instanceParams : kInstanceParamsListForZeroStride) {
            for (wgpu::RenderPipeline pipeline :
                 {pipelineWithNonZeroArrayStride, pipelineWithZeroArrayStride}) {
                constexpr wgpu::IndexFormat indexFormat = wgpu::IndexFormat::Uint32;
                constexpr uint64_t indexStride = sizeof(uint32_t);

                // Build index buffer for 1 index
                wgpu::Buffer indexBuffer = CreateBuffer(indexStride, wgpu::BufferUsage::Index);
                // Build vertex buffer for vertices
                wgpu::Buffer vertexBuffer = CreateBuffer(vertexParams.bufferSize);
                // Build vertex buffer for instances
                wgpu::Buffer instanceBuffer = CreateBuffer(instanceParams.bufferSize);

                VertexBufferList vertexBufferList = {
                    {0, vertexBuffer, vertexParams.bufferOffsetForEncoder,
                     vertexParams.bufferSizeForEncoder},
                    {1, instanceBuffer, instanceParams.bufferOffsetForEncoder,
                     instanceParams.bufferSizeForEncoder}};

                IndexBufferDesc indexBufferDesc = {indexBuffer, indexFormat};

                const bool vertexModeBufferOOB = vertexParams.maxValidAccessNumber == 0;
                const bool instanceModeBufferOOB = instanceParams.maxValidAccessNumber == 0;

                // Draw validate both vertex and instance step mode buffer OOB.
                // Control case, non-zero stride for both step mode buffer
                TestRenderPassDraw(pipeline, vertexBufferList, /* vertexCount */ 1,
                                   /* instanceCount */ 1, /* firstVertex */ 0,
                                   /* firstInstance */ 0,
                                   /* isSuccess */ !vertexModeBufferOOB && !instanceModeBufferOOB);
                TestRenderPassDraw(pipeline, vertexBufferList, 1, 0, 0, 1,
                                   !vertexModeBufferOOB && !instanceModeBufferOOB);
                TestRenderPassDraw(pipeline, vertexBufferList, 0, 1, 1, 0,
                                   !vertexModeBufferOOB && !instanceModeBufferOOB);
                TestRenderPassDraw(pipeline, vertexBufferList, 0, 0, 1, 1,
                                   !vertexModeBufferOOB && !instanceModeBufferOOB);
                // Vertex step mode buffer will never OOB if (vertexCount + firstVertex) is zero,
                // and only instance step mode buffer OOB will fail validation
                TestRenderPassDraw(pipeline, vertexBufferList, 0, 1, 0, 0, !instanceModeBufferOOB);
                TestRenderPassDraw(pipeline, vertexBufferList, 0, 0, 0, 1, !instanceModeBufferOOB);
                // Instance step mode buffer will never OOB if (instanceCount + firstInstance) is
                // zero, and only vertex step mode buffer OOB will fail validation
                TestRenderPassDraw(pipeline, vertexBufferList, 1, 0, 0, 0, !vertexModeBufferOOB);
                TestRenderPassDraw(pipeline, vertexBufferList, 0, 0, 1, 0, !vertexModeBufferOOB);
                // If both (vertexCount + firstVertex) and (instanceCount + firstInstance) are zero,
                // all vertex buffer will never OOB
                TestRenderPassDraw(pipeline, vertexBufferList, 0, 0, 0, 0, true);

                // DrawIndexed only validate instance step mode buffer OOB.
                // Control case, non-zero stride for instance step mode buffer
                TestRenderPassDrawIndexed(
                    pipeline, indexBufferDesc, vertexBufferList, /* indexCount */ 1,
                    /* instanceCount */ 1, /* firstIndex */ 0, /* baseVertex */ 0,
                    /* firstInstance */ 0, /* isSuccess */ !instanceModeBufferOOB);
                TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 1, 0, 0, 0,
                                          1, !instanceModeBufferOOB);
                // Instance step mode buffer will never OOB if (instanceCount + firstInstance) is
                // zero, validation shall always succeed
                TestRenderPassDrawIndexed(pipeline, indexBufferDesc, vertexBufferList, 1, 0, 0, 0,
                                          0, true);
            }
        }
    }
}

// Verify that if setVertexBuffer and/or setIndexBuffer for multiple times, only the last one is
// taken into account
TEST_F(DrawVertexAndIndexBufferOOBValidationTests, SetBufferMultipleTime) {
    wgpu::IndexFormat indexFormat = wgpu::IndexFormat::Uint32;
    uint32_t indexStride = sizeof(uint32_t);

    // Build index buffer for 11 indexes
    wgpu::Buffer indexBuffer11 = CreateBuffer(11 * indexStride, wgpu::BufferUsage::Index);
    // Build index buffer for 12 indexes
    wgpu::Buffer indexBuffer12 = CreateBuffer(12 * indexStride, wgpu::BufferUsage::Index);
    // Build vertex buffer for 2 vertices
    wgpu::Buffer vertexBuffer2 = CreateBuffer(2 * kFloat32x4Stride);
    // Build vertex buffer for 3 vertices
    wgpu::Buffer vertexBuffer3 = CreateBuffer(3 * kFloat32x4Stride);
    // Build vertex buffer for 4 instances
    wgpu::Buffer instanceBuffer4 = CreateBuffer(4 * kFloat32x2Stride);
    // Build vertex buffer for 5 instances
    wgpu::Buffer instanceBuffer5 = CreateBuffer(5 * kFloat32x2Stride);

    // Test for setting vertex buffer for multiple times
    {
        wgpu::RenderPipeline pipeline = CreateBasicRenderPipelineWithInstance();

        // Set to vertexBuffer3 and instanceBuffer5 at last
        VertexBufferList vertexBufferList = {{0, vertexBuffer2, 0, wgpu::kWholeSize},
                                             {1, instanceBuffer4, 0, wgpu::kWholeSize},
                                             {1, instanceBuffer5, 0, wgpu::kWholeSize},
                                             {0, vertexBuffer3, 0, wgpu::kWholeSize}};

        // For Draw, the max vertexCount is 3 and the max instanceCount is 5
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 5, 0, 0, true);
        TestRenderPassDraw(pipeline, vertexBufferList, 4, 5, 0, 0, false);
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 6, 0, 0, false);
        // For DrawIndex, the max instanceCount is 5
        TestRenderPassDrawIndexed(pipeline, {indexBuffer12, indexFormat}, vertexBufferList, 12, 5,
                                  0, 0, 0, true);
        TestRenderPassDrawIndexed(pipeline, {indexBuffer12, indexFormat}, vertexBufferList, 12, 6,
                                  0, 0, 0, false);

        // Set to vertexBuffer2 and instanceBuffer4 at last
        vertexBufferList = VertexBufferList{{0, vertexBuffer3, 0, wgpu::kWholeSize},
                                            {1, instanceBuffer5, 0, wgpu::kWholeSize},
                                            {0, vertexBuffer2, 0, wgpu::kWholeSize},
                                            {1, instanceBuffer4, 0, wgpu::kWholeSize}};

        // For Draw, the max vertexCount is 2 and the max instanceCount is 4
        TestRenderPassDraw(pipeline, vertexBufferList, 2, 4, 0, 0, true);
        TestRenderPassDraw(pipeline, vertexBufferList, 3, 4, 0, 0, false);
        TestRenderPassDraw(pipeline, vertexBufferList, 2, 5, 0, 0, false);
        // For DrawIndex, the max instanceCount is 4
        TestRenderPassDrawIndexed(pipeline, {indexBuffer12, indexFormat}, vertexBufferList, 12, 4,
                                  0, 0, 0, true);
        TestRenderPassDrawIndexed(pipeline, {indexBuffer12, indexFormat}, vertexBufferList, 12, 5,
                                  0, 0, 0, false);
    }

    // Test for setIndexBuffer multiple times
    {
        wgpu::RenderPipeline pipeline = CreateBasicRenderPipeline();

        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder renderPassEncoder =
                encoder.BeginRenderPass(GetBasicRenderPassDescriptor());
            renderPassEncoder.SetPipeline(pipeline);

            // Index buffer is set to indexBuffer12 at last
            renderPassEncoder.SetIndexBuffer(indexBuffer11, indexFormat);
            renderPassEncoder.SetIndexBuffer(indexBuffer12, indexFormat);

            renderPassEncoder.SetVertexBuffer(0, vertexBuffer3);
            // It should be ok to draw 12 index
            renderPassEncoder.DrawIndexed(12, 1, 0, 0, 0);
            renderPassEncoder.End();

            // Expect success
            encoder.Finish();
        }

        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder renderPassEncoder =
                encoder.BeginRenderPass(GetBasicRenderPassDescriptor());
            renderPassEncoder.SetPipeline(pipeline);

            // Index buffer is set to indexBuffer12 at last
            renderPassEncoder.SetIndexBuffer(indexBuffer11, indexFormat);
            renderPassEncoder.SetIndexBuffer(indexBuffer12, indexFormat);

            renderPassEncoder.SetVertexBuffer(0, vertexBuffer3);
            // It should be index buffer OOB to draw 13 index
            renderPassEncoder.DrawIndexed(13, 1, 0, 0, 0);
            renderPassEncoder.End();

            // Expect failure
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }

        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder renderPassEncoder =
                encoder.BeginRenderPass(GetBasicRenderPassDescriptor());
            renderPassEncoder.SetPipeline(pipeline);

            // Index buffer is set to indexBuffer11 at last
            renderPassEncoder.SetIndexBuffer(indexBuffer12, indexFormat);
            renderPassEncoder.SetIndexBuffer(indexBuffer11, indexFormat);

            renderPassEncoder.SetVertexBuffer(0, vertexBuffer3);
            // It should be ok to draw 11 index
            renderPassEncoder.DrawIndexed(11, 1, 0, 0, 0);
            renderPassEncoder.End();

            // Expect success
            encoder.Finish();
        }

        {
            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
            wgpu::RenderPassEncoder renderPassEncoder =
                encoder.BeginRenderPass(GetBasicRenderPassDescriptor());
            renderPassEncoder.SetPipeline(pipeline);

            // Index buffer is set to indexBuffer11 at last
            renderPassEncoder.SetIndexBuffer(indexBuffer12, indexFormat);
            renderPassEncoder.SetIndexBuffer(indexBuffer11, indexFormat);

            renderPassEncoder.SetVertexBuffer(0, vertexBuffer3);
            // It should be index buffer OOB to draw 12 index
            renderPassEncoder.DrawIndexed(12, 1, 0, 0, 0);
            renderPassEncoder.End();

            // Expect failure
            ASSERT_DEVICE_ERROR(encoder.Finish());
        }
    }
}

}  // anonymous namespace
}  // namespace dawn
