/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * 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 Image comparison utilities.
 *//*--------------------------------------------------------------------*/

#include "tcuImageCompare.hpp"
#include "tcuSurface.hpp"
#include "tcuFuzzyImageCompare.hpp"
#include "tcuBilinearImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuFloat.hpp"

#include <string.h>

namespace tcu
{

namespace
{

void computeScaleAndBias (const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, tcu::Vec4& scale, tcu::Vec4& bias)
{
	Vec4 minVal;
	Vec4 maxVal;
	const float eps = 0.0001f;

	{
		Vec4 refMin;
		Vec4 refMax;
		estimatePixelValueRange(reference, refMin, refMax);

		minVal	= refMin;
		maxVal	= refMax;
	}

	{
		Vec4 resMin;
		Vec4 resMax;

		estimatePixelValueRange(result, resMin, resMax);

		minVal[0] = de::min(minVal[0], resMin[0]);
		minVal[1] = de::min(minVal[1], resMin[1]);
		minVal[2] = de::min(minVal[2], resMin[2]);
		minVal[3] = de::min(minVal[3], resMin[3]);

		maxVal[0] = de::max(maxVal[0], resMax[0]);
		maxVal[1] = de::max(maxVal[1], resMax[1]);
		maxVal[2] = de::max(maxVal[2], resMax[2]);
		maxVal[3] = de::max(maxVal[3], resMax[3]);
	}

	for (int c = 0; c < 4; c++)
	{
		if (maxVal[c] - minVal[c] < eps)
		{
			scale[c]	= (maxVal[c] < eps) ? 1.0f : (1.0f / maxVal[c]);
			bias[c]		= (c == 3) ? (1.0f - maxVal[c]*scale[c]) : (0.0f - minVal[c]*scale[c]);
		}
		else
		{
			scale[c]	= 1.0f / (maxVal[c] - minVal[c]);
			bias[c]		= 0.0f - minVal[c]*scale[c];
		}
	}
}

static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& errorMask, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue)
{
	const tcu::IVec4	okColor				(0, 255, 0, 255);
	const tcu::IVec4	errorColor			(255, 0, 0, 255);
	const int			width				= reference.getWidth();
	const int			height				= reference.getHeight();
	const int			depth				= reference.getDepth();
	int					numFailingPixels	= 0;

	// Accept pixels "sampling" over the image bounds pixels since "taps" could be anything
	const int			beginX				= (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.x()) : (0);
	const int			beginY				= (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.y()) : (0);
	const int			beginZ				= (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.z()) : (0);
	const int			endX				= (acceptOutOfBoundsAsAnyValue) ? (width  - maxPositionDeviation.x()) : (width);
	const int			endY				= (acceptOutOfBoundsAsAnyValue) ? (height - maxPositionDeviation.y()) : (height);
	const int			endZ				= (acceptOutOfBoundsAsAnyValue) ? (depth  - maxPositionDeviation.z()) : (depth);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
	DE_ASSERT(endX > 0 && endY > 0 && endZ > 0);	// most likely a bug

	tcu::clear(errorMask, okColor);

	for (int z = beginZ; z < endZ; z++)
	{
		for (int y = beginY; y < endY; y++)
		{
			for (int x = beginX; x < endX; x++)
			{
				const IVec4	refPix = reference.getPixelInt(x, y, z);
				const IVec4	cmpPix = result.getPixelInt(x, y, z);

				// Exact match
				{
					const UVec4	diff = abs(refPix - cmpPix).cast<deUint32>();
					const bool	isOk = boolAll(lessThanEqual(diff, threshold));

					if (isOk)
						continue;
				}

				// Find matching pixels for both result and reference pixel

				{
					bool pixelFoundForReference = false;

					// Find deviated result pixel for reference

					for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth  - 1, z + maxPositionDeviation.z()) && !pixelFoundForReference; ++sz)
					for (int sy = de::max(0, y - maxPositionDeviation.y()); sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForReference; ++sy)
					for (int sx = de::max(0, x - maxPositionDeviation.x()); sx <= de::min(width  - 1, x + maxPositionDeviation.x()) && !pixelFoundForReference; ++sx)
					{
						const IVec4	deviatedCmpPix	= result.getPixelInt(sx, sy, sz);
						const UVec4	diff			= abs(refPix - deviatedCmpPix).cast<deUint32>();
						const bool	isOk			= boolAll(lessThanEqual(diff, threshold));

						pixelFoundForReference		= isOk;
					}

					if (!pixelFoundForReference)
					{
						errorMask.setPixel(errorColor, x, y, z);
						++numFailingPixels;
						continue;
					}
				}
				{
					bool pixelFoundForResult = false;

					// Find deviated reference pixel for result

					for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth  - 1, z + maxPositionDeviation.z()) && !pixelFoundForResult; ++sz)
					for (int sy = de::max(0, y - maxPositionDeviation.y()); sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForResult; ++sy)
					for (int sx = de::max(0, x - maxPositionDeviation.x()); sx <= de::min(width  - 1, x + maxPositionDeviation.x()) && !pixelFoundForResult; ++sx)
					{
						const IVec4	deviatedRefPix	= reference.getPixelInt(sx, sy, sz);
						const UVec4	diff			= abs(cmpPix - deviatedRefPix).cast<deUint32>();
						const bool	isOk			= boolAll(lessThanEqual(diff, threshold));

						pixelFoundForResult			= isOk;
					}

					if (!pixelFoundForResult)
					{
						errorMask.setPixel(errorColor, x, y, z);
						++numFailingPixels;
						continue;
					}
				}
			}
		}
	}

	return numFailingPixels;
}

} // anonymous

/*--------------------------------------------------------------------*//*!
 * \brief Fuzzy image comparison
 *
 * This image comparison is designed for comparing images rendered by 3D
 * graphics APIs such as OpenGL. The comparison allows small local differences
 * and compensates for aliasing.
 *
 * The algorithm first performs light blurring on both images and then
 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
 * defined by adjecent pixels. This compensates for both 1-pixel deviations
 * in geometry and aliasing in texture data.
 *
 * Error metric is computed based on the differences. On valid images the
 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
 * 0.05.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note				Currently supports only UNORM_INT8 formats
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Error metric threshold (good values are 0.02-0.05)
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool fuzzyCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, float threshold, CompareLogMode logMode)
{
	FuzzyCompareParams	params;		// Use defaults.
	TextureLevel		errorMask		(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
	float				difference		= fuzzyCompare(params, reference, result, errorMask.getAccess());
	bool				isOk			= difference <= threshold;
	Vec4				pixelBias		(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale		(1.0f, 1.0f, 1.0f, 1.0f);

	if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// Generate more accurate error mask.
		params.maxSampleSkip = 0;
		fuzzyCompare(params, reference, result, errorMask.getAccess());

		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computeScaleAndBias(reference, result, pixelScale, pixelBias);

		if (!isOk)
			log << TestLog::Message << "Image comparison failed: difference = " << difference << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result, pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return isOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fuzzy image comparison
 *
 * This image comparison is designed for comparing images rendered by 3D
 * graphics APIs such as OpenGL. The comparison allows small local differences
 * and compensates for aliasing.
 *
 * The algorithm first performs light blurring on both images and then
 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
 * defined by adjecent pixels. This compensates for both 1-pixel deviations
 * in geometry and aliasing in texture data.
 *
 * Error metric is computed based on the differences. On valid images the
 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
 * 0.05.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note				Currently supports only UNORM_INT8 formats
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Error metric threshold (good values are 0.02-0.05)
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool fuzzyCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, float threshold, CompareLogMode logMode)
{
	return fuzzyCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold, logMode);
}

static deInt64 computeSquaredDiffSum (const ConstPixelBufferAccess& ref, const ConstPixelBufferAccess& cmp, const PixelBufferAccess& diffMask, int diffFactor)
{
	TCU_CHECK_INTERNAL(ref.getFormat().type == TextureFormat::UNORM_INT8 && cmp.getFormat().type == TextureFormat::UNORM_INT8);
	DE_ASSERT(ref.getWidth() == cmp.getWidth() && ref.getWidth() == diffMask.getWidth());
	DE_ASSERT(ref.getHeight() == cmp.getHeight() && ref.getHeight() == diffMask.getHeight());

	deInt64 diffSum = 0;

	for (int y = 0; y < cmp.getHeight(); y++)
	{
		for (int x = 0; x < cmp.getWidth(); x++)
		{
			IVec4	a		= ref.getPixelInt(x, y);
			IVec4	b		= cmp.getPixelInt(x, y);
			IVec4	diff	= abs(a - b);
			int		sum		= diff.x() + diff.y() + diff.z() + diff.w();
			int		sqSum	= diff.x()*diff.x() + diff.y()*diff.y() + diff.z()*diff.z() + diff.w()*diff.w();

			diffMask.setPixel(tcu::RGBA(deClamp32(sum*diffFactor, 0, 255), deClamp32(255-sum*diffFactor, 0, 255), 0, 255).toVec(), x, y);

			diffSum += (deInt64)sqSum;
		}
	}

	return diffSum;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel difference accuracy metric
 *
 * Computes accuracy metric using per-pixel differences between reference
 * and result images.
 *
 * \note					Supports only integer- and fixed-point formats
 * \param log				Test log for results
 * \param imageSetName		Name for image set when logging results
 * \param imageSetDesc		Description for image set
 * \param reference			Reference image
 * \param result			Result image
 * \param bestScoreDiff		Scaling factor
 * \param worstScoreDiff	Scaling factor
 * \param logMode			Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
int measurePixelDiffAccuracy (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
{
	TextureLevel	diffMask		(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
	int				diffFactor		= 8;
	deInt64			squaredSum		= computeSquaredDiffSum(reference, result, diffMask.getAccess(), diffFactor);
	float			sum				= deFloatSqrt((float)squaredSum);
	int				score			= deClamp32(deFloorFloatToInt32(100.0f - (de::max(sum-(float)bestScoreDiff, 0.0f) / (float)(worstScoreDiff-bestScoreDiff))*100.0f), 0, 100);
	const int		failThreshold	= 10;
	Vec4			pixelBias		(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4			pixelScale		(1.0f, 1.0f, 1.0f, 1.0f);

	if (logMode == COMPARE_LOG_EVERYTHING || score <= failThreshold)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computeScaleAndBias(reference, result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",			result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",		reference,	pixelScale, pixelBias)
			<< TestLog::Image("DiffMask",	"Difference",		diffMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",			result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	if (logMode != COMPARE_LOG_ON_ERROR || score <= failThreshold)
		log << TestLog::Integer("DiffSum", "Squared difference sum", "", QP_KEY_TAG_NONE, squaredSum)
			<< TestLog::Integer("Score", "Score", "", QP_KEY_TAG_QUALITY, score);

	return score;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel difference accuracy metric
 *
 * Computes accuracy metric using per-pixel differences between reference
 * and result images.
 *
 * \note					Supports only integer- and fixed-point formats
 * \param log				Test log for results
 * \param imageSetName		Name for image set when logging results
 * \param imageSetDesc		Description for image set
 * \param reference			Reference image
 * \param result			Result image
 * \param bestScoreDiff		Scaling factor
 * \param worstScoreDiff	Scaling factor
 * \param logMode			Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
int measurePixelDiffAccuracy (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
{
	return measurePixelDiffAccuracy(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), bestScoreDiff, worstScoreDiff, logMode);
}

/*--------------------------------------------------------------------*//*!
 * Returns the index of float in a float space without denormals
 * so that:
 * 1) f(0.0) = 0
 * 2) f(-0.0) = 0
 * 3) f(b) = f(a) + 1  <==>  b = nextAfter(a)
 *
 * See computeFloatFlushRelaxedULPDiff for details
 *//*--------------------------------------------------------------------*/
static deInt32 getPositionOfIEEEFloatWithoutDenormals (float x)
{
	DE_ASSERT(!deIsNaN(x)); // not sane

	if (x == 0.0f)
		return 0;
	else if (x < 0.0f)
		return -getPositionOfIEEEFloatWithoutDenormals(-x);
	else
	{
		DE_ASSERT(x > 0.0f);

		const tcu::Float32 f(x);

		if (f.isDenorm())
		{
			// Denorms are flushed to zero
			return 0;
		}
		else
		{
			// sign is 0, and it's a normal number. Natural position is its bit
			// pattern but since we've collapsed the denorms, we must remove
			// the gap here too to keep the float enumeration continuous.
			//
			// Denormals occupy one exponent pattern. Removing one from
			// exponent should to the trick. Add one since the removed range
			// contained one representable value, 0.
			return (deInt32)(f.bits() - (1u << 23u) + 1u);
		}
	}
}

static deUint32 computeFloatFlushRelaxedULPDiff (float a, float b)
{
	if (deIsNaN(a) && deIsNaN(b))
		return 0;
	else if (deIsNaN(a) || deIsNaN(b))
	{
		return 0xFFFFFFFFu;
	}
	else
	{
		// Using the "definition 5" in Muller, Jean-Michel. "On the definition of ulp (x)" (2005)
		// assuming a floating point space is IEEE single precision floating point space without
		// denormals (and signed zeros).
		const deInt32 aIndex = getPositionOfIEEEFloatWithoutDenormals(a);
		const deInt32 bIndex = getPositionOfIEEEFloatWithoutDenormals(b);
		return (deUint32)de::abs(aIndex - bIndex);
	}
}

static tcu::UVec4 computeFlushRelaxedULPDiff (const tcu::Vec4& a, const tcu::Vec4& b)
{
	return tcu::UVec4(computeFloatFlushRelaxedULPDiff(a.x(), b.x()),
					  computeFloatFlushRelaxedULPDiff(a.y(), b.y()),
					  computeFloatFlushRelaxedULPDiff(a.z(), b.z()),
					  computeFloatFlushRelaxedULPDiff(a.w(), b.w()));
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison uses ULP (units in last place) metric for computing the
 * difference between floating-point values and thus this function can
 * be used only for comparing floating-point texture data. In ULP calculation
 * the denormal numbers are allowed to be flushed to zero.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatUlpThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode)
{
	int					width				= reference.getWidth();
	int					height				= reference.getHeight();
	int					depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	UVec4				maxDiff				(0, 0, 0, 0);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	TCU_CHECK(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				const Vec4	refPix	= reference.getPixel(x, y, z);
				const Vec4	cmpPix	= result.getPixel(x, y, z);
				const UVec4	diff	= computeFlushRelaxedULPDiff(refPix, cmpPix);
				const bool	isOk	= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for floating-point and fixed-point formats.
 * Difference is computed in floating-point space.
 *
 * On failure an error image is generated that shows where the failing
 * pixels are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const Vec4& threshold, CompareLogMode logMode)
{
	int					width				= reference.getWidth();
	int					height				= reference.getHeight();
	int					depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	Vec4				maxDiff				(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				Vec4	refPix		= reference.getPixel(x, y, z);
				Vec4	cmpPix		= result.getPixel(x, y, z);

				Vec4	diff		= abs(refPix - cmpPix);
				bool	isOk		= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * color. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for floating-point and fixed-point formats.
 * Difference is computed in floating-point space.
 *
 * On failure an error image is generated that shows where the failing
 * pixels are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference color
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Vec4& reference, const ConstPixelBufferAccess& result, const Vec4& threshold, CompareLogMode logMode)
{
	const int			width				= result.getWidth();
	const int			height				= result.getHeight();
	const int			depth				= result.getDepth();

	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	Vec4				maxDiff				(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				const Vec4	cmpPix		= result.getPixel(x, y, z);
				const Vec4	diff		= abs(reference - cmpPix);
				const bool	isOk		= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(result, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result image is normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << ", reference = " << reference << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode)
{
	int					width				= reference.getWidth();
	int					height				= reference.getHeight();
	int					depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	UVec4				maxDiff				(0, 0, 0, 0);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				IVec4	refPix		= reference.getPixelInt(x, y, z);
				IVec4	cmpPix		= result.getPixelInt(x, y, z);

				UVec4	diff		= abs(refPix - cmpPix).cast<deUint32>();
				bool	isOk		= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel depth/stencil threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for depth and depth/stencil images.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed depth difference (stencil must be exact)
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool dsThresholdCompare(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const float threshold, CompareLogMode logMode)
{
	int					width = reference.getWidth();
	int					height = reference.getHeight();
	int					depth = reference.getDepth();
	TextureLevel		errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask = errorMaskStorage.getAccess();
	float				maxDiff = 0.0;
	bool				allStencilOk = true;
	bool				hasDepth = tcu::hasDepthComponent(result.getFormat().order);
	bool				hasStencil = tcu::hasStencilComponent(result.getFormat().order);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				bool	isOk = true;

				if (hasDepth)
				{
					float	refDepth = reference.getPixDepth(x, y, z);
					float	cmpDepth = result.getPixDepth(x, y, z);

					float	diff = refDepth - cmpDepth;
					isOk = diff <= threshold;
					maxDiff = (float) deMax(maxDiff, diff);
				}

				if (hasStencil)
				{
					deUint8 refStencil = (deUint8) reference.getPixStencil(x, y, z);
					deUint8 cmpStencil = (deUint8) result.getPixStencil(x, y, z);

					bool isStencilOk = (refStencil == cmpStencil);
					allStencilOk = allStencilOk && isStencilOk;
					isOk = isOk && isStencilOk;
				}

				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
			}
		}
	}

	bool compareOk = (maxDiff <= threshold) && allStencilOk;

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		if (!compareOk)
		{
			if (maxDiff > threshold)
				log << TestLog::Message << "Depth comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;
			if (!allStencilOk)
				log << TestLog::Message << "Stencil comparison failed" << TestLog::EndMessage;
		}

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			// TODO: Convert depth/stencil buffers into separate depth & stencil for logging?
//			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
//			<< TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask", "Error mask", errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
#if 0
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
			<< TestLog::EndImageSet;
#endif
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based deviation-ignoring comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if there is no pixel matching the given threshold
 * value in the search volume.
 *
 * If the search volume contains out-of-bounds pixels, comparison can be set
 * to either ignore these pixels in search or to accept any pixel that has
 * out-of-bounds pixels in its search volume.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log							Test log for results
 * \param imageSetName					Name for image set when logging results
 * \param imageSetDesc					Description for image set
 * \param reference						Reference image
 * \param result						Result image
 * \param threshold						Maximum allowed difference
 * \param maxPositionDeviation			Maximum allowed distance in the search
 *										volume.
 * \param acceptOutOfBoundsAsAnyValue	Accept any pixel in the boundary region
 * \param logMode						Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdPositionDeviationCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, CompareLogMode logMode)
{
	const int			width				= reference.getWidth();
	const int			height				= reference.getHeight();
	const int			depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	const int			numFailingPixels	= findNumPositionDeviationFailingPixels(errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
	const bool			compareOk			= numFailingPixels == 0;
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log	<< TestLog::Message
				<< "Image comparison failed:\n"
				<< "\tallowed position deviation = " << maxPositionDeviation << "\n"
				<< "\tcolor threshold = " << threshold
				<< TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based deviation-ignoring comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Pixel fails the test if there is no pixel matching the given
 * threshold value in the search volume. Comparison fails if the number of
 * failing pixels exceeds the given limit.
 *
 * If the search volume contains out-of-bounds pixels, comparison can be set
 * to either ignore these pixels in search or to accept any pixel that has
 * out-of-bounds pixels in its search volume.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log							Test log for results
 * \param imageSetName					Name for image set when logging results
 * \param imageSetDesc					Description for image set
 * \param reference						Reference image
 * \param result						Result image
 * \param threshold						Maximum allowed difference
 * \param maxPositionDeviation			Maximum allowed distance in the search
 *										volume.
 * \param acceptOutOfBoundsAsAnyValue	Accept any pixel in the boundary region
 * \param maxAllowedFailingPixels		Maximum number of failing pixels
 * \param logMode						Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdPositionDeviationErrorThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, int maxAllowedFailingPixels, CompareLogMode logMode)
{
	const int			width				= reference.getWidth();
	const int			height				= reference.getHeight();
	const int			depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	const int			numFailingPixels	= findNumPositionDeviationFailingPixels(errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
	const bool			compareOk			= numFailingPixels <= maxAllowedFailingPixels;
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log	<< TestLog::Message
				<< "Image comparison failed:\n"
				<< "\tallowed position deviation = " << maxPositionDeviation << "\n"
				<< "\tcolor threshold = " << threshold
				<< TestLog::EndMessage;
		log << TestLog::Message << "Number of failing pixels = " << numFailingPixels << ", max allowed = " << maxAllowedFailingPixels << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool pixelThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, const RGBA& threshold, CompareLogMode logMode)
{
	return intThresholdCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold.toIVec().cast<deUint32>(), logMode);
}

/*--------------------------------------------------------------------*//*!
 * \brief Bilinear image comparison
 *
 * \todo [pyry] Describe
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note				Currently supports only RGBA, UNORM_INT8 formats
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum local difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool bilinearCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const RGBA threshold, CompareLogMode logMode)
{
	TextureLevel		errorMask		(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
	bool				isOk			= bilinearCompare(reference, result, errorMask, threshold);
	Vec4				pixelBias		(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale		(1.0f, 1.0f, 1.0f, 1.0f);

	if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computeScaleAndBias(reference, result, pixelScale, pixelBias);

		if (!isOk)
			log << TestLog::Message << "Image comparison failed, threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result, pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return isOk;
}

} // tcu
