/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 * @file  gl4cVertexAttrib64BitTests.hpp
 * @brief Implement conformance tests for GL_ARB_vertex_attrib_64bit functionality
 **/

#include "gl4cVertexAttrib64BitTest.hpp"

#include "gluContextInfo.hpp"
#include "gluStrUtil.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"

#include <algorithm>
#include <iomanip>
#include <string>
#include <vector>

using namespace glw;

namespace VertexAttrib64Bit
{

class Base : public deqp::TestCase
{
public:
    /* Public constructor and destructor */
    Base(deqp::Context &context, const char *name, const char *description);

    virtual ~Base()
    {
    }

    /* Public methods */
    void BuildProgram(const GLchar *fragment_shader_code, GLuint &program_id, const GLchar *vertex_shader_code,
                      GLuint &out_fragment_shader_id, GLuint &out_vertex_shader_id) const;

    void BuildProgramVSOnly(GLuint out_program_id, const GLchar *vertex_shader_code,
                            GLuint &out_vertex_shader_id) const;

    void CompileShader(GLuint id, const GLchar *source_code) const;

    GLint GetMaxVertexAttribs() const;

    void IterateStart();

    tcu::TestNode::IterateResult IterateStop(bool result) const;

    void LinkProgram(GLuint id) const;

    static GLdouble RandomDouble(GLdouble min, GLdouble max);

    void RequireExtension(const GLchar *extension_name) const;

    /* Public fields */
    /* Test framework objects */
    glw::Functions gl; /* prefix "m_" ommitted for readability */
    tcu::TestLog &m_log;
};

/** Constructor
 *
 **/
Base::Base(deqp::Context &context, const char *name, const char *description)
    : TestCase(context, name, description)
    , m_log(m_context.getTestContext().getLog())
{
    /* Nothing to be done here */
}

void Base::BuildProgram(const GLchar *fragment_shader_code, GLuint &program_id, const GLchar *vertex_shader_code,
                        GLuint &out_fragment_shader_id, GLuint &out_vertex_shader_id) const
{
    out_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

    out_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

    CompileShader(out_fragment_shader_id, fragment_shader_code);
    CompileShader(out_vertex_shader_id, vertex_shader_code);

    gl.attachShader(program_id, out_fragment_shader_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");

    gl.attachShader(program_id, out_vertex_shader_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");

    LinkProgram(program_id);
}

/** Builds and links a program object consisting only of vertex shader stage.
 *  The function also creates a vertex shader, assigns it user-provided body
 *  and compiles it.
 *
 *  @param program_id           ID of a created program object to configure.
 *  @param vertex_shader_code   Source code to use for the vertex shader.
 *  @param out_vertex_shader_id Will hold
 **/
void Base::BuildProgramVSOnly(GLuint program_id, const GLchar *vertex_shader_code, GLuint &out_vertex_shader_id) const
{
    out_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

    CompileShader(out_vertex_shader_id, vertex_shader_code);

    gl.attachShader(program_id, out_vertex_shader_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");

    LinkProgram(program_id);
}

void Base::CompileShader(GLuint id, const GLchar *source_code) const
{
    GLint status = 0;

    gl.shaderSource(id, 1, &source_code, 0 /* length */);
    GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");

    gl.compileShader(id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");

    gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");

    if (GL_FALSE == status)
    {
        GLint message_length = 0;
        std::vector<GLchar> message;

        gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &message_length);
        GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");

        message.resize(message_length + 1);

        gl.getShaderInfoLog(id, message_length, &message_length, &message[0]);
        GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");

        m_log << tcu::TestLog::Section("Shader compilation error", "");

        m_log << tcu::TestLog::Message << "Compilation log:\n" << &message[0] << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "Shader source:\n" << source_code << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::EndSection;

        TCU_FAIL("Shader compilation failed");
    }
}

/** Get value of GL_MAX_VERTEX_ATTRIBS
 *
 * Throws exception in case of failure
 *
 * @return Value
 **/
GLint Base::GetMaxVertexAttribs() const
{
    GLint max_vertex_attribs;

    gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");

    return max_vertex_attribs;
}

void Base::IterateStart()
{
    gl = m_context.getRenderContext().getFunctions();
}

tcu::TestNode::IterateResult Base::IterateStop(bool result) const
{
    /* Set test result */
    if (false == result)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    }
    else
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    }

    /* Done */
    return tcu::TestNode::STOP;
}

void Base::LinkProgram(GLuint id) const
{
    GLint status = 0;
    gl.linkProgram(id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");

    gl.getProgramiv(id, GL_LINK_STATUS, &status);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");

    if (GL_FALSE == status)
    {
        GLint message_length = 0;
        std::vector<GLchar> message;

        gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &message_length);
        GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");

        message.resize(message_length + 1);

        gl.getProgramInfoLog(id, message_length, &message_length, &message[0]);
        GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");

        m_log << tcu::TestLog::Section("Program link error", "");

        m_log << tcu::TestLog::Message << "Link log:\n" << &message[0] << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::EndSection;

        TCU_FAIL("Program linking failed");
    }
}

/** Return "random" double value from range <min:max>
 *
 * @return Value
 **/
GLdouble Base::RandomDouble(GLdouble min, GLdouble max)
{
    static const glw::GLushort max_value = 0x2000;
    static glw::GLushort value           = 0x1234;

    GLdouble fraction    = ((GLdouble)value) / ((GLdouble)max_value);
    const GLdouble range = max - min;

    value = static_cast<glw::GLushort>((max_value <= value) ? 0 : value + 1);

    return min + fraction * range;
}

/** Throws tcu::NotSupportedError if requested extensions is not available.
 *
 **/
void Base::RequireExtension(const GLchar *extension_name) const
{
    const std::vector<std::string> &extensions = m_context.getContextInfo().getExtensions();

    if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
    {
        std::string message = "Required extension is not supported: ";
        message.append(extension_name);

        throw tcu::NotSupportedError(message);
    }
}

/** Implementation of conformance test "1", description follows.
 *
 *  Make sure the following errors are generated as specified:
 *
 *  a) GL_INVALID_VALUE should be generated by:
 *     I.    glVertexAttribL1d     ()
 *     II.   glVertexAttribL2d     ()
 *     III.  glVertexAttribL3d     ()
 *     IV.   glVertexAttribL4d     ()
 *     V.    glVertexAttribL1dv    ()
 *     VI.   glVertexAttribL2dv    ()
 *     VII.  glVertexAttribL3dv    ()
 *     VIII. glVertexAttribL4dv    ()
 *     IX.   glVertexAttribLPointer()
 *
 *     if <index> is greater than or equal to GL_MAX_VERTEX_ATTRIBS;
 *
 *  b) GL_INVALID_ENUM should be generated by glVertexAttribLPointer()
 *     if <type> is not GL_DOUBLE;
 *
 *  c) GL_INVALID_VALUE should be generated by glVertexAttribLPointer()
 *     if <size> is not 1, 2, 3 or 4.
 *
 *  d) GL_INVALID_VALUE should be generated by glVertexAttribLPointer()
 *     if <stride> is negative.
 *
 *  e) GL_INVALID_OPERATION should be generated by glVertexAttribLPointer()
 *     if zero is bound to the GL_ARRAY_BUFFER buffer object binding
 *     point and the <pointer> argument is not NULL.
 *
 *  f) GL_INVALID_OPERATION should be generated by glGetVertexAttribLdv()
 *     if <index> is zero.
 **/
class ApiErrorsTest : public Base
{
public:
    /* Public methods */
    ApiErrorsTest(deqp::Context &context);

    virtual ~ApiErrorsTest()
    {
    }

    /* Public methods inheritated from TestCase */
    virtual void deinit();
    virtual tcu::TestNode::IterateResult iterate();

private:
    /* Private methods */
    void invalidEnum(bool &result);
    void invalidOperation(bool &result);
    void invalidValue(bool &result);
    void verifyError(GLenum expected_error, const char *function_name, int line_number, bool &result);

    /* Private fields */
    GLuint m_vertex_array_object_id;
};

/** Constructor
 *
 * @param context CTS context instance
 **/
ApiErrorsTest::ApiErrorsTest(deqp::Context &context)
    : Base(context, "api_errors", "Verify that API routines provoke errors as specified")
    , m_vertex_array_object_id(0)
{
    /* Nothing to be done here */
}

void ApiErrorsTest::deinit()
{
    /* Delete VAO */
    if (0 != m_vertex_array_object_id)
    {
        gl.bindVertexArray(0);
        gl.deleteVertexArrays(1, &m_vertex_array_object_id);
        m_vertex_array_object_id = 0;
    }
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult ApiErrorsTest::iterate()
{
    IterateStart();

    bool result = true;

    RequireExtension("GL_ARB_vertex_attrib_64bit");

    gl.genVertexArrays(1, &m_vertex_array_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");

    gl.bindVertexArray(m_vertex_array_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");

    invalidEnum(result);
    invalidOperation(result);
    invalidValue(result);

    /* Done */
    return IterateStop(result);
}

/** Test if GL_INVALID_ENUM error is provoked as expected
 *
 * @param result If test fails result is set to false, not modified otherwise.
 **/
void ApiErrorsTest::invalidEnum(bool &result)
{
    /*
     *b) GL_INVALID_ENUM should be generated by glVertexAttribLPointer()
     *   if <type> is not GL_DOUBLE;
     */

    static const GLenum type_array[]      = {GL_BYTE,
                                             GL_UNSIGNED_BYTE,
                                             GL_SHORT,
                                             GL_UNSIGNED_SHORT,
                                             GL_INT,
                                             GL_UNSIGNED_INT,
                                             GL_HALF_FLOAT,
                                             GL_FLOAT,
                                             GL_FIXED,
                                             GL_INT_2_10_10_10_REV,
                                             GL_UNSIGNED_INT_2_10_10_10_REV,
                                             GL_UNSIGNED_INT_10F_11F_11F_REV};
    static const GLuint type_array_length = sizeof(type_array) / sizeof(type_array[0]);

    for (GLuint i = 0; i < type_array_length; ++i)
    {
        const GLenum type = type_array[i];

        std::stringstream message;
        message << "VertexAttribLPointer(..., " << glu::getTypeName(type) << " /* type */, ...)";

        gl.vertexAttribLPointer(1 /*index */, 4 /*size */, type, 0 /* stride */, 0 /* pointer */);
        verifyError(GL_INVALID_ENUM, message.str().c_str(), __LINE__, result);
    }

    gl.vertexAttribLPointer(1 /* index */, 4 /*size */, GL_DOUBLE, 0 /* stride */, 0 /* pointer */);
    verifyError(GL_NO_ERROR, "VertexAttribLPointer(..., GL_DOUBLE /* type */, ...)", __LINE__, result);
}

/** Test if GL_INVALID_OPERATON error is provoked as expected
 *
 * @param result If test fails result is set to false, not modified otherwise.
 **/
void ApiErrorsTest::invalidOperation(bool &result)
{

    /*
     *e) GL_INVALID_OPERATION should be generated by glVertexAttribLPointer()
     *   if zero is bound to the GL_ARRAY_BUFFER buffer object binding
     *   point and the <pointer> argument is not NULL.
     */
    static const GLvoid *pointer_array[]     = {(GLvoid *)1, (GLvoid *)4, (GLvoid *)-16};
    static const GLuint pointer_array_length = sizeof(pointer_array) / sizeof(pointer_array[0]);

    gl.bindBuffer(GL_ARRAY_BUFFER, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

    for (GLuint i = 0; i < pointer_array_length; ++i)
    {
        const GLvoid *pointer = pointer_array[i];

        std::stringstream message;
        message << "VertexAttribLPointer(..., " << pointer << " /* pointer */)";

        gl.vertexAttribLPointer(1 /* index */, 4 /*size */, GL_DOUBLE, 0 /* stride */, pointer);
        verifyError(GL_INVALID_OPERATION, message.str().c_str(), __LINE__, result);
    }
}

/** Test if GL_INVALID_VALUE error is provoked as expected
 *
 * @param result If test fails result is set to false, not modified otherwise.
 **/
void ApiErrorsTest::invalidValue(bool &result)
{
    GLint max_vertex_attribs = GetMaxVertexAttribs();
    const GLdouble vector[4] = {0.0, 0.0, 0.0, 0.0};

    /*
     * a) GL_INVALID_VALUE should be generated by:
     *    I.    glVertexAttribL1d     ()
     *    II.   glVertexAttribL2d     ()
     *    III.  glVertexAttribL3d     ()
     *    IV.   glVertexAttribL4d     ()
     *    V.    glVertexAttribL1dv    ()
     *    VI.   glVertexAttribL2dv    ()
     *    VII.  glVertexAttribL3dv    ()
     *    VIII. glVertexAttribL4dv    ()
     *    IX.   glVertexAttribLPointer()
     *
     *    if <index> is greater than or equal to GL_MAX_VERTEX_ATTRIBS;
     */
    gl.vertexAttribL1d(max_vertex_attribs, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL1d(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL1d(max_vertex_attribs + 1, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL1d(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL2d(max_vertex_attribs, 0.0, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL2d(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL2d(max_vertex_attribs + 1, 0.0, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL2d(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL3d(max_vertex_attribs, 0.0, 0.0, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL3d(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL3d(max_vertex_attribs + 1, 0.0, 0.0, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL3d(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL4d(max_vertex_attribs, 0.0, 0.0, 0.0, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL4d(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL4d(max_vertex_attribs + 1, 0.0, 0.0, 0.0, 0.0);
    verifyError(GL_INVALID_VALUE, "VertexAttribL4d(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL1dv(max_vertex_attribs, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL1dv(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL1dv(max_vertex_attribs + 1, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL1dv(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL2dv(max_vertex_attribs, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL2dv(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL2dv(max_vertex_attribs + 1, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL2dv(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL3dv(max_vertex_attribs, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL3dv(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL3dv(max_vertex_attribs + 1, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL3dv(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribL4dv(max_vertex_attribs, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL4dv(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribL4dv(max_vertex_attribs + 1, vector);
    verifyError(GL_INVALID_VALUE, "VertexAttribL4dv(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    gl.vertexAttribLPointer(max_vertex_attribs, 4 /*size */, GL_DOUBLE, 0 /* stride */, 0 /* pointer */);
    verifyError(GL_INVALID_VALUE, "VertexAttribLPointer(GL_MAX_VERTEX_ATTRIBS, ...)", __LINE__, result);

    gl.vertexAttribLPointer(max_vertex_attribs + 1, 4 /*size */, GL_DOUBLE, 0 /* stride */, 0 /* pointer */);
    verifyError(GL_INVALID_VALUE, "VertexAttribLPointer(GL_MAX_VERTEX_ATTRIBS + 1, ...)", __LINE__, result);

    /*
     *c) GL_INVALID_VALUE should be generated by glVertexAttribLPointer()
     *if <size> is not 1, 2, 3 or 4.
     */
    gl.vertexAttribLPointer(1, 0 /*size */, GL_DOUBLE, 0 /* stride */, 0 /* pointer */);
    verifyError(GL_INVALID_VALUE, "VertexAttribLPointer(..., 0 /* size */, ...)", __LINE__, result);

    gl.vertexAttribLPointer(1, 5 /*size */, GL_DOUBLE, 0 /* stride */, 0 /* pointer */);
    verifyError(GL_INVALID_VALUE, "VertexAttribLPointer(..., 5 /* size */, ...)", __LINE__, result);

    /*
     *d) GL_INVALID_VALUE should be generated by glVertexAttribLPointer()
     *   if <stride> is negative.
     */
    gl.vertexAttribLPointer(1, 4 /*size */, GL_DOUBLE, -1 /* stride */, 0 /* pointer */);
    verifyError(GL_INVALID_VALUE, "VertexAttribLPointer(..., -1 /* stride */, ...)", __LINE__, result);

    gl.vertexAttribLPointer(1, 4 /*size */, GL_DOUBLE, -4 /* stride */, 0 /* pointer */);
    verifyError(GL_INVALID_VALUE, "VertexAttribLPointer(..., -4 /* stride */, ...)", __LINE__, result);
}

/** Verify that GetError returns expected error code. In case of failure logs error message.
 *
 * @param expected_error Expected error code
 * @param function_name  Name of function to log in case of error
 * @param line_number    Line number, for reference
 * @param result         Result of verification, set to false in case of failure, not modified otherwise
 **/
void ApiErrorsTest::verifyError(GLenum expected_error, const char *function_name, int line_number, bool &result)
{
    GLenum error = gl.getError();

    if (expected_error != error)
    {
        m_log << tcu::TestLog::Section("Error", "");

        m_log << tcu::TestLog::Message << "GetError returned: " << glu::getErrorStr(error) << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "Expected: " << glu::getErrorStr(expected_error) << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "Operation: " << function_name << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "File: " << __FILE__ << "@" << line_number << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::EndSection;

        result = false;
    }
}

/** Implementation of conformance test "2", description follows.
 *
 *  Make sure that all available generic vertex attributes report
 *  correct values when queried with corresponding glGetVertexAttribL*()
 *  function, after they had been set with a glVertexAttribL*() call.
 *  All double-precision floating-point setters and getters should
 *  be checked, as enlisted below:
 *
 *  * glVertexAttribL1d ()
 *  * glVertexAttribL2d ()
 *  * glVertexAttribL3d ()
 *  * glVertexAttribL4d ()
 *  * glVertexAttribL1dv()
 *  * glVertexAttribL2dv()
 *  * glVertexAttribL3dv()
 *  * glVertexAttribL4dv()
 *
 *  The test should also verify glGetVertexAttribiv() and
 *  glGetVertexAttribLdv() report correct property values for all
 *  vertex attribute arrays configured with glVertexAttribLPointer()
 *  call. Two different configurations should be checked for each
 *  VAA index.
 **/
class GetVertexAttribTest : public Base
{
public:
    /* Public constructor and destructor */
    GetVertexAttribTest(deqp::Context &context);

    virtual ~GetVertexAttribTest()
    {
    }

    /* Public methods inheritated from TestCase */
    virtual void deinit();
    virtual tcu::TestNode::IterateResult iterate();

private:
    /* Private types */
    /** Template class to store vertex attribute data
     *
     * @tparam SIZE Number of elements
     **/
    template <GLuint SIZE>
    class vertexAttribute
    {
    public:
        vertexAttribute(GLdouble min, GLdouble max)
        {
            for (GLuint i = 0; i < SIZE; ++i)
            {
                m_array[i] = RandomDouble(min, max);
            }
        }

        GLdouble m_array[SIZE];
    };

    /* Private methods */
    /* checkVertexAttrib methods */
    template <GLuint SIZE>
    void checkVertexAttribLd(GLuint index, bool &result) const;

    template <GLuint SIZE>
    void checkVertexAttribLdv(GLuint index, bool &result) const;

    void checkVertexAttribLPointer(GLuint index, bool &result) const;

    /* Wrappers for vertexAttribLd routines */
    template <GLuint SIZE>
    void vertexAttribLd(GLuint index, const vertexAttribute<SIZE> &attribute) const;

    template <GLuint SIZE>
    void vertexAttribLdv(GLuint index, const vertexAttribute<SIZE> &attribute) const;

    /* Utilities */
    bool compareDoubles(const GLdouble *a, const GLdouble *b, GLuint length) const;

    void initTest();

    bool verifyResults(GLuint index, GLenum pname, GLint expected_value) const;

    bool verifyResults(const GLdouble *set_values, GLuint length, GLuint index, const char *function_name,
                       int line_number) const;

    bool verifyPointerResults(const GLdouble *set_values, GLuint length, GLuint index, int line_number) const;

    void logError(const GLdouble *set_values, const GLdouble *get_values, GLuint length, const char *function_name,
                  GLuint index, int line_number) const;

    /* Private fields */
    const GLdouble m_epsilon;
    static const GLuint m_n_iterations = 128;
    GLint m_max_vertex_attribs;
    const GLdouble m_min;
    const GLdouble m_max;

    /* GL objects */
    GLuint m_buffer_object_id;
    GLuint m_vertex_array_object_id;
};

/** Constructor
 *
 * @param context CTS context
 **/
GetVertexAttribTest::GetVertexAttribTest(deqp::Context &context)
    : Base(context, "get_vertex_attrib", "Verify that GetVertexAttribL* routines")
    , m_epsilon(0.0)
    , m_max_vertex_attribs(0)
    , m_min(-16.384)
    , m_max(16.384)
    , m_buffer_object_id(0)
    , m_vertex_array_object_id(0)
{
    /* Nothing to be done */
}

/** Clean up after test
 *
 **/
void GetVertexAttribTest::deinit()
{
    if (0 != m_buffer_object_id)
    {
        gl.bindBuffer(GL_ARRAY_BUFFER, 0);
        gl.deleteBuffers(1, &m_buffer_object_id);
        m_buffer_object_id = 0;
    }

    if (0 != m_vertex_array_object_id)
    {
        gl.bindVertexArray(0);
        gl.deleteVertexArrays(1, &m_vertex_array_object_id);
        m_vertex_array_object_id = 0;
    }
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult GetVertexAttribTest::iterate()
{
    IterateStart();

    bool result = true;

    RequireExtension("GL_ARB_vertex_attrib_64bit");

    initTest();

    for (GLint i = 1; i < m_max_vertex_attribs; ++i)
    {
        checkVertexAttribLd<1>(i, result);
        checkVertexAttribLd<2>(i, result);
        checkVertexAttribLd<3>(i, result);
        checkVertexAttribLd<4>(i, result);
        checkVertexAttribLdv<1>(i, result);
        checkVertexAttribLdv<2>(i, result);
        checkVertexAttribLdv<3>(i, result);
        checkVertexAttribLdv<4>(i, result);
        checkVertexAttribLPointer(i, result);
    }

    /* Done */
    return IterateStop(result);
}

/** Verifies glVertexAttribLd routines
 *
 * @tparam SIZE Size of vertex attribute
 *
 * @param index  Index of vertex attribute, starts from 1.
 * @param result Result of verification, set to false in case of failure, not modified otherwise.
 **/
template <GLuint SIZE>
void GetVertexAttribTest::checkVertexAttribLd(GLuint index, bool &result) const
{
    std::stringstream function_name;

    function_name << "VertexAttribL" << SIZE << "d";

    for (GLuint i = 0; i < m_n_iterations; ++i)
    {
        vertexAttribute<SIZE> vertex_attribute(m_min, m_max);

        vertexAttribLd<SIZE>(index, vertex_attribute);
        GLU_EXPECT_NO_ERROR(gl.getError(), function_name.str().c_str());

        if (false == verifyResults(vertex_attribute.m_array, SIZE, index, function_name.str().c_str(), __LINE__))
        {
            result = false;
            return;
        }
    }
}

/** Verifies glVertexAttribLdv routines
 *
 * @tparam SIZE Size of vertex attribute
 *
 * @param index  Index of vertex attribute, starts from 1.
 * @param result Result of verification, set to false in case of failure, not modified otherwise.
 **/
template <GLuint SIZE>
void GetVertexAttribTest::checkVertexAttribLdv(GLuint index, bool &result) const
{
    std::stringstream function_name;

    function_name << "VertexAttribL" << SIZE << "dv";

    for (GLuint i = 0; i < m_n_iterations; ++i)
    {
        vertexAttribute<SIZE> vertex_attribute(m_min, m_max);

        vertexAttribLdv<SIZE>(index, vertex_attribute);
        GLU_EXPECT_NO_ERROR(gl.getError(), function_name.str().c_str());

        if (false == verifyResults(vertex_attribute.m_array, SIZE, index, function_name.str().c_str(), __LINE__))
        {
            result = false;
            return;
        }
    }
}

/** Verifies glVertexAttribLPointer
 *
 * @param index  Index of vertex attribute, starts from 1.
 * @param result Result of verification, set to false in case of failure, not modified otherwise.
 **/
void GetVertexAttribTest::checkVertexAttribLPointer(GLuint index, bool &result) const
{
    static const GLuint max_size   = 4;
    static const GLuint max_stride = 16;

    gl.bindVertexArray(m_vertex_array_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

    for (GLuint size = 1; size <= max_size; ++size)
    {
        for (GLuint stride = 0; stride < max_stride; ++stride)
        {
            gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
            GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

            gl.vertexAttribLPointer(index, size, GL_DOUBLE, stride, (GLvoid *)0);
            GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");

            gl.bindBuffer(GL_ARRAY_BUFFER, 0);
            GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, m_buffer_object_id))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, size))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, stride))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, GL_DOUBLE))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_FALSE))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, GL_FALSE))
            {
                result = false;
            }

            if (false == verifyResults(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0))
            {
                result = false;
            }
        }
    }
}

/** Wrapper of vertexAttribLd routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 1.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLd<1>(GLuint index,
                                            const GetVertexAttribTest::vertexAttribute<1> &attribute) const
{
    gl.vertexAttribL1d(index, attribute.m_array[0]);
}

/** Wrapper of vertexAttribLd routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 2.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLd<2>(GLuint index,
                                            const GetVertexAttribTest::vertexAttribute<2> &attribute) const
{
    gl.vertexAttribL2d(index, attribute.m_array[0], attribute.m_array[1]);
}

/** Wrapper of vertexAttribLd routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 3.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLd<3>(GLuint index,
                                            const GetVertexAttribTest::vertexAttribute<3> &attribute) const
{
    gl.vertexAttribL3d(index, attribute.m_array[0], attribute.m_array[1], attribute.m_array[2]);
}

/** Wrapper of vertexAttribLd routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 4.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLd<4>(GLuint index,
                                            const GetVertexAttribTest::vertexAttribute<4> &attribute) const
{
    gl.vertexAttribL4d(index, attribute.m_array[0], attribute.m_array[1], attribute.m_array[2], attribute.m_array[3]);
}

/** Wrapper of vertexAttribLdv routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 1.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLdv<1>(GLuint index,
                                             const GetVertexAttribTest::vertexAttribute<1> &attribute) const
{
    gl.vertexAttribL1dv(index, attribute.m_array);
}

/** Wrapper of vertexAttribLdv routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 2.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLdv<2>(GLuint index,
                                             const GetVertexAttribTest::vertexAttribute<2> &attribute) const
{
    gl.vertexAttribL2dv(index, attribute.m_array);
}

/** Wrapper of vertexAttribLdv routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 3.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLdv<3>(GLuint index,
                                             const GetVertexAttribTest::vertexAttribute<3> &attribute) const
{
    gl.vertexAttribL3dv(index, attribute.m_array);
}

/** Wrapper of vertexAttribLdv routines.
 *
 * @tparam SIZE Size of vertex attribute. Specialisation for 4.
 *
 * @param index     Index parameter
 * @param attribute Vertex attribute data are taken from provided instance of vertexAttribute
 **/
template <>
void GetVertexAttribTest::vertexAttribLdv<4>(GLuint index,
                                             const GetVertexAttribTest::vertexAttribute<4> &attribute) const
{
    gl.vertexAttribL4dv(index, attribute.m_array);
}

/** Compare two arrays of doubles
 *
 * @param a      First array of doubles
 * @param b      Second array of doubles
 * @param length Length of arrays
 *
 * @return true if arrays are considered equal, false otherwise
 **/
bool GetVertexAttribTest::compareDoubles(const GLdouble *a, const GLdouble *b, GLuint length) const
{
    for (GLuint i = 0; i < length; ++i)
    {
        if ((b[i] > a[i] + m_epsilon) || (b[i] < a[i] - m_epsilon))
        {
            return false;
        }
    }

    return true;
}

/** Prepare buffer and vertex array object, get max vertex attributes
 *
 **/
void GetVertexAttribTest::initTest()
{
    gl.genBuffers(1, &m_buffer_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

    gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

    gl.bufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLdouble), 0, GL_DYNAMIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BufferStorage");

    gl.genVertexArrays(1, &m_vertex_array_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");

    m_max_vertex_attribs = GetMaxVertexAttribs();
}

/** Logs message informing that values got with GetVertexAttribLdv do not match set with "function_name"
 *
 * @param set_values    Values set with "function_name"
 * @param get_values    Values extracted with GetVertexAttribLdv
 * @param length        Length of "get/set_values" arrays
 * @param function_name Name of function used to set vertex attributes
 * @param index         Index of vertex attribute
 * @param line_number   Line number refereing to location of "function_name"
 **/
void GetVertexAttribTest::logError(const GLdouble *set_values, const GLdouble *get_values, GLuint length,
                                   const char *function_name, GLuint index, int line_number) const
{
    m_log << tcu::TestLog::Section("Error", "");

    tcu::MessageBuilder message = m_log << tcu::TestLog::Message;
    message << "Values set with " << function_name << " [";

    for (GLuint i = 0; i < length; ++i)
    {
        message << std::setprecision(24) << set_values[i];

        if (length != i + 1)
        {
            message << ", ";
        }
    }

    message << "]" << tcu::TestLog::EndMessage;

    message = m_log << tcu::TestLog::Message;
    message << "Values got with GetVertexAttribLdv"
            << " [";

    for (GLuint i = 0; i < length; ++i)
    {
        message << std::setprecision(24) << get_values[i];

        if (length != i + 1)
        {
            message << ", ";
        }
    }

    message << "]" << tcu::TestLog::EndMessage;

    m_log << tcu::TestLog::Message << "Index: " << index << tcu::TestLog::EndMessage;

    m_log << tcu::TestLog::Message << "File: " << __FILE__ << "@" << line_number << tcu::TestLog::EndMessage;

    m_log << tcu::TestLog::EndSection;
}

/** Verify results of vertexAttribLPointer
 *
 * @param index          Index of vertex attribute
 * @param pname          Parameter name to be querried with getVertexAttribiv and getVertexAttribLdv
 * @param expected_value Expected valued
 *
 * @return true if Results match expected_value, false otherwise
 **/
bool GetVertexAttribTest::verifyResults(GLuint index, GLenum pname, GLint expected_value) const
{
    GLint params_getVertexAttribiv     = 0;
    GLdouble params_getVertexAttribLdv = 0.0;

    gl.getVertexAttribiv(index, pname, &params_getVertexAttribiv);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GetVertexAttribiv");

    gl.getVertexAttribLdv(index, pname, &params_getVertexAttribLdv);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GetVertexAttribLdv");

    if ((expected_value != params_getVertexAttribiv) || (expected_value != params_getVertexAttribLdv))
    {
        m_log << tcu::TestLog::Section("Error", "");

        m_log << tcu::TestLog::Message << "GetVertexAttribiv(" << index << "/* index */, "
              << glu::getVertexAttribParameterNameName(pname) << "/* pname */)" << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "Result: " << params_getVertexAttribiv << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "GetVertexAttribLdv(" << index << "/* index */, "
              << glu::getVertexAttribParameterNameName(pname) << "/* pname */)" << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "Result: " << params_getVertexAttribLdv << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "Expected: " << expected_value << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::Message << "File: " << __FILE__ << "@" << __LINE__ << tcu::TestLog::EndMessage;

        m_log << tcu::TestLog::EndSection;

        return false;
    }

    return true;
}

/** Verify results of vertexAttribLdv routines
 *
 * @param set_values    Values set with vertexAttribLdv
 * @param length        Length of "set_values" array
 * @param index         Index of vertex attribute
 * @param function_name Name of function used to set, it will be used for error logging
 * @param line_number   Line number refering to location of "function_name", used to log errors
 *
 * @return true if results match set values, false otherwise
 **/
bool GetVertexAttribTest::verifyResults(const GLdouble *set_values, GLuint length, GLuint index,
                                        const char *function_name, int line_number) const
{
    GLdouble results[4] = {0.0, 0.0, 0.0, 0.0};

    gl.getVertexAttribLdv(index, GL_CURRENT_VERTEX_ATTRIB, results);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GetVertexAttribLdv");

    if (false == compareDoubles(set_values, results, length))
    {
        logError(set_values, results, length, function_name, index, line_number);

        return false;
    }

    return true;
}

/** Implementation of conformance test "3", description follows.
 *
 *  Verify that a total of GL_MAX_VERTEX_ATTRIBS double and dvec2,
 *  (GL_MAX_VERTEX_ATTRIBS / 2) dvec3, dvec4 and dmat2,
 *  (GL_MAX_VERTEX_ATTRIBS / 3) dmat3x2,
 *  (GL_MAX_VERTEX_ATTRIBS / 4) dmat4x2, dmat2x3 and dmat2x4,
 *  (GL_MAX_VERTEX_ATTRIBS / 6) dmat3 and dmat3x4,
 *  (GL_MAX_VERTEX_ATTRIBS / 8) dmat4x3 and dmat4,
 *  attributes can be used in each shader stage at the same time.
 *
 *  The test should run in 7 iterations:
 *
 *  a) In the first iteration, (GL_MAX_VERTEX_ATTRIBS / 2) double
 *      attributes and (GL_MAX_VERTEX_ATTRIBS / 2) dvec2 attributes
 *      should be defined in a vertex shader. The test should verify
 *      the values exposed by these attributes and write 1 to an
 *      output variable if all attribute values are found to be
 *      correct, or set it to 0 if at least one of the retrieved
 *      values is found invalid.
 *
 *      Double attributes should be assigned the value:
 *                  (n_attribute + gl_VertexID * 2)
 *
 *      Dvec2 attribute components should be assigned the following
 *      vector values:
 *                  (n_attribute + gl_VertexID * 3 + 1,
 *                  n_attribute + gl_VertexID * 3 + 2)
 *
 *  b) In the second iteration, (GL_MAX_VERTEX_ATTRIBS / 4) dvec3
 *      and (GL_MAX_VERTEX_ATTRIBS / 4) dvec4 attributes should be
 *      defined in a vertex shader. Verification of the data exposed
 *      by these input variables should be performed as in step a),
 *      with an exception of the values passed through the attributes.
 *
 *      Dvec3 attribute components should be assigned the following
 *      vector values:
 *                  (n_attribute + gl_VertexID * 3 + 0,
 *                  n_attribute + gl_VertexID * 3 + 1,
 *                  n_attribute + gl_VertexID * 3 + 2).
 *
 *      Dvec4 attribute components should be assigned the following
 *      vector values:
 *                  (n_attribute + gl_VertexID * 4 + 0,
 *                  n_attribute + gl_VertexID * 4 + 1,
 *                  n_attribute + gl_VertexID * 4 + 2,
 *                  n_attribute + gl_VertexID * 4 + 3).
 *
 *      n_attribute corresponds to the ordinal number of each attribute,
 *      as defined in the shader.
 *
 *  c) In the third iteration, (GL_MAX_VERTEX_ATTRIBS / 2) dmat2 attributes
 *      should be defined in a vertex shader. Verification of the data exposed
 *      by these input variables should be performed as in step a), with an
 *      exception of the values passed through the attributes.
 *
 *      Subsequent matrix elements should be assigned the following value:
 *              (n_type + n_attribute + gl_VertexID * 16 + n_value)
 *
 *      n_type corresponds to the ordinal number of type as per the
 *      order at the beginning of the paragraph.
 *      n_value corresponds to the ordinal number of the element.
 *
 *  d) In the fourth iteration, (GL_MAX_VERTEX_ATTRIBS / 8) dmat3x2 and
 *      (GL_MAX_VERTEX_ATTRIBS / 8) dmat4x2 attributes should be defined in a
 *      vertex shader. Verification of the data exposed by these input
 *      variables should be performed as in step a), with an exception of the
 *      values passed through the attributes.
 *
 *      Use the same element values as in step c)
 *
 *  e) In the fifth iteration, (GL_MAX_VERTEX_ATTRIBS / 8) dmat2x3 and
 *      (GL_MAX_VERTEX_ATTRIBS / 8) dmat2x4 attributes should be defined in a
 *      vertex shader. Verification of the data exposed by these input
 *      variables should be performed as in step a), with an exception of the
 *      values passed through the attributes.
 *
 *      Use the same element values as in step c)
 *
 *  f) In the sixth iteration, (GL_MAX_VERTEX_ATTRIBS / 12) dmat3 and
 *      (GL_MAX_VERTEX_ATTRIBS / 12) dmat3x4 attributes should be defined in a
 *      vertex shader. Verification of the data exposed by these input
 *      variables should be performed as in step a), with an exception of the
 *      values passed through the attributes.
 *
 *      Use the same element values as in step c)
 *
 *  g) In the seventh iteration, (GL_MAX_VERTEX_ATTRIBS / 16) dmat4x3 and
 *      (GL_MAX_VERTEX_ATTRIBS / 16) dmat4 attributes should be defined in a
 *      vertex shader. Verification of the data exposed by these input
 *      variables should be performed as in step a), with an exception of the
 *      values passed through the attributes.
 *
 *      Use the same element values as in step c)
 *
 *  h) Modify the language of cases a) - g), so that instead of separate
 *      attributes, all attributes of the same type are now a single arrayed
 *      attribute.
 *
 *  Vertex shaders from both iterations should be used to form two program
 *  objects. 1024 vertices should be used for a non-indiced GL_POINTS
 *  draw call, made using those two programs.
 *
 *  All glVertexAttribL*() and glVertexAttribLPointer() should be used for
 *  the purpose of the test. The following draw call API functions should be
 *  tested:
 *
 *  a) glDrawArrays()
 *  b) glDrawArraysInstanced(), primcount > 1, zero vertex attrib divisor
 *  c) glDrawArraysInstanced(), primcount > 1, non-zero vertex attrib divisor
 *  d) glDrawElements()
 *  e) glDrawElementsInstanced(), properties as in b)
 *  f) glDrawElementsInstanced(), properties as in c)
 *
 *  All shaders used by the test should come in two flavors:
 *
 *  - one where attribute locations are explicitly defined in the body;
 *  - the other one where attribute locations are to be assigned by
 *      the compiler.
 *
 *  For each shader, the test should make sure that all attributes have
 *  been assigned correct amount of locations. (eg: dvec4 attribute
 *  should be granted exactly one location).
 *
 *  Data stored in output variables should be XFBed to the test.
 *  The test passes if the retrieved values are found to be valid
 *  for all vertex shader invocations.
 **/

class LimitTest : public Base
{
public:
    /* Public constructor and destructor */
    LimitTest(deqp::Context &context);

    virtual ~LimitTest()
    {
    }

    /* Public methods inheritated from TestCase */
    virtual void deinit();
    virtual tcu::TestNode::IterateResult iterate();

private:
    /* Private types */
    class programInfo
    {
    public:
        programInfo(const glw::Functions &gl);
        ~programInfo();

        GLuint m_fragment_shader_id;
        GLuint m_program_id;
        GLuint m_vertex_shader_id;

    private:
        const glw::Functions &gl;
    };

    struct attributeConfiguration
    {
        attributeConfiguration()
            : m_n_attributes_per_group(0)
            , m_n_elements(0)
            , m_n_rows(0)
            , m_n_types(0)
            , m_type_names(0)
            , m_vertex_length(0)
        {
            /* nothing to be done */
        }

        GLint m_n_attributes_per_group;
        const GLint *m_n_elements;
        const GLint *m_n_rows;
        GLint m_n_types;
        const GLchar *const *m_type_names;
        GLint m_vertex_length;
    };

    typedef GLint _varyingType;

    /* Private enums */
    enum _iteration
    {
        DOUBLE_DVEC2,    // 1 + 1         = 2
        DVEC3_DVEC4,     // 2 + 2         = 4
        DMAT2,           // 2 * 1         = 2
        DMAT3X2_DMAT4X2, // 3 * 1 + 4 * 1 = 8
        DMAT2X3_DMAT2X4, // 2 * 2 + 2 * 2 = 8
        DMAT3_DMAT3X4,   // 3 * 2 + 3 * 2 = 12
        DMAT4X3_DMAT4    // 4 * 2 + 4 * 2 = 16
    };

    enum _attributeType
    {
        REGULAR,
        PER_INSTANCE,
        CONSTANT,
    };

    /*Private methods */
    GLint calculateAttributeGroupOffset(const attributeConfiguration &configuration, GLint index) const;

    GLint calculateAttributeLocation(const attributeConfiguration &configuration, GLint attribute, GLint n_type) const;

    void calculateVertexLength(attributeConfiguration &configuration) const;

    void configureAttribute(_iteration iteration, const attributeConfiguration &configuration, GLint n_type,
                            GLuint program_id, bool use_arrays, bool use_vertex_array) const;

    void getProgramDetails(_iteration iteration, bool use_arrays, bool use_locations, bool use_vertex_attrib_divisor,
                           std::string &out_varying_name, std::string &out_vertex_shader_code) const;

    void getVertexArrayConfiguration(_iteration iteration, attributeConfiguration &out_configuration) const;

    void logTestIterationAndConfig(_iteration iteration, _attributeType attribute_type, bool use_arrays,
                                   bool use_locations) const;

    void prepareProgram(_iteration iteration, bool use_arrays, bool use_locations, bool use_vertex_attrib_divisor,
                        programInfo &programInfo);

    void prepareVertexArray(_iteration iteration, _attributeType attribute_type, GLuint program_id,
                            bool use_arrays) const;

    void prepareVertexArrayBuffer(_iteration iteration);

    void setAttributes(_iteration iteration, const attributeConfiguration &configuration, GLuint vertex,
                       std::vector<GLdouble> &out_buffer_data) const;

    void setAttributes_a(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                         std::vector<GLdouble> &out_buffer_data) const;

    void setAttributes_a_scalar(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                                std::vector<GLdouble> &out_buffer_data) const;

    void setAttributes_a_vec(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                             std::vector<GLdouble> &out_buffer_data) const;

    void setAttributes_b(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                         std::vector<GLdouble> &out_buffer_dataa) const;

    void setAttributes_c(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                         std::vector<GLdouble> &out_buffer_data) const;

    bool testDrawArrays() const;
    bool testDrawArraysInstanced() const;
    bool testDrawElements() const;
    bool testDrawElementsInstanced() const;
    void testInit();
    bool testIteration(_iteration iteration);

    bool testProgram(_iteration iteration, GLuint program_id, bool use_arrays) const;

    bool testProgramWithConstant(_iteration iteration, GLuint program_id, bool use_arrays) const;

    bool testProgramWithDivisor(_iteration iteration, GLuint program_id, bool use_arrays) const;

    bool verifyResult(bool use_instancing) const;

    /* Private fields */
    /* Constants */
    static const GLint m_array_attribute = -1;
    static const GLuint m_n_instances    = 16;
    static const GLuint m_n_varyings     = 1;
    static const GLuint m_n_vertices     = 1024;
    static const GLuint m_transform_feedback_buffer_size =
        sizeof(_varyingType) * m_n_instances * m_n_vertices * m_n_varyings;

    /* GL objects */
    GLuint m_element_array_buffer_id;
    GLuint m_transoform_feedback_buffer_id;
    GLuint m_vertex_array_buffer_id;
    GLuint m_vertex_array_object_id;
};

/** Constructor
 *
 **/
LimitTest::programInfo::programInfo(const glw::Functions &gl_functions)
    : m_fragment_shader_id(0)
    , m_program_id(0)
    , m_vertex_shader_id(0)
    , gl(gl_functions)
{
    /* Nothing to be done here */
}

/** Destructor
 *
 **/
LimitTest::programInfo::~programInfo()
{
    if (0 != m_program_id)
    {
        gl.deleteProgram(m_program_id);
        m_program_id = 0;
    }

    if (0 != m_fragment_shader_id)
    {
        gl.deleteShader(m_fragment_shader_id);
        m_fragment_shader_id = 0;
    }

    if (0 != m_vertex_shader_id)
    {
        gl.deleteShader(m_vertex_shader_id);
        m_vertex_shader_id = 0;
    }
}

/** Constructor
 *
 * @param context CTS context
 **/
LimitTest::LimitTest(deqp::Context &context)
    : Base(context, "limits_test", "Verify that maximum allowed number of attribiutes can be used")
    , m_element_array_buffer_id(0)
    , m_transoform_feedback_buffer_id(0)
    , m_vertex_array_buffer_id(0)
    , m_vertex_array_object_id(0)
{
    /* Nothing to be done here */
}

/** Clean up after test
 *
 **/
void LimitTest::deinit()
{
    /* Restore default settings */
    if (0 != gl.disable)
    {
        gl.disable(GL_RASTERIZER_DISCARD);
    }

    /* Delete GL objects */
    if (0 != m_element_array_buffer_id)
    {
        gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        gl.deleteBuffers(1, &m_element_array_buffer_id);
        m_element_array_buffer_id = 0;
    }

    if (0 != m_transoform_feedback_buffer_id)
    {
        gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
        gl.deleteBuffers(1, &m_transoform_feedback_buffer_id);
        m_transoform_feedback_buffer_id = 0;
    }

    if (0 != m_vertex_array_buffer_id)
    {
        gl.bindBuffer(GL_ARRAY_BUFFER, 0);
        gl.deleteBuffers(1, &m_vertex_array_buffer_id);
        m_vertex_array_buffer_id = 0;
    }

    if (0 != m_vertex_array_object_id)
    {
        gl.bindVertexArray(0);
        gl.deleteVertexArrays(1, &m_vertex_array_object_id);
        m_vertex_array_object_id = 0;
    }
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult LimitTest::iterate()
{
    IterateStart();

    bool result = true;

    RequireExtension("GL_ARB_vertex_attrib_64bit");

    testInit();

    if (false == testIteration(DOUBLE_DVEC2))
    {
        result = false;
    }

    if (false == testIteration(DVEC3_DVEC4))
    {
        result = false;
    }

    if (false == testIteration(DMAT2))
    {
        result = false;
    }

    if (false == testIteration(DMAT3X2_DMAT4X2))
    {
        result = false;
    }

    if (false == testIteration(DMAT2X3_DMAT2X4))
    {
        result = false;
    }

    if (false == testIteration(DMAT3_DMAT3X4))
    {
        result = false;
    }

    if (false == testIteration(DMAT4X3_DMAT4))
    {
        result = false;
    }

    /* Done */
    return IterateStop(result);
}

/** Calculate offset of "n_type" attributes group in doubles, tightly packed, for vertex buffer offsets
 *
 * @param configuration Attribute configuration
 * @param n_type        Attribute type ordinal number
 *
 * @return Calculated offset
 **/
GLint LimitTest::calculateAttributeGroupOffset(const attributeConfiguration &configuration, GLint n_type) const
{
    GLint result = 0;

    for (GLint i = 0; i < n_type; ++i)
    {
        result += configuration.m_n_attributes_per_group * configuration.m_n_elements[i];
    }

    return result;
}

/** Calculates attribute location for manually setting "layout(location =)".
 *  Results are in reveresed order of vertex buffer
 *
 * @param configuration Attribute configuration
 * @param attribute     Intex of attribute in "n_type" group
 * @param n_type        Ordinal number of type
 *
 * @return Calculated location
 **/
GLint LimitTest::calculateAttributeLocation(const attributeConfiguration &configuration, GLint attribute,
                                            GLint n_type) const
{
    const GLint n_types = configuration.m_n_types;
    GLint result        = 0;

    /* Amount of location required for types after given "n_type" */
    for (GLint i = n_types - 1; i > n_type; --i)
    {
        const GLint n_elements = configuration.m_n_elements[i];
        const GLint n_rows     = configuration.m_n_rows[i];
        const GLint n_columns  = n_elements / n_rows;

        result += n_columns * configuration.m_n_attributes_per_group;
    }

    /* Amount of locations required for attributes after given attribute in given "n_type" */
    /* Arrayed attributes does not have any attributes after */
    if (m_array_attribute != attribute)
    {
        const GLint n_elements = configuration.m_n_elements[n_type];
        const GLint n_rows     = configuration.m_n_rows[n_type];
        const GLint n_columns  = n_elements / n_rows;

        result += n_columns * (configuration.m_n_attributes_per_group - 1 - attribute);
    }

    /* Done */
    return result;
}

/** Calculate vertex length in "doubles", tightly packed, for offset in vertex buffer
 *
 * @param configuration Attribute configuration, result is store as field ::m_vertex_length
 **/
void LimitTest::calculateVertexLength(attributeConfiguration &configuration) const
{
    GLint result = 0;

    for (GLint i = 0; i < configuration.m_n_types; ++i)
    {
        result += configuration.m_n_elements[i] * configuration.m_n_attributes_per_group;
    }

    configuration.m_vertex_length = result;
}

/** Configure attributes in given "n_type" group
 *
 * @param iteration        Iteration id
 * @param configuration    Configuration of attributes
 * @param n_type           "n_type" of attibutes
 * @param program_id       Program object id
 * @param use_arrays       If attributes are groupd in arrays
 * @param use_vertex_array If attributes are configured with vertex array or as constants
 **/
void LimitTest::configureAttribute(_iteration iteration, const attributeConfiguration &configuration, GLint n_type,
                                   GLuint program_id, bool use_arrays, bool use_vertex_array) const
{
    static const GLint invalid_attrib_location = -1;

    const GLint attributes_index = n_type * configuration.m_n_attributes_per_group;
    const GLint group_offset     = calculateAttributeGroupOffset(configuration, n_type);
    const GLint n_elements       = configuration.m_n_elements[n_type];
    const GLint n_rows           = configuration.m_n_rows[n_type];
    const GLint n_columns        = n_elements / n_rows;
    const GLint vertex_length    = configuration.m_vertex_length;

    /* For each attribute in "n_type" group */
    for (GLint i = 0; i < configuration.m_n_attributes_per_group; ++i)
    {
        const GLint attribute_ordinal = i + attributes_index;
        std::stringstream attribute_name;

        /* Separate attributes are called: attribute_ORDINAL, arrayed: attribute_N_TYPE[INDEX] */
        if (false == use_arrays)
        {
            attribute_name << "attribute_" << attribute_ordinal;
        }
        else
        {
            attribute_name << "attribute_" << n_type << "[" << i << "]";
        }

        /* get location */
        GLint attribute_location = gl.getAttribLocation(program_id, attribute_name.str().c_str());
        GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");

        if (invalid_attrib_location == attribute_location)
        {
            m_log << tcu::TestLog::Message << "GetAttribLocation(" << program_id << ", " << attribute_name.str()
                  << ") returned: " << attribute_location << tcu::TestLog::EndMessage;

            TCU_FAIL("Inactive attribute");
        }

        /* Configure */
        if (true == use_vertex_array)
        {
            /* With vertex array */
            for (GLint column = 0; column < n_columns; ++column)
            {
                const GLint attribute_offset = group_offset + i * n_elements;
                const GLint column_offset    = column * n_rows;

                gl.enableVertexAttribArray(attribute_location + column);
                GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");

                gl.vertexAttribLPointer(attribute_location + column, n_rows /* size */, GL_DOUBLE,
                                        static_cast<glw::GLsizei>(vertex_length * sizeof(GLdouble)),
                                        (GLvoid *)((attribute_offset + column_offset) * sizeof(GLdouble)));
                GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribLPointer");
            }
        }
        else
        {
            /* As constant */
            for (GLint column = 0; column < n_columns; ++column)
            {
                switch (iteration)
                {
                case DOUBLE_DVEC2:

                    /* Double attributes should be assigned the value:
                     (n_attribute + gl_VertexID * 2) */
                    /* Dvec2 attribute components should be assigned the following
                     vector values:
                     (n_attribute + gl_VertexID * 3 + 1,
                     n_attribute + gl_VertexID * 3 + 2)*/

                    if (1 == n_rows)
                    {
                        gl.vertexAttribL1d(attribute_location, attribute_ordinal);
                    }
                    else
                    {
                        gl.vertexAttribL2d(attribute_location, attribute_ordinal + 1, attribute_ordinal + 2);
                    }

                    break;

                case DVEC3_DVEC4:

                    /* Dvec3 attribute components should be assigned the following
                     vector values:
                     (n_attribute + gl_VertexID * 3 + 0,
                     n_attribute + gl_VertexID * 3 + 1,
                     n_attribute + gl_VertexID * 3 + 2).

                     Dvec4 attribute components should be assigned the following
                     vector values:
                     (n_attribute + gl_VertexID * 4 + 0,
                     n_attribute + gl_VertexID * 4 + 1,
                     n_attribute + gl_VertexID * 4 + 2,
                     n_attribute + gl_VertexID * 4 + 3).*/

                    if (3 == n_rows)
                    {
                        gl.vertexAttribL3d(attribute_location, attribute_ordinal + 0, attribute_ordinal + 1,
                                           attribute_ordinal + 2);
                    }
                    else
                    {
                        gl.vertexAttribL4d(attribute_location, attribute_ordinal + 0, attribute_ordinal + 1,
                                           attribute_ordinal + 2, attribute_ordinal + 3);
                    }

                    break;

                case DMAT2:
                case DMAT3X2_DMAT4X2:
                case DMAT2X3_DMAT2X4:
                case DMAT3_DMAT3X4:
                case DMAT4X3_DMAT4:

                    /* Subsequent matrix elements should be assigned the following value:
                     (n_type + n_attribute + gl_VertexID * 16 + n_value)*/

                    if (2 == n_rows)
                    {
                        gl.vertexAttribL2d(attribute_location + column,
                                           n_type + attribute_ordinal + 0 + column * n_rows,
                                           n_type + attribute_ordinal + 1 + column * n_rows);
                    }
                    else if (3 == n_rows)
                    {
                        gl.vertexAttribL3d(attribute_location + column,
                                           n_type + attribute_ordinal + 0 + column * n_rows,
                                           n_type + attribute_ordinal + 1 + column * n_rows,
                                           n_type + attribute_ordinal + 2 + column * n_rows);
                    }
                    else
                    {
                        gl.vertexAttribL4d(attribute_location + column,
                                           n_type + attribute_ordinal + 0 + column * n_rows,
                                           n_type + attribute_ordinal + 1 + column * n_rows,
                                           n_type + attribute_ordinal + 2 + column * n_rows,
                                           n_type + attribute_ordinal + 3 + column * n_rows);
                    }

                    break;
                }
            }
        }
    }
}

/** Get varying name and vertex shader code for given configuration
 *
 * @param iteration                 Iteration id
 * @param use_arrays                If attributes should be grouped in arrays
 * @param use_locations             If attributes locations should be set manualy
 * @param use_vertex_attrib_divisor If vertex attribute divisor should be used
 * @param out_varying_name          Name of varying to be captured with transform feedback
 * @param out_vertex_shader_code    Source code of vertex shader
 **/
void LimitTest::getProgramDetails(_iteration iteration, bool use_arrays, bool use_locations,
                                  bool use_vertex_attrib_divisor, std::string &out_varying_name,
                                  std::string &out_vertex_shader_code) const
{
    static const GLchar *varying_name = "vs_output_value";

    attributeConfiguration configuration;
    GLint n_attributes = 0;
    GLint n_types      = 0;
    std::stringstream stream;

    const GLchar *advancement_str = (true == use_vertex_attrib_divisor) ? "gl_InstanceID" : "gl_VertexID";

    getVertexArrayConfiguration(iteration, configuration);

    n_attributes = configuration.m_n_attributes_per_group;
    n_types      = configuration.m_n_types;

    /* Preamble */
    stream << "#version 400\n"
              "#extension GL_ARB_vertex_attrib_64bit : require\n"
              "\n"
              "precision highp float;\n"
              "\n";

    /* Attribute declarations */
    /* Spearated attributes are called: attribute_ORDINAL, arrayed: attribute_N_TYPE */
    for (GLint n_type = 0; n_type < n_types; ++n_type)
    {
        const GLint attribute_offset = n_type * n_attributes;
        const GLchar *type_name      = configuration.m_type_names[n_type];

        stream << "// " << type_name << "\n";

        if (false == use_arrays)
        {
            for (GLint attribute = 0; attribute < n_attributes; ++attribute)
            {
                if (true == use_locations)
                {
                    const GLint location = calculateAttributeLocation(configuration, attribute, n_type);

                    stream << "layout(location = " << location << ") ";
                }

                stream << "in " << type_name << " attribute_" << attribute + attribute_offset << ";\n";
            }
        }
        else
        {
            if (true == use_locations)
            {
                const GLint location = calculateAttributeLocation(configuration, m_array_attribute, n_type);

                stream << "layout(location = " << location << ") ";
            }

            stream << "in " << type_name << " attribute_" << n_type << "[" << n_attributes << "];\n";
        }

        stream << "\n";
    }

    /* Varying declaration */
    stream << "out int " << varying_name << ";\n\n";

    /* Main */
    stream << "void main()\n"
              "{\n";

    for (GLint n_type = 0; n_type < n_types; ++n_type)
    {
        const GLint n_elements  = configuration.m_n_elements[n_type];
        const GLchar *type_name = configuration.m_type_names[n_type];

        stream << "// " << type_name << "\n";

        /* if (attribute_name != type(values))
         * {
         *     varying = 0;
         * }
         */
        for (GLint attribute = 0; attribute < n_attributes; ++attribute)
        {
            const GLint attribute_ordinal = attribute + n_type * n_attributes;

            /* First attribute is verified with "if", rest with "else if" */
            if (0 == attribute_ordinal)
            {
                stream << "    if (attribute_";
            }
            else
            {
                stream << "    else if (attribute_";
            }

            /* Spearated attributes are called: attribute_ORDINAL, arrayed: attribute_N_TYPE[INDEX] */
            if (false == use_arrays)
            {
                stream << attribute_ordinal;
            }
            else
            {
                stream << n_type << "[" << attribute << "]";
            }

            /* != type() */
            stream << " != " << type_name << "(";

            /* Values for type constructor, depend on iteration */
            switch (iteration)
            {
            case DOUBLE_DVEC2:

                /* Double attributes should be assigned the value:
                 (n_attribute + gl_VertexID * 2) */
                /* Dvec2 attribute components should be assigned the following
                 vector values:
                 (n_attribute + gl_VertexID * 3 + 1,
                 n_attribute + gl_VertexID * 3 + 2)*/

                if (1 == n_elements)
                {
                    stream << attribute_ordinal << " + " << advancement_str << " * 2";
                }
                else
                {
                    stream << attribute_ordinal << " + " << advancement_str << " * 3 + 1"
                           << ", " << attribute_ordinal << " + " << advancement_str << " * 3 + 2";
                }

                break;

            case DVEC3_DVEC4:

                /* Dvec3 attribute components should be assigned the following
                 vector values:
                 (n_attribute + gl_VertexID * 3 + 0,
                 n_attribute + gl_VertexID * 3 + 1,
                 n_attribute + gl_VertexID * 3 + 2).

                 Dvec4 attribute components should be assigned the following
                 vector values:
                 (n_attribute + gl_VertexID * 4 + 0,
                 n_attribute + gl_VertexID * 4 + 1,
                 n_attribute + gl_VertexID * 4 + 2,
                 n_attribute + gl_VertexID * 4 + 3).*/

                for (GLint element = 0; element < n_elements; ++element)
                {
                    stream << attribute_ordinal << " + " << advancement_str << " * " << n_elements << " + " << element;

                    if (n_elements != element + 1)
                    {
                        stream << ", ";
                    }
                }

                break;

            case DMAT2:
            case DMAT3X2_DMAT4X2:
            case DMAT2X3_DMAT2X4:
            case DMAT3_DMAT3X4:
            case DMAT4X3_DMAT4:

                /* Subsequent matrix elements should be assigned the following value:
                 (n_type + n_attribute + gl_VertexID * 16 + n_value)*/

                for (GLint element = 0; element < n_elements; ++element)
                {
                    stream << n_type << " + " << attribute_ordinal << " + " << advancement_str << " * 16 + " << element;

                    if (n_elements != element + 1)
                    {
                        stream << ", ";
                    }
                }

                break;
            }

            /* type() { varying = 0 } */
            stream << "))\n"
                   << "    {\n"
                   << "        " << varying_name << " = 0;\n"
                   << "    }\n";
        }
    }

    /* All attributes verified: else { varyin = 1 }
     Close main body */
    stream << "    else\n"
           << "    {\n"
           << "        " << varying_name << " = 1;\n"
           << "    }\n"
           << "}\n\n";

    /* Store results */
    out_varying_name       = varying_name;
    out_vertex_shader_code = stream.str();
}

/** Get configuration of vertex array object
 *
 * @param iteration         Iteration id
 * @param out_configuration Configuration
 **/
void LimitTest::getVertexArrayConfiguration(_iteration iteration, attributeConfiguration &out_configuration) const
{
    static const GLuint n_elements_per_scalar = 1;
    static const GLuint n_elements_per_vec2   = 2;
    static const GLuint n_elements_per_vec3   = 3;
    static const GLuint n_elements_per_vec4   = 4;
    static const GLuint n_elements_per_mat2   = 4;
    static const GLuint n_elements_per_mat2x3 = 6;
    static const GLuint n_elements_per_mat2x4 = 8;
    static const GLuint n_elements_per_mat3   = 9;
    static const GLuint n_elements_per_mat3x2 = 6;
    static const GLuint n_elements_per_mat3x4 = 12;
    static const GLuint n_elements_per_mat4   = 16;
    static const GLuint n_elements_per_mat4x2 = 8;
    static const GLuint n_elements_per_mat4x3 = 12;

    const GLint max_vertex_attribs = GetMaxVertexAttribs();

    switch (iteration)
    {
    case DOUBLE_DVEC2:
    {
        static const GLint n_elements[] = {n_elements_per_scalar, n_elements_per_vec2};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 2;

        static const GLchar *type_names[] = {"double", "dvec2"};

        static const GLint n_rows[] = {
            1,
            2,
        };

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    case DVEC3_DVEC4:
    {
        static const GLint n_elements[] = {n_elements_per_vec3, n_elements_per_vec4};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 4;

        static const GLchar *type_names[] = {"dvec3", "dvec4"};

        static const GLint n_rows[] = {
            3,
            4,
        };

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    case DMAT2:
    {
        static const GLint n_elements[] = {n_elements_per_mat2};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 2;

        static const GLchar *type_names[] = {"dmat2"};

        static const GLint n_rows[] = {2};

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    case DMAT3X2_DMAT4X2:
    {
        static const GLint n_elements[] = {n_elements_per_mat3x2, n_elements_per_mat4x2};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 8;

        static const GLchar *type_names[] = {"dmat3x2", "dmat4x2"};

        static const GLint n_rows[] = {2, 2};

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    case DMAT2X3_DMAT2X4:
    {
        static const GLint n_elements[] = {n_elements_per_mat2x3, n_elements_per_mat2x4};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 8;

        static const GLchar *type_names[] = {"dmat2x3", "dmat2x4"};

        static const GLint n_rows[] = {3, 4};

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    case DMAT3_DMAT3X4:
    {
        static const GLint n_elements[] = {n_elements_per_mat3, n_elements_per_mat3x4};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 12;

        static const GLchar *type_names[] = {"dmat3", "dmat3x4"};

        static const GLint n_rows[] = {3, 4};

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    case DMAT4X3_DMAT4:
    {
        static const GLint n_elements[] = {n_elements_per_mat4x3, n_elements_per_mat4};
        static const GLint n_types      = sizeof(n_elements) / sizeof(n_elements[0]);

        static const GLint divisor = 16;

        static const GLchar *type_names[] = {"dmat4x3", "dmat4"};

        static const GLint n_rows[] = {3, 4};

        out_configuration.m_n_attributes_per_group = max_vertex_attribs / divisor;
        out_configuration.m_n_elements             = n_elements;
        out_configuration.m_n_rows                 = n_rows;
        out_configuration.m_n_types                = n_types;
        out_configuration.m_type_names             = type_names;
    }
    break;
    }

    calculateVertexLength(out_configuration);
}

/** Logs iteration and configuration of test
 *
 * @param iteration      Iteration id
 * @param use_arrays     If attributes are grouped in arrays
 * @param use_locations  If manual attribute locations are used
 * @param attribute_type Regular, constant or per instance
 **/
void LimitTest::logTestIterationAndConfig(_iteration iteration, _attributeType attribute_type, bool use_arrays,
                                          bool use_locations) const
{
    tcu::MessageBuilder message = m_log << tcu::TestLog::Message;

    switch (iteration)
    {
    case DOUBLE_DVEC2:
        message << "Iteration: double + dvec2";

        break;
    case DVEC3_DVEC4:
        message << "Iteration: devc3 + dvec4";

        break;
    case DMAT2:
        message << "Iteration: dmat2";

        break;
    case DMAT3X2_DMAT4X2:
        message << "Iteration: dmat3x2 + dmat4x2";

        break;
    case DMAT2X3_DMAT2X4:
        message << "Iteration: dmat2x3 + dmat2x4";

        break;
    case DMAT3_DMAT3X4:
        message << "Iteration: dmat3 + dmat3x4";

        break;
    case DMAT4X3_DMAT4:
        message << "Iteration: dmat4x3 + dmat4";

        break;
    }

    message << "Configuration: ";

    if (true == use_arrays)
    {
        message << "arrayed attributes";
    }
    else
    {
        message << "separate attributes";
    }

    message << ", ";

    if (true == use_locations)
    {
        message << "reversed locations";
    }
    else
    {
        message << "default locations";
    }

    message << ", ";

    switch (attribute_type)
    {
    case REGULAR:
        message << "vertex attribute divisor: 0";

        break;
    case CONSTANT:
        message << "constant vertex attribute";

        break;
    case PER_INSTANCE:
        message << "vertex attribute divisor: 1";

        break;
    }

    message << tcu::TestLog::EndMessage;
}

/** Prepare program info for given configuration
 *
 * @param iteration                 Iteration id
 * @param use_arrays                If attributes should be grouped in arrays
 * @param use_locations             If manual attribute locations should be used
 * @param use_vertex_attrib_divisor If vertex attribute divisor should be used
 * @param program_info              Program info
 **/
void LimitTest::prepareProgram(_iteration iteration, bool use_arrays, bool use_locations,
                               bool use_vertex_attrib_divisor, programInfo &program_info)
{
    static const GLchar *fragment_shader_code = "#version 400\n"
                                                "#extension GL_ARB_vertex_attrib_64bit : require\n"
                                                "\n"
                                                "precision highp float;\n"
                                                "\n"
                                                "void main()\n"
                                                "{\n"
                                                "    discard;\n"
                                                "}\n\n";
    std::string varying_name;
    std::string vertex_shader_code;

    program_info.m_program_id = gl.createProgram();
    GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");

    getProgramDetails(iteration, use_arrays, use_locations, use_vertex_attrib_divisor, varying_name,
                      vertex_shader_code);

    {
        const GLchar *temp_varying_name = varying_name.c_str();

        gl.transformFeedbackVaryings(program_info.m_program_id, m_n_varyings, &temp_varying_name,
                                     GL_INTERLEAVED_ATTRIBS);
        GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
    }

    BuildProgram(fragment_shader_code, program_info.m_program_id, vertex_shader_code.c_str(),
                 program_info.m_fragment_shader_id, program_info.m_vertex_shader_id);
}

/** Configure vertex array object for all attributes
 *
 * @param iteration      Iteration id
 * @param attribute_type Regular, constant or per instance
 * @param program_id     Program object id
 * @param use_arrays     If attributes are grouped with arrays
 **/
void LimitTest::prepareVertexArray(_iteration iteration, _attributeType attribute_type, GLuint program_id,
                                   bool use_arrays) const
{
    const GLint max_vertex_attribs     = GetMaxVertexAttribs();
    const GLuint vertex_attrib_divisor = (PER_INSTANCE == attribute_type) ? 1 : 0;

    attributeConfiguration configuration;

    getVertexArrayConfiguration(iteration, configuration);

    /* Set vertex attributes divisor and disable */
    for (GLint i = 0; i < max_vertex_attribs; ++i)
    {
        gl.vertexAttribDivisor(i, vertex_attrib_divisor);
        GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttribDivisor");

        gl.disableVertexAttribArray(i);
        GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
    }

    for (GLint n_type = 0; n_type < configuration.m_n_types; ++n_type)
    {
        configureAttribute(iteration, configuration, n_type, program_id, use_arrays, (CONSTANT != attribute_type));
    }
}

/** Prepare vertex buffer data for given iteration
 *
 * @param iteration Iteration id
 **/
void LimitTest::prepareVertexArrayBuffer(_iteration iteration)
{
    GLuint buffer_length = 0;
    attributeConfiguration configuration;

    getVertexArrayConfiguration(iteration, configuration);

    buffer_length = m_n_vertices * configuration.m_vertex_length;

    std::vector<GLdouble> buffer_data;
    buffer_data.resize(buffer_length);

    for (GLuint vertex = 0; vertex < m_n_vertices; ++vertex)
    {
        setAttributes(iteration, configuration, vertex, buffer_data);
    }

    gl.bufferData(GL_ARRAY_BUFFER, buffer_length * sizeof(GLdouble), &buffer_data[0], GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
}

/** Set all attributes for <vertex>
 *
 * @param iteration       Iteration id
 * @param configuration   Attribute configuration
 * @param vertex          Vertex orinal number
 * @param out_buffer_data Buffer data
 **/
void LimitTest::setAttributes(_iteration iteration, const attributeConfiguration &configuration, GLuint vertex,
                              std::vector<GLdouble> &out_buffer_data) const
{
    const GLint n_types = configuration.m_n_types;

    for (GLint n_type = 0; n_type < n_types; ++n_type)
    {
        switch (iteration)
        {
        case DOUBLE_DVEC2:

            setAttributes_a(configuration, n_type, vertex, out_buffer_data);

            break;

        case DVEC3_DVEC4:

            setAttributes_b(configuration, n_type, vertex, out_buffer_data);

            break;

        case DMAT2:
        case DMAT3X2_DMAT4X2:
        case DMAT2X3_DMAT2X4:
        case DMAT3_DMAT3X4:
        case DMAT4X3_DMAT4:

            setAttributes_c(configuration, n_type, vertex, out_buffer_data);

            break;
        }
    }
}

/** Set attributes of given <n_type> for <vertex>, as described in "iteration a".
 *
 * @param configuration   Attribute configuration
 * @param n_type          "n_type" ordinal number
 * @param vertex          Vertex orinal number
 * @param out_buffer_data Buffer data
 **/
void LimitTest::setAttributes_a(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                                std::vector<GLdouble> &out_buffer_data) const
{
    const GLint n_elements = configuration.m_n_elements[n_type];

    if (1 == n_elements)
    {
        setAttributes_a_scalar(configuration, n_type, vertex, out_buffer_data);
    }
    else
    {
        setAttributes_a_vec(configuration, n_type, vertex, out_buffer_data);
    }
}

/** Set scalar double attributes of given <n_type> for <vertex>, as described in "iteration a".
 *
 * @param configuration   Attribute configuration
 * @param n_type          "n_type" ordinal number
 * @param vertex          Vertex orinal number
 * @param out_buffer_data Buffer data
 **/
void LimitTest::setAttributes_a_scalar(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                                       std::vector<GLdouble> &out_buffer_data) const
{
    const GLint n_attributes    = configuration.m_n_attributes_per_group;
    const GLint attribute_index = n_attributes * n_type;
    GLuint vertex_offset        = vertex * configuration.m_vertex_length;

    const GLint group_offset = calculateAttributeGroupOffset(configuration, n_type) + vertex_offset;

    /* Double attributes should be assigned the value:
     (n_attribute + gl_VertexID * 2) */

    for (GLint attribute = 0; attribute < n_attributes; ++attribute)
    {
        const GLuint attribute_offset = attribute + group_offset;

        out_buffer_data[attribute_offset] = attribute + attribute_index + vertex * 2;
    }
}

/** Set dvec2 attributes of given <n_type> for <vertex>, as described in "iteration a".
 *
 * @param configuration   Attribute configuration
 * @param n_type          "n_type" ordinal number
 * @param vertex          Vertex orinal number
 * @param out_buffer_data Buffer data
 **/
void LimitTest::setAttributes_a_vec(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                                    std::vector<GLdouble> &out_buffer_data) const
{
    const GLint n_attributes    = configuration.m_n_attributes_per_group;
    const GLint attribute_index = n_attributes * n_type;
    const GLint n_elements      = configuration.m_n_elements[n_type];
    GLuint vertex_offset        = vertex * configuration.m_vertex_length;

    const GLint group_offset = calculateAttributeGroupOffset(configuration, n_type) + vertex_offset;

    /* Dvec2 attribute components should be assigned the following
     vector values:
     (n_attribute + gl_VertexID * 3 + 1,
     n_attribute + gl_VertexID * 3 + 2)*/

    for (GLint attribute = 0; attribute < n_attributes; ++attribute)
    {
        const GLuint attribute_offset = n_elements * attribute + group_offset;

        for (GLint i = 0; i < n_elements; ++i)
        {
            out_buffer_data[attribute_offset + i] = attribute + attribute_index + vertex * 3 + i + 1;
        }
    }
}

/** Set attributes of given <n_type> for <vertex>, as described in "iteration b".
 *
 * @param configuration   Attribute configuration
 * @param n_type          "n_type" ordinal number
 * @param vertex          Vertex orinal number
 * @param out_buffer_data Buffer data
 **/
void LimitTest::setAttributes_b(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                                std::vector<GLdouble> &out_buffer_data) const
{
    const GLint n_attributes    = configuration.m_n_attributes_per_group;
    const GLint attribute_index = n_attributes * n_type;
    const GLint n_elements      = configuration.m_n_elements[n_type];
    GLuint vertex_offset        = vertex * configuration.m_vertex_length;

    const GLint group_offset = calculateAttributeGroupOffset(configuration, n_type) + vertex_offset;

    /* Dvec3 attribute components should be assigned the following
     vector values:
     (n_attribute + gl_VertexID * 3 + 0,
     n_attribute + gl_VertexID * 3 + 1,
     n_attribute + gl_VertexID * 3 + 2).

     Dvec4 attribute components should be assigned the following
     vector values:
     (n_attribute + gl_VertexID * 4 + 0,
     n_attribute + gl_VertexID * 4 + 1,
     n_attribute + gl_VertexID * 4 + 2,
     n_attribute + gl_VertexID * 4 + 3).*/

    for (GLint attribute = 0; attribute < n_attributes; ++attribute)
    {
        const GLuint attribute_offset = n_elements * attribute + group_offset;

        for (GLint i = 0; i < n_elements; ++i)
        {
            out_buffer_data[attribute_offset + i] = attribute + attribute_index + vertex * n_elements + i;
        }
    }
}

/** Set attributes of given <n_type> for <vertex>, as described in "iteration c".
 *
 * @param configuration   Attribute configuration
 * @param n_type          "n_type" ordinal number
 * @param vertex          Vertex orinal number
 * @param out_buffer_data Buffer data
 **/
void LimitTest::setAttributes_c(const attributeConfiguration &configuration, GLint n_type, GLuint vertex,
                                std::vector<GLdouble> &out_buffer_data) const
{
    const GLint n_attributes    = configuration.m_n_attributes_per_group;
    const GLint attribute_index = n_attributes * n_type;
    const GLint n_elements      = configuration.m_n_elements[n_type];
    GLuint vertex_offset        = vertex * configuration.m_vertex_length;

    const GLint group_offset = calculateAttributeGroupOffset(configuration, n_type) + vertex_offset;

    /* Subsequent matrix elements should be assigned the following value:
     (n_type + n_attribute + gl_VertexID * 16 + n_value)*/

    for (GLint attribute = 0; attribute < n_attributes; ++attribute)
    {
        const GLuint attribute_offset = n_elements * attribute + group_offset;

        for (GLint i = 0; i < n_elements; ++i)
        {
            out_buffer_data[attribute_offset + i] = n_type + attribute + attribute_index + vertex * 16 + i;
        }
    }
}

/** Run test with DrawArrays routine
 *
 * @return true if test pass, false otherwise
 **/
bool LimitTest::testDrawArrays() const
{
    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

    gl.drawArrays(GL_POINTS, 0 /* first */, m_n_vertices);
    GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");

    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");

    if (true == verifyResult(false))
    {
        return true;
    }
    else
    {
        m_log << tcu::TestLog::Message << "Draw function: DrawArrays" << tcu::TestLog::EndMessage;

        return false;
    }
}

/** Run test with DrawArraysInstanced routine
 *
 * @return true if test pass, false otherwise
 **/
bool LimitTest::testDrawArraysInstanced() const
{
    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

    gl.drawArraysInstanced(GL_POINTS, 0 /* first */, m_n_vertices, m_n_instances);
    GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArraysInstanced");

    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");

    if (true == verifyResult(true))
    {
        return true;
    }
    else
    {
        m_log << tcu::TestLog::Message << "Draw function: DrawArraysInstanced" << tcu::TestLog::EndMessage;

        return false;
    }
}

/** Run test with DrawElements routine
 *
 * @return true if test pass, false otherwise
 **/
bool LimitTest::testDrawElements() const
{
    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

    gl.drawElements(GL_POINTS, m_n_vertices, GL_UNSIGNED_INT, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");

    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");

    if (true == verifyResult(false))
    {
        return true;
    }
    else
    {
        m_log << tcu::TestLog::Message << "Draw function: DrawElements" << tcu::TestLog::EndMessage;

        return false;
    }
}

/** Run test with DrawElementsInstanced routine
 *
 * @return true if test pass, false otherwise
 **/
bool LimitTest::testDrawElementsInstanced() const
{
    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

    gl.drawElementsInstanced(GL_POINTS, m_n_vertices, GL_UNSIGNED_INT, 0, m_n_instances);
    GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElementsInstanced");

    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");

    if (true == verifyResult(true))
    {
        return true;
    }
    else
    {
        m_log << tcu::TestLog::Message << "Draw function: DrawElementsInstanced" << tcu::TestLog::EndMessage;

        return false;
    }
}

/** Test initialisation
 *
 **/
void LimitTest::testInit()
{
    /* Prepare data for element array buffer */
    std::vector<GLuint> indices_data;
    indices_data.resize(m_n_vertices);
    for (GLuint i = 0; i < m_n_vertices; ++i)
    {
        indices_data[i] = i;
    }

    /* Prepare vertex array object */
    gl.genVertexArrays(1, &m_vertex_array_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");

    gl.bindVertexArray(m_vertex_array_object_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");

    /* Generate buffers */
    gl.genBuffers(1, &m_element_array_buffer_id);
    gl.genBuffers(1, &m_transoform_feedback_buffer_id);
    gl.genBuffers(1, &m_vertex_array_buffer_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

    /* Prepare element array buffer */
    gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_element_array_buffer_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

    gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, m_n_vertices * sizeof(GLuint), &indices_data[0], GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

    /* Prepare transform feedback buffer */
    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transoform_feedback_buffer_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

    gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_size, 0 /* data */, GL_DYNAMIC_COPY);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

    /* Bind array buffer for future use */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_vertex_array_buffer_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

    /* Disabe rasterization */
    gl.enable(GL_RASTERIZER_DISCARD);
    GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
}

/** Tests specified "iteration"
 *
 * @param iteration Iteration id
 *
 * @return true if tests pass, false otherwise
 **/
bool LimitTest::testIteration(_iteration iteration)
{
    bool result = true;

    /* Program infos */
    programInfo _no_array__no_location______regular(gl);
    programInfo use_array__no_location______regular(gl);
    programInfo _no_array_use_location______regular(gl);
    programInfo use_array_use_location______regular(gl);
    programInfo _no_array__no_location_per_instance(gl);
    programInfo use_array__no_location_per_instance(gl);
    programInfo _no_array_use_location_per_instance(gl);
    programInfo use_array_use_location_per_instance(gl);

    /* Prepare programs for all configuration */
    prepareProgram(iteration, false, false, false, _no_array__no_location______regular);
    prepareProgram(iteration, true, false, false, use_array__no_location______regular);
    prepareProgram(iteration, false, true, false, _no_array_use_location______regular);
    prepareProgram(iteration, true, true, false, use_array_use_location______regular);
    prepareProgram(iteration, false, false, true, _no_array__no_location_per_instance);
    prepareProgram(iteration, true, false, true, use_array__no_location_per_instance);
    prepareProgram(iteration, false, true, true, _no_array_use_location_per_instance);
    prepareProgram(iteration, true, true, true, use_array_use_location_per_instance);

    /* Bind buffers */
    gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_element_array_buffer_id);
    gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_transoform_feedback_buffer_id, 0,
                       m_transform_feedback_buffer_size);
    GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");

    /* Prepare vertex array buffer for iteration */
    prepareVertexArrayBuffer(iteration);

    /* Regular and instanced draw calls, vertex attribute divisor: 0 */
    if (false == testProgram(iteration, _no_array__no_location______regular.m_program_id, false))
    {
        logTestIterationAndConfig(iteration, REGULAR, false /* use_arrays */, false /* use_locations */);

        result = false;
    }

    if (false == testProgram(iteration, use_array__no_location______regular.m_program_id, true))
    {
        logTestIterationAndConfig(iteration, REGULAR, true /* use_arrays */, false /* use_locations */);

        result = false;
    }

    if (false == testProgram(iteration, _no_array_use_location______regular.m_program_id, false))
    {
        logTestIterationAndConfig(iteration, REGULAR, false /* use_arrays */, true /* use_locations */);

        result = false;
    }

    if (false == testProgram(iteration, use_array_use_location______regular.m_program_id, true))
    {
        logTestIterationAndConfig(iteration, REGULAR, true /* use_arrays */, true /* use_locations */);

        result = false;
    }

    /* Regular draw calls, constant vertex attribute */
    if (false == testProgramWithConstant(iteration, _no_array__no_location_per_instance.m_program_id, false))
    {
        logTestIterationAndConfig(iteration, CONSTANT, false /* use_arrays */, false /* use_locations */);

        result = false;
    }

    if (false == testProgramWithConstant(iteration, use_array__no_location_per_instance.m_program_id, true))
    {
        logTestIterationAndConfig(iteration, CONSTANT, true /* use_arrays */, false /* use_locations */);

        result = false;
    }

    if (false == testProgramWithConstant(iteration, _no_array_use_location_per_instance.m_program_id, false))
    {
        logTestIterationAndConfig(iteration, CONSTANT, false /* use_arrays */, true /* use_locations */);

        result = false;
    }

    if (false == testProgramWithConstant(iteration, use_array_use_location_per_instance.m_program_id, true))
    {
        logTestIterationAndConfig(iteration, CONSTANT, true /* use_arrays */, true /* use_locations */);

        result = false;
    }

    /* Instanced draw calls, vertex attribute divisor: 1 */
    if (false == testProgramWithDivisor(iteration, _no_array__no_location_per_instance.m_program_id, false))
    {
        logTestIterationAndConfig(iteration, PER_INSTANCE, false /* use_arrays */, false /* use_locations */);

        result = false;
    }

    if (false == testProgramWithDivisor(iteration, use_array__no_location_per_instance.m_program_id, true))
    {
        logTestIterationAndConfig(iteration, PER_INSTANCE, true /* use_arrays */, false /* use_locations */);

        result = false;
    }

    if (false == testProgramWithDivisor(iteration, _no_array_use_location_per_instance.m_program_id, false))
    {
        logTestIterationAndConfig(iteration, PER_INSTANCE, false /* use_arrays */, true /* use_locations */);

        result = false;
    }

    if (false == testProgramWithDivisor(iteration, use_array_use_location_per_instance.m_program_id, true))
    {
        logTestIterationAndConfig(iteration, PER_INSTANCE, true /* use_arrays */, true /* use_locations */);

        result = false;
    }

    /* Done */
    return result;
}

/** Tests regular and instanced draw calls with vertex attribute divisor set to 0
 *
 * @param iteration  Iteration id
 * @param program_id Program object id
 * @param use_arrays true if arrays of attributes are used
 *
 * @return true if tests pass, false otherwise
 **/
bool LimitTest::testProgram(_iteration iteration, GLuint program_id, bool use_arrays) const
{
    bool result = true;

    gl.useProgram(program_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

    prepareVertexArray(iteration, REGULAR, program_id, use_arrays);

    if (false == testDrawArrays())
    {
        result = false;
    }

    if (false == testDrawElements())
    {
        result = false;
    }

    if (false == testDrawArraysInstanced())
    {
        result = false;
    }

    if (false == testDrawElementsInstanced())
    {
        result = false;
    }

    return result;
}

/** Tests constant attributes value, set with VertexAttribLd* routines
 *
 * @param iteration  Iteration id
 * @param program_id Program object id
 * @param use_arrays true if arrays of attributes are used
 *
 * @return true if tests pass, false otherwise
 **/
bool LimitTest::testProgramWithConstant(_iteration iteration, GLuint program_id, bool use_arrays) const
{
    bool result = true;

    gl.useProgram(program_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

    prepareVertexArray(iteration, CONSTANT, program_id, use_arrays);

    if (false == testDrawArrays())
    {
        result = false;
    }

    if (false == testDrawElements())
    {
        result = false;
    }

    return result;
}

/** Tests instanced draw calls with vertex attribute divisor set to 1
 *
 * @param iteration  Iteration id
 * @param program_id Program object id
 * @param use_arrays true if arrays of attributes are used
 *
 * @return true if tests pass, false otherwise
 **/
bool LimitTest::testProgramWithDivisor(_iteration iteration, GLuint program_id, bool use_arrays) const
{
    bool result = true;

    gl.useProgram(program_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

    prepareVertexArray(iteration, PER_INSTANCE, program_id, use_arrays);

    if (false == testDrawArraysInstanced())
    {
        result = false;
    }

    if (false == testDrawElementsInstanced())
    {
        result = false;
    }

    return result;
}

/** Verifies results
 *
 * @param use_instancing true if instanced draw call was made, otherwise false
 *
 * @result true if all vertices outputed 1, false otherwise
 **/
bool LimitTest::verifyResult(bool use_instancing) const
{
    _varyingType *buffer_data = (_varyingType *)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    const GLuint n_instances  = (true == use_instancing) ? m_n_instances : 1;
    bool result               = true;

    GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");

    if (0 == buffer_data)
    {
        TCU_FAIL("Failed to map GL_TRANSFORM_FEEDBACK_BUFFER buffer");
    }

    /* For each instance */
    for (GLuint instance = 0; instance < n_instances; ++instance)
    {
        const GLuint instance_offset = instance * m_n_vertices * m_n_varyings;

        /* For each vertex */
        for (GLuint vertex = 0; vertex < m_n_vertices; ++vertex)
        {
            const GLuint vertex_offset = vertex * m_n_varyings;

            if (1 != buffer_data[vertex_offset + instance_offset])
            {
                if (true == use_instancing)
                {
                    m_log << tcu::TestLog::Message << "Failure. Instance: " << instance << " Vertex: " << vertex
                          << tcu::TestLog::EndMessage;
                }
                else
                {
                    m_log << tcu::TestLog::Message << "Failure. Vertex: " << vertex << tcu::TestLog::EndMessage;
                }

                /* Save failure and break loop */
                result = false;

                /* Sorry about that, but this is nested loop */
                goto end;
            }
        }
    }

end:
    gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");

    return result;
}

/** Implementation of conformance test "4", description follows.
 *
 *  Make sure non-trivial VAO configurations are correctly supported
 *  for double-precision floating-point types.
 *
 *  Consider the following Vertex Buffer Object configurations:
 *
 *  BO1:
 *  0            72 73 75      91 96
 *  --------------+-+--+-------+---
 *  |      A      |B| C|    D  | E|  (times 1024)
 *  -------------------------------
 *
 *  where:
 *
 *  A: 3x3 double matrix  (72 bytes)
 *  B: 1 unsigned byte    (1  byte)
 *  C: 1 short            (2  bytes)
 *  D: 2 doubles          (16 bytes)
 *  E: padding            (5  bytes)
 *                     (+) --------
 *                         96 bytes
 *
 *  BO2:
 *  --+------------------
 *  |A|         B       |  (times 1024)
 *  --+------------------
 *
 *  where:
 *
 *  A: 1 signed byte     (1  byte)
 *  B: 4x2 double matrix (64 bytes)
 *                    (+) --------
 *                        65 bytes
 *
 *  A VAO used for the test should be configured as described
 *  below:
 *
 *  Att 0 (L): VAP-type:GL_DOUBLE,        GLSL-type: dmat3,   stride:96,
 *             offset:  0,                normalized:0,       source:BO1;
 *  Att 1 (F): VAP-type:GL_UNSIGNED_BYTE, GLSL-type: float,   stride:5,
 *             offset:  0,                normalized:1,       source:BO2;
 *  Att 2 (L): VAP-type:GL_DOUBLE,        GLSL-type: dvec2,   stride:96,
 *             offset:  75,               normalized:0,       source:BO1;
 *  Att 3 (L): VAP-type:GL_DOUBLE,        GLSL-type: double,  stride:48,
 *             offset:  0,                normalized:0,       source:BO1;
 *  Att 4 (L): VAP-type:GL_DOUBLE,        GLSL-type: dmat4x2, stride:65,
 *             offset:  1,                normalized:0,       source:BO2;
 *  Att 5 (F): VAP-type:GL_SHORT,         GLSL-type: float,   stride:96,
 *             offset:  73,               normalized:0,       source:BO1;
 *  Att 6 (I): VAP-type:GL_BYTE,          GLSL-type: int,     stride:96,
 *             offset:  72,               normalized:1,       source:BO1;
 *
 *  where:
 *
 *  GLSL-type: Input variable type, as to be used in corresponding
 *             vertex shader.
 *  (F):       glVertexAttribPointer() call should be used to configure
 *             given vertex attribute array;
 *  (I):       glVertexAttribIPointer() call should be used to configure
 *             given vertex attribute array;
 *  (L):       glVertexAttribLPointer() call should be used to configure
 *             given vertex attribute array;
 *  VAP-type:  <type> argument as passed to corresponding
 *             glVertexAttrib*Pointer() call.
 *
 *  The test should use a program object consisting only of VS.
 *  The shader should read all the attributes and store the
 *  values in corresponding output variables. These should then be
 *  XFBed out to the test implementation, which should then verify
 *  the values read in the shader are valid in light of the specification.
 *
 *  All the draw call types described in test 3) should be tested.
 *  A single draw call for each of the types, rendering a total of
 *  1024 points should be used for the purpose of the test
 *
 **/
class VAOTest : public Base
{
public:
    /* Public methods */
    VAOTest(deqp::Context &context);

    virtual ~VAOTest()
    {
    }

    /* Public methods inheritated from TestCase */
    virtual void deinit();
    virtual tcu::TestNode::IterateResult iterate();

private:
    /* Private type declarations */
    enum _draw_call_type
    {
        DRAW_CALL_TYPE_ARRAYS,
        DRAW_CALL_TYPE_ELEMENTS,

        /* Always last */
        DRAW_CALL_TYPE_COUNT
    };

    /* Private methods */
    bool executeTest(_draw_call_type draw_call, bool instanced, bool zero_vertex_attrib_divisor);

    void initBufferObjects();
    void initBuffers();
    void initProgramObject();
    void initVAO();

    bool verifyXFBData(const void *data, _draw_call_type draw_call, bool instanced, bool zero_vertex_attrib_divisor);

    /* Private fields */
    unsigned char *m_bo_1_data;
    unsigned int m_bo_1_data_size;
    unsigned int m_bo_1_offset_matrix;
    unsigned int m_bo_1_offset_ubyte;
    unsigned int m_bo_1_offset_short;
    unsigned int m_bo_1_offset_double;
    unsigned char *m_bo_2_data;
    unsigned int m_bo_2_data_size;
    unsigned int m_bo_2_offset_sbyte;
    unsigned int m_bo_2_offset_matrix;
    unsigned short *m_bo_index_data;
    unsigned int m_bo_index_data_size;
    glw::GLuint m_bo_id_1;
    glw::GLuint m_bo_id_2;
    glw::GLuint m_bo_id_indices;
    glw::GLuint m_bo_id_result;
    glw::GLint m_po_bo1_dmat3_attr_location;
    glw::GLint m_po_bo2_dmat4x2_attr_location;
    glw::GLint m_po_bo1_double_attr_location;
    glw::GLint m_po_bo1_dvec2_attr_location;
    glw::GLint m_po_bo1_float2_attr_location;
    glw::GLint m_po_bo1_int_attr_location;
    glw::GLint m_po_bo2_float_attr_location;
    glw::GLuint m_po_id;
    glw::GLuint m_vao_id;
    glw::GLuint m_vs_id;
    unsigned int m_xfb_bo1_dmat3_offset;
    unsigned int m_xfb_bo1_dmat3_size;
    unsigned int m_xfb_bo1_double_offset;
    unsigned int m_xfb_bo1_double_size;
    unsigned int m_xfb_bo1_dvec2_offset;
    unsigned int m_xfb_bo1_dvec2_size;
    unsigned int m_xfb_bo1_float2_offset;
    unsigned int m_xfb_bo1_float2_size;
    unsigned int m_xfb_bo1_int_offset;
    unsigned int m_xfb_bo1_int_size;
    unsigned int m_xfb_bo2_dmat4x2_offset;
    unsigned int m_xfb_bo2_dmat4x2_size;
    unsigned int m_xfb_bo2_float_offset;
    unsigned int m_xfb_bo2_float_size;
    unsigned int m_xfb_total_size;

    const unsigned int m_bo_1_batch_size;
    const unsigned int m_bo_2_batch_size;
    const unsigned int m_n_batches;
    const unsigned int m_n_draw_call_instances;
    const unsigned int m_nonzero_vertex_attrib_divisor;
    const unsigned int m_po_bo1_dmat3_attr_offset;
    const unsigned int m_po_bo1_dmat3_attr_stride;
    const unsigned int m_po_bo1_double_attr_offset;
    const unsigned int m_po_bo1_double_attr_stride;
    const unsigned int m_po_bo1_dvec2_attr_offset;
    const unsigned int m_po_bo1_dvec2_attr_stride;
    const unsigned int m_po_bo1_float2_attr_offset;
    const unsigned int m_po_bo1_float2_attr_stride;
    const unsigned int m_po_bo1_int_attr_offset;
    const unsigned int m_po_bo1_int_attr_stride;
    const unsigned int m_po_bo2_dmat4x2_attr_offset;
    const unsigned int m_po_bo2_dmat4x2_attr_stride;
    const unsigned int m_po_bo2_float_attr_offset;
    const unsigned int m_po_bo2_float_attr_stride;
};

/** Constructor
 *
 * @param context CTS context instance
 **/
VAOTest::VAOTest(deqp::Context &context)
    : Base(context, "vao",
           "Verify that non-trivial VAO configurations are correctly supported "
           "for double-precision floating-point types.")
    , m_bo_1_data(DE_NULL)
    , m_bo_1_data_size(0)
    , m_bo_1_offset_matrix(0)
    , m_bo_1_offset_ubyte(72)
    , m_bo_1_offset_short(73)
    , m_bo_1_offset_double(75)
    , m_bo_2_data(DE_NULL)
    , m_bo_2_data_size(0)
    , m_bo_2_offset_sbyte(0)
    , m_bo_2_offset_matrix(1)
    , m_bo_index_data(DE_NULL)
    , m_bo_index_data_size(0)
    , m_bo_id_1(0)
    , m_bo_id_2(0)
    , m_bo_id_indices(0)
    , m_bo_id_result(0)
    , m_po_bo1_dmat3_attr_location(-1)
    , m_po_bo2_dmat4x2_attr_location(-1)
    , m_po_bo1_double_attr_location(-1)
    , m_po_bo1_dvec2_attr_location(-1)
    , m_po_bo1_float2_attr_location(-1)
    , m_po_bo1_int_attr_location(-1)
    , m_po_bo2_float_attr_location(-1)
    , m_po_id(0)
    , m_vao_id(0)
    , m_vs_id(0)
    , m_xfb_bo1_dmat3_offset(0)
    , m_xfb_bo1_dmat3_size(0)
    , m_xfb_bo1_double_offset(0)
    , m_xfb_bo1_double_size(0)
    , m_xfb_bo1_dvec2_offset(0)
    , m_xfb_bo1_dvec2_size(0)
    , m_xfb_bo1_float2_offset(0)
    , m_xfb_bo1_float2_size(0)
    , m_xfb_bo1_int_offset(0)
    , m_xfb_bo1_int_size(0)
    , m_xfb_bo2_dmat4x2_offset(0)
    , m_xfb_bo2_dmat4x2_size(0)
    , m_xfb_bo2_float_offset(0)
    , m_xfb_bo2_float_size(0)
    , m_xfb_total_size(0)
    , m_bo_1_batch_size(96)
    , m_bo_2_batch_size(65)
    , m_n_batches(1024)
    , m_n_draw_call_instances(4)
    , m_nonzero_vertex_attrib_divisor(2)
    , m_po_bo1_dmat3_attr_offset(0)
    , m_po_bo1_dmat3_attr_stride(96)
    , m_po_bo1_double_attr_offset(0)
    , m_po_bo1_double_attr_stride(48)
    , m_po_bo1_dvec2_attr_offset(75)
    , m_po_bo1_dvec2_attr_stride(96)
    , m_po_bo1_float2_attr_offset(73)
    , m_po_bo1_float2_attr_stride(96)
    , m_po_bo1_int_attr_offset(72)
    , m_po_bo1_int_attr_stride(96)
    , m_po_bo2_dmat4x2_attr_offset(1)
    , m_po_bo2_dmat4x2_attr_stride(65)
    , m_po_bo2_float_attr_offset(0)
    , m_po_bo2_float_attr_stride(5)
{
    /* Nothing to be done here */
}

/** Deinitializes GL objects and deallocates buffers that may have
 *  been created during test execution */
void VAOTest::deinit()
{
    if (m_bo_1_data != DE_NULL)
    {
        delete[] m_bo_1_data;

        m_bo_1_data = DE_NULL;
    }

    if (m_bo_2_data != DE_NULL)
    {
        delete[] m_bo_2_data;

        m_bo_2_data = DE_NULL;
    }

    if (m_bo_index_data != DE_NULL)
    {
        delete[] m_bo_index_data;

        m_bo_index_data = DE_NULL;
    }

    if (m_bo_id_1 != 0)
    {
        gl.deleteBuffers(1, &m_bo_id_1);

        m_bo_id_1 = 0;
    }

    if (m_bo_id_2 != 0)
    {
        gl.deleteBuffers(1, &m_bo_id_2);

        m_bo_id_2 = 0;
    }

    if (m_bo_id_indices != 0)
    {
        gl.deleteBuffers(1, &m_bo_id_indices);

        m_bo_id_indices = 0;
    }

    if (m_bo_id_result != 0)
    {
        gl.deleteBuffers(1, &m_bo_id_result);

        m_bo_id_result = 0;
    }

    if (m_po_id != 0)
    {
        gl.deleteProgram(m_po_id);

        m_po_id = 0;
    }

    if (m_vao_id != 0)
    {
        gl.deleteVertexArrays(1, &m_vao_id);

        m_vao_id = 0;
    }

    if (m_vs_id != 0)
    {
        gl.deleteShader(m_vs_id);

        m_vs_id = 0;
    }
}

/** Executes a single test iteration.
 *
 *  This function may throw error exceptions if GL implementation misbehaves.
 *
 *  @param draw_call                  Type of the draw call that should be issued.
 *  @param instanced                  True if the draw call should be instanced, false otherwise.
 *  @param zero_vertex_attrib_divisor True if a zero divisor should be used for all checked attributes,
 *                                    false to use a value of m_nonzero_vertex_attrib_divisor as the divisor.
 *
 *  @return true if the test iteration passed, false otherwise.
 **/
bool VAOTest::executeTest(_draw_call_type draw_call, bool instanced, bool zero_vertex_attrib_divisor)
{
    bool result = true;

    gl.beginTransformFeedback(GL_POINTS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
    {
        const glw::GLint divisor      = (zero_vertex_attrib_divisor) ? 0 : m_nonzero_vertex_attrib_divisor;
        const glw::GLint attributes[] = {
            m_po_bo1_dmat3_attr_location,       m_po_bo1_dmat3_attr_location + 1,   m_po_bo1_dmat3_attr_location + 2,

            m_po_bo2_dmat4x2_attr_location,     m_po_bo2_dmat4x2_attr_location + 1, m_po_bo2_dmat4x2_attr_location + 2,
            m_po_bo2_dmat4x2_attr_location + 3,

            m_po_bo1_double_attr_location,      m_po_bo1_dvec2_attr_location,       m_po_bo1_float2_attr_location,
            m_po_bo1_int_attr_location,         m_po_bo2_float_attr_location};
        const unsigned int n_attributes = sizeof(attributes) / sizeof(attributes[0]);

        for (unsigned int n_attribute = 0; n_attribute < n_attributes; ++n_attribute)
        {
            glw::GLint attribute = attributes[n_attribute];

            /* Configure vertex attribute divisor */
            gl.vertexAttribDivisor(attribute, divisor);
            GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor() call failed.");
        } /* for (all attribute locations) */

        /* Issue the draw call */
        switch (draw_call)
        {
        case DRAW_CALL_TYPE_ARRAYS:
        {
            if (instanced)
            {
                gl.drawArraysInstanced(GL_POINTS, 0 /* first */, m_n_batches, m_n_draw_call_instances);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced() call failed");
            }
            else
            {
                gl.drawArrays(GL_POINTS, 0 /* first */, m_n_batches);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
            }

            break;
        } /* case DRAW_CALL_TYPE_ARRAYS: */

        case DRAW_CALL_TYPE_ELEMENTS:
        {
            if (instanced)
            {
                gl.drawElementsInstanced(GL_POINTS, m_n_batches, GL_UNSIGNED_SHORT, DE_NULL /* indices */,
                                         m_n_draw_call_instances);
                GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElementsInstanced() call failed.");
            }
            else
            {
                gl.drawElements(GL_POINTS, m_n_batches, GL_UNSIGNED_SHORT, DE_NULL); /* indices */
                GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements() call failed.");
            }

            break;
        } /* case DRAW_CALL_TYPE_ELEMENTS: */

        default:
        {
            TCU_FAIL("Unrecognized draw call type");
        }
        } /* switch (draw_call) */
    }
    gl.endTransformFeedback();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");

    /* Retrieve the results */
    const void *pXFBData = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);

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

    /* Verify the data */
    result = verifyXFBData(pXFBData, draw_call, instanced, zero_vertex_attrib_divisor);

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

    return result;
}

/** Initializes buffer objects that will be used by the test.
 *
 *  This function may throw error exceptions if GL implementation misbehaves.
 **/
void VAOTest::initBufferObjects()
{
    DE_ASSERT(m_bo_1_data != DE_NULL);
    DE_ASSERT(m_bo_2_data != DE_NULL);

    /* Generate BOs */
    gl.genBuffers(1, &m_bo_id_1);
    gl.genBuffers(1, &m_bo_id_2);
    gl.genBuffers(1, &m_bo_id_indices);
    gl.genBuffers(1, &m_bo_id_result);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");

    /* Initiailize BO storage */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

    gl.bufferData(GL_ARRAY_BUFFER, m_bo_1_data_size, m_bo_1_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

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

    gl.bufferData(GL_ARRAY_BUFFER, m_bo_2_data_size, m_bo_2_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

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

    gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, m_bo_index_data_size, m_bo_index_data, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

    /* Finally, reserve sufficient amount of space for the data to be XFBed out from
     * the test program. We need:
     *
     * a) dmat3:   (3 * 3 * 2) components: 18 float components
     * b) float:   (1)         component :  1 float component
     * c) dvec2:   (2 * 2)     components:  4 float components
     * d) double:  (1 * 2)     components:  2 float components
     * e) dmat4x2: (4 * 2 * 2) components: 16 float components
     * f) int:     (1)         components:  1 int   component
     * g) float:   (1)         component:   1 float components
     * h) padding: 4 bytes because fp64 buffer needs 8 bytes alignment
     *                                 (+)------
     *                                    (42 float + 1 int + 4 bytes padding) components times 1024 batches: 43008 floats, 1024 ints
     *
     * Don't forget about instanced draw calls. We'll be XFBing data for either 1 or m_n_draw_call_instances
     * instances.
     */
    const unsigned int xfb_dat_pad = sizeof(int);
    const unsigned int xfb_data_size =
        static_cast<unsigned int>((42 * sizeof(float) + sizeof(int) + xfb_dat_pad) * 1024 * m_n_draw_call_instances);

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

    gl.bufferData(GL_ARRAY_BUFFER, xfb_data_size, DE_NULL /* data */, GL_STATIC_DRAW);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

    /* Set up XFB bindings */
    gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_result);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

    gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id_result);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
}

/** Initializes buffers that will later be used to fill storage of buffer objects used by the test. */
void VAOTest::initBuffers()
{
    DE_ASSERT(m_bo_1_data == DE_NULL);
    DE_ASSERT(m_bo_2_data == DE_NULL);
    DE_ASSERT(m_bo_index_data == DE_NULL);

    /* Prepare buffers storing underlying data. The buffers will be used for:
     *
     * - storage purposes;
     * - verification of the data XFBed from the vertex shader.
     */
    m_bo_1_data_size     = m_bo_1_batch_size * m_n_batches;
    m_bo_2_data_size     = m_bo_2_batch_size * m_n_batches;
    m_bo_index_data_size = static_cast<unsigned int>(sizeof(unsigned short) * m_n_batches);

    m_bo_1_data     = new unsigned char[m_bo_1_data_size];
    m_bo_2_data     = new unsigned char[m_bo_2_data_size];
    m_bo_index_data = new unsigned short[m_bo_index_data_size / sizeof(unsigned short)];

    /* Workaround for alignment issue that may result in bus error on some platforms */
    union
    {
        double d;
        unsigned char c[sizeof(double)];
    } u;

    /* Fill index data */
    for (unsigned short n_index = 0; n_index < (unsigned short)m_n_batches; ++n_index)
    {
        m_bo_index_data[n_index] = (unsigned short)((unsigned short)(m_n_batches - 1) - n_index);
    }

    /* Fill 3x3 matrix data in BO1 */
    for (unsigned int n_matrix = 0; n_matrix < m_n_batches; ++n_matrix)
    {
        double *matrix_ptr = (double *)(m_bo_1_data + n_matrix * m_bo_1_batch_size + m_bo_1_offset_matrix);

        for (unsigned int n_element = 0; n_element < 9 /* 3x3 matrix */; ++n_element)
        {
            matrix_ptr[n_element] = (double)(n_matrix * 3 * 3 + n_element + 1);
        }
    } /* for (all matrices) */

    /* Fill unsigned byte data in BO1 */
    for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
    {
        unsigned char *data_ptr = m_bo_1_data + n_element * m_bo_1_batch_size + m_bo_1_offset_ubyte;

        *data_ptr = (unsigned char)n_element;
    }

    /* Fill short data in BO1 */
    for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
    {
        unsigned short *data_ptr =
            (unsigned short *)(m_bo_1_data + n_element * m_bo_1_batch_size + m_bo_1_offset_short);

        *data_ptr = (unsigned short)n_element;
    }

    /* Fill 2 doubles data in BO1 */
    for (unsigned int n_batch = 0; n_batch < m_n_batches; ++n_batch)
    {
        unsigned char *data1_ptr = m_bo_1_data + n_batch * m_bo_1_batch_size + m_bo_1_offset_double;
        unsigned char *data2_ptr = data1_ptr + sizeof(double);

        u.d = (double)(2 * n_batch);
        memcpy(data1_ptr, u.c, sizeof(double));
        u.d = (double)(2 * n_batch + 1);
        memcpy(data2_ptr, u.c, sizeof(double));
    }

    /* Fill signed byte data in BO2 */
    for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
    {
        signed char *data_ptr = (signed char *)(m_bo_2_data + n_element * m_bo_2_batch_size + m_bo_2_offset_sbyte);

        *data_ptr = (signed char)n_element;
    }

    /* Fill 4x2 matrix data in BO2 */
    for (unsigned int n_matrix = 0; n_matrix < m_n_batches; ++n_matrix)
    {
        unsigned char *matrix_ptr = m_bo_2_data + n_matrix * m_bo_2_batch_size + m_bo_2_offset_matrix;

        for (unsigned int n_element = 0; n_element < 8 /* 4x2 matrix */; ++n_element)
        {
            u.d = (double)(n_matrix * 4 * 2 + n_element);
            memcpy(matrix_ptr + (sizeof(double) * n_element), u.c, sizeof(double));
        }
    } /* for (all matrices) */
}

/** Initializes a program object used by the test.
 *
 *  This function may throw error exceptions if GL implementation misbehaves.
 *
 **/
void VAOTest::initProgramObject()
{
    DE_ASSERT(m_po_id == 0);
    DE_ASSERT(m_vs_id == 0);

    /* Generate a program object */
    m_po_id = gl.createProgram();
    GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");

    /* Configure XFB */
    const char *xfb_varyings[]        = {"out_bo1_dmat3",  "out_bo1_double",  "out_bo1_int",   "out_bo1_dvec2",
                                         "out_bo1_float2", "out_bo2_dmat4x2", "out_bo2_float", "gl_SkipComponents1"};
    const unsigned int n_xfb_varyings = sizeof(xfb_varyings) / sizeof(xfb_varyings[0]);

    gl.transformFeedbackVaryings(m_po_id, n_xfb_varyings, xfb_varyings, GL_INTERLEAVED_ATTRIBS);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");

    /* Initialize XFB-specific offset information for the verification routine */
    m_xfb_bo1_dmat3_offset   = 0;
    m_xfb_bo1_dmat3_size     = sizeof(double) * 3 * 3;
    m_xfb_bo1_double_offset  = m_xfb_bo1_dmat3_offset + m_xfb_bo1_dmat3_size;
    m_xfb_bo1_double_size    = sizeof(double);
    m_xfb_bo1_int_offset     = m_xfb_bo1_double_offset + m_xfb_bo1_double_size;
    m_xfb_bo1_int_size       = sizeof(int);
    m_xfb_bo1_dvec2_offset   = m_xfb_bo1_int_offset + m_xfb_bo1_int_size;
    m_xfb_bo1_dvec2_size     = sizeof(double) * 2;
    m_xfb_bo1_float2_offset  = m_xfb_bo1_dvec2_offset + m_xfb_bo1_dvec2_size;
    m_xfb_bo1_float2_size    = sizeof(float);
    m_xfb_bo2_dmat4x2_offset = m_xfb_bo1_float2_offset + m_xfb_bo1_float2_size;
    m_xfb_bo2_dmat4x2_size   = sizeof(double) * 4 * 2;
    m_xfb_bo2_float_offset   = m_xfb_bo2_dmat4x2_offset + m_xfb_bo2_dmat4x2_size;
    m_xfb_bo2_float_size     = sizeof(float);
    m_xfb_total_size = m_xfb_bo1_dmat3_size + m_xfb_bo1_double_size + m_xfb_bo1_int_size + m_xfb_bo1_dvec2_size +
                       m_xfb_bo1_float2_size + m_xfb_bo2_dmat4x2_size + m_xfb_bo2_float_size + sizeof(int);

    /* Build the test program object */
    const char *vs_code = "#version 400\n"
                          "\n"
                          "#extension GL_ARB_vertex_attrib_64bit : require\n"
                          "\n"
                          "in dmat3   in_bo1_dmat3;\n"
                          "in double  in_bo1_double;\n"
                          "in dvec2   in_bo1_dvec2;\n"
                          "in float   in_bo1_float2;\n"
                          "in int     in_bo1_int;\n"
                          "in dmat4x2 in_bo2_dmat4x2;\n"
                          "in float   in_bo2_float;\n"
                          "\n"
                          "out dmat3   out_bo1_dmat3;\n"
                          "out double  out_bo1_double;\n"
                          "out dvec2   out_bo1_dvec2;\n"
                          "out float   out_bo1_float2;\n"
                          "out int     out_bo1_int;\n"
                          "out dmat4x2 out_bo2_dmat4x2;\n"
                          "out float   out_bo2_float;\n"
                          "\n"
                          "void main()\n"
                          "{\n"
                          "    out_bo1_dmat3   = in_bo1_dmat3;\n"
                          "    out_bo1_double  = in_bo1_double;\n"
                          "    out_bo1_dvec2   = in_bo1_dvec2;\n"
                          "    out_bo1_int     = in_bo1_int;\n"
                          "    out_bo1_float2  = in_bo1_float2;\n"
                          "    out_bo2_dmat4x2 = in_bo2_dmat4x2;\n"
                          "    out_bo2_float   = in_bo2_float;\n"
                          "}\n";

    BuildProgramVSOnly(m_po_id, vs_code, m_vs_id);

    m_po_bo1_dmat3_attr_location   = gl.getAttribLocation(m_po_id, "in_bo1_dmat3");
    m_po_bo1_double_attr_location  = gl.getAttribLocation(m_po_id, "in_bo1_double");
    m_po_bo1_dvec2_attr_location   = gl.getAttribLocation(m_po_id, "in_bo1_dvec2");
    m_po_bo1_float2_attr_location  = gl.getAttribLocation(m_po_id, "in_bo1_float2");
    m_po_bo1_int_attr_location     = gl.getAttribLocation(m_po_id, "in_bo1_int");
    m_po_bo2_dmat4x2_attr_location = gl.getAttribLocation(m_po_id, "in_bo2_dmat4x2");
    m_po_bo2_float_attr_location   = gl.getAttribLocation(m_po_id, "in_bo2_float");
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() call(s) failed.");

    if (m_po_bo1_dmat3_attr_location == -1 || m_po_bo1_double_attr_location == -1 ||
        m_po_bo1_dvec2_attr_location == -1 || m_po_bo1_int_attr_location == -1 || m_po_bo1_float2_attr_location == -1 ||
        m_po_bo2_dmat4x2_attr_location == -1 || m_po_bo2_float_attr_location == -1)
    {
        TCU_FAIL("At least one attribute is considered inactive which is invalid.");
    }
}

/** Initializes a vertex array object used by the test.
 *
 *  This function may throw error exceptions if GL implementation misbehaves.
 **/
void VAOTest::initVAO()
{
    gl.genVertexArrays(1, &m_vao_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");

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

    /* Set up BO1-sourced attributes */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_1);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

    gl.vertexAttribLPointer(m_po_bo1_dmat3_attr_location + 0, 3, /* size */
                            GL_DOUBLE, m_po_bo1_dmat3_attr_stride,
                            (const glw::GLvoid *)(uintptr_t)m_po_bo1_dmat3_attr_offset);
    gl.vertexAttribLPointer(m_po_bo1_dmat3_attr_location + 1, 3, /* size */
                            GL_DOUBLE, m_po_bo1_dmat3_attr_stride,
                            (const glw::GLvoid *)(m_po_bo1_dmat3_attr_offset + 1 * sizeof(double) * 3));
    gl.vertexAttribLPointer(m_po_bo1_dmat3_attr_location + 2, 3, /* size */
                            GL_DOUBLE, m_po_bo1_dmat3_attr_stride,
                            (const glw::GLvoid *)(m_po_bo1_dmat3_attr_offset + 2 * sizeof(double) * 3));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribLPointer() call(s) failed.");

    gl.enableVertexAttribArray(m_po_bo1_dmat3_attr_location + 0);
    gl.enableVertexAttribArray(m_po_bo1_dmat3_attr_location + 1);
    gl.enableVertexAttribArray(m_po_bo1_dmat3_attr_location + 2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call(s) failed.");

    gl.vertexAttribLPointer(m_po_bo1_dvec2_attr_location, 2, /* size */
                            GL_DOUBLE, m_po_bo1_dvec2_attr_stride,
                            (const glw::GLvoid *)(uintptr_t)m_po_bo1_dvec2_attr_offset);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribLPointer() call failed.");

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

    gl.vertexAttribLPointer(m_po_bo1_double_attr_location, 1, /* size */
                            GL_DOUBLE, m_po_bo1_double_attr_stride,
                            (const glw::GLvoid *)(uintptr_t)m_po_bo1_double_attr_offset);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribLPointer() call failed.");

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

    gl.vertexAttribPointer(m_po_bo1_float2_attr_location, 1, /* size */
                           GL_SHORT, GL_FALSE,               /* normalized */
                           m_po_bo1_float2_attr_stride, (const glw::GLvoid *)(uintptr_t)m_po_bo1_float2_attr_offset);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");

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

    gl.vertexAttribIPointer(m_po_bo1_int_attr_location, 1, /* size */
                            GL_BYTE, m_po_bo1_int_attr_stride,
                            (const glw::GLvoid *)(uintptr_t)m_po_bo1_int_attr_offset);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer() call failed.");

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

    /* Set up BO2-sourced attributes */
    gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_2);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

    gl.vertexAttribPointer(m_po_bo2_float_attr_location, 1, /* size */
                           GL_UNSIGNED_BYTE, GL_TRUE, m_po_bo2_float_attr_stride,
                           (const glw::GLvoid *)(uintptr_t)m_po_bo2_float_attr_offset);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");

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

    gl.vertexAttribLPointer(m_po_bo2_dmat4x2_attr_location + 0, 2, /* size */
                            GL_DOUBLE, m_po_bo2_dmat4x2_attr_stride,
                            (const glw::GLvoid *)(uintptr_t)m_po_bo2_dmat4x2_attr_offset);
    gl.vertexAttribLPointer(m_po_bo2_dmat4x2_attr_location + 1, 2, /* size */
                            GL_DOUBLE, m_po_bo2_dmat4x2_attr_stride,
                            (const glw::GLvoid *)(m_po_bo2_dmat4x2_attr_offset + 2 * sizeof(double)));
    gl.vertexAttribLPointer(m_po_bo2_dmat4x2_attr_location + 2, 2, /* size */
                            GL_DOUBLE, m_po_bo2_dmat4x2_attr_stride,
                            (const glw::GLvoid *)(m_po_bo2_dmat4x2_attr_offset + 4 * sizeof(double)));
    gl.vertexAttribLPointer(m_po_bo2_dmat4x2_attr_location + 3, 2, /* size */
                            GL_DOUBLE, m_po_bo2_dmat4x2_attr_stride,
                            (const glw::GLvoid *)(m_po_bo2_dmat4x2_attr_offset + 6 * sizeof(double)));
    GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribLPointer() call failed.");

    gl.enableVertexAttribArray(m_po_bo2_dmat4x2_attr_location + 0);
    gl.enableVertexAttribArray(m_po_bo2_dmat4x2_attr_location + 1);
    gl.enableVertexAttribArray(m_po_bo2_dmat4x2_attr_location + 2);
    gl.enableVertexAttribArray(m_po_bo2_dmat4x2_attr_location + 3);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call(s) failed.");

    /* Set up element binding */
    gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_id_indices);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
}

/** Executes the test
 *
 *  @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult VAOTest::iterate()
{
    IterateStart();

    bool result = true;

    RequireExtension("GL_ARB_vertex_attrib_64bit");

    /* Initialize GL objects required to run the test */
    initBuffers();
    initBufferObjects();
    initProgramObject();
    initVAO();

    /* Activate the program object before we continue */
    gl.useProgram(m_po_id);
    GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

    /* Iterate through all draw call combinations */
    for (int n_draw_call_type = 0; n_draw_call_type < DRAW_CALL_TYPE_COUNT; ++n_draw_call_type)
    {
        _draw_call_type draw_call = (_draw_call_type)n_draw_call_type;

        for (int n_instanced_draw_call = 0; n_instanced_draw_call <= 1; /* false & true */
             ++n_instanced_draw_call)
        {
            bool instanced_draw_call = (n_instanced_draw_call == 1);

            for (int n_vertex_attrib_divisor = 0; n_vertex_attrib_divisor <= 1; /* 0 & non-zero divisor */
                 ++n_vertex_attrib_divisor)
            {
                bool zero_vertex_attrib_divisor = (n_vertex_attrib_divisor == 0);

                /* Execute the test */
                result &= executeTest(draw_call, instanced_draw_call, zero_vertex_attrib_divisor);
            } /* for (two vertex attrib divisor configurations) */
        }     /* for (non-instanced & instanced draw calls) */
    }         /* for (array-based & indiced draw calls) */

    /* Done */
    return IterateStop(result);
}

/** Verifies data that has been XFBed out by the draw call.
 *
 *  @param data                       XFBed data. Must not be NULL.
 *  @param draw_call                  Type of the draw call that was issued.
 *  @param instanced                  True if the draw call was instanced, false otherwise.
 *  @param zero_vertex_attrib_divisor True if a zero divisor was used for all checked attributes,
 *                                    false if the divisors were set to a value of m_nonzero_vertex_attrib_divisor.
 */
bool VAOTest::verifyXFBData(const void *data, _draw_call_type draw_call, bool instanced,
                            bool zero_vertex_attrib_divisor)
{
    const float epsilon               = 1e-5f;
    bool is_indiced                   = (draw_call == DRAW_CALL_TYPE_ELEMENTS);
    const unsigned int n_instances    = (instanced) ? m_n_draw_call_instances : 1;
    bool result                       = true;
    const unsigned char *xfb_data_ptr = (const unsigned char *)data;

    for (unsigned int n_instance = 0; n_instance < n_instances; ++n_instance)
    {
        /* Verify dmat3 data from BO1 has been exposed correctly */
        for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
        {
            unsigned int in_index  = n_element;
            unsigned int xfb_index = is_indiced ? m_bo_index_data[n_element] : n_element;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const double *in_matrix_data_ptr =
                (const double *)(m_bo_1_data + (in_index)*m_po_bo1_dmat3_attr_stride + m_po_bo1_dmat3_attr_offset);
            const double *xfb_matrix_data_ptr =
                (const double *)(xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size +
                                 m_xfb_bo1_dmat3_offset);

            if (memcmp(in_matrix_data_ptr, xfb_matrix_data_ptr, m_xfb_bo1_dmat3_size) != 0)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO1 dmat3 attribute values mismatch for batch ["
                                   << n_element
                                   << "]"
                                      ", expected:["
                                   << in_matrix_data_ptr[0] << ", " << in_matrix_data_ptr[1] << ", "
                                   << in_matrix_data_ptr[2] << ", " << in_matrix_data_ptr[3] << ", "
                                   << in_matrix_data_ptr[4] << ", " << in_matrix_data_ptr[5] << ", "
                                   << in_matrix_data_ptr[6] << ", " << in_matrix_data_ptr[7] << ", "
                                   << in_matrix_data_ptr[8] << ", "
                                   << "], XFBed out:[" << xfb_matrix_data_ptr[0] << ", " << xfb_matrix_data_ptr[1]
                                   << ", " << xfb_matrix_data_ptr[2] << ", " << xfb_matrix_data_ptr[3] << ", "
                                   << xfb_matrix_data_ptr[4] << ", " << xfb_matrix_data_ptr[5] << ", "
                                   << xfb_matrix_data_ptr[6] << ", " << xfb_matrix_data_ptr[7] << ", "
                                   << xfb_matrix_data_ptr[8] << ", "
                                   << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }

        /* Verify float data from BO2 has been exposed correctly */
        for (unsigned int n_batch = 0; n_batch < m_n_batches; ++n_batch)
        {
            unsigned int in_index        = n_batch;
            const unsigned int xfb_index = is_indiced ? m_bo_index_data[n_batch] : n_batch;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const unsigned char *in_ubyte_data_ptr =
                (const unsigned char *)(m_bo_2_data + (in_index)*m_po_bo2_float_attr_stride +
                                        m_po_bo2_float_attr_offset);
            const float *xfb_float_data_ptr =
                (const float *)(xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size +
                                m_xfb_bo2_float_offset);
            float expected_value = ((float)*in_ubyte_data_ptr / 255.0f);

            if (de::abs(expected_value - *xfb_float_data_ptr) > epsilon)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO2 float attribute value mismatch for batch ["
                                   << n_batch
                                   << "]"
                                      ", expected: ["
                                   << expected_value
                                   << "]"
                                      ", XFBed out:["
                                   << *xfb_float_data_ptr << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }

        /* Verify dvec2 data from BO1 has been exposed correctly */
        for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
        {
            unsigned int in_index        = n_element;
            const unsigned int xfb_index = is_indiced ? m_bo_index_data[n_element] : n_element;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const double *in_dvec2_data_ptr =
                (const double *)(m_bo_1_data + (in_index)*m_po_bo1_dvec2_attr_stride + m_po_bo1_dvec2_attr_offset);
            const double *xfb_dvec2_data_ptr =
                (const double *)(xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size +
                                 m_xfb_bo1_dvec2_offset);

            if (memcmp(in_dvec2_data_ptr, xfb_dvec2_data_ptr, m_xfb_bo1_dvec2_size) != 0)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO1 dvec2 attribute values mismatch for batch ["
                                   << n_element
                                   << "]"
                                      ", expected:["
                                   << in_dvec2_data_ptr[0] << ", " << in_dvec2_data_ptr[1] << ", "
                                   << "], XFBed out:[" << xfb_dvec2_data_ptr[0] << ", " << xfb_dvec2_data_ptr[1] << ", "
                                   << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }

        /* Verify double data from BO1 has been exposed correctly */
        for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
        {
            unsigned int in_index        = n_element;
            const unsigned int xfb_index = is_indiced ? m_bo_index_data[n_element] : n_element;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const double *in_double_data_ptr =
                (const double *)(m_bo_1_data + (in_index)*m_po_bo1_double_attr_stride + m_po_bo1_double_attr_offset);
            const double *xfb_double_data_ptr =
                (const double *)(xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size +
                                 m_xfb_bo1_double_offset);

            if (memcmp(in_double_data_ptr, xfb_double_data_ptr, m_xfb_bo1_double_size) != 0)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO1 double attribute value mismatch for batch ["
                                   << n_element
                                   << "]"
                                      ", expected: ["
                                   << *in_double_data_ptr
                                   << "]"
                                      ", XFBed out:["
                                   << *xfb_double_data_ptr << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }

        /* Verify dmat4x2 data from BO2 has been exposed correctly */
        for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
        {
            unsigned int in_index        = n_element;
            const unsigned int xfb_index = is_indiced ? m_bo_index_data[n_element] : n_element;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const unsigned char *in_matrix_data_ptr =
                m_bo_2_data + (in_index)*m_po_bo2_dmat4x2_attr_stride + m_po_bo2_dmat4x2_attr_offset;
            const unsigned char *xfb_matrix_data_ptr =
                xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size + m_xfb_bo2_dmat4x2_offset;

            if (memcmp(in_matrix_data_ptr, xfb_matrix_data_ptr, m_xfb_bo2_dmat4x2_size) != 0)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO2 dmat4x2 attribute values mismatch for batch ["
                                   << n_element
                                   << "]"
                                      ", expected:["
                                   << in_matrix_data_ptr[0] << ", " << in_matrix_data_ptr[1] << ", "
                                   << in_matrix_data_ptr[2] << ", " << in_matrix_data_ptr[3] << ", "
                                   << in_matrix_data_ptr[4] << ", " << in_matrix_data_ptr[5] << ", "
                                   << in_matrix_data_ptr[6] << ", " << in_matrix_data_ptr[7] << ", "
                                   << "], XFBed out:[" << xfb_matrix_data_ptr[0] << ", " << xfb_matrix_data_ptr[1]
                                   << ", " << xfb_matrix_data_ptr[2] << ", " << xfb_matrix_data_ptr[3] << ", "
                                   << xfb_matrix_data_ptr[4] << ", " << xfb_matrix_data_ptr[5] << ", "
                                   << xfb_matrix_data_ptr[6] << ", " << xfb_matrix_data_ptr[7] << ", "
                                   << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }

        /* Verify int data from BO1 has been exposed correctly */
        for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
        {
            unsigned int in_index        = n_element;
            const unsigned int xfb_index = is_indiced ? m_bo_index_data[n_element] : n_element;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const signed char *in_char_data_ptr =
                (const signed char *)(m_bo_1_data + (in_index)*m_po_bo1_int_attr_stride + m_po_bo1_int_attr_offset);
            const signed int *xfb_int_data_ptr =
                (const signed int *)(xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size +
                                     m_xfb_bo1_int_offset);

            if (de::abs((signed int)*in_char_data_ptr - *xfb_int_data_ptr) > 0)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO1 int attribute value mismatch for batch ["
                                   << n_element
                                   << "]"
                                      ", expected: ["
                                   << (signed int)*in_char_data_ptr
                                   << "]"
                                      ", XFBed out:["
                                   << *xfb_int_data_ptr << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }

        /* Verify float data from BO1 has been exposed correctly */
        for (unsigned int n_element = 0; n_element < m_n_batches; ++n_element)
        {
            unsigned int in_index        = n_element;
            const unsigned int xfb_index = is_indiced ? m_bo_index_data[n_element] : n_element;

            if (!zero_vertex_attrib_divisor)
            {
                in_index = n_instance / m_nonzero_vertex_attrib_divisor;
            }

            const unsigned short *in_short_data_ptr =
                (const unsigned short *)(m_bo_1_data + (in_index)*m_po_bo1_float2_attr_stride +
                                         m_po_bo1_float2_attr_offset);
            const float *xfb_float_data_ptr =
                (const float *)(xfb_data_ptr + (m_n_batches * n_instance + xfb_index) * m_xfb_total_size +
                                m_xfb_bo1_float2_offset);

            if (de::abs(*in_short_data_ptr - *xfb_float_data_ptr) > epsilon)
            {
                m_testCtx.getLog() << tcu::TestLog::Message << "BO1 float attribute value mismatch for batch ["
                                   << n_element
                                   << "]"
                                      ", expected: ["
                                   << (signed int)*in_short_data_ptr
                                   << "]"
                                      ", XFBed out:["
                                   << *xfb_float_data_ptr << "]" << tcu::TestLog::EndMessage;

                result = false;
                break;
            }
        }
    } /* for (all instances) */

    return result;
}

} /* namespace VertexAttrib64Bit */

namespace gl4cts
{

VertexAttrib64BitTests::VertexAttrib64BitTests(deqp::Context &context)
    : TestCaseGroup(context, "vertex_attrib_64bit", "Verifes GL_ARB_vertex_attrib_64bit functionality")
{
    /* Nothing to be done here */
}

void VertexAttrib64BitTests::init(void)
{
    addChild(new VertexAttrib64Bit::ApiErrorsTest(m_context));
    addChild(new VertexAttrib64Bit::GetVertexAttribTest(m_context));
    addChild(new VertexAttrib64Bit::LimitTest(m_context));
    addChild(new VertexAttrib64Bit::VAOTest(m_context));
}

} /* namespace gl4cts */
