//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// MultiDrawTest: Tests of GL_ANGLE_multi_draw
// MultiDrawIndirectTest: Tests of GL_EXT_multi_draw_indirect

#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

using namespace angle;

namespace
{

// Create a kWidth * kHeight canvas equally split into kCountX * kCountY tiles
// each containing a quad partially covering each tile
constexpr uint32_t kWidth                  = 256;
constexpr uint32_t kHeight                 = 256;
constexpr uint32_t kCountX                 = 8;
constexpr uint32_t kCountY                 = 8;
constexpr uint32_t kQuadCount              = kCountX * kCountY;
constexpr uint32_t kTriCount               = kQuadCount * 2;
constexpr std::array<GLfloat, 2> kTileSize = {
    1.f / static_cast<GLfloat>(kCountX),
    1.f / static_cast<GLfloat>(kCountY),
};
constexpr std::array<uint32_t, 2> kTilePixelSize  = {kWidth / kCountX, kHeight / kCountY};
constexpr std::array<GLfloat, 2> kQuadRadius      = {0.25f * kTileSize[0], 0.25f * kTileSize[1]};
constexpr std::array<uint32_t, 2> kPixelCheckSize = {
    static_cast<uint32_t>(kQuadRadius[0] * kWidth),
    static_cast<uint32_t>(kQuadRadius[1] * kHeight)};

constexpr std::array<GLfloat, 2> getTileCenter(uint32_t x, uint32_t y)
{
    return {
        kTileSize[0] * (0.5f + static_cast<GLfloat>(x)),
        kTileSize[1] * (0.5f + static_cast<GLfloat>(y)),
    };
}
constexpr std::array<std::array<GLfloat, 3>, 4> getQuadVertices(uint32_t x, uint32_t y)
{
    const auto center = getTileCenter(x, y);
    return {
        std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] - kQuadRadius[1], 0.0f},
        std::array<GLfloat, 3>{center[0] + kQuadRadius[0], center[1] - kQuadRadius[1], 0.0f},
        std::array<GLfloat, 3>{center[0] + kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},
        std::array<GLfloat, 3>{center[0] - kQuadRadius[0], center[1] + kQuadRadius[1], 0.0f},
    };
}

enum class DrawIDOption
{
    NoDrawID,
    UseDrawID,
};

enum class InstancingOption
{
    NoInstancing,
    UseInstancing,
};

enum class BufferDataUsageOption
{
    StaticDraw,
    DynamicDraw
};

using MultiDrawTestParams =
    std::tuple<angle::PlatformParameters, DrawIDOption, InstancingOption, BufferDataUsageOption>;

using MultiDrawIndirectTestParams = angle::PlatformParameters;

struct PrintToStringParamName
{
    std::string operator()(const ::testing::TestParamInfo<MultiDrawTestParams> &info) const
    {
        ::std::stringstream ss;
        ss << std::get<0>(info.param)
           << (std::get<3>(info.param) == BufferDataUsageOption::StaticDraw ? "__StaticDraw"
                                                                            : "__DynamicDraw")
           << (std::get<2>(info.param) == InstancingOption::UseInstancing ? "__Instanced" : "")
           << (std::get<1>(info.param) == DrawIDOption::UseDrawID ? "__DrawID" : "");
        return ss.str();
    }
};

struct DrawArraysIndirectCommand
{
    DrawArraysIndirectCommand() : count(0u), instanceCount(0u), first(0u), baseInstance(0u) {}
    DrawArraysIndirectCommand(GLuint count, GLuint instanceCount, GLuint first, GLuint baseInstance)
        : count(count), instanceCount(instanceCount), first(first), baseInstance(baseInstance)
    {}
    GLuint count;
    GLuint instanceCount;
    GLuint first;
    GLuint baseInstance;
};

struct DrawElementsIndirectCommand
{
    DrawElementsIndirectCommand()
        : count(0), primCount(0), firstIndex(0), baseVertex(0), baseInstance(0)
    {}
    DrawElementsIndirectCommand(GLuint count,
                                GLuint primCount,
                                GLuint firstIndex,
                                GLint baseVertex,
                                GLuint baseInstance)
        : count(count),
          primCount(primCount),
          firstIndex(firstIndex),
          baseVertex(baseVertex),
          baseInstance(baseInstance)
    {}
    GLuint count;
    GLuint primCount;
    GLuint firstIndex;
    GLint baseVertex;
    GLuint baseInstance;
};

// The tests in MultiDrawTest and MultiDrawNoInstancingSupportTest check the correctness
// of the ANGLE_multi_draw extension.
// An array of quads is drawn across the screen.
// gl_DrawID is checked by using it to select the color of the draw.
// MultiDraw*Instanced entrypoints use the existing instancing APIs which are
// more fully tested in InstancingTest.cpp.
// Correct interaction with the instancing APIs is tested here by using scaling
// and then instancing the array of quads over four quadrants on the screen.
class MultiDrawTest : public ANGLETestBase, public ::testing::TestWithParam<MultiDrawTestParams>
{
  protected:
    MultiDrawTest()
        : ANGLETestBase(std::get<0>(GetParam())),
          mNonIndexedVertexBuffer(0u),
          mVertexBuffer(0u),
          mIndexBuffer(0u),
          mInstanceBuffer(0u),
          mProgram(0u),
          mPositionLoc(0u),
          mInstanceLoc(0u)
    {
        setWindowWidth(kWidth);
        setWindowHeight(kHeight);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }

    bool IsDrawIDTest() const { return std::get<1>(GetParam()) == DrawIDOption::UseDrawID; }

    bool IsInstancedTest() const
    {
        return std::get<2>(GetParam()) == InstancingOption::UseInstancing;
    }

    GLenum getBufferDataUsage() const
    {
        return std::get<3>(GetParam()) == BufferDataUsageOption::StaticDraw ? GL_STATIC_DRAW
                                                                            : GL_DYNAMIC_DRAW;
    }

    std::string VertexShaderSource()
    {

        std::stringstream shader;
        shader << (IsDrawIDTest() ? "#extension GL_ANGLE_multi_draw : require\n" : "")
               << (IsInstancedTest() ? "attribute float vInstance;" : "") << R"(
attribute vec2 vPosition;
varying vec4 color;
void main()
{
    int id = )" << (IsDrawIDTest() ? "gl_DrawID" : "0")
               << ";"
               << R"(
    float quad_id = float(id / 2);
    float color_id = quad_id - (3.0 * floor(quad_id / 3.0));
    if (color_id == 0.0) {
      color = vec4(1, 0, 0, 1);
    } else if (color_id == 1.0) {
      color = vec4(0, 1, 0, 1);
    } else {
      color = vec4(0, 0, 1, 1);
    }

    mat3 transform = mat3(1.0);
)"
               << (IsInstancedTest() ? R"(
    transform[0][0] = 0.5;
    transform[1][1] = 0.5;
    if (vInstance == 0.0) {

    } else if (vInstance == 1.0) {
        transform[2][0] = 0.5;
    } else if (vInstance == 2.0) {
        transform[2][1] = 0.5;
    } else if (vInstance == 3.0) {
        transform[2][0] = 0.5;
        transform[2][1] = 0.5;
    }
)"
                                     : "")
               << R"(
    gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
})";

        return shader.str();
    }

    std::string FragmentShaderSource()
    {
        return
            R"(precision mediump float;
            varying vec4 color;
            void main()
            {
                gl_FragColor = color;
            })";
    }

    void SetupProgram()
    {
        mProgram = CompileProgram(VertexShaderSource().c_str(), FragmentShaderSource().c_str());
        EXPECT_GL_NO_ERROR();
        ASSERT_GE(mProgram, 1u);
        glUseProgram(mProgram);
        mPositionLoc = glGetAttribLocation(mProgram, "vPosition");
        mInstanceLoc = glGetAttribLocation(mProgram, "vInstance");
    }

    void SetupBuffers()
    {
        for (uint32_t y = 0; y < kCountY; ++y)
        {
            for (uint32_t x = 0; x < kCountX; ++x)
            {
                // v3 ---- v2
                // |       |
                // |       |
                // v0 ---- v1
                uint32_t quadIndex         = y * kCountX + x;
                GLushort starting_index    = static_cast<GLushort>(4 * quadIndex);
                std::array<GLushort, 6> is = {0, 1, 2, 0, 2, 3};
                const auto vs              = getQuadVertices(x, y);
                for (GLushort i : is)
                {
                    mIndices.push_back(starting_index + i);
                }

                for (const auto &v : vs)
                {
                    mVertices.insert(mVertices.end(), v.begin(), v.end());
                }

                for (GLushort i : is)
                {
                    mNonIndexedVertices.insert(mNonIndexedVertices.end(), vs[i].begin(),
                                               vs[i].end());
                }
            }
        }

        std::array<GLfloat, 4> instances{0, 1, 2, 3};

        glGenBuffers(1, &mNonIndexedVertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mNonIndexedVertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mNonIndexedVertices.size(),
                     mNonIndexedVertices.data(), getBufferDataUsage());

        glGenBuffers(1, &mVertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mVertices.size(), mVertices.data(),
                     getBufferDataUsage());

        glGenBuffers(1, &mIndexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * mIndices.size(), mIndices.data(),
                     getBufferDataUsage());

        glGenBuffers(1, &mInstanceBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mInstanceBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * instances.size(), instances.data(),
                     getBufferDataUsage());

        ASSERT_GL_NO_ERROR();
    }

    void DoVertexAttribDivisor(GLint location, GLuint divisor)
    {
        if (getClientMajorVersion() <= 2)
        {
            ASSERT_TRUE(IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
            glVertexAttribDivisorANGLE(location, divisor);
        }
        else
        {
            glVertexAttribDivisor(location, divisor);
        }
    }

    void DoDrawArrays()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindBuffer(GL_ARRAY_BUFFER, mNonIndexedVertexBuffer);
        glEnableVertexAttribArray(mPositionLoc);
        glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

        std::vector<GLint> firsts(kTriCount);
        std::vector<GLsizei> counts(kTriCount, 3);
        for (uint32_t i = 0; i < kTriCount; ++i)
            firsts[i] = i * 3;

        if (IsInstancedTest())
        {
            glBindBuffer(GL_ARRAY_BUFFER, mInstanceBuffer);
            glEnableVertexAttribArray(mInstanceLoc);
            glVertexAttribPointer(mInstanceLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
            DoVertexAttribDivisor(mInstanceLoc, 1);
            std::vector<GLsizei> instanceCounts(kTriCount, 4);
            glMultiDrawArraysInstancedANGLE(GL_TRIANGLES, firsts.data(), counts.data(),
                                            instanceCounts.data(), kTriCount);
        }
        else
        {
            glMultiDrawArraysANGLE(GL_TRIANGLES, firsts.data(), counts.data(), kTriCount);
        }
    }

    void DoDrawElements()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
        glEnableVertexAttribArray(mPositionLoc);
        glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

        std::vector<GLsizei> counts(kTriCount, 3);
        std::vector<const GLvoid *> indices(kTriCount);
        for (uint32_t i = 0; i < kTriCount; ++i)
            indices[i] = reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(i * 3 * 2));

        if (IsInstancedTest())
        {
            glBindBuffer(GL_ARRAY_BUFFER, mInstanceBuffer);
            glEnableVertexAttribArray(mInstanceLoc);
            glVertexAttribPointer(mInstanceLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
            DoVertexAttribDivisor(mInstanceLoc, 1);
            std::vector<GLsizei> instanceCounts(kTriCount, 4);
            glMultiDrawElementsInstancedANGLE(GL_TRIANGLES, counts.data(), GL_UNSIGNED_SHORT,
                                              indices.data(), instanceCounts.data(), kTriCount);
        }
        else
        {
            glMultiDrawElementsANGLE(GL_TRIANGLES, counts.data(), GL_UNSIGNED_SHORT, indices.data(),
                                     kTriCount);
        }
    }

    enum class DrawIDOptionOverride
    {
        Default,
        NoDrawID,
        UseDrawID,
    };

    void CheckDrawResult(DrawIDOptionOverride overrideDrawID)
    {
        for (uint32_t y = 0; y < kCountY; ++y)
        {
            for (uint32_t x = 0; x < kCountX; ++x)
            {
                uint32_t center_x = x * kTilePixelSize[0] + kTilePixelSize[0] / 2;
                uint32_t center_y = y * kTilePixelSize[1] + kTilePixelSize[1] / 2;
                uint32_t quadID = IsDrawIDTest() && overrideDrawID != DrawIDOptionOverride::NoDrawID
                                      ? y * kCountX + x
                                      : 0;
                uint32_t colorID              = quadID % 3u;
                std::array<GLColor, 3> colors = {GLColor(255, 0, 0, 255), GLColor(0, 255, 0, 255),
                                                 GLColor(0, 0, 255, 255)};
                GLColor expected              = colors[colorID];

                if (IsInstancedTest())
                {
                    EXPECT_PIXEL_RECT_EQ(center_x / 2 - kPixelCheckSize[0] / 4,
                                         center_y / 2 - kPixelCheckSize[1] / 4,
                                         kPixelCheckSize[0] / 2, kPixelCheckSize[1] / 2, expected);
                    EXPECT_PIXEL_RECT_EQ(center_x / 2 - kPixelCheckSize[0] / 4 + kWidth / 2,
                                         center_y / 2 - kPixelCheckSize[1] / 4,
                                         kPixelCheckSize[0] / 2, kPixelCheckSize[1] / 2, expected);
                    EXPECT_PIXEL_RECT_EQ(center_x / 2 - kPixelCheckSize[0] / 4,
                                         center_y / 2 - kPixelCheckSize[1] / 4 + kHeight / 2,
                                         kPixelCheckSize[0] / 2, kPixelCheckSize[1] / 2, expected);
                    EXPECT_PIXEL_RECT_EQ(center_x / 2 - kPixelCheckSize[0] / 4 + kWidth / 2,
                                         center_y / 2 - kPixelCheckSize[1] / 4 + kHeight / 2,
                                         kPixelCheckSize[0] / 2, kPixelCheckSize[1] / 2, expected);
                }
                else
                {
                    EXPECT_PIXEL_RECT_EQ(center_x - kPixelCheckSize[0] / 2,
                                         center_y - kPixelCheckSize[1] / 2, kPixelCheckSize[0],
                                         kPixelCheckSize[1], expected);
                }
            }
        }
    }

    void TearDown() override
    {
        if (mNonIndexedVertexBuffer != 0u)
        {
            glDeleteBuffers(1, &mNonIndexedVertexBuffer);
        }
        if (mVertexBuffer != 0u)
        {
            glDeleteBuffers(1, &mVertexBuffer);
        }
        if (mIndexBuffer != 0u)
        {
            glDeleteBuffers(1, &mIndexBuffer);
        }
        if (mInstanceBuffer != 0u)
        {
            glDeleteBuffers(1, &mInstanceBuffer);
        }
        if (mProgram != 0)
        {
            glDeleteProgram(mProgram);
        }
        ANGLETestBase::ANGLETestTearDown();
    }

    bool requestMultiDrawExtension() { return EnsureGLExtensionEnabled("GL_ANGLE_multi_draw"); }

    bool requestInstancedExtension()
    {
        return EnsureGLExtensionEnabled("GL_ANGLE_instanced_arrays");
    }

    bool requestExtensions()
    {
        if (IsInstancedTest() && getClientMajorVersion() <= 2)
        {
            if (!requestInstancedExtension())
            {
                return false;
            }
        }
        return requestMultiDrawExtension();
    }

    std::vector<GLushort> mIndices;
    std::vector<GLfloat> mVertices;
    std::vector<GLfloat> mNonIndexedVertices;
    GLuint mNonIndexedVertexBuffer;
    GLuint mVertexBuffer;
    GLuint mIndexBuffer;
    GLuint mInstanceBuffer;
    GLuint mProgram;
    GLint mPositionLoc;
    GLint mInstanceLoc;
};

class MultiDrawNoInstancingSupportTest : public MultiDrawTest
{
    void SetUp() override
    {
        ASSERT_LE(getClientMajorVersion(), 2);
        ASSERT_TRUE(IsInstancedTest());
        MultiDrawTest::SetUp();
    }
};

// The tests in MultiDrawIndirectTest check the correctness
// of the EXT_multi_draw_indirect extension.
// 4 magenta triangles are drawn at the corners of the screen
// in different orders from the same vertex and index arrays.
class MultiDrawIndirectTest : public ANGLETestBase,
                              public ::testing::TestWithParam<MultiDrawIndirectTestParams>
{
  protected:
    MultiDrawIndirectTest()
        : ANGLETestBase(GetParam()),
          mPositionLoc(0u),
          mColorLoc(0u),
          mVertexBuffer(0u),
          mColorBuffer(0u),
          mIndexBuffer(0u),
          mIndirectBuffer(0u),
          mProgram(0u)
    {
        setWindowWidth(kWidth);
        setWindowHeight(kHeight);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void SetUp() override { ANGLETestBase::ANGLETestSetUp(); }

    void SetupProgramIndirect(bool isMultiColor)
    {
        // Define the vertex and fragment shaders
        std::stringstream kVS;
        kVS << R"(#version 310 es
in vec3 aPos;
)"
            << (isMultiColor ? R"(in vec4 aColor;
out vec4 vColor;)"
                             : "")
            << R"(
void main()
{
    gl_Position = vec4(aPos.x, aPos.y, 0, 1);
)" << (isMultiColor ? R"(vColor = vec4(aColor.x, aColor.y, aColor.z, 1.0);)" : "")
            << R"(
})";

        std::stringstream kFS;
        kFS << R"(#version 310 es
precision mediump float;
)"
            << (isMultiColor ? R"(in vec4 vColor;
)"
                             : "")
            << R"(
out vec4 colorOut;
void main()
{
)" << (isMultiColor ? R"(colorOut = vColor;)" : R"(colorOut = vec4(1.0, 0.0, 1.0, 1.0);)")
            << R"(
})";
        mProgram = CompileProgram(kVS.str().c_str(), kFS.str().c_str());
        EXPECT_GL_NO_ERROR();
        ASSERT_GE(mProgram, 1u);
        glUseProgram(mProgram);
        mPositionLoc = glGetAttribLocation(mProgram, "aPos");
        mColorLoc    = glGetAttribLocation(mProgram, "aColor");
    }

    void TearDown() override
    {
        if (mVertexBuffer != 0u)
        {
            glDeleteBuffers(1, &mVertexBuffer);
        }
        if (mColorBuffer != 0u)
        {
            glDeleteBuffers(1, &mColorBuffer);
        }
        if (mIndexBuffer != 0u)
        {
            glDeleteBuffers(1, &mIndexBuffer);
        }
        if (mProgram != 0)
        {
            glDeleteProgram(mProgram);
        }
        if (mIndirectBuffer != 0u)
        {
            glDeleteBuffers(1, &mIndirectBuffer);
        }
        ANGLETestBase::ANGLETestTearDown();
    }

    GLint mPositionLoc;
    GLint mColorLoc;
    GLuint mVertexBuffer;
    GLuint mColorBuffer;
    GLuint mIndexBuffer;
    GLuint mIndirectBuffer;
    GLuint mProgram;
};

// glMultiDraw*ANGLE are emulated and should always be available
TEST_P(MultiDrawTest, RequestExtension)
{
    EXPECT_TRUE(requestMultiDrawExtension());
}

// Test that compile a program with the extension succeeds
TEST_P(MultiDrawTest, CanCompile)
{
    ANGLE_SKIP_TEST_IF(!requestExtensions());
    SetupProgram();
}

// Tests basic functionality of glMultiDrawArraysANGLE
TEST_P(MultiDrawTest, MultiDrawArrays)
{
    ANGLE_SKIP_TEST_IF(!requestExtensions());

    // http://anglebug.com/5265
    ANGLE_SKIP_TEST_IF(IsInstancedTest() && IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());

    SetupBuffers();
    SetupProgram();
    DoDrawArrays();
    EXPECT_GL_NO_ERROR();
    CheckDrawResult(DrawIDOptionOverride::Default);
}

// Tests basic functionality of glMultiDrawElementsANGLE
TEST_P(MultiDrawTest, MultiDrawElements)
{
    ANGLE_SKIP_TEST_IF(!requestExtensions());
    SetupBuffers();
    SetupProgram();
    DoDrawElements();
    EXPECT_GL_NO_ERROR();
    CheckDrawResult(DrawIDOptionOverride::Default);
}

// Tests that glMultiDrawArraysANGLE followed by glDrawArrays works.  gl_DrawID in the second call
// must be 0.
TEST_P(MultiDrawTest, MultiDrawArraysThenDrawArrays)
{
    ANGLE_SKIP_TEST_IF(!requestExtensions());

    // http://anglebug.com/5265
    ANGLE_SKIP_TEST_IF(IsInstancedTest() && IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());

    SetupBuffers();
    SetupProgram();
    DoDrawArrays();
    EXPECT_GL_NO_ERROR();
    CheckDrawResult(DrawIDOptionOverride::Default);

    if (IsInstancedTest())
    {
        ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_instanced_arrays") &&
                           !IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
        if (IsGLExtensionEnabled("GL_EXT_instanced_arrays"))
        {
            glDrawArraysInstancedEXT(GL_TRIANGLES, 0, 3 * kTriCount, 4);
        }
        else
        {
            glDrawArraysInstancedANGLE(GL_TRIANGLES, 0, 3 * kTriCount, 4);
        }
        ASSERT_GL_NO_ERROR();
    }
    else
    {
        glDrawArrays(GL_TRIANGLES, 0, 3 * kTriCount);
        ASSERT_GL_NO_ERROR();
    }
    CheckDrawResult(DrawIDOptionOverride::NoDrawID);
}

// Tests basic functionality of glMultiDrawArraysIndirectEXT
TEST_P(MultiDrawIndirectTest, MultiDrawArraysIndirect)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multi_draw_indirect"));

    // Set up the vertex array
    const GLint triangleCount           = 4;
    const std::vector<GLfloat> vertices = {
        -1, 1,  0, -1, 0, 0, 0, 1,  0, 1, 1,  0, 1, 0,  0, 0, 1, 0,
        -1, -1, 0, -1, 0, 0, 0, -1, 0, 1, -1, 0, 0, -1, 0, 1, 0, 0,
    };

    // Set up the vertex buffer
    GLVertexArray vao;
    glBindVertexArray(vao);

    glGenBuffers(1, &mVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Generate program
    SetupProgramIndirect(false);

    // Set up the vertex array format
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    EXPECT_GL_NO_ERROR();

    // Set up the indirect data array
    std::array<DrawArraysIndirectCommand, triangleCount> indirectData;
    const GLsizei icSize = sizeof(DrawArraysIndirectCommand);
    for (auto i = 0; i < triangleCount; i++)
    {
        indirectData[i] = DrawArraysIndirectCommand(3, 1, 3 * i, i);
    }

    glGenBuffers(1, &mIndirectBuffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, mIndirectBuffer);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, icSize * indirectData.size(), indirectData.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Invalid value check for drawcount and stride
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES, nullptr, 0, 0);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES, nullptr, -1, 0);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES, nullptr, 1, 2);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Check the error from sourcing beyond the allocated buffer size
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawArraysIndirectEXT(
        GL_TRIANGLES,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * triangleCount)), 1, 0);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Draw all triangles using glMultiDrawArraysIndirect
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES, nullptr, triangleCount, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw the triangles in different order
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES, nullptr, 1, 0);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES,
                                 reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * 2)),
                                 triangleCount - 2, 0);
    glMultiDrawArraysIndirectEXT(
        GL_TRIANGLES, reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize)), 1, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw the triangles partially using stride
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawArraysIndirectEXT(GL_TRIANGLES, nullptr, 2, icSize * 3);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);
}

// Tests basic functionality of glMultiDrawElementsIndirectEXT
TEST_P(MultiDrawIndirectTest, MultiDrawElementsIndirect)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multi_draw_indirect"));

    // Set up the vertex array
    const GLint triangleCount           = 4;
    const std::vector<GLfloat> vertices = {
        -1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0,
    };
    const std::vector<GLuint> indices = {
        1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 0, 1,
    };

    // Set up the vertex and index buffers
    GLVertexArray vao;
    glBindVertexArray(vao);

    glGenBuffers(1, &mVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    glGenBuffers(1, &mIndexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Generate program
    SetupProgramIndirect(false);

    // Set up the vertex array format
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    EXPECT_GL_NO_ERROR();

    // Set up the indirect data array
    std::array<DrawElementsIndirectCommand, triangleCount> indirectData;
    const GLsizei icSize = sizeof(DrawElementsIndirectCommand);
    for (auto i = 0; i < triangleCount; i++)
    {
        indirectData[i] = DrawElementsIndirectCommand(3, 1, 3 * i, 0, i);
    }

    glGenBuffers(1, &mIndirectBuffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, mIndirectBuffer);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, icSize * indirectData.size(), indirectData.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Invalid value check for drawcount and stride
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, 0, 0);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, -1, 0);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, 1, 2);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Check the error from sourcing beyond the allocated buffer size
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(
        GL_TRIANGLES, GL_UNSIGNED_INT,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * triangleCount)), 1, 0);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Draw all triangles using glMultiDrawElementsIndirect
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, triangleCount, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw the triangles in a different order
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, 1, 0);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT,
                                   reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize)),
                                   triangleCount - 2, 0);
    glMultiDrawElementsIndirectEXT(
        GL_TRIANGLES, GL_UNSIGNED_INT,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * 3)), 1, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw the triangles partially using stride
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, 2, icSize * 3);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);
}

// Test functionality glMultiDrawElementsIndirectEXT with unsigned short
// indices and instanced attributes.
TEST_P(MultiDrawIndirectTest, MultiDrawElementsIndirectInstancedUshort)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multi_draw_indirect"));

    // Set up the vertex array
    const GLint triangleCount           = 4;
    const std::vector<GLfloat> vertices = {
        -1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0,
    };
    const std::vector<GLushort> indices = {
        1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 0, 1,
    };
    const std::vector<GLuint> instancedColor = {GLColor::white.asUint(), GLColor::red.asUint(),
                                                GLColor::green.asUint(), GLColor::blue.asUint()};

    // Generate program
    SetupProgramIndirect(true);

    // Set up the vertex and index buffers
    GLVertexArray vao;
    glBindVertexArray(vao);

    glGenBuffers(1, &mVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    GLBuffer instanceBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, instanceBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLuint) * instancedColor.size(), instancedColor.data(),
                 GL_STATIC_DRAW);
    glEnableVertexAttribArray(mColorLoc);
    glVertexAttribPointer(mColorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
    glVertexAttribDivisor(mColorLoc, 1);

    glGenBuffers(1, &mIndexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Set up the indirect data array
    std::array<DrawElementsIndirectCommand, triangleCount> indirectData;
    const GLsizei icSize = sizeof(DrawElementsIndirectCommand);
    for (auto i = 0; i < triangleCount; i++)
    {
        indirectData[i] = DrawElementsIndirectCommand(3, 1, 3 * i, 0, i);
    }

    glGenBuffers(1, &mIndirectBuffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, mIndirectBuffer);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, icSize * indirectData.size(), indirectData.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Invalid value check for drawcount and stride
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, 0, 0);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, -1, 0);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, 1, 2);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    // Check the error from sourcing beyond the allocated buffer size
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(
        GL_TRIANGLES, GL_UNSIGNED_SHORT,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * triangleCount)), 1, 0);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Draw all triangles using glMultiDrawElementsIndirect
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, triangleCount, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::white);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw the triangles in a different order
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, 1, 0);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT,
                                   reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize)),
                                   triangleCount - 2, 0);
    glMultiDrawElementsIndirectEXT(
        GL_TRIANGLES, GL_UNSIGNED_SHORT,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * 3)), 1, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::white);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw the triangles partially using stride
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, 2, icSize * 3);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::white);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);
}

// Tests functionality of glMultiDrawElementsIndirectEXT with more than one triangle in one element
// of the indirect buffer.
TEST_P(MultiDrawIndirectTest, MultiDrawElementsIndirectMultipleTriangles)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multi_draw_indirect"));

    // Set up the vertex array
    const GLint triangleCount           = 4;
    const std::vector<GLfloat> vertices = {
        -1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0,
    };
    const std::vector<GLuint> indices = {
        1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 0, 1,
    };

    // Set up the vertex and index buffers
    GLVertexArray vao;
    glBindVertexArray(vao);

    glGenBuffers(1, &mVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    glGenBuffers(1, &mIndexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Generate program
    SetupProgramIndirect(false);

    // Set up the vertex array format
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    EXPECT_GL_NO_ERROR();

    // Set up the indirect data array; first element represents two triangles.
    std::array<DrawElementsIndirectCommand, triangleCount - 1> indirectData;
    const GLsizei icSize = sizeof(DrawElementsIndirectCommand);
    for (auto i = 0; i < triangleCount - 1; i++)
    {
        if (i == 0)
        {
            indirectData[i] = DrawElementsIndirectCommand(6, 2, 0, 0, i);
        }
        else
        {
            indirectData[i] = DrawElementsIndirectCommand(3, 1, 3 * (i + 1), 0, i);
        }
    }

    glGenBuffers(1, &mIndirectBuffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, mIndirectBuffer);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, icSize * indirectData.size(), indirectData.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Draw all triangles using glMultiDrawElementsIndirect
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, triangleCount - 1, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);
}

// Tests glMultiDrawElementsIndirectEXT with glMultiDrawElementsANGLE to see if the index buffer
// offset is being reset.
TEST_P(MultiDrawIndirectTest, MultiDrawElementsIndirectCheckBufferOffset)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multi_draw_indirect"));

    // Set up the vertex array
    const GLint triangleCount           = 4;
    const std::vector<GLfloat> vertices = {
        -1, 0, 0, -1, 1,  0, 0, 1,  0, 0, 1,  0, 1,  1,  0, 1,  0, 0,
        1,  0, 0, 1,  -1, 0, 0, -1, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0,
    };
    const std::vector<GLfloat> colors = {
        1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
        0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0,
    };
    const std::vector<GLuint> indices = {
        3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2,
    };

    // Set up the vertex and index buffers
    GLVertexArray vao;
    glBindVertexArray(vao);

    glGenBuffers(1, &mVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    glGenBuffers(1, &mColorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mColorBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * colors.size(), colors.data(), GL_STATIC_DRAW);

    glGenBuffers(1, &mIndexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Generate program
    SetupProgramIndirect(true);

    // Set up the vertex array format
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    EXPECT_GL_NO_ERROR();

    glBindBuffer(GL_ARRAY_BUFFER, mColorBuffer);
    glEnableVertexAttribArray(mColorLoc);
    glVertexAttribPointer(mColorLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    EXPECT_GL_NO_ERROR();

    // Set up the arrays for the direct draw
    std::vector<GLsizei> counts(triangleCount, 3);
    std::vector<const GLvoid *> indicesDirect(triangleCount);
    for (auto i = 0; i < triangleCount; i++)
    {
        indicesDirect[i] =
            reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(i * 3 * sizeof(GLuint)));
    }

    // Set up the indirect data array for indirect draw
    std::array<DrawElementsIndirectCommand, triangleCount> indirectData;
    const GLsizei icSize = sizeof(DrawElementsIndirectCommand);
    for (auto i = 0; i < triangleCount; i++)
    {
        indirectData[i] = DrawElementsIndirectCommand(3, 1, 3 * i, 0, i);
    }

    glGenBuffers(1, &mIndirectBuffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, mIndirectBuffer);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, icSize * indirectData.size(), indirectData.data(),
                 GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    // Draw using glMultiDrawElementsIndirect
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(
        GL_TRIANGLES, GL_UNSIGNED_INT,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * 2)), triangleCount - 2, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw using glMultiDrawElementsANGLE
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsANGLE(GL_TRIANGLES, counts.data(), GL_UNSIGNED_INT, indicesDirect.data(),
                             triangleCount);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw using glMultiDrawElementsANGLE again
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsANGLE(GL_TRIANGLES, counts.data(), GL_UNSIGNED_INT, indicesDirect.data(),
                             triangleCount - 1);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw using glMultiDrawElementsIndirect again
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(
        GL_TRIANGLES, GL_UNSIGNED_INT,
        reinterpret_cast<const void *>(static_cast<uintptr_t>(icSize * 3)), triangleCount - 3, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::transparentBlack);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);

    // Draw using glMultiDrawElementsIndirect one more time
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMultiDrawElementsIndirectEXT(GL_TRIANGLES, GL_UNSIGNED_INT, nullptr, triangleCount, 0);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::transparentBlack);
}

// Check that glMultiDraw*Instanced without instancing support results in GL_INVALID_OPERATION
TEST_P(MultiDrawNoInstancingSupportTest, InvalidOperation)
{
    ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
    requestMultiDrawExtension();
    SetupBuffers();
    SetupProgram();

    GLint first       = 0;
    GLsizei count     = 3;
    GLvoid *indices   = nullptr;
    GLsizei instances = 1;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindBuffer(GL_ARRAY_BUFFER, mNonIndexedVertexBuffer);
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glMultiDrawArraysInstancedANGLE(GL_TRIANGLES, &first, &count, &instances, 1);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glEnableVertexAttribArray(mPositionLoc);
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glMultiDrawElementsInstancedANGLE(GL_TRIANGLES, &count, GL_UNSIGNED_SHORT, &indices, &instances,
                                      1);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

const angle::PlatformParameters platforms[] = {
    ES2_D3D9(),  ES2_OPENGL(), ES2_OPENGLES(), ES2_VULKAN(),
    ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(),
};

const angle::PlatformParameters es2_platforms[] = {
    ES2_D3D9(),
    ES2_OPENGL(),
    ES2_OPENGLES(),
    ES2_VULKAN(),
};

INSTANTIATE_TEST_SUITE_P(
    ,
    MultiDrawTest,
    testing::Combine(
        testing::ValuesIn(::angle::FilterTestParams(platforms, ArraySize(platforms))),
        testing::Values(DrawIDOption::NoDrawID, DrawIDOption::UseDrawID),
        testing::Values(InstancingOption::NoInstancing, InstancingOption::UseInstancing),
        testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw)),
    PrintToStringParamName());

INSTANTIATE_TEST_SUITE_P(
    ,
    MultiDrawNoInstancingSupportTest,
    testing::Combine(
        testing::ValuesIn(::angle::FilterTestParams(es2_platforms, ArraySize(es2_platforms))),
        testing::Values(DrawIDOption::NoDrawID, DrawIDOption::UseDrawID),
        testing::Values(InstancingOption::UseInstancing),
        testing::Values(BufferDataUsageOption::StaticDraw, BufferDataUsageOption::DynamicDraw)),
    PrintToStringParamName());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultiDrawIndirectTest);

ANGLE_INSTANTIATE_TEST_ES31_AND(MultiDrawIndirectTest,
                                ES31_VULKAN().disable(Feature::SupportsMultiDrawIndirect));
}  // namespace
