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

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

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"(
            @stage(fragment) fn main() -> @location(0) vec4<f32> {
                return vec4<f32>(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 << " : vec4<f32>,";
                attributeCount++;
            }
        }

        std::stringstream shaderStringStream;

        shaderStringStream << R"(
            @stage(vertex)
            fn main()" << inputStringStream.str()
                           << R"() -> @builtin(position) vec4<f32> {
                return vec4<f32>(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::VertexBufferNotUsed, {}},
             {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::VertexBufferNotUsed, {}},
             {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
