/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-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
 */ /*-------------------------------------------------------------------*/

/**
 */ /*!
 * \file  gl4cDirectStateAccessVertexArraysTests.cpp
 * \brief Conformance tests for the Direct State Access feature functionality (Vertex Array Objects access part).
 */ /*-----------------------------------------------------------------------------------------------------------*/

/* Includes. */
#include "gl4cDirectStateAccessTests.hpp"

#include "deSharedPtr.hpp"

#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"

#include "tcuFuzzyImageCompare.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"

#include "glw.h"
#include "glwFunctions.hpp"

#include <algorithm>
#include <climits>
#include <cmath>
#include <set>
#include <sstream>
#include <stack>

namespace gl4cts
{
namespace DirectStateAccess
{
namespace VertexArrays
{
/******************************** Creation Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_creation", "Vertex Array Objects Creation Test")
{
    /* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* VertexArrays' objects */
    static const glw::GLuint vertex_arrays_count = 2;

    glw::GLuint vertex_arrays_legacy[vertex_arrays_count] = {};
    glw::GLuint vertex_arrays_dsa[vertex_arrays_count]    = {};

    try
    {
        /* Check legacy state creation. */
        gl.genVertexArrays(vertex_arrays_count, vertex_arrays_legacy);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed");

        for (glw::GLuint i = 0; i < vertex_arrays_count; ++i)
        {
            if (gl.isVertexArray(vertex_arrays_legacy[i]))
            {
                is_ok = false;

                /* Log. */
                m_context.getTestContext().getLog()
                    << tcu::TestLog::Message
                    << "GenVertexArrays has created default objects, but it should create only a names."
                    << tcu::TestLog::EndMessage;
            }
        }

        /* Check direct state creation. */
        gl.createVertexArrays(vertex_arrays_count, vertex_arrays_dsa);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays have failed");

        for (glw::GLuint i = 0; i < vertex_arrays_count; ++i)
        {
            if (!gl.isVertexArray(vertex_arrays_dsa[i]))
            {
                is_ok = false;

                /* Log. */
                m_context.getTestContext().getLog()
                    << tcu::TestLog::Message << "CreateVertexArrays has not created default objects."
                    << tcu::TestLog::EndMessage;
            }
        }
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    for (glw::GLuint i = 0; i < vertex_arrays_count; ++i)
    {
        if (vertex_arrays_legacy[i])
        {
            gl.deleteVertexArrays(1, &vertex_arrays_legacy[i]);

            vertex_arrays_legacy[i] = 0;
        }

        if (vertex_arrays_dsa[i])
        {
            gl.deleteVertexArrays(1, &vertex_arrays_dsa[i]);

            vertex_arrays_dsa[i] = 0;
        }
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/******************************** Vertex Array Object Enable Disable Attributes Test Implementation   ********************************/

/** @brief Vertex Array Object Enable Disable Attributes Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
EnableDisableAttributesTest::EnableDisableAttributesTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_enable_disable_attributes",
                     "Vertex Array Objects Enable Disable Attributes Test")
    , m_po_even(0)
    , m_po_odd(0)
    , m_vao(0)
    , m_bo(0)
    , m_bo_xfb(0)
    , m_max_attributes(16) /* Required Minimum: OpenGL 4.5 Table 23.57: Implementation Dependent Vertex Shader Limits */
{
    /* Intentionally left blank. */
}

/** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult EnableDisableAttributesTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_max_attributes);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, ...) have failed");

        m_po_even = PrepareProgram(false);
        m_po_odd  = PrepareProgram(true);

        PrepareVAO();
        PrepareXFB();

        is_ok &= TurnOnAttributes(true, false);
        is_ok &= DrawAndCheck(false);

        is_ok &= TurnOnAttributes(false, true);
        is_ok &= DrawAndCheck(true);
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    Clean();

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

glw::GLuint EnableDisableAttributesTest::PrepareProgram(const bool bind_even_or_odd)
{
    /* Preprocess vertex shader sources. */
    std::string declarations = "";
    std::string copies       = "    sum = 0;\n";

    for (glw::GLint i = (glw::GLint)(bind_even_or_odd); i < m_max_attributes; i += 2)
    {
        declarations.append((std::string("in int a_").append(Utilities::itoa(i))).append(";\n"));
        copies.append((std::string("    sum += a_").append(Utilities::itoa(i))).append(";\n"));
    }

    std::string vs_template(s_vertex_shader_template);

    std::string vs_source = Utilities::replace(vs_template, "DECLARATION_TEMPLATE", declarations);
    vs_source             = Utilities::replace(vs_source, "COPY_TEMPLATE", copies);

    /* Build and compile. */
    return BuildProgram(vs_source.c_str(), bind_even_or_odd);
}

/** @brief Build test's GLSL program.
 *
 *  @note The function may throw if unexpected error has occured.
 */
glw::GLuint EnableDisableAttributesTest::BuildProgram(const char *vertex_shader, const bool bind_even_or_odd)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    struct Shader
    {
        glw::GLchar const *const source;
        glw::GLenum const type;
        glw::GLuint id;
    } shader[] = {{vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};

    glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);

    glw::GLuint po = 0;

    try
    {
        /* Create program. */
        po = gl.createProgram();
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

        /* Shader compilation. */

        for (glw::GLuint i = 0; i < shader_count; ++i)
        {
            if (DE_NULL != shader[i].source)
            {
                shader[i].id = gl.createShader(shader[i].type);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

                gl.attachShader(po, shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

                gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

                gl.compileShader(shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

                glw::GLint status = GL_FALSE;

                gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                if (GL_FALSE == status)
                {
                    glw::GLint log_size = 0;
                    gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                    glw::GLchar *log_text = new glw::GLchar[log_size];

                    gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "Shader compilation has failed.\n"
                        << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
                        << "Shader compilation error log:\n"
                        << log_text << "\n"
                        << "Shader source code:\n"
                        << shader[i].source << "\n"
                        << tcu::TestLog::EndMessage;

                    delete[] log_text;

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

                    throw 0;
                }
            }
        }

        /* Transform Feedback setup. */
        static const glw::GLchar *xfb_varying = "sum";

        gl.transformFeedbackVaryings(po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        for (glw::GLint i = (glw::GLint)(bind_even_or_odd); i < m_max_attributes; i += 2)
        {
            std::string attribute = std::string("a_").append(Utilities::itoa(i));

            gl.bindAttribLocation(po, i, attribute.c_str());
            GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed.");
        }

        /* Link. */
        gl.linkProgram(po);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        glw::GLint status = GL_FALSE;

        gl.getProgramiv(po, GL_LINK_STATUS, &status);

        if (GL_TRUE == status)
        {
            for (glw::GLuint i = 0; i < shader_count; ++i)
            {
                if (shader[i].id)
                {
                    gl.detachShader(po, shader[i].id);

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
                }
            }
        }
        else
        {
            glw::GLint log_size = 0;

            gl.getProgramiv(po, GL_INFO_LOG_LENGTH, &log_size);

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

            glw::GLchar *log_text = new glw::GLchar[log_size];

            gl.getProgramInfoLog(po, log_size, NULL, &log_text[0]);

            m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
                                                << log_text << "\n"
                                                << tcu::TestLog::EndMessage;

            delete[] log_text;

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

            throw 0;
        }
    }
    catch (...)
    {
        if (po)
        {
            gl.deleteProgram(po);

            po = 0;
        }
    }

    for (glw::GLuint i = 0; i < shader_count; ++i)
    {
        if (0 != shader[i].id)
        {
            gl.deleteShader(shader[i].id);

            shader[i].id = 0;
        }
    }

    if (0 == po)
    {
        throw 0;
    }

    return po;
}

/** @brief Prepare vertex array object for the test.
 */
void EnableDisableAttributesTest::PrepareVAO()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* VAO creation. */
    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    glw::GLint *reference_data = new glw::GLint[m_max_attributes];

    if (DE_NULL == reference_data)
    {
        throw 0;
    }

    for (glw::GLint i = 0; i < m_max_attributes; ++i)
    {
        reference_data[i] = i;
    }

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint) * m_max_attributes, reference_data, GL_STATIC_DRAW);

    delete[] reference_data;

    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    /* VAO setup. */
    for (glw::GLint i = 0; i < m_max_attributes; ++i)
    {
        gl.vertexAttribIPointer(i, 1, GL_INT, static_cast<glw::GLsizei>(sizeof(glw::GLint) * m_max_attributes),
                                glu::BufferOffsetAsPointer(i * sizeof(glw::GLint)));

        GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
    }
}

/** @brief Prepare buffer object for test GLSL program transform feedback results.
 */
void EnableDisableAttributesTest::PrepareXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    /* Preparing storage. */
    gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
}

/** @brief Draw test program, fetch transform feedback results and compare them with expected values.
 *
 *  @param [in] bind_even_or_odd         Even or odd attribute are enabled.
 *
 *  @return True if expected results are equal to returned by XFB, false otherwise.
 */
bool EnableDisableAttributesTest::DrawAndCheck(bool bind_even_or_odd)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup state. */
    gl.useProgram(bind_even_or_odd ? m_po_odd : m_po_even);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

    /* Draw. */
    gl.drawArrays(GL_POINTS, 0, 1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

    /* State reset. */
    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

    /* Result query. */
    glw::GLint *result_ptr = (glw::GLint *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

    glw::GLint result = *result_ptr;

    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

    /* Check result and return. */
    if (bind_even_or_odd)
    {
        glw::GLint reference_sum = 0;

        for (glw::GLint i = 1; i < m_max_attributes; i += 2)
        {
            reference_sum += i;
        }

        if (reference_sum == result)
        {
            return true;
        }
    }
    else
    {
        glw::GLint reference_sum = 0;

        for (glw::GLint i = 0; i < m_max_attributes; i += 2)
        {
            reference_sum += i;
        }

        if (reference_sum == result)
        {
            return true;
        }
    }

    return false;
}

/** @brief Turn on even or odd attributes (up to m_max_attributes) using EnableVertexArrayAttrib function.
 *
 *  @param [in] enable_even         Turn on even attribute indexes.
 *  @param [in] enable_odd          Turn on odd  attribute indexes.
 *
 *  @return True if EnableVertexArrayAttrib does not generate any error, false otherwise.
 */
bool EnableDisableAttributesTest::TurnOnAttributes(bool enable_even, bool enable_odd)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.bindVertexArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    for (glw::GLint i = 0; i < m_max_attributes; ++i)
    {
        bool disable = true;

        if (i % 2) /* if odd */
        {
            if (enable_odd)
            {
                gl.enableVertexArrayAttrib(m_vao, i);

                if (glw::GLenum error = gl.getError())
                {
                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "glEnableVertexArrayAttrib generated error "
                        << glu::getErrorStr(error) << " when called with VAO " << m_vao << " and index " << i << "."
                        << tcu::TestLog::EndMessage;

                    return false;
                }

                disable = false;
            }
        }
        else
        {
            if (enable_even)
            {
                gl.enableVertexArrayAttrib(m_vao, i);

                if (glw::GLenum error = gl.getError())
                {
                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "glEnableVertexArrayAttrib generated error "
                        << glu::getErrorStr(error) << " when called with VAO " << m_vao << " and index " << i << "."
                        << tcu::TestLog::EndMessage;

                    return false;
                }

                disable = false;
            }
        }

        if (disable)
        {
            gl.disableVertexArrayAttrib(m_vao, i);

            if (glw::GLenum error = gl.getError())
            {
                m_context.getTestContext().getLog()
                    << tcu::TestLog::Message << "glDisableVertexArrayAttrib generated error " << glu::getErrorStr(error)
                    << " when called with VAO " << m_vao << " and index " << i << "." << tcu::TestLog::EndMessage;

                return false;
            }
        }
    }

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    return true;
}

/** @brief Clean GL objects. */
void EnableDisableAttributesTest::Clean()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.useProgram(0);

    if (m_po_even)
    {
        gl.deleteProgram(m_po_even);

        m_po_even = 0;
    }

    if (m_po_odd)
    {
        gl.deleteProgram(m_po_odd);

        m_po_odd = 0;
    }

    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo)
    {
        gl.deleteBuffers(1, &m_bo);

        m_bo = 0;
    }

    if (m_bo_xfb)
    {
        gl.deleteBuffers(1, &m_bo_xfb);

        m_bo_xfb = 0;
    }

    if (m_max_attributes)
    {
        m_max_attributes =
            16; /* OpenGL 4.5 Required Minimum Table 23.57: Implementation Dependent Vertex Shader Limits */
    }

    while (gl.getError())
        ;
}

std::string Utilities::itoa(glw::GLuint i)
{
    std::string s = "";

    std::stringstream ss;

    ss << i;

    s = ss.str();

    return s;
}

std::string Utilities::replace(const std::string &src, const std::string &key, const std::string &value)
{
    size_t pos      = 0;
    std::string dst = src;

    while (std::string::npos != (pos = dst.find(key, pos)))
    {
        dst.replace(pos, key.length(), value);
        pos += key.length();
    }

    return dst;
}

const glw::GLchar EnableDisableAttributesTest::s_vertex_shader_template[] = "#version 450\n"
                                                                            "\n"
                                                                            "DECLARATION_TEMPLATE"
                                                                            "out int sum;\n"
                                                                            "\n"
                                                                            "void main()\n"
                                                                            "{\n"
                                                                            "COPY_TEMPLATE"
                                                                            "}\n";

const glw::GLchar EnableDisableAttributesTest::s_fragment_shader[] = "#version 450\n"
                                                                     "\n"
                                                                     "out vec4 color;\n"
                                                                     "\n"
                                                                     "void main()\n"
                                                                     "{\n"
                                                                     "    color = vec4(1.0);"
                                                                     "}\n";

/******************************** Vertex Array Object Element Buffer Test Implementation   ********************************/

/** @brief Vertex Array Object Element Buffer Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ElementBufferTest::ElementBufferTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_element_buffer", "Vertex Array Objects Element Buffer Test")
    , m_po(0)
    , m_vao(0)
    , m_bo_array(0)
    , m_bo_elements(0)
    , m_bo_xfb(0)
{
    /* Intentionally left blank. */
}

/** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ElementBufferTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        PrepareProgram();
        is_ok &= PrepareVAO();
        PrepareXFB();
        is_ok &= DrawAndCheck();
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    Clean();

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Build test's GLSL program.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void ElementBufferTest::PrepareProgram()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    struct Shader
    {
        glw::GLchar const *const source;
        glw::GLenum const type;
        glw::GLuint id;
    } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};

    glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);

    try
    {
        /* Create program. */
        m_po = gl.createProgram();
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

        /* Shader compilation. */

        for (glw::GLuint i = 0; i < shader_count; ++i)
        {
            if (DE_NULL != shader[i].source)
            {
                shader[i].id = gl.createShader(shader[i].type);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

                gl.attachShader(m_po, shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

                gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

                gl.compileShader(shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

                glw::GLint status = GL_FALSE;

                gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                if (GL_FALSE == status)
                {
                    glw::GLint log_size = 0;
                    gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                    glw::GLchar *log_text = new glw::GLchar[log_size];

                    gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "Shader compilation has failed.\n"
                        << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
                        << "Shader compilation error log:\n"
                        << log_text << "\n"
                        << "Shader source code:\n"
                        << shader[i].source << "\n"
                        << tcu::TestLog::EndMessage;

                    delete[] log_text;

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

                    throw 0;
                }
            }
        }

        /* Transform Feedback setup. */
        static const glw::GLchar *xfb_varying = "result";

        gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        /* Link. */
        gl.linkProgram(m_po);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        glw::GLint status = GL_FALSE;

        gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

        if (GL_TRUE == status)
        {
            for (glw::GLuint i = 0; i < shader_count; ++i)
            {
                if (shader[i].id)
                {
                    gl.detachShader(m_po, shader[i].id);

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
                }
            }
        }
        else
        {
            glw::GLint log_size = 0;

            gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

            glw::GLchar *log_text = new glw::GLchar[log_size];

            gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

            m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
                                                << log_text << "\n"
                                                << tcu::TestLog::EndMessage;

            delete[] log_text;

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

            throw 0;
        }
    }
    catch (...)
    {
        if (m_po)
        {
            gl.deleteProgram(m_po);

            m_po = 0;
        }
    }

    for (glw::GLuint i = 0; i < shader_count; ++i)
    {
        if (0 != shader[i].id)
        {
            gl.deleteShader(shader[i].id);

            shader[i].id = 0;
        }
    }

    if (0 == m_po)
    {
        throw 0;
    }
}

/** @brief Prepare vertex array object for the test of VertexArrayElementBuffer function.
 *
 *  @return True if function VertexArrayElementBuffer* does not generate any error.
 */
bool ElementBufferTest::PrepareVAO()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* VAO creation. */
    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Array buffer creation. */
    glw::GLint array_data[3] = {2, 1, 0};

    gl.genBuffers(1, &m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.vertexAttribIPointer(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0, NULL);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");

    gl.enableVertexAttribArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.bindVertexArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Element buffer creation. */
    glw::GLuint elements_data[3] = {2, 1, 0};

    gl.genBuffers(1, &m_bo_elements);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_elements);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements_data), elements_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.vertexArrayElementBuffer(m_vao, m_bo_elements);

    if (glw::GLenum error = gl.getError())
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "VertexArrayElementBuffer has unexpectedly generated "
            << glu::getErrorStr(error) << "error. Test fails.\n"
            << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/** @brief Prepare buffer object for test GLSL program transform feedback results.
 */
void ElementBufferTest::PrepareXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    /* Preparing storage. */
    gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
}

/** @brief Draw test program, fetch transform feedback results and compare them with expected values.
 *
 *  @return True if expected results are equal to returned by XFB, false otherwise.
 */
bool ElementBufferTest::DrawAndCheck()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup state. */
    gl.useProgram(m_po);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

    /* Draw. */
    gl.drawElements(GL_POINTS, 3, GL_UNSIGNED_INT, NULL);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

    /* State reset. */
    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

    /* Result query. */
    glw::GLint *result_ptr = (glw::GLint *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

    glw::GLint result[3] = {result_ptr[0], result_ptr[1], result_ptr[2]};

    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

    /* Check result and return. */
    for (glw::GLint i = 0; i < 3; ++i)
    {
        if (i != result[i])
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "Result vector is equal to [" << result[0] << ", " << result[1] << ", "
                << result[2] << "], but [0, 1, 2] was expected." << tcu::TestLog::EndMessage;

            return false;
        }
    }

    return true;
}

/** @brief Clean GL objects. */
void ElementBufferTest::Clean()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.useProgram(0);

    if (m_po)
    {
        gl.deleteProgram(m_po);

        m_po = 0;
    }

    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo_array)
    {
        gl.deleteBuffers(1, &m_bo_array);

        m_bo_array = 0;
    }

    if (m_bo_elements)
    {
        gl.deleteBuffers(1, &m_bo_elements);

        m_bo_elements = 0;
    }

    if (m_bo_xfb)
    {
        gl.deleteBuffers(1, &m_bo_xfb);

        m_bo_xfb = 0;
    }

    while (gl.getError())
        ;
}

const glw::GLchar ElementBufferTest::s_vertex_shader[] = "#version 450\n"
                                                         "\n"
                                                         "in int a;"
                                                         "out int result;\n"
                                                         "\n"
                                                         "void main()\n"
                                                         "{\n"
                                                         "    gl_Position = vec4(1.0);\n"
                                                         "    result = a;"
                                                         "}\n";

const glw::GLchar ElementBufferTest::s_fragment_shader[] = "#version 450\n"
                                                           "\n"
                                                           "out vec4 color;\n"
                                                           "\n"
                                                           "void main()\n"
                                                           "{\n"
                                                           "    color = vec4(1.0);"
                                                           "}\n";

/******************************** Vertex Array Object Vertex Buffer and Buffers Test Implementation   ********************************/

/** @brief Vertex Array Object Element Buffer Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
VertexBuffersTest::VertexBuffersTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_vertex_buffers", "Vertex Array Object Vertex Buffer and Buffers Test")
    , m_po(0)
    , m_vao(0)
    , m_bo_array_0(0)
    , m_bo_array_1(0)
    , m_bo_xfb(0)
{
    /* Intentionally left blank. */
}

/** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult VertexBuffersTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        PrepareProgram();
        is_ok &= PrepareVAO(false);
        PrepareXFB();
        is_ok &= DrawAndCheck();
        Clean();

        PrepareProgram();
        is_ok &= PrepareVAO(true);
        PrepareXFB();
        is_ok &= DrawAndCheck();
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    Clean();

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Build test's GLSL program.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void VertexBuffersTest::PrepareProgram()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    struct Shader
    {
        glw::GLchar const *const source;
        glw::GLenum const type;
        glw::GLuint id;
    } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};

    glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);

    try
    {
        /* Create program. */
        m_po = gl.createProgram();
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

        /* Shader compilation. */

        for (glw::GLuint i = 0; i < shader_count; ++i)
        {
            if (DE_NULL != shader[i].source)
            {
                shader[i].id = gl.createShader(shader[i].type);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

                gl.attachShader(m_po, shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

                gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

                gl.compileShader(shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

                glw::GLint status = GL_FALSE;

                gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                if (GL_FALSE == status)
                {
                    glw::GLint log_size = 0;
                    gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                    glw::GLchar *log_text = new glw::GLchar[log_size];

                    gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "Shader compilation has failed.\n"
                        << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
                        << "Shader compilation error log:\n"
                        << log_text << "\n"
                        << "Shader source code:\n"
                        << shader[i].source << "\n"
                        << tcu::TestLog::EndMessage;

                    delete[] log_text;

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

                    throw 0;
                }
            }
        }

        /* Transform Feedback setup. */
        static const glw::GLchar *xfb_varying = "result";

        gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        /* Link. */
        gl.linkProgram(m_po);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        glw::GLint status = GL_FALSE;

        gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

        if (GL_TRUE == status)
        {
            for (glw::GLuint i = 0; i < shader_count; ++i)
            {
                if (shader[i].id)
                {
                    gl.detachShader(m_po, shader[i].id);

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
                }
            }
        }
        else
        {
            glw::GLint log_size = 0;

            gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

            glw::GLchar *log_text = new glw::GLchar[log_size];

            gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

            m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
                                                << log_text << "\n"
                                                << tcu::TestLog::EndMessage;

            delete[] log_text;

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

            throw 0;
        }
    }
    catch (...)
    {
        if (m_po)
        {
            gl.deleteProgram(m_po);

            m_po = 0;
        }
    }

    for (glw::GLuint i = 0; i < shader_count; ++i)
    {
        if (0 != shader[i].id)
        {
            gl.deleteShader(shader[i].id);

            shader[i].id = 0;
        }
    }

    if (0 == m_po)
    {
        throw 0;
    }
}

/** @brief Prepare vertex array object for the test of gl.vertexArrayVertexBuffer* functions.
 *
 *  @param [in] use_multiple_buffers_function    Use gl.vertexArrayVertexBuffers instead of gl.vertexArrayVertexBuffer.
 *
 *  @return True if functions gl.vertexArrayVertexBuffer* do not generate any error.
 */
bool VertexBuffersTest::PrepareVAO(bool use_multiple_buffers_function)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* VAO creation. */
    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Array buffer 0 creation. */
    glw::GLint array_data_0[4] = {0, 2, 1, 3};

    gl.genBuffers(1, &m_bo_array_0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_0), array_data_0, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0);

    gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1);

    gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_0"), 1, GL_INT, 0);

    gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_1"), 1, GL_INT, 0);

    if (use_multiple_buffers_function)
    {
        const glw::GLuint buffers[2]          = {m_bo_array_0, m_bo_array_0};
        static const glw::GLintptr offsets[2] = {0, sizeof(glw::GLint)};
        static const glw::GLsizei strides[2]  = {sizeof(glw::GLint) * 2, sizeof(glw::GLint) * 2};

        gl.vertexArrayVertexBuffers(m_vao, 0, 2, buffers, offsets, strides);

        if (glw::GLenum error = gl.getError())
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "VertexArrayVertexBuffers has unexpectedly generated "
                << glu::getErrorStr(error) << "error. Test fails.\n"
                << tcu::TestLog::EndMessage;

            return false;
        }
    }
    else
    {
        gl.vertexArrayVertexBuffer(m_vao, 0, m_bo_array_0, (glw::GLintptr)NULL, sizeof(glw::GLint) * 2);

        if (glw::GLenum error = gl.getError())
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "VertexArrayVertexBuffer has unexpectedly generated "
                << glu::getErrorStr(error) << "error. Test fails.\n"
                << tcu::TestLog::EndMessage;

            return false;
        }

        gl.vertexArrayVertexBuffer(m_vao, 1, m_bo_array_0, sizeof(glw::GLint), sizeof(glw::GLint) * 2);

        if (glw::GLenum error = gl.getError())
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "VertexArrayVertexBuffer has unexpectedly generated "
                << glu::getErrorStr(error) << "error. Test fails.\n"
                << tcu::TestLog::EndMessage;

            return false;
        }
    }

    gl.enableVertexAttribArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.enableVertexAttribArray(1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    /* Array buffer 1 creation. */
    glw::GLint array_data_1[2] = {4, 5};

    gl.genBuffers(1, &m_bo_array_1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_1), array_data_1, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_2"), 2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");

    gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_2"), 1, GL_INT, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");

    if (use_multiple_buffers_function)
    {
        glw::GLintptr offset = (glw::GLintptr)NULL;
        glw::GLsizei stride  = sizeof(glw::GLint);

        gl.vertexArrayVertexBuffers(m_vao, 2, 1, &m_bo_array_1, &offset, &stride);

        if (glw::GLenum error = gl.getError())
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "VertexArrayVertexBuffers has unexpectedly generated "
                << glu::getErrorStr(error) << "error. Test fails.\n"
                << tcu::TestLog::EndMessage;

            return false;
        }
    }
    else
    {
        gl.vertexArrayVertexBuffer(m_vao, 2, m_bo_array_1, (glw::GLintptr)NULL, sizeof(glw::GLint));

        if (glw::GLenum error = gl.getError())
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "VertexArrayVertexBuffer has unexpectedly generated "
                << glu::getErrorStr(error) << "error. Test fails.\n"
                << tcu::TestLog::EndMessage;

            return false;
        }
    }

    gl.enableVertexAttribArray(2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.bindVertexArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    return true;
}

/** @brief Prepare buffer object for test GLSL program transform feedback results.
 */
void VertexBuffersTest::PrepareXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    /* Preparing storage. */
    gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
}

/** @brief Draw test program, fetch transform feedback results and compare them with expected values.
 *
 *  @return True if expected results are equal to returned by XFB, false otherwise.
 */
bool VertexBuffersTest::DrawAndCheck()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup state. */
    gl.useProgram(m_po);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

    /* Draw. */
    gl.drawArrays(GL_POINTS, 0, 2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

    /* State reset. */
    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

    /* Result query. */
    glw::GLint *result_ptr = (glw::GLint *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

    glw::GLint result[2] = {result_ptr[0], result_ptr[1]};

    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

    static const glw::GLint reference[2] = {0 + 2 + 4, 1 + 3 + 5};

    /* Check result and return. */
    for (glw::GLint i = 0; i < 2; ++i)
    {
        if (reference[i] != result[i])
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "Result vector is equal to [" << result[0] << ", " << result[1]
                << "], but [" << reference[0] << ", " << reference[1] << "] was expected." << tcu::TestLog::EndMessage;

            return false;
        }
    }

    return true;
}

/** @brief Clean GL objects. */
void VertexBuffersTest::Clean()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.useProgram(0);

    if (m_po)
    {
        gl.deleteProgram(m_po);

        m_po = 0;
    }

    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo_array_0)
    {
        gl.deleteBuffers(1, &m_bo_array_0);

        m_bo_array_0 = 0;
    }

    if (m_bo_array_1)
    {
        gl.deleteBuffers(1, &m_bo_array_1);

        m_bo_array_1 = 0;
    }

    if (m_bo_xfb)
    {
        gl.deleteBuffers(1, &m_bo_xfb);

        m_bo_xfb = 0;
    }

    while (gl.getError())
        ;
}

const glw::GLchar VertexBuffersTest::s_vertex_shader[] = "#version 450\n"
                                                         "\n"
                                                         "in  int a_0;"
                                                         "in  int a_1;"
                                                         "in  int a_2;"
                                                         "\n"
                                                         "out int result;\n"
                                                         "\n"
                                                         "void main()\n"
                                                         "{\n"
                                                         "    gl_Position = vec4(1.0);\n"
                                                         "    result = a_0 + a_1 + a_2;"
                                                         "}\n";

const glw::GLchar VertexBuffersTest::s_fragment_shader[] = "#version 450\n"
                                                           "\n"
                                                           "out vec4 color;\n"
                                                           "\n"
                                                           "void main()\n"
                                                           "{\n"
                                                           "    color = vec4(1.0);"
                                                           "}\n";

/******************************** Vertex Array Object Attribute Format Test Implementation   ********************************/

/** @brief Vertex Array Object Element Buffer Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
AttributeFormatTest::AttributeFormatTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_attribute_format", "Vertex Array Object Attribute Format Test")
    , m_po(0)
    , m_vao(0)
    , m_bo_array(0)
    , m_bo_xfb(0)
{
    /* Intentionally left blank. */
}

/** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult AttributeFormatTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        PrepareXFB();

        /* Test floating function. */
        for (glw::GLuint i = 1; i <= 4 /* max size */; ++i)
        {
            PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);

            is_ok &= PrepareVAO<glw::GLfloat>(i, GL_FLOAT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, true, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, true);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
            is_ok &= DrawAndCheck<glw::GLfloat>(i, false);

            CleanVAO();

            CleanProgram();
        }

        for (glw::GLuint i = 1; i <= 2 /* max size */; ++i)
        {
            PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE);

            is_ok &= PrepareVAO<glw::GLdouble>(i, GL_DOUBLE, false, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE);
            is_ok &= DrawAndCheck<glw::GLdouble>(i, false);

            CleanProgram();
            CleanVAO();
        }

        for (glw::GLuint i = 1; i <= 4 /* max size */; ++i)
        {
            PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);

            is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
            is_ok &= DrawAndCheck<glw::GLint>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
            is_ok &= DrawAndCheck<glw::GLint>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
            is_ok &= DrawAndCheck<glw::GLint>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
            is_ok &= DrawAndCheck<glw::GLint>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
            is_ok &= DrawAndCheck<glw::GLint>(i, false);

            CleanVAO();

            is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
            is_ok &= DrawAndCheck<glw::GLint>(i, false);

            CleanVAO();

            CleanProgram();
        }
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    CleanProgram();
    CleanVAO();
    CleanXFB();

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Build test's GLSL program.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void AttributeFormatTest::PrepareProgram(glw::GLint size, AtributeFormatFunctionType function_selector)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    struct Shader
    {
        glw::GLchar const *source[3];
        glw::GLuint const count;
        glw::GLenum const type;
        glw::GLuint id;
    } shader[] = {
        {{s_vertex_shader_head, s_vertex_shader_declaration[function_selector][size - 1], s_vertex_shader_body},
         3,
         GL_VERTEX_SHADER,
         0},
        {{s_fragment_shader, DE_NULL, DE_NULL}, 1, GL_FRAGMENT_SHADER, 0}};

    glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);

    try
    {
        /* Create program. */
        m_po = gl.createProgram();
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

        /* Shader compilation. */

        for (glw::GLuint i = 0; i < shader_count; ++i)
        {
            {
                shader[i].id = gl.createShader(shader[i].type);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

                gl.attachShader(m_po, shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

                gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

                gl.compileShader(shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

                glw::GLint status = GL_FALSE;

                gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                if (GL_FALSE == status)
                {
                    glw::GLint log_size = 0;
                    gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                    glw::GLchar *log_text = new glw::GLchar[log_size];

                    gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "Shader compilation has failed.\n"
                        << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
                        << "Shader compilation error log:\n"
                        << log_text << "\n"
                        << "Shader source code:\n"
                        << shader[i].source << "\n"
                        << tcu::TestLog::EndMessage;

                    delete[] log_text;

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

                    throw 0;
                }
            }
        }

        /* Transform Feedback setup. */
        static const glw::GLchar *xfb_varying = "result";

        gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        /* Link. */
        gl.linkProgram(m_po);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        glw::GLint status = GL_FALSE;

        gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

        if (GL_TRUE == status)
        {
            for (glw::GLuint i = 0; i < shader_count; ++i)
            {
                if (shader[i].id)
                {
                    gl.detachShader(m_po, shader[i].id);

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
                }
            }
        }
        else
        {
            glw::GLint log_size = 0;

            gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

            glw::GLchar *log_text = new glw::GLchar[log_size];

            gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

            m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
                                                << log_text << "\n"
                                                << tcu::TestLog::EndMessage;

            delete[] log_text;

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

            throw 0;
        }
    }
    catch (...)
    {
        if (m_po)
        {
            gl.deleteProgram(m_po);

            m_po = 0;
        }
    }

    for (glw::GLuint i = 0; i < shader_count; ++i)
    {
        if (0 != shader[i].id)
        {
            gl.deleteShader(shader[i].id);

            shader[i].id = 0;
        }
    }

    if (0 == m_po)
    {
        throw 0;
    }
}

template <>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLuint>()
{
    return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLuint) - 4 /* 1.0 / 16.0 */));
}

template <>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLushort>()
{
    return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLushort) - 4 /* 1.0 / 16.0 */));
}

template <>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLubyte>()
{
    return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLubyte) - 4 /* 1.0 / 16.0 */));
}

template <>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLint>()
{
    return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLint) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
}

template <>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLshort>()
{
    return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLshort) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
}

template <>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLbyte>()
{
    return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLbyte) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
}

template <typename T>
glw::GLdouble AttributeFormatTest::NormalizationScaleFactor()
{
    return 1.0; /* Rest of the types cannot be normalized. */
}

/** @brief Prepare vertex array object for the test of VertexArrayAttrib*Format function.
 *
 *  @param [in] size                Size passed to VertexArrayAttrib*Format.
 *  @param [in] type_gl_name        Type passed to VertexArrayAttrib*Format.
 *  @param [in] function_selector   Selects one of VertexArrayAttrib*Format functions.
 *
 *  @return True if function VertexArrayAttrib*Format does not generate any error.
 */
template <typename T>
bool AttributeFormatTest::PrepareVAO(glw::GLint size, glw::GLenum type_gl_name, bool normalized,
                                     AtributeFormatFunctionType function_selector)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* VAO creation. */
    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Array buffer 0 creation. */

    const glw::GLdouble scale = normalized ? NormalizationScaleFactor<T>() : 1.0;

    const T array_data[16] = {(T)(0.0 * scale),  (T)(1.0 * scale),  (T)(2.0 * scale),  (T)(3.0 * scale),
                              (T)(4.0 * scale),  (T)(5.0 * scale),  (T)(6.0 * scale),  (T)(7.0 * scale),
                              (T)(8.0 * scale),  (T)(9.0 * scale),  (T)(10.0 * scale), (T)(11.0 * scale),
                              (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale)};

    gl.genBuffers(1, &m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    /* Attribute setup. */
    gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");

    gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");

    /* Tested attribute format setup. */
    switch (function_selector)
    {
    case ATTRIBUTE_FORMAT_FUNCTION_FLOAT:
        gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, normalized, 0);
        gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, normalized, 0);
        break;

    case ATTRIBUTE_FORMAT_FUNCTION_DOUBLE:
        gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0);
        gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0);
        break;

    case ATTRIBUTE_FORMAT_FUNCTION_INTEGER:
        gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0);
        gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0);
        break;
    default:
        throw 0;
    }

    if (glw::GLenum error = gl.getError())
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message
            << ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ?
                    "VertexArrayAttribFormat" :
                    ((ATTRIBUTE_FORMAT_FUNCTION_DOUBLE == function_selector) ?
                         "VertexArrayAttribLFormat" :
                         ((ATTRIBUTE_FORMAT_FUNCTION_INTEGER == function_selector) ? "VertexArrayAttribIFormat" :
                                                                                     "VertexArrayAttrib?Format")))
            << " has unexpectedly generated " << glu::getErrorStr(error) << "error for test with size = " << size
            << ", type = " << glu::getTypeStr(type_gl_name)
            << ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ?
                    (normalized ? ", which was normalized." : ", which was not normalized.") :
                    ".")
            << " Test fails.\n"
            << tcu::TestLog::EndMessage;

        return false;
    }

    gl.bindVertexBuffer(0, m_bo_array, 0, static_cast<glw::GLsizei>(sizeof(T) * size * 2));
    gl.bindVertexBuffer(1, m_bo_array, size * sizeof(T), static_cast<glw::GLsizei>(sizeof(T) * size * 2));

    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.enableVertexAttribArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.enableVertexAttribArray(1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.bindVertexArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    return true;
}

/** @brief Prepare buffer object for test GLSL program transform feedback results.
 */
void AttributeFormatTest::PrepareXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    /* Calculating maximum size. */
    glw::GLsizei size = static_cast<glw::GLsizei>(
        de::max(sizeof(glw::GLubyte),
                de::max(sizeof(glw::GLbyte),
                        de::max(sizeof(glw::GLushort),
                                de::max(sizeof(glw::GLshort),
                                        de::max(sizeof(glw::GLhalf),
                                                de::max(sizeof(glw::GLint),
                                                        de::max(sizeof(glw::GLuint),
                                                                de::max(sizeof(glw::GLfixed),
                                                                        de::max(sizeof(glw::GLfloat),
                                                                                sizeof(glw::GLdouble)))))))))) *
        4 /* maximum number of components */);

    /* Preparing storage. */
    gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_MAP_READ_BIT);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
}

template <>
bool AttributeFormatTest::compare<glw::GLfloat>(glw::GLfloat a, glw::GLfloat b)
{
    if (de::abs(a - b) < 0.03125)
    {
        return true;
    }

    return false;
}

template <>
bool AttributeFormatTest::compare<glw::GLdouble>(glw::GLdouble a, glw::GLdouble b)
{
    if (de::abs(a - b) < 0.03125)
    {
        return true;
    }

    return false;
}

template <typename T>
bool AttributeFormatTest::compare(T a, T b)
{
    return (a == b);
}

/** @brief Draw test program, fetch transform feedback results and compare them with expected values.
 *
 *  @param [in] size         Count of elements of the XFB vector is expected.
 *  @param [in] normalized   Normalized values are expected.
 *
 *  @return True if expected results are equal to returned by XFB, false otherwise.
 */
template <typename T>
bool AttributeFormatTest::DrawAndCheck(glw::GLint size, bool normalized)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup state. */
    gl.useProgram(m_po);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Draw. */
    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

    gl.drawArrays(GL_POINTS, 0, 2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

    /* Result query. */
    T *result_ptr = (T *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

    T result[8] = {0};

    for (glw::GLint i = 0; i < size * 2 /* two points */; ++i)
    {
        result[i] = result_ptr[i];
    }

    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

    const glw::GLdouble scale = normalized ? (1.0 / 16.0) /* Floating point scalling factor. */ : 1.0;

    const T array_data[16] = {(T)(0.0 * scale),  (T)(1.0 * scale),  (T)(2.0 * scale),  (T)(3.0 * scale),
                              (T)(4.0 * scale),  (T)(5.0 * scale),  (T)(6.0 * scale),  (T)(7.0 * scale),
                              (T)(8.0 * scale),  (T)(9.0 * scale),  (T)(10.0 * scale), (T)(11.0 * scale),
                              (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale)};

    T reference[8] = {0};

    for (glw::GLint i = 0; i < 2 /* two points */; ++i)
    {
        for (glw::GLint j = 0; j < size /* size components */; ++j)
        {
            reference[i * size + j] = array_data[i * size * 2 + j] + array_data[i * size * 2 + j + size];
        }
    }

    /* Check result and return. */
    for (glw::GLint i = 0; i < size * 2 /* two points */; ++i)
    {
        if (!AttributeFormatTest::compare<T>(reference[i], result[i]))
        {
            std::string reference_str = "[ ";

            for (glw::GLint j = 0; j < size * 2 /* two points */; ++j)
            {
                std::stringstream ss;

                ss << reference[j];

                reference_str.append(ss.str());

                if (j < size * 2 - 1 /* if it is not the last value */)
                {
                    reference_str.append(", ");
                }
                else
                {
                    reference_str.append(" ]");
                }
            }

            std::string result_str = "[ ";

            for (glw::GLint j = 0; j < size * 2 /* two points */; ++j)
            {
                std::stringstream ss;

                ss << result[j];

                result_str.append(ss.str());

                if (j < size * 2 - 1 /* if it is not the last value */)
                {
                    result_str.append(", ");
                }
                else
                {
                    result_str.append(" ]");
                }
            }

            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "Result vector is equal to " << result_str.c_str() << ", but "
                << reference_str.c_str() << " was expected." << tcu::TestLog::EndMessage;

            return false;
        }
    }

    return true;
}

/** @brief Clean GLSL program object. */
void AttributeFormatTest::CleanProgram()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.useProgram(0);

    if (m_po)
    {
        gl.deleteProgram(m_po);

        m_po = 0;
    }
}

/** @brief Clean Vertex Array Object and related buffer. */
void AttributeFormatTest::CleanVAO()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo_array)
    {
        gl.deleteBuffers(1, &m_bo_array);

        m_bo_array = 0;
    }
}

/** @brief Clean GL objects related to transform feedback. */
void AttributeFormatTest::CleanXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    if (m_bo_xfb)
    {
        gl.deleteBuffers(1, &m_bo_xfb);

        m_bo_xfb = 0;
    }

    while (gl.getError())
        ;
}

const glw::GLchar *AttributeFormatTest::s_vertex_shader_head = "#version 450\n"
                                                               "\n";

const glw::GLchar *AttributeFormatTest::s_vertex_shader_body = "\n"
                                                               "void main()\n"
                                                               "{\n"
                                                               "    gl_Position = vec4(1.0);\n"
                                                               "    result = a_0 + a_1;"
                                                               "}\n";

const glw::GLchar *AttributeFormatTest::s_vertex_shader_declaration[ATTRIBUTE_FORMAT_FUNCTION_COUNT]
                                                                   [4 /* sizes count */] = {{
                                                                                                "in  float a_0;"
                                                                                                "in  float a_1;"
                                                                                                "out float result;\n",

                                                                                                "in  vec2 a_0;"
                                                                                                "in  vec2 a_1;"
                                                                                                "out vec2 result;\n",

                                                                                                "in  vec3 a_0;"
                                                                                                "in  vec3 a_1;"
                                                                                                "out vec3 result;\n",

                                                                                                "in  vec4 a_0;"
                                                                                                "in  vec4 a_1;"
                                                                                                "out vec4 result;\n",
                                                                                            },
                                                                                            {
                                                                                                "in  double a_0;"
                                                                                                "in  double a_1;"
                                                                                                "out double result;\n",

                                                                                                "in  dvec2 a_0;"
                                                                                                "in  dvec2 a_1;"
                                                                                                "out dvec2 result;\n",

                                                                                                "in  dvec3 a_0;"
                                                                                                "in  dvec3 a_1;"
                                                                                                "out dvec3 result;\n",

                                                                                                "in  dvec4 a_0;"
                                                                                                "in  dvec4 a_1;"
                                                                                                "out dvec4 result;\n",
                                                                                            },
                                                                                            {
                                                                                                "in  int a_0;"
                                                                                                "in  int a_1;"
                                                                                                "out int result;\n",

                                                                                                "in  ivec2 a_0;"
                                                                                                "in  ivec2 a_1;"
                                                                                                "out ivec2 result;\n",

                                                                                                "in  ivec3 a_0;"
                                                                                                "in  ivec3 a_1;"
                                                                                                "out ivec3 result;\n",

                                                                                                "in  ivec4 a_0;"
                                                                                                "in  ivec4 a_1;"
                                                                                                "out ivec4 result;\n",
                                                                                            }};

const glw::GLchar *AttributeFormatTest::s_fragment_shader = "#version 450\n"
                                                            "\n"
                                                            "out vec4 color;\n"
                                                            "\n"
                                                            "void main()\n"
                                                            "{\n"
                                                            "    color = vec4(1.0);"
                                                            "}\n";

/******************************** Vertex Array Object Attribute Binding Test Implementation   ********************************/

/** @brief Attribute Binding Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
AttributeBindingTest::AttributeBindingTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_attribute_binding", "Vertex Array Objects Attribute Binding Test")
    , m_po(0)
    , m_vao(0)
    , m_bo_array(0)
    , m_bo_xfb(0)
{
    /* Intentionally left blank. */
}

/** @brief Iterate Attribute Binding Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult AttributeBindingTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        PrepareProgram();
        is_ok &= PrepareVAO();
        PrepareXFB();
        is_ok &= DrawAndCheck();
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    Clean();

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Build test's GLSL program.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void AttributeBindingTest::PrepareProgram()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    struct Shader
    {
        glw::GLchar const *const source;
        glw::GLenum const type;
        glw::GLuint id;
    } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};

    glw::GLuint const shader_count = DE_LENGTH_OF_ARRAY(shader);

    try
    {
        /* Create program. */
        m_po = gl.createProgram();
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

        /* Shader compilation. */

        for (glw::GLuint i = 0; i < shader_count; ++i)
        {
            if (DE_NULL != shader[i].source)
            {
                shader[i].id = gl.createShader(shader[i].type);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

                gl.attachShader(m_po, shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

                gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

                gl.compileShader(shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

                glw::GLint status = GL_FALSE;

                gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                if (GL_FALSE == status)
                {
                    glw::GLint log_size = 0;
                    gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                    glw::GLchar *log_text = new glw::GLchar[log_size];

                    gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "Shader compilation has failed.\n"
                        << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
                        << "Shader compilation error log:\n"
                        << log_text << "\n"
                        << "Shader source code:\n"
                        << shader[i].source << "\n"
                        << tcu::TestLog::EndMessage;

                    delete[] log_text;

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

                    throw 0;
                }
            }
        }

        /* Binding attributes. */
        gl.bindAttribLocation(m_po, 0, "a_0");
        gl.bindAttribLocation(m_po, 1, "a_1");
        GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed.");

        /* Transform Feedback setup. */
        static const glw::GLchar *xfb_varying = "result";
        gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        /* Link. */
        gl.linkProgram(m_po);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        glw::GLint status = GL_FALSE;

        gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

        if (GL_TRUE == status)
        {
            for (glw::GLuint i = 0; i < shader_count; ++i)
            {
                if (shader[i].id)
                {
                    gl.detachShader(m_po, shader[i].id);

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
                }
            }
        }
        else
        {
            glw::GLint log_size = 0;

            gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

            glw::GLchar *log_text = new glw::GLchar[log_size];

            gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

            m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
                                                << log_text << "\n"
                                                << tcu::TestLog::EndMessage;

            delete[] log_text;

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

            throw 0;
        }
    }
    catch (...)
    {
        if (m_po)
        {
            gl.deleteProgram(m_po);

            m_po = 0;
        }
    }

    for (glw::GLuint i = 0; i < shader_count; ++i)
    {
        if (0 != shader[i].id)
        {
            gl.deleteShader(shader[i].id);

            shader[i].id = 0;
        }
    }

    if (0 == m_po)
    {
        throw 0;
    }
}

/** @brief Prepare vertex array object for the test.
 *
 *  @return True if function VertexArrayAttribBinding does not generate any error.
 */
bool AttributeBindingTest::PrepareVAO()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* VAO creation. */
    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Array buffer creation. */
    glw::GLint array_data[2] = {1, 0};

    gl.genBuffers(1, &m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.vertexAttribIPointer(0, 1, GL_INT, sizeof(glw::GLint) * 2, NULL);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");

    gl.vertexAttribIPointer(1, 1, GL_INT, sizeof(glw::GLint) * 2, glu::BufferOffsetAsPointer(1 * sizeof(glw::GLint)));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");

    gl.enableVertexAttribArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.enableVertexAttribArray(1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.vertexArrayAttribBinding(m_vao, 0, 1);
    gl.vertexArrayAttribBinding(m_vao, 1, 0);

    if (glw::GLenum error = gl.getError())
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "VertexArrayAttribBinding has unexpectedly generated "
            << glu::getErrorStr(error) << "error. Test fails.\n"
            << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/** @brief Prepare buffer object for test GLSL program transform feedback results.
 */
void AttributeBindingTest::PrepareXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    /* Preparing storage. */
    gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
}

/** @brief Draw test program, fetch transform feedback results and compare them with expected values.
 *
 *  @return True if expected results are equal to returned by XFB, false otherwise.
 */
bool AttributeBindingTest::DrawAndCheck()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup state. */
    gl.useProgram(m_po);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

    /* Draw. */
    gl.drawArrays(GL_POINTS, 0, 1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

    /* State reset. */
    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

    /* Result query. */
    glw::GLint *result_ptr = (glw::GLint *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

    glw::GLint result[2] = {result_ptr[0], result_ptr[1]};

    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

    /* Check result and return. */
    if ((0 == result[0]) || (1 == result[1]))
    {
        return true;
    }

    return false;
}

/** @brief Clean GL objects. */
void AttributeBindingTest::Clean()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.useProgram(0);

    if (m_po)
    {
        gl.deleteProgram(m_po);

        m_po = 0;
    }

    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo_array)
    {
        gl.deleteBuffers(1, &m_bo_array);

        m_bo_array = 0;
    }

    if (m_bo_xfb)
    {
        gl.deleteBuffers(1, &m_bo_xfb);

        m_bo_xfb = 0;
    }

    while (gl.getError())
        ;
}

const glw::GLchar AttributeBindingTest::s_vertex_shader[] = "#version 450\n"
                                                            "\n"
                                                            "in int a_0;\n"
                                                            "in int a_1;\n"
                                                            "out ivec2 result;\n"
                                                            "\n"
                                                            "void main()\n"
                                                            "{\n"
                                                            "    gl_Position = vec4(1.0);\n"
                                                            "    result[0] = a_0;\n"
                                                            "    result[1] = a_1;\n"
                                                            "}\n";

const glw::GLchar AttributeBindingTest::s_fragment_shader[] = "#version 450\n"
                                                              "\n"
                                                              "out vec4 color;\n"
                                                              "\n"
                                                              "void main()\n"
                                                              "{\n"
                                                              "    color = vec4(1.0);"
                                                              "}\n";

/******************************** Vertex Array Attribute Binding Divisor Test Implementation   ********************************/

/** @brief Vertex Array Attribute Binding Divisor Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
AttributeBindingDivisorTest::AttributeBindingDivisorTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor", "Vertex Array Attribute Binding Divisor Test")
    , m_po(0)
    , m_vao(0)
    , m_bo_array(0)
    , m_bo_xfb(0)
{
    /* Intentionally left blank. */
}

/** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult AttributeBindingDivisorTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        PrepareProgram();
        PrepareVAO();
        PrepareXFB();

        {
            glw::GLint reference[] = {0, 2};
            is_ok                  = SetDivisor(2);
            Draw(1, 2);
            is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
                             "Draw of 1 point with 2 instances with 2 divisor has failed.");
        }

        {
            glw::GLint reference[] = {0, 0, 1, 1};
            is_ok                  = SetDivisor(1);
            Draw(2, 2);
            is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
                             "Draw of 2 points with 2 instances with 1 divisor has failed.");
        }

        {
            glw::GLint reference[] = {0, 1, 2, 3};
            is_ok                  = SetDivisor(1);
            Draw(1, 4);
            is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
                             "Draw of 1 point with 4 instances with 1 divisor has failed.");
        }

        {
            glw::GLint reference[] = {0, 1, 0, 1};
            is_ok                  = SetDivisor(0);
            Draw(2, 2);
            is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
                             "Draw of 2 points with 2 instances with 0 divisor has failed.");
        }

        {
            glw::GLint reference[] = {0, 1, 2, 3};
            is_ok                  = SetDivisor(0);
            Draw(4, 1);
            is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
                             "Draw of 4 points with 1 instance with 0 divisor has failed.");
        }
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    Clean();

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Build test's GLSL program.
 *
 *  @note The function may throw if unexpected error has occured.
 */
void AttributeBindingDivisorTest::PrepareProgram()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    struct Shader
    {
        glw::GLchar const *const source;
        glw::GLenum const type;
        glw::GLuint id;
    } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};

    glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

    try
    {
        /* Create program. */
        m_po = gl.createProgram();
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

        /* Shader compilation. */

        for (glw::GLuint i = 0; i < shader_count; ++i)
        {
            if (DE_NULL != shader[i].source)
            {
                shader[i].id = gl.createShader(shader[i].type);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

                gl.attachShader(m_po, shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

                gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

                gl.compileShader(shader[i].id);

                GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

                glw::GLint status = GL_FALSE;

                gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                if (GL_FALSE == status)
                {
                    glw::GLint log_size = 0;
                    gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

                    glw::GLchar *log_text = new glw::GLchar[log_size];

                    gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

                    m_context.getTestContext().getLog()
                        << tcu::TestLog::Message << "Shader compilation has failed.\n"
                        << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
                        << "Shader compilation error log:\n"
                        << log_text << "\n"
                        << "Shader source code:\n"
                        << shader[i].source << "\n"
                        << tcu::TestLog::EndMessage;

                    delete[] log_text;

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

                    throw 0;
                }
            }
        }

        /* Transform Feedback setup. */
        static const glw::GLchar *xfb_varying = "result";

        gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        /* Link. */
        gl.linkProgram(m_po);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

        glw::GLint status = GL_FALSE;

        gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

        if (GL_TRUE == status)
        {
            for (glw::GLuint i = 0; i < shader_count; ++i)
            {
                if (shader[i].id)
                {
                    gl.detachShader(m_po, shader[i].id);

                    GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
                }
            }
        }
        else
        {
            glw::GLint log_size = 0;

            gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

            glw::GLchar *log_text = new glw::GLchar[log_size];

            gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

            m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
                                                << log_text << "\n"
                                                << tcu::TestLog::EndMessage;

            delete[] log_text;

            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

            throw 0;
        }
    }
    catch (...)
    {
        if (m_po)
        {
            gl.deleteProgram(m_po);

            m_po = 0;
        }
    }

    for (glw::GLuint i = 0; i < shader_count; ++i)
    {
        if (0 != shader[i].id)
        {
            gl.deleteShader(shader[i].id);

            shader[i].id = 0;
        }
    }

    if (m_po)
    {
        gl.useProgram(m_po);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    }

    if (0 == m_po)
    {
        throw 0;
    }
}

/** @brief Prepare vertex array object for the test.
 */
void AttributeBindingDivisorTest::PrepareVAO()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* VAO creation. */
    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    /* Array buffer 0 creation. */
    glw::GLint array_data[4] = {0, 1, 2, 3};

    gl.genBuffers(1, &m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");

    gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a"), 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");

    gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");

    gl.bindVertexBuffer(0, m_bo_array, 0, sizeof(glw::GLint));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed.");

    gl.enableVertexAttribArray(gl.getAttribLocation(m_po, "a"));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
}

/** @brief Prepare buffer object for test GLSL program transform feedback results.
 */
void AttributeBindingDivisorTest::PrepareXFB()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Buffer creation. */
    gl.genBuffers(1, &m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");

    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    /* Preparing storage. */
    gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
}

/** @brief Draw number of points and number of instances with XFB environment.
 *
 *  @param [in] number_of_points        Number of points to be drawn.
 *  @param [in] number_of_instances     Number of instances to be drawn.
 */
void AttributeBindingDivisorTest::Draw(glw::GLuint number_of_points, glw::GLuint number_of_instances)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup state. */
    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

    /* Draw. */
    gl.drawArraysInstanced(GL_POINTS, 0, number_of_points, number_of_instances);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced call failed.");

    /* State reset. */
    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
}

/** @brief Call VertexArrayBindingDivisor on m_vao object and check errors.
 *
 *  @param [in] divisor        Divisor to be passed.
 *
 *  @return True if VertexArrayBindingDivisor doe not generate any error, false otherwise.
 */
bool AttributeBindingDivisorTest::SetDivisor(glw::GLuint divisor)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Setup. */
    gl.vertexArrayBindingDivisor(m_vao, 0, divisor);

    /* Checking for errors (this is tested function so it fail the test if there is error). */
    if (glw::GLenum error = gl.getError())
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "VertexArrayBindingDivisor unexpectedl generated " << glu::getErrorStr(error)
            << " error when called with divisor" << divisor << ". " << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/** @brief Check transform feedback results and log.
 *
 *  @param [in] count           Number of results to be checked.
 *  @param [in] expected        Expected results.
 *  @param [in] log_message     Message to be logged if expected values are not equal to queried.
 *
 *  @return True if expected values are equal to queried, false otherwise.
 */
bool AttributeBindingDivisorTest::CheckXFB(const glw::GLuint count, const glw::GLint expected[],
                                           const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Result setup */
    bool is_ok = true;

    /* Result query. */
    glw::GLint *result = (glw::GLint *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");

    /* Check result and return. */
    for (glw::GLuint i = 0; i < count; ++i)
    {
        if (expected[i] != result[i])
        {
            std::string expected_str = "[";
            std::string result_str   = "[";

            for (glw::GLuint j = 0; j < count; ++j)
            {
                expected_str.append(Utilities::itoa((glw::GLuint)expected[j]));
                result_str.append(Utilities::itoa((glw::GLuint)result[j]));

                if (j < count - 1)
                {
                    expected_str.append(", ");
                    result_str.append(", ");
                }
                else
                {
                    expected_str.append("]");
                    result_str.append("]");
                }
            }

            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "Result is " << result_str << ", but " << expected_str << " was expected. "
                << log_message << tcu::TestLog::EndMessage;

            is_ok = false;
            break;
        }
    }

    /* Unmaping GL buffer. */
    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");

    return is_ok;
}

/** @brief Clean GL objects. */
void AttributeBindingDivisorTest::Clean()
{
    /* Shortcut for GL functionality */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.useProgram(0);

    if (m_po)
    {
        gl.deleteProgram(m_po);

        m_po = 0;
    }

    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo_array)
    {
        gl.deleteBuffers(1, &m_bo_array);

        m_bo_array = 0;
    }

    if (m_bo_xfb)
    {
        gl.deleteBuffers(1, &m_bo_xfb);

        m_bo_xfb = 0;
    }

    while (gl.getError())
        ;
}

const glw::GLchar AttributeBindingDivisorTest::s_vertex_shader[] = "#version 450\n"
                                                                   "\n"
                                                                   "in  int a;\n"
                                                                   "out int result;\n"
                                                                   "\n"
                                                                   "void main()\n"
                                                                   "{\n"
                                                                   "    gl_Position = vec4(1.0);\n"
                                                                   "    result = a;"
                                                                   "}\n";

const glw::GLchar AttributeBindingDivisorTest::s_fragment_shader[] = "#version 450\n"
                                                                     "\n"
                                                                     "out vec4 color;\n"
                                                                     "\n"
                                                                     "void main()\n"
                                                                     "{\n"
                                                                     "    color = vec4(1.0);"
                                                                     "}\n";

/******************************** Get Vertex Array Test Implementation   ********************************/

/** @brief Get Vertex Array Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetVertexArrayTest::GetVertexArrayTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_get_vertex_array", "Get Vertex Array Test")
{
    /* Intentionally left blank. */
}

/** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetVertexArrayTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Test objects. */
    glw::GLuint vao = 0;
    glw::GLuint bo  = 0;

    try
    {
        gl.genVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        gl.bindVertexArray(vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

        gl.genBuffers(1, &bo);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");

        gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

        glw::GLint result = 0;
        gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &result);

        if (glw::GLenum error = gl.getError())
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "GetVertexArrayiv unexpectedly generated " << glu::getErrorStr(error)
                << "error. Test fails." << tcu::TestLog::EndMessage;

            is_ok = false;
        }

        if ((glw::GLuint)result != bo)
        {
            m_context.getTestContext().getLog()
                << tcu::TestLog::Message << "GetVertexArrayiv was expected to return " << bo << ", but " << result
                << " was observed. Test fails." << tcu::TestLog::EndMessage;

            is_ok = false;
        }
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    if (bo)
    {
        gl.deleteBuffers(1, &bo);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/******************************** Get Vertex Array Test Indexed Implementation   ********************************/

/** @brief Get Vertex Array Indexed Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetVertexArrayIndexedTest::GetVertexArrayIndexedTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed", "Get Vertex Array Indexed Test")
    , m_vao(0)
{
    m_bo[0] = 0;
    m_bo[1] = 0;
    m_bo[2] = 0;
    m_bo[3] = 0;
}

/** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetVertexArrayIndexedTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        PrepareVAO();

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 0, GL_TRUE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 1, GL_TRUE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 2, GL_TRUE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 3, GL_TRUE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 5, GL_FALSE);

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0, 0);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 1, 2);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 2, 0);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 3, 8);

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 0, GL_BYTE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 1, GL_SHORT);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 2, GL_FLOAT);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 3, GL_UNSIGNED_INT_2_10_10_10_REV);

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 0, GL_TRUE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 1, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 2, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 3, GL_FALSE);

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 0, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 1, GL_TRUE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 2, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 3, GL_FALSE);

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0, 3);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1, 2);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 2, 1);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 3, 0);

        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 0, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 1, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 2, GL_FALSE);
        is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 3, GL_FALSE);

        is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 0, 0);
        is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 0);
        is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 2, 4);
        is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 3, 0);

        is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 0, 0);
        is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 1, 2);
        is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 2, 8);
        is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 3, 4);
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    if (m_bo[0] || m_bo[1] || m_bo[2] || m_bo[3])
    {
        gl.deleteBuffers(4, m_bo);

        m_bo[0] = 0;
        m_bo[1] = 0;
        m_bo[2] = 0;
        m_bo[3] = 0;
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Prepare vertex array object for the test.
 */
void GetVertexArrayIndexedTest::PrepareVAO()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.genVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

    gl.bindVertexArray(m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");

    gl.genBuffers(4, m_bo);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");

    /* Attribute 0. */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[0]);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.vertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, NULL);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

    gl.enableVertexAttribArray(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.vertexAttribDivisor(0, 3);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");

    /* Attribute 1. */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[1]);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.vertexAttribIPointer(1, 2, GL_SHORT, 2, glu::BufferOffsetAsPointer(2 * sizeof(glw::GLchar)));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

    gl.enableVertexAttribArray(1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.vertexAttribDivisor(1, 2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");

    /* Attribute 2. */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[2]);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.vertexAttribBinding(2, 2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");

    gl.vertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 4);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");

    gl.bindVertexBuffer(2, m_bo[2], 8, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed.");

    gl.enableVertexAttribArray(2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.vertexAttribDivisor(2, 1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");

    /* Attribute 3. */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[3]);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

    gl.vertexAttribPointer(3, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 8,
                           glu::BufferOffsetAsPointer(4 * sizeof(glw::GLchar)));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");

    gl.enableVertexAttribArray(3);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");

    gl.vertexAttribDivisor(3, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
}

/** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log.
 *
 *  @param [in] pname        Parameter to be queried.
 *  @param [in] index        Index to be queried.
 *  @param [in] expected     Expected error.
 *
 *  @return True if value is equal to expected, false otherwise.
 */
bool GetVertexArrayIndexedTest::Check(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLint result = 0;

    gl.getVertexArrayIndexediv(m_vao, index, pname, &result);

    if (glw::GLenum error = gl.getError())
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index " << index << ", with pname"
            << glu::getVertexAttribParameterNameStr(pname) << " unexpectedly generated " << glu::getErrorStr(error)
            << "error. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    if (result != expected)
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index " << index << " and with pname"
            << glu::getVertexAttribParameterNameStr(pname) << " returned " << result << ", but " << expected
            << " was expected. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log.
 *
 *  @param [in] pname        Parameter to be queried.
 *  @param [in] index        Index to be queried.
 *  @param [in] expected     Expected error.
 *
 *  @return True if value is equal to expected, false otherwise.
 */
bool GetVertexArrayIndexedTest::Check64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLint64 result = 0;

    gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result);

    if (glw::GLenum error = gl.getError())
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index " << index << ", with pname"
            << glu::getVertexAttribParameterNameStr(pname) << " unexpectedly generated " << glu::getErrorStr(error)
            << "error. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    if (result != expected)
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index " << index << " and with pname"
            << glu::getVertexAttribParameterNameStr(pname) << " returned " << result << ", but " << expected
            << " was expected. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Defaults Test Implementation   ********************************/

/** @brief Defaults Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DefaultsTest::DefaultsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_defaults", "Defaults Test")
    , m_vao(0)
{
}

/** @brief Iterate Defaults Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DefaultsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Test objects. */
    glw::GLint max_attributes = 8;

    try
    {
        /* Query limits. */
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

        /* Prepare default Vertex Array Object. */
        PrepareVAO();

        /* Check default values per attribute index. */
        for (glw::GLint i = 0; i < max_attributes; ++i)
        {
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_ENABLED, i, GL_FALSE);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_SIZE, i, 4);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_STRIDE, i, 0);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_TYPE, i, GL_FLOAT);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, i, GL_FALSE);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_INTEGER, i, GL_FALSE);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, i, 0);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_LONG, i, GL_FALSE);
            is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, i, 0);
            is_ok &= CheckIndexed64(GL_VERTEX_BINDING_OFFSET, i, 0);
        }

        /* Check default values per vertex array object. */
        is_ok &= Check(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0);
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Cleanup. */
    if (m_vao)
    {
        gl.deleteVertexArrays(1, &m_vao);

        m_vao = 0;
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Prepare vertex array object for the test.
 */
void DefaultsTest::PrepareVAO()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    gl.createVertexArrays(1, &m_vao);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
}

/** @brief Compare value queried using GetVertexArrayiv with expected value and log.
 *
 *  @param [in] pname        Parameter to be queried.
 *  @param [in] expected     Expected error.
 *
 *  @return True if value is equal to expected, false otherwise.
 */
bool DefaultsTest::Check(const glw::GLenum pname, const glw::GLint expected)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLint result = 0;

    gl.getVertexArrayiv(m_vao, pname, &result);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayiv call failed.");

    if (result != expected)
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "Default Vertex Array Object has parameter "
            << glu::getVertexAttribParameterNameStr(pname) << " equal to " << result << ", but " << expected
            << " was expected. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log.
 *
 *  @param [in] pname        Parameter to be queried.
 *  @param [in] index        Index to be queried.
 *  @param [in] expected     Expected error.
 *
 *  @return True if value is equal to expected, false otherwise.
 */
bool DefaultsTest::CheckIndexed(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLint result = 0;

    gl.getVertexArrayIndexediv(m_vao, index, pname, &result);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexediv call failed.");

    if (result != expected)
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "Default Vertex Array Object at index " << index << " has parameter "
            << glu::getVertexAttribParameterNameStr(pname) << " equal to " << result << ", but " << expected
            << " was expected. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log.
 *
 *  @param [in] pname        Parameter to be queried.
 *  @param [in] index        Index to be queried.
 *  @param [in] expected     Expected error.
 *
 *  @return True if value is equal to expected, false otherwise.
 */
bool DefaultsTest::CheckIndexed64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLint64 result = 0;

    gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexed64iv call failed.");

    if (result != expected)
    {
        m_context.getTestContext().getLog()
            << tcu::TestLog::Message << "Default Vertex Array Object at index " << index << " has parameter "
            << glu::getVertexAttribParameterNameStr(pname) << " equal to " << result << ", but " << expected
            << " was expected. Test fails." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Creation Error Test Implementation   ********************************/

/** @brief Creation Error Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationErrorTest::CreationErrorTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_creation_error", "Creation Error Test")
{
}

/** @brief Iterate Creation Error Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationErrorTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    try
    {
        glw::GLuint negative_vao = 0;

        gl.createVertexArrays(-1, &negative_vao);

        is_ok = CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated if n is negative.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool CreationErrorTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << "was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Enable Disable Attribute Errors Test Implementation   ********************************/

/** @brief Enable Disable Attribute Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
EnableDisableAttributeErrorsTest::EnableDisableAttributeErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_enable_disable_attribute_errors", "Enable Disable Attribute Errors Test")
{
}

/** @brief Enable Disable Attribute Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult EnableDisableAttributeErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Test objects. */
    glw::GLint max_attributes = 8;

    /* Tested VAOs. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;
    try
    {
        /* Query limits. */
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

        /* Prepare valid VAO. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;

        /* Test not a VAO. */
        gl.enableVertexArrayAttrib(0, not_a_vao);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by EnableVertexArrayAttrib if "
                                                  "vaobj is not the name of an existing vertex array object.");

        gl.disableVertexArrayAttrib(0, not_a_vao);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by DisableVertexArrayAttrib if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* Test to big attribute index. */
        gl.enableVertexArrayAttrib(max_attributes, vao);

        is_ok &= CheckError(
            GL_INVALID_OPERATION,
            "INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS.");

        gl.disableVertexArrayAttrib(max_attributes, vao);

        is_ok &= CheckError(
            GL_INVALID_OPERATION,
            "INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS.");

        gl.enableVertexArrayAttrib(max_attributes + 1, vao);

        is_ok &= CheckError(
            GL_INVALID_OPERATION,
            "INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS.");

        gl.disableVertexArrayAttrib(max_attributes + 1, vao);

        is_ok &= CheckError(
            GL_INVALID_OPERATION,
            "INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool EnableDisableAttributeErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << "was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Element Buffer Errors Test Implementation   ********************************/

/** @brief Element Buffer Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ElementBufferErrorsTest::ElementBufferErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_element_buffer_errors", "Element Buffer Errors Test")
{
}

/** @brief Element Buffer Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ElementBufferErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;
    glw::GLuint bo        = 0;
    glw::GLuint not_a_bo  = 0;

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        gl.createBuffers(1, &bo);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;
        while (gl.isBuffer(++not_a_bo))
            ;

        /* Test not a VAO. */
        gl.vertexArrayElementBuffer(not_a_vao, bo);

        is_ok &=
            CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by VertexArrayElementBuffer if "
                                             "vaobj is not the name of an existing vertex array object.");

        /* Test not a BO. */
        gl.vertexArrayElementBuffer(vao, not_a_bo);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error is generated by VertexArrayElementBuffer if "
                                                  "buffer is not zero or the name of an existing buffer object.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    if (bo)
    {
        gl.deleteBuffers(1, &bo);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool ElementBufferErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Vertex Buffers Errors Test Implementation   ********************************/

/** @brief Vertex Buffers Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
VertexBuffersErrorsTest::VertexBuffersErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_vertex_buffers_errors", "Vertex Buffers Errors Test")
{
}

/** @brief Vertex Buffers Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult VertexBuffersErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;
    glw::GLuint bo        = 0;
    glw::GLuint not_a_bo  = 0;

    /* Valid setup. */
    glw::GLintptr valid_offset = 0;
    glw::GLsizei valid_stride  = 1;

    /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
    glw::GLint max_vertex_attrib_bindings = 16;
    glw::GLint max_vertex_attrib_stride   = 2048;

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        gl.createBuffers(1, &bo);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;
        while (gl.isBuffer(++not_a_bo))
            ;

        /* Prepare limits. */
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &max_vertex_attrib_stride);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

        /* Invalid setup. */
        glw::GLintptr invalid_offset  = -1;
        glw::GLsizei invalid_stride_0 = -1;
        glw::GLsizei invalid_stride_1 = max_vertex_attrib_stride + 1;

        /* Test not a VAO. */
        gl.vertexArrayVertexBuffer(not_a_vao, 0, bo, valid_offset, valid_stride);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if "
                                                  "vaobj is not the name of an existing vertex array object.");

        gl.vertexArrayVertexBuffers(not_a_vao, 0, 1, &bo, &valid_offset, &valid_stride);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* Test not a BO. */
        gl.vertexArrayVertexBuffer(vao, 0, not_a_bo, valid_offset, valid_stride);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if "
                                                  "vaobj is not the name of an existing vertex array object.");

        gl.vertexArrayVertexBuffers(vao, 0, 1, &not_a_bo, &valid_offset, &valid_stride);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* Test too big binding index. */
        gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings, bo, valid_offset, valid_stride);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if "
                                              "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");

        gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings + 1, bo, valid_offset, valid_stride);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if "
                                              "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");

        gl.vertexArrayVertexBuffers(vao, max_vertex_attrib_bindings, 1, &bo, &valid_offset, &valid_stride);

        is_ok &=
            CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
                                             "first+count is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");

        /* Test too big stride. */
        gl.vertexArrayVertexBuffer(vao, 0, bo, -1, valid_stride);

        is_ok &= CheckError(GL_INVALID_VALUE,
                            "INVALID_VALUE is generated by VertexArrayVertexBuffer if offset less than zero.");

        gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, -1);

        is_ok &= CheckError(GL_INVALID_VALUE,
                            "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is less than zero.");

        gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, max_vertex_attrib_stride + 1);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is "
                                              "greater than the value of MAX_VERTEX_ATTRIB_STRIDE.");

        gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &invalid_offset, &valid_stride);

        is_ok &=
            CheckError(GL_INVALID_VALUE,
                       "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in offsets is negative.");

        gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_0);

        is_ok &=
            CheckError(GL_INVALID_VALUE,
                       "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in strides is negative.");

        gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_1);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffers if a value in "
                                              "strides is greater than the value of MAX_VERTEX_ATTRIB_STRIDE.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    if (bo)
    {
        gl.deleteBuffers(1, &bo);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool VertexBuffersErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Attribute Format Errors Test Implementation   ********************************/

/** @brief Attribute Format Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
AttributeFormatErrorsTest::AttributeFormatErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_attribute_format_errors", "Attribute Format Errors Test")
{
}

/** @brief Attribute Format Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult AttributeFormatErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;

    /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
    glw::GLint max_vertex_attribs                = 16;
    glw::GLint max_vertex_attrib_relative_offset = 2047;

    /* Invalid values. */
    glw::GLenum bad_type = 0;

    static const glw::GLenum accepted_types[] = {GL_BYTE,
                                                 GL_SHORT,
                                                 GL_INT,
                                                 GL_FIXED,
                                                 GL_FLOAT,
                                                 GL_HALF_FLOAT,
                                                 GL_DOUBLE,
                                                 GL_UNSIGNED_BYTE,
                                                 GL_UNSIGNED_SHORT,
                                                 GL_UNSIGNED_INT,
                                                 GL_INT_2_10_10_10_REV,
                                                 GL_UNSIGNED_INT_2_10_10_10_REV,
                                                 GL_UNSIGNED_INT_10F_11F_11F_REV};

    {
        bool is_accepted_type = true;
        while (is_accepted_type)
        {
            bad_type++;
            is_accepted_type = false;
            for (glw::GLuint i = 0; i < DE_LENGTH_OF_ARRAY(accepted_types); ++i)
            {
                if (accepted_types[i] == bad_type)
                {
                    is_accepted_type = true;
                    break;
                }
            }
        }
    }

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;

        /* Prepare limits. */
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &max_vertex_attrib_relative_offset);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

        /* TESTS OF VERTEXARRAYATTRIBFORMAT */

        /* MAX_VERTEX_ATTRIBS < */
        gl.vertexArrayAttribFormat(vao, max_vertex_attribs, 1, GL_BYTE, GL_FALSE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if "
                                              "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");

        gl.vertexArrayAttribFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, GL_FALSE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if "
                                              "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");

        gl.vertexArrayAttribIFormat(vao, max_vertex_attribs, 1, GL_BYTE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
                                              "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");

        gl.vertexArrayAttribIFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
                                              "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");

        gl.vertexArrayAttribLFormat(vao, max_vertex_attribs, 1, GL_DOUBLE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
                                              "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");

        gl.vertexArrayAttribLFormat(vao, max_vertex_attribs + 1, 1, GL_DOUBLE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
                                              "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");

        /* size */
        gl.vertexArrayAttribFormat(vao, 0, 0, GL_BYTE, GL_FALSE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is "
                                              "not one of the accepted values (0).");

        gl.vertexArrayAttribFormat(vao, 0, 5, GL_BYTE, GL_FALSE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is "
                                              "not one of the accepted values (5).");

        gl.vertexArrayAttribIFormat(vao, 0, 0, GL_BYTE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is "
                                              "not one of the accepted values (0).");

        gl.vertexArrayAttribIFormat(vao, 0, 5, GL_BYTE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is "
                                              "not one of the accepted values (5).");

        gl.vertexArrayAttribLFormat(vao, 0, 0, GL_DOUBLE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is "
                                              "not one of the accepted values (0).");

        gl.vertexArrayAttribLFormat(vao, 0, 5, GL_DOUBLE, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is "
                                              "not one of the accepted values (5).");

        /* relative offset */
        gl.vertexArrayAttribFormat(vao, 0, 1, GL_BYTE, GL_FALSE, max_vertex_attrib_relative_offset + 1);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if "
                                              "relativeoffset is greater than the value of "
                                              "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");

        gl.vertexArrayAttribIFormat(vao, 0, 1, GL_BYTE, max_vertex_attrib_relative_offset + 1);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
                                              "relativeoffset is greater than the value of "
                                              "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");

        gl.vertexArrayAttribLFormat(vao, 0, 1, GL_DOUBLE, max_vertex_attrib_relative_offset + 1);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
                                              "relativeoffset is greater than the value of "
                                              "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");

        /* type */
        gl.vertexArrayAttribFormat(vao, 0, 1, bad_type, GL_FALSE, 0);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM was not generated by VertexArrayAttribFormat if type is not one of the accepted tokens.");

        gl.vertexArrayAttribIFormat(vao, 0, 1, bad_type, 0);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is not one of the accepted tokens.");

        gl.vertexArrayAttribLFormat(vao, 0, 1, bad_type, 0);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is not one of the accepted tokens.");

        /* type UNSIGNED_INT_10F_11F_11F_REV case */
        gl.vertexArrayAttribIFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is UNSIGNED_INT_10F_11F_11F_REV.");

        gl.vertexArrayAttribLFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is UNSIGNED_INT_10F_11F_11F_REV.");

        /* Test not a VAO. */
        gl.vertexArrayAttribFormat(not_a_vao, 0, 1, GL_BYTE, GL_FALSE, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
                                                  "vaobj is not the name of an existing vertex array object.");

        gl.vertexArrayAttribIFormat(not_a_vao, 0, 1, GL_BYTE, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribIFormat if "
                                                  "vaobj is not the name of an existing vertex array object.");

        gl.vertexArrayAttribLFormat(not_a_vao, 0, 1, GL_DOUBLE, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribLFormat if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* BGRA */
        gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_BYTE, GL_TRUE, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
                                                  "size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV or "
                                                  "UNSIGNED_INT_2_10_10_10_REV.");

        gl.vertexArrayAttribFormat(vao, 0, 1, GL_INT_2_10_10_10_REV, GL_TRUE, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
                                                  "type is INT_2_10_10_10_REV and size is neither 4 nor BGRA.");

        gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0);

        is_ok &=
            CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if type "
                                             "is UNSIGNED_INT_2_10_10_10_REV and size is neither 4 nor BGRA.");

        gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_TRUE, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
                                                  "type is UNSIGNED_INT_10F_11F_11F_REV and size is not 3.");

        gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_UNSIGNED_BYTE, GL_FALSE, 0);

        is_ok &= CheckError(
            GL_INVALID_OPERATION,
            "INVALID_OPERATION was not generated by VertexArrayAttribFormat if size is BGRA and normalized is FALSE.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool AttributeFormatErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Attribute Binding Errors Test Implementation   ********************************/

/** @brief Attribute Binding Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
AttributeBindingErrorsTest::AttributeBindingErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_attribute_binding_errors", "Attribute Binding Errors Test")
{
}

/** @brief Attribute Binding Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult AttributeBindingErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;

    /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
    glw::GLint max_vertex_attribs         = 16;
    glw::GLint max_vertex_attrib_bindings = 16;

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;

        /* Prepare limits. */
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

        /* Not a VAO. */
        gl.vertexArrayAttribBinding(not_a_vao, 0, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribBinding if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* Too big attribute index. */
        gl.vertexArrayAttribBinding(vao, max_vertex_attribs, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
                                              "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");

        gl.vertexArrayAttribBinding(vao, max_vertex_attribs + 1, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
                                              "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");

        /* Too big binding index. */
        gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
                                              "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");

        gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings + 1);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
                                              "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool AttributeBindingErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Attribute Binding Divisor Errors Test Implementation   ********************************/

/** @brief Attribute Binding Divisor Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
AttributeBindingDivisorErrorsTest::AttributeBindingDivisorErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor_errors", "Attribute Binding Divisor Errors Test")
{
}

/** @brief Attribute Binding Divisor Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult AttributeBindingDivisorErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;

    /* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
    glw::GLint max_vertex_attrib_bindings = 16;

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;

        /* Prepare limits. */
        gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");

        /* Not a VAO. */
        gl.vertexArrayBindingDivisor(not_a_vao, 0, 0);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayBindingDivisor if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* Too big binding index. */
        gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if "
                                              "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");

        gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings + 1, 0);

        is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if "
                                              "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool AttributeBindingDivisorErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Get Vertex Array Errors Test Implementation   ********************************/

/** @brief Get Vertex Array Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetVertexArrayErrorsTest::GetVertexArrayErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_get_vertex_array_errors", "Get Vertex Array Errors Test")
{
}

/** @brief Iterate over Get Vertex Array Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetVertexArrayErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;

    glw::GLint storage = 0;

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;

        /* Not a VAO. */
        gl.getVertexArrayiv(not_a_vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &storage);

        is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayiv if "
                                                  "vaobj is not the name of an existing vertex array object.");

        /* Bad parameter. */
        gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING + 1, &storage);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM error was not generated by GetVertexArrayiv if pname is not ELEMENT_ARRAY_BUFFER_BINDING.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool GetVertexArrayErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}

/******************************** Get Vertex Array Indexed Errors Test Implementation   ********************************/

/** @brief Get Vertex Array Indexed Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetVertexArrayIndexedErrorsTest::GetVertexArrayIndexedErrorsTest(deqp::Context &context)
    : deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed_errors", "Get Vertex Array Indexed Errors Test")
{
}

/** @brief Iterate over Get Vertex Array Indexed Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetVertexArrayIndexedErrorsTest::iterate()
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    /* Get context setup. */
    bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

    if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

        return STOP;
    }

    /* Running tests. */
    bool is_ok    = true;
    bool is_error = false;

    /* Tested Objects. */
    glw::GLuint vao       = 0;
    glw::GLuint not_a_vao = 0;

    /* Dummy storage. */
    glw::GLint storage     = 0;
    glw::GLint64 storage64 = 0;

    /* Bad parameter setup. */
    glw::GLenum bad_pname = 0;

    static const glw::GLenum accepted_pnames[] = {
        GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_VERTEX_ATTRIB_ARRAY_SIZE,       GL_VERTEX_ATTRIB_ARRAY_STRIDE,
        GL_VERTEX_ATTRIB_ARRAY_TYPE,    GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_VERTEX_ATTRIB_ARRAY_INTEGER,
        GL_VERTEX_ATTRIB_ARRAY_LONG,    GL_VERTEX_ATTRIB_ARRAY_DIVISOR,    GL_VERTEX_ATTRIB_RELATIVE_OFFSET};

    {
        bool is_accepted_pname = true;
        while (is_accepted_pname)
        {
            bad_pname++;
            is_accepted_pname = false;
            for (glw::GLuint i = 0; i < DE_LENGTH_OF_ARRAY(accepted_pnames); ++i)
            {
                if (accepted_pnames[i] == bad_pname)
                {
                    is_accepted_pname = true;
                    break;
                }
            }
        }
    }

    try
    {
        /* Prepare valid Objects. */
        gl.createVertexArrays(1, &vao);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");

        /* Prepare invalid VAO. */
        while (gl.isVertexArray(++not_a_vao))
            ;

        /* Not a VAO. */
        gl.getVertexArrayIndexediv(not_a_vao, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &storage);

        is_ok &=
            CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayIndexediv if "
                                             "vaobj is not the name of an existing vertex array object.");

        gl.getVertexArrayIndexed64iv(not_a_vao, 0, GL_VERTEX_BINDING_OFFSET, &storage64);

        is_ok &=
            CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayIndexed64iv "
                                             "if vaobj is not the name of an existing vertex array object.");

        /* Bad parameter. */
        gl.getVertexArrayIndexediv(vao, 0, bad_pname, &storage);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM error was not generated by GetVertexArrayIndexediv if pname is not one of the valid values.");

        /* Bad parameter 64. */
        gl.getVertexArrayIndexed64iv(vao, 0, GL_VERTEX_BINDING_OFFSET + 1, &storage64);

        is_ok &= CheckError(
            GL_INVALID_ENUM,
            "INVALID_ENUM error was not generated by GetVertexArrayIndexed64iv if pname is not VERTEX_BINDING_OFFSET.");
    }
    catch (...)
    {
        is_ok    = false;
        is_error = true;
    }

    /* Clean up. */
    if (vao)
    {
        gl.deleteVertexArrays(1, &vao);
    }

    /* Errors clean up. */
    while (gl.getError())
        ;

    /* Result's setup. */
    if (is_ok)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }
    else
    {
        if (is_error)
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
        }
        else
        {
            m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
        }
    }

    return STOP;
}

/** @brief Compare error returned by GL with expected value and log.
 *
 *  @param [in] expected        Expected error.
 *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
 *
 *  @return True if GL error is equal to expected, false otherwise.
 */
bool GetVertexArrayIndexedErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar *log_message)
{
    /* Shortcut for GL functionality. */
    const glw::Functions &gl = m_context.getRenderContext().getFunctions();

    glw::GLenum error = 0;

    if (expected != (error = gl.getError()))
    {
        m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
                                            << " was observed instead." << tcu::TestLog::EndMessage;

        return false;
    }

    return true;
}
} // namespace VertexArrays
} // namespace DirectStateAccess
} // namespace gl4cts
