/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 * Copyright (c) 2016 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 "vktShaderRenderDerivateTests.hpp"
#include "vktShaderRender.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"

#include "gluTextureUtil.hpp"

#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuFloat.hpp"
#include "tcuInterval.hpp"

#include "deUniquePtr.hpp"
#include "glwEnums.hpp"

#include <sstream>
#include <string>

namespace vkt
{
namespace sr
{
namespace
{

using namespace vk;

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

enum
{
	VIEWPORT_WIDTH			= 99,
	VIEWPORT_HEIGHT			= 133,
	MAX_FAILED_MESSAGES		= 10
};

enum DerivateFunc
{
	DERIVATE_DFDX			= 0,
	DERIVATE_DFDXFINE,
	DERIVATE_DFDXCOARSE,

	DERIVATE_DFDY,
	DERIVATE_DFDYFINE,
	DERIVATE_DFDYCOARSE,

	DERIVATE_FWIDTH,
	DERIVATE_FWIDTHFINE,
	DERIVATE_FWIDTHCOARSE,

	DERIVATE_LAST
};

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

	SURFACETYPE_LAST
};

// Utilities

static const char* getDerivateFuncName (DerivateFunc func)
{
	switch (func)
	{
		case DERIVATE_DFDX:				return "dFdx";
		case DERIVATE_DFDXFINE:			return "dFdxFine";
		case DERIVATE_DFDXCOARSE:		return "dFdxCoarse";
		case DERIVATE_DFDY:				return "dFdy";
		case DERIVATE_DFDYFINE:			return "dFdyFine";
		case DERIVATE_DFDYCOARSE:		return "dFdyCoarse";
		case DERIVATE_FWIDTH:			return "fwidth";
		case DERIVATE_FWIDTHFINE:		return "fwidthFine";
		case DERIVATE_FWIDTHCOARSE:		return "fwidthCoarse";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static const char* getDerivateFuncCaseName (DerivateFunc func)
{
	switch (func)
	{
		case DERIVATE_DFDX:				return "dfdx";
		case DERIVATE_DFDXFINE:			return "dfdxfine";
		case DERIVATE_DFDXCOARSE:		return "dfdxcoarse";
		case DERIVATE_DFDY:				return "dfdy";
		case DERIVATE_DFDYFINE:			return "dfdyfine";
		case DERIVATE_DFDYCOARSE:		return "dfdycoarse";
		case DERIVATE_FWIDTH:			return "fwidth";
		case DERIVATE_FWIDTHFINE:		return "fwidthfine";
		case DERIVATE_FWIDTHCOARSE:		return "fwidthcoarse";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline bool isDfdxFunc (DerivateFunc func)
{
	return func == DERIVATE_DFDX || func == DERIVATE_DFDXFINE || func == DERIVATE_DFDXCOARSE;
}

static inline bool isDfdyFunc (DerivateFunc func)
{
	return func == DERIVATE_DFDY || func == DERIVATE_DFDYFINE || func == DERIVATE_DFDYCOARSE;
}

static inline bool isFwidthFunc (DerivateFunc func)
{
	return func == DERIVATE_FWIDTH || func == DERIVATE_FWIDTHFINE || func == DERIVATE_FWIDTHCOARSE;
}

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

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

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(isDfdxFunc(derivateFunc) || isDfdyFunc(derivateFunc));

	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	= (isDfdxFunc(derivateFunc))
													? (function.evaluateAt((float)x + 2.0f, (float)y + 0.5f))
													: (function.evaluateAt((float)x + 0.5f, (float)y + 2.0f));
		const tcu::Vec4	functionValueBackward	= (isDfdyFunc(derivateFunc))
													? (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" << ((isDfdxFunc(derivateFunc)) ? ('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;
}

// TestCase utils

struct DerivateCaseDefinition
{
	DerivateCaseDefinition (void)
	{
		func					= DERIVATE_LAST;
		dataType				= glu::TYPE_LAST;
		precision				= glu::PRECISION_LAST;
		inNonUniformControlFlow	= false;
		coordDataType			= glu::TYPE_LAST;
		coordPrecision			= glu::PRECISION_LAST;
		surfaceType				= SURFACETYPE_UNORM_FBO;
		numSamples				= 0;
	}

	DerivateFunc			func;
	glu::DataType			dataType;
	glu::Precision			precision;
	bool					inNonUniformControlFlow;

	glu::DataType			coordDataType;
	glu::Precision			coordPrecision;

	SurfaceType				surfaceType;
	int						numSamples;
};

struct DerivateCaseValues
{
	tcu::Vec4	coordMin;
	tcu::Vec4	coordMax;
	tcu::Vec4	derivScale;
	tcu::Vec4	derivBias;
};

struct TextureCaseValues
{
	tcu::Vec4	texValueMin;
	tcu::Vec4	texValueMax;
};

class DerivateUniformSetup : public UniformSetup
{
public:
						DerivateUniformSetup		(bool useSampler);
	virtual				~DerivateUniformSetup		(void);

	virtual void		setup						(ShaderRenderCaseInstance& instance, const tcu::Vec4&) const;

private:
	const bool			m_useSampler;
};

DerivateUniformSetup::DerivateUniformSetup (bool useSampler)
	: m_useSampler(useSampler)
{
}

DerivateUniformSetup::~DerivateUniformSetup (void)
{
}

// TriangleDerivateCaseInstance

class TriangleDerivateCaseInstance : public ShaderRenderCaseInstance
{
public:
									TriangleDerivateCaseInstance	(Context&						context,
																	 const UniformSetup&			uniformSetup,
																	 const DerivateCaseDefinition&	definitions,
																	 const DerivateCaseValues&		values);
	virtual							~TriangleDerivateCaseInstance	(void);
	virtual tcu::TestStatus			iterate							(void);
	DerivateCaseDefinition			getDerivateCaseDefinition		(void) { return m_definitions; }
	DerivateCaseValues				getDerivateCaseValues			(void) { return m_values; }

protected:
	virtual bool					verify							(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask) = 0;
	tcu::Vec4						getSurfaceThreshold				(void) const;
	virtual void					setupDefaultInputs				(void);

	const DerivateCaseDefinition&	m_definitions;
	const DerivateCaseValues&		m_values;
};

static VkSampleCountFlagBits getVkSampleCount (int numSamples)
{
	switch (numSamples)
	{
		case 0:		return VK_SAMPLE_COUNT_1_BIT;
		case 2:		return VK_SAMPLE_COUNT_2_BIT;
		case 4:		return VK_SAMPLE_COUNT_4_BIT;
		default:
			DE_ASSERT(false);
			return (VkSampleCountFlagBits)0;
	}
}

TriangleDerivateCaseInstance::TriangleDerivateCaseInstance (Context&						context,
															const UniformSetup&				uniformSetup,
															const DerivateCaseDefinition&	definitions,
															const DerivateCaseValues&		values)
	: ShaderRenderCaseInstance	(context, true, DE_NULL, uniformSetup, DE_NULL)
	, m_definitions				(definitions)
	, m_values					(values)
{
	m_renderSize	= tcu::UVec2(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	m_colorFormat	= vk::mapTextureFormat(glu::mapGLInternalFormat(m_definitions.surfaceType == SURFACETYPE_FLOAT_FBO ? GL_RGBA32UI : GL_RGBA8));

	setSampleCount(getVkSampleCount(definitions.numSamples));
}

TriangleDerivateCaseInstance::~TriangleDerivateCaseInstance (void)
{
}

tcu::Vec4 TriangleDerivateCaseInstance::getSurfaceThreshold (void) const
{
	switch (m_definitions.surfaceType)
	{
		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);
	}
}

void TriangleDerivateCaseInstance::setupDefaultInputs (void)
{
	const int		numVertices			= 4;
	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_values.coordMin.x(), m_values.coordMin.y(), m_values.coordMin.z(),								m_values.coordMax.w(),
		m_values.coordMin.x(), m_values.coordMax.y(), (m_values.coordMin.z()+m_values.coordMax.z())*0.5f,	(m_values.coordMin.w()+m_values.coordMax.w())*0.5f,
		m_values.coordMax.x(), m_values.coordMin.y(), (m_values.coordMin.z()+m_values.coordMax.z())*0.5f,	(m_values.coordMin.w()+m_values.coordMax.w())*0.5f,
		m_values.coordMax.x(), m_values.coordMax.y(), m_values.coordMax.z(),								m_values.coordMin.w()
	};

	addAttribute(0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (deUint32)sizeof(float), numVertices, positions);
	if (m_definitions.coordDataType != glu::TYPE_LAST)
		addAttribute(1u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 4 * (deUint32)sizeof(float), numVertices, coords);
}

tcu::TestStatus TriangleDerivateCaseInstance::iterate (void)
{
	tcu::TestLog&				log				= m_context.getTestContext().getLog();
	const deUint32				numVertices		= 4;
	const deUint32				numTriangles	= 2;
	const deUint16				indices[]		= { 0, 2, 1, 2, 3, 1 };
	tcu::TextureLevel			resultImage;

	if (m_definitions.inNonUniformControlFlow)
	{
		if (!m_context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
			throw tcu::NotSupportedError("Derivatives in dynamic control flow requires Vulkan 1.1");

		vk::VkPhysicalDeviceSubgroupProperties subgroupProperties;
		deMemset(&subgroupProperties, 0, sizeof(subgroupProperties));
		subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;

		vk::VkPhysicalDeviceProperties2 properties2;
		deMemset(&properties2, 0, sizeof(properties2));
		properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
		properties2.pNext = &subgroupProperties;

		m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties2);

		if (subgroupProperties.subgroupSize < 4)
			throw tcu::NotSupportedError("Derivatives in dynamic control flow requires subgroupSize >= 4");

		if ((subgroupProperties.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT) == 0)
			throw tcu::NotSupportedError("Derivative dynamic control flow tests require VK_SUBGROUP_FEATURE_BALLOT_BIT");

		if ((subgroupProperties.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
			throw tcu::NotSupportedError("Derivative dynamic control flow tests require subgroup supported stage including VK_SHADER_STAGE_FRAGMENT_BIT");
	}

	setup();

	render(numVertices, numTriangles, indices);

	{
		const tcu::TextureLevel&		renderedImage	= getResultImage();

		if (m_definitions.surfaceType == SURFACETYPE_FLOAT_FBO)
		{
			const tcu::TextureFormat	dataFormat		(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);

			resultImage.setStorage(dataFormat, renderedImage.getWidth(), renderedImage.getHeight());
			tcu::copy(resultImage.getAccess(), tcu::ConstPixelBufferAccess(dataFormat, renderedImage.getSize(), renderedImage.getAccess().getDataPtr()));
		}
		else
		{
			resultImage = renderedImage;
		}
	}

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

		const bool isOk = verify(resultImage.getAccess(), errorMask.getAccess());

		log << TestLog::ImageSet("Result", "Result images")
			<< TestLog::Image("Rendered", "Rendered image", resultImage);

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

		log << TestLog::EndImageSet;

		if (isOk)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Image comparison failed");
	}
}

void DerivateUniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4&) const
{
	DerivateCaseDefinition	definitions		= dynamic_cast<TriangleDerivateCaseInstance&>(instance).getDerivateCaseDefinition();
	DerivateCaseValues		values			= dynamic_cast<TriangleDerivateCaseInstance&>(instance).getDerivateCaseValues();

	DE_ASSERT(glu::isDataTypeFloatOrVec(definitions.dataType));

	instance.addUniform(0u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, glu::getDataTypeScalarSize(definitions.dataType) * sizeof(float), values.derivScale.getPtr());
	instance.addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, glu::getDataTypeScalarSize(definitions.dataType) * sizeof(float), values.derivBias.getPtr());

	if (m_useSampler)
		instance.useSampler(2u, 0u); // To the uniform binding location 2 bind the texture 0
}

// TriangleDerivateCase

class TriangleDerivateCase : public ShaderRenderCase
{
public:
									TriangleDerivateCase	(tcu::TestContext&		testCtx,
															 const std::string&		name,
															 const std::string&		description,
															 const UniformSetup*	uniformSetup);
	virtual							~TriangleDerivateCase	(void);

protected:
	mutable DerivateCaseDefinition	m_definitions;
	mutable DerivateCaseValues		m_values;
};

TriangleDerivateCase::TriangleDerivateCase (tcu::TestContext&		testCtx,
											const std::string&		name,
											const std::string&		description,
											const UniformSetup*		uniformSetup)
	: ShaderRenderCase		(testCtx, name, description, false, (ShaderEvaluator*)DE_NULL, uniformSetup, DE_NULL)
	, m_definitions			()
{
}

TriangleDerivateCase::~TriangleDerivateCase (void)
{
}

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

	const std::string vertexTmpl =
		"#version 450\n"
		"layout(location = 0) in highp vec4 a_position;\n"
		+ string(coordType != glu::TYPE_LAST ? "layout(location = 1) in ${PRECISION} ${DATATYPE} a_coord;\n"
											   "layout(location = 0) out ${PRECISION} ${DATATYPE} v_coord;\n" : "") +
		"out gl_PerVertex {\n"
		"	vec4 gl_Position;\n"
		"};\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		+ string(coordType != glu::TYPE_LAST ? "	v_coord = a_coord;\n" : "") +
		"}\n";

	map<string, string> vertexParams;

	if (coordType != glu::TYPE_LAST)
	{
		vertexParams["PRECISION"]	= glu::getPrecisionName(precision);
		vertexParams["DATATYPE"]	= glu::getDataTypeName(coordType);
	}

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

// ConstantDerivateCaseInstance

class ConstantDerivateCaseInstance : public TriangleDerivateCaseInstance
{
public:
								ConstantDerivateCaseInstance	(Context&						context,
																 const UniformSetup&			uniformSetup,
																 const DerivateCaseDefinition&	definitions,
																 const DerivateCaseValues&		values);
	virtual						~ConstantDerivateCaseInstance	(void);

	virtual bool				verify							(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
};

ConstantDerivateCaseInstance::ConstantDerivateCaseInstance (Context&							context,
															const UniformSetup&					uniformSetup,
															const DerivateCaseDefinition&		definitions,
															const DerivateCaseValues&			values)
	: TriangleDerivateCaseInstance	(context, uniformSetup, definitions, values)
{
}

ConstantDerivateCaseInstance::~ConstantDerivateCaseInstance (void)
{
}

bool ConstantDerivateCaseInstance::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_values.derivScale);

	return verifyConstantDerivate(m_context.getTestContext().getLog(), result, errorMask, m_definitions.dataType,
								  reference, threshold, m_values.derivScale, m_values.derivBias);
}

// ConstantDerivateCase

class ConstantDerivateCase : public TriangleDerivateCase
{
public:
							ConstantDerivateCase		(tcu::TestContext&		testCtx,
														 const std::string&		name,
														 const std::string&		description,
														 DerivateFunc			func,
														 glu::DataType			type);
	virtual					~ConstantDerivateCase		(void);

	virtual	void			initPrograms				(vk::SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance				(Context& context) const;
};

ConstantDerivateCase::ConstantDerivateCase (tcu::TestContext&		testCtx,
											const std::string&		name,
											const std::string&		description,
											DerivateFunc			func,
											glu::DataType			type)
	: TriangleDerivateCase	(testCtx, name, description, new DerivateUniformSetup(false))
{
	m_definitions.func				= func;
	m_definitions.dataType			= type;
	m_definitions.precision			= glu::PRECISION_HIGHP;
}

ConstantDerivateCase::~ConstantDerivateCase (void)
{
}

TestInstance* ConstantDerivateCase::createInstance (Context& context) const
{
	DE_ASSERT(m_uniformSetup != DE_NULL);
	return new ConstantDerivateCaseInstance(context, *m_uniformSetup, m_definitions, m_values);
}

void ConstantDerivateCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const char* fragmentTmpl =
		"#version 450\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
		"layout(binding = 1, std140) uniform Bias { ${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_definitions.precision);
	fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_definitions.dataType);
	fragmentParams["FUNC"]				= getDerivateFuncName(m_definitions.func);
	fragmentParams["VALUE"]				= m_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "vec4(1.0, 7.2, -1e5, 0.0)" :
										  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? "vec3(1e2, 8.0, 0.01)" :
										  m_definitions.dataType == glu::TYPE_FLOAT_VEC2 ? "vec2(-0.0, 2.7)" :
										  /* TYPE_FLOAT */								   "7.7";
	fragmentParams["CAST_TO_OUTPUT"]	= m_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
										  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
										  m_definitions.dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
										  /* TYPE_FLOAT */								   "vec4(res, 0.0, 0.0, 1.0)";

	std::string fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
	programCollection.glslSources.add("vert") << glu::VertexSource(genVertexSource(m_definitions.coordDataType, m_definitions.coordPrecision));
	programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);

	m_values.derivScale		= tcu::Vec4(1e3f, 1e3f, 1e3f, 1e3f);
	m_values.derivBias		= tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
}

// Linear cases

class LinearDerivateUniformSetup : public DerivateUniformSetup
{
public:
					LinearDerivateUniformSetup		(bool useSampler, BaseUniformType usedDefaultUniform);
	virtual			~LinearDerivateUniformSetup		(void);

	virtual void	setup							(ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;

private:
	const BaseUniformType	m_usedDefaultUniform;
};

LinearDerivateUniformSetup::LinearDerivateUniformSetup (bool useSampler, BaseUniformType usedDefaultUniform)
	: DerivateUniformSetup	(useSampler)
	, m_usedDefaultUniform	(usedDefaultUniform)
{
}

LinearDerivateUniformSetup::~LinearDerivateUniformSetup (void)
{
}

void LinearDerivateUniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
{
	DerivateUniformSetup::setup(instance, constCoords);

	if (m_usedDefaultUniform != U_LAST)
		switch (m_usedDefaultUniform)
		{
			case UB_TRUE:
			case UI_ONE:
			case UI_TWO:
				instance.useUniform(2u, m_usedDefaultUniform);
				break;
			default:
				DE_ASSERT(false);
				break;
		}
}

class LinearDerivateCaseInstance : public TriangleDerivateCaseInstance
{
public:
								LinearDerivateCaseInstance	(Context&						context,
															 const UniformSetup&			uniformSetup,
															 const DerivateCaseDefinition&	definitions,
															 const DerivateCaseValues&		values);
	virtual						~LinearDerivateCaseInstance	(void);

	virtual bool				verify						(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
};

LinearDerivateCaseInstance::LinearDerivateCaseInstance (Context&						context,
														const UniformSetup&				uniformSetup,
														const DerivateCaseDefinition&	definitions,
														const DerivateCaseValues&		values)
	: TriangleDerivateCaseInstance	(context, uniformSetup, definitions, values)
{
}

LinearDerivateCaseInstance::~LinearDerivateCaseInstance (void)
{
}

bool LinearDerivateCaseInstance::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_values.derivScale);

	if (isDfdxFunc(m_definitions.func) || isDfdyFunc(m_definitions.func))
	{
		const bool			isX			= isDfdxFunc(m_definitions.func);
		const float			div			= isX ? float(result.getWidth()) : float(result.getHeight());
		const tcu::Vec4		scale		= isX ? xScale : yScale;
		tcu::Vec4			reference	= ((m_values.coordMax - m_values.coordMin) / div);
		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_definitions.precision, m_values.coordMin, m_values.coordMax, reference);
		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
		const int			numComps	= glu::getDataTypeFloatScalars(m_definitions.dataType);

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

		m_context.getTestContext().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_context.getTestContext().getLog(), result, errorMask, m_definitions.dataType,
								   reference, threshold, m_values.derivScale, m_values.derivBias,
								   LOG_NOTHING))
		{
			m_context.getTestContext().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_context.getTestContext().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::UVec2			viewportSize	(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
			const float					w				= float(viewportSize.x());
			const float					h				= float(viewportSize.y());
			const tcu::Vec4				valueRamp		= (m_values.coordMax - m_values.coordMin);
			Linear2DFunctionEvaluator	function;

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

			return reverifyConstantDerivateWithFlushRelaxations(m_context.getTestContext().getLog(), result, errorMask,
																m_definitions.dataType, m_definitions.precision, m_values.derivScale,
																m_values.derivBias, surfaceThreshold, m_definitions.func,
																function);
		}
	}
	else
	{
		DE_ASSERT(isFwidthFunc(m_definitions.func));
		const float			w			= float(result.getWidth());
		const float			h			= float(result.getHeight());

		const tcu::Vec4		dx			= ((m_values.coordMax - m_values.coordMin) / w) * xScale;
		const tcu::Vec4		dy			= ((m_values.coordMax - m_values.coordMin) / h) * yScale;
		const tcu::Vec4		reference	= tcu::abs(dx) + tcu::abs(dy);
		const tcu::Vec4		dxThreshold	= getDerivateThreshold(m_definitions.precision, m_values.coordMin*xScale, m_values.coordMax*xScale, dx);
		const tcu::Vec4		dyThreshold	= getDerivateThreshold(m_definitions.precision, m_values.coordMin*yScale, m_values.coordMax*yScale, dy);
		const tcu::Vec4		threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));

		return verifyConstantDerivate(m_context.getTestContext().getLog(), result, errorMask, m_definitions.dataType,
									  reference, threshold, m_values.derivScale, m_values.derivBias);
	}
}

// LinearDerivateCase

class LinearDerivateCase : public TriangleDerivateCase
{
public:
							LinearDerivateCase			(tcu::TestContext&		testCtx,
														 const std::string&		name,
														 const std::string&		description,
														 DerivateFunc			func,
														 glu::DataType			type,
														 glu::Precision			precision,
														 bool					inNonUniformControlFlow,
														 SurfaceType			surfaceType,
														 int					numSamples,
														 const std::string&		fragmentSrcTmpl,
														 BaseUniformType		usedDefaultUniform);
	virtual					~LinearDerivateCase			(void);

	virtual	void			initPrograms				(vk::SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance				(Context& context) const;

private:
	const std::string		m_fragmentTmpl;
};

LinearDerivateCase::LinearDerivateCase (tcu::TestContext&		testCtx,
										const std::string&		name,
										const std::string&		description,
										DerivateFunc			func,
										glu::DataType			type,
										glu::Precision			precision,
										bool					inNonUniformControlFlow,
										SurfaceType				surfaceType,
										int						numSamples,
										const std::string&		fragmentSrcTmpl,
										BaseUniformType			usedDefaultUniform)
	: TriangleDerivateCase	(testCtx, name, description, new LinearDerivateUniformSetup(false, usedDefaultUniform))
	, m_fragmentTmpl		(fragmentSrcTmpl)
{
	m_definitions.func						= func;
	m_definitions.dataType					= type;
	m_definitions.precision					= precision;
	m_definitions.inNonUniformControlFlow	= inNonUniformControlFlow;
	m_definitions.coordDataType				= m_definitions.dataType;
	m_definitions.coordPrecision			= m_definitions.precision;
	m_definitions.surfaceType				= surfaceType;
	m_definitions.numSamples				= numSamples;
}

LinearDerivateCase::~LinearDerivateCase (void)
{
}

TestInstance* LinearDerivateCase::createInstance (Context& context) const
{
	DE_ASSERT(m_uniformSetup != DE_NULL);
	return new LinearDerivateCaseInstance(context, *m_uniformSetup, m_definitions, m_values);
}

void LinearDerivateCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const SpirvVersion				spirvVersion = m_definitions.inNonUniformControlFlow ? vk::SPIRV_VERSION_1_3 : vk::SPIRV_VERSION_1_0;
	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, spirvVersion, 0u);

	const tcu::UVec2	viewportSize	(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	const float			w				= float(viewportSize.x());
	const float			h				= float(viewportSize.y());
	const bool			packToInt		= m_definitions.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_definitions.precision);
	fragmentParams["PRECISION"]			= glu::getPrecisionName(m_definitions.precision);
	fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_definitions.dataType);
	fragmentParams["FUNC"]				= getDerivateFuncName(m_definitions.func);

	if (packToInt)
	{
		fragmentParams["CAST_TO_OUTPUT"]	= m_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
											  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
											  m_definitions.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_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
											  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
											  m_definitions.dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
											  /* TYPE_FLOAT */								   "vec4(res, 0.0, 0.0, 1.0)";
	}

	std::string fragmentSrc = tcu::StringTemplate(m_fragmentTmpl).specialize(fragmentParams);
	programCollection.glslSources.add("vert") << glu::VertexSource(genVertexSource(m_definitions.coordDataType, m_definitions.coordPrecision));
	programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSrc) << buildOptions;

	switch (m_definitions.precision)
	{
		case glu::PRECISION_HIGHP:
			m_values.coordMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
			m_values.coordMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
			break;

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

		case glu::PRECISION_LOWP:
			m_values.coordMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
			m_values.coordMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
			break;

		default:
			DE_ASSERT(false);
	}

	if (m_definitions.surfaceType == SURFACETYPE_FLOAT_FBO)
	{
		// No scale or bias used for accuracy.
		m_values.derivScale	= tcu::Vec4(1.0f);
		m_values.derivBias		= tcu::Vec4(0.0f);
	}
	else
	{
		// Compute scale - bias that normalizes to 0..1 range.
		const tcu::Vec4 dx = (m_values.coordMax - m_values.coordMin) / tcu::Vec4(w, w, w*0.5f, -w*0.5f);
		const tcu::Vec4 dy = (m_values.coordMax - m_values.coordMin) / tcu::Vec4(h, h, h*0.5f, -h*0.5f);

		if (isDfdxFunc(m_definitions.func))
			m_values.derivScale = 0.5f / dx;
		else if (isDfdyFunc(m_definitions.func))
			m_values.derivScale = 0.5f / dy;
		else if (isFwidthFunc(m_definitions.func))
			m_values.derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
		else
			DE_ASSERT(false);

		m_values.derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	}
}

// TextureDerivateCaseInstance

class TextureDerivateCaseInstance : public TriangleDerivateCaseInstance
{
public:
								TextureDerivateCaseInstance		(Context&							context,
																 const UniformSetup&				uniformSetup,
																 const DerivateCaseDefinition&		definitions,
																 const DerivateCaseValues&			values,
																 const TextureCaseValues&			textureValues);
	virtual						~TextureDerivateCaseInstance	(void);

	virtual bool				verify							(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);

private:
	const TextureCaseValues&	m_textureValues;
};

TextureDerivateCaseInstance::TextureDerivateCaseInstance (Context&							context,
														  const UniformSetup&				uniformSetup,
														  const DerivateCaseDefinition&		definitions,
														  const DerivateCaseValues&			values,
														  const TextureCaseValues&			textureValues)
	: TriangleDerivateCaseInstance	(context, uniformSetup, definitions, values)
	, m_textureValues				(textureValues)
{
	de::MovePtr<tcu::Texture2D>		texture;

	// Lowp and mediump cases use RGBA16F format, while highp uses RGBA32F.
	{
		const tcu::UVec2			viewportSize	(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
		const tcu::TextureFormat	format			= glu::mapGLInternalFormat(m_definitions.precision == glu::PRECISION_HIGHP ? GL_RGBA32F : GL_RGBA16F);

		texture = de::MovePtr<tcu::Texture2D>(new tcu::Texture2D(format, viewportSize.x(), viewportSize.y()));
		texture->allocLevel(0);
	}

	// Fill with gradients.
	{
		const tcu::PixelBufferAccess level0 = texture->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_textureValues.texValueMin + (m_textureValues.texValueMax - m_textureValues.texValueMin)*s, x, y);
			}
		}
	}

	de::SharedPtr<TextureBinding>	testTexture		(new TextureBinding(texture.release(),
																		tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
																					 tcu::Sampler::CLAMP_TO_EDGE,
																					 tcu::Sampler::CLAMP_TO_EDGE,
																					 tcu::Sampler::NEAREST,
																					 tcu::Sampler::NEAREST)));
	m_textures.push_back(testTexture);
}

TextureDerivateCaseInstance::~TextureDerivateCaseInstance (void)
{
}

bool TextureDerivateCaseInstance::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_values.derivScale);

	if (isDfdxFunc(m_definitions.func) || isDfdyFunc(m_definitions.func))
	{
		const bool			isX			= isDfdxFunc(m_definitions.func);
		const float			div			= isX ? w : h;
		const tcu::Vec4		scale		= isX ? xScale : yScale;
		tcu::Vec4			reference	= ((m_textureValues.texValueMax - m_textureValues.texValueMin) / div);
		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_definitions.precision, m_textureValues.texValueMin, m_textureValues.texValueMax, reference);
		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
		const int			numComps	= glu::getDataTypeFloatScalars(m_definitions.dataType);

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

		m_context.getTestContext().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_context.getTestContext().getLog(), compareArea, maskArea, m_definitions.dataType,
								   reference, threshold, m_values.derivScale, m_values.derivBias,
								   LOG_NOTHING))
		{
			m_context.getTestContext().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_context.getTestContext().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_textureValues.texValueMax - m_textureValues.texValueMin);
			Linear2DFunctionEvaluator	function;

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

			return reverifyConstantDerivateWithFlushRelaxations(m_context.getTestContext().getLog(), compareArea, maskArea,
																m_definitions.dataType, m_definitions.precision, m_values.derivScale,
																m_values.derivBias, surfaceThreshold, m_definitions.func,
																function);
		}
	}
	else
	{
		DE_ASSERT(isFwidthFunc(m_definitions.func));
		const tcu::Vec4	dx			= ((m_textureValues.texValueMax - m_textureValues.texValueMin) / w) * xScale;
		const tcu::Vec4	dy			= ((m_textureValues.texValueMax - m_textureValues.texValueMin) / h) * yScale;
		const tcu::Vec4	reference	= tcu::abs(dx) + tcu::abs(dy);
		const tcu::Vec4	dxThreshold	= getDerivateThreshold(m_definitions.precision, m_textureValues.texValueMin*xScale, m_textureValues.texValueMax*xScale, dx);
		const tcu::Vec4	dyThreshold	= getDerivateThreshold(m_definitions.precision, m_textureValues.texValueMin*yScale, m_textureValues.texValueMax*yScale, dy);
		const tcu::Vec4	threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));

		return verifyConstantDerivate(m_context.getTestContext().getLog(), compareArea, maskArea, m_definitions.dataType,
									  reference, threshold, m_values.derivScale, m_values.derivBias);
	}
}

// TextureDerivateCase

class TextureDerivateCase : public TriangleDerivateCase
{
public:
							TextureDerivateCase			(tcu::TestContext&		testCtx,
														 const std::string&		name,
														 const std::string&		description,
														 DerivateFunc			func,
														 glu::DataType			type,
														 glu::Precision			precision,
														 SurfaceType			surfaceType,
														 int					numSamples);
	virtual					~TextureDerivateCase		(void);

	virtual	void			initPrograms				(vk::SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance				(Context& context) const;

private:
	mutable TextureCaseValues	m_textureValues;
};

TextureDerivateCase::TextureDerivateCase (tcu::TestContext&		testCtx,
										  const std::string&	name,
										  const std::string&	description,
										  DerivateFunc			func,
										  glu::DataType			type,
										  glu::Precision		precision,
										  SurfaceType			surfaceType,
										  int					numSamples)
	: TriangleDerivateCase	(testCtx, name, description, new DerivateUniformSetup(true))
{
	m_definitions.dataType			= type;
	m_definitions.func				= func;
	m_definitions.precision			= precision;
	m_definitions.coordDataType		= glu::TYPE_FLOAT_VEC2;
	m_definitions.coordPrecision	= glu::PRECISION_HIGHP;
	m_definitions.surfaceType		= surfaceType;
	m_definitions.numSamples		= numSamples;
}

TextureDerivateCase::~TextureDerivateCase (void)
{
}

TestInstance* TextureDerivateCase::createInstance (Context& context) const
{
	DE_ASSERT(m_uniformSetup != DE_NULL);
	return new TextureDerivateCaseInstance(context, *m_uniformSetup, m_definitions, m_values, m_textureValues);
}

void TextureDerivateCase::initPrograms (vk::SourceCollections& programCollection) const
{
	// Generate shader
	{
		const char* fragmentTmpl =
			"#version 450\n"
			"layout(location = 0) in highp vec2 v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2) uniform ${PRECISION} sampler2D u_sampler;\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_definitions.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_definitions.precision);
		fragmentParams["PRECISION"]			= glu::getPrecisionName(m_definitions.precision);
		fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_definitions.dataType);
		fragmentParams["FUNC"]				= getDerivateFuncName(m_definitions.func);
		fragmentParams["SWIZZLE"]			= m_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "" :
											  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? ".xyz" :
											  m_definitions.dataType == glu::TYPE_FLOAT_VEC2 ? ".xy" :
											  /* TYPE_FLOAT */								   ".x";

		if (packToInt)
		{
			fragmentParams["CAST_TO_OUTPUT"]	= m_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
												  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
												  m_definitions.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_definitions.dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
												  m_definitions.dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
												  m_definitions.dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
												  /* TYPE_FLOAT */								   "vec4(res, 0.0, 0.0, 1.0)";
		}

		std::string fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
		programCollection.glslSources.add("vert") << glu::VertexSource(genVertexSource(m_definitions.coordDataType, m_definitions.coordPrecision));
		programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
	}

	// 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_definitions.precision)
	{
		case glu::PRECISION_HIGHP:
			m_textureValues.texValueMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
			m_textureValues.texValueMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
			break;

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

		case glu::PRECISION_LOWP:
			m_textureValues.texValueMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
			m_textureValues.texValueMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
			break;

		default:
			DE_ASSERT(false);
	}

	// Texture coordinates
	m_values.coordMin = tcu::Vec4(0.0f);
	m_values.coordMax = tcu::Vec4(1.0f);

	if (m_definitions.surfaceType == SURFACETYPE_FLOAT_FBO)
	{
		// No scale or bias used for accuracy.
		m_values.derivScale		= tcu::Vec4(1.0f);
		m_values.derivBias		= tcu::Vec4(0.0f);
	}
	else
	{
		// Compute scale - bias that normalizes to 0..1 range.
		const tcu::UVec2	viewportSize	(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
		const float			w				= float(viewportSize.x());
		const float			h				= float(viewportSize.y());
		const tcu::Vec4		dx				= (m_textureValues.texValueMax - m_textureValues.texValueMin) / tcu::Vec4(w, w, w*0.5f, -w*0.5f);
		const tcu::Vec4		dy				= (m_textureValues.texValueMax - m_textureValues.texValueMin) / tcu::Vec4(h, h, h*0.5f, -h*0.5f);

		if (isDfdxFunc(m_definitions.func))
			m_values.derivScale = 0.5f / dx;
		else if (isDfdyFunc(m_definitions.func))
			m_values.derivScale = 0.5f / dy;
		else if (isFwidthFunc(m_definitions.func))
			m_values.derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
		else
			DE_ASSERT(false);

		m_values.derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	}
}

// ShaderDerivateTests

class ShaderDerivateTests : public tcu::TestCaseGroup
{
public:
							ShaderDerivateTests		(tcu::TestContext& testCtx);
	virtual					~ShaderDerivateTests	(void);

	virtual void			init					(void);

private:
							ShaderDerivateTests		(const ShaderDerivateTests&);		// not allowed!
	ShaderDerivateTests&	operator=				(const ShaderDerivateTests&);		// not allowed!
};

ShaderDerivateTests::ShaderDerivateTests (tcu::TestContext& testCtx)
	: TestCaseGroup(testCtx, "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;
		BaseUniformType		usedDefaultUniform;
		bool				inNonUniformControlFlow;
	} s_linearDerivateCases[] =
	{
		{
			"linear",
			"Basic derivate of linearly interpolated argument",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${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",

			U_LAST,
			false
		},
		{
			"in_function",
			"Derivate of linear function argument",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${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",

			U_LAST,
			false
		},
		{
			"static_if",
			"Derivate of linearly interpolated value in static if",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${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",

			U_LAST,
			false
		},
		{
			"static_loop",
			"Derivate of linearly interpolated value in static loop",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${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",

			U_LAST,
			false
		},
		{
			"static_switch",
			"Derivate of linearly interpolated value in static switch",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${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",

			U_LAST,
			false
		},
		{
			"uniform_if",
			"Derivate of linearly interpolated value in uniform if",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2, std140) uniform Ui_true { 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",

			UB_TRUE,
			false
		},
		{
			"uniform_loop",
			"Derivate of linearly interpolated value in uniform loop",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2, std140) uniform Ui_two { 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",

			UI_TWO,
			false
		},
		{
			"uniform_switch",
			"Derivate of linearly interpolated value in uniform switch",

			"#version 450\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2, std140) uniform Ui_one { 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",

			UI_ONE,
			false
		},
		{
			"dynamic_if",
			"Derivate of linearly interpolated value in static if",

			"#version 450\n"
			"#extension GL_KHR_shader_subgroup_ballot : require\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2, std140) uniform Ui_one { int ui_one; };\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res;\n"
			"	bool non_uniform = ((uint(gl_FragCoord.x * 0.4) + uint(gl_FragCoord.y * 0.3)) & 2) != 0;\n"
			"	uvec4 quad_ballot = uvec4(0);\n"
			"	quad_ballot[gl_SubgroupInvocationID >> 5] = 0xf << (gl_SubgroupInvocationID & 0x1c);\n"
			"	bool quad_uniform = (subgroupBallot(non_uniform) & quad_ballot) == quad_ballot;\n"
			"	if (quad_uniform)\n"
			"		res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
			"	else\n"
			"		res = ${FUNC}(v_coord * float(ui_one)) * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n",

			UI_ONE,
			true
		},
		{
			"dynamic_loop",
			"Derivate of linearly interpolated value in uniform loop",

			"#version 450\n"
			"#extension GL_KHR_shader_subgroup_ballot : require\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2, std140) uniform Ui_one { int ui_one; };\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
			"	bool non_uniform = ((uint(gl_FragCoord.x * 0.4) + uint(gl_FragCoord.y * 0.3)) & 2) != 0;\n"
			"	uvec4 quad_ballot = uvec4(0);\n"
			"	quad_ballot[gl_SubgroupInvocationID >> 5] = 0xf << (gl_SubgroupInvocationID & 0x1c);\n"
			"	bool quad_uniform = (subgroupBallot(non_uniform) & quad_ballot) == quad_ballot;\n"
			"	for (int i = 0; i < ui_one + int(quad_uniform); i++)\n"
			"		res = ${FUNC}(v_coord * float(i - int(quad_uniform) + 1));\n"
			"	res = res * u_scale + u_bias;\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n",

			UI_ONE,
			true
		},
		{
			"dynamic_switch",
			"Derivate of linearly interpolated value in uniform switch",

			"#version 450\n"
			"#extension GL_KHR_shader_subgroup_ballot : require\n"
			"layout(location = 0) in ${PRECISION} ${DATATYPE} v_coord;\n"
			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
			"layout(binding = 0, std140) uniform Scale { ${PRECISION} ${DATATYPE} u_scale; };\n"
			"layout(binding = 1, std140) uniform Bias { ${PRECISION} ${DATATYPE} u_bias; };\n"
			"layout(binding = 2, std140) uniform Ui_one { int ui_one; };\n"
			"void main (void)\n"
			"{\n"
			"	${PRECISION} ${DATATYPE} res;\n"
			"	bool non_uniform = ((uint(gl_FragCoord.x * 0.4) + uint(gl_FragCoord.y * 0.3)) & 2) != 0;\n"
			"	uvec4 quad_ballot = uvec4(0);\n"
			"	quad_ballot[gl_SubgroupInvocationID >> 5] = 0xf << (gl_SubgroupInvocationID & 0x1c);\n"
			"	bool quad_uniform = (subgroupBallot(non_uniform) & quad_ballot) == quad_ballot;\n"
			"	switch (int(quad_uniform))\n"
			"	{\n"
			"		case 0:	res = ${FUNC}(v_coord) * u_scale + u_bias;	break;\n"
			"		case 1:	res = ${FUNC}(v_coord * float(ui_one)) * u_scale + u_bias;	break;\n"
			"	}\n"
			"	o_color = ${CAST_TO_OUTPUT};\n"
			"}\n",

			UI_ONE,
			true
		},
	};

	static const struct
	{
		const char*		name;
		SurfaceType		surfaceType;
		int				numSamples;
	} s_fboConfigs[] =
	{
		{ "fbo",			SURFACETYPE_UNORM_FBO,		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;
		SurfaceType		surfaceType;
		int				numSamples;
	} s_textureConfigs[] =
	{
		{ "basic",			SURFACETYPE_UNORM_FBO,		0 },
		{ "msaa4",			SURFACETYPE_UNORM_FBO,		4 },
		{ "float",			SURFACETYPE_FLOAT_FBO,		0 },
	};

	// .dfdx[fine|coarse], .dfdy[fine|coarse], .fwidth[fine|coarse]
	for (int funcNdx = 0; funcNdx < DERIVATE_LAST; funcNdx++)
	{
		const DerivateFunc					function		= DerivateFunc(funcNdx);
		de::MovePtr<tcu::TestCaseGroup>		functionGroup	(new tcu::TestCaseGroup(m_testCtx, getDerivateFuncCaseName(function), getDerivateFuncName(function)));

		// .constant - no precision variants, checks that derivate of constant arguments is 0
		{
			de::MovePtr<tcu::TestCaseGroup>	constantGroup	(new tcu::TestCaseGroup(m_testCtx, "constant", "Derivate of constant argument"));

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

			functionGroup->addChild(constantGroup.release());
		}

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

			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_UNORM_FBO;
					const int				numSamples		= 0;
					std::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_testCtx, caseName.str(), "", function, dataType, precision, s_linearDerivateCases[caseNdx].inNonUniformControlFlow, surfaceType, numSamples, source, s_linearDerivateCases[caseNdx].usedDefaultUniform));
				}
			}

			functionGroup->addChild(linearCaseGroup.release());
		}

		// Fbo cases
		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_fboConfigs); caseNdx++)
		{
			de::MovePtr<tcu::TestCaseGroup>	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;

			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);
					std::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_testCtx, caseName.str(), "", function, dataType, precision, false, surfaceType, numSamples, source, U_LAST));
				}
			}

			functionGroup->addChild(fboGroup.release());
		}

		// .texture
		{
			de::MovePtr<tcu::TestCaseGroup>		textureGroup	(new tcu::TestCaseGroup(m_testCtx, "texture", "Derivate of texture lookup result"));

			for (int texCaseNdx = 0; texCaseNdx < DE_LENGTH_OF_ARRAY(s_textureConfigs); texCaseNdx++)
			{
				de::MovePtr<tcu::TestCaseGroup>	caseGroup		(new tcu::TestCaseGroup(m_testCtx, s_textureConfigs[texCaseNdx].name, ""));
				const SurfaceType				surfaceType		= s_textureConfigs[texCaseNdx].surfaceType;
				const int						numSamples		= s_textureConfigs[texCaseNdx].numSamples;

				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);
						std::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_testCtx, caseName.str(), "", function, dataType, precision, surfaceType, numSamples));
					}
				}

				textureGroup->addChild(caseGroup.release());
			}

			functionGroup->addChild(textureGroup.release());
		}

		addChild(functionGroup.release());
	}
}

} // anonymous

tcu::TestCaseGroup* createDerivateTests (tcu::TestContext& testCtx)
{
	return new ShaderDerivateTests(testCtx);
}

} // sr
} // vkt
