/*-------------------------------------------------------------------------
 * 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);
	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");
}

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* createSeparateShaderTests (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 = BINDING_LAST * NUM_INTERPOLATIONS * 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));
	}

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

	{
		gls::ShaderLibrary					shaderLibrary	(ctx.getTestContext(), ctx.getRenderContext(), ctx.getContextInfo());
		const std::vector<tcu::TestNode*>	children		= shaderLibrary.loadShaderFile("shaders/separate_shader_validation.test");

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

	return group;
}

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