/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * 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.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

#include "es31cDrawIndirectTests.hpp"
#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "tcuMatrix.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuVectorUtil.hpp"

#include <map>

namespace glcts
{
using namespace glw;
namespace
{

class DILogger
{
public:
    DILogger() : null_log_(0)
    {
    }

    DILogger(const DILogger &rhs)
    {
        null_log_ = rhs.null_log_;
        if (!null_log_)
        {
            str_ << rhs.str_.str();
        }
    }

    ~DILogger()
    {
        s_tcuLog->writeMessage(str_.str().c_str());
        if (!str_.str().empty())
        {
            s_tcuLog->writeMessage(NL);
        }
    }

    template <class T>
    DILogger &operator<<(const T &t)
    {
        if (!null_log_)
        {
            str_ << t;
        }
        return *this;
    }

    DILogger &nullify()
    {
        null_log_ = true;
        return *this;
    }

    static void setOutput(tcu::TestLog &log)
    {
        s_tcuLog = &log;
    }

private:
    void operator=(const DILogger &);
    bool null_log_;
    std::ostringstream str_;
    static tcu::TestLog *s_tcuLog;
};
tcu::TestLog *DILogger::s_tcuLog = NULL;

class DIResult
{
public:
    DIResult() : status_(NO_ERROR)
    {
    }

    DILogger error()
    {
        return sub_result(ERROR);
    }
    long code() const
    {
        return status_;
    }
    DILogger sub_result(long _code)
    {
        if (_code == NO_ERROR)
        {
            return sub_result_inner(_code).nullify();
        }
        else
        {
            return sub_result_inner(_code);
        }
    }

private:
    DILogger sub_result_inner(long _code)
    {
        status_ |= _code;
        return DILogger();
    }
    DILogger logger_;
    long status_;
};

namespace test_api
{
struct ES3
{
    static bool isES()
    {
        return true;
    }
    static std::string glslVer(bool = false)
    {
        return "#version 310 es";
    }
    static void ES_Only()
    {
    }
};

struct GL
{
    static bool isES()
    {
        return false;
    }
    static std::string glslVer(bool compute = false)
    {
        if (compute)
        {
            return "#version 430";
        }
        else
        {
            return "#version 400";
        }
    }
    static void GL_Only()
    {
    }
};
} // namespace test_api

namespace shaders
{

template <typename api>
std::string vshSimple()
{
    return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL "    gl_Position = i_vertex;" NL "}";
}
template <typename api>
std::string vshSimple_point()
{
    return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL "    gl_Position = i_vertex;" NL
                               "#if defined(GL_ES)" NL "    gl_PointSize = 1.0;" NL "#endif" NL "}";
}

template <typename api>
std::string fshSimple()
{
    return api::glslVer() + NL "precision highp float; " NL "out vec4 outColor;" NL "void main() {" NL
                               "  outColor = vec4(0.1,0.2,0.3,1.0);" NL "}";
}
} // namespace shaders

class DrawIndirectBase : public glcts::SubcaseBase
{
protected:
    typedef std::vector<unsigned int> CDataArray;
    typedef std::vector<tcu::Vec3> CVertexArray;
    typedef std::vector<tcu::Vec4> CColorArray;
    typedef std::vector<GLuint> CElementArray;

    enum TDrawFunction
    {
        DRAW_ARRAYS,
        DRAW_ELEMENTS,
    };

    typedef struct
    {
        GLuint count;
        GLuint primCount;
        GLuint first;
        GLuint reservedMustBeZero;
    } DrawArraysIndirectCommand;

    typedef struct
    {
        GLuint count;
        GLuint primCount;
        GLuint firstIndex;
        GLint baseVertex;
        GLuint reservedMustBeZero;
    } DrawElementsIndirectCommand;

    int getWindowWidth()
    {
        return m_context.getRenderContext().getRenderTarget().getWidth();
    }

    int getWindowHeight()
    {
        return m_context.getRenderContext().getRenderTarget().getHeight();
    }

    void getDataSize(int &width, int &height)
    {
        width  = std::min(getWindowWidth(), 16384);              // Cap width to 16384
        height = std::min(getWindowHeight(), 4 * 16384 / width); // Height is 4 if width is capped
    }

    GLuint CreateComputeProgram(const std::string &cs, bool linkAndCheck)
    {
        const GLuint p = glCreateProgram();

        const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
        glAttachShader(p, sh);
        glDeleteShader(sh);
        const char *const src[1] = {cs.c_str()};
        glShaderSource(sh, 1, src, NULL);
        glCompileShader(sh);

        if (linkAndCheck)
        {
            glLinkProgram(p);
            if (!CheckProgram(p))
            {
                return 0;
            }
        }

        return p;
    }

    GLuint CreateProgram(const std::string &vs, const std::string &gs, const std::string &fs, bool linkAndCheck)
    {
        const GLuint p = glCreateProgram();

        if (!vs.empty())
        {
            const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
            glAttachShader(p, sh);
            glDeleteShader(sh);
            const char *const src[1] = {vs.c_str()};
            glShaderSource(sh, 1, src, NULL);
            glCompileShader(sh);
        }
        if (!gs.empty())
        {
            const GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
            glAttachShader(p, sh);
            glDeleteShader(sh);
            const char *const src[1] = {gs.c_str()};
            glShaderSource(sh, 1, src, NULL);
            glCompileShader(sh);
        }
        if (!fs.empty())
        {
            const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
            glAttachShader(p, sh);
            glDeleteShader(sh);
            const char *const src[1] = {fs.c_str()};
            glShaderSource(sh, 1, src, NULL);
            glCompileShader(sh);
        }

        if (linkAndCheck)
        {
            glLinkProgram(p);
            if (!CheckProgram(p))
            {
                return 0;
            }
        }

        return p;
    }

    long CheckProgram(GLuint program)
    {
        DIResult status;
        GLint progStatus;
        glGetProgramiv(program, GL_LINK_STATUS, &progStatus);

        if (progStatus == GL_FALSE)
        {

            status.error() << "GL_LINK_STATUS is false";

            GLint attached_shaders;
            glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);

            if (attached_shaders > 0)
            {
                std::vector<GLuint> shaders(attached_shaders);
                glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);

                for (GLint i = 0; i < attached_shaders; ++i)
                {
                    // shader type
                    GLenum type;
                    glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));
                    switch (type)
                    {
                    case GL_VERTEX_SHADER:
                        status.error() << "*** Vertex Shader ***\n";
                        break;
                    case GL_FRAGMENT_SHADER:
                        status.error() << "*** Fragment Shader ***\n";
                        break;
                    case GL_COMPUTE_SHADER:
                        status.error() << "*** Compute Shader ***\n";
                        break;
                    default:
                        status.error() << "*** Unknown Shader ***\n";
                        break;
                    }

                    // shader source
                    GLint length;
                    glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
                    if (length > 0)
                    {
                        std::vector<GLchar> source(length);
                        glGetShaderSource(shaders[i], length, NULL, &source[0]);
                        status.error() << source[0];
                    }

                    // shader info log
                    glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
                    if (length > 0)
                    {
                        std::vector<GLchar> log(length);
                        glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
                        status.error() << &log[0];
                    }
                }
            }

            // program info log
            GLint length;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
            if (length > 0)
            {
                std::vector<GLchar> log(length);
                glGetProgramInfoLog(program, length, NULL, &log[0]);
                status.error() << &log[0];
            }
        }

        return status.code() == NO_ERROR;
    }

    template <typename api>
    void ReadPixelsFloat(int x, int y, int width, int height, void *data);

    template <typename api>
    void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);

    template <typename T>
    void DataGen(std::vector<T> &data, unsigned int sizeX, unsigned int sizeY, T valueMin, T valueMax)
    {
        data.resize(sizeX * sizeY, 0);
        T range = valueMax - valueMin;
        T stepX = range / sizeX;
        T stepY = range / sizeY;

        for (unsigned int i = 0; i < sizeY; ++i)
        {
            T valueY = i * stepY;

            for (unsigned int j = 0; j < sizeX; ++j)
            {
                data[j + i * sizeX] = valueMin + j * stepX + valueY;
            }
        }
    }

    template <typename T>
    long DataCompare(const std::vector<T> &dataRef, unsigned int widthRef, unsigned int heightRef,
                     const std::vector<T> &dataTest, unsigned int widthTest, unsigned int heightTest,
                     unsigned offsetYRef = 0, unsigned offsetYTest = 0)
    {
        if (widthRef * heightRef > dataRef.size())
            throw std::runtime_error("Invalid reference buffer resolution!");

        if (widthTest * heightTest > dataTest.size())
            throw std::runtime_error("Invalid test buffer resolution!");

        unsigned int width  = std::min(widthRef, widthTest);
        unsigned int height = std::min(heightRef, heightTest);

        for (unsigned int i = 0; i < height; ++i)
        {
            unsigned int offsetRef  = (i + offsetYRef) * widthRef;
            unsigned int offsetTest = (i + offsetYTest) * widthTest;

            for (size_t j = 0; j < width; ++j)
            {
                if (dataRef[offsetRef + j] != dataTest[offsetTest + j])
                {
                    DIResult status;
                    status.error() << "Compare failed: different values [x: " << j << ", y: " << i + offsetYTest
                                   << ", reference: " << dataRef[offsetRef + j]
                                   << ", test: " << dataTest[offsetTest + j] << "]";
                    return status.code();
                }
            }
        }

        return NO_ERROR;
    }

    template <typename api>
    long BindingPointCheck(GLuint expectedValue)
    {
        DIResult status;

        GLint valueInt = -9999;
        glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueInt);
        if (valueInt != static_cast<GLint>(expectedValue))
        {
            status.error() << "glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueInt
                           << ", expected: " << expectedValue;
        }

        GLboolean valueBool = expectedValue ? GL_FALSE : GL_TRUE;
        glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueBool);
        if (valueBool != (expectedValue ? GL_TRUE : GL_FALSE))
        {
            status.error() << "glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: "
                           << BoolToString(valueBool)
                           << ", expected: " << BoolToString(expectedValue ? GL_TRUE : GL_FALSE);
        }

        GLfloat valueFloat         = -9999;
        GLfloat expectedFloatValue = static_cast<GLfloat>(expectedValue);
        glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueFloat);
        if (valueFloat != expectedFloatValue)
        {
            status.error() << "glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueFloat
                           << ", expected: " << expectedValue;
        }

        if (!api::isES())
        {
            GLdouble valueDouble = -9999;
            glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueDouble);
            if (valueDouble != static_cast<GLdouble>(expectedValue))
            {
                status.error() << "glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: "
                               << valueDouble << ", expected: " << expectedValue;
            }
        }

        return status.code();
    }

    template <typename T>
    long BuffersCompare(const std::vector<T> &bufferTest, unsigned int widthTest, unsigned int heightTest,
                        const std::vector<T> &bufferRef, unsigned int widthRef, unsigned int heightRef)
    {

        const tcu::PixelFormat &pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat();
        tcu::Vec4 epsilon                   = tcu::Vec4(
            1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
            1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));

        double stepX = widthRef / static_cast<double>(widthTest);
        double stepY = heightRef / static_cast<double>(heightTest);
        for (unsigned int i = 0; i < heightTest; ++i)
        {
            unsigned int offsetTest = i * widthTest;
            unsigned int offsetRef  = static_cast<int>(i * stepY + 0.5) * widthRef;
            for (unsigned int j = 0; j < widthTest; ++j)
            {
                unsigned int posXRef = static_cast<int>(j * stepX + 0.5);
                if (!ColorVerify(bufferTest[j + offsetTest], bufferRef[posXRef + offsetRef], epsilon))
                {
                    DIResult status;
                    status.error() << "(x,y)= (" << j << "," << i << "). Color RGBA(" << bufferTest[j + offsetTest][0]
                                   << "," << bufferTest[j + offsetTest][1] << "," << bufferTest[j + offsetTest][2]
                                   << "," << bufferTest[j + offsetTest][3] << ") is different than expected RGBA("
                                   << bufferRef[posXRef + offsetRef][0] << "," << bufferRef[posXRef + offsetRef][1]
                                   << "," << bufferRef[posXRef + offsetRef][2] << ","
                                   << bufferRef[posXRef + offsetRef][3] << ")";
                    return status.code();
                }
            }
        }
        return NO_ERROR;
    }

    template <typename T>
    bool ColorVerify(T color, T colorExpected, tcu::Vec4 epsilon)
    {
        for (int i = 0; i < 3; ++i)
        {
            if (fabsf(colorExpected[i] - color[i]) > epsilon[i])
                return false;
        }
        return true;
    }

    long BufferCheck(const CDataArray &dataRef, unsigned int widthRef, unsigned int heightRef, const void *bufTest,
                     unsigned int widthTest, unsigned int heightTest, unsigned int offsetYRef = 0,
                     unsigned int offsetYTest = 0)
    {
        if (bufTest == 0)
        {
            throw std::runtime_error("Invalid test buffer!");
        }

        CDataArray dataTest(widthTest * heightTest, 0);
        memcpy(&dataTest[0], bufTest, widthTest * heightTest * sizeof(unsigned int));

        return DataCompare(dataRef, widthRef, heightRef, dataTest, widthTest, heightTest, offsetYRef, offsetYTest);
    }

    template <typename api>
    long StateValidate(GLboolean mapped, GLbitfield access, GLbitfield accessFlag, GLintptr offset, GLsizeiptr length)
    {
        DIResult result;

        if (!api::isES())
        {
            int v;
            glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS, &v);
            if (v != static_cast<int>(access))
            {
                result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS) returned incorrect state: "
                               << AccessToString(v) << ", expected: " << AccessToString(access);
            }
        }

        int v;
        glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS_FLAGS, &v);
        if (v != static_cast<int>(accessFlag))
        {
            result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS) returned incorrect state: " << v
                           << ", expected: " << accessFlag;
        }

        glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAPPED, &v);
        if (v != mapped)
        {
            result.error() << "glGetBufferParameteriv(GL_BUFFER_MAPPED) returned incorrect state: "
                           << BoolToString((GLboolean)v) << ", expected: " << BoolToString((GLboolean)access);
        }

        glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_OFFSET, &v);
        if (v != offset)
        {
            result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_OFFSET) returned incorrect offset: " << v
                           << ", expected: " << offset;
        }

        glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_LENGTH, &v);
        if (v != length)
        {
            result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_LENGTH) returned incorrect length: " << v
                           << ", expected: " << length;
        }

        return result.code();
    }

    void PointsGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
    {
        output.reserve(drawSizeY * 2);
        float rasterSizeX = 2.0f / static_cast<float>(getWindowWidth());
        float rasterSizeY = 2.0f / static_cast<float>(getWindowHeight());
        for (unsigned int i = 0; i < drawSizeY; ++i)
        {
            float offsetY = -1.0f + rasterSizeY * static_cast<float>(i) + rasterSizeY / 2;
            for (unsigned int j = 0; j < drawSizeX; ++j)
            {
                float offsetX = -1.0f + rasterSizeX * static_cast<float>(j) + rasterSizeX / 2;
                output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
            }
        }
    }

    float LinesOffsetY(unsigned int i, float rasterSize)
    {
        // Offset lines slightly from the center of pixels so as not to hit rasterizer
        // tie-break conditions (the right-edge of the screen at half-integer pixel
        // heights is the right corner of a diamond). rasterSize/16 is the smallest
        // offset that the spec guarantees the rasterizer can resolve.
        return -1.0f + rasterSize * static_cast<float>(i) + rasterSize / 2 + rasterSize / 16;
    }

    void LinesGen(unsigned int, unsigned int drawSizeY, CColorArray &output)
    {
        output.reserve(drawSizeY * 2);
        float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
        for (unsigned int i = 0; i < drawSizeY; ++i)
        {
            float offsetY = LinesOffsetY(i, rasterSize);
            output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
        }
    }

    void LinesAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray &output)
    {
        float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
        for (unsigned int i = 0; i < drawSizeY; ++i)
        {
            float offsetY = LinesOffsetY(i, rasterSize);
            output.push_back(tcu::Vec4(-1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj
            output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj
        }
    }

    void LineStripAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray &output)
    {
        float rasterSize = 2.0f / static_cast<float>(getWindowHeight());
        output.push_back(tcu::Vec4(-1.5f, rasterSize / 2, 0.0f, 1.0f));
        for (unsigned int i = 0; i < drawSizeY; ++i)
        {
            float offsetY = LinesOffsetY(i, rasterSize);
            output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f));
        }
        output.push_back(tcu::Vec4(1.5f, 1.0f - rasterSize / 2, 0.0f, 1.0f));
    }

    void TrianglesGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
    {
        output.reserve(drawSizeX * 2 * 6);

        switch (drawSizeX)
        {
        case 1:
        {
            output.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(4.0f, -1.0f, 0.0f, 1.0f));
            output.push_back(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f));
        }
        break;
        case 0:
        {
            throw std::runtime_error("Invalid drawSizeX!");
        }
        default:
        {
            float drawStepX = 2.0f / static_cast<float>(drawSizeX);
            float drawStepY = 2.0f / static_cast<float>(drawSizeY);

            for (unsigned int i = 0; i < drawSizeY; ++i)
            {
                float offsetY = -1.0f + drawStepY * static_cast<float>(i);
                for (unsigned int j = 0; j < drawSizeX; ++j)
                {
                    float offsetX = -1.0f + drawStepX * static_cast<float>(j);

                    output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
                    output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f));
                    output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f));

                    output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f));
                    output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY + drawStepY, 0.0f, 1.0f));
                    output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f));
                }
            }
        }
        break;
        }
    }

    void TrianglesAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
    {
        // Add a small amount (quarter pixel) of jitter to add to the rectangle sides to avoid
        // triangle edges landing precisely on fragment centers.
        float jigX = 0.5f / getWindowWidth();
        float jigY = 0.5f / getWindowHeight();

        float sizeX = 1.0f / static_cast<float>(drawSizeX);
        float sizeY = 1.0f / static_cast<float>(drawSizeY);

        for (unsigned int i = 0; i < drawSizeX; ++i)
        {
            float offsetY = -0.5f + jigY + sizeY * static_cast<float>(i);
            for (unsigned int j = 0; j < drawSizeY; ++j)
            {
                float offsetX = -0.5f + jigX + sizeX * static_cast<float>(j);

                output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f));

                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f));
            }
        }
    }

    void TriangleStripAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
    {
        // Add a small amount (quarter pixel) of jitter to add to the rectangle sides to avoid
        // triangle edges landing precisely on fragment centers.
        float jigX = 0.5f / getWindowWidth();
        float jigY = 0.5f / getWindowHeight();

        float sizeX = 1.0f / static_cast<float>(drawSizeX);
        float sizeY = 1.0f / static_cast<float>(drawSizeY);

        for (unsigned int i = 0; i < drawSizeX; ++i)
        {
            float offsetY = -0.5f + jigY + sizeY * static_cast<float>(i);
            for (unsigned int j = 0; j < drawSizeY; ++j)
            {
                float offsetX = -0.5f + jigX + sizeX * static_cast<float>(j);

                output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f));
                output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY - sizeY, 0.0f, 1.0f));
            }
        }
    }

    void PrimitiveGen(GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY, CColorArray &output)
    {
        switch (primitiveType)
        {
        case GL_POINTS:
            PointsGen(drawSizeX, drawSizeY, output);
            break;
        case GL_LINES:
        case GL_LINE_STRIP:
        case GL_LINE_LOOP:
            LinesGen(drawSizeX, drawSizeY, output);
            break;
        case GL_LINES_ADJACENCY:
            LinesAdjacencyGen(drawSizeX, drawSizeY, output);
            break;
        case GL_LINE_STRIP_ADJACENCY:
            LineStripAdjacencyGen(drawSizeX, drawSizeY, output);
            break;
        case GL_TRIANGLES:
        case GL_TRIANGLE_STRIP:
        case GL_TRIANGLE_FAN:
            TrianglesGen(drawSizeX, drawSizeY, output);
            break;
        case GL_TRIANGLES_ADJACENCY:
            TrianglesAdjacencyGen(drawSizeX, drawSizeY, output);
            break;
        case GL_TRIANGLE_STRIP_ADJACENCY:
            TriangleStripAdjacencyGen(drawSizeX, drawSizeY, output);
            break;
        default:
            throw std::runtime_error("Unknown primitive type!");
        }
    }

    std::string BoolToString(GLboolean value)
    {
        if (value == GL_TRUE)
            return "GL_TRUE";

        return "GL_FALSE";
    }

    std::string AccessToString(GLbitfield access)
    {
        switch (access)
        {
        case GL_READ_WRITE:
            return "GL_READ_WRITE";
        case GL_READ_ONLY:
            return "GL_READ_ONLY";
        case GL_WRITE_ONLY:
            return "GL_WRITE_ONLY";
        default:
            throw std::runtime_error("Invalid access type!");
        }
    }
};

template <>
void DrawIndirectBase::ReadPixelsFloat<test_api::GL>(int x, int y, int width, int height, void *data)
{
    glReadPixels(x, y, width, height, GL_RGBA, GL_FLOAT, data);
}

template <>
void DrawIndirectBase::ReadPixelsFloat<test_api::ES3>(int x, int y, int width, int height, void *data)
{
    // Use 1010102 pixel buffer for RGB10_A2 FBO to preserve precision during pixel transfer
    std::vector<GLuint> uData(width * height);
    const tcu::PixelFormat &pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat();
    GLfloat *fData                      = reinterpret_cast<GLfloat *>(data);
    GLenum type = ((pixelFormat.redBits == 10) && (pixelFormat.greenBits == 10) && (pixelFormat.blueBits == 10) &&
                   (pixelFormat.alphaBits == 2)) ?
                      GL_UNSIGNED_INT_2_10_10_10_REV :
                      GL_UNSIGNED_BYTE;

    glReadPixels(x, y, width, height, GL_RGBA, type, &uData[0]);

    if (type == GL_UNSIGNED_BYTE)
    {
        for (size_t i = 0; i < uData.size(); i++)
        {
            GLubyte *uCompData = reinterpret_cast<GLubyte *>(&uData[i]);

            for (size_t c = 0; c < 4; c++)
            {
                fData[i * 4 + c] = float(uCompData[c]) / 255.0f;
            }
        }
    }
    else
    {
        for (size_t i = 0; i < uData.size(); i++)
        {
            fData[i * 4]     = float(uData[i] & 0x3FF) / 1023.0f;
            fData[i * 4 + 1] = float((uData[i] >> 10) & 0x3FF) / 1023.0f;
            fData[i * 4 + 2] = float((uData[i] >> 20) & 0x3FF) / 1023.0f;
            fData[i * 4 + 3] = float((uData[i] >> 30) & 0x3) / 3.0f;
        }
    }
}

template <>
void DrawIndirectBase::GetBufferSubData<test_api::GL>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)
{
    glGetBufferSubData(target, offset, size, data);
}

template <>
void DrawIndirectBase::GetBufferSubData<test_api::ES3>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)
{
    void *ptr = glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
    memcpy(data, ptr, size);
    glUnmapBuffer(target);
}

template <typename api>
struct CDefaultBindingPoint : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Draw Indirect: Check default binding point";
    }

    virtual std::string Purpose()
    {
        return "Verify that default binding point is set to zero";
    }

    virtual std::string Method()
    {
        return "Use glGetIntegerv, glGetBooleanv, glGetFloatv, glGetDoublev to get default binding point";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if default binding point is zero";
    }

    virtual long Run()
    {
        return BindingPointCheck<api>(0);
    }
};

template <typename api>
struct CZeroBindingPoint : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Draw Indirect: Zero binding point";
    }

    virtual std::string Purpose()
    {
        return "Verify that binding point is set to zero";
    }

    virtual std::string Method()
    {
        return "Bind zero and check that binding point is set to zero";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if binding point is set to zero";
    }

    virtual long Run()
    {
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);

        return BindingPointCheck<api>(0);
    }
};

template <typename api>
struct CSingleBindingPoint : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Draw Indirect: Single binding point";
    }

    virtual std::string Purpose()
    {
        return "Verify that binding point is set to correct value";
    }

    virtual std::string Method()
    {
        return "Bind non-zero buffer and check that binding point is set to correct value";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if binding point is set to correct value";
    }

    virtual long Run()
    {
        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        long ret = BindingPointCheck<api>(_buffer);

        return ret;
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <typename api>
class CMultiBindingPoint : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Draw Indirect: Multi binding point";
    }

    virtual std::string Purpose()
    {
        return "Verify that binding points are set to correct value";
    }

    virtual std::string Method()
    {
        return "Bind in loop non-zero buffers and check that binding points are set to correct value";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if binding points are set to correct value";
    }

    virtual long Run()
    {
        DIResult result;

        const int buffNum = sizeof(_buffers) / sizeof(_buffers[0]);

        glGenBuffers(buffNum, _buffers);

        for (int i = 0; i < buffNum; ++i)
        {
            glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[i]);
            result.sub_result(BindingPointCheck<api>(_buffers[i]));
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffers[10];
};

template <typename api>
struct CDeleteBindingPoint : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Draw Indirect: Delete binding point";
    }

    virtual std::string Purpose()
    {
        return "Verify that after deleting buffer, binding point is set to correct value";
    }

    virtual std::string Method()
    {
        return "Bind non-zero buffer, delete buffer, check that binding point is set to 0";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if binding point is set to correct value";
    }

    virtual long Run()
    {
        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <typename api>
struct CBufferData : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glBufferData and GetBufferSubData<api>";
    }

    virtual std::string Purpose()
    {
        return "Verify that glBufferData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data using glBufferData" NL
               "4. Get data using GetBufferSubData<api>" NL "5. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);

        CDataArray dataTest(dataWidth * dataHeight, 0);

        glGenBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
        CDataArray dataRef1;
        DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 0, 50);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
                     GL_DYNAMIC_DRAW);
        result.sub_result(BindingPointCheck<api>(_buffers[1]));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        CDataArray dataRef2;
        DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 70);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[2]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
                     GL_STREAM_DRAW);
        result.sub_result(BindingPointCheck<api>(_buffers[2]));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[3]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, 300, NULL, GL_STATIC_DRAW);
        result.sub_result(BindingPointCheck<api>(_buffers[3]));

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[4]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, 400, NULL, GL_DYNAMIC_READ);
        result.sub_result(BindingPointCheck<api>(_buffers[4]));

        CDataArray dataRef5;
        DataGen<unsigned int>(dataRef5, dataWidth, dataHeight, 0, 50);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[5]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef5.size() * sizeof(unsigned int)), &dataRef5[0],
                     GL_STREAM_READ);
        result.sub_result(BindingPointCheck<api>(_buffers[5]));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef5, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        CDataArray dataRef6;
        DataGen<unsigned int>(dataRef6, dataWidth, dataHeight, 10, 40);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[6]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef6.size() * sizeof(unsigned int)), &dataRef6[0],
                     GL_STATIC_READ);
        result.sub_result(BindingPointCheck<api>(_buffers[6]));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef6, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        CDataArray dataRef7;
        DataGen<unsigned int>(dataRef7, dataWidth, dataHeight, 4, 70);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[7]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef7.size() * sizeof(unsigned int)), &dataRef7[0],
                     GL_DYNAMIC_COPY);
        result.sub_result(BindingPointCheck<api>(_buffers[7]));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef7, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[8]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, 800, NULL, GL_STREAM_COPY);
        result.sub_result(BindingPointCheck<api>(_buffers[8]));

        CDataArray dataRef9;
        DataGen<unsigned int>(dataRef9, dataWidth, dataHeight, 18, 35);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[9]);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
                     GL_STATIC_COPY);
        result.sub_result(BindingPointCheck<api>(_buffers[9]));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        //reallocation: same size
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
                     GL_STATIC_COPY);
        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        //reallocation: larger size
        DataGen<unsigned int>(dataRef9, dataWidth * 2, dataHeight * 2, 18, 35);
        dataTest.resize(dataRef9.size());
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
                     GL_STATIC_COPY);
        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(
            DataCompare(dataRef9, dataWidth * 2, dataHeight * 2, dataTest, dataWidth * 2, dataHeight * 2));

        //reallocation: smaller size
        DataGen<unsigned int>(dataRef9, dataWidth / 2, dataHeight / 2, 18, 35);
        dataTest.resize(dataRef9.size());
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0],
                     GL_STATIC_COPY);
        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(
            DataCompare(dataRef9, dataWidth / 2, dataHeight / 2, dataTest, dataWidth / 2, dataHeight / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffers[10];
};

template <typename api>
struct CBufferSubData : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check function: glBufferSubData and GetBufferSubData<api>";
    }

    virtual std::string Purpose()
    {
        return "Verify that glBufferSubData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Allocate buffer using glBufferData" NL
               "4. Set data using glBufferSubData" NL "5. Get data using GetBufferSubData<api>" NL "6. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        CDataArray dataRef;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 4, 70);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), NULL,
                     GL_DYNAMIC_DRAW);
        glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0]);

        CDataArray dataTest(dataWidth * dataHeight, 0);
        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);

        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        CDataArray dataSubRef;
        DataGen<unsigned int>(dataSubRef, dataWidth / 2, dataHeight / 2, 80, 90);
        glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 4, (GLsizeiptr)(dataSubRef.size() * sizeof(unsigned int)),
                        &dataSubRef[0]);
        std::copy(dataSubRef.begin(), dataSubRef.end(), dataRef.begin() + 1);

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <typename api>
struct CBufferMap : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glMapBuffer, glUnmapBuffer and getParameteriv";
    }

    virtual std::string Purpose()
    {
        return "Verify that glMapBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
               "5. Verify mapped buffer" NL "6. Check state" NL "7. Unmap buffer" NL "8. Check state";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        api::GL_Only();

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        CDataArray dataRef;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
                     GL_DYNAMIC_DRAW);

        result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));

        void *buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY);
        if (buf == 0)
        {
            result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY) returned NULL";
        }

        if (buf)
        {
            result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

            result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
                                                 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY);
        if (buf == 0)
        {
            result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY) returned NULL";
        }

        if (buf)
        {
            result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0,
                                                 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));
            memcpy(buf, &dataRef[0], dataRef.size() * sizeof(unsigned int));
            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE);
        if (buf == 0)
        {
            result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE) returned NULL";
        }

        if (buf)
        {
            result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

            result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_WRITE, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, 0,
                                                 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <typename api>
struct CBufferGetPointerv : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glBuffergetPointerv";
    }

    virtual std::string Purpose()
    {
        return "Verify that glBuffergetPointerv accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL
               "5. Get a pointer to buffer" NL "6. Compare pointers from point 4) and 5)" NL
               "7. Verify mapped buffer" NL "8. Unmap buffer";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        CDataArray dataRef;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
                     GL_DYNAMIC_DRAW);

        void *ptr = 0;
        glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);

        if (ptr != 0)
        {
            result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned invalid "
                              "pointer, expected: NULL";
        }

        void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
                                     GL_MAP_READ_BIT);
        if (buf == 0)
        {
            result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";

            return result.code();
        }

        glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr);

        if (ptr == 0)
        {
            result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned NULL";
        }

        if (ptr)
        {
            result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, ptr, dataWidth, dataHeight));
        }

        if (ptr != buf)
        {
            result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) different pointer "
                              "than glMapBuffer(GL_DRAW_INDIRECT_BUFFER)";
        }

        if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
        {
            result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
        }
        buf = 0;
        ptr = 0;

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <class api>
struct CBufferMapRange : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glMapRangeBuffer, glUnmapBuffer and getParameteriv";
    }

    virtual std::string Purpose()
    {
        return "Verify that glMapRangeBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "Bind non-zero buffer and check that binding point is set to correct value";
    }

    virtual std::string PassCriteria()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer using glMapBufferRange" NL
               "5. Check state" NL "6. Verify mapped buffer" NL "7. Unmap buffer" NL "8. Check state";
    }

    virtual long Run()
    {
        DIResult result;

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        CDataArray dataRef;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
                     GL_DYNAMIC_DRAW);

        result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));

        void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)),
                                     GL_MAP_READ_BIT);
        if (buf == 0)
        {
            result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
        }

        if (buf)
        {
            result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight));

            result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
                                                 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int))));

            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)),
                               GL_MAP_READ_BIT);
        if (buf == 0)
        {
            result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
        }

        if (buf)
        {
            result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2));

            result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0,
                                                 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));

            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
                               (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)), GL_MAP_READ_BIT);
        if (buf == 0)
        {
            result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
        }

        if (buf)
        {
            result.sub_result(
                BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2, dataHeight / 4));

            result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT,
                                                 (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)),
                                                 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int))));

            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <class api>
struct CBufferFlushMappedRange : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glFlushMappedBufferRange";
    }

    virtual std::string Purpose()
    {
        return "Verify that glFlushMappedBufferRange and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL
               "4. Map buffer with GL_MAP_FLUSH_EXPLICIT_BIT flag" NL "5. Check state" NL "6. Modify mapped buffer" NL
               "7. Flush buffer" NL "8. Unmap buffer" NL "9. Check state" NL "10. Verify buffer";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        CDataArray dataRef;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 1000);

        CDataArray dataRef2;
        DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 1000, 2000);

        const int halfSize    = dataHeight / 2 * dataWidth;
        const int quarterSize = dataHeight / 4 * dataWidth;

        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0],
                     GL_DYNAMIC_DRAW);

        result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));

        void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, quarterSize * sizeof(unsigned int),
                                     halfSize * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);

        if (buf == 0)
        {
            result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
        }

        if (buf)
        {
            result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,
                                                 quarterSize * sizeof(unsigned int), halfSize * sizeof(unsigned int)));

            memcpy(buf, &dataRef2[quarterSize], halfSize * sizeof(unsigned int));
            glFlushMappedBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, halfSize * sizeof(unsigned int));

            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;

            result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0));
        }

        CDataArray dataTest(dataWidth * dataHeight, 0);
        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);

        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));

        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
                                      dataHeight / 4, dataHeight / 4));

        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4,
                                      dataHeight * 3 / 4, dataHeight * 3 / 4));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <class api>
struct CBufferBindRange : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glBindBufferRange";
    }

    virtual std::string Purpose()
    {
        return "Verify that glBindBufferRange accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer using glBindBufferRange" NL "3. Set data" NL "4. Verify buffer";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer);

        CDataArray dataRef;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 100);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef.size() * sizeof(unsigned int), &dataRef[0], GL_DYNAMIC_DRAW);

        CDataArray dataTest(dataWidth * dataHeight, 0);
        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
        result.sub_result(BindingPointCheck<api>(0));

        glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, 0, dataTest.size() * sizeof(unsigned int) / 4);
        result.sub_result(BindingPointCheck<api>(_buffer));

        CDataArray dataRef2;
        DataGen<unsigned int>(dataRef2, dataWidth, dataHeight / 2, 10, 15);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 4, &dataRef2[0],
                     GL_DYNAMIC_DRAW);

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4));
        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight * 3 / 4, dataTest, dataWidth, dataHeight * 3 / 4,
                                      dataHeight / 4, dataHeight / 4));

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
        result.sub_result(BindingPointCheck<api>(0));

        glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, dataTest.size() * sizeof(unsigned int) / 4,
                          dataTest.size() * sizeof(unsigned int) / 4);
        result.sub_result(BindingPointCheck<api>(_buffer));

        glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 2,
                     &dataRef2[dataRef2.size() / 2], GL_DYNAMIC_DRAW);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2));
        result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2,
                                      dataHeight / 2, dataHeight / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(1, &_buffer);

        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffer;
};

template <class api>
struct CBufferBindBase : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glBindBufferBase";
    }

    virtual std::string Purpose()
    {
        return "Verify that glBindBufferBase accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer using glBindBufferBase" NL "3. Set data" NL "4. Verify buffer";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;

        glGenBuffers(2, _buffers);

        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        CDataArray dataTest(dataWidth * dataHeight, 0);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[0]);
        CDataArray dataRef1;
        DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef1.size() * sizeof(unsigned int), &dataRef1[0], GL_DYNAMIC_DRAW);

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
        result.sub_result(BindingPointCheck<api>(0));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
        result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));
        result.sub_result(BindingPointCheck<api>(_buffers[0]));

        glBindBufferBase(GL_DRAW_INDIRECT_BUFFER, 0, _buffers[1]);
        result.sub_result(BindingPointCheck<api>(_buffers[1]));

        CDataArray dataRef2;
        DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 50, 70);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int), &dataRef2[0], GL_DYNAMIC_DRAW);

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        result.sub_result(BindingPointCheck<api>(_buffers[1]));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(2, _buffers);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffers[2];
};

template <class api>
struct CBufferCopySubData : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Check functions: glCopyBufferSubData";
    }

    virtual std::string Purpose()
    {
        return "Verify that glCopyBufferSubData accepts GL_DRAW_INDIRECT_BUFFER enum";
    }

    virtual std::string Method()
    {
        return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Verify buffer" NL
               "5. Modify buffer using glCopyBufferSubData" NL "6. Verify buffer";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        DIResult result;
        int dataWidth, dataHeight;
        getDataSize(dataWidth, dataHeight);
        CDataArray dataTest(dataWidth * dataHeight, 0);

        glGenBuffers(2, _buffers);
        glBindBuffer(GL_ARRAY_BUFFER, _buffers[0]);

        CDataArray dataRef1;
        DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0],
                     GL_DYNAMIC_DRAW);

        GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
        result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]);

        CDataArray dataRef2;
        DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 30);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
                     GL_DYNAMIC_DRAW);

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glCopyBufferSubData(GL_ARRAY_BUFFER, GL_DRAW_INDIRECT_BUFFER, 0, 0,
                            (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0],
                     GL_DYNAMIC_DRAW);

        GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)),
                              &dataTest[0]);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        glCopyBufferSubData(GL_DRAW_INDIRECT_BUFFER, GL_ARRAY_BUFFER, 0, 0,
                            (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)));

        GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]);
        result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDeleteBuffers(2, _buffers);
        return BindingPointCheck<api>(0);
    }

private:
    GLuint _buffers[2];
};

class CBasicVertexDef : public DrawIndirectBase
{
public:
    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run()
    {
        CColorArray coords;
        PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);

        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenBuffers(1, &_vbo);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            indirectArrays.count              = static_cast<GLuint>(coords.size());
            indirectArrays.primCount          = 1;
            indirectArrays.first              = 0;
            indirectArrays.reservedMustBeZero = 0;

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
                glDrawArraysIndirect(_primitiveType, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        case DRAW_ELEMENTS:
        {
            indirectElements.count              = static_cast<GLuint>(coords.size());
            indirectElements.primCount          = 1;
            indirectElements.firstIndex         = 0;
            indirectElements.baseVertex         = 0;
            indirectElements.reservedMustBeZero = 0;

            glGenBuffers(1, &_ebo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                         GL_STATIC_DRAW);

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
                glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);

        DIResult result;
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        glUseProgram(0);

        if (_vao)
        {
            glDeleteVertexArrays(1, &_vao);
        }
        if (_vbo)
        {
            glDeleteBuffers(1, &_vbo);
        }
        if (_ebo)
        {
            glDeleteBuffers(1, &_ebo);
        }
        if (_program)
        {
            glDeleteProgram(_program);
        }

        return NO_ERROR;
    }

    CBasicVertexDef(TDrawFunction drawFunc, GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY)
        : _drawFunc(drawFunc)
        , _primitiveType(primitiveType)
        , _drawSizeX(drawSizeX)
        , _drawSizeY(drawSizeY)
        , _vao(0)
        , _vbo(0)
        , _ebo(0)
        , _program(0)
    {
    }

private:
    TDrawFunction _drawFunc;
    GLenum _primitiveType;
    unsigned int _drawSizeX;
    unsigned int _drawSizeY;

    GLuint _vao;
    GLuint _vbo, _ebo;
    GLuint _program;

    CBasicVertexDef()
    {
    }
};

class CBasicVertexInstancingDef : public DrawIndirectBase
{
public:
    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run()
    {
        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);

        CColorArray coords_instanced(4);
        coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
        coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
        coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
        coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);

        CColorArray colors_instanced(2);
        colors_instanced[0] = tcu::Vec4(1.0, 0.0, 0.0, 1.0);
        colors_instanced[1] = tcu::Vec4(0.0, 1.0, 0.0, 1.0);

        _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenBuffers(1, &_vbo);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glBufferData(GL_ARRAY_BUFFER,
                     (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
                                  coords_instanced.size() * sizeof(coords_instanced[0]) +
                                  colors_instanced.size() * sizeof(colors_instanced[0])),
                     NULL, GL_STATIC_DRAW);

        const size_t coords_offset           = 0;
        const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
        const size_t colors_instanced_offset =
            coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);

        glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
                        (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)colors_instanced_offset,
                        (GLsizeiptr)(colors_instanced.size() * sizeof(colors_instanced[0])), &colors_instanced[0]);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        //i_vertex (coords)
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_offset));
        glEnableVertexAttribArray(0);

        //i_vertex_instanced (coords_instanced)
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_instanced_offset));
        glEnableVertexAttribArray(1);
        glVertexAttribDivisor(1, 1);

        //i_vertex_color_instanced (color_instanced)
        glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(colors_instanced_offset));
        glEnableVertexAttribArray(2);
        glVertexAttribDivisor(2, 3);

        DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            indirectArrays.count              = static_cast<GLuint>(coords.size());
            indirectArrays.primCount          = 4;
            indirectArrays.first              = 0;
            indirectArrays.reservedMustBeZero = 0;

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
                glDrawArraysIndirect(GL_TRIANGLES, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        case DRAW_ELEMENTS:
        {
            indirectElements.count              = static_cast<GLuint>(coords.size());
            indirectElements.primCount          = 4;
            indirectElements.firstIndex         = 0;
            indirectElements.baseVertex         = 0;
            indirectElements.reservedMustBeZero = 0;

            glGenBuffers(1, &_ebo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                         GL_STATIC_DRAW);

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
                glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[0]);
        CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[1]);

        CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
        DIResult result;

        ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
                             &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
                             &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
                             getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        glUseProgram(0);

        if (_vao)
        {
            glDeleteVertexArrays(1, &_vao);
        }
        if (_vbo)
        {
            glDeleteBuffers(1, &_vbo);
        }
        if (_ebo)
        {
            glDeleteBuffers(1, &_ebo);
        }
        if (_program)
        {
            glDeleteProgram(_program);
        }

        return NO_ERROR;
    }

    template <typename api>
    std::string Vsh()
    {
        return api::glslVer() + NL
               "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
               "layout(location = 2) in vec4 i_vertex_color_instanced;" NL "out vec4 vertex_color_instanced;" NL
               "void main()" NL "{" NL "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
               "    vertex_color_instanced = i_vertex_color_instanced;" NL "}";
    }

    template <typename api>
    std::string Fsh()
    {
        return api::glslVer() + NL "precision highp float; " NL "in  vec4 vertex_color_instanced;" NL
                                   "out vec4 outColor;" NL "void main() {" NL "  outColor = vertex_color_instanced;" NL
                                   "}";
    }

    CBasicVertexInstancingDef(TDrawFunction drawFunc)
        : _drawFunc(drawFunc)
        , _drawSizeX(2)
        , _drawSizeY(2)
        , _vao(0)
        , _vbo(0)
        , _ebo(0)
        , _program(0)
    {
    }

private:
    TDrawFunction _drawFunc;
    unsigned int _drawSizeX;
    unsigned int _drawSizeY;

    GLuint _vao;
    GLuint _vbo, _ebo;
    GLuint _program;

    CBasicVertexInstancingDef()
    {
    }
};

template <typename api>
class CVBODrawArraysSingle : public CBasicVertexDef
{
public:
    virtual std::string Title()
    {
        return "VBO: Single primitive using glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawArraysSingle() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 1, 1)
    {
    }
    virtual long Run()
    {
        return CBasicVertexDef::Run<api>();
    }
};

template <typename api>
class CVBODrawArraysMany : public CBasicVertexDef
{
public:
    virtual std::string Title()
    {
        return "VBO: Many primitives using glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawArraysMany() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 8, 8)
    {
    }
    virtual long Run()
    {
        return CBasicVertexDef::Run<api>();
    }
};

template <typename api>
class CVBODrawArraysInstancing : public CBasicVertexInstancingDef
{
public:
    virtual std::string Title()
    {
        return "VBO: Single primitive using glDrawArraysIndirect, multiple instances";
    }

    virtual std::string Purpose()
    {
        return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawArraysInstancing() : CBasicVertexInstancingDef(DRAW_ARRAYS)
    {
    }
    virtual long Run()
    {
        return CBasicVertexInstancingDef::Run<api>();
    }
};

class CBasicXFBPausedDef : public DrawIndirectBase
{
public:
    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run()
    {
        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);

        _program = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);

        const GLchar *varyings[] = {"dataOut"};
        glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
        glLinkProgram(_program);
        if (!CheckProgram(_program))
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenBuffers(1, &_vbo);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenTransformFeedbacks(1, &_xfo);
        glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);

        glGenBuffers(1, &_xfbo);
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfbo);
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STATIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfbo);

        glBeginTransformFeedback(GL_TRIANGLES);
        glPauseTransformFeedback();

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            indirectArrays.count              = static_cast<GLuint>(coords.size());
            indirectArrays.primCount          = 1;
            indirectArrays.first              = 0;
            indirectArrays.reservedMustBeZero = 0;

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
                glDrawArraysIndirect(GL_TRIANGLES, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        case DRAW_ELEMENTS:
        {
            indirectElements.count              = static_cast<GLuint>(coords.size());
            indirectElements.primCount          = 1;
            indirectElements.firstIndex         = 0;
            indirectElements.baseVertex         = 0;
            indirectElements.reservedMustBeZero = 0;

            glGenBuffers(1, &_ebo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                         GL_STATIC_DRAW);

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
                glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
                glDeleteBuffers(1, &buffer);
            }
        }

        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        glResumeTransformFeedback();
        glEndTransformFeedback();

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);

        DIResult result;
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        glUseProgram(0);

        if (_vao)
        {
            glDeleteVertexArrays(1, &_vao);
        }
        if (_vbo)
        {
            glDeleteBuffers(1, &_vbo);
        }
        if (_ebo)
        {
            glDeleteBuffers(1, &_ebo);
        }
        if (_xfbo)
        {
            glDeleteBuffers(1, &_xfbo);
        }
        if (_program)
        {
            glDeleteProgram(_program);
        }
        if (_xfo)
        {
            glDeleteTransformFeedbacks(1, &_xfo);
        }

        return NO_ERROR;
    }

    template <typename api>
    std::string Vsh()
    {
        return api::glslVer() + NL "in vec4 i_vertex;" NL "out vec4 dataOut;" NL "void main()" NL "{" NL
                                   "    gl_Position = i_vertex;" NL "    dataOut = i_vertex;" NL "}";
    }

    CBasicXFBPausedDef(TDrawFunction drawFunc)
        : _drawFunc(drawFunc)
        , _drawSizeX(2)
        , _drawSizeY(2)
        , _vao(0)
        , _vbo(0)
        , _ebo(0)
        , _xfbo(0)
        , _program(0)
        , _xfo(0)
    {
    }

private:
    TDrawFunction _drawFunc;
    unsigned int _drawSizeX;
    unsigned int _drawSizeY;

    GLuint _vao;
    GLuint _vbo, _ebo, _xfbo;
    GLuint _program;
    GLuint _xfo;

    CBasicXFBPausedDef()
    {
    }
};

template <typename api>
class CVBODrawArraysXFBPaused : public CBasicXFBPausedDef
{
public:
    virtual std::string Title()
    {
        return "VBO: glDrawArraysIndirect, in paused transform feedback operation";
    }

    virtual std::string Purpose()
    {
        return "Verify  glDrawArraysIndirect works, if XFB is active and paused";
    }

    virtual std::string Method()
    {
        return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawArraysXFBPaused() : CBasicXFBPausedDef(DRAW_ARRAYS)
    {
    }
    virtual long Run()
    {
        return CBasicXFBPausedDef::Run<api>();
    }
};

template <typename api>
class CVBODrawElementsSingle : public CBasicVertexDef
{
public:
    virtual std::string Title()
    {
        return "VBO: Single primitive using glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawElementsSingle() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 1, 1)
    {
    }
    virtual long Run()
    {
        return CBasicVertexDef::Run<api>();
    }
};

template <typename api>
class CVBODrawElementsMany : public CBasicVertexDef
{
public:
    virtual std::string Title()
    {
        return "VBO: Many primitives using glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawElementsMany() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 8, 8)
    {
    }

    virtual long Run()
    {
        return CBasicVertexDef::Run<api>();
    }
};

template <typename api>
class CVBODrawElementsInstancing : public CBasicVertexInstancingDef
{
public:
    virtual std::string Title()
    {
        return "VBO: Single primitive using glDrawElementsIndirect, multiple instances";
    }

    virtual std::string Purpose()
    {
        return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawElementsInstancing() : CBasicVertexInstancingDef(DRAW_ELEMENTS)
    {
    }
    virtual long Run()
    {
        return CBasicVertexInstancingDef::Run<api>();
    }
};

template <typename api>
class CVBODrawElementsXFBPaused : public CBasicXFBPausedDef
{
public:
    virtual std::string Title()
    {
        return "VBO: glDrawElementsIndirect, in paused transform feedback operation";
    }

    virtual std::string Purpose()
    {
        return "Verify  glDrawElementsIndirect works, if XFB is active and paused";
    }

    virtual std::string Method()
    {
        return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CVBODrawElementsXFBPaused() : CBasicXFBPausedDef(DRAW_ELEMENTS)
    {
    }
    virtual long Run()
    {
        return CBasicXFBPausedDef::Run<api>();
    }
};

template <typename api>
class CBufferIndirectDrawArraysSimple : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawArraysIndirect: many primitives simple";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;
        indirectArrays.first                     = 0;
        indirectArrays.reservedMustBeZero        = 0;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        glDrawArraysIndirect(GL_TRIANGLES, 0);

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawArraysNoFirst : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawArraysIndirect: non-zero 'first' argument";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with specified non-zero 'first' argument" NL
               "in indirect buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size()) / 2;
        indirectArrays.primCount                 = 1;
        indirectArrays.first                     = static_cast<GLuint>(coords.size()) / 2;
        indirectArrays.reservedMustBeZero        = 0;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        glDrawArraysIndirect(GL_TRIANGLES, 0);

        CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
        CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth(), getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawArraysOffset : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawArraysIndirect: offset as a function parameter";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with offset as a function parameter";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect with offset" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;
        indirectArrays.first                     = 0;
        indirectArrays.reservedMustBeZero        = 0;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
        glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), sizeof(DrawArraysIndirectCommand),
                        &indirectArrays);
        glDrawArraysIndirect(GL_TRIANGLES, (void *)sizeof(DrawArraysIndirectCommand));

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawElementsSimple : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawElementsIndirect: many primitives simple";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;
        indirectElements.baseVertex                  = 0;
        indirectElements.firstIndex                  = 0;
        indirectElements.reservedMustBeZero          = 0;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        glDeleteBuffers(1, &_ebo);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect, _ebo;
};

template <typename api>
class CBufferIndirectDrawElementsNoFirstIndex : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawElementsIndirect: non-zero first index";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with non-zero first index" NL "in indirect buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
        indirectElements.primCount                   = 1;
        indirectElements.baseVertex                  = 0;
        indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 2;
        indirectElements.reservedMustBeZero          = 0;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

        CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
        CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth(), getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect, _ebo;
};

template <typename api>
class CBufferIndirectDrawElementsNoBasevertex : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawElementsIndirect: non-zero base vertex";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with non-zero base vertex" NL "in indirect buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
        indirectElements.primCount                   = 1;
        indirectElements.baseVertex                  = static_cast<GLint>(coords.size()) / 2;
        indirectElements.firstIndex                  = 0;
        indirectElements.reservedMustBeZero          = 0;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

        CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
        CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth(), getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
class CBufferIndirectDrawElementsOffset : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawElementsIndirect: offset as a function parameter";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with offset as a function parameter";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect with offset" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;
        indirectElements.baseVertex                  = 0;
        indirectElements.firstIndex                  = 0;
        indirectElements.reservedMustBeZero          = 0;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * 3, NULL, GL_STATIC_DRAW);
        glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand),
                        sizeof(DrawElementsIndirectCommand), &indirectElements);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);
        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)sizeof(DrawElementsIndirectCommand));

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

class CBasicVertexIDsDef : public DrawIndirectBase
{
public:
    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run()
    {
        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords);

        CColorArray coords_instanced(4);
        coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0);
        coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0);
        coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0);
        coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0);

        std::vector<glw::GLfloat> ref_VertexId(coords.size());
        for (size_t i = 0; i < ref_VertexId.size(); i++)
        {
            ref_VertexId[i] = glw::GLfloat(i);
        }

        std::vector<glw::GLfloat> ref_InstanceId(4);
        for (size_t i = 0; i < ref_InstanceId.size(); i++)
        {
            ref_InstanceId[i] = glw::GLfloat(i);
        }

        _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenBuffers(1, &_vbo);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glBufferData(GL_ARRAY_BUFFER,
                     (GLsizeiptr)(coords.size() * sizeof(coords[0]) +
                                  coords_instanced.size() * sizeof(coords_instanced[0]) +
                                  ref_VertexId.size() * sizeof(ref_VertexId[0]) +
                                  ref_InstanceId.size() * sizeof(ref_InstanceId[0])),
                     NULL, GL_STATIC_DRAW);

        const size_t coords_offset           = 0;
        const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]);
        const size_t ref_VertexId_offset =
            coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]);
        const size_t ref_InstanceId_offset = ref_VertexId_offset + ref_VertexId.size() * sizeof(ref_VertexId[0]);

        glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset,
                        (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_VertexId_offset,
                        (GLsizeiptr)(ref_VertexId.size() * sizeof(ref_VertexId[0])), &ref_VertexId[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_InstanceId_offset,
                        (GLsizeiptr)(ref_InstanceId.size() * sizeof(ref_InstanceId[0])), &ref_InstanceId[0]);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        //i_vertex (coords)
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_offset));
        glEnableVertexAttribArray(0);

        //i_vertex_instanced (coords_instanced)
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(coords_instanced_offset));
        glEnableVertexAttribArray(1);
        glVertexAttribDivisor(1, 1);

        //i_ref_VertexId
        glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(ref_VertexId_offset));
        glEnableVertexAttribArray(2);
        //i_ref_InstanceId
        glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid *>(ref_InstanceId_offset));
        glEnableVertexAttribArray(3);
        glVertexAttribDivisor(3, 1);

        DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};
        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            indirectArrays.count              = static_cast<GLuint>(coords.size());
            indirectArrays.primCount          = 4;
            indirectArrays.first              = 0;
            indirectArrays.reservedMustBeZero = 0;

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW);
                glDrawArraysIndirect(GL_TRIANGLES, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        case DRAW_ELEMENTS:
        {
            indirectElements.count              = static_cast<GLuint>(coords.size());
            indirectElements.primCount          = 4;
            indirectElements.firstIndex         = 0;
            indirectElements.baseVertex         = 0;
            indirectElements.reservedMustBeZero = 0;

            glGenBuffers(1, &_ebo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                         GL_STATIC_DRAW);

            {
                GLuint buffer;
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
                glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW);
                glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
                glDeleteBuffers(1, &buffer);
            }
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.5f, 0.0f));
        CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.75f, 0.0f));
        CColorArray bufferRef3(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.25f, 0.0f));
        CColorArray bufferRef4(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.0f, 0.0f));

        CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f));
        DIResult result;

        ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2,
                             &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2,
                             &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef3,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2,
                             getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef4,
                                         getWindowWidth() / 2, getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        glUseProgram(0);

        if (_vao)
        {
            glDeleteVertexArrays(1, &_vao);
        }
        if (_vbo)
        {
            glDeleteBuffers(1, &_vbo);
        }
        if (_ebo)
        {
            glDeleteBuffers(1, &_ebo);
        }
        if (_program)
        {
            glDeleteProgram(_program);
        }

        return NO_ERROR;
    }

    template <typename api>
    std::string Vsh()
    {
        return api::glslVer() + NL
               "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL
               "layout(location = 2) in float i_ref_VertexId;" NL "layout(location = 3) in float i_ref_InstanceId;" NL
               "out vec4 val_Result;" NL "void main()" NL "{" NL
               "    gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL
               "    if ( gl_VertexID == int(i_ref_VertexId + .5) && gl_InstanceID == int(i_ref_InstanceId + .5)) {" NL
               "        val_Result = vec4(0.0, 1.0, float(gl_InstanceID) / 4.0, 1.0);" NL "    } else {" NL
               "        val_Result = vec4(1.0, 0.0, 0.0, 1.0);" NL "    }" NL "}";
    }

    template <typename api>
    std::string Fsh()
    {
        return api::glslVer() + NL "precision highp float; " NL "in vec4 val_Result;" NL "out vec4 outColor;" NL
                                   "void main() {" NL "  outColor = val_Result;" NL "}";
    }

    CBasicVertexIDsDef(TDrawFunction drawFunc)
        : _drawFunc(drawFunc)
        , _drawSizeX(2)
        , _drawSizeY(2)
        , _vao(0)
        , _vbo(0)
        , _ebo(0)
        , _program(0)
    {
    }

private:
    TDrawFunction _drawFunc;
    unsigned int _drawSizeX;
    unsigned int _drawSizeY;

    GLuint _vao;
    GLuint _vbo, _ebo;
    GLuint _program;

    CBasicVertexIDsDef()
    {
    }
};

template <typename api>
class CBufferIndirectDrawArraysVertexIds : public CBasicVertexIDsDef
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawArraysIndirect: all non-zero arguments, verify vertex ids";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        return CBasicVertexIDsDef::Run<api>();
    }

    CBufferIndirectDrawArraysVertexIds() : CBasicVertexIDsDef(DRAW_ARRAYS)
    {
    }
};

template <typename api>
class CBufferIndirectDrawElementsVertexIds : public CBasicVertexIDsDef
{
public:
    virtual std::string Title()
    {
        return "Indirect buffer glDrawElementsIndirect: all non-zero arguments, verify vertex ids";
    }

    virtual std::string Purpose()
    {
        return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Run()
    {
        return CBasicVertexIDsDef::Run<api>();
    }

    CBufferIndirectDrawElementsVertexIds() : CBasicVertexIDsDef(DRAW_ELEMENTS)
    {
    }
};

template <typename api>
class CIndicesDataTypeUnsignedShort : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect indices data type: unsigned short";
    }

    virtual std::string Purpose()
    {
        return "Verify that unsigned short indices are accepted by glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
               "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
        indirectElements.primCount                   = 1;
        indirectElements.baseVertex                  = -static_cast<GLint>(coords.size()) / 4;
        indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 4;
        indirectElements.reservedMustBeZero          = 0;

        std::vector<GLushort> elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLushort>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
        glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0);

        CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
        CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth(), getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
class CIndicesDataTypeUnsignedByte : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect indices data type: unsigned byte";
    }

    virtual std::string Purpose()
    {
        return "Verify that unsigned byte indices are accepted by glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL
               "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 2, 2, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size()) / 2;
        indirectElements.primCount                   = 1;
        indirectElements.baseVertex                  = -static_cast<GLint>(coords.size()) / 4;
        indirectElements.firstIndex                  = static_cast<GLuint>(coords.size()) / 4;
        indirectElements.reservedMustBeZero          = 0;

        std::vector<GLubyte> elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLubyte>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
        glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 0);

        CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
        CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth(), getWindowHeight() / 2));

        ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 2));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

class CPrimitiveMode : public DrawIndirectBase
{
public:
    template <typename api>
    bool IsGeometryShaderSupported()
    {
        if (api::isES())
        {
            const glu::ContextInfo &info = m_context.getContextInfo();
            const glu::ContextType &type = m_context.getRenderContext().getType();

            /* ES 3.2+ included geometry shaders into the core */
            if (glu::contextSupports(type, glu::ApiType(3, 2, glu::PROFILE_ES)))
            {
                return true;
            }
            /* ES 3.1 may be able to support geometry shaders via extensions */
            else if ((glu::contextSupports(type, glu::ApiType(3, 1, glu::PROFILE_ES))) &&
                     ((true == info.isExtensionSupported("GL_EXT_geometry_shader")) ||
                      (true == info.isExtensionSupported("GL_OES_geometry_shader"))))
            {
                return true;
            }
            else
            {
                OutputNotSupported("Geometry shader is not supported\n");
                return false;
            }
        }
        else
        {
            return true;
        }
    }
    virtual long Setup()
    {
        _sizeX = getWindowWidth();
        _sizeY = getWindowHeight();
        if (_primitiveType != GL_TRIANGLE_STRIP && _primitiveType != GL_TRIANGLE_STRIP_ADJACENCY &&
            _primitiveType != GL_TRIANGLES && _primitiveType != GL_TRIANGLES_ADJACENCY &&
            _primitiveType != GL_TRIANGLE_FAN)
        {
            _sizeX &= (-4);
            _sizeY &= (-4);
        }
        if ((int)_drawSizeX < 0 || (int)_drawSizeY < 0)
        {
            //no PrimitiveGen dimensions given. assume same dimensions as rendered image^
            _drawSizeX = _sizeX;
            _drawSizeY = _sizeY;
            if (_primitiveType == GL_POINTS)
            {
                //clamp vertex number (and rendering size) for points to max. 10000
                _sizeX = _drawSizeX = std::min(_drawSizeX, 100u);
                _sizeY = _drawSizeY = std::min(_drawSizeY, 100u);
            }
        }

        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run(bool pointMode = false)
    {

        glClear(GL_COLOR_BUFFER_BIT);

        _program = CreateProgram(pointMode ? shaders::vshSimple_point<api>() : shaders::vshSimple<api>(), "",
                                 shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        CColorArray padding(10, tcu::Vec4(0.0f));

        glBufferData(GL_ARRAY_BUFFER,
                     (GLsizeiptr)(coords.size() * (sizeof(coords[0])) + padding.size() * (sizeof(padding[0]))), NULL,
                     GL_STREAM_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(padding.size() * (sizeof(padding[0]))), &padding[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(padding.size() * (sizeof(padding[0]))),
                        (GLsizeiptr)(coords.size() * (sizeof(coords[0]))), &coords[0]);

        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            indirectArrays.count              = static_cast<GLuint>(coords.size()) / 2;
            indirectArrays.primCount          = 1;
            indirectArrays.first              = 10;
            indirectArrays.reservedMustBeZero = 0;

            glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW);
            glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), &indirectArrays);

            glDrawArraysIndirect(_primitiveType, 0);
        }
        break;
        case DRAW_ELEMENTS:
        {
            indirectElements.count              = static_cast<GLuint>(coords.size()) / 2;
            indirectElements.primCount          = 1;
            indirectElements.baseVertex         = 7;
            indirectElements.firstIndex         = 3;
            indirectElements.reservedMustBeZero = 0;

            glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW);
            glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements);

            glGenBuffers(1, &_ebo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                         GL_STATIC_DRAW);

            glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0);
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        CColorArray bufferRef1(_sizeX * _sizeY / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
        CColorArray bufferRef2(_sizeX * _sizeY / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(_sizeX * _sizeY, tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, (_sizeY + 1) / 2, _sizeX, _sizeY / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef1, _sizeX, _sizeY / 2));

        switch (_primitiveType)
        {
        case GL_TRIANGLES_ADJACENCY:
        case GL_TRIANGLE_STRIP_ADJACENCY:
        {
            CColorArray bufferRef3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
            CColorArray bufferRef4(_sizeX * _sizeY / 8, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
            CColorArray bufferRef5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));

            CColorArray bufferTest3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f));
            CColorArray bufferTest4(_sizeX * _sizeY / 8, tcu::Vec4(0.0f));
            CColorArray bufferTest5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f));

            ReadPixelsFloat<api>(0, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
            result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));

            ReadPixelsFloat<api>((_sizeX + 3) / 4, (_sizeY + 3) / 4, _sizeX / 2, _sizeY / 4, &bufferTest4[0]);
            result.sub_result(BuffersCompare(bufferTest4, _sizeX / 2, _sizeY / 4, bufferRef4, _sizeX / 2, _sizeY / 4));

            ReadPixelsFloat<api>((_sizeX * 3 + 3) / 4, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]);
            result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4));

            ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 4, &bufferTest5[0]);
            result.sub_result(BuffersCompare(bufferTest5, _sizeX, _sizeY / 4, bufferRef5, _sizeX, _sizeY / 4));
        }
        break;
        default:
        {
            ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 2, &bufferTest[0]);
            result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef2, _sizeX, _sizeY / 2));
        }
        break;
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

    CPrimitiveMode(TDrawFunction drawFunc, GLenum primitiveType, unsigned int sizeX = -1, unsigned sizeY = -1)
        : _drawFunc(drawFunc)
        , _primitiveType(primitiveType)
        , _drawSizeX(sizeX)
        , _drawSizeY(sizeY)
        , _sizeX(0)
        , _sizeY(0)
        , _program(0)
        , _vao(0)
        , _buffer(0)
        , _ebo(0)
        , _bufferIndirect(0)
    {
    }

private:
    TDrawFunction _drawFunc;
    GLenum _primitiveType;
    unsigned int _drawSizeX, _drawSizeY; //dims for primitive generator
    unsigned int _sizeX, _sizeY;         //rendering size
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;

    CPrimitiveMode();
};

template <typename api>
class CModeDrawArraysPoints : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_POINTS";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_POINTS works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysPoints() : CPrimitiveMode(DRAW_ARRAYS, GL_POINTS)
    {
    }

    virtual long Run()
    {
        return CPrimitiveMode::Run<api>(true);
    }
};

template <typename api>
class CModeDrawArraysLines : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_LINES";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_LINES works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysLines() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES)
    {
    }

    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysLineStrip : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_LINE_STRIP";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_LINE_STRIP works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysLineStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP)
    {
    }
    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysLineLoop : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_LINE_LOOP";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_LINE_LOOP works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysLineLoop() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_LOOP)
    {
    }

    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysTriangleStrip : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysTriangleStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP, 2, 2)
    {
    }

    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysTriangleFan : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_TRIANGLE_FAN";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_TRIANGLE_FAN works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysTriangleFan() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_FAN, 2, 2)
    {
    }

    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysLinesAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_LINES_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_LINES_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysLinesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES_ADJACENCY)
    {
    }

    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysLineStripAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_LINE_STRIP_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysLineStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP_ADJACENCY)
    {
    }

    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysTrianglesAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_TRIANGLES_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_TRIANGLES_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysTrianglesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLES_ADJACENCY, 4, 4)
    {
    }

    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawArraysTriangleStripAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawArraysTriangleStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
    {
    }
    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsPoints : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_POINTS";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_POINTS works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsPoints() : CPrimitiveMode(DRAW_ELEMENTS, GL_POINTS)
    {
    }

    virtual long Run()
    {
        return CPrimitiveMode::Run<api>(true);
    }
};

template <typename api>
class CModeDrawElementsLines : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_LINES";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_LINES works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsLines() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES)
    {
    }
    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsLineStrip : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_LINE_STRIP";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_LINE_STRIP works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsLineStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP)
    {
    }
    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsLineLoop : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_LINE_LOOP";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_LINE_LOOP works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsLineLoop() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_LOOP)
    {
    }
    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsTriangleStrip : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsTriangleStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP, 2, 2)
    {
    }
    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsTriangleFan : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_TRIANGLE_FAN";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_TRIANGLE_FAN works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsTriangleFan() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_FAN, 2, 2)
    {
    }
    virtual long Run()
    {
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsLinesAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_LINES_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_LINES_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsLinesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES_ADJACENCY)
    {
    }
    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsLineStripAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_LINE_STRIP_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_LINE_STRIP_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsLineStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP_ADJACENCY)
    {
    }
    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsTrianglesAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_TRIANGLES_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_TRIANGLES_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsTrianglesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLES_ADJACENCY, 4, 4)
    {
    }
    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

template <typename api>
class CModeDrawElementsTriangleStripAdjacency : public CPrimitiveMode
{
public:
    virtual std::string Title()
    {
        return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY";
    }

    virtual std::string Purpose()
    {
        return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly";
    }

    virtual std::string Method()
    {
        return "1. Create and fill VBO" NL "2. Create indirect buffer" NL
               "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CModeDrawElementsTriangleStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4)
    {
    }
    virtual long Run()
    {
        if (!IsGeometryShaderSupported<api>())
            return NOT_SUPPORTED;
        return CPrimitiveMode::Run<api>();
    }
};

class CTransformFeedback : public DrawIndirectBase
{
public:
    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run()
    {
        CColorArray coords;
        PrimitiveGen(GL_TRIANGLE_STRIP, 8, 8, coords);

        glClear(GL_COLOR_BUFFER_BIT);

        _program                 = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false);
        const GLchar *varyings[] = {"dataOut"};
        glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
        glLinkProgram(_program);
        if (!CheckProgram(_program))
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenBuffers(1, &_vbo);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW);

        glGenBuffers(1, &_ubo);
        glBindBuffer(GL_UNIFORM_BUFFER, _ubo);
        glBufferData(GL_UNIFORM_BUFFER, 4 * 5 * sizeof(GLuint), NULL, GL_STATIC_DRAW);
        glBindBufferBase(GL_UNIFORM_BUFFER, glGetUniformBlockIndex(_program, "BLOCK"), _ubo);
        std::vector<GLuint> uboData;

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            uboData.resize(4 * 4, 0);

            uboData[0]  = static_cast<GLuint>(coords.size()); //count
            uboData[4]  = 1;                                  //primcount
            uboData[8]  = 0;                                  //first
            uboData[12] = 0;                                  //mbz
        }
        break;
        case DRAW_ELEMENTS:
        {
            uboData.resize(4 * 5, 0);
            uboData[0]  = static_cast<GLuint>(coords.size()); //count
            uboData[4]  = 1;                                  //primcount
            uboData[8]  = 0;                                  //firstindex
            uboData[12] = 0;                                  //basevertex
            uboData[16] = 0;                                  //mbz
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }
        glBufferSubData(GL_UNIFORM_BUFFER, 0, (GLsizeiptr)(uboData.size() * sizeof(uboData[0])), &uboData[0]);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glGenBuffers(1, &_bufferIndirect);

        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _bufferIndirect);
        GLuint zeroes[] = {0, 0, 0, 0, 0};
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(zeroes), zeroes, GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);

        glEnable(GL_RASTERIZER_DISCARD);
        glBeginTransformFeedback(GL_POINTS);
        glDrawArrays(GL_POINTS, 0, 5);
        glEndTransformFeedback();
        glDisable(GL_RASTERIZER_DISCARD);

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
            glDrawArraysIndirect(GL_TRIANGLES, 0);
            break;
        case DRAW_ELEMENTS:
            glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

            break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);

        DIResult result;
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        glUseProgram(0);

        if (_vao)
        {
            glDeleteVertexArrays(1, &_vao);
        }
        if (_vbo)
        {
            glDeleteBuffers(1, &_vbo);
        }
        if (_ebo)
        {
            glDeleteBuffers(1, &_ebo);
        }
        if (_ubo)
        {
            glDeleteBuffers(1, &_ubo);
        }
        if (_bufferIndirect)
        {
            glDeleteBuffers(1, &_bufferIndirect);
        }
        if (_program)
        {
            glDeleteProgram(_program);
        }
        return NO_ERROR;
    }

    CTransformFeedback(TDrawFunction drawFunc)
        : _drawFunc(drawFunc)
        , _program(0)
        , _vao(0)
        , _vbo(0)
        , _ebo(0)
        , _ubo(0)
        , _bufferIndirect(0)
    {
    }

private:
    TDrawFunction _drawFunc;
    GLuint _program;
    GLuint _vao, _vbo, _ebo, _ubo, _bufferIndirect;

    CTransformFeedback();

    template <typename api>
    std::string Vsh()
    {
        return api::glslVer() + NL "flat out highp uint dataOut;" NL "in vec4 i_vertex;" NL
                                   "layout(std140) uniform  BLOCK {" NL " uint m[5];" NL "} b;" NL "void main() {" NL
                                   "  dataOut = b.m[min(4, gl_VertexID)];" NL "    gl_Position = i_vertex;" NL "}";
    }
};

template <typename api>
struct CTransformFeedbackArray : public CTransformFeedback
{
    virtual std::string Title()
    {
        return "Transform feedback: glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that transform feedback works correctly with glDrawArrayIndirect";
    }

    virtual std::string Method()
    {
        return "1. Create data" NL "2. Use data as input to glDrawArrayIndirect" NL "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CTransformFeedbackArray() : CTransformFeedback(DRAW_ARRAYS)
    {
    }

    virtual long Run()
    {
        return CTransformFeedback::Run<api>();
    }
};

template <typename api>
struct CTransformFeedbackElements : public CTransformFeedback
{
    virtual std::string Title()
    {
        return "Transform feedback: glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that transform feedback works correctly with glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Create data" NL "2. Use data as input to glDrawElementsIndirect" NL "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CTransformFeedbackElements() : CTransformFeedback(DRAW_ELEMENTS)
    {
    }

    virtual long Run()
    {
        return CTransformFeedback::Run<api>();
    }
};

class CComputeBase : public DrawIndirectBase
{
public:
    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    template <typename api>
    long Run()
    {

        int width, height;
        glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &width);
        glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &height);

        width  = std::min(width, getWindowWidth());
        height = std::min(height, getWindowHeight());

        glViewport(0, 0, width, height);

        CColorArray coords(width * height, tcu::Vec4(0));
        CColorArray colors(width * height, tcu::Vec4(0));

        _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), false);
        glBindAttribLocation(_program, 0, "in_coords");
        glBindAttribLocation(_program, 1, "in_colors");
        glLinkProgram(_program);
        if (!CheckProgram(_program))
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_bufferCoords);
        glBindBuffer(GL_ARRAY_BUFFER, _bufferCoords);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), 0, GL_STREAM_DRAW);

        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
        glEnableVertexAttribArray(0);

        glGenBuffers(1, &_bufferColors);
        glBindBuffer(GL_ARRAY_BUFFER, _bufferColors);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(colors.size() * sizeof(colors[0])), 0, GL_STREAM_DRAW);

        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
        glEnableVertexAttribArray(1);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        DrawArraysIndirectCommand indirectArrays     = {0, 0, 0, 0};

        CElementArray elements(width * height, 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);
        }
        break;
        case DRAW_ELEMENTS:
        {
            glGenBuffers(1, &_ebo);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                         GL_STATIC_DRAW);

            glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements,
                         GL_STATIC_DRAW);
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        _programCompute = CreateComputeProgram(Csh<api>(), false);
        glLinkProgram(_programCompute);
        if (!CheckProgram(_programCompute))
        {
            return ERROR;
        }
        glUseProgram(_programCompute);
        glUniform1ui(glGetUniformLocation(_programCompute, "width"), width);
        glUniform1ui(glGetUniformLocation(_programCompute, "height"), height);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _bufferCoords);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, _bufferColors);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, _bufferIndirect);

        glDispatchCompute(width, height, 1);
        glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);

        glUseProgram(_program);

        switch (_drawFunc)
        {
        case DRAW_ARRAYS:
        {
            glDrawArraysIndirect(GL_POINTS, 0);
        }
        break;
        case DRAW_ELEMENTS:
        {
            glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, 0);
        }
        break;
        default:
            throw std::runtime_error("Unknown draw function!");
            break;
        }

        CColorArray bufferRef1(width * height / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
        CColorArray bufferRef2(width * height / 4, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
        CColorArray bufferRef3(width * height / 4, tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f));
        CColorArray bufferRef4(width * height / 4, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
        CColorArray bufferTest(width * height / 4, tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, width / 2, height / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef1, width / 2, height / 2))
            << "Region 0 verification failed";

        ReadPixelsFloat<api>((width + 1) / 2, 0, width / 2, height / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef2, width / 2, height / 2))
            << "Region 1 verification failed";

        ReadPixelsFloat<api>(0, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef3, width / 2, height / 2))
            << "Region 2 verification failed";

        ReadPixelsFloat<api>((width + 1) / 2, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef4, width / 2, height / 2))
            << "Region 3 verification failed";

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(0);
        glDeleteProgram(_program);
        glDeleteProgram(_programCompute);
        glDeleteVertexArrays(1, &_vao);
        if (_ebo)
            glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferCoords);
        glDeleteBuffers(1, &_bufferColors);
        glDeleteBuffers(1, &_bufferIndirect);
        glViewport(0, 0, getWindowWidth(), getWindowHeight());
        return NO_ERROR;
    }
    CComputeBase(TDrawFunction drawFunc)
        : _drawFunc(drawFunc)
        , _program(0)
        , _programCompute(0)
        , _vao(0)
        , _ebo(0)
        , _bufferCoords(0)
        , _bufferColors(0)
        , _bufferIndirect(0)
    {
    }

private:
    CComputeBase();
    TDrawFunction _drawFunc;

    template <typename api>
    std::string Vsh()
    {
        return api::glslVer() + NL "in vec4 in_coords;" NL "in vec4 in_colors;" NL "out vec4 colors;" NL
                                   "void main() {" NL "  colors = in_colors;" NL "  gl_Position = in_coords;" NL
                                   "#if defined(GL_ES)" NL "  gl_PointSize = 1.0;" NL "#endif" NL "}";
    }

    template <typename api>
    std::string Fsh()
    {
        return api::glslVer() + NL "precision highp float;" NL "in vec4 colors;" NL "out vec4 outColor;" NL
                                   "void main() {" NL "  outColor = colors;" NL "}";
    }

    template <typename api>
    std::string Csh()
    {
        return api::glslVer(true) + NL "precision highp int;                                           " NL
                                       "precision highp float;                                         " NL
                                       "                                                               " NL
                                       "layout(local_size_x = 1) in;                                   " NL
                                       "layout(std430, binding = 0) buffer Vertices {                  " NL
                                       "    vec4 vertices[];                                           " NL
                                       "};                                                             " NL
                                       "layout(std430, binding = 1) buffer Colors {                    " NL
                                       "    vec4 colors[];                                             " NL
                                       "};                                                             " NL
                                       "layout(std430, binding = 2) buffer Indirect {                  " NL
                                       "    uint indirect[4];                                          " NL
                                       "};                                                             " NL
                                       "                                                               " NL
                                       "uniform uint height;                                           " NL
                                       "uniform uint width;                                            " NL
                                       "                                                               " NL
                                       "void main() {                                                  " NL
                                       "    uint w = gl_GlobalInvocationID.x;                          " NL
                                       "    uint h = gl_GlobalInvocationID.y;                          " NL
                                       "    float stepX = 2.0 / float(width);                          " NL
                                       "    float stepY = 2.0 / float(height);                         " NL
                                       "    float offsetX = -1.0 + stepX * float(w) + stepX / 2.0;     " NL
                                       "    float offsetY = -1.0 + stepY * float(h) + stepY / 2.0;     " NL
                                       "    uint arrayOffset = h * width + w;                          " NL
                                       "    vertices[ arrayOffset ] = vec4(offsetX, offsetY, 0.0, 1.0);" NL
                                       "    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);                     " NL
                                       "    if(w > (width / 2u - 1u)) {                                " NL
                                       "        color = color + vec4(0.5, 0.0, 0.0, 0.0);              " NL
                                       "    }                                                          " NL
                                       "    if(h > (height / 2u - 1u)) {                               " NL
                                       "        color = color + vec4(0.0, 0.5, 0.0, 0.0);              " NL
                                       "    }                                                          " NL
                                       "    colors[ arrayOffset ] = color;                             " NL
                                       "    if(w == 0u && h == 0u) {                                   " NL
                                       "        indirect[0] = width * height;                          " NL
                                       "        indirect[1] =  1u;                                     " NL
                                       "    }                                                          " NL
                                       "}                                                              ";
    }

    GLuint _program, _programCompute;
    GLuint _vao;
    GLuint _ebo;
    GLuint _bufferCoords;
    GLuint _bufferColors;
    GLuint _bufferIndirect;
};

template <typename api>
struct CComputeShaderArray : public CComputeBase
{
    virtual std::string Title()
    {
        return "Compute Shader: glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that data created by Compute Shader can be used as an input to glDrawArrayIndirect";
    }

    virtual std::string Method()
    {
        return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawArrayIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CComputeShaderArray() : CComputeBase(DRAW_ARRAYS)
    {
    }

    virtual long Run()
    {
        return CComputeBase::Run<api>();
    }
};

template <typename api>
struct CComputeShaderElements : public CComputeBase
{
    virtual std::string Title()
    {
        return "Compute Shader: glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that data created by Compute Shader can be used as an input to glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawElementsIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    CComputeShaderElements() : CComputeBase(DRAW_ELEMENTS)
    {
    }

    virtual long Run()
    {
        return CComputeBase::Run<api>();
    }
};

template <typename api>
class CPrimitiveRestartElements : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Primitive restart - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that primitive restart works correctly with glDrawElementsIndirect";
    }

    virtual std::string Method()
    {
        return "1. Define primitives using VBO" NL "2. Draw primitives using glDrawElementsIndirect" NL
               "3. Verify results";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if no OpenGL errors reported";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    int PrimitiveRestartIndex();

    void EnablePrimitiveRestart();

    void DisablePrimitiveRestart();

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords1;
        TriangleStipGen(coords1, -1.0f, 1.0f, -1.0, -0.5, 2);

        CColorArray coords2;
        TriangleStipGen(coords2, -1.0f, 1.0f, 0.5, 1.0, 4);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords1.size() + coords2.size()) * sizeof(coords1[0]), NULL,
                     GL_STREAM_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(coords1.size() * sizeof(coords1[0])), &coords1[0]);
        glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(coords1.size() * sizeof(coords1[0])),
                        (GLsizeiptr)(coords2.size() * sizeof(coords2[0])), &coords2[0]);
        glVertexAttribPointer(0, sizeof(coords1[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords1[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords1.size() + coords2.size() + 1);
        indirectElements.primCount                   = static_cast<GLuint>((coords1.size() + coords2.size()) / 2);

        CElementArray elements;
        for (size_t i = 0; i < coords1.size(); ++i)
        {
            elements.push_back(static_cast<GLuint>(i));
        }

        elements.push_back(PrimitiveRestartIndex());
        for (size_t i = 0; i < coords2.size(); ++i)
        {
            elements.push_back(static_cast<GLuint>(coords1.size() + i));
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        EnablePrimitiveRestart();

        glDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_INT, 0);

        CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f));
        CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));
        CColorArray bufferTest1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.0f));
        CColorArray bufferTest2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f));

        DIResult result;
        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 4, &bufferTest1[0]);
        result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 4));
        // height = 2 * (getWindowHeight() / 4)  to avoid border pixels
        // in case the height is not a multiple of 4.
        ReadPixelsFloat<api>(0, (getWindowHeight() + 3) / 4, getWindowWidth(), 2 * (getWindowHeight() / 4),
                             &bufferTest2[0]);
        result.sub_result(BuffersCompare(bufferTest2, getWindowWidth(), getWindowHeight() / 2, bufferRef2,
                                         getWindowWidth(), 2 * (getWindowHeight() / 4)));

        ReadPixelsFloat<api>(0, (getWindowHeight() * 3 + 3) / 4, getWindowWidth(), getWindowHeight() / 4,
                             &bufferTest1[0]);
        result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1,
                                         getWindowWidth(), getWindowHeight() / 4));

        return result.code();
    }

    virtual long Cleanup()
    {

        DisablePrimitiveRestart();
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    void TriangleStipGen(CColorArray &coords, float widthStart, float widthEnd, float heightStart, float heightEnd,
                         unsigned int primNum)
    {
        float widthStep  = (widthEnd - widthStart) / static_cast<float>(primNum);
        float heightStep = (heightEnd - heightStart) / static_cast<float>(primNum);
        for (unsigned int i = 0; i < primNum; ++i)
        {
            float heightOffset = heightStart + heightStep * static_cast<float>(i);
            for (unsigned int j = 0; j < primNum; ++j)
            {
                float widthOffset = widthStart + widthStep * static_cast<float>(j);

                coords.push_back(tcu::Vec4(widthOffset, heightOffset, 0.0f, 1.0f));
                coords.push_back(tcu::Vec4(widthOffset, heightOffset + heightStep, 0.0f, 1.0f));
                coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset, 0.0f, 1.0f));
                coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset + heightStep, 0.0f, 1.0f));
            }
        }
    }
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <>
int CPrimitiveRestartElements<test_api::ES3>::PrimitiveRestartIndex()
{
    return 0xffffffff;
}

template <>
int CPrimitiveRestartElements<test_api::GL>::PrimitiveRestartIndex()
{
    return 3432432;
}

template <>
void CPrimitiveRestartElements<test_api::ES3>::DisablePrimitiveRestart()
{
    glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
}

template <>
void CPrimitiveRestartElements<test_api::GL>::DisablePrimitiveRestart()
{
    glDisable(GL_PRIMITIVE_RESTART);
}

template <>
void CPrimitiveRestartElements<test_api::ES3>::EnablePrimitiveRestart()
{
    glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
}

template <>
void CPrimitiveRestartElements<test_api::GL>::EnablePrimitiveRestart()
{
    glPrimitiveRestartIndex(PrimitiveRestartIndex());
    glEnable(GL_PRIMITIVE_RESTART);
}

template <typename api>
struct CNegativeZeroBufferArray : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: no indirect buffer/parameter - glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call glDrawArrayIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);

        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        glDrawArraysIndirect(GL_TRIANGLES, 0);
        DIResult result;
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer;
};

template <typename api>
struct CNegativeZeroBufferElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: no indirect buffer/parameter - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call glDrawElementsIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

        DIResult result;
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo;
};

template <typename api>
struct CNegativeInvalidModeArray : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: invalid mode - glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Set invalid mode to glDrawArrayIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        glDrawArraysIndirect(GL_FLOAT, 0);

        DIResult result;
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
        }

        glDrawArraysIndirect(GL_STATIC_DRAW, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW as mode";
        }

        glDrawArraysIndirect(GL_DRAW_INDIRECT_BUFFER, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_DRAW_INDIRECT_BUFFER as mode";
        }

        glDrawArraysIndirect(GL_INVALID_ENUM, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM as mode";
        }

        glDrawArraysIndirect(GL_COLOR_BUFFER_BIT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_COLOR_BUFFER_BIT as mode";
        }

        glDrawArraysIndirect(GL_ARRAY_BUFFER, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_ARRAY_BUFFER as mode";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeInvalidModeElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: invalid mode - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Set invalid mode to glDrawElemenetsIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;
        glDrawElementsIndirect(GL_INVALID_ENUM, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode";
        }

        glDrawElementsIndirect(GL_UNSIGNED_INT, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_UNSIGNED_INT as mode";
        }

        glDrawElementsIndirect(GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_ELEMENT_ARRAY_BUFFER as mode";
        }

        glDrawElementsIndirect(GL_FASTEST, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_FASTEST as mode";
        }

        glDrawElementsIndirect(GL_PACK_ALIGNMENT, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_PACK_ALIGNMENT as mode";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVAOArrays : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: no VAO - glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Use glDrawArraysIndirect with default VAO";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        DIResult result;
        glDrawArraysIndirect(GL_TRIANGLES, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver";
        }

        if (glu::isContextTypeES(m_context.getRenderContext().getType()))
            glDisableVertexAttribArray(0);

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {

        if (glu::isContextTypeES(m_context.getRenderContext().getType()))
            glDisableVertexAttribArray(0);

        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVAOElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: no VAO - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Use glDrawElemenetsIndirect with default VAO";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;
        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver";
        }

        if (glu::isContextTypeES(m_context.getRenderContext().getType()))
            glDisableVertexAttribArray(0);

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVBOArrays : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: no VBO - glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Use glDrawArraysIndirect with enabled vertex array, that has no VBO bound";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        DIResult result;
        glDrawArraysIndirect(GL_TRIANGLES, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver";
        }

        glDisableVertexAttribArray(0);

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeNoVBOElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: no VBO - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Use glDrawElementsIndirect with enabled vertex array, that has no VBO bound";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {

        api::ES_Only();

        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;
        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver";
        }

        glDisableVertexAttribArray(0);

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeBufferMappedArray : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: buffer mapped - glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawArrayIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        DIResult result;
        void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), GL_MAP_READ_BIT);
        if (buf == 0)
        {
            result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL";
        }

        glDrawArraysIndirect(GL_TRIANGLES, 0);

        GLenum error = glGetError();
        if (error == GL_INVALID_OPERATION)
        {
            //GL error: nothing is rendered
            CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
            CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

            ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
            result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
                                             getWindowWidth(), getWindowHeight()));
        }
        else if (error == GL_NO_ERROR)
        {
            //No GL error: undefined
        }
        else
        {
            result.error() << "Invalid error code returned by a driver";
        }

        if (buf)
        {
            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeBufferMappedElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: buffer mapped - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawElementsIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;
        void *buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT);
        if (buf == 0)
        {
            result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);

        GLenum error = glGetError();
        if (error == GL_INVALID_OPERATION)
        {
            //GL error: nothing is rendered
            CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
            CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

            ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
            result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef,
                                             getWindowWidth(), getWindowHeight()));
        }
        else if (error == GL_NO_ERROR)
        {
            //No GL error: undefined
        }
        else
        {
            result.error() << "Invalid error code returned by a driver";
        }

        if (buf)
        {
            if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE)
            {
                result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE";
            }
            buf = 0;
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeDataWrongElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: invalid type - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "1. Bind non-zero buffer" NL "2. Call glDrawElementsIndirect with invalid type";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;

        glDrawElementsIndirect(GL_TRIANGLES, GL_FLOAT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_FLOAT type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_INT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_INT type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_STATIC_DRAW, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_SHORT, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_SHORT type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_BYTE, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_BYTE type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_DOUBLE, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_DOUBLE type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_INVALID_ENUM, 0);
        if (glGetError() != GL_INVALID_ENUM)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
class CNegativeGshArray : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Negative: incompatible the input primitive type of gsh - glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
               "4. Call glDrawArrayIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;
        indirectArrays.first                     = 0;
        indirectArrays.reservedMustBeZero        = 0;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        DIResult result;

        glDrawArraysIndirect(GL_POINTS, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    std::string Vsh()
    {
        return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
    }

    std::string Gsh()
    {
        return "#version 150" NL "layout(triangles) in;" NL "layout(triangle_strip, max_vertices = 10) out;" NL
               "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
               "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
    }

    std::string Fsh()
    {
        return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
               "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
    }
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
class CNegativeGshElements : public DrawIndirectBase
{
public:
    virtual std::string Title()
    {
        return "Negative: incompatible the input primitive type of gsh - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL
               "4. Call glDrawElementsIndirect";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(Vsh(), Gsh(), Fsh(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    std::string Vsh()
    {
        return "#version 150" NL "in vec4 coords;" NL "void main() {" NL "  gl_Position = coords;" NL "}";
    }

    std::string Gsh()
    {
        return "#version 150" NL "layout(lines) in;" NL "layout(line_strip, max_vertices = 10) out;" NL
               "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL
               "     gl_Position = gl_in[i].gl_Position;" NL "     EmitVertex();" NL " }" NL "}";
    }

    std::string Fsh()
    {
        return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL
               "  outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}";
    }
    int _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeInvalidSizeArrays : public DrawIndirectBase
{
    struct TWrongStructure1
    {
        GLuint count;
        GLuint primCount;
    };

    struct TWrongStructure2
    {
        GLfloat count;
        GLuint primCount;
    };

    virtual std::string Title()
    {
        return "Negative: wrong structure - glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call glDrawArrayIndirect with wrong structure";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        TWrongStructure1 indirectArrays = {0, 0};
        indirectArrays.count            = static_cast<GLuint>(coords.size());
        indirectArrays.primCount        = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure1), &indirectArrays, GL_STATIC_DRAW);

        DIResult result;

        glDrawArraysIndirect(GL_TRIANGLES, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        glDeleteBuffers(1, &_bufferIndirect);

        TWrongStructure2 indirectArrays2 = {0, 0};
        indirectArrays2.count            = static_cast<GLfloat>(coords.size());
        indirectArrays2.primCount        = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure2), &indirectArrays2, GL_STATIC_DRAW);

        glDrawArraysIndirect(GL_TRIANGLES, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeInvalidSizeElements : public DrawIndirectBase
{
    struct TWrongStructure
    {
        GLfloat count;
        GLuint primCount;
    };

    virtual std::string Title()
    {
        return "Negative: wrong structure - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call glDrawElementsIndirect with wrong structure";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectElements = {0, 0, 0, 0};
        indirectElements.count                     = static_cast<GLuint>(coords.size());
        indirectElements.primCount                 = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        TWrongStructure indirectElements2 = {0, 0};
        indirectElements2.count           = static_cast<GLfloat>(coords.size());
        indirectElements2.primCount       = 1;

        glDeleteBuffers(1, &_bufferIndirect);
        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure), &indirectElements2, GL_STATIC_DRAW);

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeStructureWrongOffsetArray : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: wrong offset - glDrawArrayIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call glDrawArrayIndirect with wrong offset";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawArraysIndirectCommand indirectArrays = {0, 0, 0, 0};
        indirectArrays.count                     = static_cast<GLuint>(coords.size());
        indirectArrays.primCount                 = 1;

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW);

        DIResult result;

        glDrawArraysIndirect(GL_TRIANGLES, (void *)(sizeof(DrawArraysIndirectCommand) * 2));
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        glDrawArraysIndirect(GL_TRIANGLES, (void *)(sizeof(GLuint)));
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _bufferIndirect;
};

template <typename api>
struct CNegativeStructureWrongOffsetElements : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: wrong offset - glDrawElementsIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call glDrawElementsIndirect with wrong structure";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Setup()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        return NO_ERROR;
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        CColorArray coords;
        PrimitiveGen(GL_TRIANGLES, 8, 8, coords);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);

        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0);
        glEnableVertexAttribArray(0);

        DrawElementsIndirectCommand indirectElements = {0, 0, 0, 0, 0};
        indirectElements.count                       = static_cast<GLuint>(coords.size());
        indirectElements.primCount                   = 1;

        CElementArray elements(coords.size(), 0);
        for (size_t i = 0; i < elements.size(); ++i)
        {
            elements[i] = static_cast<GLuint>(i);
        }

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0],
                     GL_STATIC_DRAW);

        DIResult result;

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)(sizeof(DrawElementsIndirectCommand) * 2));
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void *)(sizeof(GLuint)));
        if (glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }

        CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f));
        CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f));

        ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]);
        result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(),
                                         getWindowHeight()));

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeUnalignedOffset : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: unaligned offset - glDrawElementsIndirect and glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no system/driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call with unaligned offset (1, 3, 1023)";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Run()
    {
        _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true);
        if (!_program)
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        std::vector<GLuint> zarro(4096, 0);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);
        glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

        DIResult result;

        int offsets[] = {1, 3, 1023};
        for (size_t i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++)
        {
            glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, reinterpret_cast<void *>((uintptr_t)offsets[i]));
            if (glGetError() != GL_INVALID_VALUE)
            {
                result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
            }
            glDrawArraysIndirect(GL_TRIANGLES, reinterpret_cast<void *>((uintptr_t)offsets[i]));
            if (glGetError() != GL_INVALID_VALUE)
            {
                result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type";
            }
        }

        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        return NO_ERROR;
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect;
};

template <typename api>
struct CNegativeXFB : public DrawIndirectBase
{
    virtual std::string Title()
    {
        return "Negative: transform feedback active and not paused - glDrawElementsIndirect and glDrawArraysIndirect";
    }

    virtual std::string Purpose()
    {
        return "Verify that a driver sets error and no system/driver crash occurred";
    }

    virtual std::string Method()
    {
        return "Call with transform feedback active";
    }

    virtual std::string PassCriteria()
    {
        return "The test will pass if OpenGL errors reported and no driver crash occurred";
    }

    virtual long Run()
    {
        api::ES_Only();

        bool drawWithXFBAllowed = m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader");

        _program                 = CreateProgram(Vsh(), "", shaders::fshSimple<api>(), false);
        const GLchar *varyings[] = {"dataOut"};
        glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
        glLinkProgram(_program);
        if (!CheckProgram(_program))
        {
            return ERROR;
        }
        glUseProgram(_program);

        glGenVertexArrays(1, &_vao);
        glBindVertexArray(_vao);

        std::vector<GLuint> zarro(4096, 0);

        glGenBuffers(1, &_buffer);
        glBindBuffer(GL_ARRAY_BUFFER, _buffer);
        glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);

        glGenBuffers(1, &_bufferIndirect);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

        glGenBuffers(1, &_ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);

        glGenBuffers(1, &_xfb);
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfb);
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);

        DIResult result;

        //Without XFO
        glBeginTransformFeedback(GL_POINTS);

        glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
        if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }
        glDrawArraysIndirect(GL_POINTS, NULL);
        if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }
        glEndTransformFeedback();

        //With XFO
        glGenTransformFeedbacks(1, &_xfo);
        glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb);
        glBeginTransformFeedback(GL_POINTS);
        glPauseTransformFeedback();
        glResumeTransformFeedback();

        glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
        if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }
        glDrawArraysIndirect(GL_POINTS, NULL);
        if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION)
        {
            result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type";
        }
        glEndTransformFeedback();

        glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
        return result.code();
    }

    virtual long Cleanup()
    {
        glDisableVertexAttribArray(0);
        glUseProgram(0);
        glDeleteProgram(_program);
        glDeleteVertexArrays(1, &_vao);
        glDeleteBuffers(1, &_buffer);
        glDeleteBuffers(1, &_ebo);
        glDeleteBuffers(1, &_bufferIndirect);
        glDeleteBuffers(1, &_xfb);
        glDeleteTransformFeedbacks(1, &_xfo);
        return NO_ERROR;
    }

    std::string Vsh()
    {
        return api::glslVer() + NL "out highp vec4 dataOut;" NL "in vec4 i_vertex;" NL "void main() {" NL
                                   "  dataOut = i_vertex;" NL "  gl_Position = i_vertex;" NL "}";
    }

private:
    GLuint _program;
    GLuint _vao, _buffer, _ebo, _bufferIndirect, _xfo, _xfb;
};

} // namespace
DrawIndirectTestsGL40::DrawIndirectTestsGL40(glcts::Context &context) : TestCaseGroup(context, "draw_indirect", "")
{
}

DrawIndirectTestsGL40::~DrawIndirectTestsGL40(void)
{
}

void DrawIndirectTestsGL40::init()
{
    using namespace glcts;

    DILogger::setOutput(m_context.getTestContext().getLog());

    addChild(
        new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::GL>>));
    addChild(
        new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::GL>>));
    addChild(
        new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::GL>>));

    addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-buffer-unMap", TestSubcase::Create<CBufferMap<test_api::GL>>));
    addChild(
        new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
                             TestSubcase::Create<CBufferFlushMappedRange<test_api::GL>>));
    addChild(
        new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::GL>>));

    addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
                             TestSubcase::Create<CVBODrawArraysSingle<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
                             TestSubcase::Create<CVBODrawArraysMany<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
                             TestSubcase::Create<CVBODrawArraysInstancing<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
                             TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
                             TestSubcase::Create<CVBODrawElementsSingle<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
                             TestSubcase::Create<CVBODrawElementsMany<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
                             TestSubcase::Create<CVBODrawElementsInstancing<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
                             TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL>>));

    addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
                             TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
                             TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
                             TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
                             TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-simple",
                             TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
                             TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
                             TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
                             TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
                             TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::GL>>));

    addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
                             TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
                             TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::GL>>));

    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
                             TestSubcase::Create<CModeDrawArraysPoints<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
                             TestSubcase::Create<CModeDrawArraysLines<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
                             TestSubcase::Create<CModeDrawArraysLineStrip<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
                             TestSubcase::Create<CModeDrawArraysLineLoop<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
                             TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
                             TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
                             TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
                             TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
                             TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
                             TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::GL>>));

    addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
                             TestSubcase::Create<CModeDrawElementsPoints<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
                             TestSubcase::Create<CModeDrawElementsLines<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
                             TestSubcase::Create<CModeDrawElementsLineStrip<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
                             TestSubcase::Create<CModeDrawElementsLineLoop<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
                             TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
                             TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
                             TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
                             TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
                             TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::GL>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
                             TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::GL>>));

    addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
                             TestSubcase::Create<CTransformFeedbackArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
                             TestSubcase::Create<CTransformFeedbackElements<test_api::GL>>));

    addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
                             TestSubcase::Create<CPrimitiveRestartElements<test_api::GL>>));

    addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
                             TestSubcase::Create<CNegativeZeroBufferArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-noindirect-elements",
                             TestSubcase::Create<CNegativeZeroBufferElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
                             TestSubcase::Create<CNegativeInvalidModeArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
                             TestSubcase::Create<CNegativeInvalidModeElements<test_api::GL>>));
    addChild(
        new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-noVAO-elements",
                             TestSubcase::Create<CNegativeNoVAOElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
                             TestSubcase::Create<CNegativeBufferMappedArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
                             TestSubcase::Create<CNegativeBufferMappedElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-invalidType-elements",
                             TestSubcase::Create<CNegativeDataWrongElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-gshIncompatible-arrays",
                             TestSubcase::Create<CNegativeGshArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-gshIncompatible-elements",
                             TestSubcase::Create<CNegativeGshElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
                             TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
                             TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
                             TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
                             TestSubcase::Create<CNegativeInvalidSizeElements<test_api::GL>>));
    addChild(new TestSubcase(m_context, "negative-unalignedOffset",
                             TestSubcase::Create<CNegativeUnalignedOffset<test_api::GL>>));
}

DrawIndirectTestsGL43::DrawIndirectTestsGL43(glcts::Context &context) : TestCaseGroup(context, "draw_indirect_43", "")
{
}

DrawIndirectTestsGL43::~DrawIndirectTestsGL43(void)
{
}

void DrawIndirectTestsGL43::init()
{
    using namespace glcts;

    DILogger::setOutput(m_context.getTestContext().getLog());
    addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
                             TestSubcase::Create<CComputeShaderArray<test_api::GL>>));
    addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
                             TestSubcase::Create<CComputeShaderElements<test_api::GL>>));
}

DrawIndirectTestsES31::DrawIndirectTestsES31(glcts::Context &context) : TestCaseGroup(context, "draw_indirect", "")
{
}

DrawIndirectTestsES31::~DrawIndirectTestsES31(void)
{
}

void DrawIndirectTestsES31::init()
{
    using namespace glcts;

    DILogger::setOutput(m_context.getTestContext().getLog());

    addChild(
        new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::ES3>>));
    addChild(
        new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::ES3>>));
    addChild(
        new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::ES3>>));
    addChild(
        new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange",
                             TestSubcase::Create<CBufferFlushMappedRange<test_api::ES3>>));
    addChild(
        new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive",
                             TestSubcase::Create<CVBODrawArraysSingle<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives",
                             TestSubcase::Create<CVBODrawArraysMany<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-instancing",
                             TestSubcase::Create<CVBODrawArraysInstancing<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused",
                             TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive",
                             TestSubcase::Create<CVBODrawElementsSingle<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives",
                             TestSubcase::Create<CVBODrawElementsMany<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-instancing",
                             TestSubcase::Create<CVBODrawElementsInstancing<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused",
                             TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "basic-drawArrays-simple",
                             TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst",
                             TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset",
                             TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds",
                             TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-simple",
                             TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex",
                             TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-basevertex",
                             TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset",
                             TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds",
                             TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short",
                             TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte",
                             TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points",
                             TestSubcase::Create<CModeDrawArraysPoints<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines",
                             TestSubcase::Create<CModeDrawArraysLines<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip",
                             TestSubcase::Create<CModeDrawArraysLineStrip<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop",
                             TestSubcase::Create<CModeDrawArraysLineLoop<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip",
                             TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan",
                             TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency",
                             TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency",
                             TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency",
                             TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency",
                             TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "basic-mode-drawElements-points",
                             TestSubcase::Create<CModeDrawElementsPoints<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines",
                             TestSubcase::Create<CModeDrawElementsLines<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip",
                             TestSubcase::Create<CModeDrawElementsLineStrip<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop",
                             TestSubcase::Create<CModeDrawElementsLineLoop<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip",
                             TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan",
                             TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency",
                             TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency",
                             TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency",
                             TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency",
                             TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays",
                             TestSubcase::Create<CTransformFeedbackArray<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements",
                             TestSubcase::Create<CTransformFeedbackElements<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays",
                             TestSubcase::Create<CComputeShaderArray<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements",
                             TestSubcase::Create<CComputeShaderElements<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements",
                             TestSubcase::Create<CPrimitiveRestartElements<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "negative-noindirect-arrays",
                             TestSubcase::Create<CNegativeZeroBufferArray<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-noindirect-elements",
                             TestSubcase::Create<CNegativeZeroBufferElements<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-invalidMode-arrays",
                             TestSubcase::Create<CNegativeInvalidModeArray<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-invalidMode-elements",
                             TestSubcase::Create<CNegativeInvalidModeElements<test_api::ES3>>));
    addChild(
        new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-noVAO-elements",
                             TestSubcase::Create<CNegativeNoVAOElements<test_api::ES3>>));
    addChild(
        new TestSubcase(m_context, "negative-noVBO-arrays", TestSubcase::Create<CNegativeNoVBOArrays<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-noVBO-elements",
                             TestSubcase::Create<CNegativeNoVBOElements<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays",
                             TestSubcase::Create<CNegativeBufferMappedArray<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-bufferMapped-elements",
                             TestSubcase::Create<CNegativeBufferMappedElements<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-invalidType-elements",
                             TestSubcase::Create<CNegativeDataWrongElements<test_api::ES3>>));

    addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays",
                             TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-wrongOffset-elements",
                             TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-invalidSize-arrays",
                             TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-invalidSize-elements",
                             TestSubcase::Create<CNegativeInvalidSizeElements<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-unalignedOffset",
                             TestSubcase::Create<CNegativeUnalignedOffset<test_api::ES3>>));
    addChild(new TestSubcase(m_context, "negative-xfb", TestSubcase::Create<CNegativeXFB<test_api::ES3>>));
}
} // namespace glcts
