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

#include "glsShaderLibraryCase.hpp"

#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuSurface.hpp"

#include "tcuStringTemplate.hpp"
#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "gluDrawUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluStrUtil.hpp"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "deRandom.hpp"
#include "deInt32.h"
#include "deMath.h"
#include "deString.h"
#include "deStringUtil.hpp"
#include "deSharedPtr.hpp"

#include <map>
#include <vector>
#include <string>
#include <sstream>

namespace deqp
{
namespace gls
{

using namespace tcu;
using namespace glu;
using namespace glu::sl;

using std::vector;
using std::string;
using std::ostringstream;
using std::map;
using std::pair;

using de::SharedPtr;

// OpenGL-specific specialization utils

static vector<RequiredExtension> checkAndSpecializeExtensions (const vector<RequiredExtension>&	src,
															   const ContextInfo&				ctxInfo)
{
	vector<RequiredExtension>	specialized;

	for (size_t extNdx = 0; extNdx < src.size(); ++extNdx)
	{
		const RequiredExtension&	extension		= src[extNdx];
		int							supportedAltNdx	= -1;

		for (size_t alternativeNdx = 0; alternativeNdx < extension.alternatives.size(); ++alternativeNdx)
		{
			if (ctxInfo.isExtensionSupported(extension.alternatives[alternativeNdx].c_str()))
			{
				supportedAltNdx	= (int)alternativeNdx;
				break;
			}
		}

		if (supportedAltNdx >= 0)
		{
			specialized.push_back(RequiredExtension(extension.alternatives[supportedAltNdx], extension.effectiveStages));
		}
		else
		{
			// no extension(s). Make a nice output
			std::ostringstream extensionList;

			for (size_t ndx = 0; ndx < extension.alternatives.size(); ++ndx)
			{
				if (!extensionList.str().empty())
					extensionList << ", ";
				extensionList << extension.alternatives[ndx];
			}

			if (extension.alternatives.size() == 1)
				throw tcu::NotSupportedError("Test requires extension " + extensionList.str());
			else
				throw tcu::NotSupportedError("Test requires any extension of " + extensionList.str());
		}
	}

	return specialized;
}

static void checkImplementationLimits (const vector<RequiredCapability>&	requiredCaps,
									   const ContextInfo&					ctxInfo)
{
	for (size_t capNdx = 0; capNdx < requiredCaps.size(); ++capNdx)
	{
		const RequiredCapability& capability = requiredCaps[capNdx];
		if (capability.type != CAPABILITY_LIMIT)
			continue;

		const deUint32	pname			= capability.enumName;
		const int		requiredValue	= capability.referenceValue;
		const int		supportedValue	= ctxInfo.getInt((int)pname);

		if (supportedValue <= requiredValue)
			throw tcu::NotSupportedError("Test requires " + de::toString(glu::getGettableStateStr(pname)) + " (" + de::toString(supportedValue) + ") >= " + de::toString(requiredValue));
	}
}

// Shader source specialization

// This functions builds a matching vertex shader for a 'both' case, when
// the fragment shader is being tested.
// We need to build attributes and varyings for each 'input'.
static string genVertexShader (const ShaderCaseSpecification& spec)
{
	ostringstream		res;
	const bool			usesInout	= glslVersionUsesInOutQualifiers(spec.targetVersion);
	const char* const	vtxIn		= usesInout ? "in"	: "attribute";
	const char* const	vtxOut		= usesInout ? "out"	: "varying";

	res << glu::getGLSLVersionDeclaration(spec.targetVersion) << "\n";

	// Declarations (position + attribute/varying for each input).
	res << "precision highp float;\n";
	res << "precision highp int;\n";
	res << "\n";
	res << vtxIn << " highp vec4 dEQP_Position;\n";

	for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++)
	{
		const Value&		val			= spec.values.inputs[ndx];
		const DataType		basicType	= val.type.getBasicType();
		const DataType		floatType	= getDataTypeFloatScalars(basicType);
		const char* const	typeStr		= getDataTypeName(floatType);

		res << vtxIn << " " << typeStr << " a_" << val.name << ";\n";

		if (getDataTypeScalarType(basicType) == TYPE_FLOAT)
			res << vtxOut << " " << typeStr << " " << val.name << ";\n";
		else
			res << vtxOut << " " << typeStr << " v_" << val.name << ";\n";
	}
	res << "\n";

	// Main function.
	// - gl_Position = dEQP_Position;
	// - for each input: write attribute directly to varying
	res << "void main()\n";
	res << "{\n";
	res << "	gl_Position = dEQP_Position;\n";
	for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++)
	{
		const Value&	val		= spec.values.inputs[ndx];
		const string&	name	= val.name;

		if (getDataTypeScalarType(val.type.getBasicType()) == TYPE_FLOAT)
			res << "	" << name << " = a_" << name << ";\n";
		else
			res << "	v_" << name << " = a_" << name << ";\n";
	}

	res << "}\n";
	return res.str();
}

static void genCompareOp (ostringstream& output, const char* dstVec4Var, const ValueBlock& valueBlock, const char* nonFloatNamePrefix, const char* checkVarName)
{
	bool isFirstOutput = true;

	for (size_t ndx = 0; ndx < valueBlock.outputs.size(); ndx++)
	{
		const Value&	val		= valueBlock.outputs[ndx];

		// Check if we're only interested in one variable (then skip if not the right one).
		if (checkVarName && val.name != checkVarName)
			continue;

		// Prefix.
		if (isFirstOutput)
		{
			output << "bool RES = ";
			isFirstOutput = false;
		}
		else
			output << "RES = RES && ";

		// Generate actual comparison.
		if (getDataTypeScalarType(val.type.getBasicType()) == TYPE_FLOAT)
			output << "isOk(" << val.name << ", ref_" << val.name << ", 0.05);\n";
		else
			output << "isOk(" << nonFloatNamePrefix << val.name << ", ref_" << val.name << ");\n";
	}

	if (isFirstOutput)
		output << dstVec4Var << " = vec4(1.0);\n";	// \todo [petri] Should we give warning if not expect-failure case?
	else
		output << dstVec4Var << " = vec4(RES, RES, RES, 1.0);\n";
}

static inline bool supportsFragmentHighp (glu::GLSLVersion version)
{
	return version != glu::GLSL_VERSION_100_ES;
}

static string genFragmentShader (const ShaderCaseSpecification& spec)
{
	ostringstream		shader;
	const bool			usesInout		= glslVersionUsesInOutQualifiers(spec.targetVersion);
	const bool			customColorOut	= usesInout;
	const char*	const	fragIn			= usesInout ? "in" : "varying";
	const char*	const	prec			= supportsFragmentHighp(spec.targetVersion) ? "highp" : "mediump";

	shader << glu::getGLSLVersionDeclaration(spec.targetVersion) << "\n";

	shader << "precision " << prec << " float;\n";
	shader << "precision " << prec << " int;\n";
	shader << "\n";

	if (customColorOut)
	{
		shader << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
		shader << "\n";
	}

	genCompareFunctions(shader, spec.values, true);
	shader << "\n";

	// Declarations (varying, reference for each output).
	for (size_t ndx = 0; ndx < spec.values.outputs.size(); ndx++)
	{
		const Value&		val				= spec.values.outputs[ndx];
		const DataType		basicType		= val.type.getBasicType();
		const DataType		floatType		= getDataTypeFloatScalars(basicType);
		const char* const	floatTypeStr	= getDataTypeName(floatType);
		const char* const	refTypeStr		= getDataTypeName(basicType);

		if (getDataTypeScalarType(basicType) == TYPE_FLOAT)
			shader << fragIn << " " << floatTypeStr << " " << val.name << ";\n";
		else
			shader << fragIn << " " << floatTypeStr << " v_" << val.name << ";\n";

		shader << "uniform " << refTypeStr << " ref_" << val.name << ";\n";
	}

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

	shader << "	";
	genCompareOp(shader, customColorOut ? "dEQP_FragColor" : "gl_FragColor", spec.values, "v_", DE_NULL);

	shader << "}\n";
	return shader.str();
}

// Specialize a shader for the vertex shader test case.
static string specializeVertexShader (const ShaderCaseSpecification& spec, const std::string& src, const vector<RequiredExtension>& extensions)
{
	ostringstream		decl;
	ostringstream		setup;
	ostringstream		output;
	const bool			usesInout	= glslVersionUsesInOutQualifiers(spec.targetVersion);
	const char* const	vtxIn		= usesInout ? "in"	: "attribute";
	const char* const	vtxOut		= usesInout ? "out"	: "varying";

	// generated from "both" case
	DE_ASSERT(spec.caseType == CASETYPE_VERTEX_ONLY);

	// Output (write out position).
	output << "gl_Position = dEQP_Position;\n";

	// Declarations (position + attribute for each input, varying for each output).
	decl << vtxIn << " highp vec4 dEQP_Position;\n";

	for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++)
	{
		const Value&		val				= spec.values.inputs[ndx];
		const DataType		basicType		= val.type.getBasicType();
		const DataType		floatType		= getDataTypeFloatScalars(basicType);
		const char* const	floatTypeStr	= getDataTypeName(floatType);
		const char* const	refTypeStr		= getDataTypeName(basicType);

		if (getDataTypeScalarType(basicType) == TYPE_FLOAT)
		{
			decl << vtxIn << " " << floatTypeStr << " " << val.name << ";\n";
		}
		else
		{
			decl << vtxIn << " " << floatTypeStr << " a_" << val.name << ";\n";
			setup << refTypeStr << " " << val.name << " = " << refTypeStr << "(a_" << val.name << ");\n";
		}
	}

	// \todo [2015-07-24 pyry] Why are uniforms missing?

	for (size_t ndx = 0; ndx < spec.values.outputs.size(); ndx++)
	{
		const Value&		val				= spec.values.outputs[ndx];
		const DataType		basicType		= val.type.getBasicType();
		const DataType		floatType		= getDataTypeFloatScalars(basicType);
		const char* const	floatTypeStr	= getDataTypeName(floatType);
		const char* const	refTypeStr		= getDataTypeName(basicType);

		if (getDataTypeScalarType(basicType) == TYPE_FLOAT)
			decl << vtxOut << " " << floatTypeStr << " " << val.name << ";\n";
		else
		{
			decl << vtxOut << " " << floatTypeStr << " v_" << val.name << ";\n";
			decl << refTypeStr << " " << val.name << ";\n";

			output << "v_" << val.name << " = " << floatTypeStr << "(" << val.name << ");\n";
		}
	}

	// Shader specialization.
	map<string, string> params;
	params.insert(pair<string, string>("DECLARATIONS", decl.str()));
	params.insert(pair<string, string>("SETUP", setup.str()));
	params.insert(pair<string, string>("OUTPUT", output.str()));
	params.insert(pair<string, string>("POSITION_FRAG_COLOR", "gl_Position"));

	StringTemplate	tmpl	(src);
	const string	baseSrc	= tmpl.specialize(params);
	const string	withExt	= injectExtensionRequirements(baseSrc, extensions, SHADERTYPE_VERTEX);

	return withExt;
}

// Specialize a shader for the fragment shader test case.
static string specializeFragmentShader (const ShaderCaseSpecification& spec, const std::string& src, const vector<RequiredExtension>& extensions)
{
	ostringstream		decl;
	ostringstream		setup;
	ostringstream		output;

	const bool			usesInout		= glslVersionUsesInOutQualifiers(spec.targetVersion);
	const bool			customColorOut	= usesInout;
	const char* const	fragIn			= usesInout			? "in"				: "varying";
	const char* const	fragColor		= customColorOut	? "dEQP_FragColor"	: "gl_FragColor";

	// generated from "both" case
	DE_ASSERT(spec.caseType == CASETYPE_FRAGMENT_ONLY);

	genCompareFunctions(decl, spec.values, false);
	genCompareOp(output, fragColor, spec.values, "", DE_NULL);

	if (customColorOut)
		decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";

	for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++)
	{
		const Value&		val				= spec.values.inputs[ndx];
		const DataType		basicType		= val.type.getBasicType();
		const DataType		floatType		= getDataTypeFloatScalars(basicType);
		const char* const	floatTypeStr	= getDataTypeName(floatType);
		const char* const	refTypeStr		= getDataTypeName(basicType);

		if (getDataTypeScalarType(basicType) == TYPE_FLOAT)
			decl << fragIn << " " << floatTypeStr << " " << val.name << ";\n";
		else
		{
			decl << fragIn << " " << floatTypeStr << " v_" << val.name << ";\n";
			std::string offset = isDataTypeIntOrIVec(basicType) ? " * 1.0025" : ""; // \todo [petri] bit of a hack to avoid errors in chop() due to varying interpolation
			setup << refTypeStr << " " << val.name << " = " << refTypeStr << "(v_" << val.name << offset << ");\n";
		}
	}

	// \todo [2015-07-24 pyry] Why are uniforms missing?

	for (size_t ndx = 0; ndx < spec.values.outputs.size(); ndx++)
	{
		const Value&		val				= spec.values.outputs[ndx];
		const DataType		basicType		= val.type.getBasicType();
		const char* const	refTypeStr		= getDataTypeName(basicType);

		decl << "uniform " << refTypeStr << " ref_" << val.name << ";\n";
		decl << refTypeStr << " " << val.name << ";\n";
	}

	/* \todo [2010-04-01 petri] Check all outputs. */

	// Shader specialization.
	map<string, string> params;
	params.insert(pair<string, string>("DECLARATIONS", decl.str()));
	params.insert(pair<string, string>("SETUP", setup.str()));
	params.insert(pair<string, string>("OUTPUT", output.str()));
	params.insert(pair<string, string>("POSITION_FRAG_COLOR", fragColor));

	StringTemplate	tmpl	(src);
	const string	baseSrc	= tmpl.specialize(params);
	const string	withExt	= injectExtensionRequirements(baseSrc, extensions, SHADERTYPE_FRAGMENT);

	return withExt;
}

static void generateUniformDeclarations (std::ostream& dst, const ValueBlock& valueBlock)
{
	for (size_t ndx = 0; ndx < valueBlock.uniforms.size(); ndx++)
	{
		const Value&		val		= valueBlock.uniforms[ndx];
		const char* const	typeStr	= getDataTypeName(val.type.getBasicType());

		if (val.name.find('.') == string::npos)
			dst << "uniform " << typeStr << " " << val.name << ";\n";
	}
}

static map<string, string> generateVertexSpecialization (const ProgramSpecializationParams& specParams)
{
	const bool				usesInout	= glslVersionUsesInOutQualifiers(specParams.caseSpec.targetVersion);
	const char*				vtxIn		= usesInout ? "in" : "attribute";
	ostringstream			decl;
	ostringstream			setup;
	map<string, string>		params;

	decl << vtxIn << " highp vec4 dEQP_Position;\n";

	for (size_t ndx = 0; ndx < specParams.caseSpec.values.inputs.size(); ndx++)
	{
		const Value&		val			= specParams.caseSpec.values.inputs[ndx];
		const DataType		basicType	= val.type.getBasicType();
		const char* const	typeStr		= getDataTypeName(val.type.getBasicType());

		if (getDataTypeScalarType(basicType) == TYPE_FLOAT)
		{
			decl << vtxIn << " " << typeStr << " " << val.name << ";\n";
		}
		else
		{
			const DataType		floatType		= getDataTypeFloatScalars(basicType);
			const char* const	floatTypeStr	= getDataTypeName(floatType);

			decl << vtxIn << " " << floatTypeStr << " a_" << val.name << ";\n";
			setup << typeStr << " " << val.name << " = " << typeStr << "(a_" << val.name << ");\n";
		}
	}

	generateUniformDeclarations(decl, specParams.caseSpec.values);

	params.insert(pair<string, string>("VERTEX_DECLARATIONS",	decl.str()));
	params.insert(pair<string, string>("VERTEX_SETUP",			setup.str()));
	params.insert(pair<string, string>("VERTEX_OUTPUT",			string("gl_Position = dEQP_Position;\n")));

	return params;
}

static map<string, string> generateFragmentSpecialization (const ProgramSpecializationParams& specParams)
{
	const bool			usesInout		= glslVersionUsesInOutQualifiers(specParams.caseSpec.targetVersion);
	const bool			customColorOut	= usesInout;
	const char* const	fragColor		= customColorOut ? "dEQP_FragColor"	: "gl_FragColor";
	ostringstream		decl;
	ostringstream		output;
	map<string, string>	params;

	genCompareFunctions(decl, specParams.caseSpec.values, false);
	genCompareOp(output, fragColor, specParams.caseSpec.values, "", DE_NULL);

	if (customColorOut)
		decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";

	for (size_t ndx = 0; ndx < specParams.caseSpec.values.outputs.size(); ndx++)
	{
		const Value&		val			= specParams.caseSpec.values.outputs[ndx];
		const char*	const	refTypeStr	= getDataTypeName(val.type.getBasicType());

		decl << "uniform " << refTypeStr << " ref_" << val.name << ";\n";
		decl << refTypeStr << " " << val.name << ";\n";
	}

	generateUniformDeclarations(decl, specParams.caseSpec.values);

	params.insert(pair<string, string>("FRAGMENT_DECLARATIONS",	decl.str()));
	params.insert(pair<string, string>("FRAGMENT_OUTPUT",		output.str()));
	params.insert(pair<string, string>("FRAG_COLOR",			fragColor));

	return params;
}

static map<string, string> generateGeometrySpecialization (const ProgramSpecializationParams& specParams)
{
	ostringstream		decl;
	map<string, string>	params;

	decl << "layout (triangles) in;\n";
	decl << "layout (triangle_strip, max_vertices=3) out;\n";
	decl << "\n";

	generateUniformDeclarations(decl, specParams.caseSpec.values);

	params.insert(pair<string, string>("GEOMETRY_DECLARATIONS",		decl.str()));

	return params;
}

static map<string, string> generateTessControlSpecialization (const ProgramSpecializationParams& specParams)
{
	ostringstream		decl;
	ostringstream		output;
	map<string, string>	params;

	decl << "layout (vertices=3) out;\n";
	decl << "\n";

	generateUniformDeclarations(decl, specParams.caseSpec.values);

	output <<	"gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
				"gl_TessLevelInner[0] = 2.0;\n"
				"gl_TessLevelInner[1] = 2.0;\n"
				"gl_TessLevelOuter[0] = 2.0;\n"
				"gl_TessLevelOuter[1] = 2.0;\n"
				"gl_TessLevelOuter[2] = 2.0;\n"
				"gl_TessLevelOuter[3] = 2.0;";

	params.insert(pair<string, string>("TESSELLATION_CONTROL_DECLARATIONS",	decl.str()));
	params.insert(pair<string, string>("TESSELLATION_CONTROL_OUTPUT",		output.str()));
	params.insert(pair<string, string>("GL_MAX_PATCH_VERTICES",				de::toString(specParams.maxPatchVertices)));

	return params;
}

static map<string, string> generateTessEvalSpecialization (const ProgramSpecializationParams& specParams)
{
	ostringstream		decl;
	ostringstream		output;
	map<string, string>	params;

	decl << "layout (triangles) in;\n";
	decl << "\n";

	generateUniformDeclarations(decl, specParams.caseSpec.values);

	output <<	"gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position + gl_TessCoord[1] * gl_in[1].gl_Position + gl_TessCoord[2] * gl_in[2].gl_Position;\n";

	params.insert(pair<string, string>("TESSELLATION_EVALUATION_DECLARATIONS",	decl.str()));
	params.insert(pair<string, string>("TESSELLATION_EVALUATION_OUTPUT",		output.str()));
	params.insert(pair<string, string>("GL_MAX_PATCH_VERTICES",					de::toString(specParams.maxPatchVertices)));

	return params;
}

static void specializeShaderSources (ProgramSources&					dst,
									 const ProgramSources&				src,
									 const ProgramSpecializationParams&	specParams,
									 glu::ShaderType					shaderType,
									 map<string, string>				(*specializationGenerator) (const ProgramSpecializationParams& specParams))
{
	if (!src.sources[shaderType].empty())
	{
		const map<string, string>	tmplParams	= specializationGenerator(specParams);

		for (size_t ndx = 0; ndx < src.sources[shaderType].size(); ++ndx)
		{
			const StringTemplate	tmpl			(src.sources[shaderType][ndx]);
			const std::string		baseGLSLCode	= tmpl.specialize(tmplParams);
			const std::string		sourceWithExts	= injectExtensionRequirements(baseGLSLCode, specParams.requiredExtensions, shaderType);

			dst << glu::ShaderSource(shaderType, sourceWithExts);
		}
	}
}

static void specializeProgramSources (glu::ProgramSources&					dst,
									  const glu::ProgramSources&			src,
									  const ProgramSpecializationParams&	specParams)
{
	specializeShaderSources(dst, src, specParams, SHADERTYPE_VERTEX,					generateVertexSpecialization);
	specializeShaderSources(dst, src, specParams, SHADERTYPE_FRAGMENT,					generateFragmentSpecialization);
	specializeShaderSources(dst, src, specParams, SHADERTYPE_GEOMETRY,					generateGeometrySpecialization);
	specializeShaderSources(dst, src, specParams, SHADERTYPE_TESSELLATION_CONTROL,		generateTessControlSpecialization);
	specializeShaderSources(dst, src, specParams, SHADERTYPE_TESSELLATION_EVALUATION,	generateTessEvalSpecialization);

	dst << ProgramSeparable(src.separable);
}

enum
{
	VIEWPORT_WIDTH		= 128,
	VIEWPORT_HEIGHT		= 128
};

class BeforeDrawValidator : public glu::DrawUtilCallback
{
public:
	enum TargetType
	{
		TARGETTYPE_PROGRAM = 0,
		TARGETTYPE_PIPELINE,

		TARGETTYPE_LAST
	};

							BeforeDrawValidator	(const glw::Functions& gl, glw::GLuint target, TargetType targetType);

	void					beforeDrawCall		(void);

	const std::string&		getInfoLog			(void) const;
	glw::GLint				getValidateStatus	(void) const;

private:
	const glw::Functions&	m_gl;
	const glw::GLuint		m_target;
	const TargetType		m_targetType;

	glw::GLint				m_validateStatus;
	std::string				m_logMessage;
};

BeforeDrawValidator::BeforeDrawValidator (const glw::Functions& gl, glw::GLuint target, TargetType targetType)
	: m_gl				(gl)
	, m_target			(target)
	, m_targetType		(targetType)
	, m_validateStatus	(-1)
{
	DE_ASSERT(targetType < TARGETTYPE_LAST);
}

void BeforeDrawValidator::beforeDrawCall (void)
{
	glw::GLint					bytesWritten	= 0;
	glw::GLint					infoLogLength;
	std::vector<glw::GLchar>	logBuffer;
	int							stringLength;

	// validate
	if (m_targetType == TARGETTYPE_PROGRAM)
		m_gl.validateProgram(m_target);
	else if (m_targetType == TARGETTYPE_PIPELINE)
		m_gl.validateProgramPipeline(m_target);
	else
		DE_ASSERT(false);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "validate");

	// check status
	m_validateStatus = -1;

	if (m_targetType == TARGETTYPE_PROGRAM)
		m_gl.getProgramiv(m_target, GL_VALIDATE_STATUS, &m_validateStatus);
	else if (m_targetType == TARGETTYPE_PIPELINE)
		m_gl.getProgramPipelineiv(m_target, GL_VALIDATE_STATUS, &m_validateStatus);
	else
		DE_ASSERT(false);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "get validate status");
	TCU_CHECK(m_validateStatus == GL_TRUE || m_validateStatus == GL_FALSE);

	// read log

	infoLogLength = 0;

	if (m_targetType == TARGETTYPE_PROGRAM)
		m_gl.getProgramiv(m_target, GL_INFO_LOG_LENGTH, &infoLogLength);
	else if (m_targetType == TARGETTYPE_PIPELINE)
		m_gl.getProgramPipelineiv(m_target, GL_INFO_LOG_LENGTH, &infoLogLength);
	else
		DE_ASSERT(false);

	GLU_EXPECT_NO_ERROR(m_gl.getError(), "get info log length");

	if (infoLogLength <= 0)
	{
		m_logMessage.clear();
		return;
	}

	logBuffer.resize(infoLogLength + 2, '0'); // +1 for zero terminator (infoLogLength should include it, but better play it safe), +1 to make sure buffer is always larger

	if (m_targetType == TARGETTYPE_PROGRAM)
		m_gl.getProgramInfoLog(m_target, infoLogLength + 1, &bytesWritten, &logBuffer[0]);
	else if (m_targetType == TARGETTYPE_PIPELINE)
		m_gl.getProgramPipelineInfoLog(m_target, infoLogLength + 1, &bytesWritten, &logBuffer[0]);
	else
		DE_ASSERT(false);

	// just ignore bytesWritten to be safe, find the null terminator
	stringLength = (int)(std::find(logBuffer.begin(), logBuffer.end(), '0') - logBuffer.begin());
	m_logMessage.assign(&logBuffer[0], stringLength);
}

const std::string& BeforeDrawValidator::getInfoLog (void) const
{
	return m_logMessage;
}

glw::GLint BeforeDrawValidator::getValidateStatus (void) const
{
	return m_validateStatus;
}

// ShaderCase.

ShaderLibraryCase::ShaderLibraryCase (tcu::TestContext& testCtx, RenderContext& renderCtx, const glu::ContextInfo& contextInfo, const char* name, const char* description, const ShaderCaseSpecification& specification)
	: tcu::TestCase	(testCtx, name, description)
	, m_renderCtx	(renderCtx)
	, m_contextInfo	(contextInfo)
	, m_spec		(specification)
{
}

ShaderLibraryCase::~ShaderLibraryCase (void)
{
}

void ShaderLibraryCase::init (void)
{
	DE_ASSERT(isValid(m_spec));

	if (!isGLSLVersionSupported(m_renderCtx.getType(), m_spec.targetVersion))
		TCU_THROW(NotSupportedError, (string(getGLSLVersionName(m_spec.targetVersion)) + " is not supported").c_str());

	checkImplementationLimits(m_spec.requiredCaps, m_contextInfo);

	// log the expected result
	switch (m_spec.expectResult)
	{
		case EXPECT_PASS:
			// Don't write anything
			break;

		case EXPECT_COMPILE_FAIL:
			m_testCtx.getLog() << tcu::TestLog::Message << "Expecting shader compilation to fail." << tcu::TestLog::EndMessage;
			break;

		case EXPECT_LINK_FAIL:
			m_testCtx.getLog() << tcu::TestLog::Message << "Expecting program linking to fail." << tcu::TestLog::EndMessage;
			break;

		case EXPECT_COMPILE_LINK_FAIL:
			m_testCtx.getLog() << tcu::TestLog::Message << "Expecting either shader compilation or program linking to fail." << tcu::TestLog::EndMessage;
			break;

		case EXPECT_VALIDATION_FAIL:
			m_testCtx.getLog() << tcu::TestLog::Message << "Expecting program validation to fail." << tcu::TestLog::EndMessage;
			break;

		case EXPECT_BUILD_SUCCESSFUL:
			m_testCtx.getLog() << tcu::TestLog::Message << "Expecting shader compilation and program linking to succeed. Resulting program will not be executed." << tcu::TestLog::EndMessage;
			break;

		default:
			DE_ASSERT(false);
			break;
	}
}

static void setUniformValue (const glw::Functions& gl, const std::vector<deUint32>& pipelinePrograms, const std::string& name, const Value& val, int arrayNdx, tcu::TestLog& log)
{
	bool foundAnyMatch = false;

	for (int programNdx = 0; programNdx < (int)pipelinePrograms.size(); ++programNdx)
	{
		const DataType	dataType	= val.type.getBasicType();
		const int		scalarSize	= getDataTypeScalarSize(dataType);
		const int		loc			= gl.getUniformLocation(pipelinePrograms[programNdx], name.c_str());
		const int		elemNdx		= arrayNdx * scalarSize;

		DE_ASSERT(elemNdx+scalarSize <= (int)val.elements.size());

		if (loc == -1)
			continue;

		foundAnyMatch = true;

		DE_STATIC_ASSERT(sizeof(Value::Element) == sizeof(glw::GLfloat));
		DE_STATIC_ASSERT(sizeof(Value::Element) == sizeof(glw::GLint));

		gl.useProgram(pipelinePrograms[programNdx]);

		switch (dataType)
		{
			case TYPE_FLOAT:		gl.uniform1fv(loc, 1, &val.elements[elemNdx].float32);						break;
			case TYPE_FLOAT_VEC2:	gl.uniform2fv(loc, 1, &val.elements[elemNdx].float32);						break;
			case TYPE_FLOAT_VEC3:	gl.uniform3fv(loc, 1, &val.elements[elemNdx].float32);						break;
			case TYPE_FLOAT_VEC4:	gl.uniform4fv(loc, 1, &val.elements[elemNdx].float32);						break;
			case TYPE_FLOAT_MAT2:	gl.uniformMatrix2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);		break;
			case TYPE_FLOAT_MAT3:	gl.uniformMatrix3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);		break;
			case TYPE_FLOAT_MAT4:	gl.uniformMatrix4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);		break;
			case TYPE_INT:			gl.uniform1iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_INT_VEC2:		gl.uniform2iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_INT_VEC3:		gl.uniform3iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_INT_VEC4:		gl.uniform4iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_BOOL:			gl.uniform1iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_BOOL_VEC2:	gl.uniform2iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_BOOL_VEC3:	gl.uniform3iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_BOOL_VEC4:	gl.uniform4iv(loc, 1, &val.elements[elemNdx].int32);						break;
			case TYPE_UINT:			gl.uniform1uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32);		break;
			case TYPE_UINT_VEC2:	gl.uniform2uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32);		break;
			case TYPE_UINT_VEC3:	gl.uniform3uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32);		break;
			case TYPE_UINT_VEC4:	gl.uniform4uiv(loc, 1, (const deUint32*)&val.elements[elemNdx].int32);		break;
			case TYPE_FLOAT_MAT2X3:	gl.uniformMatrix2x3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);	break;
			case TYPE_FLOAT_MAT2X4:	gl.uniformMatrix2x4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);	break;
			case TYPE_FLOAT_MAT3X2:	gl.uniformMatrix3x2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);	break;
			case TYPE_FLOAT_MAT3X4:	gl.uniformMatrix3x4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);	break;
			case TYPE_FLOAT_MAT4X2:	gl.uniformMatrix4x2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);	break;
			case TYPE_FLOAT_MAT4X3:	gl.uniformMatrix4x3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);	break;

			case TYPE_SAMPLER_2D:
			case TYPE_SAMPLER_CUBE:
				DE_FATAL("implement!");
				break;

			default:
				DE_ASSERT(false);
		}
	}

	if (!foundAnyMatch)
		log << tcu::TestLog::Message << "WARNING // Uniform \"" << name << "\" location is not valid, location = -1. Cannot set value to the uniform." << tcu::TestLog::EndMessage;
}

static bool isTessellationPresent (const ShaderCaseSpecification& spec)
{
	if (spec.programs[0].sources.separable)
	{
		const deUint32 tessellationBits =	(1 << glu::SHADERTYPE_TESSELLATION_CONTROL)		|
											(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);

		for (int programNdx = 0; programNdx < (int)spec.programs.size(); ++programNdx)
			if (spec.programs[programNdx].activeStages & tessellationBits)
				return true;
		return false;
	}
	else
		return !spec.programs[0].sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].empty() ||
			   !spec.programs[0].sources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].empty();
}

static bool isTessellationSupported (const glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo)
{
	if (renderCtx.getType().getProfile() == PROFILE_ES)
	{
		const int	majorVer	= renderCtx.getType().getMajorVersion();
		const int	minorVer	= renderCtx.getType().getMinorVersion();

		return (majorVer > 3) || (majorVer == 3 && minorVer >= 2) ||
			   ctxInfo.isExtensionSupported("GL_EXT_tessellation_shader");
	}
	else
		return false;
}

static bool checkPixels (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& surface)
{
	bool	allWhite		= true;
	bool	allBlack		= true;
	bool	anyUnexpected	= false;

	for (int y = 0; y < surface.getHeight(); y++)
	{
		for (int x = 0; x < surface.getWidth(); x++)
		{
			const tcu::IVec4	pixel		 = surface.getPixelInt(x, y);
			// Note: we really do not want to involve alpha in the check comparison
			// \todo [2010-09-22 kalle] Do we know that alpha would be one? If yes, could use color constants white and black.
			const bool			isWhite		 = (pixel[0] == 255) && (pixel[1] == 255) && (pixel[2] == 255);
			const bool			isBlack		 = (pixel[0] ==   0) && (pixel[1] ==   0) && (pixel[2] ==   0);

			allWhite		= allWhite && isWhite;
			allBlack		= allBlack && isBlack;
			anyUnexpected	= anyUnexpected || (!isWhite && !isBlack);
		}
	}

	if (!allWhite)
	{
		if (anyUnexpected)
			log << TestLog::Message << "WARNING: expecting all rendered pixels to be white or black, but got other colors as well!" << TestLog::EndMessage;
		else if (!allBlack)
			log << TestLog::Message << "WARNING: got inconsistent results over the image, when all pixels should be the same color!" << TestLog::EndMessage;

		return false;
	}

	return true;
}

bool ShaderLibraryCase::execute (void)
{
	const float							quadSize				= 1.0f;
	static const float					s_positions[4*4]		=
	{
		-quadSize, -quadSize, 0.0f, 1.0f,
		-quadSize, +quadSize, 0.0f, 1.0f,
		+quadSize, -quadSize, 0.0f, 1.0f,
		+quadSize, +quadSize, 0.0f, 1.0f
	};

	static const deUint16				s_indices[2*3]			=
	{
		0, 1, 2,
		1, 3, 2
	};

	TestLog&							log						= m_testCtx.getLog();
	const glw::Functions&				gl						= m_renderCtx.getFunctions();

	// Compute viewport.
	const tcu::RenderTarget&			renderTarget			= m_renderCtx.getRenderTarget();
	de::Random							rnd						(deStringHash(getName()));
	const int							width					= deMin32(renderTarget.getWidth(),	VIEWPORT_WIDTH);
	const int							height					= deMin32(renderTarget.getHeight(),	VIEWPORT_HEIGHT);
	const int							viewportX				= rnd.getInt(0, renderTarget.getWidth()  - width);
	const int							viewportY				= rnd.getInt(0, renderTarget.getHeight() - height);
	const int							numVerticesPerDraw		= 4;
	const bool							tessellationPresent		= isTessellationPresent(m_spec);
	const bool							separablePrograms		= m_spec.programs[0].sources.separable;

	bool								allCompilesOk			= true;
	bool								allLinksOk				= true;
	const char*							failReason				= DE_NULL;

	vector<ProgramSources>				specializedSources		(m_spec.programs.size());

	deUint32							vertexProgramID			= -1;
	vector<deUint32>					pipelineProgramIDs;
	vector<SharedPtr<ShaderProgram> >	programs;
	SharedPtr<ProgramPipeline>			programPipeline;

	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): start");

	if(isCapabilityRequired(CAPABILITY_ONLY_GLSL_ES_100_SUPPORT, m_spec))
	{
		// GL_MAJOR_VERSION query does not exist on GLES2
		// so succeeding query implies GLES3+ hardware.
		glw::GLint majorVersion = 0;
		gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
		if (gl.getError() == GL_NO_ERROR)
			return true;
	}

	if(isCapabilityRequired(CAPABILITY_EXACTLY_ONE_DRAW_BUFFER, m_spec))
	{
		// on unextended ES2 there is only one draw buffer
		// and there is no GL_MAX_DRAW_BUFFERS query
		glw::GLint maxDrawBuffers = 0;
		gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
		if ((gl.getError() == GL_NO_ERROR) && (maxDrawBuffers > 1))
			throw tcu::NotSupportedError("Test requires exactly one draw buffer");
	}

	// Specialize shaders
	if (m_spec.caseType == CASETYPE_VERTEX_ONLY)
	{
		const vector<RequiredExtension>	reqExt	= checkAndSpecializeExtensions(m_spec.programs[0].requiredExtensions, m_contextInfo);

		DE_ASSERT(m_spec.programs.size() == 1 && m_spec.programs[0].sources.sources[SHADERTYPE_VERTEX].size() == 1);
		specializedSources[0] << glu::VertexSource(specializeVertexShader(m_spec, m_spec.programs[0].sources.sources[SHADERTYPE_VERTEX][0], reqExt))
							  << glu::FragmentSource(genFragmentShader(m_spec));
	}
	else if (m_spec.caseType == CASETYPE_FRAGMENT_ONLY)
	{
		const vector<RequiredExtension>	reqExt	= checkAndSpecializeExtensions(m_spec.programs[0].requiredExtensions, m_contextInfo);

		DE_ASSERT(m_spec.programs.size() == 1 && m_spec.programs[0].sources.sources[SHADERTYPE_FRAGMENT].size() == 1);
		specializedSources[0] << glu::VertexSource(genVertexShader(m_spec))
							  << glu::FragmentSource(specializeFragmentShader(m_spec, m_spec.programs[0].sources.sources[SHADERTYPE_FRAGMENT][0], reqExt));
	}
	else
	{
		DE_ASSERT(m_spec.caseType == CASETYPE_COMPLETE);

		const int	maxPatchVertices	= isTessellationPresent(m_spec) && isTessellationSupported(m_renderCtx, m_contextInfo)
										? m_contextInfo.getInt(GL_MAX_PATCH_VERTICES) : 0;

		for (size_t progNdx = 0; progNdx < m_spec.programs.size(); progNdx++)
		{
			const ProgramSpecializationParams	progSpecParams	(m_spec, checkAndSpecializeExtensions(m_spec.programs[progNdx].requiredExtensions, m_contextInfo), maxPatchVertices);

			specializeProgramSources(specializedSources[progNdx], m_spec.programs[progNdx].sources, progSpecParams);
		}
	}

	if (!separablePrograms)
	{
		de::SharedPtr<glu::ShaderProgram>	program		(new glu::ShaderProgram(m_renderCtx, specializedSources[0]));

		vertexProgramID = program->getProgram();
		pipelineProgramIDs.push_back(program->getProgram());
		programs.push_back(program);

		// Check that compile/link results are what we expect.

		DE_STATIC_ASSERT(glu::SHADERTYPE_VERTEX == 0);
		for (int stage = glu::SHADERTYPE_VERTEX; stage < glu::SHADERTYPE_LAST; ++stage)
			if (program->hasShader((glu::ShaderType)stage) && !program->getShaderInfo((glu::ShaderType)stage).compileOk)
				allCompilesOk = false;

		if (!program->getProgramInfo().linkOk)
			allLinksOk = false;

		log << *program;
	}
	else
	{
		// Separate programs
		for (size_t programNdx = 0; programNdx < m_spec.programs.size(); ++programNdx)
		{
			de::SharedPtr<glu::ShaderProgram> program(new glu::ShaderProgram(m_renderCtx, specializedSources[programNdx]));

			if (m_spec.programs[programNdx].activeStages & (1u << glu::SHADERTYPE_VERTEX))
				vertexProgramID = program->getProgram();

			pipelineProgramIDs.push_back(program->getProgram());
			programs.push_back(program);

			// Check that compile/link results are what we expect.

			DE_STATIC_ASSERT(glu::SHADERTYPE_VERTEX == 0);
			for (int stage = glu::SHADERTYPE_VERTEX; stage < glu::SHADERTYPE_LAST; ++stage)
				if (program->hasShader((glu::ShaderType)stage) && !program->getShaderInfo((glu::ShaderType)stage).compileOk)
					allCompilesOk = false;

			if (!program->getProgramInfo().linkOk)
				allLinksOk = false;

			// Log program and active stages
			{
				const tcu::ScopedLogSection	section		(log, "Program", "Program " + de::toString(programNdx+1));
				tcu::MessageBuilder			builder		(&log);
				bool						firstStage	= true;

				builder << "Pipeline uses stages: ";
				for (int stage = glu::SHADERTYPE_VERTEX; stage < glu::SHADERTYPE_LAST; ++stage)
				{
					if (m_spec.programs[programNdx].activeStages & (1u << stage))
					{
						if (!firstStage)
							builder << ", ";
						builder << glu::getShaderTypeName((glu::ShaderType)stage);
						firstStage = true;
					}
				}
				builder << tcu::TestLog::EndMessage;

				log << *program;
			}
		}
	}

	switch (m_spec.expectResult)
	{
		case EXPECT_PASS:
		case EXPECT_VALIDATION_FAIL:
		case EXPECT_BUILD_SUCCESSFUL:
			if (!allCompilesOk)
				failReason = "expected shaders to compile and link properly, but failed to compile.";
			else if (!allLinksOk)
				failReason = "expected shaders to compile and link properly, but failed to link.";
			break;

		case EXPECT_COMPILE_FAIL:
			if (allCompilesOk && !allLinksOk)
				failReason = "expected compilation to fail, but shaders compiled and link failed.";
			else if (allCompilesOk)
				failReason = "expected compilation to fail, but shaders compiled correctly.";
			break;

		case EXPECT_LINK_FAIL:
			if (!allCompilesOk)
				failReason = "expected linking to fail, but unable to compile.";
			else if (allLinksOk)
				failReason = "expected linking to fail, but passed.";
			break;

		case EXPECT_COMPILE_LINK_FAIL:
			if (allCompilesOk && allLinksOk)
				failReason = "expected compile or link to fail, but passed.";
			break;

		default:
			DE_ASSERT(false);
			return false;
	}

	if (failReason != DE_NULL)
	{
		// \todo [2010-06-07 petri] These should be handled in the test case?
		log << TestLog::Message << "ERROR: " << failReason << TestLog::EndMessage;

		if (isCapabilityRequired(CAPABILITY_FULL_GLSL_ES_100_SUPPORT, m_spec))
		{
			log	<< TestLog::Message
				<< "Assuming build failure is caused by implementation not supporting full GLSL ES 100 specification, which is not required."
				<< TestLog::EndMessage;

			if (allCompilesOk && !allLinksOk)
			{
				// Used features are detectable at compile time. If implementation parses shader
				// at link time, report it as quality warning.
				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, failReason);
			}
			else
				m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Full GLSL ES 100 is not supported");
		}
		else if (m_spec.expectResult == EXPECT_COMPILE_FAIL && allCompilesOk && !allLinksOk)
		{
			// If implementation parses shader at link time, report it as quality warning.
			m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, failReason);
		}
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failReason);
		return false;
	}

	// Return if shader is not intended to be run
	if (m_spec.expectResult == EXPECT_COMPILE_FAIL		||
		m_spec.expectResult == EXPECT_COMPILE_LINK_FAIL	||
		m_spec.expectResult == EXPECT_LINK_FAIL			||
		m_spec.expectResult == EXPECT_BUILD_SUCCESSFUL)
		return true;

	// Setup viewport.
	gl.viewport(viewportX, viewportY, width, height);

	if (separablePrograms)
	{
		programPipeline = de::SharedPtr<glu::ProgramPipeline>(new glu::ProgramPipeline(m_renderCtx));

		// Setup pipeline
		gl.bindProgramPipeline(programPipeline->getPipeline());
		for (int programNdx = 0; programNdx < (int)m_spec.programs.size(); ++programNdx)
		{
			deUint32 shaderFlags = 0;
			for (int stage = glu::SHADERTYPE_VERTEX; stage < glu::SHADERTYPE_LAST; ++stage)
				if (m_spec.programs[programNdx].activeStages & (1u << stage))
					shaderFlags |= glu::getGLShaderTypeBit((glu::ShaderType)stage);

			programPipeline->useProgramStages(shaderFlags, pipelineProgramIDs[programNdx]);
		}

		programPipeline->activeShaderProgram(vertexProgramID);
		GLU_EXPECT_NO_ERROR(gl.getError(), "setup pipeline");
	}
	else
	{
		// Start using program
		gl.useProgram(vertexProgramID);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
	}

	// Fetch location for positions positions.
	int positionLoc = gl.getAttribLocation(vertexProgramID, "dEQP_Position");
	if (positionLoc == -1)
	{
		string errStr = string("no location found for attribute 'dEQP_Position'");
		TCU_FAIL(errStr.c_str());
	}

	// Iterate all value blocks.
	{
		const ValueBlock&	valueBlock		= m_spec.values;

		// always render at least one pass even if there is no input/output data
		const int			numRenderPasses	= valueBlock.outputs.empty() ? 1 : (int)valueBlock.outputs[0].elements.size() / valueBlock.outputs[0].type.getScalarSize();

		// Iterate all array sub-cases.
		for (int arrayNdx = 0; arrayNdx < numRenderPasses; arrayNdx++)
		{
			vector<VertexArrayBinding>	vertexArrays;
			int							attribValueNdx		= 0;
			vector<vector<float> >		attribValues		(valueBlock.inputs.size());
			glw::GLenum					postDrawError;
			BeforeDrawValidator			beforeDrawValidator	(gl,
															 (separablePrograms) ? (programPipeline->getPipeline())			: (vertexProgramID),
															 (separablePrograms) ? (BeforeDrawValidator::TARGETTYPE_PIPELINE)	: (BeforeDrawValidator::TARGETTYPE_PROGRAM));

			vertexArrays.push_back(va::Float(positionLoc, 4, numVerticesPerDraw, 0, &s_positions[0]));

			// Collect VA pointer for inputs
			for (size_t valNdx = 0; valNdx < valueBlock.inputs.size(); valNdx++)
			{
				const Value&		val			= valueBlock.inputs[valNdx];
				const char* const	valueName	= val.name.c_str();
				const DataType		dataType	= val.type.getBasicType();
				const int			scalarSize	= getDataTypeScalarSize(dataType);

				// Replicate values four times.
				std::vector<float>& scalars = attribValues[attribValueNdx++];
				scalars.resize(numVerticesPerDraw * scalarSize);
				if (isDataTypeFloatOrVec(dataType) || isDataTypeMatrix(dataType))
				{
					for (int repNdx = 0; repNdx < numVerticesPerDraw; repNdx++)
						for (int ndx = 0; ndx < scalarSize; ndx++)
							scalars[repNdx*scalarSize + ndx] = val.elements[arrayNdx*scalarSize + ndx].float32;
				}
				else
				{
					// convert to floats.
					for (int repNdx = 0; repNdx < numVerticesPerDraw; repNdx++)
					{
						for (int ndx = 0; ndx < scalarSize; ndx++)
						{
							float v = (float)val.elements[arrayNdx*scalarSize + ndx].int32;
							DE_ASSERT(val.elements[arrayNdx*scalarSize + ndx].int32 == (int)v);
							scalars[repNdx*scalarSize + ndx] = v;
						}
					}
				}

				// Attribute name prefix.
				string attribPrefix = "";
				// \todo [2010-05-27 petri] Should latter condition only apply for vertex cases (or actually non-fragment cases)?
				if ((m_spec.caseType == CASETYPE_FRAGMENT_ONLY) || (getDataTypeScalarType(dataType) != TYPE_FLOAT))
					attribPrefix = "a_";

				// Input always given as attribute.
				string attribName = attribPrefix + valueName;
				int attribLoc = gl.getAttribLocation(vertexProgramID, attribName.c_str());
				if (attribLoc == -1)
				{
					log << TestLog::Message << "Warning: no location found for attribute '" << attribName << "'" << TestLog::EndMessage;
					continue;
				}

				if (isDataTypeMatrix(dataType))
				{
					int numCols = getDataTypeMatrixNumColumns(dataType);
					int numRows = getDataTypeMatrixNumRows(dataType);
					DE_ASSERT(scalarSize == numCols*numRows);

					for (int i = 0; i < numCols; i++)
						vertexArrays.push_back(va::Float(attribLoc + i, numRows, numVerticesPerDraw, scalarSize*(int)sizeof(float), &scalars[i * numRows]));
				}
				else
				{
					DE_ASSERT(isDataTypeFloatOrVec(dataType) || isDataTypeIntOrIVec(dataType) || isDataTypeUintOrUVec(dataType) || isDataTypeBoolOrBVec(dataType));
					vertexArrays.push_back(va::Float(attribLoc, scalarSize, numVerticesPerDraw, 0, &scalars[0]));
				}

				GLU_EXPECT_NO_ERROR(gl.getError(), "set vertex attrib array");
			}

			GLU_EXPECT_NO_ERROR(gl.getError(), "before set uniforms");

			// set reference values for outputs.
			for (size_t valNdx = 0; valNdx < valueBlock.outputs.size(); valNdx++)
			{
				const Value&		val			= valueBlock.outputs[valNdx];
				const char* const	valueName	= val.name.c_str();

				// Set reference value.
				string refName = string("ref_") + valueName;
				setUniformValue(gl, pipelineProgramIDs, refName, val, arrayNdx, m_testCtx.getLog());
				GLU_EXPECT_NO_ERROR(gl.getError(), "set reference uniforms");
			}

			// set uniform values
			for (size_t valNdx = 0; valNdx < valueBlock.uniforms.size(); valNdx++)
			{
				const Value&		val			= valueBlock.uniforms[valNdx];
				const char* const	valueName	= val.name.c_str();

				setUniformValue(gl, pipelineProgramIDs, valueName, val, arrayNdx, m_testCtx.getLog());
				GLU_EXPECT_NO_ERROR(gl.getError(), "set uniforms");
			}

			// Clear.
			gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
			gl.clear(GL_COLOR_BUFFER_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "clear buffer");

			// Use program or pipeline
			if (separablePrograms)
				gl.useProgram(0);
			else
				gl.useProgram(vertexProgramID);

			// Draw.
			if (tessellationPresent)
			{
				gl.patchParameteri(GL_PATCH_VERTICES, 3);
				GLU_EXPECT_NO_ERROR(gl.getError(), "set patchParameteri(PATCH_VERTICES, 3)");
			}

			draw(m_renderCtx,
				 vertexProgramID,
				 (int)vertexArrays.size(),
				 &vertexArrays[0],
				 (tessellationPresent) ?
					(pr::Patches(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0])) :
					(pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0])),
				 (m_spec.expectResult == EXPECT_VALIDATION_FAIL) ?
					(&beforeDrawValidator) :
					(DE_NULL));

			postDrawError = gl.getError();

			if (m_spec.expectResult == EXPECT_PASS)
			{
				// Read back results.
				Surface			surface			(width, height);
				const float		w				= s_positions[3];
				const int		minY			= deCeilFloatToInt32 (((-quadSize / w) * 0.5f + 0.5f) * (float)height + 1.0f);
				const int		maxY			= deFloorFloatToInt32(((+quadSize / w) * 0.5f + 0.5f) * (float)height - 0.5f);
				const int		minX			= deCeilFloatToInt32 (((-quadSize / w) * 0.5f + 0.5f) * (float)width + 1.0f);
				const int		maxX			= deFloorFloatToInt32(((+quadSize / w) * 0.5f + 0.5f) * (float)width - 0.5f);

				GLU_EXPECT_NO_ERROR(postDrawError, "draw");

				glu::readPixels(m_renderCtx, viewportX, viewportY, surface.getAccess());
				GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");

				if (!checkPixels(log, tcu::getSubregion(surface.getAccess(), minX, minY, maxX-minX+1, maxY-minY+1)))
				{
					log << TestLog::Message << "INCORRECT RESULT for sub-case " << arrayNdx+1 << " of " << numRenderPasses << "):"
						<< TestLog::EndMessage;

					log << TestLog::Message << "Failing shader input/output values:" << TestLog::EndMessage;
					dumpValues(log, valueBlock, arrayNdx);

					// Dump image on failure.
					log << TestLog::Image("Result", "Rendered result image", surface);

					gl.useProgram(0);
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
					return false;
				}
			}
			else if (m_spec.expectResult == EXPECT_VALIDATION_FAIL)
			{
				log	<< TestLog::Message
					<< "Draw call generated error: "
					<< glu::getErrorStr(postDrawError) << " "
					<< ((postDrawError == GL_INVALID_OPERATION) ? ("(expected)") : ("(unexpected)")) << "\n"
					<< "Validate status: "
					<< glu::getBooleanStr(beforeDrawValidator.getValidateStatus()) << " "
					<< ((beforeDrawValidator.getValidateStatus() == GL_FALSE) ? ("(expected)") : ("(unexpected)")) << "\n"
					<< "Info log: "
					<< ((beforeDrawValidator.getInfoLog().empty()) ? ("[empty string]") : (beforeDrawValidator.getInfoLog())) << "\n"
					<< TestLog::EndMessage;

				// test result

				if (postDrawError != GL_NO_ERROR && postDrawError != GL_INVALID_OPERATION)
				{
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, ("Draw: got unexpected error: " + de::toString(glu::getErrorStr(postDrawError))).c_str());
					return false;
				}

				if (beforeDrawValidator.getValidateStatus() == GL_TRUE)
				{
					if (postDrawError == GL_NO_ERROR)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "expected validation and rendering to fail but validation and rendering succeeded");
					else if (postDrawError == GL_INVALID_OPERATION)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "expected validation and rendering to fail but validation succeeded (rendering failed as expected)");
					else
						DE_ASSERT(false);
					return false;
				}
				else if (beforeDrawValidator.getValidateStatus() == GL_FALSE && postDrawError == GL_NO_ERROR)
				{
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "expected validation and rendering to fail but rendering succeeded (validation failed as expected)");
					return false;
				}
				else if (beforeDrawValidator.getValidateStatus() == GL_FALSE && postDrawError == GL_INVALID_OPERATION)
				{
					// Validation does not depend on input values, no need to test all values
					return true;
				}
				else
					DE_ASSERT(false);
			}
			else
				DE_ASSERT(false);
		}
	}

	gl.useProgram(0);
	if (separablePrograms)
		gl.bindProgramPipeline(0);

	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): end");
	return true;
}

TestCase::IterateResult ShaderLibraryCase::iterate (void)
{
	// Initialize state to pass.
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	bool executeOk = execute();

	DE_ASSERT(executeOk ? m_testCtx.getTestResult() == QP_TEST_RESULT_PASS : m_testCtx.getTestResult() != QP_TEST_RESULT_PASS);
	DE_UNREF(executeOk);
	return TestCase::STOP;
}

} // gls
} // deqp
