/*-------------------------------------------------------------------------
 * 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 std::map;
using std::set;
using std::ostringstream;
using std::string;
using std::vector;
using de::MovePtr;
using de::Random;
using de::UniquePtr;
using tcu::MessageBuilder;
using tcu::RenderTarget;
using tcu::StringTemplate;
using tcu::Surface;
using tcu::TestLog;
using tcu::ResultCollector;
using glu::CallLogWrapper;
using glu::DataType;
using glu::VariableDeclaration;
using glu::Precision;
using glu::Program;
using glu::ProgramPipeline;
using glu::ProgramSources;
using glu::RenderContext;
using glu::ShaderProgram;
using glu::ShaderType;
using glu::Storage;
using glu::VarType;
using glu::VertexSource;
using glu::FragmentSource;
using glu::ProgramSeparable;

using namespace glw;

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

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 (deUint32							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 (deUint32							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 (deUint32 vtxSeed_, GLfloat vtxScale_, deUint32 frgSeed_, GLfloat frgScale_)
		: vtxSeed	(vtxSeed_)
		, vtxScale	(vtxScale_)
		, frgSeed	(frgSeed_)
		, frgScale	(frgScale_) {}
	deUint32	vtxSeed;
	GLfloat		vtxScale;
	deUint32	frgSeed;
	GLfloat		frgScale;
};

ProgramParams genProgramParams (Random& rnd)
{
	const deUint32	vtxSeed		= rnd.getUint32();
	const GLfloat	vtxScale	= (float)rnd.getInt(8, 16) / 16.0f;
	const deUint32	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;
};

deUint32 paramsSeed (const TestParams& params)
{
	deUint32 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 (deUint32 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,
														 deUint32				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 deUint32	initVtxSeed	= m_params.switchVtx ? m_rnd.getUint32() : pp.vtxSeed;

	const string	frgName		= m_params.useSameName ? "scale" : "frgScale";
	const deUint32	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, deUint32 seed)
{
	const RenderContext&	renderCtx	= getRenderContext();
	Random					rnd			(seed > 0 ? seed : m_rnd.getUint32());
	Rectangle				viewport	= randomViewport(renderCtx, rnd,
														 VIEWPORT_SIZE, VIEWPORT_SIZE);
	deUint32				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;
	deUint32					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;
	deUint32					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";
	}
}


} // anonymous

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 (deUint32 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 (deUint32 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 (deUint32 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 (deUint32 flags = 0; flags < INTERFACEFLAGS_LAST; ++flags)
	{
		deUint32				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));
	}

	deUint32		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 (deUint32 i = 0; i < 128; ++i)
	{
		TestParams		params;
		string			code;
		deUint32		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;

}
} // Functional
} // gles31
} // deqp
