/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 Tests for separate shader objects
 *//*--------------------------------------------------------------------*/

#include "es31fSeparateShaderTests.hpp"

#include "deInt32.h"
#include "deString.h"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include "deRandom.hpp"
#include "deSTLUtil.hpp"
#include "tcuCommandLine.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuResultCollector.hpp"
#include "tcuRGBA.hpp"
#include "tcuSurface.hpp"
#include "tcuStringTemplate.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluVarType.hpp"
#include "glsShaderLibrary.hpp"
#include "glwFunctions.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"

#include <cstdarg>
#include <algorithm>
#include <map>
#include <sstream>
#include <string>
#include <set>
#include <vector>

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

using de::MovePtr;
using de::Random;
using de::UniquePtr;
using glu::CallLogWrapper;
using glu::DataType;
using glu::FragmentSource;
using glu::Precision;
using glu::Program;
using glu::ProgramPipeline;
using glu::ProgramSeparable;
using glu::ProgramSources;
using glu::RenderContext;
using glu::ShaderProgram;
using glu::ShaderType;
using glu::Storage;
using glu::VariableDeclaration;
using glu::VarType;
using glu::VertexSource;
using std::map;
using std::ostringstream;
using std::set;
using std::string;
using std::vector;
using tcu::MessageBuilder;
using tcu::RenderTarget;
using tcu::ResultCollector;
using tcu::StringTemplate;
using tcu::Surface;
using tcu::TestLog;

using namespace glw;

#define LOG_CALL(CALL)        \
    do                        \
    {                         \
        enableLogging(true);  \
        CALL;                 \
        enableLogging(false); \
    } while (false)

enum
{
    VIEWPORT_SIZE = 128
};

enum VaryingInterpolation
{
    VARYINGINTERPOLATION_SMOOTH = 0,
    VARYINGINTERPOLATION_FLAT,
    VARYINGINTERPOLATION_CENTROID,
    VARYINGINTERPOLATION_DEFAULT,
    VARYINGINTERPOLATION_RANDOM,

    VARYINGINTERPOLATION_LAST
};

DataType randomType(Random &rnd)
{
    using namespace glu;

    if (rnd.getInt(0, 7) == 0)
    {
        const int numCols = rnd.getInt(2, 4), numRows = rnd.getInt(2, 4);

        return getDataTypeMatrix(numCols, numRows);
    }
    else
    {
        static const DataType s_types[] = {TYPE_FLOAT, TYPE_INT, TYPE_UINT};
        static const float s_weights[]  = {3.0, 1.0, 1.0};
        const int size                  = rnd.getInt(1, 4);
        const DataType scalarType =
            rnd.chooseWeighted<DataType>(DE_ARRAY_BEGIN(s_types), DE_ARRAY_END(s_types), DE_ARRAY_BEGIN(s_weights));
        return getDataTypeVector(scalarType, size);
    }

    DE_FATAL("Impossible");
    return TYPE_INVALID;
}

VaryingInterpolation randomInterpolation(Random &rnd)
{
    static const VaryingInterpolation s_validInterpolations[] = {
        VARYINGINTERPOLATION_SMOOTH,
        VARYINGINTERPOLATION_FLAT,
        VARYINGINTERPOLATION_CENTROID,
        VARYINGINTERPOLATION_DEFAULT,
    };
    return s_validInterpolations[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_validInterpolations) - 1)];
}

glu::Interpolation getGluInterpolation(VaryingInterpolation interpolation)
{
    switch (interpolation)
    {
    case VARYINGINTERPOLATION_SMOOTH:
        return glu::INTERPOLATION_SMOOTH;
    case VARYINGINTERPOLATION_FLAT:
        return glu::INTERPOLATION_FLAT;
    case VARYINGINTERPOLATION_CENTROID:
        return glu::INTERPOLATION_CENTROID;
    case VARYINGINTERPOLATION_DEFAULT:
        return glu::INTERPOLATION_LAST; //!< Last means no qualifier, i.e. default
    default:
        DE_FATAL("Invalid interpolation");
        return glu::INTERPOLATION_LAST;
    }
}

// used only for debug sanity checks
#if defined(DE_DEBUG)
VaryingInterpolation getVaryingInterpolation(glu::Interpolation interpolation)
{
    switch (interpolation)
    {
    case glu::INTERPOLATION_SMOOTH:
        return VARYINGINTERPOLATION_SMOOTH;
    case glu::INTERPOLATION_FLAT:
        return VARYINGINTERPOLATION_FLAT;
    case glu::INTERPOLATION_CENTROID:
        return VARYINGINTERPOLATION_CENTROID;
    case glu::INTERPOLATION_LAST:
        return VARYINGINTERPOLATION_DEFAULT; //!< Last means no qualifier, i.e. default
    default:
        DE_FATAL("Invalid interpolation");
        return VARYINGINTERPOLATION_LAST;
    }
}
#endif

enum BindingKind
{
    BINDING_NAME,
    BINDING_LOCATION,
    BINDING_LAST
};

BindingKind randomBinding(Random &rnd)
{
    return rnd.getBool() ? BINDING_LOCATION : BINDING_NAME;
}

void printInputColor(ostringstream &oss, const VariableDeclaration &input)
{
    using namespace glu;

    const DataType basicType = input.varType.getBasicType();
    string exp               = input.name;

    switch (getDataTypeScalarType(basicType))
    {
    case TYPE_FLOAT:
        break;

    case TYPE_INT:
    case TYPE_UINT:
    {
        DataType floatType = getDataTypeFloatScalars(basicType);
        exp                = string() + "(" + getDataTypeName(floatType) + "(" + exp + ") / 255.0" + ")";
        break;
    }

    default:
        DE_FATAL("Impossible");
    }

    if (isDataTypeScalarOrVector(basicType))
    {
        switch (getDataTypeScalarSize(basicType))
        {
        case 1:
            oss << "hsv(vec3(" << exp << ", 1.0, 1.0))";
            break;
        case 2:
            oss << "hsv(vec3(" << exp << ", 1.0))";
            break;
        case 3:
            oss << "vec4(" << exp << ", 1.0)";
            break;
        case 4:
            oss << exp;
            break;
        default:
            DE_FATAL("Impossible");
        }
    }
    else if (isDataTypeMatrix(basicType))
    {
        int rows    = getDataTypeMatrixNumRows(basicType);
        int columns = getDataTypeMatrixNumColumns(basicType);

        if (rows == columns)
            oss << "hsv(vec3(determinant(" << exp << ")))";
        else
        {
            if (rows != 3 && columns >= 3)
            {
                exp = "transpose(" + exp + ")";
                std::swap(rows, columns);
            }
            exp = exp + "[0]";
            if (rows > 3)
                exp = exp + ".xyz";
            oss << "hsv(" << exp << ")";
        }
    }
    else
        DE_FATAL("Impossible");
}

// Representation for the varyings between vertex and fragment shaders

struct VaryingParams
{
    VaryingParams(void)
        : count(0)
        , type(glu::TYPE_LAST)
        , binding(BINDING_LAST)
        , vtxInterp(VARYINGINTERPOLATION_LAST)
        , frgInterp(VARYINGINTERPOLATION_LAST)
    {
    }

    int count;
    DataType type;
    BindingKind binding;
    VaryingInterpolation vtxInterp;
    VaryingInterpolation frgInterp;
};

struct VaryingInterface
{
    vector<VariableDeclaration> vtxOutputs;
    vector<VariableDeclaration> frgInputs;
};

// Generate corresponding input and output variable declarations that may vary
// in compatible ways.

VaryingInterpolation chooseInterpolation(VaryingInterpolation param, DataType type, Random &rnd)
{
    if (glu::getDataTypeScalarType(type) != glu::TYPE_FLOAT)
        return VARYINGINTERPOLATION_FLAT;

    if (param == VARYINGINTERPOLATION_RANDOM)
        return randomInterpolation(rnd);

    return param;
}

bool isSSOCompatibleInterpolation(VaryingInterpolation vertexInterpolation, VaryingInterpolation fragmentInterpolation)
{
    // interpolations must be fully specified
    DE_ASSERT(vertexInterpolation != VARYINGINTERPOLATION_RANDOM);
    DE_ASSERT(vertexInterpolation < VARYINGINTERPOLATION_LAST);
    DE_ASSERT(fragmentInterpolation != VARYINGINTERPOLATION_RANDOM);
    DE_ASSERT(fragmentInterpolation < VARYINGINTERPOLATION_LAST);

    // interpolation can only be either smooth or flat. Auxiliary storage does not matter.
    const bool isSmoothVtx =
        (vertexInterpolation == VARYINGINTERPOLATION_SMOOTH) ||  //!< trivial
        (vertexInterpolation == VARYINGINTERPOLATION_DEFAULT) || //!< default to smooth
        (vertexInterpolation == VARYINGINTERPOLATION_CENTROID);  //!< default to smooth, ignore storage
    const bool isSmoothFrag =
        (fragmentInterpolation == VARYINGINTERPOLATION_SMOOTH) ||  //!< trivial
        (fragmentInterpolation == VARYINGINTERPOLATION_DEFAULT) || //!< default to smooth
        (fragmentInterpolation == VARYINGINTERPOLATION_CENTROID);  //!< default to smooth, ignore storage
    // Khronos bug #12630: flat / smooth qualifiers must match in SSO
    return isSmoothVtx == isSmoothFrag;
}

VaryingInterface genVaryingInterface(const VaryingParams &params, Random &rnd)
{
    using namespace glu;

    VaryingInterface ret;
    int offset = 0;

    for (int varNdx = 0; varNdx < params.count; ++varNdx)
    {
        const BindingKind binding            = ((params.binding == BINDING_LAST) ? randomBinding(rnd) : params.binding);
        const DataType type                  = ((params.type == TYPE_LAST) ? randomType(rnd) : params.type);
        const VaryingInterpolation vtxInterp = chooseInterpolation(params.vtxInterp, type, rnd);
        const VaryingInterpolation frgInterp = chooseInterpolation(params.frgInterp, type, rnd);
        const VaryingInterpolation vtxCompatInterp =
            (isSSOCompatibleInterpolation(vtxInterp, frgInterp)) ? (vtxInterp) : (frgInterp);
        const int loc        = ((binding == BINDING_LOCATION) ? offset : -1);
        const string ndxStr  = de::toString(varNdx);
        const string vtxName = ((binding == BINDING_NAME) ? "var" + ndxStr : "vtxVar" + ndxStr);
        const string frgName = ((binding == BINDING_NAME) ? "var" + ndxStr : "frgVar" + ndxStr);
        const VarType varType(type, PRECISION_HIGHP);

        offset += getDataTypeNumLocations(type);

        // Over 16 locations aren't necessarily supported, so halt here.
        if (offset > 16)
            break;

        ret.vtxOutputs.push_back(
            VariableDeclaration(varType, vtxName, STORAGE_OUT, getGluInterpolation(vtxCompatInterp), loc));
        ret.frgInputs.push_back(VariableDeclaration(varType, frgName, STORAGE_IN, getGluInterpolation(frgInterp), loc));
    }

    return ret;
}

// Create vertex output variable declarations that are maximally compatible
// with the fragment input variables.

vector<VariableDeclaration> varyingCompatVtxOutputs(const VaryingInterface &varyings)
{
    vector<VariableDeclaration> outputs = varyings.vtxOutputs;

    for (size_t i = 0; i < outputs.size(); ++i)
    {
        outputs[i].interpolation = varyings.frgInputs[i].interpolation;
        outputs[i].name          = varyings.frgInputs[i].name;
    }

    return outputs;
}

// Shader source generation

void printFloat(ostringstream &oss, double d)
{
    oss.setf(oss.fixed | oss.internal);
    oss.precision(4);
    oss.width(7);
    oss << d;
}

void printFloatDeclaration(ostringstream &oss, const string &varName, bool uniform, GLfloat value = 0.0)
{
    using namespace glu;

    const VarType varType(TYPE_FLOAT, PRECISION_HIGHP);

    if (uniform)
        oss << VariableDeclaration(varType, varName, STORAGE_UNIFORM) << ";\n";
    else
        oss << VariableDeclaration(varType, varName, STORAGE_CONST) << " = " << de::floatToString(value, 6) << ";\n";
}

void printRandomInitializer(ostringstream &oss, DataType type, Random &rnd)
{
    using namespace glu;
    const int size = getDataTypeScalarSize(type);

    if (size > 0)
        oss << getDataTypeName(type) << "(";

    for (int i = 0; i < size; ++i)
    {
        oss << (i == 0 ? "" : ", ");
        switch (getDataTypeScalarType(type))
        {
        case TYPE_FLOAT:
            printFloat(oss, rnd.getInt(0, 16) / 16.0);
            break;

        case TYPE_INT:
        case TYPE_UINT:
            oss << rnd.getInt(0, 255);
            break;

        case TYPE_BOOL:
            oss << (rnd.getBool() ? "true" : "false");
            break;

        default:
            DE_FATAL("Impossible");
        }
    }

    if (size > 0)
        oss << ")";
}

string genVtxShaderSrc(uint32_t seed, const vector<VariableDeclaration> &outputs, const string &varName, bool uniform,
                       float value = 0.0)
{
    ostringstream oss;
    Random rnd(seed);
    enum
    {
        NUM_COMPONENTS = 2
    };
    static const int s_quadrants[][NUM_COMPONENTS] = {{1, 1}, {-1, 1}, {1, -1}};

    oss << "#version 310 es\n";

    printFloatDeclaration(oss, varName, uniform, value);

    for (vector<VariableDeclaration>::const_iterator it = outputs.begin(); it != outputs.end(); ++it)
        oss << *it << ";\n";

    oss << "const vec2 triangle[3] = vec2[3](\n";

    for (int vertexNdx = 0; vertexNdx < DE_LENGTH_OF_ARRAY(s_quadrants); ++vertexNdx)
    {
        oss << "\tvec2(";

        for (int componentNdx = 0; componentNdx < NUM_COMPONENTS; ++componentNdx)
        {
            printFloat(oss, s_quadrants[vertexNdx][componentNdx] * rnd.getInt(4, 16) / 16.0);
            oss << (componentNdx < 1 ? ", " : "");
        }

        oss << ")" << (vertexNdx < 2 ? "," : "") << "\n";
    }
    oss << ");\n";

    for (vector<VariableDeclaration>::const_iterator it = outputs.begin(); it != outputs.end(); ++it)
    {
        const DataType type   = it->varType.getBasicType();
        const string typeName = glu::getDataTypeName(type);

        oss << "const " << typeName << " " << it->name << "Inits[3] = " << typeName << "[3](\n";
        for (int i = 0; i < 3; ++i)
        {
            oss << (i == 0 ? "\t" : ",\n\t");
            printRandomInitializer(oss, type, rnd);
        }
        oss << ");\n";
    }

    oss << "void main (void)\n"
        << "{\n"
        << "\tgl_Position = vec4(" << varName << " * triangle[gl_VertexID], 0.0, 1.0);\n";

    for (vector<VariableDeclaration>::const_iterator it = outputs.begin(); it != outputs.end(); ++it)
        oss << "\t" << it->name << " = " << it->name << "Inits[gl_VertexID];\n";

    oss << "}\n";

    return oss.str();
}

string genFrgShaderSrc(uint32_t seed, const vector<VariableDeclaration> &inputs, const string &varName, bool uniform,
                       float value = 0.0)
{
    Random rnd(seed);
    ostringstream oss;

    oss.precision(4);
    oss.width(7);
    oss << "#version 310 es\n";

    oss << "precision highp float;\n";

    oss << "out vec4 fragColor;\n";

    printFloatDeclaration(oss, varName, uniform, value);

    for (vector<VariableDeclaration>::const_iterator it = inputs.begin(); it != inputs.end(); ++it)
        oss << *it << ";\n";

    // glsl % isn't defined for negative numbers
    oss << "int imod (int n, int d)"
        << "\n"
        << "{"
        << "\n"
        << "\t"
        << "return (n < 0 ? d - 1 - (-1 - n) % d : n % d);"
        << "\n"
        << "}"
        << "\n";

    oss << "vec4 hsv (vec3 hsv)"
        << "{"
        << "\n"
        << "\tfloat h = hsv.x * 3.0;\n"
        << "\tfloat r = max(0.0, 1.0 - h) + max(0.0, h - 2.0);\n"
        << "\tfloat g = max(0.0, 1.0 - abs(h - 1.0));\n"
        << "\tfloat b = max(0.0, 1.0 - abs(h - 2.0));\n"
        << "\tvec3 hs = mix(vec3(1.0), vec3(r, g, b), hsv.y);\n"
        << "\treturn vec4(hsv.z * hs, 1.0);\n"
        << "}\n";

    oss << "void main (void)\n"
        << "{\n";

    oss << "\t"
        << "fragColor = vec4(vec3(" << varName << "), 1.0);"
        << "\n";

    if (inputs.size() > 0)
    {
        oss << "\t"
            << "switch (imod(int(0.5 * (";

        printFloat(oss, rnd.getFloat(0.5f, 2.0f));
        oss << " * gl_FragCoord.x - ";

        printFloat(oss, rnd.getFloat(0.5f, 2.0f));
        oss << " * gl_FragCoord.y)), " << inputs.size() << "))"
            << "\n"
            << "\t"
            << "{"
            << "\n";

        for (size_t i = 0; i < inputs.size(); ++i)
        {
            oss << "\t\t"
                << "case " << i << ":"
                << "\n"
                << "\t\t\t"
                << "fragColor *= ";

            printInputColor(oss, inputs[i]);

            oss << ";"
                << "\n"
                << "\t\t\t"
                << "break;"
                << "\n";
        }

        oss << "\t\t"
            << "case " << inputs.size() << ":\n"
            << "\t\t\t"
            << "fragColor = vec4(1.0, 0.0, 1.0, 1.0);"
            << "\n";
        oss << "\t\t\t"
            << "break;"
            << "\n";

        oss << "\t\t"
            << "case -1:\n"
            << "\t\t\t"
            << "fragColor = vec4(1.0, 1.0, 0.0, 1.0);"
            << "\n";
        oss << "\t\t\t"
            << "break;"
            << "\n";

        oss << "\t\t"
            << "default:"
            << "\n"
            << "\t\t\t"
            << "fragColor = vec4(1.0, 1.0, 0.0, 1.0);"
            << "\n";

        oss << "\t"
            << "}\n";
    }

    oss << "}\n";

    return oss.str();
}

// ProgramWrapper

class ProgramWrapper
{
public:
    virtual ~ProgramWrapper(void)
    {
    }

    virtual GLuint getProgramName(void)   = 0;
    virtual void writeToLog(TestLog &log) = 0;
};

class ShaderProgramWrapper : public ProgramWrapper
{
public:
    ShaderProgramWrapper(const RenderContext &renderCtx, const ProgramSources &sources)
        : m_shaderProgram(renderCtx, sources)
    {
    }
    ~ShaderProgramWrapper(void)
    {
    }

    GLuint getProgramName(void)
    {
        return m_shaderProgram.getProgram();
    }
    ShaderProgram &getShaderProgram(void)
    {
        return m_shaderProgram;
    }
    void writeToLog(TestLog &log)
    {
        log << m_shaderProgram;
    }

private:
    ShaderProgram m_shaderProgram;
};

class RawProgramWrapper : public ProgramWrapper
{
public:
    RawProgramWrapper(const RenderContext &renderCtx, GLuint programName, ShaderType shaderType, const string &source)
        : m_program(renderCtx, programName)
        , m_shaderType(shaderType)
        , m_source(source)
    {
    }
    ~RawProgramWrapper(void)
    {
    }

    GLuint getProgramName(void)
    {
        return m_program.getProgram();
    }
    Program &getProgram(void)
    {
        return m_program;
    }
    void writeToLog(TestLog &log);

private:
    Program m_program;
    ShaderType m_shaderType;
    const string m_source;
};

void RawProgramWrapper::writeToLog(TestLog &log)
{
    const string info   = m_program.getInfoLog();
    qpShaderType qpType = glu::getLogShaderType(m_shaderType);

    log << TestLog::ShaderProgram(true, info)
        << TestLog::Shader(qpType, m_source, true, "[Shader created by glCreateShaderProgramv()]")
        << TestLog::EndShaderProgram;
}

// ProgramParams

struct ProgramParams
{
    ProgramParams(uint32_t vtxSeed_, GLfloat vtxScale_, uint32_t frgSeed_, GLfloat frgScale_)
        : vtxSeed(vtxSeed_)
        , vtxScale(vtxScale_)
        , frgSeed(frgSeed_)
        , frgScale(frgScale_)
    {
    }
    uint32_t vtxSeed;
    GLfloat vtxScale;
    uint32_t frgSeed;
    GLfloat frgScale;
};

ProgramParams genProgramParams(Random &rnd)
{
    const uint32_t vtxSeed = rnd.getUint32();
    const GLfloat vtxScale = (float)rnd.getInt(8, 16) / 16.0f;
    const uint32_t frgSeed = rnd.getUint32();
    const GLfloat frgScale = (float)rnd.getInt(0, 16) / 16.0f;

    return ProgramParams(vtxSeed, vtxScale, frgSeed, frgScale);
}

// TestParams

struct TestParams
{
    bool initSingle;
    bool switchVtx;
    bool switchFrg;
    bool useUniform;
    bool useSameName;
    bool useCreateHelper;
    bool useProgramUniform;
    VaryingParams varyings;
};

uint32_t paramsSeed(const TestParams &params)
{
    uint32_t paramCode =
        (params.initSingle << 0 | params.switchVtx << 1 | params.switchFrg << 2 | params.useUniform << 3 |
         params.useSameName << 4 | params.useCreateHelper << 5 | params.useProgramUniform << 6);

    paramCode = deUint32Hash(paramCode) + params.varyings.count;
    paramCode = deUint32Hash(paramCode) + params.varyings.type;
    paramCode = deUint32Hash(paramCode) + params.varyings.binding;
    paramCode = deUint32Hash(paramCode) + params.varyings.vtxInterp;
    paramCode = deUint32Hash(paramCode) + params.varyings.frgInterp;

    return deUint32Hash(paramCode);
}

string paramsCode(const TestParams &params)
{
    using namespace glu;

    ostringstream oss;

    oss << (params.initSingle ? "1" : "2") << (params.switchVtx ? "v" : "") << (params.switchFrg ? "f" : "")
        << (params.useProgramUniform ? "p" : "") << (params.useUniform ? "u" : "") << (params.useSameName ? "s" : "")
        << (params.useCreateHelper ? "c" : "") << de::toString(params.varyings.count)
        << (params.varyings.binding == BINDING_NAME     ? "n" :
            params.varyings.binding == BINDING_LOCATION ? "l" :
            params.varyings.binding == BINDING_LAST     ? "r" :
                                                          "")
        << (params.varyings.vtxInterp == VARYINGINTERPOLATION_SMOOTH   ? "m" :
            params.varyings.vtxInterp == VARYINGINTERPOLATION_CENTROID ? "e" :
            params.varyings.vtxInterp == VARYINGINTERPOLATION_FLAT     ? "a" :
            params.varyings.vtxInterp == VARYINGINTERPOLATION_RANDOM   ? "r" :
                                                                         "o")
        << (params.varyings.frgInterp == VARYINGINTERPOLATION_SMOOTH   ? "m" :
            params.varyings.frgInterp == VARYINGINTERPOLATION_CENTROID ? "e" :
            params.varyings.frgInterp == VARYINGINTERPOLATION_FLAT     ? "a" :
            params.varyings.frgInterp == VARYINGINTERPOLATION_RANDOM   ? "r" :
                                                                         "o");
    return oss.str();
}

bool paramsValid(const TestParams &params)
{
    using namespace glu;

    // Final pipeline has a single program?
    if (params.initSingle)
    {
        // Cannot have conflicting names for uniforms or constants
        if (params.useSameName)
            return false;

        // CreateShaderProgram would never get called
        if (!params.switchVtx && !params.switchFrg && params.useCreateHelper)
            return false;

        // Must switch either all or nothing
        if (params.switchVtx != params.switchFrg)
            return false;
    }

    // ProgramUniform would never get called
    if (params.useProgramUniform && !params.useUniform)
        return false;

    // Interpolation is meaningless if we don't use an in/out variable.
    if (params.varyings.count == 0 && !(params.varyings.vtxInterp == VARYINGINTERPOLATION_LAST &&
                                        params.varyings.frgInterp == VARYINGINTERPOLATION_LAST))
        return false;

    // Mismatch by flat / smooth is not allowed. See Khronos bug #12630
    // \note: iterpolations might be RANDOM, causing generated varyings potentially match / mismatch anyway.
    //        This is checked later on. Here, we just make sure that we don't force the generator to generate
    //        only invalid varying configurations, i.e. there exists a valid varying configuration for this
    //        test param config.
    if ((params.varyings.vtxInterp != VARYINGINTERPOLATION_RANDOM) &&
        (params.varyings.frgInterp != VARYINGINTERPOLATION_RANDOM) &&
        (params.varyings.vtxInterp == VARYINGINTERPOLATION_FLAT) !=
            (params.varyings.frgInterp == VARYINGINTERPOLATION_FLAT))
        return false;

    return true;
}

// used only for debug sanity checks
#if defined(DE_DEBUG)
bool varyingsValid(const VaryingInterface &varyings)
{
    for (int ndx = 0; ndx < (int)varyings.vtxOutputs.size(); ++ndx)
    {
        const VaryingInterpolation vertexInterpolation =
            getVaryingInterpolation(varyings.vtxOutputs[ndx].interpolation);
        const VaryingInterpolation fragmentInterpolation =
            getVaryingInterpolation(varyings.frgInputs[ndx].interpolation);

        if (!isSSOCompatibleInterpolation(vertexInterpolation, fragmentInterpolation))
            return false;
    }

    return true;
}
#endif

void logParams(TestLog &log, const TestParams &params)
{
    // We don't log operational details here since those are shown
    // in the log messages during execution.
    MessageBuilder msg = log.message();

    msg << "Pipeline configuration:\n";

    msg << "Vertex and fragment shaders have " << (params.useUniform ? "uniform" : "constant") << "s with "
        << (params.useSameName ? "the same name" : "different names") << ".\n";

    if (params.varyings.count == 0)
        msg << "There are no varyings.\n";
    else
    {
        if (params.varyings.count == 1)
            msg << "There is one varying.\n";
        else
            msg << "There are " << params.varyings.count << " varyings.\n";

        if (params.varyings.type == glu::TYPE_LAST)
            msg << "Varyings are of random types.\n";
        else
            msg << "Varyings are of type '" << glu::getDataTypeName(params.varyings.type) << "'.\n";

        msg << "Varying outputs and inputs correspond ";
        switch (params.varyings.binding)
        {
        case BINDING_NAME:
            msg << "by name.\n";
            break;
        case BINDING_LOCATION:
            msg << "by location.\n";
            break;
        case BINDING_LAST:
            msg << "randomly either by name or by location.\n";
            break;
        default:
            DE_FATAL("Impossible");
        }

        msg << "In the vertex shader the varyings are qualified ";
        if (params.varyings.vtxInterp == VARYINGINTERPOLATION_DEFAULT)
            msg << "with no interpolation qualifiers.\n";
        else if (params.varyings.vtxInterp == VARYINGINTERPOLATION_RANDOM)
            msg << "with a random interpolation qualifier.\n";
        else
            msg << "'" << glu::getInterpolationName(getGluInterpolation(params.varyings.vtxInterp)) << "'.\n";

        msg << "In the fragment shader the varyings are qualified ";
        if (params.varyings.frgInterp == VARYINGINTERPOLATION_DEFAULT)
            msg << "with no interpolation qualifiers.\n";
        else if (params.varyings.frgInterp == VARYINGINTERPOLATION_RANDOM)
            msg << "with a random interpolation qualifier.\n";
        else
            msg << "'" << glu::getInterpolationName(getGluInterpolation(params.varyings.frgInterp)) << "'.\n";
    }

    msg << TestLog::EndMessage;

    log.writeMessage("");
}

TestParams genParams(uint32_t seed)
{
    Random rnd(seed);
    TestParams params;
    int tryNdx = 0;

    do
    {
        params.initSingle        = rnd.getBool();
        params.switchVtx         = rnd.getBool();
        params.switchFrg         = rnd.getBool();
        params.useUniform        = rnd.getBool();
        params.useProgramUniform = params.useUniform && rnd.getBool();
        params.useCreateHelper   = rnd.getBool();
        params.useSameName       = rnd.getBool();
        {
            int i                 = rnd.getInt(-1, 3);
            params.varyings.count = (i == -1 ? 0 : 1 << i);
        }
        if (params.varyings.count > 0)
        {
            params.varyings.type      = glu::TYPE_LAST;
            params.varyings.binding   = BINDING_LAST;
            params.varyings.vtxInterp = VARYINGINTERPOLATION_RANDOM;
            params.varyings.frgInterp = VARYINGINTERPOLATION_RANDOM;
        }
        else
        {
            params.varyings.type      = glu::TYPE_INVALID;
            params.varyings.binding   = BINDING_LAST;
            params.varyings.vtxInterp = VARYINGINTERPOLATION_LAST;
            params.varyings.frgInterp = VARYINGINTERPOLATION_LAST;
        }

        tryNdx += 1;
    } while (!paramsValid(params) && tryNdx < 16);

    DE_ASSERT(paramsValid(params));

    return params;
}

// Program pipeline wrapper that retains references to component programs.

struct Pipeline
{
    Pipeline(MovePtr<ProgramPipeline> pipeline_, MovePtr<ProgramWrapper> fullProg_, MovePtr<ProgramWrapper> vtxProg_,
             MovePtr<ProgramWrapper> frgProg_)
        : pipeline(pipeline_)
        , fullProg(fullProg_)
        , vtxProg(vtxProg_)
        , frgProg(frgProg_)
    {
    }

    ProgramWrapper &getVertexProgram(void) const
    {
        return vtxProg ? *vtxProg : *fullProg;
    }

    ProgramWrapper &getFragmentProgram(void) const
    {
        return frgProg ? *frgProg : *fullProg;
    }

    UniquePtr<ProgramPipeline> pipeline;
    UniquePtr<ProgramWrapper> fullProg;
    UniquePtr<ProgramWrapper> vtxProg;
    UniquePtr<ProgramWrapper> frgProg;
};

void logPipeline(TestLog &log, const Pipeline &pipeline)
{
    ProgramWrapper &vtxProg = pipeline.getVertexProgram();
    ProgramWrapper &frgProg = pipeline.getFragmentProgram();

    log.writeMessage("// Failed program pipeline:");
    if (&vtxProg == &frgProg)
    {
        log.writeMessage("// Common program for both vertex and fragment stages:");
        vtxProg.writeToLog(log);
    }
    else
    {
        log.writeMessage("// Vertex stage program:");
        vtxProg.writeToLog(log);
        log.writeMessage("// Fragment stage program:");
        frgProg.writeToLog(log);
    }
}

// Rectangle

struct Rectangle
{
    Rectangle(int x_, int y_, int width_, int height_) : x(x_), y(y_), width(width_), height(height_)
    {
    }
    int x;
    int y;
    int width;
    int height;
};

void setViewport(const RenderContext &renderCtx, const Rectangle &rect)
{
    renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
}

void readRectangle(const RenderContext &renderCtx, const Rectangle &rect, Surface &dst)
{
    dst.setSize(rect.width, rect.height);
    glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
}

Rectangle randomViewport(const RenderContext &ctx, Random &rnd, GLint maxWidth, GLint maxHeight)
{
    const RenderTarget &target = ctx.getRenderTarget();
    GLint width                = de::min(target.getWidth(), maxWidth);
    GLint xOff                 = rnd.getInt(0, target.getWidth() - width);
    GLint height               = de::min(target.getHeight(), maxHeight);
    GLint yOff                 = rnd.getInt(0, target.getHeight() - height);

    return Rectangle(xOff, yOff, width, height);
}

// SeparateShaderTest

class SeparateShaderTest : public TestCase, private CallLogWrapper
{
public:
    typedef void (SeparateShaderTest::*TestFunc)(MovePtr<Pipeline> &pipeOut);

    SeparateShaderTest(Context &ctx, const string &name, const string &description, int iterations,
                       const TestParams &params, TestFunc testFunc);

    IterateResult iterate(void);

    void testPipelineRendering(MovePtr<Pipeline> &pipeOut);
    void testCurrentProgPriority(MovePtr<Pipeline> &pipeOut);
    void testActiveProgramUniform(MovePtr<Pipeline> &pipeOut);
    void testPipelineQueryActive(MovePtr<Pipeline> &pipeOut);
    void testPipelineQueryPrograms(MovePtr<Pipeline> &pipeOut);

private:
    TestLog &log(void);
    const RenderContext &getRenderContext(void);

    void setUniform(ProgramWrapper &program, const string &uniformName, GLfloat value, bool useProgramUni);

    void drawSurface(Surface &dst, uint32_t seed = 0);

    MovePtr<ProgramWrapper> createShaderProgram(const string *vtxSource, const string *frgSource, bool separable);

    MovePtr<ProgramWrapper> createSingleShaderProgram(ShaderType shaderType, const string &src);

    MovePtr<Pipeline> createPipeline(const ProgramParams &pp);

    MovePtr<ProgramWrapper> createReferenceProgram(const ProgramParams &pp);

    int m_iterations;
    int m_currentIteration;
    TestParams m_params;
    TestFunc m_testFunc;
    Random m_rnd;
    ResultCollector m_status;
    VaryingInterface m_varyings;

    // Per-iteration state required for logging on exception
    MovePtr<ProgramWrapper> m_fullProg;
    MovePtr<ProgramWrapper> m_vtxProg;
    MovePtr<ProgramWrapper> m_frgProg;
};

const RenderContext &SeparateShaderTest::getRenderContext(void)
{
    return m_context.getRenderContext();
}

TestLog &SeparateShaderTest::log(void)
{
    return m_testCtx.getLog();
}

SeparateShaderTest::SeparateShaderTest(Context &ctx, const string &name, const string &description, int iterations,
                                       const TestParams &params, TestFunc testFunc)
    : TestCase(ctx, name.c_str(), description.c_str())
    , CallLogWrapper(ctx.getRenderContext().getFunctions(), log())
    , m_iterations(iterations)
    , m_currentIteration(0)
    , m_params(params)
    , m_testFunc(testFunc)
    , m_rnd(paramsSeed(params))
    , m_status(log(), "// ")
    , m_varyings(genVaryingInterface(params.varyings, m_rnd))
{
    DE_ASSERT(paramsValid(params));
    DE_ASSERT(varyingsValid(m_varyings));
}

MovePtr<ProgramWrapper> SeparateShaderTest::createShaderProgram(const string *vtxSource, const string *frgSource,
                                                                bool separable)
{
    ProgramSources sources;

    if (vtxSource != DE_NULL)
        sources << VertexSource(*vtxSource);
    if (frgSource != DE_NULL)
        sources << FragmentSource(*frgSource);
    sources << ProgramSeparable(separable);

    MovePtr<ShaderProgramWrapper> wrapper(new ShaderProgramWrapper(getRenderContext(), sources));
    if (!wrapper->getShaderProgram().isOk())
    {
        log().writeMessage("Couldn't create shader program");
        wrapper->writeToLog(log());
        TCU_FAIL("Couldn't create shader program");
    }

    return MovePtr<ProgramWrapper>(wrapper.release());
}

MovePtr<ProgramWrapper> SeparateShaderTest::createSingleShaderProgram(ShaderType shaderType, const string &src)
{
    const RenderContext &renderCtx = getRenderContext();

    if (m_params.useCreateHelper)
    {
        const char *const srcStr = src.c_str();
        const GLenum glType      = glu::getGLShaderType(shaderType);
        const GLuint programName = glCreateShaderProgramv(glType, 1, &srcStr);

        if (glGetError() != GL_NO_ERROR || programName == 0)
        {
            qpShaderType qpType = glu::getLogShaderType(shaderType);

            log() << TestLog::Message << "glCreateShaderProgramv() failed" << TestLog::EndMessage
                  << TestLog::ShaderProgram(false, "[glCreateShaderProgramv() failed]")
                  << TestLog::Shader(qpType, src, false, "[glCreateShaderProgramv() failed]")
                  << TestLog::EndShaderProgram;
            TCU_FAIL("glCreateShaderProgramv() failed");
        }

        RawProgramWrapper *const wrapper = new RawProgramWrapper(renderCtx, programName, shaderType, src);
        MovePtr<ProgramWrapper> wrapperPtr(wrapper);
        Program &program = wrapper->getProgram();

        if (!program.getLinkStatus())
        {
            log().writeMessage("glCreateShaderProgramv() failed at linking");
            wrapper->writeToLog(log());
            TCU_FAIL("glCreateShaderProgram() failed at linking");
        }
        return wrapperPtr;
    }
    else
    {
        switch (shaderType)
        {
        case glu::SHADERTYPE_VERTEX:
            return createShaderProgram(&src, DE_NULL, true);
        case glu::SHADERTYPE_FRAGMENT:
            return createShaderProgram(DE_NULL, &src, true);
        default:
            DE_FATAL("Impossible case");
        }
    }
    return MovePtr<ProgramWrapper>(); // Shut up compiler warnings.
}

void SeparateShaderTest::setUniform(ProgramWrapper &program, const string &uniformName, GLfloat value,
                                    bool useProgramUniform)
{
    const GLuint progName = program.getProgramName();
    const GLint location  = glGetUniformLocation(progName, uniformName.c_str());
    MessageBuilder msg    = log().message();

    msg << "// Set program " << progName << "'s uniform '" << uniformName << "' to " << value;
    if (useProgramUniform)
    {
        msg << " using glProgramUniform1f";
        glProgramUniform1f(progName, location, value);
    }
    else
    {
        msg << " using glUseProgram and glUniform1f";
        glUseProgram(progName);
        glUniform1f(location, value);
        glUseProgram(0);
    }
    msg << TestLog::EndMessage;
}

MovePtr<Pipeline> SeparateShaderTest::createPipeline(const ProgramParams &pp)
{
    const bool useUniform      = m_params.useUniform;
    const string vtxName       = m_params.useSameName ? "scale" : "vtxScale";
    const uint32_t initVtxSeed = m_params.switchVtx ? m_rnd.getUint32() : pp.vtxSeed;

    const string frgName       = m_params.useSameName ? "scale" : "frgScale";
    const uint32_t initFrgSeed = m_params.switchFrg ? m_rnd.getUint32() : pp.frgSeed;
    const string frgSource     = genFrgShaderSrc(initFrgSeed, m_varyings.frgInputs, frgName, useUniform, pp.frgScale);

    const RenderContext &renderCtx = getRenderContext();
    MovePtr<ProgramPipeline> pipeline(new ProgramPipeline(renderCtx));
    MovePtr<ProgramWrapper> fullProg;
    MovePtr<ProgramWrapper> vtxProg;
    MovePtr<ProgramWrapper> frgProg;

    // We cannot allow a situation where we have a single program with a
    // single uniform, because then the vertex and fragment shader uniforms
    // would not be distinct in the final pipeline, and we are going to test
    // that altering one uniform will not affect the other.
    DE_ASSERT(!(m_params.initSingle && m_params.useSameName && !m_params.switchVtx && !m_params.switchFrg));

    if (m_params.initSingle)
    {
        string vtxSource =
            genVtxShaderSrc(initVtxSeed, varyingCompatVtxOutputs(m_varyings), vtxName, useUniform, pp.vtxScale);
        fullProg = createShaderProgram(&vtxSource, &frgSource, true);
        pipeline->useProgramStages(GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, fullProg->getProgramName());
        log() << TestLog::Message << "// Created pipeline " << pipeline->getPipeline() << " with two-shader program "
              << fullProg->getProgramName() << TestLog::EndMessage;
    }
    else
    {
        string vtxSource = genVtxShaderSrc(initVtxSeed, m_varyings.vtxOutputs, vtxName, useUniform, pp.vtxScale);
        vtxProg          = createSingleShaderProgram(glu::SHADERTYPE_VERTEX, vtxSource);
        pipeline->useProgramStages(GL_VERTEX_SHADER_BIT, vtxProg->getProgramName());

        frgProg = createSingleShaderProgram(glu::SHADERTYPE_FRAGMENT, frgSource);
        pipeline->useProgramStages(GL_FRAGMENT_SHADER_BIT, frgProg->getProgramName());

        log() << TestLog::Message << "// Created pipeline " << pipeline->getPipeline() << " with vertex program "
              << vtxProg->getProgramName() << " and fragment program " << frgProg->getProgramName()
              << TestLog::EndMessage;
    }

    m_status.check(pipeline->isValid(), "Pipeline is invalid after initialization");

    if (m_params.switchVtx)
    {
        string newSource = genVtxShaderSrc(pp.vtxSeed, m_varyings.vtxOutputs, vtxName, useUniform, pp.vtxScale);
        vtxProg          = createSingleShaderProgram(glu::SHADERTYPE_VERTEX, newSource);
        pipeline->useProgramStages(GL_VERTEX_SHADER_BIT, vtxProg->getProgramName());
        log() << TestLog::Message << "// Switched pipeline " << pipeline->getPipeline()
              << "'s vertex stage to single-shader program " << vtxProg->getProgramName() << TestLog::EndMessage;
    }
    if (m_params.switchFrg)
    {
        string newSource = genFrgShaderSrc(pp.frgSeed, m_varyings.frgInputs, frgName, useUniform, pp.frgScale);
        frgProg          = createSingleShaderProgram(glu::SHADERTYPE_FRAGMENT, newSource);
        pipeline->useProgramStages(GL_FRAGMENT_SHADER_BIT, frgProg->getProgramName());
        log() << TestLog::Message << "// Switched pipeline " << pipeline->getPipeline()
              << "'s fragment stage to single-shader program " << frgProg->getProgramName() << TestLog::EndMessage;
    }

    if (m_params.switchVtx || m_params.switchFrg)
        m_status.check(pipeline->isValid(), "Pipeline became invalid after changing a stage's program");

    if (m_params.useUniform)
    {
        ProgramWrapper &vtxStage = *(vtxProg ? vtxProg : fullProg);
        ProgramWrapper &frgStage = *(frgProg ? frgProg : fullProg);

        setUniform(vtxStage, vtxName, pp.vtxScale, m_params.useProgramUniform);
        setUniform(frgStage, frgName, pp.frgScale, m_params.useProgramUniform);
    }
    else
        log().writeMessage("// Programs use constants instead of uniforms");

    return MovePtr<Pipeline>(new Pipeline(pipeline, fullProg, vtxProg, frgProg));
}

MovePtr<ProgramWrapper> SeparateShaderTest::createReferenceProgram(const ProgramParams &pp)
{
    bool useUniform = m_params.useUniform;
    const string vtxSrc =
        genVtxShaderSrc(pp.vtxSeed, varyingCompatVtxOutputs(m_varyings), "vtxScale", useUniform, pp.vtxScale);
    const string frgSrc = genFrgShaderSrc(pp.frgSeed, m_varyings.frgInputs, "frgScale", useUniform, pp.frgScale);
    MovePtr<ProgramWrapper> program = createShaderProgram(&vtxSrc, &frgSrc, false);
    GLuint progName                 = program->getProgramName();

    log() << TestLog::Message << "// Created monolithic shader program " << progName << TestLog::EndMessage;

    if (useUniform)
    {
        setUniform(*program, "vtxScale", pp.vtxScale, false);
        setUniform(*program, "frgScale", pp.frgScale, false);
    }

    return program;
}

void SeparateShaderTest::drawSurface(Surface &dst, uint32_t seed)
{
    const RenderContext &renderCtx = getRenderContext();
    Random rnd(seed > 0 ? seed : m_rnd.getUint32());
    Rectangle viewport = randomViewport(renderCtx, rnd, VIEWPORT_SIZE, VIEWPORT_SIZE);
    uint32_t vao       = 0;

    if (!glu::isContextTypeES(renderCtx.getType()))
    {
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
    }

    glClearColor(0.125f, 0.25f, 0.5f, 1.f);
    setViewport(renderCtx, viewport);
    glClear(GL_COLOR_BUFFER_BIT);
    GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
    readRectangle(renderCtx, viewport, dst);
    log().writeMessage("// Drew a triangle");

    if (vao)
        glDeleteVertexArrays(1, &vao);
}

void SeparateShaderTest::testPipelineRendering(MovePtr<Pipeline> &pipeOut)
{
    ProgramParams pp   = genProgramParams(m_rnd);
    Pipeline &pipeline = *(pipeOut = createPipeline(pp));
    GLuint pipeName    = pipeline.pipeline->getPipeline();
    UniquePtr<ProgramWrapper> refProgram(createReferenceProgram(pp));
    GLuint refProgName = refProgram->getProgramName();
    Surface refSurface;
    Surface pipelineSurface;
    GLuint drawSeed = m_rnd.getUint32();

    glUseProgram(refProgName);
    log() << TestLog::Message << "// Use program " << refProgName << TestLog::EndMessage;
    drawSurface(refSurface, drawSeed);
    glUseProgram(0);

    glBindProgramPipeline(pipeName);
    log() << TestLog::Message << "// Bind pipeline " << pipeName << TestLog::EndMessage;
    drawSurface(pipelineSurface, drawSeed);
    glBindProgramPipeline(0);

    {
        const bool result = tcu::fuzzyCompare(m_testCtx.getLog(), "Program pipeline result",
                                              "Result of comparing a program pipeline with a monolithic program",
                                              refSurface, pipelineSurface, 0.05f, tcu::COMPARE_LOG_RESULT);

        m_status.check(result, "Pipeline rendering differs from equivalent monolithic program");
    }
}

void SeparateShaderTest::testCurrentProgPriority(MovePtr<Pipeline> &pipeOut)
{
    ProgramParams pipePp    = genProgramParams(m_rnd);
    ProgramParams programPp = genProgramParams(m_rnd);
    Pipeline &pipeline      = *(pipeOut = createPipeline(pipePp));
    GLuint pipeName         = pipeline.pipeline->getPipeline();
    UniquePtr<ProgramWrapper> program(createReferenceProgram(programPp));
    Surface pipelineSurface;
    Surface refSurface;
    Surface resultSurface;
    uint32_t drawSeed = m_rnd.getUint32();

    LOG_CALL(glBindProgramPipeline(pipeName));
    drawSurface(pipelineSurface, drawSeed);
    LOG_CALL(glBindProgramPipeline(0));

    LOG_CALL(glUseProgram(program->getProgramName()));
    drawSurface(refSurface, drawSeed);
    LOG_CALL(glUseProgram(0));

    LOG_CALL(glUseProgram(program->getProgramName()));
    LOG_CALL(glBindProgramPipeline(pipeName));
    drawSurface(resultSurface, drawSeed);
    LOG_CALL(glBindProgramPipeline(0));
    LOG_CALL(glUseProgram(0));

    bool result = tcu::pixelThresholdCompare(m_testCtx.getLog(), "Active program rendering result",
                                             "Active program rendering result", refSurface, resultSurface,
                                             tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

    m_status.check(result, "glBindProgramPipeline() affects glUseProgram()");
    if (!result)
        log() << TestLog::Image("Pipeline image", "Image produced by pipeline", pipelineSurface);
}

void SeparateShaderTest::testActiveProgramUniform(MovePtr<Pipeline> &pipeOut)
{
    ProgramParams refPp = genProgramParams(m_rnd);
    Surface refSurface;
    Surface resultSurface;
    uint32_t drawSeed = m_rnd.getUint32();

    DE_UNREF(pipeOut);
    {
        UniquePtr<ProgramWrapper> refProg(createReferenceProgram(refPp));
        GLuint refProgName = refProg->getProgramName();

        glUseProgram(refProgName);
        log() << TestLog::Message << "// Use reference program " << refProgName << TestLog::EndMessage;
        drawSurface(refSurface, drawSeed);
        glUseProgram(0);
    }

    {
        ProgramParams changePp = genProgramParams(m_rnd);
        changePp.vtxSeed       = refPp.vtxSeed;
        changePp.frgSeed       = refPp.frgSeed;
        UniquePtr<ProgramWrapper> changeProg(createReferenceProgram(changePp));
        GLuint changeName = changeProg->getProgramName();
        ProgramPipeline pipeline(getRenderContext());
        GLint vtxLoc = glGetUniformLocation(changeName, "vtxScale");
        GLint frgLoc = glGetUniformLocation(changeName, "frgScale");

        LOG_CALL(glBindProgramPipeline(pipeline.getPipeline()));

        pipeline.activeShaderProgram(changeName);
        log() << TestLog::Message << "// Set active shader program to " << changeName << TestLog::EndMessage;

        glUniform1f(vtxLoc, refPp.vtxScale);
        log() << TestLog::Message << "// Set uniform 'vtxScale' to " << refPp.vtxScale << " using glUniform1f"
              << TestLog::EndMessage;
        glUniform1f(frgLoc, refPp.frgScale);
        log() << TestLog::Message << "// Set uniform 'frgScale' to " << refPp.frgScale << " using glUniform1f"
              << TestLog::EndMessage;

        pipeline.activeShaderProgram(0);
        LOG_CALL(glBindProgramPipeline(0));

        LOG_CALL(glUseProgram(changeName));
        drawSurface(resultSurface, drawSeed);
        LOG_CALL(glUseProgram(0));
    }

    bool result =
        tcu::fuzzyCompare(m_testCtx.getLog(), "Active program uniform result", "Active program uniform result",
                          refSurface, resultSurface, 0.05f, tcu::COMPARE_LOG_RESULT);

    m_status.check(result, "glUniform() did not correctly modify "
                           "the active program of the bound pipeline");
}

void SeparateShaderTest::testPipelineQueryPrograms(MovePtr<Pipeline> &pipeOut)
{
    ProgramParams pipePp = genProgramParams(m_rnd);
    Pipeline &pipeline   = *(pipeOut = createPipeline(pipePp));
    GLuint pipeName      = pipeline.pipeline->getPipeline();
    GLint queryVtx       = 0;
    GLint queryFrg       = 0;

    LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_VERTEX_SHADER, &queryVtx)));
    m_status.check(GLuint(queryVtx) == pipeline.getVertexProgram().getProgramName(),
                   "Program pipeline query reported wrong vertex shader program");

    LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_FRAGMENT_SHADER, &queryFrg)));
    m_status.check(GLuint(queryFrg) == pipeline.getFragmentProgram().getProgramName(),
                   "Program pipeline query reported wrong fragment shader program");
}

void SeparateShaderTest::testPipelineQueryActive(MovePtr<Pipeline> &pipeOut)
{
    ProgramParams pipePp = genProgramParams(m_rnd);
    Pipeline &pipeline   = *(pipeOut = createPipeline(pipePp));
    GLuint pipeName      = pipeline.pipeline->getPipeline();
    GLuint newActive     = pipeline.getVertexProgram().getProgramName();
    GLint queryActive    = 0;

    LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_ACTIVE_PROGRAM, &queryActive)));
    m_status.check(queryActive == 0, "Program pipeline query reported non-zero initial active program");

    pipeline.pipeline->activeShaderProgram(newActive);
    log() << TestLog::Message << "Set pipeline " << pipeName << "'s active shader program to " << newActive
          << TestLog::EndMessage;

    LOG_CALL(GLU_CHECK_CALL(glGetProgramPipelineiv(pipeName, GL_ACTIVE_PROGRAM, &queryActive)));
    m_status.check(GLuint(queryActive) == newActive, "Program pipeline query reported incorrect active program");

    pipeline.pipeline->activeShaderProgram(0);
}

TestCase::IterateResult SeparateShaderTest::iterate(void)
{
    MovePtr<Pipeline> pipeline;

    DE_ASSERT(m_iterations > 0);

    if (m_currentIteration == 0)
        logParams(log(), m_params);

    ++m_currentIteration;

    try
    {
        (this->*m_testFunc)(pipeline);
        log().writeMessage("");
    }
    catch (const tcu::Exception &)
    {
        if (pipeline)
            logPipeline(log(), *pipeline);
        throw;
    }

    if (m_status.getResult() != QP_TEST_RESULT_PASS)
    {
        if (pipeline)
            logPipeline(log(), *pipeline);
    }
    else if (m_currentIteration < m_iterations)
        return CONTINUE;

    m_status.setTestContextResult(m_testCtx);
    return STOP;
}

// Group construction utilities

enum ParamFlags
{
    PARAMFLAGS_SWITCH_FRAGMENT = 1 << 0,
    PARAMFLAGS_SWITCH_VERTEX   = 1 << 1,
    PARAMFLAGS_INIT_SINGLE     = 1 << 2,
    PARAMFLAGS_LAST            = 1 << 3,
    PARAMFLAGS_MASK            = PARAMFLAGS_LAST - 1
};

bool areCaseParamFlagsValid(ParamFlags flags)
{
    const ParamFlags switchAll = ParamFlags(PARAMFLAGS_SWITCH_VERTEX | PARAMFLAGS_SWITCH_FRAGMENT);

    if ((flags & PARAMFLAGS_INIT_SINGLE) != 0)
        return (flags & switchAll) == 0 || (flags & switchAll) == switchAll;
    else
        return true;
}

bool addRenderTest(TestCaseGroup &group, const string &namePrefix, const string &descPrefix, int numIterations,
                   ParamFlags flags, TestParams params)
{
    ostringstream name;
    ostringstream desc;

    DE_ASSERT(areCaseParamFlagsValid(flags));

    name << namePrefix;
    desc << descPrefix;

    params.initSingle = (flags & PARAMFLAGS_INIT_SINGLE) != 0;
    params.switchVtx  = (flags & PARAMFLAGS_SWITCH_VERTEX) != 0;
    params.switchFrg  = (flags & PARAMFLAGS_SWITCH_FRAGMENT) != 0;

    name << (flags & PARAMFLAGS_INIT_SINGLE ? "single_program" : "separate_programs");
    desc << (flags & PARAMFLAGS_INIT_SINGLE ? "Single program with two shaders" : "Separate programs for each shader");

    switch (flags & (PARAMFLAGS_SWITCH_FRAGMENT | PARAMFLAGS_SWITCH_VERTEX))
    {
    case 0:
        break;
    case PARAMFLAGS_SWITCH_FRAGMENT:
        name << "_add_fragment";
        desc << ", then add a fragment program";
        break;
    case PARAMFLAGS_SWITCH_VERTEX:
        name << "_add_vertex";
        desc << ", then add a vertex program";
        break;
    case PARAMFLAGS_SWITCH_FRAGMENT | PARAMFLAGS_SWITCH_VERTEX:
        name << "_add_both";
        desc << ", then add both vertex and shader programs";
        break;
    }

    if (!paramsValid(params))
        return false;

    group.addChild(new SeparateShaderTest(group.getContext(), name.str(), desc.str(), numIterations, params,
                                          &SeparateShaderTest::testPipelineRendering));

    return true;
}

void describeInterpolation(const string &stage, VaryingInterpolation qual, ostringstream &name, ostringstream &desc)
{
    DE_ASSERT(qual < VARYINGINTERPOLATION_RANDOM);

    if (qual == VARYINGINTERPOLATION_DEFAULT)
    {
        desc << ", unqualified in " << stage << " shader";
        return;
    }
    else
    {
        const string qualName = glu::getInterpolationName(getGluInterpolation(qual));

        name << "_" << stage << "_" << qualName;
        desc << ", qualified '" << qualName << "' in " << stage << " shader";
    }
}

} // namespace

TestCaseGroup *createCommonSeparateShaderTests(Context &ctx)
{
    TestParams defaultParams;
    int numIterations    = 4;
    TestCaseGroup *group = new TestCaseGroup(ctx, "separate_shader", "Separate shader tests");

    defaultParams.useUniform         = false;
    defaultParams.initSingle         = false;
    defaultParams.switchVtx          = false;
    defaultParams.switchFrg          = false;
    defaultParams.useCreateHelper    = false;
    defaultParams.useProgramUniform  = false;
    defaultParams.useSameName        = false;
    defaultParams.varyings.count     = 0;
    defaultParams.varyings.type      = glu::TYPE_INVALID;
    defaultParams.varyings.binding   = BINDING_NAME;
    defaultParams.varyings.vtxInterp = VARYINGINTERPOLATION_LAST;
    defaultParams.varyings.frgInterp = VARYINGINTERPOLATION_LAST;

    TestCaseGroup *stagesGroup = new TestCaseGroup(ctx, "pipeline", "Pipeline configuration tests");
    group->addChild(stagesGroup);

    for (uint32_t flags = 0; flags < PARAMFLAGS_LAST << 2; ++flags)
    {
        TestParams params = defaultParams;
        ostringstream name;
        ostringstream desc;

        if (!areCaseParamFlagsValid(ParamFlags(flags & PARAMFLAGS_MASK)))
            continue;

        if (flags & (PARAMFLAGS_LAST << 1))
        {
            params.useSameName = true;
            name << "same_";
            desc << "Identically named ";
        }
        else
        {
            name << "different_";
            desc << "Differently named ";
        }

        if (flags & PARAMFLAGS_LAST)
        {
            params.useUniform = true;
            name << "uniform_";
            desc << "uniforms, ";
        }
        else
        {
            name << "constant_";
            desc << "constants, ";
        }

        addRenderTest(*stagesGroup, name.str(), desc.str(), numIterations, ParamFlags(flags & PARAMFLAGS_MASK), params);
    }

    TestCaseGroup *programUniformGroup = new TestCaseGroup(ctx, "program_uniform", "ProgramUniform tests");
    group->addChild(programUniformGroup);

    for (uint32_t flags = 0; flags < PARAMFLAGS_LAST; ++flags)
    {
        TestParams params = defaultParams;

        if (!areCaseParamFlagsValid(ParamFlags(flags)))
            continue;

        params.useUniform        = true;
        params.useProgramUniform = true;

        addRenderTest(*programUniformGroup, "", "", numIterations, ParamFlags(flags), params);
    }

    TestCaseGroup *createShaderProgramGroup =
        new TestCaseGroup(ctx, "create_shader_program", "CreateShaderProgram tests");
    group->addChild(createShaderProgramGroup);

    for (uint32_t flags = 0; flags < PARAMFLAGS_LAST; ++flags)
    {
        TestParams params = defaultParams;

        if (!areCaseParamFlagsValid(ParamFlags(flags)))
            continue;

        params.useCreateHelper = true;

        addRenderTest(*createShaderProgramGroup, "", "", numIterations, ParamFlags(flags), params);
    }

    TestCaseGroup *interfaceGroup = new TestCaseGroup(ctx, "interface", "Shader interface compatibility tests");
    group->addChild(interfaceGroup);

    enum
    {
        NUM_INTERPOLATIONS =
            VARYINGINTERPOLATION_RANDOM, // VARYINGINTERPOLATION_RANDOM is one after last fully specified interpolation
        INTERFACEFLAGS_LAST =
            static_cast<int>(BINDING_LAST) * static_cast<int>(NUM_INTERPOLATIONS) * static_cast<int>(NUM_INTERPOLATIONS)
    };

    for (uint32_t flags = 0; flags < INTERFACEFLAGS_LAST; ++flags)
    {
        uint32_t tmpFlags              = flags;
        VaryingInterpolation frgInterp = VaryingInterpolation(tmpFlags % NUM_INTERPOLATIONS);
        VaryingInterpolation vtxInterp = VaryingInterpolation((tmpFlags /= NUM_INTERPOLATIONS) % NUM_INTERPOLATIONS);
        BindingKind binding            = BindingKind((tmpFlags /= NUM_INTERPOLATIONS) % BINDING_LAST);
        TestParams params              = defaultParams;
        ostringstream name;
        ostringstream desc;

        params.varyings.count     = 1;
        params.varyings.type      = glu::TYPE_FLOAT;
        params.varyings.binding   = binding;
        params.varyings.vtxInterp = vtxInterp;
        params.varyings.frgInterp = frgInterp;

        switch (binding)
        {
        case BINDING_LOCATION:
            name << "same_location";
            desc << "Varyings have same location, ";
            break;
        case BINDING_NAME:
            name << "same_name";
            desc << "Varyings have same name, ";
            break;
        default:
            DE_FATAL("Impossible");
        }

        describeInterpolation("vertex", vtxInterp, name, desc);
        describeInterpolation("fragment", frgInterp, name, desc);

        if (!paramsValid(params))
            continue;

        interfaceGroup->addChild(new SeparateShaderTest(ctx, name.str(), desc.str(), numIterations, params,
                                                        &SeparateShaderTest::testPipelineRendering));
    }

    uint32_t baseSeed = ctx.getTestContext().getCommandLine().getBaseSeed();
    Random rnd(deStringHash("separate_shader.random") + baseSeed);
    set<string> seen;
    TestCaseGroup *randomGroup = new TestCaseGroup(ctx, "random", "Random pipeline configuration tests");
    group->addChild(randomGroup);

    for (uint32_t i = 0; i < 128; ++i)
    {
        TestParams params;
        string code;
        uint32_t genIterations = 4096;

        do
        {
            params = genParams(rnd.getUint32());
            code   = paramsCode(params);
        } while (de::contains(seen, code) && --genIterations > 0);

        seen.insert(code);

        string name = de::toString(i); // Would be code but baseSeed can change

        randomGroup->addChild(
            new SeparateShaderTest(ctx, name, name, numIterations, params, &SeparateShaderTest::testPipelineRendering));
    }

    TestCaseGroup *apiGroup = new TestCaseGroup(ctx, "api", "Program pipeline API tests");
    group->addChild(apiGroup);

    {
        // More or less random parameters. These shouldn't have much effect, so just
        // do a single sample.
        TestParams params = defaultParams;
        params.useUniform = true;
        apiGroup->addChild(new SeparateShaderTest(ctx, "current_program_priority",
                                                  "Test priority between current program and pipeline binding", 1,
                                                  params, &SeparateShaderTest::testCurrentProgPriority));
        apiGroup->addChild(new SeparateShaderTest(ctx, "active_program_uniform",
                                                  "Test that glUniform() affects a pipeline's active program", 1,
                                                  params, &SeparateShaderTest::testActiveProgramUniform));

        apiGroup->addChild(new SeparateShaderTest(ctx, "pipeline_programs",
                                                  "Test queries for programs in program pipeline stages", 1, params,
                                                  &SeparateShaderTest::testPipelineQueryPrograms));

        apiGroup->addChild(new SeparateShaderTest(ctx, "pipeline_active",
                                                  "Test query for active programs in a program pipeline", 1, params,
                                                  &SeparateShaderTest::testPipelineQueryActive));
    }

    return group;
}

TestCaseGroup *createGLESSeparateShaderTests(Context &ctx)
{
    TestCaseGroup *group = createCommonSeparateShaderTests(ctx);

    TestCaseGroup *interfaceMismatchGroup =
        new TestCaseGroup(ctx, "validation", "Negative program pipeline interface matching");
    group->addChild(interfaceMismatchGroup);

    {
        TestCaseGroup *es31Group = new TestCaseGroup(ctx, "es31", "GLSL ES 3.1 pipeline interface matching");
        gls::ShaderLibrary shaderLibrary(ctx.getTestContext(), ctx.getRenderContext(), ctx.getContextInfo());
        const std::vector<tcu::TestNode *> children =
            shaderLibrary.loadShaderFile("shaders/es31/separate_shader_validation.test");

        for (int i = 0; i < (int)children.size(); i++)
            es31Group->addChild(children[i]);

        interfaceMismatchGroup->addChild(es31Group);
    }

    {
        TestCaseGroup *es32Group = new TestCaseGroup(ctx, "es32", "GLSL ES 3.2 pipeline interface matching");
        gls::ShaderLibrary shaderLibrary(ctx.getTestContext(), ctx.getRenderContext(), ctx.getContextInfo());
        const std::vector<tcu::TestNode *> children =
            shaderLibrary.loadShaderFile("shaders/es32/separate_shader_validation.test");

        for (int i = 0; i < (int)children.size(); i++)
            es32Group->addChild(children[i]);

        interfaceMismatchGroup->addChild(es32Group);
    }

    return group;
}
} // namespace Functional
} // namespace gles31
} // namespace deqp
