//
// Copyright 2015 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.
//

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

using namespace angle;

namespace
{
enum Geometry
{
    Quad,
    Point
};
enum Storage
{
    Buffer,
    Memory
};
enum Draw
{
    Indexed,
    NonIndexed
};
enum Vendor
{
    Angle,
    Ext
};
}  // namespace

class InstancingTest : public ANGLETest
{
  protected:
    InstancingTest()
    {
        setWindowWidth(256);
        setWindowHeight(256);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void testTearDown() override
    {
        glDeleteBuffers(1, &mInstanceBuffer);
        glDeleteProgram(mProgram[0]);
        glDeleteProgram(mProgram[1]);
    }

    void testSetUp() override
    {
        for (unsigned i = 0; i < kMaxDrawn; ++i)
        {
            mInstanceData[i] = i * kDrawSize;
        }
        glGenBuffers(1, &mInstanceBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mInstanceBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(mInstanceData), mInstanceData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        const std::string inst = "attribute float a_instance;";
        const std::string pos  = "attribute vec2 a_position;";
        const std::string main = R"(
            void main()
            {
                gl_PointSize = 6.0;
                gl_Position = vec4(a_position.x, a_position.y + a_instance, 0, 1);
            }
        )";

        // attrib 0 is instanced
        const std::string inst0 = inst + pos + main;
        mProgram[0]             = CompileProgram(inst0.c_str(), essl1_shaders::fs::Red());
        ASSERT_NE(0u, mProgram[0]);
        ASSERT_EQ(0, glGetAttribLocation(mProgram[0], "a_instance"));
        ASSERT_EQ(1, glGetAttribLocation(mProgram[0], "a_position"));

        // attrib 1 is instanced
        const std::string inst1 = pos + inst + main;
        mProgram[1]             = CompileProgram(inst1.c_str(), essl1_shaders::fs::Red());
        ASSERT_NE(0u, mProgram[1]);
        ASSERT_EQ(1, glGetAttribLocation(mProgram[1], "a_instance"));
        ASSERT_EQ(0, glGetAttribLocation(mProgram[1], "a_position"));

        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    }

    void runTest(unsigned numInstance,
                 unsigned divisor,
                 const int instanceAttrib,  // which attrib is instanced: 0 or 1
                 Geometry geometry,
                 Draw draw,
                 Storage storage,
                 Vendor vendor,
                 unsigned offset)  // for NonIndexed/DrawArrays only
    {
        if (vendor == Angle)
        {
            ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));
        }
        else if (vendor == Ext)
        {
            ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_instanced_arrays"));
        }

        // TODO: Fix these.  http://anglebug.com/3129
        ANGLE_SKIP_TEST_IF(IsD3D9() && draw == Indexed && geometry == Point);
        ANGLE_SKIP_TEST_IF(IsD3D9() && IsAMD());

        // D3D11 FL9_3 has a special codepath that emulates instanced points rendering
        // but it has bugs and was only implemented for vertex positions in a buffer object,
        // not client memory as used in this test.
        ANGLE_SKIP_TEST_IF(IsD3D11_FL93() && geometry == Point);

        // Unknown problem.  FL9_3 is not officially supported anyway.
        ANGLE_SKIP_TEST_IF(IsD3D11_FL93() && geometry == Quad && draw == NonIndexed);

        // The window is divided into kMaxDrawn slices of size kDrawSize.
        // The slice drawn into is determined by the instance datum.
        // The instance data array selects all the slices in order.
        // 'lastDrawn' is the index (zero-based) of the last slice into which we draw.
        const unsigned lastDrawn = (numInstance - 1) / divisor;

        // Ensure the numInstance and divisor parameters are valid.
        ASSERT_TRUE(lastDrawn < kMaxDrawn);

        ASSERT_TRUE(instanceAttrib == 0 || instanceAttrib == 1);
        const int positionAttrib = 1 - instanceAttrib;

        glUseProgram(mProgram[instanceAttrib]);

        glBindBuffer(GL_ARRAY_BUFFER, storage == Buffer ? mInstanceBuffer : 0);
        glVertexAttribPointer(instanceAttrib, 1, GL_FLOAT, GL_FALSE, 0,
                              storage == Buffer ? nullptr : mInstanceData);
        glEnableVertexAttribArray(instanceAttrib);
        if (vendor == Angle)
            glVertexAttribDivisorANGLE(instanceAttrib, divisor);
        else if (vendor == Ext)
            glVertexAttribDivisorEXT(instanceAttrib, divisor);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 0,
                              geometry == Point ? kPointVertices : kQuadVertices);
        glEnableVertexAttribArray(positionAttrib);
        if (vendor == Angle)
            glVertexAttribDivisorANGLE(positionAttrib, 0);
        else if (vendor == Ext)
            glVertexAttribDivisorEXT(positionAttrib, 0);

        glClear(GL_COLOR_BUFFER_BIT);

        if (geometry == Point)
        {
            if (draw == Indexed)
                if (vendor == Angle)
                    glDrawElementsInstancedANGLE(GL_POINTS, ArraySize(kPointIndices),
                                                 GL_UNSIGNED_SHORT, kPointIndices, numInstance);
                else
                    glDrawElementsInstancedEXT(GL_POINTS, ArraySize(kPointIndices),
                                               GL_UNSIGNED_SHORT, kPointIndices, numInstance);
            else if (vendor == Angle)
                glDrawArraysInstancedANGLE(GL_POINTS, offset, 4 /*vertices*/, numInstance);
            else
                glDrawArraysInstancedEXT(GL_POINTS, offset, 4 /*vertices*/, numInstance);
        }
        else
        {
            if (draw == Indexed)
                if (vendor == Angle)
                    glDrawElementsInstancedANGLE(GL_TRIANGLES, ArraySize(kQuadIndices),
                                                 GL_UNSIGNED_SHORT, kQuadIndices, numInstance);
                else
                    glDrawElementsInstancedEXT(GL_TRIANGLES, ArraySize(kQuadIndices),
                                               GL_UNSIGNED_SHORT, kQuadIndices, numInstance);
            else if (vendor == Angle)
                glDrawArraysInstancedANGLE(GL_TRIANGLES, offset, 6 /*vertices*/, numInstance);
            else
                glDrawArraysInstancedEXT(GL_TRIANGLES, offset, 6 /*vertices*/, numInstance);
        }

        ASSERT_GL_NO_ERROR();
        checkDrawing(lastDrawn);
    }

    void checkDrawing(unsigned lastDrawn)
    {
        for (unsigned i = 0; i < kMaxDrawn; ++i)
        {
            float y =
                -1.0f + static_cast<float>(kDrawSize) / 2.0f + static_cast<float>(i * kDrawSize);
            int iy = static_cast<int>((y + 1.0f) / 2.0f * getWindowHeight());
            for (unsigned j = 0; j < 8; j += 2)
            {
                int ix = static_cast<int>((kPointVertices[j] + 1.0f) / 2.0f * getWindowWidth());
                EXPECT_PIXEL_COLOR_EQ(ix, iy, i <= lastDrawn ? GLColor::red : GLColor::blue)
                    << std::endl;
            }
        }
    }

    GLuint mProgram[2];
    GLuint mInstanceBuffer;

    static constexpr unsigned kMaxDrawn = 16;
    static constexpr float kDrawSize    = 2.0 / kMaxDrawn;
    GLfloat mInstanceData[kMaxDrawn];

    // clang-format off

    // Vertices 0-5 are two triangles that form a quad filling the first "slice" of the window.
    // See above about slices.  Vertices 4-9 are the same two triangles.
    static constexpr GLfloat kQuadVertices[] = {
        -1, -1,
         1, -1,
        -1, -1 + kDrawSize,
         1, -1,
         1, -1 + kDrawSize,
        -1, -1 + kDrawSize,
         1, -1,
         1, -1,
        -1, -1 + kDrawSize,
        -1, -1,
    };

    // Points 0-3 are spread across the first "slice."
    // Points 2-4 are the same.
    static constexpr GLfloat kPointVertices[] = {
        -0.6f, -1 + kDrawSize / 2.0,
        -0.2f, -1 + kDrawSize / 2.0,
         0.2f, -1 + kDrawSize / 2.0,
         0.6f, -1 + kDrawSize / 2.0,
        -0.2f, -1 + kDrawSize / 2.0,
        -0.6f, -1 + kDrawSize / 2.0,
    };
    // clang-format on

    // Same two triangles as described above.
    static constexpr GLushort kQuadIndices[] = {2, 9, 7, 5, 6, 4};

    // Same four points as described above.
    static constexpr GLushort kPointIndices[] = {1, 5, 3, 2};
};

constexpr unsigned InstancingTest::kMaxDrawn;
constexpr float InstancingTest::kDrawSize;
constexpr GLfloat InstancingTest::kQuadVertices[];
constexpr GLfloat InstancingTest::kPointVertices[];
constexpr GLushort InstancingTest::kQuadIndices[];
constexpr GLushort InstancingTest::kPointIndices[];

#define TEST_INDEXED(attrib, geometry, storage, vendor)                      \
    TEST_P(InstancingTest, IndexedAttrib##attrib##geometry##storage##vendor) \
    {                                                                        \
        runTest(11, 2, attrib, geometry, Indexed, storage, vendor, 0);       \
    }

#define TEST_NONINDEXED(attrib, geometry, storage, vendor, offset)                              \
    TEST_P(InstancingTest, NonIndexedAttrib##attrib##geometry##storage##vendor##Offset##offset) \
    {                                                                                           \
        runTest(11, 2, attrib, geometry, NonIndexed, storage, vendor, offset);                  \
    }

#define TEST_DIVISOR(numInstance, divisor)                                    \
    TEST_P(InstancingTest, Instances##numInstance##Divisor##divisor)          \
    {                                                                         \
        runTest(numInstance, divisor, 1, Quad, NonIndexed, Buffer, Angle, 0); \
    }

// D3D9 and D3D11 FL9_3, have a special codepath that rearranges the input layout sent to D3D,
// to ensure that slot/stream zero of the input layout doesn't contain per-instance data, so
// we test with attribute 0 being instanced, as will as attribute 1 being instanced.
//
// Tests with a non-zero 'offset' check that "first" parameter to glDrawArraysInstancedANGLE is only
// an offset into the non-instanced vertex attributes.
TEST_INDEXED(0, Quad, Buffer, Angle)
TEST_INDEXED(0, Quad, Memory, Angle)
TEST_INDEXED(1, Quad, Buffer, Angle)
TEST_INDEXED(1, Quad, Memory, Angle)
TEST_INDEXED(0, Point, Buffer, Angle)
TEST_INDEXED(0, Point, Memory, Angle)
TEST_INDEXED(1, Point, Buffer, Angle)
TEST_INDEXED(1, Point, Memory, Angle)
TEST_INDEXED(0, Quad, Buffer, Ext)
TEST_INDEXED(0, Quad, Memory, Ext)
TEST_INDEXED(1, Quad, Buffer, Ext)
TEST_INDEXED(1, Quad, Memory, Ext)
TEST_INDEXED(0, Point, Buffer, Ext)
TEST_INDEXED(0, Point, Memory, Ext)
TEST_INDEXED(1, Point, Buffer, Ext)
TEST_INDEXED(1, Point, Memory, Ext)

// offset should be 0 or 4 for quads
TEST_NONINDEXED(0, Quad, Buffer, Angle, 0)
TEST_NONINDEXED(0, Quad, Buffer, Angle, 4)
TEST_NONINDEXED(0, Quad, Memory, Angle, 0)
TEST_NONINDEXED(0, Quad, Memory, Angle, 4)
TEST_NONINDEXED(1, Quad, Buffer, Angle, 0)
TEST_NONINDEXED(1, Quad, Buffer, Angle, 4)
TEST_NONINDEXED(1, Quad, Memory, Angle, 0)
TEST_NONINDEXED(1, Quad, Memory, Angle, 4)
TEST_NONINDEXED(0, Quad, Buffer, Ext, 0)
TEST_NONINDEXED(0, Quad, Buffer, Ext, 4)
TEST_NONINDEXED(0, Quad, Memory, Ext, 0)
TEST_NONINDEXED(0, Quad, Memory, Ext, 4)
TEST_NONINDEXED(1, Quad, Buffer, Ext, 0)
TEST_NONINDEXED(1, Quad, Buffer, Ext, 4)
TEST_NONINDEXED(1, Quad, Memory, Ext, 0)
TEST_NONINDEXED(1, Quad, Memory, Ext, 4)

// offset should be 0 or 2 for points
TEST_NONINDEXED(0, Point, Buffer, Angle, 0)
TEST_NONINDEXED(0, Point, Buffer, Angle, 2)
TEST_NONINDEXED(0, Point, Memory, Angle, 0)
TEST_NONINDEXED(0, Point, Memory, Angle, 2)
TEST_NONINDEXED(1, Point, Buffer, Angle, 0)
TEST_NONINDEXED(1, Point, Buffer, Angle, 2)
TEST_NONINDEXED(1, Point, Memory, Angle, 0)
TEST_NONINDEXED(1, Point, Memory, Angle, 2)
TEST_NONINDEXED(0, Point, Buffer, Ext, 0)
TEST_NONINDEXED(0, Point, Buffer, Ext, 2)
TEST_NONINDEXED(0, Point, Memory, Ext, 0)
TEST_NONINDEXED(0, Point, Memory, Ext, 2)
TEST_NONINDEXED(1, Point, Buffer, Ext, 0)
TEST_NONINDEXED(1, Point, Buffer, Ext, 2)
TEST_NONINDEXED(1, Point, Memory, Ext, 0)
TEST_NONINDEXED(1, Point, Memory, Ext, 2)

// The following tests produce each value of 'lastDrawn' in runTest() from 1 to kMaxDrawn, a few
// different ways.
TEST_DIVISOR(1, 1)
TEST_DIVISOR(1, 2)
TEST_DIVISOR(2, 1)
TEST_DIVISOR(3, 1)
TEST_DIVISOR(3, 2)
TEST_DIVISOR(4, 1)
TEST_DIVISOR(5, 1)
TEST_DIVISOR(5, 2)
TEST_DIVISOR(6, 1)
TEST_DIVISOR(6, 2)
TEST_DIVISOR(7, 1)
TEST_DIVISOR(7, 2)
TEST_DIVISOR(8, 1)
TEST_DIVISOR(8, 2)
TEST_DIVISOR(8, 4)
TEST_DIVISOR(9, 1)
TEST_DIVISOR(9, 2)
TEST_DIVISOR(10, 1)
TEST_DIVISOR(11, 1)
TEST_DIVISOR(11, 2)
TEST_DIVISOR(12, 1)
TEST_DIVISOR(12, 11)
TEST_DIVISOR(13, 1)
TEST_DIVISOR(13, 2)
TEST_DIVISOR(14, 1)
TEST_DIVISOR(15, 1)
TEST_DIVISOR(15, 2)
TEST_DIVISOR(16, 1)
TEST_DIVISOR(16, 3)
TEST_DIVISOR(16, 7)
TEST_DIVISOR(17, 2)
TEST_DIVISOR(20, 2)
TEST_DIVISOR(21, 2)
TEST_DIVISOR(23, 2)
TEST_DIVISOR(25, 5)
TEST_DIVISOR(25, 33)
TEST_DIVISOR(26, 2)
TEST_DIVISOR(26, 3)
TEST_DIVISOR(27, 2)
TEST_DIVISOR(27, 4)
TEST_DIVISOR(28, 3)
TEST_DIVISOR(29, 2)
TEST_DIVISOR(29, 11)
TEST_DIVISOR(30, 4)
TEST_DIVISOR(31, 6)
TEST_DIVISOR(32, 2)
TEST_DIVISOR(32, 3)
TEST_DIVISOR(32, 8)
TEST_DIVISOR(34, 3)
TEST_DIVISOR(34, 30)

class InstancingTestES3 : public InstancingTest
{
  public:
    InstancingTestES3() {}
};

class InstancingTestES31 : public InstancingTest
{
  public:
    InstancingTestES31() {}
};

// Verify that VertexAttribDivisor can update both binding divisor and attribBinding.
TEST_P(InstancingTestES31, UpdateAttribBindingByVertexAttribDivisor)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_instanced_arrays"));

    glUseProgram(mProgram[0]);

    // Get the attribute locations
    GLint positionLoc    = glGetAttribLocation(mProgram[0], "a_position");
    GLint instancePosLoc = glGetAttribLocation(mProgram[0], "a_instance");
    ASSERT_NE(-1, positionLoc);
    ASSERT_NE(-1, instancePosLoc);
    ASSERT_GL_NO_ERROR();

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    GLBuffer quadBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, quadBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW);

    const unsigned numInstance = 4;
    const unsigned divisor     = 1;
    const unsigned lastDrawn   = (numInstance - 1) / divisor;

    // Ensure the numInstance and divisor parameters are valid.
    ASSERT_TRUE(lastDrawn < kMaxDrawn);

    // Set the formats by VertexAttribFormat
    glVertexAttribFormat(positionLoc, 2, GL_FLOAT, GL_FALSE, 0);
    glVertexAttribFormat(instancePosLoc, 1, GL_FLOAT, GL_FALSE, 0);
    glEnableVertexAttribArray(positionLoc);
    glEnableVertexAttribArray(instancePosLoc);

    const GLint positionBinding = instancePosLoc;
    const GLint instanceBinding = positionLoc;

    // Load the vertex position into the binding indexed positionBinding (== instancePosLoc)
    // Load the instance position into the binding indexed instanceBinding (== positionLoc)
    glBindVertexBuffer(positionBinding, quadBuffer, 0, 2 * sizeof(kQuadVertices[0]));
    glBindVertexBuffer(instanceBinding, mInstanceBuffer, 0, sizeof(mInstanceData[0]));

    // The attribute indexed positionLoc is using the binding indexed positionBinding
    // The attribute indexed instancePosLoc is using the binding indexed instanceBinding
    glVertexAttribBinding(positionLoc, positionBinding);
    glVertexAttribBinding(instancePosLoc, instanceBinding);

    // Enable instancing on the binding indexed instanceBinding
    glVertexBindingDivisor(instanceBinding, divisor);

    // Do the first instanced draw
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawElementsInstanced(GL_TRIANGLES, ArraySize(kQuadIndices), GL_UNSIGNED_SHORT, kQuadIndices,
                            numInstance);
    checkDrawing(lastDrawn);

    // Disable instancing.
    glVertexBindingDivisor(instanceBinding, 0);

    // Load the vertex position into the binding indexed positionLoc.
    // Load the instance position into the binding indexed instancePosLoc.
    glBindVertexBuffer(positionLoc, quadBuffer, 0, 2 * sizeof(kQuadVertices[0]));
    glBindVertexBuffer(instancePosLoc, mInstanceBuffer, 0, sizeof(mInstanceData[0]));

    // The attribute indexed positionLoc is using the binding indexed positionLoc.
    glVertexAttribBinding(positionLoc, positionLoc);

    // Call VertexAttribDivisor to both enable instancing on instancePosLoc and set the attribute
    // indexed instancePosLoc using the binding indexed instancePosLoc.
    glVertexAttribDivisor(instancePosLoc, divisor);

    // Do the second instanced draw
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawElementsInstanced(GL_TRIANGLES, ArraySize(kQuadIndices), GL_UNSIGNED_SHORT, kQuadIndices,
                            numInstance);
    checkDrawing(lastDrawn);

    glDeleteVertexArrays(1, &vao);
}

// Verify that a large divisor that also changes doesn't cause issues and renders correctly.
TEST_P(InstancingTestES3, LargeDivisor)
{
    // http://anglebug.com/4092
    ANGLE_SKIP_TEST_IF(isSwiftshader());
    constexpr char kVS[] = R"(#version 300 es
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec4 a_color;
out vec4 v_color;
void main()
{
    gl_Position = a_position;
    gl_PointSize = 4.0f;
    v_color = a_color;
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
in vec4 v_color;
out vec4 my_FragColor;
void main()
{
    my_FragColor = v_color;
})";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);

    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);

    GLBuffer buf;
    glBindBuffer(GL_ARRAY_BUFFER, buf);
    std::vector<GLfloat> vertices;
    for (size_t i = 0u; i < 4u; ++i)
    {
        vertices.push_back(0.0f + i * 0.25f);
        vertices.push_back(0.0f);
        vertices.push_back(0.0f);
        vertices.push_back(1.0f);
    }
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * 4u, vertices.data(), GL_DYNAMIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, nullptr);
    ASSERT_GL_NO_ERROR();

    GLBuffer colorBuf;
    glBindBuffer(GL_ARRAY_BUFFER, colorBuf);

    std::array<GLColor, 4> ubyteColors = {GLColor::red, GLColor::green};
    std::vector<float> floatColors;
    for (const GLColor &color : ubyteColors)
    {
        floatColors.push_back(color.R / 255.0f);
        floatColors.push_back(color.G / 255.0f);
        floatColors.push_back(color.B / 255.0f);
        floatColors.push_back(color.A / 255.0f);
    }
    glBufferData(GL_ARRAY_BUFFER, floatColors.size() * 4u, floatColors.data(), GL_DYNAMIC_DRAW);

    const GLuint kColorDivisor = 65536u * 2u;
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, nullptr);
    glVertexAttribDivisor(1, kColorDivisor);

    std::array<GLuint, 1u> indices       = {0u};
    std::array<GLuint, 3u> divisorsToTry = {256u, 65536u, 65536u * 2u};

    for (GLuint divisorToTry : divisorsToTry)
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glVertexAttribDivisor(0, divisorToTry);

        GLuint instanceCount        = divisorToTry + 1u;
        unsigned int pointsRendered = (instanceCount - 1u) / divisorToTry + 1u;

        glDrawElementsInstanced(GL_POINTS, indices.size(), GL_UNSIGNED_INT, indices.data(),
                                instanceCount);
        ASSERT_GL_NO_ERROR();

        // Check that the intended number of points has been rendered.
        for (unsigned int pointIndex = 0u; pointIndex < pointsRendered + 1u; ++pointIndex)
        {
            GLint pointx = static_cast<GLint>((pointIndex * 0.125f + 0.5f) * getWindowWidth());
            GLint pointy = static_cast<GLint>(0.5f * getWindowHeight());

            if (pointIndex < pointsRendered)
            {
                GLuint pointColorIndex = (pointIndex * divisorToTry) / kColorDivisor;
                EXPECT_PIXEL_COLOR_EQ(pointx, pointy, ubyteColors[pointColorIndex]);
            }
            else
            {
                // Clear color.
                EXPECT_PIXEL_COLOR_EQ(pointx, pointy, GLColor::blue);
            }
        }
    }
}

// This is a regression test. If VertexAttribDivisor was returned as a signed integer, it would be
// incorrectly clamped down to the maximum signed integer.
TEST_P(InstancingTestES3, LargestDivisor)
{
    // http://anglebug.com/4092
    ANGLE_SKIP_TEST_IF(isSwiftshader());
    constexpr GLuint kLargeDivisor = std::numeric_limits<GLuint>::max();
    glVertexAttribDivisor(0, kLargeDivisor);

    GLuint divisor = 0;
    glGetVertexAttribIuiv(0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &divisor);
    EXPECT_EQ(kLargeDivisor, divisor)
        << "Vertex attrib divisor read was not the same that was passed in.";
}

ANGLE_INSTANTIATE_TEST_ES3(InstancingTestES3);

ANGLE_INSTANTIATE_TEST_ES31(InstancingTestES31);

ANGLE_INSTANTIATE_TEST_ES2(InstancingTest);
