/*-------------------------------------------------------------------------
 * 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 <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()) : (0);
	const int			endY				= (acceptOutOfBoundsAsAnyValue) ? (height - maxPositionDeviation.y()) : (0);
	const int			endZ				= (acceptOutOfBoundsAsAnyValue) ? (depth  - maxPositionDeviation.z()) : (0);

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

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

/*--------------------------------------------------------------------*//*!
 * \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.
 *
 * 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++)
			{
				Vec4	refPix		= reference.getPixel(x, y, z);
				Vec4	cmpPix		= result.getPixel(x, y, z);
				UVec4	refBits;
				UVec4	cmpBits;

				// memcpy() is the way to do float->uint32 reinterpretation.
				memcpy(refBits.getPtr(), refPix.getPtr(), 4*sizeof(deUint32));
				memcpy(cmpBits.getPtr(), cmpPix.getPtr(), 4*sizeof(deUint32));

				UVec4	diff		= abs(refBits.cast<int>() - cmpBits.cast<int>()).cast<deUint32>();
				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 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
