/*-------------------------------------------------------------------------
 * 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 Multisample interpolation tests
 *//*--------------------------------------------------------------------*/

#include "es31fShaderMultisampleInterpolationTests.hpp"
#include "es31fMultisampleShaderRenderCase.hpp"
#include "tcuTestLog.hpp"
#include "tcuRGBA.hpp"
#include "tcuSurface.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuRenderTarget.hpp"
#include "gluContextInfo.hpp"
#include "gluShaderProgram.hpp"
#include "gluRenderContext.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deArrayUtil.hpp"
#include "deStringUtil.hpp"
#include "deMath.h"

#include <map>

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

static std::string specializeShader(const std::string& shaderSource, const glu::ContextType& contextType)
{
	const bool	isES32orGL45	= glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
								  glu::contextSupports(contextType, glu::ApiType::core(4, 5));

	std::map<std::string, std::string> args;
	args["GLSL_VERSION_DECL"]							= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(contextType));
	args["GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION"]	= isES32orGL45 ? "" : "#extension GL_OES_shader_multisample_interpolation : require\n";
	args["GLSL_EXT_SAMPLE_VARIABLES"]					= isES32orGL45 ? "" : "#extension GL_OES_sample_variables : require\n";

	return tcu::StringTemplate(shaderSource).specialize(args);
}

static bool checkSupport(Context& ctx)
{
	auto ctxType = ctx.getRenderContext().getType();
	return glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
		   glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
}

static bool verifyGreenImage (const tcu::Surface& image, tcu::TestLog& log)
{
	bool error = false;

	log << tcu::TestLog::Message << "Verifying result image, expecting green." << tcu::TestLog::EndMessage;

	// all pixels must be green

	for (int y = 0; y < image.getHeight(); ++y)
	for (int x = 0; x < image.getWidth(); ++x)
	{
		const tcu::RGBA color			= image.getPixel(x, y);
		const int		greenThreshold	= 8;

		if (color.getRed() > 0 || color.getGreen() < 255-greenThreshold || color.getBlue() > 0)
			error = true;
	}

	if (error)
		log	<< tcu::TestLog::Image("ResultImage", "Result Image", image.getAccess())
			<< tcu::TestLog::Message
			<< "Image verification failed."
			<< tcu::TestLog::EndMessage;
	else
		log	<< tcu::TestLog::Image("ResultImage", "Result Image", image.getAccess())
			<< tcu::TestLog::Message
			<< "Image verification passed."
			<< tcu::TestLog::EndMessage;

	return !error;
}

class MultisampleShadeCountRenderCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
{
public:
						MultisampleShadeCountRenderCase		(Context& context, const char* name, const char* description, int numSamples, RenderTarget target);
	virtual				~MultisampleShadeCountRenderCase	(void);

	void				init								(void);

private:
	enum
	{
		RENDER_SIZE = 128
	};

	virtual std::string	getIterationDescription				(int iteration) const;
	bool				verifyImage							(const tcu::Surface& resultImage);
};

MultisampleShadeCountRenderCase::MultisampleShadeCountRenderCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target)
	: MultisampleShaderRenderUtil::MultisampleRenderCase(context, name, description, numSamples, target, RENDER_SIZE, MultisampleShaderRenderUtil::MultisampleRenderCase::FLAG_PER_ITERATION_SHADER)
{
	m_numIterations = -1; // must be set by deriving class
}

MultisampleShadeCountRenderCase::~MultisampleShadeCountRenderCase (void)
{
}

void MultisampleShadeCountRenderCase::init (void)
{
	// requirements
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");

	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
}

std::string	MultisampleShadeCountRenderCase::getIterationDescription (int iteration) const
{
	// must be overriden
	DE_UNREF(iteration);
	DE_ASSERT(false);
	return "";
}

bool MultisampleShadeCountRenderCase::verifyImage (const tcu::Surface& resultImage)
{
	const bool				isSingleSampleTarget	= (m_renderTarget != TARGET_DEFAULT && m_numRequestedSamples == 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() <= 1);
	const int				numShadesRequired		= (isSingleSampleTarget) ? (2) : (m_numTargetSamples + 1);
	const int				rareThreshold			= 100;
	int						rareCount				= 0;
	std::map<deUint32, int>	shadeFrequency;

	m_testCtx.getLog()
		<< tcu::TestLog::Image("ResultImage", "Result Image", resultImage.getAccess())
		<< tcu::TestLog::Message
		<< "Verifying image has (at least) " << numShadesRequired << " different shades.\n"
		<< "Excluding pixels with no full coverage (pixels on the shared edge of the triangle pair)."
		<< tcu::TestLog::EndMessage;

	for (int y = 0; y < RENDER_SIZE; ++y)
	for (int x = 0; x < RENDER_SIZE; ++x)
	{
		const tcu::RGBA	color	= resultImage.getPixel(x, y);
		const deUint32	packed	= ((deUint32)color.getRed()) + ((deUint32)color.getGreen() << 8) + ((deUint32)color.getGreen() << 16);

		// on the triangle edge, skip
		if (x == y)
			continue;

		if (shadeFrequency.find(packed) == shadeFrequency.end())
			shadeFrequency[packed] = 1;
		else
			shadeFrequency[packed] = shadeFrequency[packed] + 1;
	}

	for (std::map<deUint32, int>::const_iterator it = shadeFrequency.begin(); it != shadeFrequency.end(); ++it)
		if (it->second < rareThreshold)
			rareCount++;

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Found " << (int)shadeFrequency.size() << " different shades.\n"
		<< "\tRare (less than " << rareThreshold << " pixels): " << rareCount << "\n"
		<< "\tCommon: " << (int)shadeFrequency.size() - rareCount << "\n"
		<< tcu::TestLog::EndMessage;

	if ((int)shadeFrequency.size() < numShadesRequired)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Image verification failed." << tcu::TestLog::EndMessage;
		return false;
	}
	return true;
}

class SampleQualifierRenderCase : public MultisampleShadeCountRenderCase
{
public:
				SampleQualifierRenderCase	(Context& context, const char* name, const char* description, int numSamples, RenderTarget target);
				~SampleQualifierRenderCase	(void);

	void		init						(void);

private:
	std::string	genVertexSource				(int numTargetSamples) const;
	std::string	genFragmentSource			(int numTargetSamples) const;
	std::string	getIterationDescription		(int iteration) const;
};

SampleQualifierRenderCase::SampleQualifierRenderCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target)
	: MultisampleShadeCountRenderCase(context, name, description, numSamples, target)
{
	m_numIterations = 6; // float, vec2, .3, .4, array, struct
}

SampleQualifierRenderCase::~SampleQualifierRenderCase (void)
{
}

void SampleQualifierRenderCase::init (void)
{
	const bool isSingleSampleTarget = (m_renderTarget != TARGET_DEFAULT && m_numRequestedSamples == 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() <= 1);

	// test purpose and expectations
	if (isSingleSampleTarget)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying that a sample-qualified varying is given different values for different samples.\n"
			<< "	Render high-frequency function, map result to black/white.\n"
			<< "	=> Resulting image image should contain both black and white pixels.\n"
			<< tcu::TestLog::EndMessage;
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying that a sample-qualified varying is given different values for different samples.\n"
			<< "	Render high-frequency function, map result to black/white.\n"
			<< "	=> Resulting image should contain n+1 shades of gray, n = sample count.\n"
			<< tcu::TestLog::EndMessage;
	}

	MultisampleShadeCountRenderCase::init();
}

std::string	SampleQualifierRenderCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"in highp vec4 a_position;\n";

	if (m_iteration == 0)
		buf << "sample out highp float v_input;\n";
	else if (m_iteration == 1)
		buf << "sample out highp vec2 v_input;\n";
	else if (m_iteration == 2)
		buf << "sample out highp vec3 v_input;\n";
	else if (m_iteration == 3)
		buf << "sample out highp vec4 v_input;\n";
	else if (m_iteration == 4)
		buf << "sample out highp float[2] v_input;\n";
	else if (m_iteration == 5)
		buf << "struct VaryingStruct { highp float a; highp float b; };\n"
			   "sample out VaryingStruct v_input;\n";
	else
		DE_ASSERT(false);

	buf <<	"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n";

	if (m_iteration == 0)
		buf << "	v_input = a_position.x + exp(a_position.y) + step(0.9, a_position.x)*step(a_position.y, -0.9)*8.0;\n";
	else if (m_iteration == 1)
		buf << "	v_input = a_position.xy;\n";
	else if (m_iteration == 2)
		buf << "	v_input = vec3(a_position.xy, a_position.x * 2.0 - a_position.y);\n";
	else if (m_iteration == 3)
		buf << "	v_input = vec4(a_position.xy, a_position.x * 2.0 - a_position.y, a_position.x*a_position.y);\n";
	else if (m_iteration == 4)
		buf << "	v_input[0] = a_position.x;\n"
			   "	v_input[1] = a_position.y;\n";
	else if (m_iteration == 5)
		buf << "	v_input.a = a_position.x;\n"
			   "	v_input.b = a_position.y;\n";
	else
		DE_ASSERT(false);

	buf <<	"}";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string	SampleQualifierRenderCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}";

	if (m_iteration == 0)
		buf << "sample in highp float v_input;\n";
	else if (m_iteration == 1)
		buf << "sample in highp vec2 v_input;\n";
	else if (m_iteration == 2)
		buf << "sample in highp vec3 v_input;\n";
	else if (m_iteration == 3)
		buf << "sample in highp vec4 v_input;\n";
	else if (m_iteration == 4)
		buf << "sample in highp float[2] v_input;\n";
	else if (m_iteration == 5)
		buf << "struct VaryingStruct { highp float a; highp float b; };\n"
			   "sample in VaryingStruct v_input;\n";
	else
		DE_ASSERT(false);

	buf <<	"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n";

	if (m_iteration == 0)
		buf << "	highp float field = exp(v_input) + v_input*v_input;\n";
	else if (m_iteration == 1)
		buf << "	highp float field = dot(v_input.xy, v_input.xy) + dot(21.0 * v_input.xx, sin(3.1 * v_input.xy));\n";
	else if (m_iteration == 2)
		buf << "	highp float field = dot(v_input.xy, v_input.xy) + dot(21.0 * v_input.zx, sin(3.1 * v_input.zy));\n";
	else if (m_iteration == 3)
		buf << "	highp float field = dot(v_input.xy, v_input.zw) + dot(21.0 * v_input.zy, sin(3.1 * v_input.zw));\n";
	else if (m_iteration == 4)
		buf << "	highp float field = dot(vec2(v_input[0], v_input[1]), vec2(v_input[0], v_input[1])) + dot(21.0 * vec2(v_input[0]), sin(3.1 * vec2(v_input[0], v_input[1])));\n";
	else if (m_iteration == 5)
		buf << "	highp float field = dot(vec2(v_input.a, v_input.b), vec2(v_input.a, v_input.b)) + dot(21.0 * vec2(v_input.a), sin(3.1 * vec2(v_input.a, v_input.b)));\n";
	else
		DE_ASSERT(false);

	buf <<	"	fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
			"\n"
			"	if (fract(field) > 0.5)\n"
			"		fragColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
			"}";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string	SampleQualifierRenderCase::getIterationDescription (int iteration) const
{
	if (iteration == 0)
		return "Test with float varying";
	else if (iteration == 1)
		return "Test with vec2 varying";
	else if (iteration == 2)
		return "Test with vec3 varying";
	else if (iteration == 3)
		return "Test with vec4 varying";
	else if (iteration == 4)
		return "Test with array varying";
	else if (iteration == 5)
		return "Test with struct varying";

	DE_ASSERT(false);
	return "";
}

class InterpolateAtSampleRenderCase : public MultisampleShadeCountRenderCase
{
public:
	enum IndexingMode
	{
		INDEXING_STATIC,
		INDEXING_DYNAMIC,

		INDEXING_LAST
	};
						InterpolateAtSampleRenderCase	(Context& context, const char* name, const char* description, int numSamples, RenderTarget target, IndexingMode mode);
						~InterpolateAtSampleRenderCase	(void);

	void				init							(void);
	void				preDraw							(void);

private:
	std::string			genVertexSource					(int numTargetSamples) const;
	std::string			genFragmentSource				(int numTargetSamples) const;
	std::string			getIterationDescription			(int iteration) const;

	const IndexingMode	m_indexMode;
};

InterpolateAtSampleRenderCase::InterpolateAtSampleRenderCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target, IndexingMode mode)
	: MultisampleShadeCountRenderCase	(context, name, description, numSamples, target)
	, m_indexMode						(mode)
{
	DE_ASSERT(mode < INDEXING_LAST);

	m_numIterations = 5; // float, vec2, .3, .4, array
}

InterpolateAtSampleRenderCase::~InterpolateAtSampleRenderCase (void)
{
}

void InterpolateAtSampleRenderCase::init (void)
{
	const bool isSingleSampleTarget = (m_renderTarget != TARGET_DEFAULT && m_numRequestedSamples == 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() <= 1);

	// test purpose and expectations
	if (isSingleSampleTarget)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying that a interpolateAtSample returns different values for different samples.\n"
			<< "	Render high-frequency function, map result to black/white.\n"
			<< "	=> Resulting image image should contain both black and white pixels.\n"
			<< tcu::TestLog::EndMessage;
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying that a interpolateAtSample returns different values for different samples.\n"
			<< "	Render high-frequency function, map result to black/white.\n"
			<< "	=> Resulting image should contain n+1 shades of gray, n = sample count.\n"
			<< tcu::TestLog::EndMessage;
	}

	MultisampleShadeCountRenderCase::init();
}

void InterpolateAtSampleRenderCase::preDraw (void)
{
	if (m_indexMode == INDEXING_DYNAMIC)
	{
		const deInt32			range		= m_numTargetSamples;
		const deInt32			offset		= 1;
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const deInt32			offsetLoc	= gl.getUniformLocation(m_program->getProgram(), "u_offset");
		const deInt32			rangeLoc	= gl.getUniformLocation(m_program->getProgram(), "u_range");

		if (offsetLoc == -1)
			throw tcu::TestError("Location of u_offset was -1");
		if (rangeLoc == -1)
			throw tcu::TestError("Location of u_range was -1");

		gl.uniform1i(offsetLoc, 0);
		gl.uniform1i(rangeLoc, m_numTargetSamples);
		GLU_EXPECT_NO_ERROR(gl.getError(), "set uniforms");

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Set u_offset = " << offset << "\n"
			<< "Set u_range = " << range
			<< tcu::TestLog::EndMessage;
	}
}

std::string InterpolateAtSampleRenderCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n";

	if (m_iteration == 0)
		buf << "out highp float v_input;\n";
	else if (m_iteration == 1)
		buf << "out highp vec2 v_input;\n";
	else if (m_iteration == 2)
		buf << "out highp vec3 v_input;\n";
	else if (m_iteration == 3)
		buf << "out highp vec4 v_input;\n";
	else if (m_iteration == 4)
		buf << "out highp vec2[2] v_input;\n";
	else
		DE_ASSERT(false);

	buf <<	"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n";

	if (m_iteration == 0)
		buf << "	v_input = a_position.x + exp(a_position.y) + step(0.9, a_position.x)*step(a_position.y, -0.9)*8.0;\n";
	else if (m_iteration == 1)
		buf << "	v_input = a_position.xy;\n";
	else if (m_iteration == 2)
		buf << "	v_input = vec3(a_position.xy, a_position.x * 2.0 - a_position.y);\n";
	else if (m_iteration == 3)
		buf << "	v_input = vec4(a_position.xy, a_position.x * 2.0 - a_position.y, a_position.x*a_position.y);\n";
	else if (m_iteration == 4)
		buf << "	v_input[0] = a_position.yx + vec2(0.5, 0.5);\n"
			   "	v_input[1] = a_position.xy;\n";
	else
		DE_ASSERT(false);

	buf <<	"}";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string InterpolateAtSampleRenderCase::genFragmentSource (int numTargetSamples) const
{
	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}";

	if (m_iteration == 0)
		buf << "in highp float v_input;\n";
	else if (m_iteration == 1)
		buf << "in highp vec2 v_input;\n";
	else if (m_iteration == 2)
		buf << "in highp vec3 v_input;\n";
	else if (m_iteration == 3)
		buf << "in highp vec4 v_input;\n";
	else if (m_iteration == 4)
		buf << "in highp vec2[2] v_input;\n";
	else
		DE_ASSERT(false);

	buf << "layout(location = 0) out mediump vec4 fragColor;\n";

	if (m_indexMode == INDEXING_DYNAMIC)
		buf <<	"uniform highp int u_offset;\n"
				"uniform highp int u_range;\n";

	buf <<	"void main (void)\n"
			"{\n"
			"	mediump int coverage = 0;\n"
			"\n";

	if (m_indexMode == INDEXING_STATIC)
	{
		for (int ndx = 0; ndx < numTargetSamples; ++ndx)
		{
			if (m_iteration == 0)
				buf <<	"	highp float sampleInput" << ndx << " = interpolateAtSample(v_input, " << ndx << ");\n";
			else if (m_iteration == 1)
				buf <<	"	highp vec2 sampleInput" << ndx << " = interpolateAtSample(v_input, " << ndx << ");\n";
			else if (m_iteration == 2)
				buf <<	"	highp vec3 sampleInput" << ndx << " = interpolateAtSample(v_input, " << ndx << ");\n";
			else if (m_iteration == 3)
				buf <<	"	highp vec4 sampleInput" << ndx << " = interpolateAtSample(v_input, " << ndx << ");\n";
			else if (m_iteration == 4)
				buf <<	"	highp vec2 sampleInput" << ndx << " = interpolateAtSample(v_input[1], " << ndx << ");\n";
			else
				DE_ASSERT(false);
		}
		buf <<	"\n";

		for (int ndx = 0; ndx < numTargetSamples; ++ndx)
		{
			if (m_iteration == 0)
				buf << "	highp float field" << ndx << " = exp(sampleInput" << ndx << ") + sampleInput" << ndx << "*sampleInput" << ndx << ";\n";
			else if (m_iteration == 1 || m_iteration == 4)
				buf << "	highp float field" << ndx << " = dot(sampleInput" << ndx << ", sampleInput" << ndx << ") + dot(21.0 * sampleInput" << ndx << ".xx, sin(3.1 * sampleInput" << ndx << "));\n";
			else if (m_iteration == 2)
				buf << "	highp float field" << ndx << " = dot(sampleInput" << ndx << ".xy, sampleInput" << ndx << ".xy) + dot(21.0 * sampleInput" << ndx << ".zx, sin(3.1 * sampleInput" << ndx << ".zy));\n";
			else if (m_iteration == 3)
				buf << "	highp float field" << ndx << " = dot(sampleInput" << ndx << ".xy, sampleInput" << ndx << ".zw) + dot(21.0 * sampleInput" << ndx << ".zy, sin(3.1 * sampleInput" << ndx << ".zw));\n";
			else
				DE_ASSERT(false);
		}
		buf <<	"\n";

		for (int ndx = 0; ndx < numTargetSamples; ++ndx)
			buf <<	"	if (fract(field" << ndx << ") <= 0.5)\n"
					"		++coverage;\n";
	}
	else if (m_indexMode == INDEXING_DYNAMIC)
	{
		buf <<	"	for (int ndx = 0; ndx < " << numTargetSamples << "; ++ndx)\n"
				"	{\n";

		if (m_iteration == 0)
			buf <<	"		highp float sampleInput = interpolateAtSample(v_input, (u_offset + ndx) % u_range);\n";
		else if (m_iteration == 1)
			buf <<	"		highp vec2 sampleInput = interpolateAtSample(v_input, (u_offset + ndx) % u_range);\n";
		else if (m_iteration == 2)
			buf <<	"		highp vec3 sampleInput = interpolateAtSample(v_input, (u_offset + ndx) % u_range);\n";
		else if (m_iteration == 3)
			buf <<	"		highp vec4 sampleInput = interpolateAtSample(v_input, (u_offset + ndx) % u_range);\n";
		else if (m_iteration == 4)
			buf <<	"		highp vec2 sampleInput = interpolateAtSample(v_input[1], (u_offset + ndx) % u_range);\n";
		else
			DE_ASSERT(false);

		if (m_iteration == 0)
			buf << "		highp float field = exp(sampleInput) + sampleInput*sampleInput;\n";
		else if (m_iteration == 1 || m_iteration == 4)
			buf << "		highp float field = dot(sampleInput, sampleInput) + dot(21.0 * sampleInput.xx, sin(3.1 * sampleInput));\n";
		else if (m_iteration == 2)
			buf << "		highp float field = dot(sampleInput.xy, sampleInput.xy) + dot(21.0 * sampleInput.zx, sin(3.1 * sampleInput.zy));\n";
		else if (m_iteration == 3)
			buf << "		highp float field = dot(sampleInput.xy, sampleInput.zw) + dot(21.0 * sampleInput.zy, sin(3.1 * sampleInput.zw));\n";
		else
			DE_ASSERT(false);

		buf <<	"		if (fract(field) <= 0.5)\n"
				"			++coverage;\n"
				"	}\n";
	}

	buf <<	"	fragColor = vec4(vec3(float(coverage) / float(" << numTargetSamples << ")), 1.0);\n"
			"}";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string InterpolateAtSampleRenderCase::getIterationDescription (int iteration) const
{
	if (iteration == 0)
		return "Test with float varying";
	else if (iteration < 4)
		return "Test with vec" + de::toString(iteration+1) + " varying";
	else if (iteration == 4)
		return "Test with array varying";

	DE_ASSERT(false);
	return "";
}

class SingleSampleInterpolateAtSampleCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
{
public:
	enum SampleCase
	{
		SAMPLE_0 = 0,
		SAMPLE_N,

		SAMPLE_LAST
	};

						SingleSampleInterpolateAtSampleCase		(Context& context, const char* name, const char* description, int numSamples, RenderTarget target, SampleCase sampleCase);
	virtual				~SingleSampleInterpolateAtSampleCase	(void);

	void				init									(void);

private:
	enum
	{
		RENDER_SIZE = 32
	};

	std::string			genVertexSource							(int numTargetSamples) const;
	std::string			genFragmentSource						(int numTargetSamples) const;
	bool				verifyImage								(const tcu::Surface& resultImage);

	const SampleCase	m_sampleCase;
};

SingleSampleInterpolateAtSampleCase::SingleSampleInterpolateAtSampleCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target, SampleCase sampleCase)
	: MultisampleShaderRenderUtil::MultisampleRenderCase	(context, name, description, numSamples, target, RENDER_SIZE)
	, m_sampleCase											(sampleCase)
{
	DE_ASSERT(numSamples == 0);
	DE_ASSERT(sampleCase < SAMPLE_LAST);
}

SingleSampleInterpolateAtSampleCase::~SingleSampleInterpolateAtSampleCase (void)
{
}

void SingleSampleInterpolateAtSampleCase::init (void)
{
	// requirements
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");
	if (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() > 1)
		TCU_THROW(NotSupportedError, "Non-multisample framebuffer required");

	// test purpose and expectations
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying that using interpolateAtSample with multisample buffers not available returns sample evaluated at the center of the pixel.\n"
		<< "	Interpolate varying containing screen space location.\n"
		<< "	=> fract(screen space location) should be (about) (0.5, 0.5)\n"
		<< tcu::TestLog::EndMessage;

	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
}

std::string SingleSampleInterpolateAtSampleCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n"
			"out highp vec2 v_position;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_position = (a_position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(" << (int)RENDER_SIZE << ".0, " << (int)RENDER_SIZE << ".0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string SingleSampleInterpolateAtSampleCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"in highp vec2 v_position;\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	const highp float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits + 0.03125 for other errors\n"; // 0.03125 = mediump epsilon when value = 32 (RENDER_SIZE)

	if (m_sampleCase == SAMPLE_0)
	{
		buf <<	"	highp vec2 samplePosition = interpolateAtSample(v_position, 0);\n"
				"	highp vec2 positionInsideAPixel = fract(samplePosition);\n"
				"\n"
				"	if (abs(positionInsideAPixel.x - 0.5) <= threshold && abs(positionInsideAPixel.y - 0.5) <= threshold)\n"
				"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
				"	else\n"
				"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"}\n";
	}
	else if (m_sampleCase == SAMPLE_N)
	{
		buf <<	"	bool allOk = true;\n"
				"	for (int sampleNdx = 159; sampleNdx < 163; ++sampleNdx)\n"
				"	{\n"
				"		highp vec2 samplePosition = interpolateAtSample(v_position, sampleNdx);\n"
				"		highp vec2 positionInsideAPixel = fract(samplePosition);\n"
				"		if (abs(positionInsideAPixel.x - 0.5) > threshold || abs(positionInsideAPixel.y - 0.5) > threshold)\n"
				"			allOk = false;\n"
				"	}\n"
				"\n"
				"	if (allOk)\n"
				"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
				"	else\n"
				"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"}\n";
	}
	else
		DE_ASSERT(false);

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

bool SingleSampleInterpolateAtSampleCase::verifyImage (const tcu::Surface& resultImage)
{
	return verifyGreenImage(resultImage, m_testCtx.getLog());
}

class CentroidRenderCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
{
public:
									CentroidRenderCase	(Context& context, const char* name, const char* description, int numSamples, RenderTarget target, int renderSize);
	virtual							~CentroidRenderCase	(void);

	void							init				(void);

private:
	void							setupRenderData		(void);
};

CentroidRenderCase::CentroidRenderCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target, int renderSize)
	: MultisampleShaderRenderUtil::MultisampleRenderCase(context, name, description, numSamples, target, renderSize)
{
}

CentroidRenderCase::~CentroidRenderCase (void)
{
}

void CentroidRenderCase::init (void)
{
	// requirements
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");

	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
}

void CentroidRenderCase::setupRenderData (void)
{
	const int				numTriangles	= 200;
	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
	std::vector<tcu::Vec4>	data			(numTriangles * 3 * 3);

	m_renderMode = GL_TRIANGLES;
	m_renderCount = numTriangles * 3;
	m_renderSceneDescription = "triangle fan of narrow triangles";

	m_renderAttribs["a_position"].offset = 0;
	m_renderAttribs["a_position"].stride = (int)sizeof(float[4]) * 3;
	m_renderAttribs["a_barycentricsA"].offset = (int)sizeof(float[4]);
	m_renderAttribs["a_barycentricsA"].stride = (int)sizeof(float[4]) * 3;
	m_renderAttribs["a_barycentricsB"].offset = (int)sizeof(float[4]) * 2;
	m_renderAttribs["a_barycentricsB"].stride = (int)sizeof(float[4]) * 3;

	for (int triangleNdx = 0; triangleNdx < numTriangles; ++triangleNdx)
	{
		const float angle		= ((float)triangleNdx) / (float)numTriangles * 2.0f * DE_PI;
		const float nextAngle	= ((float)triangleNdx + 1.0f) / (float)numTriangles * 2.0f * DE_PI;

		data[(triangleNdx * 3 + 0) * 3 + 0] = tcu::Vec4(0.2f, -0.3f, 0.0f, 1.0f);
		data[(triangleNdx * 3 + 0) * 3 + 1] = tcu::Vec4(1.0f,  0.0f, 0.0f, 0.0f);
		data[(triangleNdx * 3 + 0) * 3 + 2] = tcu::Vec4(1.0f,  0.0f, 0.0f, 0.0f);

		data[(triangleNdx * 3 + 1) * 3 + 0] = tcu::Vec4(2.0f * deFloatCos(angle), 2.0f * deFloatSin(angle), 0.0f, 1.0f);
		data[(triangleNdx * 3 + 1) * 3 + 1] = tcu::Vec4(0.0f,  1.0f, 0.0f, 0.0f);
		data[(triangleNdx * 3 + 1) * 3 + 2] = tcu::Vec4(0.0f,  1.0f, 0.0f, 0.0f);

		data[(triangleNdx * 3 + 2) * 3 + 0] = tcu::Vec4(2.0f * deFloatCos(nextAngle), 2.0f * deFloatSin(nextAngle), 0.0f, 1.0f);
		data[(triangleNdx * 3 + 2) * 3 + 1] = tcu::Vec4(0.0f,  0.0f, 1.0f, 0.0f);
		data[(triangleNdx * 3 + 2) * 3 + 2] = tcu::Vec4(0.0f,  0.0f, 1.0f, 0.0f);
	}

	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);
	gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(data.size() * sizeof(tcu::Vec4)), data[0].getPtr(), GL_STATIC_DRAW);
}

class CentroidQualifierAtSampleCase : public CentroidRenderCase
{
public:
									CentroidQualifierAtSampleCase	(Context& context, const char* name, const char* description, int numSamples, RenderTarget target);
	virtual							~CentroidQualifierAtSampleCase	(void);

	void							init						(void);

private:
	enum
	{
		RENDER_SIZE = 128
	};

	std::string						genVertexSource				(int numTargetSamples) const;
	std::string						genFragmentSource			(int numTargetSamples) const;
	bool							verifyImage					(const tcu::Surface& resultImage);
};

CentroidQualifierAtSampleCase::CentroidQualifierAtSampleCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target)
	: CentroidRenderCase(context, name, description, numSamples, target, RENDER_SIZE)
{
}

CentroidQualifierAtSampleCase::~CentroidQualifierAtSampleCase (void)
{
}

void CentroidQualifierAtSampleCase::init (void)
{
	// test purpose and expectations
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying that interpolateAtSample ignores the centroid-qualifier.\n"
		<< "	Draw a fan of narrow triangles (large number of pixels on the edges).\n"
		<< "	Set varyings 'barycentricsA' and 'barycentricsB' to contain barycentric coordinates.\n"
		<< "	Add centroid-qualifier for barycentricsB.\n"
		<< "	=> interpolateAtSample(barycentricsB, N) ~= interpolateAtSample(barycentricsA, N)\n"
		<< tcu::TestLog::EndMessage;

	CentroidRenderCase::init();
}

std::string CentroidQualifierAtSampleCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"in highp vec4 a_position;\n"
			"in highp vec4 a_barycentricsA;\n"
			"in highp vec4 a_barycentricsB;\n"
			"out highp vec3 v_barycentricsA;\n"
			"centroid out highp vec3 v_barycentricsB;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_barycentricsA = a_barycentricsA.xyz;\n"
			"	v_barycentricsB = a_barycentricsB.xyz;\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string CentroidQualifierAtSampleCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"in highp vec3 v_barycentricsA;\n"
			"centroid in highp vec3 v_barycentricsB;\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	const highp float threshold = 0.0005;\n"
			"	bool allOk = true;\n"
			"\n"
			"	for (int sampleNdx = 0; sampleNdx < " << numTargetSamples << "; ++sampleNdx)\n"
			"	{\n"
			"		highp vec3 sampleA = interpolateAtSample(v_barycentricsA, sampleNdx);\n"
			"		highp vec3 sampleB = interpolateAtSample(v_barycentricsB, sampleNdx);\n"
			"		bool valuesEqual = all(lessThan(abs(sampleA - sampleB), vec3(threshold)));\n"
			"		if (!valuesEqual)\n"
			"			allOk = false;\n"
			"	}\n"
			"\n"
			"	if (allOk)\n"
			"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"	else\n"
			"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

bool CentroidQualifierAtSampleCase::verifyImage (const tcu::Surface& resultImage)
{
	return verifyGreenImage(resultImage, m_testCtx.getLog());
}

class InterpolateAtSampleIDCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
{
public:
						InterpolateAtSampleIDCase	(Context& context, const char* name, const char* description, int numSamples, RenderTarget target);
	virtual				~InterpolateAtSampleIDCase	(void);

	void				init						(void);
private:
	enum
	{
		RENDER_SIZE = 32
	};

	std::string			genVertexSource				(int numTargetSamples) const;
	std::string			genFragmentSource			(int numTargetSamples) const;
	bool				verifyImage					(const tcu::Surface& resultImage);
};

InterpolateAtSampleIDCase::InterpolateAtSampleIDCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target)
	: MultisampleShaderRenderUtil::MultisampleRenderCase(context, name, description, numSamples, target, RENDER_SIZE)
{
}

InterpolateAtSampleIDCase::~InterpolateAtSampleIDCase (void)
{
}

void InterpolateAtSampleIDCase::init (void)
{
	// requirements
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_variables"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_sample_variables extension");

	// test purpose and expectations
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying that interpolateAtSample with the sample set to the current sampleID returns consistent values.\n"
		<< "	Interpolate varying containing screen space location.\n"
		<< "	=> interpolateAtSample(varying, sampleID) = varying"
		<< tcu::TestLog::EndMessage;

	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
}

std::string InterpolateAtSampleIDCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"in highp vec4 a_position;\n"
			"sample out highp vec2 v_screenPosition;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_screenPosition = (a_position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(" << (int)RENDER_SIZE << ".0, " << (int)RENDER_SIZE << ".0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string InterpolateAtSampleIDCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SAMPLE_VARIABLES}"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"sample in highp vec2 v_screenPosition;\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	const highp float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits + 0.03125 for other errors\n" // 0.03125 = mediump epsilon when value = 32 (RENDER_SIZE)
			"\n"
			"	highp vec2 offsetValue = interpolateAtSample(v_screenPosition, gl_SampleID);\n"
			"	highp vec2 refValue = v_screenPosition;\n"
			"\n"
			"	bool valuesEqual = all(lessThan(abs(offsetValue - refValue), vec2(threshold)));\n"
			"	if (valuesEqual)\n"
			"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"	else\n"
			"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

bool InterpolateAtSampleIDCase::verifyImage (const tcu::Surface& resultImage)
{
	return verifyGreenImage(resultImage, m_testCtx.getLog());
}

class InterpolateAtCentroidCase : public CentroidRenderCase
{
public:
	enum TestType
	{
		TEST_CONSISTENCY = 0,
		TEST_ARRAY_ELEMENT,

		TEST_LAST
	};

									InterpolateAtCentroidCase	(Context& context, const char* name, const char* description, int numSamples, RenderTarget target, TestType type);
	virtual							~InterpolateAtCentroidCase	(void);

	void							init						(void);

private:
	enum
	{
		RENDER_SIZE = 128
	};

	std::string						genVertexSource				(int numTargetSamples) const;
	std::string						genFragmentSource			(int numTargetSamples) const;
	bool							verifyImage					(const tcu::Surface& resultImage);

	const TestType					m_type;
};

InterpolateAtCentroidCase::InterpolateAtCentroidCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target, TestType type)
	: CentroidRenderCase	(context, name, description, numSamples, target, RENDER_SIZE)
	, m_type				(type)
{
}

InterpolateAtCentroidCase::~InterpolateAtCentroidCase (void)
{
}

void InterpolateAtCentroidCase::init (void)
{
	// test purpose and expectations
	if (m_type == TEST_CONSISTENCY)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying that interpolateAtCentroid does not return different values than a corresponding centroid-qualified varying.\n"
			<< "	Draw a fan of narrow triangles (large number of pixels on the edges).\n"
			<< "	Set varyings 'barycentricsA' and 'barycentricsB' to contain barycentric coordinates.\n"
			<< "	Add centroid-qualifier for barycentricsB.\n"
			<< "	=> interpolateAtCentroid(barycentricsA) ~= barycentricsB\n"
			<< tcu::TestLog::EndMessage;
	}
	else if (m_type == TEST_ARRAY_ELEMENT)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Testing interpolateAtCentroid with element of array as an argument."
			<< tcu::TestLog::EndMessage;
	}
	else
		DE_ASSERT(false);

	CentroidRenderCase::init();
}

std::string InterpolateAtCentroidCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	if (m_type == TEST_CONSISTENCY)
		buf <<	"${GLSL_VERSION_DECL}\n"
				"in highp vec4 a_position;\n"
				"in highp vec4 a_barycentricsA;\n"
				"in highp vec4 a_barycentricsB;\n"
				"out highp vec3 v_barycentricsA;\n"
				"centroid out highp vec3 v_barycentricsB;\n"
				"void main (void)\n"
				"{\n"
				"	gl_Position = a_position;\n"
				"	v_barycentricsA = a_barycentricsA.xyz;\n"
				"	v_barycentricsB = a_barycentricsB.xyz;\n"
				"}\n";
	else if (m_type == TEST_ARRAY_ELEMENT)
		buf <<	"${GLSL_VERSION_DECL}\n"
				"in highp vec4 a_position;\n"
				"in highp vec4 a_barycentricsA;\n"
				"in highp vec4 a_barycentricsB;\n"
				"out highp vec3[2] v_barycentrics;\n"
				"void main (void)\n"
				"{\n"
				"	gl_Position = a_position;\n"
				"	v_barycentrics[0] = a_barycentricsA.xyz;\n"
				"	v_barycentrics[1] = a_barycentricsB.xyz;\n"
				"}\n";
	else
		DE_ASSERT(false);

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string InterpolateAtCentroidCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	if (m_type == TEST_CONSISTENCY)
		buf <<	"${GLSL_VERSION_DECL}\n"
				"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
				"in highp vec3 v_barycentricsA;\n"
				"centroid in highp vec3 v_barycentricsB;\n"
				"layout(location = 0) out highp vec4 fragColor;\n"
				"void main (void)\n"
				"{\n"
				"	const highp float threshold = 0.0005;\n"
				"\n"
				"	highp vec3 centroidASampled = interpolateAtCentroid(v_barycentricsA);\n"
				"	bool valuesEqual = all(lessThan(abs(centroidASampled - v_barycentricsB), vec3(threshold)));\n"
				"	bool centroidAIsInvalid = any(greaterThan(centroidASampled, vec3(1.0))) ||\n"
				"	                          any(lessThan(centroidASampled, vec3(0.0)));\n"
				"	bool centroidBIsInvalid = any(greaterThan(v_barycentricsB, vec3(1.0))) ||\n"
				"	                          any(lessThan(v_barycentricsB, vec3(0.0)));\n"
				"\n"
				"	if (valuesEqual && !centroidAIsInvalid && !centroidBIsInvalid)\n"
				"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
				"	else if (centroidAIsInvalid || centroidBIsInvalid)\n"
				"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"	else\n"
				"		fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
				"}\n";
	else if (m_type == TEST_ARRAY_ELEMENT)
		buf <<	"${GLSL_VERSION_DECL}\n"
				"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
				"in highp vec3[2] v_barycentrics;\n"
				"layout(location = 0) out mediump vec4 fragColor;\n"
				"void main (void)\n"
				"{\n"
				"	const highp float threshold = 0.0005;\n"
				"\n"
				"	highp vec3 centroidInterpolated = interpolateAtCentroid(v_barycentrics[1]);\n"
				"	bool centroidIsInvalid = any(greaterThan(centroidInterpolated, vec3(1.0))) ||\n"
				"	                         any(lessThan(centroidInterpolated, vec3(0.0)));\n"
				"\n"
				"	if (!centroidIsInvalid)\n"
				"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
				"	else\n"
				"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"}\n";
	else
		DE_ASSERT(false);

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

bool InterpolateAtCentroidCase::verifyImage (const tcu::Surface& resultImage)
{
	return verifyGreenImage(resultImage, m_testCtx.getLog());
}

class InterpolateAtOffsetCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
{
public:
	enum TestType
	{
		TEST_QUALIFIER_NONE = 0,
		TEST_QUALIFIER_CENTROID,
		TEST_QUALIFIER_SAMPLE,
		TEST_ARRAY_ELEMENT,

		TEST_LAST
	};
						InterpolateAtOffsetCase		(Context& context, const char* name, const char* description, int numSamples, RenderTarget target, TestType testType);
	virtual				~InterpolateAtOffsetCase	(void);

	void				init						(void);
private:
	enum
	{
		RENDER_SIZE = 32
	};

	std::string			genVertexSource				(int numTargetSamples) const;
	std::string			genFragmentSource			(int numTargetSamples) const;
	bool				verifyImage					(const tcu::Surface& resultImage);

	const TestType		m_testType;
};

InterpolateAtOffsetCase::InterpolateAtOffsetCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target, TestType testType)
	: MultisampleShaderRenderUtil::MultisampleRenderCase	(context, name, description, numSamples, target, RENDER_SIZE)
	, m_testType											(testType)
{
	DE_ASSERT(testType < TEST_LAST);
}

InterpolateAtOffsetCase::~InterpolateAtOffsetCase (void)
{
}

void InterpolateAtOffsetCase::init (void)
{
	// requirements
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");

	// test purpose and expectations
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying that interpolateAtOffset returns correct values.\n"
		<< "	Interpolate varying containing screen space location.\n"
		<< "	=> interpolateAtOffset(varying, offset) should be \"varying value at the pixel center\" + offset"
		<< tcu::TestLog::EndMessage;

	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
}

std::string InterpolateAtOffsetCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;
	buf << "${GLSL_VERSION_DECL}\n"
		<< "${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
		<< "in highp vec4 a_position;\n";

	if (m_testType == TEST_QUALIFIER_NONE || m_testType == TEST_QUALIFIER_CENTROID || m_testType == TEST_QUALIFIER_SAMPLE)
	{
		const char* const qualifier = (m_testType == TEST_QUALIFIER_CENTROID) ? ("centroid ") : (m_testType == TEST_QUALIFIER_SAMPLE) ? ("sample ") : ("");
		buf << qualifier << "out highp vec2 v_screenPosition;\n"
			<< qualifier << "out highp vec2 v_offset;\n";
	}
	else if (m_testType == TEST_ARRAY_ELEMENT)
	{
		buf << "out highp vec2[2] v_screenPosition;\n"
			<< "out highp vec2 v_offset;\n";
	}
	else
		DE_ASSERT(false);

	buf	<< "void main (void)\n"
		<< "{\n"
		<< "	gl_Position = a_position;\n";

	if (m_testType != TEST_ARRAY_ELEMENT)
		buf	<< "	v_screenPosition = (a_position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(" << (int)RENDER_SIZE << ".0, " << (int)RENDER_SIZE << ".0);\n";
	else
		buf	<< "	v_screenPosition[0] = a_position.xy; // not used\n"
				"	v_screenPosition[1] = (a_position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(" << (int)RENDER_SIZE << ".0, " << (int)RENDER_SIZE << ".0);\n";

	buf	<< "	v_offset = a_position.xy * 0.5f;\n"
		<< "}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string InterpolateAtOffsetCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	const char* const	arrayIndexing = (m_testType == TEST_ARRAY_ELEMENT) ? ("[1]") : ("");
	std::ostringstream	buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}";

	if (m_testType == TEST_QUALIFIER_NONE || m_testType == TEST_QUALIFIER_CENTROID || m_testType == TEST_QUALIFIER_SAMPLE)
	{
		const char* const qualifier = (m_testType == TEST_QUALIFIER_CENTROID) ? ("centroid ") : (m_testType == TEST_QUALIFIER_SAMPLE) ? ("sample ") : ("");
		buf	<< qualifier << "in highp vec2 v_screenPosition;\n"
			<< qualifier << "in highp vec2 v_offset;\n";
	}
	else if (m_testType == TEST_ARRAY_ELEMENT)
	{
		buf << "in highp vec2[2] v_screenPosition;\n"
			<< "in highp vec2 v_offset;\n";
	}
	else
		DE_ASSERT(false);

	buf	<<	"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	const highp float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits + 0.03125 for other errors\n" // 0.03125 = mediump epsilon when value = 32 (RENDER_SIZE)
			"\n"
			"	highp vec2 pixelCenter = floor(v_screenPosition" << arrayIndexing << ") + vec2(0.5, 0.5);\n"
			"	highp vec2 offsetValue = interpolateAtOffset(v_screenPosition" << arrayIndexing << ", v_offset);\n"
			"	highp vec2 refValue = pixelCenter + v_offset;\n"
			"\n"
			"	bool valuesEqual = all(lessThan(abs(offsetValue - refValue), vec2(threshold)));\n"
			"	if (valuesEqual)\n"
			"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"	else\n"
			"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

bool InterpolateAtOffsetCase::verifyImage (const tcu::Surface& resultImage)
{
	return verifyGreenImage(resultImage, m_testCtx.getLog());
}

class InterpolateAtSamplePositionCase : public MultisampleShaderRenderUtil::MultisampleRenderCase
{
public:
						InterpolateAtSamplePositionCase		(Context& context, const char* name, const char* description, int numSamples, RenderTarget target);
	virtual				~InterpolateAtSamplePositionCase	(void);

	void				init								(void);
private:
	enum
	{
		RENDER_SIZE = 32
	};

	std::string			genVertexSource						(int numTargetSamples) const;
	std::string			genFragmentSource					(int numTargetSamples) const;
	bool				verifyImage							(const tcu::Surface& resultImage);
};

InterpolateAtSamplePositionCase::InterpolateAtSamplePositionCase (Context& context, const char* name, const char* description, int numSamples, RenderTarget target)
	: MultisampleShaderRenderUtil::MultisampleRenderCase(context, name, description, numSamples, target, RENDER_SIZE)
{
}

InterpolateAtSamplePositionCase::~InterpolateAtSamplePositionCase (void)
{
}

void InterpolateAtSamplePositionCase::init (void)
{
	// requirements
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_variables"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_sample_variables extension");

	// test purpose and expectations
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying that interpolateAtOffset with the offset of current sample position returns consistent values.\n"
		<< "	Interpolate varying containing screen space location.\n"
		<< "	=> interpolateAtOffset(varying, currentOffset) = varying"
		<< tcu::TestLog::EndMessage;

	MultisampleShaderRenderUtil::MultisampleRenderCase::init();
}

std::string InterpolateAtSamplePositionCase::genVertexSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"in highp vec4 a_position;\n"
			"sample out highp vec2 v_screenPosition;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_screenPosition = (a_position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(" << (int)RENDER_SIZE << ".0, " << (int)RENDER_SIZE << ".0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

std::string InterpolateAtSamplePositionCase::genFragmentSource (int numTargetSamples) const
{
	DE_UNREF(numTargetSamples);

	std::ostringstream buf;

	buf <<	"${GLSL_VERSION_DECL}\n"
			"${GLSL_EXT_SAMPLE_VARIABLES}"
			"${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
			"sample in highp vec2 v_screenPosition;\n"
			"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
			"	const highp float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits + 0.03125 for other errors\n" // 0.03125 = mediump epsilon when value = 32 (RENDER_SIZE)
			"\n"
			"	highp vec2 offset = gl_SamplePosition - vec2(0.5, 0.5);\n"
			"	highp vec2 offsetValue = interpolateAtOffset(v_screenPosition, offset);\n"
			"	highp vec2 refValue = v_screenPosition;\n"
			"\n"
			"	bool valuesEqual = all(lessThan(abs(offsetValue - refValue), vec2(threshold)));\n"
			"	if (valuesEqual)\n"
			"		fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
			"	else\n"
			"		fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

bool InterpolateAtSamplePositionCase::verifyImage (const tcu::Surface& resultImage)
{
	return verifyGreenImage(resultImage, m_testCtx.getLog());
}

class NegativeCompileInterpolationCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_VEC4_IDENTITY_SWIZZLE = 0,
		CASE_VEC4_CROP_SWIZZLE,
		CASE_VEC4_MIXED_SWIZZLE,
		CASE_INTERPOLATE_IVEC4,
		CASE_INTERPOLATE_UVEC4,
		CASE_INTERPOLATE_ARRAY,
		CASE_INTERPOLATE_STRUCT,
		CASE_INTERPOLATE_STRUCT_MEMBER,
		CASE_INTERPOLATE_LOCAL,
		CASE_INTERPOLATE_GLOBAL,
		CASE_INTERPOLATE_CONSTANT,

		CASE_LAST
	};
	enum InterpolatorType
	{
		INTERPOLATE_AT_SAMPLE = 0,
		INTERPOLATE_AT_CENTROID,
		INTERPOLATE_AT_OFFSET,

		INTERPOLATE_LAST
	};

							NegativeCompileInterpolationCase	(Context& context, const char* name, const char* description, CaseType caseType, InterpolatorType interpolator);

private:
	void					init								(void);
	IterateResult			iterate								(void);

	std::string				genShaderSource						(void) const;

	const CaseType			m_caseType;
	const InterpolatorType	m_interpolation;
};

NegativeCompileInterpolationCase::NegativeCompileInterpolationCase (Context& context, const char* name, const char* description, CaseType caseType, InterpolatorType interpolator)
	: TestCase			(context, name, description)
	, m_caseType		(caseType)
	, m_interpolation	(interpolator)
{
	DE_ASSERT(m_caseType < CASE_LAST);
	DE_ASSERT(m_interpolation < INTERPOLATE_LAST);
}

void NegativeCompileInterpolationCase::init (void)
{
	if (!checkSupport(m_context) && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
		TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation extension");

	if(!glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		if(m_caseType == CASE_VEC4_IDENTITY_SWIZZLE
		   || m_caseType == CASE_VEC4_CROP_SWIZZLE
		   || m_caseType == CASE_VEC4_MIXED_SWIZZLE
		   || m_caseType == CASE_INTERPOLATE_IVEC4
		   || m_caseType == CASE_INTERPOLATE_UVEC4
		   || m_caseType == CASE_INTERPOLATE_STRUCT_MEMBER)
			TCU_THROW(NotSupportedError, "Test requires a GLES context");
	}

	m_testCtx.getLog() << tcu::TestLog::Message << "Trying to compile illegal shader, expecting compile to fail." << tcu::TestLog::EndMessage;
}

NegativeCompileInterpolationCase::IterateResult NegativeCompileInterpolationCase::iterate (void)
{
	const std::string	source			= genShaderSource();
	glu::Shader			shader			(m_context.getRenderContext(), glu::SHADERTYPE_FRAGMENT);
	const char* const	sourceStrPtr	= source.c_str();

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Fragment shader source:"
						<< tcu::TestLog::EndMessage
						<< tcu::TestLog::KernelSource(source);

	shader.setSources(1, &sourceStrPtr, DE_NULL);
	shader.compile();

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Info log:"
						<< tcu::TestLog::EndMessage
						<< tcu::TestLog::KernelSource(shader.getInfoLog());

	if (shader.getCompileStatus())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Illegal shader compiled successfully." << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected compile status");
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Compile failed as expected." << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	return STOP;
}

std::string NegativeCompileInterpolationCase::genShaderSource (void) const
{
	std::ostringstream	buf;
	std::string			interpolation;
	const char*			interpolationTemplate;
	const char*			description;
	const char*			globalDeclarations		= "";
	const char*			localDeclarations		= "";
	const char*			interpolationTarget		= "";
	const char*			postSelector			= "";

	switch (m_caseType)
	{
		case CASE_VEC4_IDENTITY_SWIZZLE:
			globalDeclarations	= "in highp vec4 v_var;\n";
			interpolationTarget	= "v_var.xyzw";
			description			= "component selection is illegal";
			break;

		case CASE_VEC4_CROP_SWIZZLE:
			globalDeclarations	= "in highp vec4 v_var;\n";
			interpolationTarget	= "v_var.xy";
			postSelector		= ".x";
			description			= "component selection is illegal";
			break;

		case CASE_VEC4_MIXED_SWIZZLE:
			globalDeclarations	= "in highp vec4 v_var;\n";
			interpolationTarget	= "v_var.yzxw";
			description			= "component selection is illegal";
			break;

		case CASE_INTERPOLATE_IVEC4:
			globalDeclarations	= "flat in highp ivec4 v_var;\n";
			interpolationTarget	= "v_var";
			description			= "no overload for ivec";
			break;

		case CASE_INTERPOLATE_UVEC4:
			globalDeclarations	= "flat in highp uvec4 v_var;\n";
			interpolationTarget	= "v_var";
			description			= "no overload for uvec";
			break;

		case CASE_INTERPOLATE_ARRAY:
			globalDeclarations	= "in highp float v_var[2];\n";
			interpolationTarget	= "v_var";
			postSelector		= "[1]";
			description			= "no overload for arrays";
			break;

		case CASE_INTERPOLATE_STRUCT:
		case CASE_INTERPOLATE_STRUCT_MEMBER:
			globalDeclarations	=	"struct S\n"
									"{\n"
									"	highp float a;\n"
									"	highp float b;\n"
									"};\n"
									"in S v_var;\n";

			interpolationTarget	= (m_caseType == CASE_INTERPOLATE_STRUCT) ? ("v_var")						: ("v_var.a");
			postSelector		= (m_caseType == CASE_INTERPOLATE_STRUCT) ? (".a")							: ("");
			description			= (m_caseType == CASE_INTERPOLATE_STRUCT) ? ("no overload for this type")	: ("<interpolant> is not an input variable (just a member of)");
			break;

		case CASE_INTERPOLATE_LOCAL:
			localDeclarations	= "	highp vec4 local_var = gl_FragCoord;\n";
			interpolationTarget	= "local_var";
			description			= "<interpolant> is not an input variable";
			break;

		case CASE_INTERPOLATE_GLOBAL:
			globalDeclarations	= "highp vec4 global_var;\n";
			localDeclarations	= "	global_var = gl_FragCoord;\n";
			interpolationTarget	= "global_var";
			description			= "<interpolant> is not an input variable";
			break;

		case CASE_INTERPOLATE_CONSTANT:
			globalDeclarations	= "const highp vec4 const_var = vec4(0.2);\n";
			interpolationTarget	= "const_var";
			description			= "<interpolant> is not an input variable";
			break;

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

	switch (m_interpolation)
	{
		case INTERPOLATE_AT_SAMPLE:
			interpolationTemplate = "interpolateAtSample(${TARGET}, 0)${POST_SELECTOR}";
			break;

		case INTERPOLATE_AT_CENTROID:
			interpolationTemplate = "interpolateAtCentroid(${TARGET})${POST_SELECTOR}";
			break;

		case INTERPOLATE_AT_OFFSET:
			interpolationTemplate = "interpolateAtOffset(${TARGET}, vec2(0.2, 0.2))${POST_SELECTOR}";
			break;

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

	{
		std::map<std::string, std::string> args;
		args["TARGET"] = interpolationTarget;
		args["POST_SELECTOR"] = postSelector;

		interpolation = tcu::StringTemplate(interpolationTemplate).specialize(args);
	}

	buf <<	glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType())) << "\n"
		<< "${GLSL_EXT_SHADER_MULTISAMPLE_INTERPOLATION}"
		<<	globalDeclarations
		<<	"layout(location = 0) out mediump vec4 fragColor;\n"
			"void main (void)\n"
			"{\n"
		<<	localDeclarations
		<<	"	fragColor = vec4(" << interpolation << "); // " << description << "\n"
			"}\n";

	return specializeShader(buf.str(), m_context.getRenderContext().getType());
}

} // anonymous

ShaderMultisampleInterpolationTests::ShaderMultisampleInterpolationTests (Context& context)
	: TestCaseGroup(context, "multisample_interpolation", "Test multisample interpolation")
{
}

ShaderMultisampleInterpolationTests::~ShaderMultisampleInterpolationTests (void)
{
}

void ShaderMultisampleInterpolationTests::init (void)
{
	using namespace MultisampleShaderRenderUtil;

	static const struct RenderTarget
	{
		const char*							name;
		const char*							desc;
		int									numSamples;
		MultisampleRenderCase::RenderTarget	target;
	} targets[] =
	{
		{ "default_framebuffer",		"Test with default framebuffer",	0,	MultisampleRenderCase::TARGET_DEFAULT		},
		{ "singlesample_texture",		"Test with singlesample texture",	0,	MultisampleRenderCase::TARGET_TEXTURE		},
		{ "multisample_texture_1",		"Test with multisample texture",	1,	MultisampleRenderCase::TARGET_TEXTURE		},
		{ "multisample_texture_2",		"Test with multisample texture",	2,	MultisampleRenderCase::TARGET_TEXTURE		},
		{ "multisample_texture_4",		"Test with multisample texture",	4,	MultisampleRenderCase::TARGET_TEXTURE		},
		{ "multisample_texture_8",		"Test with multisample texture",	8,	MultisampleRenderCase::TARGET_TEXTURE		},
		{ "multisample_texture_16",		"Test with multisample texture",	16,	MultisampleRenderCase::TARGET_TEXTURE		},
		{ "singlesample_rbo",			"Test with singlesample rbo",		0,	MultisampleRenderCase::TARGET_RENDERBUFFER	},
		{ "multisample_rbo_1",			"Test with multisample rbo",		1,	MultisampleRenderCase::TARGET_RENDERBUFFER	},
		{ "multisample_rbo_2",			"Test with multisample rbo",		2,	MultisampleRenderCase::TARGET_RENDERBUFFER	},
		{ "multisample_rbo_4",			"Test with multisample rbo",		4,	MultisampleRenderCase::TARGET_RENDERBUFFER	},
		{ "multisample_rbo_8",			"Test with multisample rbo",		8,	MultisampleRenderCase::TARGET_RENDERBUFFER	},
		{ "multisample_rbo_16",			"Test with multisample rbo",		16,	MultisampleRenderCase::TARGET_RENDERBUFFER	},
	};

	static const struct
	{
		const char*									name;
		const char*									description;
		NegativeCompileInterpolationCase::CaseType	caseType;
	} negativeCompileCases[] =
	{
		{ "vec4_identity_swizzle",		"use identity swizzle",				NegativeCompileInterpolationCase::CASE_VEC4_IDENTITY_SWIZZLE		},
		{ "vec4_crop_swizzle",			"use cropped identity swizzle",		NegativeCompileInterpolationCase::CASE_VEC4_CROP_SWIZZLE			},
		{ "vec4_mixed_swizzle",			"use swizzle",						NegativeCompileInterpolationCase::CASE_VEC4_MIXED_SWIZZLE			},
		{ "interpolate_ivec4",			"interpolate integer variable",		NegativeCompileInterpolationCase::CASE_INTERPOLATE_IVEC4			},
		{ "interpolate_uvec4",			"interpolate integer variable",		NegativeCompileInterpolationCase::CASE_INTERPOLATE_UVEC4			},
		{ "interpolate_array",			"interpolate whole array",			NegativeCompileInterpolationCase::CASE_INTERPOLATE_ARRAY			},
		{ "interpolate_struct",			"interpolate whole struct",			NegativeCompileInterpolationCase::CASE_INTERPOLATE_STRUCT			},
		{ "interpolate_struct_member",	"interpolate struct member",		NegativeCompileInterpolationCase::CASE_INTERPOLATE_STRUCT_MEMBER	},
		{ "interpolate_local",			"interpolate local variable",		NegativeCompileInterpolationCase::CASE_INTERPOLATE_LOCAL			},
		{ "interpolate_global",			"interpolate global variable",		NegativeCompileInterpolationCase::CASE_INTERPOLATE_GLOBAL			},
		{ "interpolate_constant",		"interpolate constant variable",	NegativeCompileInterpolationCase::CASE_INTERPOLATE_CONSTANT			},
	};

	// .sample_qualifier
	{
		tcu::TestCaseGroup* const sampleQualifierGroup = new tcu::TestCaseGroup(m_testCtx, "sample_qualifier", "Test sample qualifier");
		addChild(sampleQualifierGroup);

		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
			sampleQualifierGroup->addChild(new SampleQualifierRenderCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target));
	}

	// .interpolate_at_sample
	{
		tcu::TestCaseGroup* const interpolateAtSampleGroup = new tcu::TestCaseGroup(m_testCtx, "interpolate_at_sample", "Test interpolateAtSample");
		addChild(interpolateAtSampleGroup);

		// .static_sample_number
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "static_sample_number", "Test interpolateAtSample sample number");
			interpolateAtSampleGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtSampleRenderCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, InterpolateAtSampleRenderCase::INDEXING_STATIC));
		}

		// .dynamic_sample_number
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "dynamic_sample_number", "Test interpolateAtSample sample number");
			interpolateAtSampleGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtSampleRenderCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, InterpolateAtSampleRenderCase::INDEXING_DYNAMIC));
		}

		// .non_multisample_buffer
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "non_multisample_buffer", "Test interpolateAtSample with non-multisample buffers");
			interpolateAtSampleGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				if (targets[targetNdx].numSamples == 0)
					group->addChild(new SingleSampleInterpolateAtSampleCase(m_context, std::string("sample_0_").append(targets[targetNdx].name).c_str(), targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, SingleSampleInterpolateAtSampleCase::SAMPLE_0));

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				if (targets[targetNdx].numSamples == 0)
					group->addChild(new SingleSampleInterpolateAtSampleCase(m_context, std::string("sample_n_").append(targets[targetNdx].name).c_str(), targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, SingleSampleInterpolateAtSampleCase::SAMPLE_N));
		}

		// .centroid_qualifier
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "centroid_qualified", "Test interpolateAtSample with centroid qualified varying");
			interpolateAtSampleGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new CentroidQualifierAtSampleCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target));
		}

		// .at_sample_id
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "at_sample_id", "Test interpolateAtSample at current sample id");
			interpolateAtSampleGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtSampleIDCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target));
		}

		// .negative
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "negative", "interpolateAtSample negative tests");
			interpolateAtSampleGroup->addChild(group);

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(negativeCompileCases); ++ndx)
				group->addChild(new NegativeCompileInterpolationCase(m_context,
																	 negativeCompileCases[ndx].name,
																	 negativeCompileCases[ndx].description,
																	 negativeCompileCases[ndx].caseType,
																	 NegativeCompileInterpolationCase::INTERPOLATE_AT_SAMPLE));
		}
	}

	// .interpolate_at_centroid
	{
		tcu::TestCaseGroup* const methodGroup = new tcu::TestCaseGroup(m_testCtx, "interpolate_at_centroid", "Test interpolateAtCentroid");
		addChild(methodGroup);

		// .consistency
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "consistency", "Test interpolateAtCentroid return value is consistent to centroid qualified value");
			methodGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtCentroidCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, InterpolateAtCentroidCase::TEST_CONSISTENCY));
		}

		// .array_element
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "array_element", "Test interpolateAtCentroid with array element");
			methodGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtCentroidCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, InterpolateAtCentroidCase::TEST_ARRAY_ELEMENT));
		}

		// .negative
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "negative", "interpolateAtCentroid negative tests");
			methodGroup->addChild(group);

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(negativeCompileCases); ++ndx)
				group->addChild(new NegativeCompileInterpolationCase(m_context,
																	 negativeCompileCases[ndx].name,
																	 negativeCompileCases[ndx].description,
																	 negativeCompileCases[ndx].caseType,
																	 NegativeCompileInterpolationCase::INTERPOLATE_AT_CENTROID));
		}
	}

	// .interpolate_at_offset
	{
		static const struct TestConfig
		{
			const char*							name;
			InterpolateAtOffsetCase::TestType	type;
		} configs[] =
		{
			{ "no_qualifiers",		InterpolateAtOffsetCase::TEST_QUALIFIER_NONE		},
			{ "centroid_qualifier",	InterpolateAtOffsetCase::TEST_QUALIFIER_CENTROID	},
			{ "sample_qualifier",	InterpolateAtOffsetCase::TEST_QUALIFIER_SAMPLE		},
		};

		tcu::TestCaseGroup* const methodGroup = new tcu::TestCaseGroup(m_testCtx, "interpolate_at_offset", "Test interpolateAtOffset");
		addChild(methodGroup);

		// .no_qualifiers
		// .centroid_qualifier
		// .sample_qualifier
		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(configs); ++configNdx)
		{
			tcu::TestCaseGroup* const qualifierGroup = new tcu::TestCaseGroup(m_testCtx, configs[configNdx].name, "Test interpolateAtOffset with qualified/non-qualified varying");
			methodGroup->addChild(qualifierGroup);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				qualifierGroup->addChild(new InterpolateAtOffsetCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, configs[configNdx].type));
		}

		// .at_sample_position
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "at_sample_position", "Test interpolateAtOffset at sample position");
			methodGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtSamplePositionCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target));
		}

		// .array_element
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "array_element", "Test interpolateAtOffset with array element");
			methodGroup->addChild(group);

			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
				group->addChild(new InterpolateAtOffsetCase(m_context, targets[targetNdx].name, targets[targetNdx].desc, targets[targetNdx].numSamples, targets[targetNdx].target, InterpolateAtOffsetCase::TEST_ARRAY_ELEMENT));
		}

		// .negative
		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "negative", "interpolateAtOffset negative tests");
			methodGroup->addChild(group);

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(negativeCompileCases); ++ndx)
				group->addChild(new NegativeCompileInterpolationCase(m_context,
																	 negativeCompileCases[ndx].name,
																	 negativeCompileCases[ndx].description,
																	 negativeCompileCases[ndx].caseType,
																	 NegativeCompileInterpolationCase::INTERPOLATE_AT_OFFSET));
		}
	}
}

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