/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 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 Shader derivate function tests.
 *
 * \todo [2013-06-25 pyry] Missing features:
 *  - lines and points
 *  - projected coordinates
 *  - continous non-trivial functions (sin, exp)
 *  - non-continous functions (step)
 *//*--------------------------------------------------------------------*/

#include "es3fShaderDerivateTests.hpp"
#include "gluShaderProgram.hpp"
#include "gluRenderContext.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluTexture.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuFloat.hpp"
#include "tcuInterval.hpp"
#include "deRandom.hpp"
#include "deUniquePtr.hpp"
#include "deString.h"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "glsShaderRenderCase.hpp" // gls::setupDefaultUniforms()

#include <sstream>

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::vector;
using std::string;
using std::map;
using tcu::TestLog;
using std::ostringstream;

enum
{
	VIEWPORT_WIDTH		= 167,
	VIEWPORT_HEIGHT		= 103,
	FBO_WIDTH			= 99,
	FBO_HEIGHT			= 133,
	MAX_FAILED_MESSAGES	= 10
};

enum DerivateFunc
{
	DERIVATE_DFDX	= 0,
	DERIVATE_DFDY,
	DERIVATE_FWIDTH,

	DERIVATE_LAST
};

enum SurfaceType
{
	SURFACETYPE_DEFAULT_FRAMEBUFFER = 0,
	SURFACETYPE_UNORM_FBO,
	SURFACETYPE_FLOAT_FBO,	// \note Uses RGBA32UI fbo actually, since FP rendertargets are not in core spec.

	SURFACETYPE_LAST
};

// Utilities

namespace
{

class AutoFbo
{
public:
	AutoFbo (const glw::Functions& gl)
		: m_gl	(gl)
		, m_fbo	(0)
	{
	}

	~AutoFbo (void)
	{
		if (m_fbo)
			m_gl.deleteFramebuffers(1, &m_fbo);
	}

	void gen (void)
	{
		DE_ASSERT(!m_fbo);
		m_gl.genFramebuffers(1, &m_fbo);
	}

	deUint32 operator* (void) const { return m_fbo; }

private:
	const glw::Functions&	m_gl;
	deUint32				m_fbo;
};

class AutoRbo
{
public:
	AutoRbo (const glw::Functions& gl)
		: m_gl	(gl)
		, m_rbo	(0)
	{
	}

	~AutoRbo (void)
	{
		if (m_rbo)
			m_gl.deleteRenderbuffers(1, &m_rbo);
	}

	void gen (void)
	{
		DE_ASSERT(!m_rbo);
		m_gl.genRenderbuffers(1, &m_rbo);
	}

	deUint32 operator* (void) const { return m_rbo; }

private:
	const glw::Functions&	m_gl;
	deUint32				m_rbo;
};

} // anonymous

static const char* getDerivateFuncName (DerivateFunc func)
{
	switch (func)
	{
		case DERIVATE_DFDX:		return "dFdx";
		case DERIVATE_DFDY:		return "dFdy";
		case DERIVATE_FWIDTH:	return "fwidth";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static const char* getDerivateFuncCaseName (DerivateFunc func)
{
	switch (func)
	{
		case DERIVATE_DFDX:		return "dfdx";
		case DERIVATE_DFDY:		return "dfdy";
		case DERIVATE_FWIDTH:	return "fwidth";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline tcu::BVec4 getDerivateMask (glu::DataType type)
{
	switch (type)
	{
		case glu::TYPE_FLOAT:		return tcu::BVec4(true, false, false, false);
		case glu::TYPE_FLOAT_VEC2:	return tcu::BVec4(true, true, false, false);
		case glu::TYPE_FLOAT_VEC3:	return tcu::BVec4(true, true, true, false);
		case glu::TYPE_FLOAT_VEC4:	return tcu::BVec4(true, true, true, true);
		default:
			DE_ASSERT(false);
			return tcu::BVec4(true);
	}
}

static inline tcu::Vec4 readDerivate (const tcu::ConstPixelBufferAccess& surface, const tcu::Vec4& derivScale, const tcu::Vec4& derivBias, int x, int y)
{
	return (surface.getPixel(x, y) - derivBias) / derivScale;
}

static inline tcu::UVec4 getCompExpBits (const tcu::Vec4& v)
{
	return tcu::UVec4(tcu::Float32(v[0]).exponentBits(),
					  tcu::Float32(v[1]).exponentBits(),
					  tcu::Float32(v[2]).exponentBits(),
					  tcu::Float32(v[3]).exponentBits());
}

float computeFloatingPointError (const float value, const int numAccurateBits)
{
	const int		numGarbageBits	= 23-numAccurateBits;
	const deUint32	mask			= (1u<<numGarbageBits)-1u;
	const int		exp				= (tcu::Float32(value).exponent() < -3) ? -3 : tcu::Float32(value).exponent();

	return tcu::Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - tcu::Float32::construct(+1, exp, 1u<<23).asFloat();
}

static int getNumMantissaBits (const glu::Precision precision)
{
	switch (precision)
	{
		case glu::PRECISION_HIGHP:		return 23;
		case glu::PRECISION_MEDIUMP:	return 10;
		case glu::PRECISION_LOWP:		return 6;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static int getMinExponent (const glu::Precision precision)
{
	switch (precision)
	{
		case glu::PRECISION_HIGHP:		return -126;
		case glu::PRECISION_MEDIUMP:	return -14;
		case glu::PRECISION_LOWP:		return -8;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static float getSingleULPForExponent (int exp, int numMantissaBits)
{
	if (numMantissaBits > 0)
	{
		DE_ASSERT(numMantissaBits <= 23);

		const int ulpBitNdx = 23-numMantissaBits;
		return tcu::Float32::construct(+1, exp, (1<<23) | (1 << ulpBitNdx)).asFloat() - tcu::Float32::construct(+1, exp, (1<<23)).asFloat();
	}
	else
	{
		DE_ASSERT(numMantissaBits == 0);
		return tcu::Float32::construct(+1, exp, (1<<23)).asFloat();
	}
}

static float getSingleULPForValue (float value, int numMantissaBits)
{
	const int exp = tcu::Float32(value).exponent();
	return getSingleULPForExponent(exp, numMantissaBits);
}

static float convertFloatFlushToZeroRtn (float value, int minExponent, int numAccurateBits)
{
	if (value == 0.0f)
	{
		return 0.0f;
	}
	else
	{
		const tcu::Float32	inputFloat			= tcu::Float32(value);
		const int			numTruncatedBits	= 23-numAccurateBits;
		const deUint32		truncMask			= (1u<<numTruncatedBits)-1u;

		if (value > 0.0f)
		{
			if (value > 0.0f && tcu::Float32(value).exponent() < minExponent)
			{
				// flush to zero if possible
				return 0.0f;
			}
			else
			{
				// just mask away non-representable bits
				return tcu::Float32::construct(+1, inputFloat.exponent(), inputFloat.mantissa() & ~truncMask).asFloat();
			}
		}
		else
		{
			if (inputFloat.mantissa() & truncMask)
			{
				// decrement one ulp if truncated bits are non-zero (i.e. if value is not representable)
				return tcu::Float32::construct(-1, inputFloat.exponent(), inputFloat.mantissa() & ~truncMask).asFloat() - getSingleULPForExponent(inputFloat.exponent(), numAccurateBits);
			}
			else
			{
				// value is representable, no need to do anything
				return value;
			}
		}
	}
}

static float convertFloatFlushToZeroRtp (float value, int minExponent, int numAccurateBits)
{
	return -convertFloatFlushToZeroRtn(-value, minExponent, numAccurateBits);
}

static float addErrorUlp (float value, float numUlps, int numMantissaBits)
{
	return value + numUlps * getSingleULPForValue(value, numMantissaBits);
}

enum
{
	INTERPOLATION_LOST_BITS = 3, // number mantissa of bits allowed to be lost in varying interpolation
};

static int getInterpolationLostBitsWarning (const glu::Precision precision)
{
	// number mantissa of bits allowed to be lost in varying interpolation
	switch (precision)
	{
		case glu::PRECISION_HIGHP:		return 9;
		case glu::PRECISION_MEDIUMP:	return 3;
		case glu::PRECISION_LOWP:		return 3;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static inline tcu::Vec4 getDerivateThreshold (const glu::Precision precision, const tcu::Vec4& valueMin, const tcu::Vec4& valueMax, const tcu::Vec4& expectedDerivate)
{
	const int			baseBits		= getNumMantissaBits(precision);
	const tcu::UVec4	derivExp		= getCompExpBits(expectedDerivate);
	const tcu::UVec4	maxValueExp		= max(getCompExpBits(valueMin), getCompExpBits(valueMax));
	const tcu::UVec4	numBitsLost		= maxValueExp - min(maxValueExp, derivExp);
	const tcu::IVec4	numAccurateBits	= max(baseBits - numBitsLost.asInt() - (int)INTERPOLATION_LOST_BITS, tcu::IVec4(0));

	return tcu::Vec4(computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
					 computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
					 computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
					 computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
}

static inline tcu::Vec4 getDerivateThresholdWarning (const glu::Precision precision, const tcu::Vec4& valueMin, const tcu::Vec4& valueMax, const tcu::Vec4& expectedDerivate)
{
	const int			baseBits		= getNumMantissaBits(precision);
	const tcu::UVec4	derivExp		= getCompExpBits(expectedDerivate);
	const tcu::UVec4	maxValueExp		= max(getCompExpBits(valueMin), getCompExpBits(valueMax));
	const tcu::UVec4	numBitsLost		= maxValueExp - min(maxValueExp, derivExp);
	const tcu::IVec4	numAccurateBits	= max(baseBits - numBitsLost.asInt() - getInterpolationLostBitsWarning(precision), tcu::IVec4(0));

	return tcu::Vec4(computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
					 computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
					 computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
					 computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
}


namespace
{

struct LogVecComps
{
	const tcu::Vec4&	v;
	int					numComps;

	LogVecComps (const tcu::Vec4& v_, int numComps_)
		: v			(v_)
		, numComps	(numComps_)
	{
	}
};

std::ostream& operator<< (std::ostream& str, const LogVecComps& v)
{
	DE_ASSERT(de::inRange(v.numComps, 1, 4));
	if (v.numComps == 1)		return str << v.v[0];
	else if (v.numComps == 2)	return str << v.v.toWidth<2>();
	else if (v.numComps == 3)	return str << v.v.toWidth<3>();
	else						return str << v.v;
}

} // anonymous

enum VerificationLogging
{
	LOG_ALL = 0,
	LOG_NOTHING
};

static qpTestResult verifyConstantDerivate (tcu::TestLog&				log,
									const tcu::ConstPixelBufferAccess&	result,
									const tcu::PixelBufferAccess&		errorMask,
									glu::DataType						dataType,
									const tcu::Vec4&					reference,
									const tcu::Vec4&					threshold,
									const tcu::Vec4&					scale,
									const tcu::Vec4&					bias,
									VerificationLogging					logPolicy = LOG_ALL)
{
	const int			numComps		= glu::getDataTypeFloatScalars(dataType);
	const tcu::BVec4	mask			= tcu::logicalNot(getDerivateMask(dataType));
	int					numFailedPixels	= 0;

	if (logPolicy == LOG_ALL)
		log << TestLog::Message << "Expecting " << LogVecComps(reference, numComps) << " with threshold " << LogVecComps(threshold, numComps) << TestLog::EndMessage;

	for (int y = 0; y < result.getHeight(); y++)
	{
		for (int x = 0; x < result.getWidth(); x++)
		{
			const tcu::Vec4		resDerivate		= readDerivate(result, scale, bias, x, y);
			const bool			isOk			= tcu::allEqual(tcu::logicalOr(tcu::lessThanEqual(tcu::abs(reference - resDerivate), threshold), mask), tcu::BVec4(true));

			if (!isOk)
			{
				if (numFailedPixels < MAX_FAILED_MESSAGES && logPolicy == LOG_ALL)
					log << TestLog::Message << "FAIL: got " << LogVecComps(resDerivate, numComps)
											<< ", diff = " << LogVecComps(tcu::abs(reference - resDerivate), numComps)
											<< ", at x = " << x << ", y = " << y
						<< TestLog::EndMessage;
				numFailedPixels += 1;
				errorMask.setPixel(tcu::RGBA::red().toVec(), x, y);
			}
		}
	}

	if (numFailedPixels >= MAX_FAILED_MESSAGES && logPolicy == LOG_ALL)
		log << TestLog::Message << "..." << TestLog::EndMessage;

	if (numFailedPixels > 0 && logPolicy == LOG_ALL)
		log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;

	return (numFailedPixels == 0) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
}

struct Linear2DFunctionEvaluator
{
	tcu::Matrix<float, 4, 3> matrix;

	//      .-----.
	//      | s_x |
	//  M x | s_y |
	//      | 1.0 |
	//      '-----'
	tcu::Vec4 evaluateAt (float screenX, float screenY) const;
};

tcu::Vec4 Linear2DFunctionEvaluator::evaluateAt (float screenX, float screenY) const
{
	const tcu::Vec3 position(screenX, screenY, 1.0f);
	return matrix * position;
}

static qpTestResult reverifyConstantDerivateWithFlushRelaxations (tcu::TestLog&							log,
														  const tcu::ConstPixelBufferAccess&	result,
														  const tcu::PixelBufferAccess&			errorMask,
														  glu::DataType							dataType,
														  glu::Precision						precision,
														  const tcu::Vec4&						derivScale,
														  const tcu::Vec4&						derivBias,
														  const tcu::Vec4&						surfaceThreshold,
														  DerivateFunc							derivateFunc,
														  const Linear2DFunctionEvaluator&		function)
{
	DE_ASSERT(result.getWidth() == errorMask.getWidth());
	DE_ASSERT(result.getHeight() == errorMask.getHeight());
	DE_ASSERT(derivateFunc == DERIVATE_DFDX || derivateFunc == DERIVATE_DFDY);

	const tcu::IVec4	red						(255, 0, 0, 255);
	const tcu::IVec4	green					(0, 255, 0, 255);
	const float			divisionErrorUlps		= 2.5f;

	const int			numComponents			= glu::getDataTypeFloatScalars(dataType);
	const int			numBits					= getNumMantissaBits(precision);
	const int			minExponent				= getMinExponent(precision);

	const int			numVaryingSampleBits	= numBits - INTERPOLATION_LOST_BITS;
	int					numFailedPixels			= 0;

	tcu::clear(errorMask, green);

	// search for failed pixels
	for (int y = 0; y < result.getHeight(); ++y)
	for (int x = 0; x < result.getWidth(); ++x)
	{
		//                 flushToZero?(f2z?(functionValueCurrent) - f2z?(functionValueBefore))
		// flushToZero? ( ------------------------------------------------------------------------ +- 2.5 ULP )
		//                                                  dx

		const tcu::Vec4	resultDerivative		= readDerivate(result, derivScale, derivBias, x, y);

		// sample at the front of the back pixel and the back of the front pixel to cover the whole area of
		// legal sample positions. In general case this is NOT OK, but we know that the target funtion is
		// (mostly*) linear which allows us to take the sample points at arbitrary points. This gets us the
		// maximum difference possible in exponents which are used in error bound calculations.
		// * non-linearity may happen around zero or with very high function values due to subnorms not
		//   behaving well.
		const tcu::Vec4	functionValueForward	= (derivateFunc == DERIVATE_DFDX)
													? (function.evaluateAt((float)x + 2.0f, (float)y + 0.5f))
													: (function.evaluateAt((float)x + 0.5f, (float)y + 2.0f));
		const tcu::Vec4	functionValueBackward	= (derivateFunc == DERIVATE_DFDX)
													? (function.evaluateAt((float)x - 1.0f, (float)y + 0.5f))
													: (function.evaluateAt((float)x + 0.5f, (float)y - 1.0f));

		bool	anyComponentFailed				= false;

		// check components separately
		for (int c = 0; c < numComponents; ++c)
		{
			// Simulate interpolation. Add allowed interpolation error and round to target precision. Allow one half ULP (i.e. correct rounding)
			const tcu::Interval	forwardComponent		(convertFloatFlushToZeroRtn(addErrorUlp((float)functionValueForward[c],  -0.5f, numVaryingSampleBits), minExponent, numBits),
														 convertFloatFlushToZeroRtp(addErrorUlp((float)functionValueForward[c],  +0.5f, numVaryingSampleBits), minExponent, numBits));
			const tcu::Interval	backwardComponent		(convertFloatFlushToZeroRtn(addErrorUlp((float)functionValueBackward[c], -0.5f, numVaryingSampleBits), minExponent, numBits),
														 convertFloatFlushToZeroRtp(addErrorUlp((float)functionValueBackward[c], +0.5f, numVaryingSampleBits), minExponent, numBits));
			const int			maxValueExp				= de::max(de::max(tcu::Float32(forwardComponent.lo()).exponent(),   tcu::Float32(forwardComponent.hi()).exponent()),
																  de::max(tcu::Float32(backwardComponent.lo()).exponent(),  tcu::Float32(backwardComponent.hi()).exponent()));

			// subtraction in numerator will likely cause a cancellation of the most
			// significant bits. Apply error bounds.

			const tcu::Interval	numerator				(forwardComponent - backwardComponent);
			const int			numeratorLoExp			= tcu::Float32(numerator.lo()).exponent();
			const int			numeratorHiExp			= tcu::Float32(numerator.hi()).exponent();
			const int			numeratorLoBitsLost		= de::max(0, maxValueExp - numeratorLoExp); //!< must clamp to zero since if forward and backward components have different
			const int			numeratorHiBitsLost		= de::max(0, maxValueExp - numeratorHiExp); //!< sign, numerator might have larger exponent than its operands.
			const int			numeratorLoBits			= de::max(0, numBits - numeratorLoBitsLost);
			const int			numeratorHiBits			= de::max(0, numBits - numeratorHiBitsLost);

			const tcu::Interval	numeratorRange			(convertFloatFlushToZeroRtn((float)numerator.lo(), minExponent, numeratorLoBits),
														 convertFloatFlushToZeroRtp((float)numerator.hi(), minExponent, numeratorHiBits));

			const tcu::Interval	divisionRange			= numeratorRange / 3.0f; // legal sample area is anywhere within this and neighboring pixels (i.e. size = 3)
			const tcu::Interval	divisionResultRange		(convertFloatFlushToZeroRtn(addErrorUlp((float)divisionRange.lo(), -divisionErrorUlps, numBits), minExponent, numBits),
														 convertFloatFlushToZeroRtp(addErrorUlp((float)divisionRange.hi(), +divisionErrorUlps, numBits), minExponent, numBits));
			const tcu::Interval	finalResultRange		(divisionResultRange.lo() - surfaceThreshold[c], divisionResultRange.hi() + surfaceThreshold[c]);

			if (resultDerivative[c] >= finalResultRange.lo() && resultDerivative[c] <= finalResultRange.hi())
			{
				// value ok
			}
			else
			{
				if (numFailedPixels < MAX_FAILED_MESSAGES)
					log << tcu::TestLog::Message
						<< "Error in pixel at " << x << ", " << y << " with component " << c << " (channel " << ("rgba"[c]) << ")\n"
						<< "\tGot pixel value " << result.getPixelInt(x, y) << "\n"
						<< "\t\tdFd" << ((derivateFunc == DERIVATE_DFDX) ? ('x') : ('y')) << " ~= " << resultDerivative[c] << "\n"
						<< "\t\tdifference to a valid range: "
							<< ((resultDerivative[c] < finalResultRange.lo()) ? ("-") : ("+"))
							<< ((resultDerivative[c] < finalResultRange.lo()) ? (finalResultRange.lo() - resultDerivative[c]) : (resultDerivative[c] - finalResultRange.hi()))
							<< "\n"
						<< "\tDerivative value range:\n"
						<< "\t\tMin: " << finalResultRange.lo() << "\n"
						<< "\t\tMax: " << finalResultRange.hi() << "\n"
						<< tcu::TestLog::EndMessage;

				++numFailedPixels;
				anyComponentFailed = true;
			}
		}

		if (anyComponentFailed)
			errorMask.setPixel(red, x, y);
	}

	if (numFailedPixels >= MAX_FAILED_MESSAGES)
		log << TestLog::Message << "..." << TestLog::EndMessage;

	if (numFailedPixels > 0)
		log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;

	return (numFailedPixels == 0) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
}

// TriangleDerivateCase

class TriangleDerivateCase : public TestCase
{
public:
							TriangleDerivateCase	(Context& context, const char* name, const char* description);
							~TriangleDerivateCase	(void);

	IterateResult			iterate					(void);

protected:
	virtual void			setupRenderState		(deUint32 program) { DE_UNREF(program); }
	virtual qpTestResult	verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask) = DE_NULL;

	tcu::IVec2				getViewportSize			(void) const;
	tcu::Vec4				getSurfaceThreshold		(void) const;

	glu::DataType			m_dataType;
	glu::Precision			m_precision;

	glu::DataType			m_coordDataType;
	glu::Precision			m_coordPrecision;

	std::string				m_fragmentSrc;

	tcu::Vec4				m_coordMin;
	tcu::Vec4				m_coordMax;
	tcu::Vec4				m_derivScale;
	tcu::Vec4				m_derivBias;

	SurfaceType				m_surfaceType;
	int						m_numSamples;
	deUint32				m_hint;
};

TriangleDerivateCase::TriangleDerivateCase (Context& context, const char* name, const char* description)
	: TestCase			(context, name, description)
	, m_dataType		(glu::TYPE_LAST)
	, m_precision		(glu::PRECISION_LAST)
	, m_coordDataType	(glu::TYPE_LAST)
	, m_coordPrecision	(glu::PRECISION_LAST)
	, m_surfaceType		(SURFACETYPE_DEFAULT_FRAMEBUFFER)
	, m_numSamples		(0)
	, m_hint			(GL_DONT_CARE)
{
	DE_ASSERT(m_surfaceType != SURFACETYPE_DEFAULT_FRAMEBUFFER || m_numSamples == 0);
}

TriangleDerivateCase::~TriangleDerivateCase (void)
{
	TriangleDerivateCase::deinit();
}

static std::string genVertexSource (glu::DataType coordType, glu::Precision precision)
{
	DE_ASSERT(glu::isDataTypeFloatOrVec(coordType));

	const char* vertexTmpl =
		"#version 300 es\n"
		"in highp vec4 a_position;\n"
		"in ${PRECISION} ${DATATYPE} a_coord;\n"
		"out ${PRECISION} ${DATATYPE} v_coord;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"	v_coord = a_coord;\n"
		"}\n";

	map<string, string> vertexParams;

	vertexParams["PRECISION"]	= glu::getPrecisionName(precision);
	vertexParams["DATATYPE"]	= glu::getDataTypeName(coordType);

	return tcu::StringTemplate(vertexTmpl).specialize(vertexParams);
}

inline tcu::IVec2 TriangleDerivateCase::getViewportSize (void) const
{
	if (m_surfaceType == SURFACETYPE_DEFAULT_FRAMEBUFFER)
	{
		const int	width	= de::min<int>(m_context.getRenderTarget().getWidth(),	VIEWPORT_WIDTH);
		const int	height	= de::min<int>(m_context.getRenderTarget().getHeight(),	VIEWPORT_HEIGHT);
		return tcu::IVec2(width, height);
	}
	else
		return tcu::IVec2(FBO_WIDTH, FBO_HEIGHT);
}

TriangleDerivateCase::IterateResult TriangleDerivateCase::iterate (void)
{
	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::makeVtxFragSources(genVertexSource(m_coordDataType, m_coordPrecision), m_fragmentSrc));
	de::Random					rnd				(deStringHash(getName()) ^ 0xbbc24);
	const bool					useFbo			= m_surfaceType != SURFACETYPE_DEFAULT_FRAMEBUFFER;
	const deUint32				fboFormat		= m_surfaceType == SURFACETYPE_FLOAT_FBO ? GL_RGBA32UI : GL_RGBA8;
	const tcu::IVec2			viewportSize	= getViewportSize();
	const int					viewportX		= useFbo ? 0 : rnd.getInt(0, m_context.getRenderTarget().getWidth()		- viewportSize.x());
	const int					viewportY		= useFbo ? 0 : rnd.getInt(0, m_context.getRenderTarget().getHeight()	- viewportSize.y());
	AutoFbo						fbo				(gl);
	AutoRbo						rbo				(gl);
	tcu::TextureLevel			result;

	m_testCtx.getLog() << program;

	if (!program.isOk())
		TCU_FAIL("Compile failed");

	if (useFbo)
	{
		m_testCtx.getLog() << TestLog::Message
						   << "Rendering to FBO, format = " << glu::getTextureFormatStr(fboFormat)
						   << ", samples = " << m_numSamples
						   << TestLog::EndMessage;

		fbo.gen();
		rbo.gen();

		gl.bindRenderbuffer(GL_RENDERBUFFER, *rbo);
		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, fboFormat, viewportSize.x(), viewportSize.y());
		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);
		TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
	}
	else
	{
		const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();

		m_testCtx.getLog()
			<< TestLog::Message
			<< "Rendering to default framebuffer\n"
			<< "\tColor depth: R=" << pixelFormat.redBits << ", G=" << pixelFormat.greenBits << ", B=" << pixelFormat.blueBits << ", A=" << pixelFormat.alphaBits
			<< TestLog::EndMessage;
	}

	m_testCtx.getLog() << TestLog::Message << "in: " << m_coordMin << " -> " << m_coordMax << "\n"
										   << "v_coord.x = in.x * x\n"
										   << "v_coord.y = in.y * y\n"
										   << "v_coord.z = in.z * (x+y)/2\n"
										   << "v_coord.w = in.w * (1 - (x+y)/2)\n"
					   << TestLog::EndMessage
					   << TestLog::Message << "u_scale: " << m_derivScale << ", u_bias: " << m_derivBias << " (displayed values have scale/bias removed)" << TestLog::EndMessage
					   << TestLog::Message << "Viewport: " << viewportSize.x() << "x" << viewportSize.y() << TestLog::EndMessage
					   << TestLog::Message << "GL_FRAGMENT_SHADER_DERIVATE_HINT: " << glu::getHintModeStr(m_hint) << TestLog::EndMessage;

	// Draw
	{
		const float positions[] =
		{
			-1.0f, -1.0f, 0.0f, 1.0f,
			-1.0f,  1.0f, 0.0f, 1.0f,
			 1.0f, -1.0f, 0.0f, 1.0f,
			 1.0f,  1.0f, 0.0f, 1.0f
		};
		const float coords[] =
		{
			m_coordMin.x(), m_coordMin.y(), m_coordMin.z(),							m_coordMax.w(),
			m_coordMin.x(), m_coordMax.y(), (m_coordMin.z()+m_coordMax.z())*0.5f,	(m_coordMin.w()+m_coordMax.w())*0.5f,
			m_coordMax.x(), m_coordMin.y(), (m_coordMin.z()+m_coordMax.z())*0.5f,	(m_coordMin.w()+m_coordMax.w())*0.5f,
			m_coordMax.x(), m_coordMax.y(), m_coordMax.z(),							m_coordMin.w()
		};
		const glu::VertexArrayBinding vertexArrays[] =
		{
			glu::va::Float("a_position",	4, 4, 0, &positions[0]),
			glu::va::Float("a_coord",		4, 4, 0, &coords[0])
		};
		const deUint16 indices[] = { 0, 2, 1, 2, 3, 1 };

		gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
		gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
		gl.disable(GL_DITHER);

		gl.useProgram(program.getProgram());

		{
			const int	scaleLoc	= gl.getUniformLocation(program.getProgram(), "u_scale");
			const int	biasLoc		= gl.getUniformLocation(program.getProgram(), "u_bias");

			switch (m_dataType)
			{
				case glu::TYPE_FLOAT:
					gl.uniform1f(scaleLoc, m_derivScale.x());
					gl.uniform1f(biasLoc, m_derivBias.x());
					break;

				case glu::TYPE_FLOAT_VEC2:
					gl.uniform2fv(scaleLoc, 1, m_derivScale.getPtr());
					gl.uniform2fv(biasLoc, 1, m_derivBias.getPtr());
					break;

				case glu::TYPE_FLOAT_VEC3:
					gl.uniform3fv(scaleLoc, 1, m_derivScale.getPtr());
					gl.uniform3fv(biasLoc, 1, m_derivBias.getPtr());
					break;

				case glu::TYPE_FLOAT_VEC4:
					gl.uniform4fv(scaleLoc, 1, m_derivScale.getPtr());
					gl.uniform4fv(biasLoc, 1, m_derivBias.getPtr());
					break;

				default:
					DE_ASSERT(false);
			}
		}

		gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
		setupRenderState(program.getProgram());

		gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, m_hint);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");

		gl.viewport(viewportX, viewportY, viewportSize.x(), viewportSize.y());
		glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
	}

	// Read back results
	{
		const bool		isMSAA		= useFbo && m_numSamples > 0;
		AutoFbo			resFbo		(gl);
		AutoRbo			resRbo		(gl);

		// Resolve if necessary
		if (isMSAA)
		{
			resFbo.gen();
			resRbo.gen();

			gl.bindRenderbuffer(GL_RENDERBUFFER, *resRbo);
			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, fboFormat, viewportSize.x(), viewportSize.y());
			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, *resFbo);
			gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *resRbo);
			TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);

			gl.blitFramebuffer(0, 0, viewportSize.x(), viewportSize.y(), 0, 0, viewportSize.x(), viewportSize.y(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Resolve blit");

			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, *resFbo);
		}

		switch (m_surfaceType)
		{
			case SURFACETYPE_DEFAULT_FRAMEBUFFER:
			case SURFACETYPE_UNORM_FBO:
				result.setStorage(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), viewportSize.x(), viewportSize.y());
				glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, result);
				break;

			case SURFACETYPE_FLOAT_FBO:
			{
				const tcu::TextureFormat	dataFormat		(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
				const tcu::TextureFormat	transferFormat	(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);

				result.setStorage(dataFormat, viewportSize.x(), viewportSize.y());
				glu::readPixels(m_context.getRenderContext(), viewportX, viewportY,
								tcu::PixelBufferAccess(transferFormat, result.getWidth(), result.getHeight(), result.getDepth(), result.getAccess().getDataPtr()));
				break;
			}

			default:
				DE_ASSERT(false);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
	}

	// Verify
	{
		tcu::Surface errorMask(result.getWidth(), result.getHeight());
		tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());

		const qpTestResult testResult = verify(result.getAccess(), errorMask.getAccess());
		const char* failStr = "Fail";

		m_testCtx.getLog() << TestLog::ImageSet("Result", "Result images")
						   << TestLog::Image("Rendered", "Rendered image", result);

		if (testResult != QP_TEST_RESULT_PASS)
			m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);

		m_testCtx.getLog() << TestLog::EndImageSet;

		if (testResult == QP_TEST_RESULT_PASS)
			failStr = "Pass";
		else if (testResult == QP_TEST_RESULT_QUALITY_WARNING)
			failStr = "QualityWarning";

		m_testCtx.setTestResult(testResult, failStr);

	}

	return STOP;
}

tcu::Vec4 TriangleDerivateCase::getSurfaceThreshold (void) const
{
	switch (m_surfaceType)
	{
		case SURFACETYPE_DEFAULT_FRAMEBUFFER:
		{
			const tcu::PixelFormat	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
			const tcu::IVec4		channelBits		(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
			const tcu::IVec4		intThreshold	= tcu::IVec4(1) << (8 - channelBits);
			const tcu::Vec4			normThreshold	= intThreshold.asFloat() / 255.0f;

			return normThreshold;
		}

		case SURFACETYPE_UNORM_FBO:				return tcu::IVec4(1).asFloat() / 255.0f;
		case SURFACETYPE_FLOAT_FBO:				return tcu::Vec4(0.0f);
		default:
			DE_ASSERT(false);
			return tcu::Vec4(0.0f);
	}
}

// ConstantDerivateCase

class ConstantDerivateCase : public TriangleDerivateCase
{
public:
						ConstantDerivateCase		(Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type);
						~ConstantDerivateCase		(void) {}

	void				init						(void);

protected:
	qpTestResult		verify						(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);

private:
	DerivateFunc		m_func;
};

ConstantDerivateCase::ConstantDerivateCase (Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type)
	: TriangleDerivateCase	(context, name, description)
	, m_func				(func)
{
	m_dataType			= type;
	m_precision			= glu::PRECISION_HIGHP;
	m_coordDataType		= m_dataType;
	m_coordPrecision	= m_precision;
}

void ConstantDerivateCase::init (void)
{
	const char* fragmentTmpl =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
		"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
		"void main (void)\n"
		"{\n"
		"	${PRECISION} ${DATATYPE} res = ${FUNC}(${VALUE}) * u_scale + u_bias;\n"
		"	o_color = ${CAST_TO_OUTPUT};\n"
		"}\n";
	map<string, string> fragmentParams;
	fragmentParams["PRECISION"]			= glu::getPrecisionName(m_precision);
	fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_dataType);
	fragmentParams["FUNC"]				= getDerivateFuncName(m_func);
	fragmentParams["VALUE"]				= m_dataType == glu::TYPE_FLOAT_VEC4 ? "vec4(1.0, 7.2, -1e5, 0.0)" :
										  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec3(1e2, 8.0, 0.01)" :
										  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec2(-0.0, 2.7)" :
										  /* TYPE_FLOAT */					   "7.7";
	fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
										  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
										  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
										  /* TYPE_FLOAT */					   "vec4(res, 0.0, 0.0, 1.0)";

	m_fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);

	m_derivScale	= tcu::Vec4(1e3f, 1e3f, 1e3f, 1e3f);
	m_derivBias		= tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
}

qpTestResult ConstantDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
{
	const tcu::Vec4 reference	(0.0f); // Derivate of constant argument should always be 0
	const tcu::Vec4	threshold	= getSurfaceThreshold() / abs(m_derivScale);

	return verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
								  reference, threshold, m_derivScale, m_derivBias);
}

// LinearDerivateCase

class LinearDerivateCase : public TriangleDerivateCase
{
public:
						LinearDerivateCase		(Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples, const char* fragmentSrcTmpl);
						~LinearDerivateCase		(void) {}

	void				init					(void);

protected:
	qpTestResult		verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);

private:
	DerivateFunc		m_func;
	std::string			m_fragmentTmpl;
};

LinearDerivateCase::LinearDerivateCase (Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples, const char* fragmentSrcTmpl)
	: TriangleDerivateCase	(context, name, description)
	, m_func				(func)
	, m_fragmentTmpl		(fragmentSrcTmpl)
{
	m_dataType			= type;
	m_precision			= precision;
	m_coordDataType		= m_dataType;
	m_coordPrecision	= m_precision;
	m_hint				= hint;
	m_surfaceType		= surfaceType;
	m_numSamples		= numSamples;
}

void LinearDerivateCase::init (void)
{
	const tcu::IVec2	viewportSize	= getViewportSize();
	const float			w				= float(viewportSize.x());
	const float			h				= float(viewportSize.y());
	const bool			packToInt		= m_surfaceType == SURFACETYPE_FLOAT_FBO;
	map<string, string>	fragmentParams;

	fragmentParams["OUTPUT_TYPE"]		= glu::getDataTypeName(packToInt ? glu::TYPE_UINT_VEC4 : glu::TYPE_FLOAT_VEC4);
	fragmentParams["OUTPUT_PREC"]		= glu::getPrecisionName(packToInt ? glu::PRECISION_HIGHP : m_precision);
	fragmentParams["PRECISION"]			= glu::getPrecisionName(m_precision);
	fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_dataType);
	fragmentParams["FUNC"]				= getDerivateFuncName(m_func);

	if (packToInt)
	{
		fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
											  m_dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
											  m_dataType == glu::TYPE_FLOAT_VEC2 ? "floatBitsToUint(vec4(res, 0.0, 1.0))" :
											  /* TYPE_FLOAT */					   "floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))";
	}
	else
	{
		fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
											  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
											  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
											  /* TYPE_FLOAT */					   "vec4(res, 0.0, 0.0, 1.0)";
	}

	m_fragmentSrc = tcu::StringTemplate(m_fragmentTmpl.c_str()).specialize(fragmentParams);

	switch (m_precision)
	{
		case glu::PRECISION_HIGHP:
			m_coordMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
			m_coordMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
			break;

		case glu::PRECISION_MEDIUMP:
			m_coordMin = tcu::Vec4(-37.0f, 47.f, -7.f, 0.0f);
			m_coordMax = tcu::Vec4(-1.0f, 12.f, 7.f, 19.f);
			break;

		case glu::PRECISION_LOWP:
			m_coordMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
			m_coordMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
			break;

		default:
			DE_ASSERT(false);
	}

	if (m_surfaceType == SURFACETYPE_FLOAT_FBO)
	{
		// No scale or bias used for accuracy.
		m_derivScale	= tcu::Vec4(1.0f);
		m_derivBias		= tcu::Vec4(0.0f);
	}
	else
	{
		// Compute scale - bias that normalizes to 0..1 range.
		const tcu::Vec4 dx = (m_coordMax - m_coordMin) / tcu::Vec4(w, w, w*0.5f, -w*0.5f);
		const tcu::Vec4 dy = (m_coordMax - m_coordMin) / tcu::Vec4(h, h, h*0.5f, -h*0.5f);

		switch (m_func)
		{
			case DERIVATE_DFDX:
				m_derivScale = 0.5f / dx;
				break;

			case DERIVATE_DFDY:
				m_derivScale = 0.5f / dy;
				break;

			case DERIVATE_FWIDTH:
				m_derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
				break;

			default:
				DE_ASSERT(false);
		}

		m_derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	}
}

qpTestResult LinearDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
{
	const tcu::Vec4		xScale				= tcu::Vec4(1.0f, 0.0f, 0.5f, -0.5f);
	const tcu::Vec4		yScale				= tcu::Vec4(0.0f, 1.0f, 0.5f, -0.5f);
	const tcu::Vec4		surfaceThreshold	= getSurfaceThreshold() / abs(m_derivScale);

	if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
	{
		const bool			isX				= m_func == DERIVATE_DFDX;
		const float			div				= isX ? float(result.getWidth()) : float(result.getHeight());
		const tcu::Vec4		scale			= isX ? xScale : yScale;
		tcu::Vec4			reference		= ((m_coordMax - m_coordMin) / div);
		const tcu::Vec4		opThreshold		= getDerivateThreshold(m_precision, m_coordMin, m_coordMax, reference);
		const tcu::Vec4		opThresholdW	= getDerivateThresholdWarning(m_precision, m_coordMin, m_coordMax, reference);
		const tcu::Vec4		threshold		= max(surfaceThreshold, opThreshold);
		const tcu::Vec4		thresholdW		= max(surfaceThreshold, opThresholdW);
		const int			numComps		= glu::getDataTypeFloatScalars(m_dataType);

		/* adjust the reference value for the correct dfdx or dfdy sample adjacency */
		reference	= reference * scale;

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying result image.\n"
			<< "\tValid derivative is " << LogVecComps(reference, numComps) << " with threshold " << LogVecComps(threshold, numComps)
			<< tcu::TestLog::EndMessage;

		// short circuit if result is strictly within the normal value error bounds.
		// This improves performance significantly.
		if (verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
								   reference, threshold, m_derivScale, m_derivBias,
								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "No incorrect derivatives found, result valid."
				<< tcu::TestLog::EndMessage;

			return QP_TEST_RESULT_PASS;
		}

		// Check with relaxed threshold value
		if (verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
								   reference, thresholdW, m_derivScale, m_derivBias,
								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "No incorrect derivatives found, result valid with quality warning."
				<< tcu::TestLog::EndMessage;

			return QP_TEST_RESULT_QUALITY_WARNING;
		}

		// some pixels exceed error bounds calculated for normal values. Verify that these
		// potentially invalid pixels are in fact valid due to (for example) subnorm flushing.

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Initial verification failed, verifying image by calculating accurate error bounds for each result pixel.\n"
			<< "\tVerifying each result derivative is within its range of legal result values."
			<< tcu::TestLog::EndMessage;

		{
			const tcu::IVec2			viewportSize	= getViewportSize();
			const float					w				= float(viewportSize.x());
			const float					h				= float(viewportSize.y());
			const tcu::Vec4				valueRamp		= (m_coordMax - m_coordMin);
			Linear2DFunctionEvaluator	function;

			function.matrix.setRow(0, tcu::Vec3(valueRamp.x() / w, 0.0f, m_coordMin.x()));
			function.matrix.setRow(1, tcu::Vec3(0.0f, valueRamp.y() / h, m_coordMin.y()));
			function.matrix.setRow(2, tcu::Vec3(valueRamp.z() / w, valueRamp.z() / h, m_coordMin.z() + m_coordMin.z()) / 2.0f);
			function.matrix.setRow(3, tcu::Vec3(-valueRamp.w() / w, -valueRamp.w() / h, m_coordMax.w() + m_coordMax.w()) / 2.0f);

			return reverifyConstantDerivateWithFlushRelaxations(m_testCtx.getLog(), result, errorMask,
																m_dataType, m_precision, m_derivScale,
																m_derivBias, surfaceThreshold, m_func,
																function);
		}
	}
	else
	{
		DE_ASSERT(m_func == DERIVATE_FWIDTH);
		const float			w				= float(result.getWidth());
		const float			h				= float(result.getHeight());

		const tcu::Vec4		dx				= ((m_coordMax - m_coordMin) / w) * xScale;
		const tcu::Vec4		dy				= ((m_coordMax - m_coordMin) / h) * yScale;
		const tcu::Vec4		reference		= tcu::abs(dx) + tcu::abs(dy);
		const tcu::Vec4		dxThreshold		= getDerivateThreshold(m_precision, m_coordMin*xScale, m_coordMax*xScale, dx);
		const tcu::Vec4		dyThreshold		= getDerivateThreshold(m_precision, m_coordMin*yScale, m_coordMax*yScale, dy);
		const tcu::Vec4		dxThresholdW	= getDerivateThresholdWarning(m_precision, m_coordMin*xScale, m_coordMax*xScale, dx);
		const tcu::Vec4		dyThresholdW	= getDerivateThresholdWarning(m_precision, m_coordMin*yScale, m_coordMax*yScale, dy);
		const tcu::Vec4		threshold		= max(surfaceThreshold, max(dxThreshold, dyThreshold));
		const tcu::Vec4		thresholdW		= max(surfaceThreshold, max(dxThresholdW, dyThresholdW));
		qpTestResult        testResult		= QP_TEST_RESULT_FAIL;

		testResult = verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
									  reference, threshold, m_derivScale, m_derivBias);

		// return if result is pass
		if (testResult == QP_TEST_RESULT_PASS)
			return testResult;

		// re-check with relaxed threshold
		testResult = verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
									  reference, thresholdW, m_derivScale, m_derivBias);

		// if with relaxed threshold test is passing then mark the result with quality warning.
		if (testResult == QP_TEST_RESULT_PASS)
			testResult = QP_TEST_RESULT_QUALITY_WARNING;

		return testResult;
	}
}

// TextureDerivateCase

class TextureDerivateCase : public TriangleDerivateCase
{
public:
						TextureDerivateCase		(Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples);
						~TextureDerivateCase	(void);

	void				init					(void);
	void				deinit					(void);

protected:
	void				setupRenderState		(deUint32 program);
	qpTestResult		verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);

private:
	DerivateFunc		m_func;

	tcu::Vec4			m_texValueMin;
	tcu::Vec4			m_texValueMax;
	glu::Texture2D*		m_texture;
};

TextureDerivateCase::TextureDerivateCase (Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples)
	: TriangleDerivateCase	(context, name, description)
	, m_func				(func)
	, m_texture				(DE_NULL)
{
	m_dataType			= type;
	m_precision			= precision;
	m_coordDataType		= glu::TYPE_FLOAT_VEC2;
	m_coordPrecision	= glu::PRECISION_HIGHP;
	m_hint				= hint;
	m_surfaceType		= surfaceType;
	m_numSamples		= numSamples;
}

TextureDerivateCase::~TextureDerivateCase (void)
{
	delete m_texture;
}

void TextureDerivateCase::init (void)
{
	// Generate shader
	{
		const char* fragmentTmpl =
			"#version 300 es\n"
			"in highp vec2 v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} sampler2D u_sampler;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} vec4 tex = texture(u_sampler, v_coord);\n"
			"	${PRECISION} ${DATATYPE} res = ${FUNC}(tex${SWIZZLE}) * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n";

		const bool			packToInt		= m_surfaceType == SURFACETYPE_FLOAT_FBO;
		map<string, string> fragmentParams;

		fragmentParams["OUTPUT_TYPE"]		= glu::getDataTypeName(packToInt ? glu::TYPE_UINT_VEC4 : glu::TYPE_FLOAT_VEC4);
		fragmentParams["OUTPUT_PREC"]		= glu::getPrecisionName(packToInt ? glu::PRECISION_HIGHP : m_precision);
		fragmentParams["PRECISION"]			= glu::getPrecisionName(m_precision);
		fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_dataType);
		fragmentParams["FUNC"]				= getDerivateFuncName(m_func);
		fragmentParams["SWIZZLE"]			= m_dataType == glu::TYPE_FLOAT_VEC4 ? "" :
											  m_dataType == glu::TYPE_FLOAT_VEC3 ? ".xyz" :
											  m_dataType == glu::TYPE_FLOAT_VEC2 ? ".xy" :
											  /* TYPE_FLOAT */					   ".x";

		if (packToInt)
		{
			fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
												  m_dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
												  m_dataType == glu::TYPE_FLOAT_VEC2 ? "floatBitsToUint(vec4(res, 0.0, 1.0))" :
												  /* TYPE_FLOAT */					   "floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))";
		}
		else
		{
			fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
												  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
												  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
												  /* TYPE_FLOAT */					   "vec4(res, 0.0, 0.0, 1.0)";
		}

		m_fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
	}

	// Texture size matches viewport and nearest sampling is used. Thus texture sampling
	// is equal to just interpolating the texture value range.

	// Determine value range for texture.

	switch (m_precision)
	{
		case glu::PRECISION_HIGHP:
			m_texValueMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
			m_texValueMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
			break;

		case glu::PRECISION_MEDIUMP:
			m_texValueMin = tcu::Vec4(-37.0f, 47.f, -7.f, 0.0f);
			m_texValueMax = tcu::Vec4(-1.0f, 12.f, 7.f, 19.f);
			break;

		case glu::PRECISION_LOWP:
			m_texValueMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
			m_texValueMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
			break;

		default:
			DE_ASSERT(false);
	}

	// Lowp and mediump cases use RGBA16F format, while highp uses RGBA32F.
	{
		const tcu::IVec2 viewportSize = getViewportSize();
		DE_ASSERT(!m_texture);
		m_texture = new glu::Texture2D(m_context.getRenderContext(), m_precision == glu::PRECISION_HIGHP ? GL_RGBA32F : GL_RGBA16F, viewportSize.x(), viewportSize.y());
		m_texture->getRefTexture().allocLevel(0);
	}

	// Texture coordinates
	m_coordMin = tcu::Vec4(0.0f);
	m_coordMax = tcu::Vec4(1.0f);

	// Fill with gradients.
	{
		const tcu::PixelBufferAccess level0 = m_texture->getRefTexture().getLevel(0);
		for (int y = 0; y < level0.getHeight(); y++)
		{
			for (int x = 0; x < level0.getWidth(); x++)
			{
				const float		xf		= (float(x)+0.5f) / float(level0.getWidth());
				const float		yf		= (float(y)+0.5f) / float(level0.getHeight());
				const tcu::Vec4	s		= tcu::Vec4(xf, yf, (xf+yf)/2.0f, 1.0f - (xf+yf)/2.0f);

				level0.setPixel(m_texValueMin + (m_texValueMax - m_texValueMin)*s, x, y);
			}
		}
	}

	m_texture->upload();

	if (m_surfaceType == SURFACETYPE_FLOAT_FBO)
	{
		// No scale or bias used for accuracy.
		m_derivScale	= tcu::Vec4(1.0f);
		m_derivBias		= tcu::Vec4(0.0f);
	}
	else
	{
		// Compute scale - bias that normalizes to 0..1 range.
		const tcu::IVec2	viewportSize	= getViewportSize();
		const float			w				= float(viewportSize.x());
		const float			h				= float(viewportSize.y());
		const tcu::Vec4		dx				= (m_texValueMax - m_texValueMin) / tcu::Vec4(w, w, w*0.5f, -w*0.5f);
		const tcu::Vec4		dy				= (m_texValueMax - m_texValueMin) / tcu::Vec4(h, h, h*0.5f, -h*0.5f);

		switch (m_func)
		{
			case DERIVATE_DFDX:
				m_derivScale = 0.5f / dx;
				break;

			case DERIVATE_DFDY:
				m_derivScale = 0.5f / dy;
				break;

			case DERIVATE_FWIDTH:
				m_derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
				break;

			default:
				DE_ASSERT(false);
		}

		m_derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	}
}

void TextureDerivateCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;
}

void TextureDerivateCase::setupRenderState (deUint32 program)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	const int				texUnit		= 1;

	gl.activeTexture	(GL_TEXTURE0+texUnit);
	gl.bindTexture		(GL_TEXTURE_2D, m_texture->getGLTexture());
	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);

	gl.uniform1i		(gl.getUniformLocation(program, "u_sampler"), texUnit);
}

qpTestResult TextureDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
{
	// \note Edges are ignored in comparison
	if (result.getWidth() < 2 || result.getHeight() < 2)
		throw tcu::NotSupportedError("Too small viewport");

	tcu::ConstPixelBufferAccess	compareArea			= tcu::getSubregion(result, 1, 1, result.getWidth()-2, result.getHeight()-2);
	tcu::PixelBufferAccess		maskArea			= tcu::getSubregion(errorMask, 1, 1, errorMask.getWidth()-2, errorMask.getHeight()-2);
	const tcu::Vec4				xScale				= tcu::Vec4(1.0f, 0.0f, 0.5f, -0.5f);
	const tcu::Vec4				yScale				= tcu::Vec4(0.0f, 1.0f, 0.5f, -0.5f);
	const float					w					= float(result.getWidth());
	const float					h					= float(result.getHeight());

	const tcu::Vec4				surfaceThreshold	= getSurfaceThreshold() / abs(m_derivScale);

	if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
	{
		const bool			isX				= m_func == DERIVATE_DFDX;
		const float			div				= isX ? w : h;
		const tcu::Vec4		scale			= isX ? xScale : yScale;
		tcu::Vec4			reference		= ((m_texValueMax - m_texValueMin) / div);
		const tcu::Vec4		opThreshold		= getDerivateThreshold(m_precision, m_texValueMin, m_texValueMax, reference);
		const tcu::Vec4		opThresholdW	= getDerivateThresholdWarning(m_precision, m_texValueMin, m_texValueMax, reference);
		const tcu::Vec4		threshold		= max(surfaceThreshold, opThreshold);
		const tcu::Vec4		thresholdW		= max(surfaceThreshold, opThresholdW);
		const int			numComps		= glu::getDataTypeFloatScalars(m_dataType);

		/* adjust the reference value for the correct dfdx or dfdy sample adjacency */
		reference	= reference * scale;

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying result image.\n"
			<< "\tValid derivative is " << LogVecComps(reference, numComps) << " with threshold " << LogVecComps(threshold, numComps)
			<< tcu::TestLog::EndMessage;

		// short circuit if result is strictly within the normal value error bounds.
		// This improves performance significantly.
		if (verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
								   reference, threshold, m_derivScale, m_derivBias,
								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "No incorrect derivatives found, result valid."
				<< tcu::TestLog::EndMessage;

			return QP_TEST_RESULT_PASS;
		}

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Verifying result image.\n"
			<< "\tValid derivative is " << LogVecComps(reference, numComps) << " with Warning threshold " << LogVecComps(thresholdW, numComps)
			<< tcu::TestLog::EndMessage;

		// Re-check with relaxed threshold
		if (verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
								   reference, thresholdW, m_derivScale, m_derivBias,
								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "No incorrect derivatives found, result valid with quality warning."
				<< tcu::TestLog::EndMessage;

			return QP_TEST_RESULT_QUALITY_WARNING;
		}


		// some pixels exceed error bounds calculated for normal values. Verify that these
		// potentially invalid pixels are in fact valid due to (for example) subnorm flushing.

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Initial verification failed, verifying image by calculating accurate error bounds for each result pixel.\n"
			<< "\tVerifying each result derivative is within its range of legal result values."
			<< tcu::TestLog::EndMessage;

		{
			const tcu::Vec4				valueRamp		= (m_texValueMax - m_texValueMin);
			Linear2DFunctionEvaluator	function;

			function.matrix.setRow(0, tcu::Vec3(valueRamp.x() / w, 0.0f, m_texValueMin.x()));
			function.matrix.setRow(1, tcu::Vec3(0.0f, valueRamp.y() / h, m_texValueMin.y()));
			function.matrix.setRow(2, tcu::Vec3(valueRamp.z() / w, valueRamp.z() / h, m_texValueMin.z() + m_texValueMin.z()) / 2.0f);
			function.matrix.setRow(3, tcu::Vec3(-valueRamp.w() / w, -valueRamp.w() / h, m_texValueMax.w() + m_texValueMax.w()) / 2.0f);

			return reverifyConstantDerivateWithFlushRelaxations(m_testCtx.getLog(), compareArea, maskArea,
																m_dataType, m_precision, m_derivScale,
																m_derivBias, surfaceThreshold, m_func,
																function);
		}
	}
	else
	{
		DE_ASSERT(m_func == DERIVATE_FWIDTH);
		const tcu::Vec4	dx				= ((m_texValueMax - m_texValueMin) / w) * xScale;
		const tcu::Vec4	dy				= ((m_texValueMax - m_texValueMin) / h) * yScale;
		const tcu::Vec4	reference		= tcu::abs(dx) + tcu::abs(dy);
		const tcu::Vec4	dxThreshold		= getDerivateThreshold(m_precision, m_texValueMin*xScale, m_texValueMax*xScale, dx);
		const tcu::Vec4	dyThreshold		= getDerivateThreshold(m_precision, m_texValueMin*yScale, m_texValueMax*yScale, dy);
		const tcu::Vec4	dxThresholdW	= getDerivateThresholdWarning(m_precision, m_texValueMin*xScale, m_texValueMax*xScale, dx);
		const tcu::Vec4	dyThresholdW	= getDerivateThresholdWarning(m_precision, m_texValueMin*yScale, m_texValueMax*yScale, dy);
		const tcu::Vec4	threshold		= max(surfaceThreshold, max(dxThreshold, dyThreshold));
		const tcu::Vec4	thresholdW		= max(surfaceThreshold, max(dxThresholdW, dyThresholdW));
		qpTestResult	testResult		= QP_TEST_RESULT_FAIL;

		testResult = verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
									  reference, threshold, m_derivScale, m_derivBias);

		if (testResult == QP_TEST_RESULT_PASS)
			return testResult;

		// Re-Check with relaxed threshold
		testResult = verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
									  reference, thresholdW, m_derivScale, m_derivBias);

		// If test is passing with relaxed threshold then mark quality warning
		if (testResult == QP_TEST_RESULT_PASS)
			testResult = QP_TEST_RESULT_QUALITY_WARNING;

		return testResult;
	}
}

ShaderDerivateTests::ShaderDerivateTests (Context& context)
	: TestCaseGroup(context, "derivate", "Derivate Function Tests")
{
}

ShaderDerivateTests::~ShaderDerivateTests (void)
{
}

struct FunctionSpec
{
	std::string		name;
	DerivateFunc	function;
	glu::DataType	dataType;
	glu::Precision	precision;

	FunctionSpec (const std::string& name_, DerivateFunc function_, glu::DataType dataType_, glu::Precision precision_)
		: name		(name_)
		, function	(function_)
		, dataType	(dataType_)
		, precision	(precision_)
	{
	}
};

void ShaderDerivateTests::init (void)
{
	static const struct
	{
		const char*		name;
		const char*		description;
		const char*		source;
	} s_linearDerivateCases[] =
	{
		{
			"linear",
			"Basic derivate of linearly interpolated argument",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"in_function",
			"Derivate of linear function argument",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"\n"
			"${PRECISION} ${DATATYPE} computeRes (${PRECISION} ${DATATYPE} value)\n"
			"{\n"
			"	return ${FUNC}(v_coord) * u_scale + u_bias;\n"
			"}\n"
			"\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res = computeRes(v_coord);\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"static_if",
			"Derivate of linearly interpolated value in static if",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res;\n"
			"	if (false)\n"
			"		res = ${FUNC}(-v_coord) * u_scale + u_bias;\n"
			"	else\n"
			"		res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"static_loop",
			"Derivate of linearly interpolated value in static loop",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
			"	for (int i = 0; i < 2; i++)\n"
			"		res += ${FUNC}(v_coord * float(i));\n"
			"	res = res * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"static_switch",
			"Derivate of linearly interpolated value in static switch",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res;\n"
			"	switch (1)\n"
			"	{\n"
			"		case 0:	res = ${FUNC}(-v_coord) * u_scale + u_bias;	break;\n"
			"		case 1:	res = ${FUNC}(v_coord) * u_scale + u_bias;	break;\n"
			"	}\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"uniform_if",
			"Derivate of linearly interpolated value in uniform if",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"uniform bool ub_true;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res;\n"
			"	if (ub_true)"
			"		res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
			"	else\n"
			"		res = ${FUNC}(-v_coord) * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"uniform_loop",
			"Derivate of linearly interpolated value in uniform loop",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"uniform int ui_two;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
			"	for (int i = 0; i < ui_two; i++)\n"
			"		res += ${FUNC}(v_coord * float(i));\n"
			"	res = res * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
		{
			"uniform_switch",
			"Derivate of linearly interpolated value in uniform switch",

			"#version 300 es\n"
			"in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
			"uniform int ui_one;\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res;\n"
			"	switch (ui_one)\n"
			"	{\n"
			"		case 0:	res = ${FUNC}(-v_coord) * u_scale + u_bias;	break;\n"
			"		case 1:	res = ${FUNC}(v_coord) * u_scale + u_bias;	break;\n"
			"	}\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n"
		},
	};

	static const struct
	{
		const char*		name;
		SurfaceType		surfaceType;
		int				numSamples;
	} s_fboConfigs[] =
	{
		{ "fbo",		SURFACETYPE_DEFAULT_FRAMEBUFFER,	0 },
		{ "fbo_msaa2",	SURFACETYPE_UNORM_FBO,				2 },
		{ "fbo_msaa4",	SURFACETYPE_UNORM_FBO,				4 },
		{ "fbo_float",	SURFACETYPE_FLOAT_FBO,				0 },
	};

	static const struct
	{
		const char*		name;
		deUint32		hint;
	} s_hints[] =
	{
		{ "fastest",	GL_FASTEST	},
		{ "nicest",		GL_NICEST	},
	};

	static const struct
	{
		const char*		name;
		SurfaceType		surfaceType;
		int				numSamples;
	} s_hintFboConfigs[] =
	{
		{ "default",		SURFACETYPE_DEFAULT_FRAMEBUFFER,	0 },
		{ "fbo_msaa4",		SURFACETYPE_UNORM_FBO,				4 },
		{ "fbo_float",		SURFACETYPE_FLOAT_FBO,				0 }
	};

	static const struct
	{
		const char*		name;
		SurfaceType		surfaceType;
		int				numSamples;
		deUint32		hint;
	} s_textureConfigs[] =
	{
		{ "basic",			SURFACETYPE_DEFAULT_FRAMEBUFFER,	0,	GL_DONT_CARE	},
		{ "msaa4",			SURFACETYPE_UNORM_FBO,				4,	GL_DONT_CARE	},
		{ "float_fastest",	SURFACETYPE_FLOAT_FBO,				0,	GL_FASTEST		},
		{ "float_nicest",	SURFACETYPE_FLOAT_FBO,				0,	GL_NICEST		},
	};

	// .dfdx, .dfdy, .fwidth
	for (int funcNdx = 0; funcNdx < DERIVATE_LAST; funcNdx++)
	{
		const DerivateFunc			function		= DerivateFunc(funcNdx);
		tcu::TestCaseGroup* const	functionGroup	= new tcu::TestCaseGroup(m_testCtx, getDerivateFuncCaseName(function), getDerivateFuncName(function));
		addChild(functionGroup);

		// .constant - no precision variants, checks that derivate of constant arguments is 0
		{
			tcu::TestCaseGroup* const constantGroup = new tcu::TestCaseGroup(m_testCtx, "constant", "Derivate of constant argument");
			functionGroup->addChild(constantGroup);

			for (int vecSize = 1; vecSize <= 4; vecSize++)
			{
				const glu::DataType dataType = vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
				constantGroup->addChild(new ConstantDerivateCase(m_context, glu::getDataTypeName(dataType), "", function, dataType));
			}
		}

		// Cases based on LinearDerivateCase
		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_linearDerivateCases); caseNdx++)
		{
			tcu::TestCaseGroup* const linearCaseGroup	= new tcu::TestCaseGroup(m_testCtx, s_linearDerivateCases[caseNdx].name, s_linearDerivateCases[caseNdx].description);
			const char*			source					= s_linearDerivateCases[caseNdx].source;
			functionGroup->addChild(linearCaseGroup);

			for (int vecSize = 1; vecSize <= 4; vecSize++)
			{
				for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
				{
					const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
					const glu::Precision	precision		= glu::Precision(precNdx);
					const SurfaceType		surfaceType		= SURFACETYPE_DEFAULT_FRAMEBUFFER;
					const int				numSamples		= 0;
					const deUint32			hint			= GL_DONT_CARE;
					ostringstream			caseName;

					if (caseNdx != 0 && precision == glu::PRECISION_LOWP)
						continue; // Skip as lowp doesn't actually produce any bits when rendered to default FB.

					caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);

					linearCaseGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples, source));
				}
			}
		}

		// Fbo cases
		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_fboConfigs); caseNdx++)
		{
			tcu::TestCaseGroup*	const	fboGroup		= new tcu::TestCaseGroup(m_testCtx, s_fboConfigs[caseNdx].name, "Derivate usage when rendering into FBO");
			const char*					source			= s_linearDerivateCases[0].source; // use source from .linear group
			const SurfaceType			surfaceType		= s_fboConfigs[caseNdx].surfaceType;
			const int					numSamples		= s_fboConfigs[caseNdx].numSamples;
			functionGroup->addChild(fboGroup);

			for (int vecSize = 1; vecSize <= 4; vecSize++)
			{
				for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
				{
					const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
					const glu::Precision	precision		= glu::Precision(precNdx);
					const deUint32			hint			= GL_DONT_CARE;
					ostringstream			caseName;

					if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
						continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.

					caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);

					fboGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples, source));
				}
			}
		}

		// .fastest, .nicest
		for (int hintCaseNdx = 0; hintCaseNdx < DE_LENGTH_OF_ARRAY(s_hints); hintCaseNdx++)
		{
			tcu::TestCaseGroup* const	hintGroup		= new tcu::TestCaseGroup(m_testCtx, s_hints[hintCaseNdx].name, "Shader derivate hints");
			const char*					source			= s_linearDerivateCases[0].source; // use source from .linear group
			const deUint32				hint			= s_hints[hintCaseNdx].hint;
			functionGroup->addChild(hintGroup);

			for (int fboCaseNdx = 0; fboCaseNdx < DE_LENGTH_OF_ARRAY(s_hintFboConfigs); fboCaseNdx++)
			{
				tcu::TestCaseGroup*	const	fboGroup		= new tcu::TestCaseGroup(m_testCtx, s_hintFboConfigs[fboCaseNdx].name, "");
				const SurfaceType			surfaceType		= s_hintFboConfigs[fboCaseNdx].surfaceType;
				const int					numSamples		= s_hintFboConfigs[fboCaseNdx].numSamples;
				hintGroup->addChild(fboGroup);

				for (int vecSize = 1; vecSize <= 4; vecSize++)
				{
					for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
					{
						const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
						const glu::Precision	precision		= glu::Precision(precNdx);
						ostringstream			caseName;

						if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
							continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.

						caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);

						fboGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples, source));
					}
				}
			}
		}

		// .texture
		{
			tcu::TestCaseGroup* const textureGroup = new tcu::TestCaseGroup(m_testCtx, "texture", "Derivate of texture lookup result");
			functionGroup->addChild(textureGroup);

			for (int texCaseNdx = 0; texCaseNdx < DE_LENGTH_OF_ARRAY(s_textureConfigs); texCaseNdx++)
			{
				tcu::TestCaseGroup*	const	caseGroup		= new tcu::TestCaseGroup(m_testCtx, s_textureConfigs[texCaseNdx].name, "");
				const SurfaceType			surfaceType		= s_textureConfigs[texCaseNdx].surfaceType;
				const int					numSamples		= s_textureConfigs[texCaseNdx].numSamples;
				const deUint32				hint			= s_textureConfigs[texCaseNdx].hint;
				textureGroup->addChild(caseGroup);

				for (int vecSize = 1; vecSize <= 4; vecSize++)
				{
					for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
					{
						const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
						const glu::Precision	precision		= glu::Precision(precNdx);
						ostringstream			caseName;

						if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
							continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.

						caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);

						caseGroup->addChild(new TextureDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples));
					}
				}
			}
		}
	}
}

} // Functional
} // gles3
} // deqp
