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

	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 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]));
}

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 bool 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;
}

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 bool 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;
}

// 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 bool		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 bool isOk = verify(result.getAccess(), errorMask.getAccess());

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

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

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

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Image comparison failed");
	}

	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:
	bool				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);
}

bool 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:
	bool				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);
	}
}

bool 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;
		const tcu::Vec4		reference	= ((m_coordMax - m_coordMin) / div) * scale;
		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_precision, m_coordMin*scale, m_coordMax*scale, reference);
		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
		const int			numComps	= glu::getDataTypeFloatScalars(m_dataType);

		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))
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "No incorrect derivatives found, result valid."
				<< tcu::TestLog::EndMessage;

			return true;
		}

		// 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		threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));

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

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

bool 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;
		const tcu::Vec4		reference	= ((m_texValueMax - m_texValueMin) / div) * scale;
		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_precision, m_texValueMin*scale, m_texValueMax*scale, reference);
		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
		const int			numComps	= glu::getDataTypeFloatScalars(m_dataType);

		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))
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "No incorrect derivatives found, result valid."
				<< tcu::TestLog::EndMessage;

			return true;
		}

		// 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	threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));

		return verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
									  reference, threshold, m_derivScale, m_derivBias);
	}
}

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
