/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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 Draw tests
 *//*--------------------------------------------------------------------*/

#include "glsDrawTest.hpp"

#include "deRandom.h"
#include "deRandom.hpp"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deFloat16.h"
#include "deUniquePtr.hpp"
#include "deArrayUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuPixelFormat.hpp"
#include "tcuRGBA.hpp"
#include "tcuSurface.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuImageCompare.hpp"
#include "tcuFloat.hpp"
#include "tcuTextureUtil.hpp"

#include "gluContextInfo.hpp"
#include "gluPixelTransfer.hpp"
#include "gluCallLogWrapper.hpp"

#include "sglrContext.hpp"
#include "sglrReferenceContext.hpp"
#include "sglrGLContext.hpp"

#include "rrGenericVector.hpp"

#include <cstring>
#include <cmath>
#include <vector>
#include <sstream>
#include <limits>

#include "glwDefs.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gls
{
namespace
{

using tcu::TestLog;
using namespace glw; // GL types

const int MAX_RENDER_TARGET_SIZE = 512;

// Utils

static GLenum targetToGL(DrawTestSpec::Target target)
{
    static const GLenum targets[] = {
        GL_ELEMENT_ARRAY_BUFFER, // TARGET_ELEMENT_ARRAY = 0,
        GL_ARRAY_BUFFER          // TARGET_ARRAY,
    };

    return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target);
}

static GLenum usageToGL(DrawTestSpec::Usage usage)
{
    static const GLenum usages[] = {
        GL_DYNAMIC_DRAW, // USAGE_DYNAMIC_DRAW = 0,
        GL_STATIC_DRAW,  // USAGE_STATIC_DRAW,
        GL_STREAM_DRAW,  // USAGE_STREAM_DRAW,

        GL_STREAM_READ, // USAGE_STREAM_READ,
        GL_STREAM_COPY, // USAGE_STREAM_COPY,

        GL_STATIC_READ, // USAGE_STATIC_READ,
        GL_STATIC_COPY, // USAGE_STATIC_COPY,

        GL_DYNAMIC_READ, // USAGE_DYNAMIC_READ,
        GL_DYNAMIC_COPY  // USAGE_DYNAMIC_COPY,
    };

    return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage);
}

static GLenum inputTypeToGL(DrawTestSpec::InputType type)
{
    static const GLenum types[] = {
        GL_FLOAT,          // INPUTTYPE_FLOAT = 0,
        GL_FIXED,          // INPUTTYPE_FIXED,
        GL_DOUBLE,         // INPUTTYPE_DOUBLE
        GL_BYTE,           // INPUTTYPE_BYTE,
        GL_SHORT,          // INPUTTYPE_SHORT,
        GL_UNSIGNED_BYTE,  // INPUTTYPE_UNSIGNED_BYTE,
        GL_UNSIGNED_SHORT, // INPUTTYPE_UNSIGNED_SHORT,

        GL_INT,                         // INPUTTYPE_INT,
        GL_UNSIGNED_INT,                // INPUTTYPE_UNSIGNED_INT,
        GL_HALF_FLOAT,                  // INPUTTYPE_HALF,
        GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
        GL_INT_2_10_10_10_REV           // INPUTTYPE_INT_2_10_10_10,
    };

    return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type);
}

static std::string outputTypeToGLType(DrawTestSpec::OutputType type)
{
    static const char *types[] = {
        "float", // OUTPUTTYPE_FLOAT = 0,
        "vec2",  // OUTPUTTYPE_VEC2,
        "vec3",  // OUTPUTTYPE_VEC3,
        "vec4",  // OUTPUTTYPE_VEC4,

        "int",  // OUTPUTTYPE_INT,
        "uint", // OUTPUTTYPE_UINT,

        "ivec2", // OUTPUTTYPE_IVEC2,
        "ivec3", // OUTPUTTYPE_IVEC3,
        "ivec4", // OUTPUTTYPE_IVEC4,

        "uvec2", // OUTPUTTYPE_UVEC2,
        "uvec3", // OUTPUTTYPE_UVEC3,
        "uvec4", // OUTPUTTYPE_UVEC4,
    };

    return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type);
}

static GLenum primitiveToGL(DrawTestSpec::Primitive primitive)
{
    static const GLenum primitives[] = {
        GL_POINTS,                   // PRIMITIVE_POINTS = 0,
        GL_TRIANGLES,                // PRIMITIVE_TRIANGLES,
        GL_TRIANGLE_FAN,             // PRIMITIVE_TRIANGLE_FAN,
        GL_TRIANGLE_STRIP,           // PRIMITIVE_TRIANGLE_STRIP,
        GL_LINES,                    // PRIMITIVE_LINES
        GL_LINE_STRIP,               // PRIMITIVE_LINE_STRIP
        GL_LINE_LOOP,                // PRIMITIVE_LINE_LOOP
        GL_LINES_ADJACENCY,          // PRIMITIVE_LINES_ADJACENCY
        GL_LINE_STRIP_ADJACENCY,     // PRIMITIVE_LINE_STRIP_ADJACENCY
        GL_TRIANGLES_ADJACENCY,      // PRIMITIVE_TRIANGLES_ADJACENCY
        GL_TRIANGLE_STRIP_ADJACENCY, // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY
    };

    return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive);
}

static uint32_t indexTypeToGL(DrawTestSpec::IndexType indexType)
{
    static const GLenum indexTypes[] = {
        GL_UNSIGNED_BYTE,  // INDEXTYPE_BYTE = 0,
        GL_UNSIGNED_SHORT, // INDEXTYPE_SHORT,
        GL_UNSIGNED_INT,   // INDEXTYPE_INT,
    };

    return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)indexType);
}

static bool inputTypeIsFloatType(DrawTestSpec::InputType type)
{
    if (type == DrawTestSpec::INPUTTYPE_FLOAT)
        return true;
    if (type == DrawTestSpec::INPUTTYPE_FIXED)
        return true;
    if (type == DrawTestSpec::INPUTTYPE_HALF)
        return true;
    if (type == DrawTestSpec::INPUTTYPE_DOUBLE)
        return true;
    return false;
}

static bool outputTypeIsFloatType(DrawTestSpec::OutputType type)
{
    if (type == DrawTestSpec::OUTPUTTYPE_FLOAT || type == DrawTestSpec::OUTPUTTYPE_VEC2 ||
        type == DrawTestSpec::OUTPUTTYPE_VEC3 || type == DrawTestSpec::OUTPUTTYPE_VEC4)
        return true;

    return false;
}

static bool outputTypeIsIntType(DrawTestSpec::OutputType type)
{
    if (type == DrawTestSpec::OUTPUTTYPE_INT || type == DrawTestSpec::OUTPUTTYPE_IVEC2 ||
        type == DrawTestSpec::OUTPUTTYPE_IVEC3 || type == DrawTestSpec::OUTPUTTYPE_IVEC4)
        return true;

    return false;
}

static bool outputTypeIsUintType(DrawTestSpec::OutputType type)
{
    if (type == DrawTestSpec::OUTPUTTYPE_UINT || type == DrawTestSpec::OUTPUTTYPE_UVEC2 ||
        type == DrawTestSpec::OUTPUTTYPE_UVEC3 || type == DrawTestSpec::OUTPUTTYPE_UVEC4)
        return true;

    return false;
}

static size_t getElementCount(DrawTestSpec::Primitive primitive, size_t primitiveCount)
{
    switch (primitive)
    {
    case DrawTestSpec::PRIMITIVE_POINTS:
        return primitiveCount;
    case DrawTestSpec::PRIMITIVE_TRIANGLES:
        return primitiveCount * 3;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
        return primitiveCount + 2;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
        return primitiveCount + 2;
    case DrawTestSpec::PRIMITIVE_LINES:
        return primitiveCount * 2;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP:
        return primitiveCount + 1;
    case DrawTestSpec::PRIMITIVE_LINE_LOOP:
        return (primitiveCount == 1) ? (2) : (primitiveCount);
    case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
        return primitiveCount * 4;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
        return primitiveCount + 3;
    case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
        return primitiveCount * 6;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
        return primitiveCount * 2 + 4;
    default:
        DE_ASSERT(false);
        return 0;
    }
}

struct MethodInfo
{
    bool indexed;
    bool instanced;
    bool ranged;
    bool first;
    bool baseVertex;
    bool indirect;
};

static MethodInfo getMethodInfo(gls::DrawTestSpec::DrawMethod method)
{
    static const MethodInfo infos[] = {
        //    indexed        instanced    ranged        first        baseVertex    indirect
        {false, false, false, true, false, false}, //!< DRAWMETHOD_DRAWARRAYS,
        {false, true, false, true, false, false},  //!< DRAWMETHOD_DRAWARRAYS_INSTANCED,
        {false, true, false, true, false, true},   //!< DRAWMETHOD_DRAWARRAYS_INDIRECT,
        {true, false, false, false, false, false}, //!< DRAWMETHOD_DRAWELEMENTS,
        {true, false, true, false, false, false},  //!< DRAWMETHOD_DRAWELEMENTS_RANGED,
        {true, true, false, false, false, false},  //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED,
        {true, true, false, false, true, true},    //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT,
        {true, false, false, false, true, false},  //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
        {true, true, false, false, true, false},   //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
        {true, false, true, false, true, false},   //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
    };

    return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(infos, (int)method);
}

template <class T>
inline static void alignmentSafeAssignment(char *dst, T val)
{
    std::memcpy(dst, &val, sizeof(T));
}

static bool checkSpecsShaderCompatible(const DrawTestSpec &a, const DrawTestSpec &b)
{
    // Only the attributes matter
    if (a.attribs.size() != b.attribs.size())
        return false;

    for (size_t ndx = 0; ndx < a.attribs.size(); ++ndx)
    {
        // Only the output type (== shader input type) matters and the usage in the shader.

        if (a.attribs[ndx].additionalPositionAttribute != b.attribs[ndx].additionalPositionAttribute)
            return false;

        // component counts need not to match
        if (outputTypeIsFloatType(a.attribs[ndx].outputType) && outputTypeIsFloatType(b.attribs[ndx].outputType))
            continue;
        if (outputTypeIsIntType(a.attribs[ndx].outputType) && outputTypeIsIntType(b.attribs[ndx].outputType))
            continue;
        if (outputTypeIsUintType(a.attribs[ndx].outputType) && outputTypeIsUintType(b.attribs[ndx].outputType))
            continue;

        return false;
    }

    return true;
}

// generate random vectors in a way that does not depend on argument evaluation order

tcu::Vec4 generateRandomVec4(de::Random &random)
{
    tcu::Vec4 retVal;

    for (int i = 0; i < 4; ++i)
        retVal[i] = random.getFloat();

    return retVal;
}

tcu::IVec4 generateRandomIVec4(de::Random &random)
{
    tcu::IVec4 retVal;

    for (int i = 0; i < 4; ++i)
        retVal[i] = random.getUint32();

    return retVal;
}

tcu::UVec4 generateRandomUVec4(de::Random &random)
{
    tcu::UVec4 retVal;

    for (int i = 0; i < 4; ++i)
        retVal[i] = random.getUint32();

    return retVal;
}

// IterationLogSectionEmitter

class IterationLogSectionEmitter
{
public:
    IterationLogSectionEmitter(tcu::TestLog &log, size_t testIteration, size_t testIterations,
                               const std::string &description, bool enabled);
    ~IterationLogSectionEmitter(void);

private:
    IterationLogSectionEmitter(const IterationLogSectionEmitter &);            // delete
    IterationLogSectionEmitter &operator=(const IterationLogSectionEmitter &); // delete

    tcu::TestLog &m_log;
    bool m_enabled;
};

IterationLogSectionEmitter::IterationLogSectionEmitter(tcu::TestLog &log, size_t testIteration, size_t testIterations,
                                                       const std::string &description, bool enabled)
    : m_log(log)
    , m_enabled(enabled)
{
    if (m_enabled)
    {
        std::ostringstream buf;
        buf << "Iteration " << (testIteration + 1) << "/" << testIterations;

        if (!description.empty())
            buf << " - " << description;

        m_log << tcu::TestLog::Section(buf.str(), buf.str());
    }
}

IterationLogSectionEmitter::~IterationLogSectionEmitter(void)
{
    if (m_enabled)
        m_log << tcu::TestLog::EndSection;
}

// GLValue

class GLValue
{
public:
    template <class Type>
    class WrappedType
    {
    public:
        static WrappedType<Type> create(Type value)
        {
            WrappedType<Type> v;
            v.m_value = value;
            return v;
        }
        inline Type getValue(void) const
        {
            return m_value;
        }

        inline WrappedType<Type> operator+(const WrappedType<Type> &other) const
        {
            return WrappedType<Type>::create((Type)(m_value + other.getValue()));
        }
        inline WrappedType<Type> operator*(const WrappedType<Type> &other) const
        {
            return WrappedType<Type>::create((Type)(m_value * other.getValue()));
        }
        inline WrappedType<Type> operator/(const WrappedType<Type> &other) const
        {
            return WrappedType<Type>::create((Type)(m_value / other.getValue()));
        }
        inline WrappedType<Type> operator-(const WrappedType<Type> &other) const
        {
            return WrappedType<Type>::create((Type)(m_value - other.getValue()));
        }

        inline WrappedType<Type> &operator+=(const WrappedType<Type> &other)
        {
            m_value += other.getValue();
            return *this;
        }
        inline WrappedType<Type> &operator*=(const WrappedType<Type> &other)
        {
            m_value *= other.getValue();
            return *this;
        }
        inline WrappedType<Type> &operator/=(const WrappedType<Type> &other)
        {
            m_value /= other.getValue();
            return *this;
        }
        inline WrappedType<Type> &operator-=(const WrappedType<Type> &other)
        {
            m_value -= other.getValue();
            return *this;
        }

        inline bool operator==(const WrappedType<Type> &other) const
        {
            return m_value == other.m_value;
        }
        inline bool operator!=(const WrappedType<Type> &other) const
        {
            return m_value != other.m_value;
        }
        inline bool operator<(const WrappedType<Type> &other) const
        {
            return m_value < other.m_value;
        }
        inline bool operator>(const WrappedType<Type> &other) const
        {
            return m_value > other.m_value;
        }
        inline bool operator<=(const WrappedType<Type> &other) const
        {
            return m_value <= other.m_value;
        }
        inline bool operator>=(const WrappedType<Type> &other) const
        {
            return m_value >= other.m_value;
        }

        inline operator Type(void) const
        {
            return m_value;
        }
        template <class T>
        inline T to(void) const
        {
            return (T)m_value;
        }

    private:
        Type m_value;
    };

    typedef WrappedType<int16_t> Short;
    typedef WrappedType<uint16_t> Ushort;

    typedef WrappedType<int8_t> Byte;
    typedef WrappedType<uint8_t> Ubyte;

    typedef WrappedType<float> Float;
    typedef WrappedType<double> Double;

    typedef WrappedType<int32_t> Int;
    typedef WrappedType<uint32_t> Uint;

    class Half
    {
    public:
        static Half create(float value)
        {
            Half h;
            h.m_value = floatToHalf(value);
            return h;
        }
        inline deFloat16 getValue(void) const
        {
            return m_value;
        }

        inline Half operator+(const Half &other) const
        {
            return create(halfToFloat(m_value) + halfToFloat(other.getValue()));
        }
        inline Half operator*(const Half &other) const
        {
            return create(halfToFloat(m_value) * halfToFloat(other.getValue()));
        }
        inline Half operator/(const Half &other) const
        {
            return create(halfToFloat(m_value) / halfToFloat(other.getValue()));
        }
        inline Half operator-(const Half &other) const
        {
            return create(halfToFloat(m_value) - halfToFloat(other.getValue()));
        }

        inline Half &operator+=(const Half &other)
        {
            m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value));
            return *this;
        }
        inline Half &operator*=(const Half &other)
        {
            m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value));
            return *this;
        }
        inline Half &operator/=(const Half &other)
        {
            m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value));
            return *this;
        }
        inline Half &operator-=(const Half &other)
        {
            m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value));
            return *this;
        }

        inline bool operator==(const Half &other) const
        {
            return m_value == other.m_value;
        }
        inline bool operator!=(const Half &other) const
        {
            return m_value != other.m_value;
        }
        inline bool operator<(const Half &other) const
        {
            return halfToFloat(m_value) < halfToFloat(other.m_value);
        }
        inline bool operator>(const Half &other) const
        {
            return halfToFloat(m_value) > halfToFloat(other.m_value);
        }
        inline bool operator<=(const Half &other) const
        {
            return halfToFloat(m_value) <= halfToFloat(other.m_value);
        }
        inline bool operator>=(const Half &other) const
        {
            return halfToFloat(m_value) >= halfToFloat(other.m_value);
        }

        template <class T>
        inline T to(void) const
        {
            return (T)halfToFloat(m_value);
        }

        inline static deFloat16 floatToHalf(float f);
        inline static float halfToFloat(deFloat16 h);

    private:
        deFloat16 m_value;
    };

    class Fixed
    {
    public:
        static Fixed create(int32_t value)
        {
            Fixed v;
            v.m_value = value;
            return v;
        }
        inline int32_t getValue(void) const
        {
            return m_value;
        }

        inline Fixed operator+(const Fixed &other) const
        {
            return create(m_value + other.getValue());
        }
        inline Fixed operator*(const Fixed &other) const
        {
            return create(m_value * other.getValue());
        }
        inline Fixed operator/(const Fixed &other) const
        {
            return create(m_value / other.getValue());
        }
        inline Fixed operator-(const Fixed &other) const
        {
            return create(m_value - other.getValue());
        }

        inline Fixed &operator+=(const Fixed &other)
        {
            m_value += other.getValue();
            return *this;
        }
        inline Fixed &operator*=(const Fixed &other)
        {
            m_value *= other.getValue();
            return *this;
        }
        inline Fixed &operator/=(const Fixed &other)
        {
            m_value /= other.getValue();
            return *this;
        }
        inline Fixed &operator-=(const Fixed &other)
        {
            m_value -= other.getValue();
            return *this;
        }

        inline bool operator==(const Fixed &other) const
        {
            return m_value == other.m_value;
        }
        inline bool operator!=(const Fixed &other) const
        {
            return m_value != other.m_value;
        }
        inline bool operator<(const Fixed &other) const
        {
            return m_value < other.m_value;
        }
        inline bool operator>(const Fixed &other) const
        {
            return m_value > other.m_value;
        }
        inline bool operator<=(const Fixed &other) const
        {
            return m_value <= other.m_value;
        }
        inline bool operator>=(const Fixed &other) const
        {
            return m_value >= other.m_value;
        }

        inline operator int32_t(void) const
        {
            return m_value;
        }
        template <class T>
        inline T to(void) const
        {
            return (T)m_value;
        }

    private:
        int32_t m_value;
    };

    // \todo [mika] This is pretty messy
    GLValue(void) : type(DrawTestSpec::INPUTTYPE_LAST)
    {
    }
    explicit GLValue(Float value) : type(DrawTestSpec::INPUTTYPE_FLOAT), fl(value)
    {
    }
    explicit GLValue(Fixed value) : type(DrawTestSpec::INPUTTYPE_FIXED), fi(value)
    {
    }
    explicit GLValue(Byte value) : type(DrawTestSpec::INPUTTYPE_BYTE), b(value)
    {
    }
    explicit GLValue(Ubyte value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE), ub(value)
    {
    }
    explicit GLValue(Short value) : type(DrawTestSpec::INPUTTYPE_SHORT), s(value)
    {
    }
    explicit GLValue(Ushort value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT), us(value)
    {
    }
    explicit GLValue(Int value) : type(DrawTestSpec::INPUTTYPE_INT), i(value)
    {
    }
    explicit GLValue(Uint value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_INT), ui(value)
    {
    }
    explicit GLValue(Half value) : type(DrawTestSpec::INPUTTYPE_HALF), h(value)
    {
    }
    explicit GLValue(Double value) : type(DrawTestSpec::INPUTTYPE_DOUBLE), d(value)
    {
    }

    float toFloat(void) const;

    static GLValue getMaxValue(DrawTestSpec::InputType type);
    static GLValue getMinValue(DrawTestSpec::InputType type);

    DrawTestSpec::InputType type;

    union
    {
        Float fl;
        Fixed fi;
        Double d;
        Byte b;
        Ubyte ub;
        Short s;
        Ushort us;
        Int i;
        Uint ui;
        Half h;
    };
};

inline deFloat16 GLValue::Half::floatToHalf(float f)
{
    // No denorm support.
    tcu::Float<uint16_t, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f);
    DE_ASSERT(!v.isNaN() && !v.isInf());
    return v.bits();
}

inline float GLValue::Half::halfToFloat(deFloat16 h)
{
    return tcu::Float16((uint16_t)h).asFloat();
}

float GLValue::toFloat(void) const
{
    switch (type)
    {
    case DrawTestSpec::INPUTTYPE_FLOAT:
        return fl.getValue();

    case DrawTestSpec::INPUTTYPE_BYTE:
        return b.getValue();

    case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:
        return ub.getValue();

    case DrawTestSpec::INPUTTYPE_SHORT:
        return s.getValue();

    case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:
        return us.getValue();

    case DrawTestSpec::INPUTTYPE_FIXED:
    {
        int maxValue = 65536;
        return (float)(double(2 * fi.getValue() + 1) / (maxValue - 1));
    }

    case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
        return (float)ui.getValue();

    case DrawTestSpec::INPUTTYPE_INT:
        return (float)i.getValue();

    case DrawTestSpec::INPUTTYPE_HALF:
        return h.to<float>();

    case DrawTestSpec::INPUTTYPE_DOUBLE:
        return d.to<float>();

    default:
        DE_ASSERT(false);
        return 0.0f;
    }
}

GLValue GLValue::getMaxValue(DrawTestSpec::InputType type)
{
    GLValue rangesHi[(int)DrawTestSpec::INPUTTYPE_LAST];

    rangesHi[(int)DrawTestSpec::INPUTTYPE_FLOAT]          = GLValue(Float::create(127.0f));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_DOUBLE]         = GLValue(Double::create(127.0f));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_BYTE]           = GLValue(Byte::create(127));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE]  = GLValue(Ubyte::create(255));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(65530));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_SHORT]          = GLValue(Short::create(32760));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_FIXED]          = GLValue(Fixed::create(32760));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_INT]            = GLValue(Int::create(2147483647));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT]   = GLValue(Uint::create(4294967295u));
    rangesHi[(int)DrawTestSpec::INPUTTYPE_HALF]           = GLValue(Half::create(256.0f));

    return rangesHi[(int)type];
}

GLValue GLValue::getMinValue(DrawTestSpec::InputType type)
{
    GLValue rangesLo[(int)DrawTestSpec::INPUTTYPE_LAST];

    rangesLo[(int)DrawTestSpec::INPUTTYPE_FLOAT]          = GLValue(Float::create(-127.0f));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_DOUBLE]         = GLValue(Double::create(-127.0f));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_BYTE]           = GLValue(Byte::create(-127));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE]  = GLValue(Ubyte::create(0));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(0));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_SHORT]          = GLValue(Short::create(-32760));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_FIXED]          = GLValue(Fixed::create(-32760));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_INT]            = GLValue(Int::create(-2147483647));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT]   = GLValue(Uint::create(0));
    rangesLo[(int)DrawTestSpec::INPUTTYPE_HALF]           = GLValue(Half::create(-256.0f));

    return rangesLo[(int)type];
}

template <typename T>
struct GLValueTypeTraits;

template <>
struct GLValueTypeTraits<GLValue::Float>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FLOAT;
};
template <>
struct GLValueTypeTraits<GLValue::Double>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_DOUBLE;
};
template <>
struct GLValueTypeTraits<GLValue::Byte>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_BYTE;
};
template <>
struct GLValueTypeTraits<GLValue::Ubyte>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE;
};
template <>
struct GLValueTypeTraits<GLValue::Ushort>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT;
};
template <>
struct GLValueTypeTraits<GLValue::Short>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_SHORT;
};
template <>
struct GLValueTypeTraits<GLValue::Fixed>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FIXED;
};
template <>
struct GLValueTypeTraits<GLValue::Int>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_INT;
};
template <>
struct GLValueTypeTraits<GLValue::Uint>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_INT;
};
template <>
struct GLValueTypeTraits<GLValue::Half>
{
    static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_HALF;
};

template <typename T>
inline T extractGLValue(const GLValue &v);

template <>
GLValue::Float inline extractGLValue<GLValue::Float>(const GLValue &v)
{
    return v.fl;
}
template <>
GLValue::Double inline extractGLValue<GLValue::Double>(const GLValue &v)
{
    return v.d;
}
template <>
GLValue::Byte inline extractGLValue<GLValue::Byte>(const GLValue &v)
{
    return v.b;
}
template <>
GLValue::Ubyte inline extractGLValue<GLValue::Ubyte>(const GLValue &v)
{
    return v.ub;
}
template <>
GLValue::Ushort inline extractGLValue<GLValue::Ushort>(const GLValue &v)
{
    return v.us;
}
template <>
GLValue::Short inline extractGLValue<GLValue::Short>(const GLValue &v)
{
    return v.s;
}
template <>
GLValue::Fixed inline extractGLValue<GLValue::Fixed>(const GLValue &v)
{
    return v.fi;
}
template <>
GLValue::Int inline extractGLValue<GLValue::Int>(const GLValue &v)
{
    return v.i;
}
template <>
GLValue::Uint inline extractGLValue<GLValue::Uint>(const GLValue &v)
{
    return v.ui;
}
template <>
GLValue::Half inline extractGLValue<GLValue::Half>(const GLValue &v)
{
    return v.h;
}

template <class T>
inline T getRandom(deRandom &rnd, T min, T max);

template <>
inline GLValue::Float getRandom(deRandom &rnd, GLValue::Float min, GLValue::Float max)
{
    if (max < min)
        return min;

    return GLValue::Float::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>()));
}

template <>
inline GLValue::Double getRandom(deRandom &rnd, GLValue::Double min, GLValue::Double max)
{
    if (max < min)
        return min;

    return GLValue::Double::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>()));
}

template <>
inline GLValue::Short getRandom(deRandom &rnd, GLValue::Short min, GLValue::Short max)
{
    if (max < min)
        return min;

    return GLValue::Short::create(
        (min == max ? min : (int16_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template <>
inline GLValue::Ushort getRandom(deRandom &rnd, GLValue::Ushort min, GLValue::Ushort max)
{
    if (max < min)
        return min;

    return GLValue::Ushort::create(
        (min == max ? min : (uint16_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template <>
inline GLValue::Byte getRandom(deRandom &rnd, GLValue::Byte min, GLValue::Byte max)
{
    if (max < min)
        return min;

    return GLValue::Byte::create(
        (min == max ? min : (int8_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template <>
inline GLValue::Ubyte getRandom(deRandom &rnd, GLValue::Ubyte min, GLValue::Ubyte max)
{
    if (max < min)
        return min;

    return GLValue::Ubyte::create(
        (min == max ? min : (uint8_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template <>
inline GLValue::Fixed getRandom(deRandom &rnd, GLValue::Fixed min, GLValue::Fixed max)
{
    if (max < min)
        return min;

    return GLValue::Fixed::create(
        (min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<uint32_t>() - min.to<uint32_t>()))));
}

template <>
inline GLValue::Half getRandom(deRandom &rnd, GLValue::Half min, GLValue::Half max)
{
    if (max < min)
        return min;

    float fMax      = max.to<float>();
    float fMin      = min.to<float>();
    GLValue::Half h = GLValue::Half::create(fMin + deRandom_getFloat(&rnd) * (fMax - fMin));
    return h;
}

template <>
inline GLValue::Int getRandom(deRandom &rnd, GLValue::Int min, GLValue::Int max)
{
    if (max < min)
        return min;

    return GLValue::Int::create(
        (min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<uint32_t>() - min.to<uint32_t>()))));
}

template <>
inline GLValue::Uint getRandom(deRandom &rnd, GLValue::Uint min, GLValue::Uint max)
{
    if (max < min)
        return min;

    return GLValue::Uint::create(
        (min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<uint32_t>() - min.to<uint32_t>()))));
}

// Minimum difference required between coordinates
template <class T>
inline T minValue(void);

template <>
inline GLValue::Float minValue(void)
{
    return GLValue::Float::create(4 * 1.0f);
}

template <>
inline GLValue::Double minValue(void)
{
    return GLValue::Double::create(4 * 1.0f);
}

template <>
inline GLValue::Short minValue(void)
{
    return GLValue::Short::create(4 * 256);
}

template <>
inline GLValue::Ushort minValue(void)
{
    return GLValue::Ushort::create(4 * 256);
}

template <>
inline GLValue::Byte minValue(void)
{
    return GLValue::Byte::create(4 * 1);
}

template <>
inline GLValue::Ubyte minValue(void)
{
    return GLValue::Ubyte::create(4 * 2);
}

template <>
inline GLValue::Fixed minValue(void)
{
    return GLValue::Fixed::create(4 * 1);
}

template <>
inline GLValue::Int minValue(void)
{
    return GLValue::Int::create(4 * 16777216);
}

template <>
inline GLValue::Uint minValue(void)
{
    return GLValue::Uint::create(4 * 16777216);
}

template <>
inline GLValue::Half minValue(void)
{
    return GLValue::Half::create(4 * 1.0f);
}

template <class T>
inline T abs(T val);

template <>
inline GLValue::Fixed abs(GLValue::Fixed val)
{
    return GLValue::Fixed::create(0x7FFFu & val.getValue());
}

template <>
inline GLValue::Ubyte abs(GLValue::Ubyte val)
{
    return val;
}

template <>
inline GLValue::Byte abs(GLValue::Byte val)
{
    return GLValue::Byte::create(0x7Fu & val.getValue());
}

template <>
inline GLValue::Ushort abs(GLValue::Ushort val)
{
    return val;
}

template <>
inline GLValue::Short abs(GLValue::Short val)
{
    return GLValue::Short::create(0x7FFFu & val.getValue());
}

template <>
inline GLValue::Float abs(GLValue::Float val)
{
    return GLValue::Float::create(std::fabs(val.to<float>()));
}

template <>
inline GLValue::Double abs(GLValue::Double val)
{
    return GLValue::Double::create(std::fabs(val.to<float>()));
}

template <>
inline GLValue::Uint abs(GLValue::Uint val)
{
    return val;
}

template <>
inline GLValue::Int abs(GLValue::Int val)
{
    return GLValue::Int::create(0x7FFFFFFFu & val.getValue());
}

template <>
inline GLValue::Half abs(GLValue::Half val)
{
    return GLValue::Half::create(std::fabs(val.to<float>()));
}

// AttributeArray

class AttributeArray
{
public:
    AttributeArray(DrawTestSpec::Storage storage, sglr::Context &context);
    ~AttributeArray(void);

    void data(DrawTestSpec::Target target, size_t size, const char *data, DrawTestSpec::Usage usage);
    void setupArray(bool bound, int offset, int size, DrawTestSpec::InputType inType, DrawTestSpec::OutputType outType,
                    bool normalized, int stride, int instanceDivisor, const rr::GenericVec4 &defaultAttrib,
                    bool isPositionAttr, bool bgraComponentOrder);
    void bindAttribute(uint32_t loc);
    void bindIndexArray(DrawTestSpec::Target storage);

    int getComponentCount(void) const
    {
        return m_componentCount;
    }
    DrawTestSpec::Target getTarget(void) const
    {
        return m_target;
    }
    DrawTestSpec::InputType getInputType(void) const
    {
        return m_inputType;
    }
    DrawTestSpec::OutputType getOutputType(void) const
    {
        return m_outputType;
    }
    DrawTestSpec::Storage getStorageType(void) const
    {
        return m_storage;
    }
    bool getNormalized(void) const
    {
        return m_normalize;
    }
    int getStride(void) const
    {
        return m_stride;
    }
    bool isBound(void) const
    {
        return m_bound;
    }
    bool isPositionAttribute(void) const
    {
        return m_isPositionAttr;
    }

private:
    DrawTestSpec::Storage m_storage;
    sglr::Context &m_ctx;
    uint32_t m_glBuffer;

    int m_size;
    char *m_data;
    int m_componentCount;
    bool m_bound;
    DrawTestSpec::Target m_target;
    DrawTestSpec::InputType m_inputType;
    DrawTestSpec::OutputType m_outputType;
    bool m_normalize;
    int m_stride;
    int m_offset;
    rr::GenericVec4 m_defaultAttrib;
    int m_instanceDivisor;
    bool m_isPositionAttr;
    bool m_bgraOrder;
};

AttributeArray::AttributeArray(DrawTestSpec::Storage storage, sglr::Context &context)
    : m_storage(storage)
    , m_ctx(context)
    , m_glBuffer(0)
    , m_size(0)
    , m_data(DE_NULL)
    , m_componentCount(1)
    , m_bound(false)
    , m_target(DrawTestSpec::TARGET_ARRAY)
    , m_inputType(DrawTestSpec::INPUTTYPE_FLOAT)
    , m_outputType(DrawTestSpec::OUTPUTTYPE_VEC4)
    , m_normalize(false)
    , m_stride(0)
    , m_offset(0)
    , m_instanceDivisor(0)
    , m_isPositionAttr(false)
    , m_bgraOrder(false)
{
    if (m_storage == DrawTestSpec::STORAGE_BUFFER)
    {
        m_ctx.genBuffers(1, &m_glBuffer);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glGenBuffers()");
    }
}

AttributeArray::~AttributeArray(void)
{
    if (m_storage == DrawTestSpec::STORAGE_BUFFER)
    {
        m_ctx.deleteBuffers(1, &m_glBuffer);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDeleteBuffers()");
    }
    else if (m_storage == DrawTestSpec::STORAGE_USER)
        delete[] m_data;
    else
        DE_ASSERT(false);
}

void AttributeArray::data(DrawTestSpec::Target target, size_t size, const char *ptr, DrawTestSpec::Usage usage)
{
    m_size   = (int)size;
    m_target = target;

    if (m_storage == DrawTestSpec::STORAGE_BUFFER)
    {
        m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

        m_ctx.bufferData(targetToGL(target), size, ptr, usageToGL(usage));
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferData()");
    }
    else if (m_storage == DrawTestSpec::STORAGE_USER)
    {
        if (m_data)
            delete[] m_data;

        m_data = new char[size];
        std::memcpy(m_data, ptr, size);
    }
    else
        DE_ASSERT(false);
}

void AttributeArray::setupArray(bool bound, int offset, int size, DrawTestSpec::InputType inputType,
                                DrawTestSpec::OutputType outType, bool normalized, int stride, int instanceDivisor,
                                const rr::GenericVec4 &defaultAttrib, bool isPositionAttr, bool bgraComponentOrder)
{
    m_componentCount  = size;
    m_bound           = bound;
    m_inputType       = inputType;
    m_outputType      = outType;
    m_normalize       = normalized;
    m_stride          = stride;
    m_offset          = offset;
    m_defaultAttrib   = defaultAttrib;
    m_instanceDivisor = instanceDivisor;
    m_isPositionAttr  = isPositionAttr;
    m_bgraOrder       = bgraComponentOrder;
}

void AttributeArray::bindAttribute(uint32_t loc)
{
    if (!isBound())
    {
        switch (m_inputType)
        {
        case DrawTestSpec::INPUTTYPE_FLOAT:
        {
            tcu::Vec4 attr = m_defaultAttrib.get<float>();

            switch (m_componentCount)
            {
            case 1:
                m_ctx.vertexAttrib1f(loc, attr.x());
                break;
            case 2:
                m_ctx.vertexAttrib2f(loc, attr.x(), attr.y());
                break;
            case 3:
                m_ctx.vertexAttrib3f(loc, attr.x(), attr.y(), attr.z());
                break;
            case 4:
                m_ctx.vertexAttrib4f(loc, attr.x(), attr.y(), attr.z(), attr.w());
                break;
            default:
                DE_ASSERT(false);
                break;
            }
            break;
        }
        case DrawTestSpec::INPUTTYPE_INT:
        {
            tcu::IVec4 attr = m_defaultAttrib.get<int32_t>();
            m_ctx.vertexAttribI4i(loc, attr.x(), attr.y(), attr.z(), attr.w());
            break;
        }
        case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
        {
            tcu::UVec4 attr = m_defaultAttrib.get<uint32_t>();
            m_ctx.vertexAttribI4ui(loc, attr.x(), attr.y(), attr.z(), attr.w());
            break;
        }
        default:
            DE_ASSERT(false);
            break;
        }
    }
    else
    {
        const uint8_t *basePtr = DE_NULL;

        if (m_storage == DrawTestSpec::STORAGE_BUFFER)
        {
            m_ctx.bindBuffer(targetToGL(m_target), m_glBuffer);
            GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

            basePtr = DE_NULL;
        }
        else if (m_storage == DrawTestSpec::STORAGE_USER)
        {
            m_ctx.bindBuffer(targetToGL(m_target), 0);
            GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

            basePtr = (const uint8_t *)m_data;
        }
        else
            DE_ASSERT(false);

        if (!inputTypeIsFloatType(m_inputType))
        {
            // Input is not float type

            if (outputTypeIsFloatType(m_outputType))
            {
                const int size = (m_bgraOrder) ? (GL_BGRA) : (m_componentCount);

                DE_ASSERT(!(m_bgraOrder && m_componentCount != 4));

                // Output type is float type
                m_ctx.vertexAttribPointer(loc, size, inputTypeToGL(m_inputType), m_normalize, m_stride,
                                          basePtr + m_offset);
                GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
            }
            else
            {
                // Output type is int type
                m_ctx.vertexAttribIPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_stride,
                                           basePtr + m_offset);
                GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()");
            }
        }
        else
        {
            // Input type is float type

            // Output type must be float type
            DE_ASSERT(outputTypeIsFloatType(m_outputType));

            m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride,
                                      basePtr + m_offset);
            GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
        }

        if (m_instanceDivisor)
            m_ctx.vertexAttribDivisor(loc, m_instanceDivisor);
    }
}

void AttributeArray::bindIndexArray(DrawTestSpec::Target target)
{
    if (m_storage == DrawTestSpec::STORAGE_USER)
    {
    }
    else if (m_storage == DrawTestSpec::STORAGE_BUFFER)
    {
        m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
    }
}

// DrawTestShaderProgram

class DrawTestShaderProgram : public sglr::ShaderProgram
{
public:
    DrawTestShaderProgram(const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays);

    void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
    void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
                        const rr::FragmentShadingContext &context) const;

private:
    static std::string genVertexSource(const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays);
    static std::string genFragmentSource(const glu::RenderContext &ctx);
    static void generateShaderParams(std::map<std::string, std::string> &params, glu::ContextType type);
    static rr::GenericVecType mapOutputType(const DrawTestSpec::OutputType &type);
    static int getComponentCount(const DrawTestSpec::OutputType &type);

    static sglr::pdec::ShaderProgramDeclaration createProgramDeclaration(const glu::RenderContext &ctx,
                                                                         const std::vector<AttributeArray *> &arrays);

    std::vector<int> m_componentCount;
    std::vector<bool> m_isCoord;
    std::vector<rr::GenericVecType> m_attrType;
};

DrawTestShaderProgram::DrawTestShaderProgram(const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays)
    : sglr::ShaderProgram(createProgramDeclaration(ctx, arrays))
    , m_componentCount(arrays.size())
    , m_isCoord(arrays.size())
    , m_attrType(arrays.size())
{
    for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
    {
        m_componentCount[arrayNdx] = getComponentCount(arrays[arrayNdx]->getOutputType());
        m_isCoord[arrayNdx]        = arrays[arrayNdx]->isPositionAttribute();
        m_attrType[arrayNdx]       = mapOutputType(arrays[arrayNdx]->getOutputType());
    }
}

template <typename T>
void calcShaderColorCoord(tcu::Vec2 &coord, tcu::Vec3 &color, const tcu::Vector<T, 4> &attribValue, bool isCoordinate,
                          int numComponents)
{
    if (isCoordinate)
        switch (numComponents)
        {
        case 1:
            coord += tcu::Vec2((float)attribValue.x(), (float)attribValue.x());
            break;
        case 2:
            coord += tcu::Vec2((float)attribValue.x(), (float)attribValue.y());
            break;
        case 3:
            coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(), (float)attribValue.y());
            break;
        case 4:
            coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(),
                               (float)attribValue.y() + (float)attribValue.w());
            break;

        default:
            DE_ASSERT(false);
        }
    else
    {
        switch (numComponents)
        {
        case 1:
            color = color * (float)attribValue.x();
            break;

        case 2:
            color.x() = color.x() * (float)attribValue.x();
            color.y() = color.y() * (float)attribValue.y();
            break;

        case 3:
            color.x() = color.x() * (float)attribValue.x();
            color.y() = color.y() * (float)attribValue.y();
            color.z() = color.z() * (float)attribValue.z();
            break;

        case 4:
            color.x() = color.x() * (float)attribValue.x() * (float)attribValue.w();
            color.y() = color.y() * (float)attribValue.y() * (float)attribValue.w();
            color.z() = color.z() * (float)attribValue.z() * (float)attribValue.w();
            break;

        default:
            DE_ASSERT(false);
        }
    }
}

void DrawTestShaderProgram::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
                                          const int numPackets) const
{
    const float u_coordScale = getUniformByName("u_coordScale").value.f;
    const float u_colorScale = getUniformByName("u_colorScale").value.f;

    for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
    {
        const size_t varyingLocColor = 0;

        rr::VertexPacket &packet = *packets[packetNdx];

        // Calc output color
        tcu::Vec2 coord = tcu::Vec2(0.0, 0.0);
        tcu::Vec3 color = tcu::Vec3(1.0, 1.0, 1.0);

        for (int attribNdx = 0; attribNdx < (int)m_attrType.size(); attribNdx++)
        {
            const int numComponents = m_componentCount[attribNdx];
            const bool isCoord      = m_isCoord[attribNdx];

            switch (m_attrType[attribNdx])
            {
            case rr::GENERICVECTYPE_FLOAT:
                calcShaderColorCoord(coord, color,
                                     rr::readVertexAttribFloat(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx),
                                     isCoord, numComponents);
                break;
            case rr::GENERICVECTYPE_INT32:
                calcShaderColorCoord(coord, color,
                                     rr::readVertexAttribInt(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx),
                                     isCoord, numComponents);
                break;
            case rr::GENERICVECTYPE_UINT32:
                calcShaderColorCoord(coord, color,
                                     rr::readVertexAttribUint(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx),
                                     isCoord, numComponents);
                break;
            default:
                DE_ASSERT(false);
            }
        }

        // Transform position
        {
            packet.position  = tcu::Vec4(u_coordScale * coord.x(), u_coordScale * coord.y(), 1.0f, 1.0f);
            packet.pointSize = 1.0f;
        }

        // Pass color to FS
        {
            packet.outputs[varyingLocColor] =
                tcu::Vec4(u_colorScale * color.x(), u_colorScale * color.y(), u_colorScale * color.z(), 1.0f) * 0.5f +
                tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
        }
    }
}

void DrawTestShaderProgram::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
                                           const rr::FragmentShadingContext &context) const
{
    const size_t varyingLocColor = 0;

    for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
    {
        rr::FragmentPacket &packet = packets[packetNdx];

        for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
            rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
                                    rr::readVarying<float>(packet, context, varyingLocColor, fragNdx));
    }
}

std::string DrawTestShaderProgram::genVertexSource(const glu::RenderContext &ctx,
                                                   const std::vector<AttributeArray *> &arrays)
{
    std::map<std::string, std::string> params;
    std::stringstream vertexShaderTmpl;

    generateShaderParams(params, ctx.getType());

    vertexShaderTmpl << "${VTX_HDR}";

    for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
    {
        vertexShaderTmpl << "${VTX_IN} highp " << outputTypeToGLType(arrays[arrayNdx]->getOutputType()) << " a_"
                         << arrayNdx << ";\n";
    }

    vertexShaderTmpl << "uniform highp float u_coordScale;\n"
                        "uniform highp float u_colorScale;\n"
                        "${VTX_OUT} ${COL_PRECISION} vec4 v_color;\n"
                        "void main(void)\n"
                        "{\n"
                        "\tgl_PointSize = 1.0;\n"
                        "\thighp vec2 coord = vec2(0.0, 0.0);\n"
                        "\thighp vec3 color = vec3(1.0, 1.0, 1.0);\n";

    for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
    {
        const bool isPositionAttr = arrays[arrayNdx]->isPositionAttribute();

        if (isPositionAttr)
        {
            switch (arrays[arrayNdx]->getOutputType())
            {
            case (DrawTestSpec::OUTPUTTYPE_FLOAT):
            case (DrawTestSpec::OUTPUTTYPE_INT):
            case (DrawTestSpec::OUTPUTTYPE_UINT):
                vertexShaderTmpl << "\tcoord += vec2(float(a_" << arrayNdx << "), float(a_" << arrayNdx << "));\n";
                break;

            case (DrawTestSpec::OUTPUTTYPE_VEC2):
            case (DrawTestSpec::OUTPUTTYPE_IVEC2):
            case (DrawTestSpec::OUTPUTTYPE_UVEC2):
                vertexShaderTmpl << "\tcoord += vec2(a_" << arrayNdx << ".xy);\n";
                break;

            case (DrawTestSpec::OUTPUTTYPE_VEC3):
            case (DrawTestSpec::OUTPUTTYPE_IVEC3):
            case (DrawTestSpec::OUTPUTTYPE_UVEC3):
                vertexShaderTmpl << "\tcoord += vec2(a_" << arrayNdx
                                 << ".xy);\n"
                                    "\tcoord.x += float(a_"
                                 << arrayNdx << ".z);\n";
                break;

            case (DrawTestSpec::OUTPUTTYPE_VEC4):
            case (DrawTestSpec::OUTPUTTYPE_IVEC4):
            case (DrawTestSpec::OUTPUTTYPE_UVEC4):
                vertexShaderTmpl << "\tcoord += vec2(a_" << arrayNdx
                                 << ".xy);\n"
                                    "\tcoord += vec2(a_"
                                 << arrayNdx << ".zw);\n";
                break;

            default:
                DE_ASSERT(false);
                break;
            }
        }
        else
        {
            switch (arrays[arrayNdx]->getOutputType())
            {
            case (DrawTestSpec::OUTPUTTYPE_FLOAT):
            case (DrawTestSpec::OUTPUTTYPE_INT):
            case (DrawTestSpec::OUTPUTTYPE_UINT):
                vertexShaderTmpl << "\tcolor = color * float(a_" << arrayNdx << ");\n";
                break;

            case (DrawTestSpec::OUTPUTTYPE_VEC2):
            case (DrawTestSpec::OUTPUTTYPE_IVEC2):
            case (DrawTestSpec::OUTPUTTYPE_UVEC2):
                vertexShaderTmpl << "\tcolor.rg = color.rg * vec2(a_" << arrayNdx << ".xy);\n";
                break;

            case (DrawTestSpec::OUTPUTTYPE_VEC3):
            case (DrawTestSpec::OUTPUTTYPE_IVEC3):
            case (DrawTestSpec::OUTPUTTYPE_UVEC3):
                vertexShaderTmpl << "\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz);\n";
                break;

            case (DrawTestSpec::OUTPUTTYPE_VEC4):
            case (DrawTestSpec::OUTPUTTYPE_IVEC4):
            case (DrawTestSpec::OUTPUTTYPE_UVEC4):
                vertexShaderTmpl << "\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz) * float(a_" << arrayNdx
                                 << ".w);\n";
                break;

            default:
                DE_ASSERT(false);
                break;
            }
        }
    }

    vertexShaderTmpl << "\tv_color = vec4(u_colorScale * color, 1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);\n"
                        "\tgl_Position = vec4(u_coordScale * coord, 1.0, 1.0);\n"
                        "}\n";

    return tcu::StringTemplate(vertexShaderTmpl.str().c_str()).specialize(params);
}

std::string DrawTestShaderProgram::genFragmentSource(const glu::RenderContext &ctx)
{
    std::map<std::string, std::string> params;

    generateShaderParams(params, ctx.getType());

    static const char *fragmentShaderTmpl = "${FRAG_HDR}"
                                            "${FRAG_IN} ${COL_PRECISION} vec4 v_color;\n"
                                            "void main(void)\n"
                                            "{\n"
                                            "\t${FRAG_COLOR} = v_color;\n"
                                            "}\n";

    return tcu::StringTemplate(fragmentShaderTmpl).specialize(params);
}

void DrawTestShaderProgram::generateShaderParams(std::map<std::string, std::string> &params, glu::ContextType type)
{
    if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_300_ES))
    {
        params["VTX_IN"]        = "in";
        params["VTX_OUT"]       = "out";
        params["FRAG_IN"]       = "in";
        params["FRAG_COLOR"]    = "dEQP_FragColor";
        params["VTX_HDR"]       = "#version 300 es\n";
        params["FRAG_HDR"]      = "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
        params["COL_PRECISION"] = "mediump";
    }
    else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_100_ES))
    {
        params["VTX_IN"]        = "attribute";
        params["VTX_OUT"]       = "varying";
        params["FRAG_IN"]       = "varying";
        params["FRAG_COLOR"]    = "gl_FragColor";
        params["VTX_HDR"]       = "";
        params["FRAG_HDR"]      = "";
        params["COL_PRECISION"] = "mediump";
    }
    else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_430))
    {
        params["VTX_IN"]        = "in";
        params["VTX_OUT"]       = "out";
        params["FRAG_IN"]       = "in";
        params["FRAG_COLOR"]    = "dEQP_FragColor";
        params["VTX_HDR"]       = "#version 430\n";
        params["FRAG_HDR"]      = "#version 430\nlayout(location = 0) out highp vec4 dEQP_FragColor;\n";
        params["COL_PRECISION"] = "highp";
    }
    else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_330))
    {
        params["VTX_IN"]        = "in";
        params["VTX_OUT"]       = "out";
        params["FRAG_IN"]       = "in";
        params["FRAG_COLOR"]    = "dEQP_FragColor";
        params["VTX_HDR"]       = "#version 330\n";
        params["FRAG_HDR"]      = "#version 330\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
        params["COL_PRECISION"] = "mediump";
    }
    else
        DE_ASSERT(false);
}

rr::GenericVecType DrawTestShaderProgram::mapOutputType(const DrawTestSpec::OutputType &type)
{
    switch (type)
    {
    case (DrawTestSpec::OUTPUTTYPE_FLOAT):
    case (DrawTestSpec::OUTPUTTYPE_VEC2):
    case (DrawTestSpec::OUTPUTTYPE_VEC3):
    case (DrawTestSpec::OUTPUTTYPE_VEC4):
        return rr::GENERICVECTYPE_FLOAT;

    case (DrawTestSpec::OUTPUTTYPE_INT):
    case (DrawTestSpec::OUTPUTTYPE_IVEC2):
    case (DrawTestSpec::OUTPUTTYPE_IVEC3):
    case (DrawTestSpec::OUTPUTTYPE_IVEC4):
        return rr::GENERICVECTYPE_INT32;

    case (DrawTestSpec::OUTPUTTYPE_UINT):
    case (DrawTestSpec::OUTPUTTYPE_UVEC2):
    case (DrawTestSpec::OUTPUTTYPE_UVEC3):
    case (DrawTestSpec::OUTPUTTYPE_UVEC4):
        return rr::GENERICVECTYPE_UINT32;

    default:
        DE_ASSERT(false);
        return rr::GENERICVECTYPE_LAST;
    }
}

int DrawTestShaderProgram::getComponentCount(const DrawTestSpec::OutputType &type)
{
    switch (type)
    {
    case (DrawTestSpec::OUTPUTTYPE_FLOAT):
    case (DrawTestSpec::OUTPUTTYPE_INT):
    case (DrawTestSpec::OUTPUTTYPE_UINT):
        return 1;

    case (DrawTestSpec::OUTPUTTYPE_VEC2):
    case (DrawTestSpec::OUTPUTTYPE_IVEC2):
    case (DrawTestSpec::OUTPUTTYPE_UVEC2):
        return 2;

    case (DrawTestSpec::OUTPUTTYPE_VEC3):
    case (DrawTestSpec::OUTPUTTYPE_IVEC3):
    case (DrawTestSpec::OUTPUTTYPE_UVEC3):
        return 3;

    case (DrawTestSpec::OUTPUTTYPE_VEC4):
    case (DrawTestSpec::OUTPUTTYPE_IVEC4):
    case (DrawTestSpec::OUTPUTTYPE_UVEC4):
        return 4;

    default:
        DE_ASSERT(false);
        return 0;
    }
}

sglr::pdec::ShaderProgramDeclaration DrawTestShaderProgram::createProgramDeclaration(
    const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays)
{
    sglr::pdec::ShaderProgramDeclaration decl;

    for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
        decl << sglr::pdec::VertexAttribute(std::string("a_") + de::toString(arrayNdx),
                                            mapOutputType(arrays[arrayNdx]->getOutputType()));

    decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT);
    decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT);

    decl << sglr::pdec::VertexSource(genVertexSource(ctx, arrays));
    decl << sglr::pdec::FragmentSource(genFragmentSource(ctx));

    decl << sglr::pdec::Uniform("u_coordScale", glu::TYPE_FLOAT);
    decl << sglr::pdec::Uniform("u_colorScale", glu::TYPE_FLOAT);

    return decl;
}

class RandomArrayGenerator
{
public:
    static char *generateArray(int seed, int elementCount, int componentCount, int offset, int stride,
                               DrawTestSpec::InputType type);
    static char *generateIndices(int seed, int elementCount, DrawTestSpec::IndexType type, int offset, int min, int max,
                                 int indexBase);
    static rr::GenericVec4 generateAttributeValue(int seed, DrawTestSpec::InputType type);

private:
    template <typename T>
    static char *createIndices(int seed, int elementCount, int offset, int min, int max, int indexBase);

    static char *generateBasicArray(int seed, int elementCount, int componentCount, int offset, int stride,
                                    DrawTestSpec::InputType type);
    template <typename T, typename GLType>
    static char *createBasicArray(int seed, int elementCount, int componentCount, int offset, int stride);
    static char *generatePackedArray(int seed, int elementCount, int componentCount, int offset, int stride);
};

char *RandomArrayGenerator::generateArray(int seed, int elementCount, int componentCount, int offset, int stride,
                                          DrawTestSpec::InputType type)
{
    if (type == DrawTestSpec::INPUTTYPE_INT_2_10_10_10 || type == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
        return generatePackedArray(seed, elementCount, componentCount, offset, stride);
    else
        return generateBasicArray(seed, elementCount, componentCount, offset, stride, type);
}

char *RandomArrayGenerator::generateBasicArray(int seed, int elementCount, int componentCount, int offset, int stride,
                                               DrawTestSpec::InputType type)
{
    switch (type)
    {
    case DrawTestSpec::INPUTTYPE_FLOAT:
        return createBasicArray<float, GLValue::Float>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_DOUBLE:
        return createBasicArray<double, GLValue::Double>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_SHORT:
        return createBasicArray<int16_t, GLValue::Short>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:
        return createBasicArray<uint16_t, GLValue::Ushort>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_BYTE:
        return createBasicArray<int8_t, GLValue::Byte>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:
        return createBasicArray<uint8_t, GLValue::Ubyte>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_FIXED:
        return createBasicArray<int32_t, GLValue::Fixed>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_INT:
        return createBasicArray<int32_t, GLValue::Int>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
        return createBasicArray<uint32_t, GLValue::Uint>(seed, elementCount, componentCount, offset, stride);
    case DrawTestSpec::INPUTTYPE_HALF:
        return createBasicArray<deFloat16, GLValue::Half>(seed, elementCount, componentCount, offset, stride);
    default:
        DE_ASSERT(false);
        break;
    }
    return DE_NULL;
}

#if (DE_COMPILER == DE_COMPILER_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
// GCC 4.8/4.9 incorrectly emits array-bounds warning from createBasicArray()
#define GCC_ARRAY_BOUNDS_FALSE_NEGATIVE 1
#endif

#if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif

template <typename T, typename GLType>
char *RandomArrayGenerator::createBasicArray(int seed, int elementCount, int componentCount, int offset, int stride)
{
    DE_ASSERT(componentCount >= 1 && componentCount <= 4);

    const GLType min = extractGLValue<GLType>(GLValue::getMinValue(GLValueTypeTraits<GLType>::Type));
    const GLType max = extractGLValue<GLType>(GLValue::getMaxValue(GLValueTypeTraits<GLType>::Type));

    const size_t componentSize = sizeof(T);
    const size_t elementSize   = componentSize * componentCount;
    const size_t bufferSize    = offset + (elementCount - 1) * stride + elementSize;

    char *data     = new char[bufferSize];
    char *writePtr = data + offset;

    GLType previousComponents[4];

    deRandom rnd;
    deRandom_init(&rnd, seed);

    for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++)
    {
        GLType components[4];

        for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
        {
            components[componentNdx] = getRandom<GLType>(rnd, min, max);

            // Try to not create vertex near previous
            if (vertexNdx != 0 && abs(components[componentNdx] - previousComponents[componentNdx]) < minValue<GLType>())
            {
                // Too close, try again (but only once)
                components[componentNdx] = getRandom<GLType>(rnd, min, max);
            }
        }

        for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
            previousComponents[componentNdx] = components[componentNdx];

        for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
            alignmentSafeAssignment(writePtr + componentNdx * componentSize, components[componentNdx].getValue());

        writePtr += stride;
    }

    return data;
}

#if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE)
#pragma GCC diagnostic pop
#endif

char *RandomArrayGenerator::generatePackedArray(int seed, int elementCount, int componentCount, int offset, int stride)
{
    DE_ASSERT(componentCount == 4);
    DE_UNREF(componentCount);

    const uint32_t limit10   = (1 << 10);
    const uint32_t limit2    = (1 << 2);
    const size_t elementSize = 4;
    const size_t bufferSize  = offset + (elementCount - 1) * stride + elementSize;

    char *data     = new char[bufferSize];
    char *writePtr = data + offset;

    deRandom rnd;
    deRandom_init(&rnd, seed);

    for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++)
    {
        const uint32_t x           = deRandom_getUint32(&rnd) % limit10;
        const uint32_t y           = deRandom_getUint32(&rnd) % limit10;
        const uint32_t z           = deRandom_getUint32(&rnd) % limit10;
        const uint32_t w           = deRandom_getUint32(&rnd) % limit2;
        const uint32_t packedValue = (w << 30) | (z << 20) | (y << 10) | (x);

        alignmentSafeAssignment(writePtr, packedValue);
        writePtr += stride;
    }

    return data;
}

char *RandomArrayGenerator::generateIndices(int seed, int elementCount, DrawTestSpec::IndexType type, int offset,
                                            int min, int max, int indexBase)
{
    char *data = DE_NULL;

    switch (type)
    {
    case DrawTestSpec::INDEXTYPE_BYTE:
        data = createIndices<uint8_t>(seed, elementCount, offset, min, max, indexBase);
        break;

    case DrawTestSpec::INDEXTYPE_SHORT:
        data = createIndices<uint16_t>(seed, elementCount, offset, min, max, indexBase);
        break;

    case DrawTestSpec::INDEXTYPE_INT:
        data = createIndices<uint32_t>(seed, elementCount, offset, min, max, indexBase);
        break;

    default:
        DE_ASSERT(false);
        break;
    }

    return data;
}

template <typename T>
char *RandomArrayGenerator::createIndices(int seed, int elementCount, int offset, int min, int max, int indexBase)
{
    const size_t elementSize = sizeof(T);
    const size_t bufferSize  = offset + elementCount * elementSize;

    char *data     = new char[bufferSize];
    char *writePtr = data + offset;

    uint32_t oldNdx1 = uint32_t(-1);
    uint32_t oldNdx2 = uint32_t(-1);

    deRandom rnd;
    deRandom_init(&rnd, seed);

    DE_ASSERT(indexBase >= 0); // watch for underflows

    if (min < 0 || (size_t)min > std::numeric_limits<T>::max() || max < 0 ||
        (size_t)max > std::numeric_limits<T>::max() || min > max)
        DE_FATAL("Invalid range");

    for (int elementNdx = 0; elementNdx < elementCount; ++elementNdx)
    {
        uint32_t ndx = getRandom(rnd, GLValue::Uint::create(min), GLValue::Uint::create(max)).getValue();

        // Try not to generate same index as any of previous two. This prevents
        // generation of degenerate triangles and lines. If [min, max] is too
        // small this cannot be guaranteed.

        if (ndx == oldNdx1)
            ++ndx;
        if (ndx > (uint32_t)max)
            ndx = min;
        if (ndx == oldNdx2)
            ++ndx;
        if (ndx > (uint32_t)max)
            ndx = min;
        if (ndx == oldNdx1)
            ++ndx;
        if (ndx > (uint32_t)max)
            ndx = min;

        oldNdx2 = oldNdx1;
        oldNdx1 = ndx;

        ndx += indexBase;

        alignmentSafeAssignment<T>(writePtr + elementSize * elementNdx, T(ndx));
    }

    return data;
}

rr::GenericVec4 RandomArrayGenerator::generateAttributeValue(int seed, DrawTestSpec::InputType type)
{
    de::Random random(seed);

    switch (type)
    {
    case DrawTestSpec::INPUTTYPE_FLOAT:
        return rr::GenericVec4(generateRandomVec4(random));

    case DrawTestSpec::INPUTTYPE_INT:
        return rr::GenericVec4(generateRandomIVec4(random));

    case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
        return rr::GenericVec4(generateRandomUVec4(random));

    default:
        DE_ASSERT(false);
        return rr::GenericVec4(tcu::Vec4(1, 1, 1, 1));
    }
}

} // namespace

// AttributePack

class AttributePack
{
public:
    AttributePack(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, sglr::Context &drawContext,
                  const tcu::UVec2 &screenSize, bool useVao, bool logEnabled);
    ~AttributePack(void);

    AttributeArray *getArray(int i);
    int getArrayCount(void);

    void newArray(DrawTestSpec::Storage storage);
    void clearArrays(void);
    void updateProgram(void);

    void render(DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex,
                int vertexCount, DrawTestSpec::IndexType indexType, const void *indexOffset, int rangeStart,
                int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale, float colorScale,
                AttributeArray *indexArray);

    const tcu::Surface &getSurface(void) const
    {
        return m_screen;
    }

private:
    tcu::TestContext &m_testCtx;
    glu::RenderContext &m_renderCtx;
    sglr::Context &m_ctx;

    std::vector<AttributeArray *> m_arrays;
    sglr::ShaderProgram *m_program;
    tcu::Surface m_screen;
    const bool m_useVao;
    const bool m_logEnabled;
    uint32_t m_programID;
    uint32_t m_vaoID;
};

AttributePack::AttributePack(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, sglr::Context &drawContext,
                             const tcu::UVec2 &screenSize, bool useVao, bool logEnabled)
    : m_testCtx(testCtx)
    , m_renderCtx(renderCtx)
    , m_ctx(drawContext)
    , m_program(DE_NULL)
    , m_screen(screenSize.x(), screenSize.y())
    , m_useVao(useVao)
    , m_logEnabled(logEnabled)
    , m_programID(0)
    , m_vaoID(0)
{
    if (m_useVao)
        m_ctx.genVertexArrays(1, &m_vaoID);
}

AttributePack::~AttributePack(void)
{
    clearArrays();

    if (m_programID)
        m_ctx.deleteProgram(m_programID);

    if (m_program)
        delete m_program;

    if (m_useVao)
        m_ctx.deleteVertexArrays(1, &m_vaoID);
}

AttributeArray *AttributePack::getArray(int i)
{
    return m_arrays.at(i);
}

int AttributePack::getArrayCount(void)
{
    return (int)m_arrays.size();
}

void AttributePack::newArray(DrawTestSpec::Storage storage)
{
    m_arrays.push_back(new AttributeArray(storage, m_ctx));
}

void AttributePack::clearArrays(void)
{
    for (std::vector<AttributeArray *>::iterator itr = m_arrays.begin(); itr != m_arrays.end(); itr++)
        delete *itr;
    m_arrays.clear();
}

void AttributePack::updateProgram(void)
{
    if (m_programID)
        m_ctx.deleteProgram(m_programID);
    if (m_program)
        delete m_program;

    m_program   = new DrawTestShaderProgram(m_renderCtx, m_arrays);
    m_programID = m_ctx.createProgram(m_program);
}

void AttributePack::render(DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex,
                           int vertexCount, DrawTestSpec::IndexType indexType, const void *indexOffset, int rangeStart,
                           int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale,
                           float colorScale, AttributeArray *indexArray)
{
    DE_ASSERT(m_program != DE_NULL);
    DE_ASSERT(m_programID != 0);

    m_ctx.viewport(0, 0, m_screen.getWidth(), m_screen.getHeight());
    m_ctx.clearColor(0.0, 0.0, 0.0, 1.0);
    m_ctx.clear(GL_COLOR_BUFFER_BIT);

    m_ctx.useProgram(m_programID);
    GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glUseProgram()");

    m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_coordScale"), coordScale);
    m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_colorScale"), colorScale);

    if (m_useVao)
        m_ctx.bindVertexArray(m_vaoID);

    if (indexArray)
        indexArray->bindIndexArray(DrawTestSpec::TARGET_ELEMENT_ARRAY);

    for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++)
    {
        std::stringstream attribName;
        attribName << "a_" << arrayNdx;

        uint32_t loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str());

        if (m_arrays[arrayNdx]->isBound())
        {
            m_ctx.enableVertexAttribArray(loc);
            GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glEnableVertexAttribArray()");
        }

        m_arrays[arrayNdx]->bindAttribute(loc);
    }

    if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS)
    {
        m_ctx.drawArrays(primitiveToGL(primitive), firstVertex, vertexCount);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArrays()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED)
    {
        m_ctx.drawArraysInstanced(primitiveToGL(primitive), firstVertex, vertexCount, instanceCount);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysInstanced()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS)
    {
        m_ctx.drawElements(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElements()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
    {
        m_ctx.drawRangeElements(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount, indexTypeToGL(indexType),
                                indexOffset);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElements()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED)
    {
        m_ctx.drawElementsInstanced(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset,
                                    instanceCount);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstanced()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT)
    {
        struct DrawCommand
        {
            GLuint count;
            GLuint primCount;
            GLuint first;
            GLuint reservedMustBeZero;
        };
        uint8_t *buffer = new uint8_t[sizeof(DrawCommand) + indirectOffset];

        {
            DrawCommand command;

            command.count              = vertexCount;
            command.primCount          = instanceCount;
            command.first              = firstVertex;
            command.reservedMustBeZero = 0;

            memcpy(buffer + indirectOffset, &command, sizeof(command));

            if (m_logEnabled)
                m_testCtx.getLog() << tcu::TestLog::Message << "DrawArraysIndirectCommand:\n"
                                   << "\tcount: " << command.count << "\n"
                                   << "\tprimCount: " << command.primCount << "\n"
                                   << "\tfirst: " << command.first << "\n"
                                   << "\treservedMustBeZero: " << command.reservedMustBeZero << "\n"
                                   << tcu::TestLog::EndMessage;
        }

        GLuint indirectBuf = 0;
        m_ctx.genBuffers(1, &indirectBuf);
        m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
        m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW);
        delete[] buffer;

        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer");

        m_ctx.drawArraysIndirect(primitiveToGL(primitive), glu::BufferOffsetAsPointer(indirectOffset));
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");

        m_ctx.deleteBuffers(1, &indirectBuf);
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT)
    {
        struct DrawCommand
        {
            GLuint count;
            GLuint primCount;
            GLuint firstIndex;
            GLint baseVertex;
            GLuint reservedMustBeZero;
        };
        uint8_t *buffer = new uint8_t[sizeof(DrawCommand) + indirectOffset];

        {
            DrawCommand command;

            // index offset must be converted to firstIndex by dividing with the index element size
            DE_ASSERT(((const uint8_t *)indexOffset - (const uint8_t *)DE_NULL) %
                          gls::DrawTestSpec::indexTypeSize(indexType) ==
                      0); // \note This is checked in spec validation

            command.count              = vertexCount;
            command.primCount          = instanceCount;
            command.firstIndex         = (glw::GLuint)(((const uint8_t *)indexOffset - (const uint8_t *)DE_NULL) /
                                               gls::DrawTestSpec::indexTypeSize(indexType));
            command.baseVertex         = baseVertex;
            command.reservedMustBeZero = 0;

            memcpy(buffer + indirectOffset, &command, sizeof(command));

            if (m_logEnabled)
                m_testCtx.getLog() << tcu::TestLog::Message << "DrawElementsIndirectCommand:\n"
                                   << "\tcount: " << command.count << "\n"
                                   << "\tprimCount: " << command.primCount << "\n"
                                   << "\tfirstIndex: " << command.firstIndex << "\n"
                                   << "\tbaseVertex: " << command.baseVertex << "\n"
                                   << "\treservedMustBeZero: " << command.reservedMustBeZero << "\n"
                                   << tcu::TestLog::EndMessage;
        }

        GLuint indirectBuf = 0;
        m_ctx.genBuffers(1, &indirectBuf);
        m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
        m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW);
        delete[] buffer;

        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer");

        m_ctx.drawElementsIndirect(primitiveToGL(primitive), indexTypeToGL(indexType),
                                   glu::BufferOffsetAsPointer(indirectOffset));
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");

        m_ctx.deleteBuffers(1, &indirectBuf);
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
    {
        m_ctx.drawElementsBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset,
                                     baseVertex);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsBaseVertex()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
    {
        m_ctx.drawElementsInstancedBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType),
                                              indexOffset, instanceCount, baseVertex);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstancedBaseVertex()");
    }
    else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
    {
        m_ctx.drawRangeElementsBaseVertex(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount,
                                          indexTypeToGL(indexType), indexOffset, baseVertex);
        GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElementsBaseVertex()");
    }
    else
        DE_ASSERT(false);

    for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++)
    {
        if (m_arrays[arrayNdx]->isBound())
        {
            std::stringstream attribName;
            attribName << "a_" << arrayNdx;

            uint32_t loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str());

            m_ctx.disableVertexAttribArray(loc);
            GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDisableVertexAttribArray()");
        }
    }

    if (m_useVao)
        m_ctx.bindVertexArray(0);

    m_ctx.useProgram(0);
    m_ctx.readPixels(m_screen, 0, 0, m_screen.getWidth(), m_screen.getHeight());
}

// DrawTestSpec

DrawTestSpec::AttributeSpec DrawTestSpec::AttributeSpec::createAttributeArray(InputType inputType,
                                                                              OutputType outputType, Storage storage,
                                                                              Usage usage, int componentCount,
                                                                              int offset, int stride, bool normalize,
                                                                              int instanceDivisor)
{
    DrawTestSpec::AttributeSpec spec;

    spec.inputType       = inputType;
    spec.outputType      = outputType;
    spec.storage         = storage;
    spec.usage           = usage;
    spec.componentCount  = componentCount;
    spec.offset          = offset;
    spec.stride          = stride;
    spec.normalize       = normalize;
    spec.instanceDivisor = instanceDivisor;

    spec.useDefaultAttribute = false;

    return spec;
}

DrawTestSpec::AttributeSpec DrawTestSpec::AttributeSpec::createDefaultAttribute(InputType inputType,
                                                                                OutputType outputType,
                                                                                int componentCount)
{
    DE_ASSERT(inputType == INPUTTYPE_INT || inputType == INPUTTYPE_UNSIGNED_INT || inputType == INPUTTYPE_FLOAT);
    DE_ASSERT(inputType == INPUTTYPE_FLOAT || componentCount == 4);

    DrawTestSpec::AttributeSpec spec;

    spec.inputType       = inputType;
    spec.outputType      = outputType;
    spec.storage         = DrawTestSpec::STORAGE_LAST;
    spec.usage           = DrawTestSpec::USAGE_LAST;
    spec.componentCount  = componentCount;
    spec.offset          = 0;
    spec.stride          = 0;
    spec.normalize       = 0;
    spec.instanceDivisor = 0;

    spec.useDefaultAttribute = true;

    return spec;
}

DrawTestSpec::AttributeSpec::AttributeSpec(void)
{
    inputType                   = DrawTestSpec::INPUTTYPE_LAST;
    outputType                  = DrawTestSpec::OUTPUTTYPE_LAST;
    storage                     = DrawTestSpec::STORAGE_LAST;
    usage                       = DrawTestSpec::USAGE_LAST;
    componentCount              = 0;
    offset                      = 0;
    stride                      = 0;
    normalize                   = false;
    instanceDivisor             = 0;
    useDefaultAttribute         = false;
    additionalPositionAttribute = false;
    bgraComponentOrder          = false;
}

int DrawTestSpec::AttributeSpec::hash(void) const
{
    if (useDefaultAttribute)
    {
        return 1 * int(inputType) + 7 * int(outputType) + 13 * componentCount;
    }
    else
    {
        return 1 * int(inputType) + 2 * int(outputType) + 3 * int(storage) + 5 * int(usage) + 7 * componentCount +
               11 * offset + 13 * stride + 17 * (normalize ? 0 : 1) + 19 * instanceDivisor;
    }
}

bool DrawTestSpec::AttributeSpec::valid(glu::ApiType ctxType) const
{
    const bool inputTypeFloat = inputType == DrawTestSpec::INPUTTYPE_FLOAT ||
                                inputType == DrawTestSpec::INPUTTYPE_FIXED || inputType == DrawTestSpec::INPUTTYPE_HALF;
    const bool inputTypeUnsignedInteger = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE ||
                                          inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT ||
                                          inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT ||
                                          inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10;
    const bool inputTypeSignedInteger =
        inputType == DrawTestSpec::INPUTTYPE_BYTE || inputType == DrawTestSpec::INPUTTYPE_SHORT ||
        inputType == DrawTestSpec::INPUTTYPE_INT || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;
    const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 ||
                                 inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;

    const bool outputTypeFloat =
        outputType == DrawTestSpec::OUTPUTTYPE_FLOAT || outputType == DrawTestSpec::OUTPUTTYPE_VEC2 ||
        outputType == DrawTestSpec::OUTPUTTYPE_VEC3 || outputType == DrawTestSpec::OUTPUTTYPE_VEC4;
    const bool outputTypeSignedInteger =
        outputType == DrawTestSpec::OUTPUTTYPE_INT || outputType == DrawTestSpec::OUTPUTTYPE_IVEC2 ||
        outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_IVEC4;
    const bool outputTypeUnsignedInteger =
        outputType == DrawTestSpec::OUTPUTTYPE_UINT || outputType == DrawTestSpec::OUTPUTTYPE_UVEC2 ||
        outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_UVEC4;

    if (useDefaultAttribute)
    {
        if (inputType != DrawTestSpec::INPUTTYPE_INT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT &&
            inputType != DrawTestSpec::INPUTTYPE_FLOAT)
            return false;

        if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && componentCount != 4)
            return false;

        // no casting allowed (undefined results)
        if (inputType == DrawTestSpec::INPUTTYPE_INT && !outputTypeSignedInteger)
            return false;
        if (inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT && !outputTypeUnsignedInteger)
            return false;
    }

    if (inputTypePacked && componentCount != 4)
        return false;

    // Invalid conversions:

    // float -> [u]int
    if (inputTypeFloat && !outputTypeFloat)
        return false;

    // uint -> int        (undefined results)
    if (inputTypeUnsignedInteger && outputTypeSignedInteger)
        return false;

    // int -> uint        (undefined results)
    if (inputTypeSignedInteger && outputTypeUnsignedInteger)
        return false;

    // packed -> non-float (packed formats are converted to floats)
    if (inputTypePacked && !outputTypeFloat)
        return false;

    // Invalid normalize. Normalize is only valid if output type is float
    if (normalize && !outputTypeFloat)
        return false;

    // Allow reverse order (GL_BGRA) only for packed and 4-component ubyte
    if (bgraComponentOrder && componentCount != 4)
        return false;
    if (bgraComponentOrder && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 &&
        inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10 && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE)
        return false;
    if (bgraComponentOrder && normalize != true)
        return false;

    // GLES2 limits
    if (ctxType == glu::ApiType::es(2, 0))
    {
        if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && inputType != DrawTestSpec::INPUTTYPE_FIXED &&
            inputType != DrawTestSpec::INPUTTYPE_BYTE && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE &&
            inputType != DrawTestSpec::INPUTTYPE_SHORT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT)
            return false;

        if (!outputTypeFloat)
            return false;

        if (bgraComponentOrder)
            return false;
    }

    // GLES3 limits
    if (ctxType.getProfile() == glu::PROFILE_ES && ctxType.getMajorVersion() == 3)
    {
        if (bgraComponentOrder)
            return false;
    }

    // No user pointers in GL core
    if (ctxType.getProfile() == glu::PROFILE_CORE)
    {
        if (!useDefaultAttribute && storage == DrawTestSpec::STORAGE_USER)
            return false;
    }

    return true;
}

bool DrawTestSpec::AttributeSpec::isBufferAligned(void) const
{
    const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 ||
                                 inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;

    // Buffer alignment, offset is a multiple of underlying data type size?
    if (storage == STORAGE_BUFFER)
    {
        int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType);
        if (inputTypePacked)
            dataTypeSize = 4;

        if (offset % dataTypeSize != 0)
            return false;
    }

    return true;
}

bool DrawTestSpec::AttributeSpec::isBufferStrideAligned(void) const
{
    const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 ||
                                 inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;

    // Buffer alignment, offset is a multiple of underlying data type size?
    if (storage == STORAGE_BUFFER)
    {
        int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType);
        if (inputTypePacked)
            dataTypeSize = 4;

        if (stride % dataTypeSize != 0)
            return false;
    }

    return true;
}

std::string DrawTestSpec::targetToString(Target target)
{
    static const char *targets[] = {
        "element_array", // TARGET_ELEMENT_ARRAY = 0,
        "array"          // TARGET_ARRAY,
    };

    return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target);
}

std::string DrawTestSpec::inputTypeToString(InputType type)
{
    static const char *types[] = {
        "float",  // INPUTTYPE_FLOAT = 0,
        "fixed",  // INPUTTYPE_FIXED,
        "double", // INPUTTYPE_DOUBLE

        "byte",  // INPUTTYPE_BYTE,
        "short", // INPUTTYPE_SHORT,

        "unsigned_byte",  // INPUTTYPE_UNSIGNED_BYTE,
        "unsigned_short", // INPUTTYPE_UNSIGNED_SHORT,

        "int",                    // INPUTTYPE_INT,
        "unsigned_int",           // INPUTTYPE_UNSIGNED_INT,
        "half",                   // INPUTTYPE_HALF,
        "unsigned_int2_10_10_10", // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
        "int2_10_10_10"           // INPUTTYPE_INT_2_10_10_10,
    };

    return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type);
}

std::string DrawTestSpec::outputTypeToString(OutputType type)
{
    static const char *types[] = {
        "float", // OUTPUTTYPE_FLOAT = 0,
        "vec2",  // OUTPUTTYPE_VEC2,
        "vec3",  // OUTPUTTYPE_VEC3,
        "vec4",  // OUTPUTTYPE_VEC4,

        "int",  // OUTPUTTYPE_INT,
        "uint", // OUTPUTTYPE_UINT,

        "ivec2", // OUTPUTTYPE_IVEC2,
        "ivec3", // OUTPUTTYPE_IVEC3,
        "ivec4", // OUTPUTTYPE_IVEC4,

        "uvec2", // OUTPUTTYPE_UVEC2,
        "uvec3", // OUTPUTTYPE_UVEC3,
        "uvec4", // OUTPUTTYPE_UVEC4,
    };

    return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type);
}

std::string DrawTestSpec::usageTypeToString(Usage usage)
{
    static const char *usages[] = {
        "dynamic_draw", // USAGE_DYNAMIC_DRAW = 0,
        "static_draw",  // USAGE_STATIC_DRAW,
        "stream_draw",  // USAGE_STREAM_DRAW,

        "stream_read", // USAGE_STREAM_READ,
        "stream_copy", // USAGE_STREAM_COPY,

        "static_read", // USAGE_STATIC_READ,
        "static_copy", // USAGE_STATIC_COPY,

        "dynamic_read", // USAGE_DYNAMIC_READ,
        "dynamic_copy", // USAGE_DYNAMIC_COPY,
    };

    return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage);
}

std::string DrawTestSpec::storageToString(Storage storage)
{
    static const char *storages[] = {
        "user_ptr", // STORAGE_USER = 0,
        "buffer"    // STORAGE_BUFFER,
    };

    return de::getSizedArrayElement<DrawTestSpec::STORAGE_LAST>(storages, (int)storage);
}

std::string DrawTestSpec::primitiveToString(Primitive primitive)
{
    static const char *primitives[] = {
        "points",                   // PRIMITIVE_POINTS ,
        "triangles",                // PRIMITIVE_TRIANGLES,
        "triangle_fan",             // PRIMITIVE_TRIANGLE_FAN,
        "triangle_strip",           // PRIMITIVE_TRIANGLE_STRIP,
        "lines",                    // PRIMITIVE_LINES
        "line_strip",               // PRIMITIVE_LINE_STRIP
        "line_loop",                // PRIMITIVE_LINE_LOOP
        "lines_adjacency",          // PRIMITIVE_LINES_ADJACENCY
        "line_strip_adjacency",     // PRIMITIVE_LINE_STRIP_ADJACENCY
        "triangles_adjacency",      // PRIMITIVE_TRIANGLES_ADJACENCY
        "triangle_strip_adjacency", // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY
    };

    return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive);
}

std::string DrawTestSpec::indexTypeToString(IndexType type)
{
    static const char *indexTypes[] = {
        "byte",  // INDEXTYPE_BYTE = 0,
        "short", // INDEXTYPE_SHORT,
        "int",   // INDEXTYPE_INT,
    };

    return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)type);
}

std::string DrawTestSpec::drawMethodToString(DrawTestSpec::DrawMethod method)
{
    static const char *methods[] = {
        "draw_arrays",                         //!< DRAWMETHOD_DRAWARRAYS
        "draw_arrays_instanced",               //!< DRAWMETHOD_DRAWARRAYS_INSTANCED
        "draw_arrays_indirect",                //!< DRAWMETHOD_DRAWARRAYS_INDIRECT
        "draw_elements",                       //!< DRAWMETHOD_DRAWELEMENTS
        "draw_range_elements",                 //!< DRAWMETHOD_DRAWELEMENTS_RANGED
        "draw_elements_instanced",             //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED
        "draw_elements_indirect",              //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT
        "draw_elements_base_vertex",           //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
        "draw_elements_instanced_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
        "draw_range_elements_base_vertex",     //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
    };

    return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(methods, (int)method);
}

int DrawTestSpec::inputTypeSize(InputType type)
{
    static const int size[] = {
        (int)sizeof(float),   // INPUTTYPE_FLOAT = 0,
        (int)sizeof(int32_t), // INPUTTYPE_FIXED,
        (int)sizeof(double),  // INPUTTYPE_DOUBLE

        (int)sizeof(int8_t),  // INPUTTYPE_BYTE,
        (int)sizeof(int16_t), // INPUTTYPE_SHORT,

        (int)sizeof(uint8_t),  // INPUTTYPE_UNSIGNED_BYTE,
        (int)sizeof(uint16_t), // INPUTTYPE_UNSIGNED_SHORT,

        (int)sizeof(int32_t),      // INPUTTYPE_INT,
        (int)sizeof(uint32_t),     // INPUTTYPE_UNSIGNED_INT,
        (int)sizeof(deFloat16),    // INPUTTYPE_HALF,
        (int)sizeof(uint32_t) / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
        (int)sizeof(uint32_t) / 4  // INPUTTYPE_INT_2_10_10_10,
    };

    return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(size, (int)type);
}

int DrawTestSpec::indexTypeSize(IndexType type)
{
    static const int size[] = {
        sizeof(uint8_t),  // INDEXTYPE_BYTE,
        sizeof(uint16_t), // INDEXTYPE_SHORT,
        sizeof(uint32_t), // INDEXTYPE_INT,
    };

    return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(size, (int)type);
}

std::string DrawTestSpec::getName(void) const
{
    const MethodInfo methodInfo = getMethodInfo(drawMethod);
    const bool hasFirst         = methodInfo.first;
    const bool instanced        = methodInfo.instanced;
    const bool ranged           = methodInfo.ranged;
    const bool indexed          = methodInfo.indexed;

    std::stringstream name;

    for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
    {
        const AttributeSpec &attrib = attribs[ndx];

        if (attribs.size() > 1)
            name << "attrib" << ndx << "_";

        if (ndx == 0 || attrib.additionalPositionAttribute)
            name << "pos_";
        else
            name << "col_";

        if (attrib.useDefaultAttribute)
        {
            name << "non_array_" << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "_"
                 << attrib.componentCount << "_" << DrawTestSpec::outputTypeToString(attrib.outputType) << "_";
        }
        else
        {
            name << DrawTestSpec::storageToString(attrib.storage) << "_" << attrib.offset << "_" << attrib.stride << "_"
                 << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType);
            if (attrib.inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 &&
                attrib.inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
                name << attrib.componentCount;
            name << "_" << (attrib.normalize ? "normalized_" : "")
                 << DrawTestSpec::outputTypeToString(attrib.outputType) << "_"
                 << DrawTestSpec::usageTypeToString(attrib.usage) << "_" << attrib.instanceDivisor << "_";
        }
    }

    if (indexed)
        name << "index_" << DrawTestSpec::indexTypeToString(indexType) << "_"
             << DrawTestSpec::storageToString(indexStorage) << "_"
             << "offset" << indexPointerOffset << "_";
    if (hasFirst)
        name << "first" << first << "_";
    if (ranged)
        name << "ranged_" << indexMin << "_" << indexMax << "_";
    if (instanced)
        name << "instances" << instanceCount << "_";

    switch (primitive)
    {
    case DrawTestSpec::PRIMITIVE_POINTS:
        name << "points_";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLES:
        name << "triangles_";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
        name << "triangle_fan_";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
        name << "triangle_strip_";
        break;
    case DrawTestSpec::PRIMITIVE_LINES:
        name << "lines_";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP:
        name << "line_strip_";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_LOOP:
        name << "line_loop_";
        break;
    case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
        name << "line_adjancency";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
        name << "line_strip_adjancency";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
        name << "triangles_adjancency";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
        name << "triangle_strip_adjancency";
        break;
    default:
        DE_ASSERT(false);
        break;
    }

    name << primitiveCount;

    return name.str();
}

std::string DrawTestSpec::getDesc(void) const
{
    std::stringstream desc;

    for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
    {
        const AttributeSpec &attrib = attribs[ndx];

        if (attrib.useDefaultAttribute)
        {
            desc << "Attribute " << ndx << ": default, "
                 << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position ,") : ("color ,"))
                 << "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
                 << ", "
                 << "input component count " << attrib.componentCount << ", "
                 << "used as " << DrawTestSpec::outputTypeToString(attrib.outputType) << ", ";
        }
        else
        {
            desc << "Attribute " << ndx << ": "
                 << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position ,") : ("color ,")) << "Storage in "
                 << DrawTestSpec::storageToString(attrib.storage) << ", "
                 << "stride " << attrib.stride << ", "
                 << "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
                 << ", "
                 << "input component count " << attrib.componentCount << ", "
                 << (attrib.normalize ? "normalized, " : "") << "used as "
                 << DrawTestSpec::outputTypeToString(attrib.outputType) << ", "
                 << "instance divisor " << attrib.instanceDivisor << ", ";
        }
    }

    if (drawMethod == DRAWMETHOD_DRAWARRAYS)
    {
        desc << "drawArrays(), "
             << "first " << first << ", ";
    }
    else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED)
    {
        desc << "drawArraysInstanced(), "
             << "first " << first << ", "
             << "instance count " << instanceCount << ", ";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS)
    {
        desc << "drawElements(), "
             << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
             << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
             << "index offset " << indexPointerOffset << ", ";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED)
    {
        desc << "drawElementsRanged(), "
             << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
             << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
             << "index offset " << indexPointerOffset << ", "
             << "range start " << indexMin << ", "
             << "range end " << indexMax << ", ";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED)
    {
        desc << "drawElementsInstanced(), "
             << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
             << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
             << "index offset " << indexPointerOffset << ", "
             << "instance count " << instanceCount << ", ";
    }
    else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT)
    {
        desc << "drawArraysIndirect(), "
             << "first " << first << ", "
             << "instance count " << instanceCount << ", "
             << "indirect offset " << indirectOffset << ", ";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
    {
        desc << "drawElementsIndirect(), "
             << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
             << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
             << "index offset " << indexPointerOffset << ", "
             << "instance count " << instanceCount << ", "
             << "indirect offset " << indirectOffset << ", "
             << "base vertex " << baseVertex << ", ";
    }
    else
        DE_ASSERT(false);

    desc << primitiveCount;

    switch (primitive)
    {
    case DrawTestSpec::PRIMITIVE_POINTS:
        desc << "points";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLES:
        desc << "triangles";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
        desc << "triangles (fan)";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
        desc << "triangles (strip)";
        break;
    case DrawTestSpec::PRIMITIVE_LINES:
        desc << "lines";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP:
        desc << "lines (strip)";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_LOOP:
        desc << "lines (loop)";
        break;
    case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
        desc << "lines (adjancency)";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
        desc << "lines (strip, adjancency)";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
        desc << "triangles (adjancency)";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
        desc << "triangles (strip, adjancency)";
        break;
    default:
        DE_ASSERT(false);
        break;
    }

    return desc.str();
}

std::string DrawTestSpec::getMultilineDesc(void) const
{
    std::stringstream desc;

    for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
    {
        const AttributeSpec &attrib = attribs[ndx];

        if (attrib.useDefaultAttribute)
        {
            desc << "Attribute " << ndx << ": default, "
                 << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position\n") : ("color\n"))
                 << "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
                 << "\n"
                 << "\tinput component count " << attrib.componentCount << "\n"
                 << "\tused as " << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n";
        }
        else
        {
            desc << "Attribute " << ndx << ": "
                 << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position\n") : ("color\n")) << "\tStorage in "
                 << DrawTestSpec::storageToString(attrib.storage) << "\n"
                 << "\tstride " << attrib.stride << "\n"
                 << "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
                 << "\n"
                 << "\tinput component count " << attrib.componentCount << "\n"
                 << (attrib.normalize ? "\tnormalized\n" : "") << "\tused as "
                 << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n"
                 << "\tinstance divisor " << attrib.instanceDivisor << "\n";
        }
    }

    if (drawMethod == DRAWMETHOD_DRAWARRAYS)
    {
        desc << "drawArrays()\n"
             << "\tfirst " << first << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED)
    {
        desc << "drawArraysInstanced()\n"
             << "\tfirst " << first << "\n"
             << "\tinstance count " << instanceCount << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS)
    {
        desc << "drawElements()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED)
    {
        desc << "drawElementsRanged()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n"
             << "\trange start " << indexMin << "\n"
             << "\trange end " << indexMax << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED)
    {
        desc << "drawElementsInstanced()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n"
             << "\tinstance count " << instanceCount << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT)
    {
        desc << "drawArraysIndirect()\n"
             << "\tfirst " << first << "\n"
             << "\tinstance count " << instanceCount << "\n"
             << "\tindirect offset " << indirectOffset << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
    {
        desc << "drawElementsIndirect()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n"
             << "\tinstance count " << instanceCount << "\n"
             << "\tindirect offset " << indirectOffset << "\n"
             << "\tbase vertex " << baseVertex << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
    {
        desc << "drawElementsBaseVertex()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n"
             << "\tbase vertex " << baseVertex << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
    {
        desc << "drawElementsInstancedBaseVertex()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n"
             << "\tinstance count " << instanceCount << "\n"
             << "\tbase vertex " << baseVertex << "\n";
    }
    else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
    {
        desc << "drawRangeElementsBaseVertex()\n"
             << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
             << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
             << "\tindex offset " << indexPointerOffset << "\n"
             << "\tbase vertex " << baseVertex << "\n"
             << "\trange start " << indexMin << "\n"
             << "\trange end " << indexMax << "\n";
    }
    else
        DE_ASSERT(false);

    desc << "\t" << primitiveCount << " ";

    switch (primitive)
    {
    case DrawTestSpec::PRIMITIVE_POINTS:
        desc << "points";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLES:
        desc << "triangles";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
        desc << "triangles (fan)";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
        desc << "triangles (strip)";
        break;
    case DrawTestSpec::PRIMITIVE_LINES:
        desc << "lines";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP:
        desc << "lines (strip)";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_LOOP:
        desc << "lines (loop)";
        break;
    case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
        desc << "lines (adjancency)";
        break;
    case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
        desc << "lines (strip, adjancency)";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
        desc << "triangles (adjancency)";
        break;
    case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
        desc << "triangles (strip, adjancency)";
        break;
    default:
        DE_ASSERT(false);
        break;
    }

    desc << "\n";

    return desc.str();
}

DrawTestSpec::DrawTestSpec(void)
{
    primitive          = PRIMITIVE_LAST;
    primitiveCount     = 0;
    drawMethod         = DRAWMETHOD_LAST;
    indexType          = INDEXTYPE_LAST;
    indexPointerOffset = 0;
    indexStorage       = STORAGE_LAST;
    first              = 0;
    indexMin           = 0;
    indexMax           = 0;
    instanceCount      = 0;
    indirectOffset     = 0;
    baseVertex         = 0;
}

int DrawTestSpec::hash(void) const
{
    // Use only drawmode-relevant values in "hashing" as the unrelevant values might not be set (causing non-deterministic behavior).
    const MethodInfo methodInfo = getMethodInfo(drawMethod);
    const bool arrayed          = methodInfo.first;
    const bool instanced        = methodInfo.instanced;
    const bool ranged           = methodInfo.ranged;
    const bool indexed          = methodInfo.indexed;
    const bool indirect         = methodInfo.indirect;
    const bool hasBaseVtx       = methodInfo.baseVertex;

    const int indexHash      = (!indexed) ? (0) : (int(indexType) + 10 * indexPointerOffset + 100 * int(indexStorage));
    const int arrayHash      = (!arrayed) ? (0) : (first);
    const int indexRangeHash = (!ranged) ? (0) : (indexMin + 10 * indexMax);
    const int instanceHash   = (!instanced) ? (0) : (instanceCount);
    const int indirectHash   = (!indirect) ? (0) : (indirectOffset);
    const int baseVtxHash    = (!hasBaseVtx) ? (0) : (baseVertex);
    const int basicHash      = int(primitive) + 10 * primitiveCount + 100 * int(drawMethod);

    return indexHash + 3 * arrayHash + 5 * indexRangeHash + 7 * instanceHash + 13 * basicHash +
           17 * (int)attribs.size() + 19 * primitiveCount + 23 * indirectHash + 27 * baseVtxHash;
}

bool DrawTestSpec::valid(void) const
{
    DE_ASSERT(apiType.getProfile() != glu::PROFILE_LAST);
    DE_ASSERT(primitive != PRIMITIVE_LAST);
    DE_ASSERT(drawMethod != DRAWMETHOD_LAST);

    const MethodInfo methodInfo = getMethodInfo(drawMethod);

    for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
        if (!attribs[ndx].valid(apiType))
            return false;

    if (methodInfo.ranged)
    {
        uint32_t maxIndexValue = 0;
        if (indexType == INDEXTYPE_BYTE)
            maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_BYTE).ub.getValue();
        else if (indexType == INDEXTYPE_SHORT)
            maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_SHORT).us.getValue();
        else if (indexType == INDEXTYPE_INT)
            maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_INT).ui.getValue();
        else
            DE_ASSERT(false);

        if (indexMin > indexMax)
            return false;
        if (indexMin < 0 || indexMax < 0)
            return false;
        if ((uint32_t)indexMin > maxIndexValue || (uint32_t)indexMax > maxIndexValue)
            return false;
    }

    if (methodInfo.first && first < 0)
        return false;

    // GLES2 limits
    if (apiType == glu::ApiType::es(2, 0))
    {
        if (drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS &&
            drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS)
            return false;
        if (drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS &&
            (indexType != INDEXTYPE_BYTE && indexType != INDEXTYPE_SHORT))
            return false;
    }

    // Indirect limitations
    if (methodInfo.indirect)
    {
        // Indirect offset alignment
        if (indirectOffset % 4 != 0)
            return false;

        // All attribute arrays must be stored in a buffer
        for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
            if (!attribs[ndx].useDefaultAttribute && attribs[ndx].storage == gls::DrawTestSpec::STORAGE_USER)
                return false;
    }
    if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
    {
        // index offset must be convertable to firstIndex
        if (indexPointerOffset % gls::DrawTestSpec::indexTypeSize(indexType) != 0)
            return false;

        // Indices must be in a buffer
        if (indexStorage != STORAGE_BUFFER)
            return false;
    }

    // Do not allow user pointer in GL core
    if (apiType.getProfile() == glu::PROFILE_CORE)
    {
        if (methodInfo.indexed && indexStorage == DrawTestSpec::STORAGE_USER)
            return false;
    }

    return true;
}

DrawTestSpec::CompatibilityTestType DrawTestSpec::isCompatibilityTest(void) const
{
    const MethodInfo methodInfo = getMethodInfo(drawMethod);

    bool bufferAlignmentBad = false;
    bool strideAlignmentBad = false;

    // Attribute buffer alignment
    for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
        if (!attribs[ndx].isBufferAligned())
            bufferAlignmentBad = true;

    // Attribute stride alignment
    for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
        if (!attribs[ndx].isBufferStrideAligned())
            strideAlignmentBad = true;

    // Index buffer alignment
    if (methodInfo.indexed)
    {
        if (indexStorage == STORAGE_BUFFER)
        {
            int indexSize = 0;
            if (indexType == INDEXTYPE_BYTE)
                indexSize = 1;
            else if (indexType == INDEXTYPE_SHORT)
                indexSize = 2;
            else if (indexType == INDEXTYPE_INT)
                indexSize = 4;
            else
                DE_ASSERT(false);

            if (indexPointerOffset % indexSize != 0)
                bufferAlignmentBad = true;
        }
    }

    // \note combination bad alignment & stride is treated as bad offset
    if (bufferAlignmentBad)
        return COMPATIBILITY_UNALIGNED_OFFSET;
    else if (strideAlignmentBad)
        return COMPATIBILITY_UNALIGNED_STRIDE;
    else
        return COMPATIBILITY_NONE;
}

enum PrimitiveClass
{
    PRIMITIVECLASS_POINT = 0,
    PRIMITIVECLASS_LINE,
    PRIMITIVECLASS_TRIANGLE,

    PRIMITIVECLASS_LAST
};

static PrimitiveClass getDrawPrimitiveClass(gls::DrawTestSpec::Primitive primitiveType)
{
    switch (primitiveType)
    {
    case gls::DrawTestSpec::PRIMITIVE_POINTS:
        return PRIMITIVECLASS_POINT;

    case gls::DrawTestSpec::PRIMITIVE_LINES:
    case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP:
    case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP:
    case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
    case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
        return PRIMITIVECLASS_LINE;

    case gls::DrawTestSpec::PRIMITIVE_TRIANGLES:
    case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
    case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
    case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
    case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
        return PRIMITIVECLASS_TRIANGLE;

    default:
        DE_ASSERT(false);
        return PRIMITIVECLASS_LAST;
    }
}

static bool containsLineCases(const std::vector<DrawTestSpec> &m_specs)
{
    for (int ndx = 0; ndx < (int)m_specs.size(); ++ndx)
    {
        if (getDrawPrimitiveClass(m_specs[ndx].primitive) == PRIMITIVECLASS_LINE)
            return true;
    }
    return false;
}

// DrawTest

DrawTest::DrawTest(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const DrawTestSpec &spec, const char *name,
                   const char *desc)
    : TestCase(testCtx, name, desc)
    , m_renderCtx(renderCtx)
    , m_contextInfo(DE_NULL)
    , m_refBuffers(DE_NULL)
    , m_refContext(DE_NULL)
    , m_glesContext(DE_NULL)
    , m_glArrayPack(DE_NULL)
    , m_rrArrayPack(DE_NULL)
    , m_maxDiffRed(-1)
    , m_maxDiffGreen(-1)
    , m_maxDiffBlue(-1)
    , m_iteration(0)
    , m_result() // \note no per-iteration result logging (only one iteration)
{
    addIteration(spec);
}

DrawTest::DrawTest(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name, const char *desc)
    : TestCase(testCtx, name, desc)
    , m_renderCtx(renderCtx)
    , m_contextInfo(DE_NULL)
    , m_refBuffers(DE_NULL)
    , m_refContext(DE_NULL)
    , m_glesContext(DE_NULL)
    , m_glArrayPack(DE_NULL)
    , m_rrArrayPack(DE_NULL)
    , m_maxDiffRed(-1)
    , m_maxDiffGreen(-1)
    , m_maxDiffBlue(-1)
    , m_iteration(0)
    , m_result(testCtx.getLog(), "Iteration result: ")
{
}

DrawTest::~DrawTest(void)
{
    deinit();
}

void DrawTest::addIteration(const DrawTestSpec &spec, const char *description)
{
    // Validate spec
    const bool validSpec = spec.valid();
    DE_ASSERT(validSpec);

    if (!validSpec)
        return;

    // Check the context type is the same with other iterations
    if (!m_specs.empty())
    {
        const bool validContext = m_specs[0].apiType == spec.apiType;
        DE_ASSERT(validContext);

        if (!validContext)
            return;
    }

    m_specs.push_back(spec);

    if (description)
        m_iteration_descriptions.push_back(std::string(description));
    else
        m_iteration_descriptions.push_back(std::string());
}

void DrawTest::init(void)
{
    DE_ASSERT(!m_specs.empty());
    DE_ASSERT(contextSupports(m_renderCtx.getType(), m_specs[0].apiType));

    const int renderTargetWidth  = de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getWidth());
    const int renderTargetHeight = de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getHeight());

    // lines have significantly different rasterization in MSAA mode
    const bool isLineCase         = containsLineCases(m_specs);
    const bool isMSAACase         = m_renderCtx.getRenderTarget().getNumSamples() > 1;
    const int renderTargetSamples = (isMSAACase && isLineCase) ? (4) : (1);

    sglr::ReferenceContextLimits limits(m_renderCtx);
    bool useVao = false;

    m_glesContext =
        new sglr::GLContext(m_renderCtx, m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS,
                            tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));

    if (m_renderCtx.getType().getAPI() == glu::ApiType::es(2, 0) ||
        m_renderCtx.getType().getAPI() == glu::ApiType::es(3, 0))
        useVao = false;
    else if (contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 1)) ||
             glu::isContextTypeGLCore(m_renderCtx.getType()))
        useVao = true;
    else
        DE_FATAL("Unknown context type");

    m_refBuffers = new sglr::ReferenceContextBuffers(m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0,
                                                     renderTargetWidth, renderTargetHeight, renderTargetSamples);
    m_refContext = new sglr::ReferenceContext(limits, m_refBuffers->getColorbuffer(), m_refBuffers->getDepthbuffer(),
                                              m_refBuffers->getStencilbuffer());

    m_glArrayPack = new AttributePack(m_testCtx, m_renderCtx, *m_glesContext,
                                      tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, true);
    m_rrArrayPack = new AttributePack(m_testCtx, m_renderCtx, *m_refContext,
                                      tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, false);

    m_maxDiffRed =
        deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits)));
    m_maxDiffGreen =
        deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits)));
    m_maxDiffBlue =
        deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits)));
    m_contextInfo = glu::ContextInfo::create(m_renderCtx);
}

void DrawTest::deinit(void)
{
    delete m_glArrayPack;
    delete m_rrArrayPack;
    delete m_refBuffers;
    delete m_refContext;
    delete m_glesContext;
    delete m_contextInfo;

    m_glArrayPack = DE_NULL;
    m_rrArrayPack = DE_NULL;
    m_refBuffers  = DE_NULL;
    m_refContext  = DE_NULL;
    m_glesContext = DE_NULL;
    m_contextInfo = DE_NULL;
}

DrawTest::IterateResult DrawTest::iterate(void)
{
    const int specNdx        = (m_iteration / 2);
    const DrawTestSpec &spec = m_specs[specNdx];

    if (spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX ||
        spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX ||
        spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
    {
        const bool supportsES32orGL45 = contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 2)) ||
                                        contextSupports(m_renderCtx.getType(), glu::ApiType::core(4, 5));
        TCU_CHECK_AND_THROW(NotSupportedError,
                            supportsES32orGL45 ||
                                m_contextInfo->isExtensionSupported("GL_EXT_draw_elements_base_vertex"),
                            "GL_EXT_draw_elements_base_vertex is not supported.");
    }

    const bool drawStep               = (m_iteration % 2) == 0;
    const bool compareStep            = (m_iteration % 2) == 1;
    const IterateResult iterateResult = ((size_t)m_iteration + 1 == m_specs.size() * 2) ? (STOP) : (CONTINUE);
    const bool updateProgram =
        (m_iteration == 0) ||
        (drawStep && !checkSpecsShaderCompatible(m_specs[specNdx],
                                                 m_specs[specNdx - 1])); // try to use the same shader in all iterations
    IterationLogSectionEmitter sectionEmitter(m_testCtx.getLog(), specNdx, m_specs.size(),
                                              m_iteration_descriptions[specNdx], drawStep && m_specs.size() != 1);

    if (drawStep)
    {
        const MethodInfo methodInfo = getMethodInfo(spec.drawMethod);
        const bool indexed          = methodInfo.indexed;
        const bool instanced        = methodInfo.instanced;
        const bool ranged           = methodInfo.ranged;
        const bool hasFirst         = methodInfo.first;
        const bool hasBaseVtx       = methodInfo.baseVertex;

        const size_t primitiveElementCount =
            getElementCount(spec.primitive, spec.primitiveCount); // !< elements to be drawn
        const int indexMin           = (ranged) ? (spec.indexMin) : (0);
        const int firstAddition      = (hasFirst) ? (spec.first) : (0);
        const int baseVertexAddition = (hasBaseVtx && spec.baseVertex > 0) ?
                                           (spec.baseVertex) :
                                           (0); // spec.baseVertex > 0 => Create bigger attribute buffer
        const int indexBase          = (hasBaseVtx && spec.baseVertex < 0) ? (-spec.baseVertex) :
                                                                             (0); // spec.baseVertex < 0 => Create bigger indices
        const size_t elementCount =
            primitiveElementCount + indexMin + firstAddition +
            baseVertexAddition; // !< elements in buffer (buffer should have at least primitiveElementCount ACCESSIBLE (index range, first) elements)
        const int maxElementIndex = (int)primitiveElementCount + indexMin + firstAddition - 1;
        const int indexMax =
            de::max(0, (ranged) ? (de::clamp<int>(spec.indexMax, 0, maxElementIndex)) : (maxElementIndex));
        float coordScale = getCoordScale(spec);
        float colorScale = getColorScale(spec);

        rr::GenericVec4 nullAttribValue;

        // Log info
        m_testCtx.getLog() << TestLog::Message << spec.getMultilineDesc() << TestLog::EndMessage;
        m_testCtx.getLog() << TestLog::Message << TestLog::EndMessage; // extra line for clarity

        // Data

        m_glArrayPack->clearArrays();
        m_rrArrayPack->clearArrays();

        for (int attribNdx = 0; attribNdx < (int)spec.attribs.size(); attribNdx++)
        {
            DrawTestSpec::AttributeSpec attribSpec = spec.attribs[attribNdx];
            const bool isPositionAttr              = (attribNdx == 0) || (attribSpec.additionalPositionAttribute);

            if (attribSpec.useDefaultAttribute)
            {
                const int seed              = 10 * attribSpec.hash() + 100 * spec.hash() + attribNdx;
                rr::GenericVec4 attribValue = RandomArrayGenerator::generateAttributeValue(seed, attribSpec.inputType);

                m_glArrayPack->newArray(DrawTestSpec::STORAGE_USER);
                m_rrArrayPack->newArray(DrawTestSpec::STORAGE_USER);

                m_glArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount,
                                                               attribSpec.inputType, attribSpec.outputType, false, 0, 0,
                                                               attribValue, isPositionAttr, false);
                m_rrArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount,
                                                               attribSpec.inputType, attribSpec.outputType, false, 0, 0,
                                                               attribValue, isPositionAttr, false);
            }
            else
            {
                const int seed = attribSpec.hash() + 100 * spec.hash() + attribNdx;
                const size_t elementSize =
                    attribSpec.componentCount * DrawTestSpec::inputTypeSize(attribSpec.inputType);
                const size_t stride                = (attribSpec.stride == 0) ? (elementSize) : (attribSpec.stride);
                const size_t evaluatedElementCount = (instanced && attribSpec.instanceDivisor > 0) ?
                                                         (spec.instanceCount / attribSpec.instanceDivisor + 1) :
                                                         (elementCount);
                const size_t referencedElementCount =
                    (ranged) ? (de::max<size_t>(evaluatedElementCount, spec.indexMax + 1)) : (evaluatedElementCount);
                const size_t bufferSize = attribSpec.offset + stride * (referencedElementCount - 1) + elementSize;
                const char *data =
                    RandomArrayGenerator::generateArray(seed, (int)referencedElementCount, attribSpec.componentCount,
                                                        attribSpec.offset, (int)stride, attribSpec.inputType);

                try
                {
                    m_glArrayPack->newArray(attribSpec.storage);
                    m_rrArrayPack->newArray(attribSpec.storage);

                    m_glArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data,
                                                             attribSpec.usage);
                    m_rrArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data,
                                                             attribSpec.usage);

                    m_glArrayPack->getArray(attribNdx)->setupArray(
                        true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType,
                        attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue,
                        isPositionAttr, attribSpec.bgraComponentOrder);
                    m_rrArrayPack->getArray(attribNdx)->setupArray(
                        true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType,
                        attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue,
                        isPositionAttr, attribSpec.bgraComponentOrder);

                    delete[] data;
                    data = NULL;
                }
                catch (...)
                {
                    delete[] data;
                    throw;
                }
            }
        }

        // Shader program
        if (updateProgram)
        {
            m_glArrayPack->updateProgram();
            m_rrArrayPack->updateProgram();
        }

        // Draw
        try
        {
            // indices
            if (indexed)
            {
                const int seed                = spec.hash();
                const size_t indexElementSize = DrawTestSpec::indexTypeSize(spec.indexType);
                const size_t indexArraySize   = spec.indexPointerOffset + indexElementSize * elementCount;
                const char *indexArray        = RandomArrayGenerator::generateIndices(
                    seed, (int)elementCount, spec.indexType, spec.indexPointerOffset, indexMin, indexMax, indexBase);
                const char *indexPointerBase =
                    (spec.indexStorage == DrawTestSpec::STORAGE_USER) ? (indexArray) : ((char *)DE_NULL);
                const char *indexPointer = indexPointerBase + spec.indexPointerOffset;

                de::UniquePtr<AttributeArray> glArray(new AttributeArray(spec.indexStorage, *m_glesContext));
                de::UniquePtr<AttributeArray> rrArray(new AttributeArray(spec.indexStorage, *m_refContext));

                try
                {
                    glArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray,
                                  DrawTestSpec::USAGE_STATIC_DRAW);
                    rrArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray,
                                  DrawTestSpec::USAGE_STATIC_DRAW);

                    m_glArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount,
                                          spec.indexType, indexPointer, spec.indexMin, spec.indexMax,
                                          spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale,
                                          colorScale, glArray.get());
                    m_rrArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount,
                                          spec.indexType, indexPointer, spec.indexMin, spec.indexMax,
                                          spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale,
                                          colorScale, rrArray.get());

                    delete[] indexArray;
                    indexArray = NULL;
                }
                catch (...)
                {
                    delete[] indexArray;
                    throw;
                }
            }
            else
            {
                m_glArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount,
                                      DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount,
                                      spec.indirectOffset, 0, coordScale, colorScale, DE_NULL);
                m_testCtx.touchWatchdog();
                m_rrArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount,
                                      DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount,
                                      spec.indirectOffset, 0, coordScale, colorScale, DE_NULL);
            }
        }
        catch (glu::Error &err)
        {
            // GL Errors are ok if the mode is not properly aligned

            const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest();

            m_testCtx.getLog() << TestLog::Message << "Got error: " << err.what() << TestLog::EndMessage;

            if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET)
                m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
            else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
                m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
            else
                throw;
        }
    }
    else if (compareStep)
    {
        if (!compare(spec.primitive))
        {
            const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest();

            if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET)
                m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
            else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
                m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
            else
                m_result.addResult(QP_TEST_RESULT_FAIL, "Image comparison failed.");
        }
    }
    else
    {
        DE_ASSERT(false);
        return STOP;
    }

    m_result.setTestContextResult(m_testCtx);

    m_iteration++;
    return iterateResult;
}

static bool isBlack(const tcu::RGBA &c)
{
    // ignore alpha channel
    return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0;
}

static bool isEdgeTripletComponent(int c1, int c2, int c3, int renderTargetDifference)
{
    const int roundingDifference = 2 * renderTargetDifference; // src and dst pixels rounded to different directions
    const int d1                 = c2 - c1;
    const int d2                 = c3 - c2;
    const int rampDiff           = de::abs(d2 - d1);

    return rampDiff > roundingDifference;
}

static bool isEdgeTriplet(const tcu::RGBA &c1, const tcu::RGBA &c2, const tcu::RGBA &c3,
                          const tcu::IVec3 &renderTargetThreshold)
{
    // black (background color) and non-black is always an edge
    {
        const bool b1 = isBlack(c1);
        const bool b2 = isBlack(c2);
        const bool b3 = isBlack(c3);

        // both pixels with coverage and pixels without coverage
        if ((b1 && b2 && b3) == false && (b1 || b2 || b3) == true)
            return true;
        // all black
        if (b1 && b2 && b3)
            return false;
        // all with coverage
        DE_ASSERT(!b1 && !b2 && !b3);
    }

    // Color is always linearly interpolated => component values change nearly linearly
    // in any constant direction on triangle hull. (df/dx ~= C).

    // Edge detection (this function) is run against the reference image
    // => no dithering to worry about

    return isEdgeTripletComponent(c1.getRed(), c2.getRed(), c3.getRed(), renderTargetThreshold.x()) ||
           isEdgeTripletComponent(c1.getGreen(), c2.getGreen(), c3.getGreen(), renderTargetThreshold.y()) ||
           isEdgeTripletComponent(c1.getBlue(), c2.getBlue(), c3.getBlue(), renderTargetThreshold.z());
}

static bool pixelNearEdge(int x, int y, const tcu::Surface &ref, const tcu::IVec3 &renderTargetThreshold)
{
    // should not be called for edge pixels
    DE_ASSERT(x >= 1 && x <= ref.getWidth() - 2);
    DE_ASSERT(y >= 1 && y <= ref.getHeight() - 2);

    // horizontal

    for (int dy = -1; dy < 2; ++dy)
    {
        const tcu::RGBA c1 = ref.getPixel(x - 1, y + dy);
        const tcu::RGBA c2 = ref.getPixel(x, y + dy);
        const tcu::RGBA c3 = ref.getPixel(x + 1, y + dy);
        if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold))
            return true;
    }

    // vertical

    for (int dx = -1; dx < 2; ++dx)
    {
        const tcu::RGBA c1 = ref.getPixel(x + dx, y - 1);
        const tcu::RGBA c2 = ref.getPixel(x + dx, y);
        const tcu::RGBA c3 = ref.getPixel(x + dx, y + 1);
        if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold))
            return true;
    }

    return false;
}

static uint32_t getVisualizationGrayscaleColor(const tcu::RGBA &c)
{
    // make triangle coverage and error pixels obvious by converting coverage to grayscale
    if (isBlack(c))
        return 0;
    else
        return 50u + (uint32_t)(c.getRed() + c.getBlue() + c.getGreen()) / 8u;
}

static bool pixelNearLineIntersection(int x, int y, const tcu::Surface &target)
{
    // should not be called for edge pixels
    DE_ASSERT(x >= 1 && x <= target.getWidth() - 2);
    DE_ASSERT(y >= 1 && y <= target.getHeight() - 2);

    int coveredPixels = 0;

    for (int dy = -1; dy < 2; dy++)
        for (int dx = -1; dx < 2; dx++)
        {
            const bool targetCoverage = !isBlack(target.getPixel(x + dx, y + dy));
            if (targetCoverage)
            {
                ++coveredPixels;

                // A single thin line cannot have more than 3 covered pixels in a 3x3 area
                if (coveredPixels >= 4)
                    return true;
            }
        }

    return false;
}

static inline bool colorsEqual(const tcu::RGBA &colorA, const tcu::RGBA &colorB, const tcu::IVec3 &compareThreshold)
{
    enum
    {
        TCU_RGBA_RGB_MASK = tcu::RGBA::RED_MASK | tcu::RGBA::GREEN_MASK | tcu::RGBA::BLUE_MASK
    };

    return tcu::compareThresholdMasked(colorA, colorB,
                                       tcu::RGBA(compareThreshold.x(), compareThreshold.y(), compareThreshold.z(), 0),
                                       TCU_RGBA_RGB_MASK);
}

// search 3x3 are for matching color
static bool pixelNeighborhoodContainsColor(const tcu::Surface &target, int x, int y, const tcu::RGBA &color,
                                           const tcu::IVec3 &compareThreshold)
{
    // should not be called for edge pixels
    DE_ASSERT(x >= 1 && x <= target.getWidth() - 2);
    DE_ASSERT(y >= 1 && y <= target.getHeight() - 2);

    for (int dy = -1; dy < 2; dy++)
        for (int dx = -1; dx < 2; dx++)
        {
            const tcu::RGBA targetCmpPixel = target.getPixel(x + dx, y + dy);
            if (colorsEqual(color, targetCmpPixel, compareThreshold))
                return true;
        }

    return false;
}

// search 3x3 are for matching coverage (coverage == (color != background color))
static bool pixelNeighborhoodContainsCoverage(const tcu::Surface &target, int x, int y, bool coverage)
{
    // should not be called for edge pixels
    DE_ASSERT(x >= 1 && x <= target.getWidth() - 2);
    DE_ASSERT(y >= 1 && y <= target.getHeight() - 2);

    for (int dy = -1; dy < 2; dy++)
        for (int dx = -1; dx < 2; dx++)
        {
            const bool targetCmpCoverage = !isBlack(target.getPixel(x + dx, y + dy));
            if (targetCmpCoverage == coverage)
                return true;
        }

    return false;
}

static bool edgeRelaxedImageCompare(tcu::TestLog &log, const char *imageSetName, const char *imageSetDesc,
                                    const tcu::Surface &reference, const tcu::Surface &result,
                                    const tcu::IVec3 &compareThreshold, const tcu::IVec3 &renderTargetThreshold,
                                    int maxAllowedInvalidPixels)
{
    DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());

    const tcu::IVec4 green(0, 255, 0, 255);
    const tcu::IVec4 red(255, 0, 0, 255);
    const int width  = reference.getWidth();
    const int height = reference.getHeight();
    tcu::TextureLevel errorMask(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width,
                                height);
    const tcu::PixelBufferAccess errorAccess = errorMask.getAccess();
    int numFailingPixels                     = 0;

    // clear errormask edges which would otherwise be transparent

    tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green);
    tcu::clear(tcu::getSubregion(errorAccess, 0, height - 1, width, 1), green);
    tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green);
    tcu::clear(tcu::getSubregion(errorAccess, width - 1, 0, 1, height), green);

    // skip edge pixels since coverage on edge cannot be verified

    for (int y = 1; y < height - 1; ++y)
        for (int x = 1; x < width - 1; ++x)
        {
            const tcu::RGBA refPixel    = reference.getPixel(x, y);
            const tcu::RGBA screenPixel = result.getPixel(x, y);
            const bool directMatch      = colorsEqual(refPixel, screenPixel, compareThreshold);
            const bool isOkReferencePixel =
                directMatch ||
                pixelNeighborhoodContainsColor(
                    result, x, y, refPixel,
                    compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)
            const bool isOkScreenPixel =
                directMatch ||
                pixelNeighborhoodContainsColor(
                    reference, x, y, screenPixel,
                    compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)

            if (isOkScreenPixel && isOkReferencePixel)
            {
                // pixel valid, write greenish pixels to make the result image easier to read
                const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
                errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
            }
            else if (!pixelNearEdge(x, y, reference, renderTargetThreshold))
            {
                // non-edge pixel values must be within threshold of the reference values
                errorAccess.setPixel(red, x, y);
                ++numFailingPixels;
            }
            else
            {
                // we are on/near an edge, verify only coverage (coverage == not background colored)
                const bool referenceCoverage     = !isBlack(refPixel);
                const bool screenCoverage        = !isBlack(screenPixel);
                const bool isOkReferenceCoverage = pixelNeighborhoodContainsCoverage(
                    result, x, y, referenceCoverage); // Check reference pixel against screen pixel
                const bool isOkScreenCoverage = pixelNeighborhoodContainsCoverage(
                    reference, x, y, screenCoverage); // Check screen pixels against reference pixel

                if (isOkScreenCoverage && isOkReferenceCoverage)
                {
                    // pixel valid, write greenish pixels to make the result image easier to read
                    const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
                    errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
                }
                else
                {
                    // coverage does not match
                    errorAccess.setPixel(red, x, y);
                    ++numFailingPixels;
                }
            }
        }

    log << TestLog::Message << "Comparing images:\n"
        << "\tallowed deviation in pixel positions = 1\n"
        << "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n"
        << "\tnumber of invalid pixels = " << numFailingPixels << TestLog::EndMessage;

    if (numFailingPixels > maxAllowedInvalidPixels)
    {
        log << TestLog::Message << "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", "
            << compareThreshold.y() << ", " << compareThreshold.z() << ")" << TestLog::EndMessage
            << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
            << TestLog::Image("Reference", "Reference", reference)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;

        return false;
    }
    else
    {
        log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
            << TestLog::EndImageSet;

        return true;
    }
}

static bool intersectionRelaxedLineImageCompare(tcu::TestLog &log, const char *imageSetName, const char *imageSetDesc,
                                                const tcu::Surface &reference, const tcu::Surface &result,
                                                const tcu::IVec3 &compareThreshold, int maxAllowedInvalidPixels)
{
    DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());

    const tcu::IVec4 green(0, 255, 0, 255);
    const tcu::IVec4 red(255, 0, 0, 255);
    const int width  = reference.getWidth();
    const int height = reference.getHeight();
    tcu::TextureLevel errorMask(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width,
                                height);
    const tcu::PixelBufferAccess errorAccess = errorMask.getAccess();
    int numFailingPixels                     = 0;

    // clear errormask edges which would otherwise be transparent

    tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green);
    tcu::clear(tcu::getSubregion(errorAccess, 0, height - 1, width, 1), green);
    tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green);
    tcu::clear(tcu::getSubregion(errorAccess, width - 1, 0, 1, height), green);

    // skip edge pixels since coverage on edge cannot be verified

    for (int y = 1; y < height - 1; ++y)
        for (int x = 1; x < width - 1; ++x)
        {
            const tcu::RGBA refPixel    = reference.getPixel(x, y);
            const tcu::RGBA screenPixel = result.getPixel(x, y);
            const bool directMatch      = colorsEqual(refPixel, screenPixel, compareThreshold);
            const bool isOkScreenPixel =
                directMatch ||
                pixelNeighborhoodContainsColor(
                    reference, x, y, screenPixel,
                    compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)
            const bool isOkReferencePixel =
                directMatch ||
                pixelNeighborhoodContainsColor(
                    result, x, y, refPixel,
                    compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)

            if (isOkScreenPixel && isOkReferencePixel)
            {
                // pixel valid, write greenish pixels to make the result image easier to read
                const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
                errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
            }
            else if (!pixelNearLineIntersection(x, y, reference) && !pixelNearLineIntersection(x, y, result))
            {
                // non-intersection pixel values must be within threshold of the reference values
                errorAccess.setPixel(red, x, y);
                ++numFailingPixels;
            }
            else
            {
                // pixel is near a line intersection
                // we are on/near an edge, verify only coverage (coverage == not background colored)
                const bool referenceCoverage  = !isBlack(refPixel);
                const bool screenCoverage     = !isBlack(screenPixel);
                const bool isOkScreenCoverage = pixelNeighborhoodContainsCoverage(
                    reference, x, y, screenCoverage); // Check screen pixels against reference pixel
                const bool isOkReferenceCoverage = pixelNeighborhoodContainsCoverage(
                    result, x, y, referenceCoverage); // Check reference pixel against screen pixel

                if (isOkScreenCoverage && isOkReferenceCoverage)
                {
                    // pixel valid, write greenish pixels to make the result image easier to read
                    const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
                    errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
                }
                else
                {
                    // coverage does not match
                    errorAccess.setPixel(red, x, y);
                    ++numFailingPixels;
                }
            }
        }

    log << TestLog::Message << "Comparing images:\n"
        << "\tallowed deviation in pixel positions = 1\n"
        << "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n"
        << "\tnumber of invalid pixels = " << numFailingPixels << TestLog::EndMessage;

    if (numFailingPixels > maxAllowedInvalidPixels)
    {
        log << TestLog::Message << "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", "
            << compareThreshold.y() << ", " << compareThreshold.z() << ")" << TestLog::EndMessage
            << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
            << TestLog::Image("Reference", "Reference", reference)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;

        return false;
    }
    else
    {
        log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
            << TestLog::EndImageSet;

        return true;
    }
}

bool DrawTest::compare(gls::DrawTestSpec::Primitive primitiveType)
{
    const tcu::Surface &ref    = m_rrArrayPack->getSurface();
    const tcu::Surface &screen = m_glArrayPack->getSurface();

    if (m_renderCtx.getRenderTarget().getNumSamples() > 1)
    {
        // \todo [mika] Improve compare when using multisampling
        m_testCtx.getLog() << tcu::TestLog::Message
                           << "Warning: Comparision of result from multisample render targets are not as stricts as "
                              "without multisampling. Might produce false positives!"
                           << tcu::TestLog::EndMessage;
        return tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", ref.getAccess(),
                                 screen.getAccess(), 0.3f, tcu::COMPARE_LOG_RESULT);
    }
    else
    {
        const PrimitiveClass primitiveClass            = getDrawPrimitiveClass(primitiveType);
        const int maxAllowedInvalidPixelsWithPoints    = 0; //!< points are unlikely to have overlapping fragments
        const int maxAllowedInvalidPixelsWithLines     = 5; //!< line are allowed to have a few bad pixels
        const int maxAllowedInvalidPixelsWithTriangles = 10;

        switch (primitiveClass)
        {
        case PRIMITIVECLASS_POINT:
        {
            // Point are extremely unlikely to have overlapping regions, don't allow any no extra / missing pixels
            return tcu::intThresholdPositionDeviationErrorThresholdCompare(
                m_testCtx.getLog(), "CompareResult", "Result of rendering", ref.getAccess(), screen.getAccess(),
                tcu::UVec4(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue, 256),
                tcu::IVec3(1, 1, 0),               //!< 3x3 search kernel
                true,                              //!< relax comparison on the image boundary
                maxAllowedInvalidPixelsWithPoints, //!< error threshold
                tcu::COMPARE_LOG_RESULT);
        }

        case PRIMITIVECLASS_LINE:
        {
            // Lines can potentially have a large number of overlapping pixels. Pixel comparison may potentially produce
            // false negatives in such pixels if for example the pixel in question is overdrawn by another line in the
            // reference image but not in the resultin image. Relax comparison near line intersection points (areas) and
            // compare only coverage, not color, in such pixels
            return intersectionRelaxedLineImageCompare(m_testCtx.getLog(), "CompareResult", "Result of rendering", ref,
                                                       screen, tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue),
                                                       maxAllowedInvalidPixelsWithLines);
        }

        case PRIMITIVECLASS_TRIANGLE:
        {
            // Triangles are likely to partially or fully overlap. Pixel difference comparison is fragile in pixels
            // where there could be potential overlapping since the  pixels might be covered by one triangle in the
            // reference image and by the other in the result image. Relax comparsion near primitive edges and
            // compare only coverage, not color, in such pixels.
            const tcu::IVec3 renderTargetThreshold =
                m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold().toIVec().xyz();

            return edgeRelaxedImageCompare(m_testCtx.getLog(), "CompareResult", "Result of rendering", ref, screen,
                                           tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue),
                                           renderTargetThreshold, maxAllowedInvalidPixelsWithTriangles);
        }

        default:
            DE_ASSERT(false);
            return false;
        }
    }
}

float DrawTest::getCoordScale(const DrawTestSpec &spec) const
{
    float maxValue = 1.0f;

    for (int arrayNdx = 0; arrayNdx < (int)spec.attribs.size(); arrayNdx++)
    {
        DrawTestSpec::AttributeSpec attribSpec = spec.attribs[arrayNdx];
        const bool isPositionAttr              = (arrayNdx == 0) || (attribSpec.additionalPositionAttribute);
        float attrMaxValue                     = 0;

        if (!isPositionAttr)
            continue;

        if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
        {
            if (attribSpec.normalize)
                attrMaxValue += 1.0f;
            else
                attrMaxValue += 1024.0f;
        }
        else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
        {
            if (attribSpec.normalize)
                attrMaxValue += 1.0f;
            else
                attrMaxValue += 512.0f;
        }
        else
        {
            const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat();

            attrMaxValue +=
                (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType)) ? (1.0f) : (max * 1.1f);
        }

        if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC3 ||
            attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 ||
            attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 ||
            attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4 ||
            attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 ||
            attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4)
            attrMaxValue *= 2;

        maxValue += attrMaxValue;
    }

    return 1.0f / maxValue;
}

float DrawTest::getColorScale(const DrawTestSpec &spec) const
{
    float colorScale = 1.0f;

    for (int arrayNdx = 1; arrayNdx < (int)spec.attribs.size(); arrayNdx++)
    {
        DrawTestSpec::AttributeSpec attribSpec = spec.attribs[arrayNdx];
        const bool isPositionAttr              = (arrayNdx == 0) || (attribSpec.additionalPositionAttribute);

        if (isPositionAttr)
            continue;

        if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
        {
            if (!attribSpec.normalize)
                colorScale *= 1.0f / 1024.0f;
        }
        else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
        {
            if (!attribSpec.normalize)
                colorScale *= 1.0f / 512.0f;
        }
        else
        {
            const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat();

            colorScale *=
                (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f : float(1.0 / double(max)));
            if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 ||
                attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4 ||
                attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4)
                colorScale *=
                    (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f :
                                                                                           float(1.0 / double(max)));
        }
    }

    return colorScale;
}

} // namespace gls
} // namespace deqp
