/*-------------------------------------------------------------------------
 * 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 Texture compare (shadow) result verifier.
 *//*--------------------------------------------------------------------*/

#include "tcuTexCompareVerifier.hpp"
#include "tcuTexVerifierUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "deMath.h"

namespace tcu
{

using namespace TexVerifierUtil;

// Generic utilities

#if defined(DE_DEBUG)
static bool isSamplerSupported (const Sampler& sampler)
{
	return sampler.compare != Sampler::COMPAREMODE_NONE &&
		   isWrapModeSupported(sampler.wrapS)			&&
		   isWrapModeSupported(sampler.wrapT)			&&
		   isWrapModeSupported(sampler.wrapR);
}
#endif // DE_DEBUG

struct CmpResultSet
{
	bool	isTrue;
	bool	isFalse;

	CmpResultSet (void)
		: isTrue	(false)
		, isFalse	(false)
	{
	}
};

static CmpResultSet execCompare (const Sampler::CompareMode	compareMode,
								 const float				cmpValue_,
								 const float				cmpReference_,
								 const int					referenceBits,
								 const bool					isFixedPoint)
{
	const bool		clampValues		= isFixedPoint;	// if comparing against a floating point texture, ref (and value) is not clamped
	const float		cmpValue		= (clampValues) ? (de::clamp(cmpValue_, 0.0f, 1.0f)) : (cmpValue_);
	const float		cmpReference	= (clampValues) ? (de::clamp(cmpReference_, 0.0f, 1.0f)) : (cmpReference_);
	const float		err				= computeFixedPointError(referenceBits);
	CmpResultSet	res;

	switch (compareMode)
	{
		case Sampler::COMPAREMODE_LESS:
			res.isTrue	= cmpReference-err < cmpValue;
			res.isFalse	= cmpReference+err >= cmpValue;
			break;

		case Sampler::COMPAREMODE_LESS_OR_EQUAL:
			res.isTrue	= cmpReference-err <= cmpValue;
			res.isFalse	= cmpReference+err > cmpValue;
			break;

		case Sampler::COMPAREMODE_GREATER:
			res.isTrue	= cmpReference+err > cmpValue;
			res.isFalse	= cmpReference-err <= cmpValue;
			break;

		case Sampler::COMPAREMODE_GREATER_OR_EQUAL:
			res.isTrue	= cmpReference+err >= cmpValue;
			res.isFalse	= cmpReference-err < cmpValue;
			break;

		case Sampler::COMPAREMODE_EQUAL:
			res.isTrue	= de::inRange(cmpValue, cmpReference-err, cmpReference+err);
			res.isFalse	= err != 0.0f || cmpValue != cmpReference;
			break;

		case Sampler::COMPAREMODE_NOT_EQUAL:
			res.isTrue	= err != 0.0f || cmpValue != cmpReference;
			res.isFalse	= de::inRange(cmpValue, cmpReference-err, cmpReference+err);
			break;

		case Sampler::COMPAREMODE_ALWAYS:
			res.isTrue	= true;
			break;

		case Sampler::COMPAREMODE_NEVER:
			res.isFalse	= true;
			break;

		default:
			DE_ASSERT(false);
	}

	DE_ASSERT(res.isTrue || res.isFalse);
	return res;
}

static inline bool isResultInSet (const CmpResultSet resultSet, const float result, const int resultBits)
{
	const float err		= computeFixedPointError(resultBits);
	const float	minR	= result-err;
	const float	maxR	= result+err;

	return (resultSet.isTrue	&& de::inRange(1.0f, minR, maxR)) ||
		   (resultSet.isFalse	&& de::inRange(0.0f, minR, maxR));
}

static inline bool coordsInBounds (const ConstPixelBufferAccess& access, int x, int y, int z)
{
	return de::inBounds(x, 0, access.getWidth()) && de::inBounds(y, 0, access.getHeight()) && de::inBounds(z, 0, access.getDepth());
}

static float lookupDepth (const tcu::ConstPixelBufferAccess& access, const Sampler& sampler, int i, int j, int k)
{
	if (coordsInBounds(access, i, j, k))
		return access.getPixDepth(i, j, k);
	else
		return sampleTextureBorder<float>(access.getFormat(), sampler).x();
}

// lookup depth value at a point that is guaranteed to not sample border such as cube map faces.
static float lookupDepthNoBorder (const tcu::ConstPixelBufferAccess& access, const Sampler& sampler, int i, int j, int k = 0)
{
	DE_UNREF(sampler);
	DE_ASSERT(coordsInBounds(access, i, j, k));
	return access.getPixDepth(i, j, k);
}

// Values are in order (0,0), (1,0), (0,1), (1,1)
static float bilinearInterpolate (const Vec4& values, const float x, const float y)
{
	const float		v00		= values[0];
	const float		v10		= values[1];
	const float		v01		= values[2];
	const float		v11		= values[3];
	const float		res		= v00*(1.0f-x)*(1.0f-y) + v10*x*(1.0f-y) + v01*(1.0f-x)*y + v11*x*y;
	return res;
}

static bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
{
	const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);

	if (format.order == TextureFormat::D)
	{
		// depth internal formats cannot be non-normalized integers
		return channelClass != tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
	}
	else if (format.order == TextureFormat::DS)
	{
		// combined formats have no single channel class, detect format manually
		switch (format.type)
		{
			case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return false;
			case tcu::TextureFormat::UNSIGNED_INT_24_8:				return true;

			default:
			{
				// unknown format
				DE_ASSERT(false);
				return true;
			}
		}
	}

	return false;
}

static bool isLinearCompareValid (const Sampler::CompareMode	compareMode,
								  const TexComparePrecision&	prec,
								  const Vec2&					depths,
								  const Vec2&					fBounds,
								  const float					cmpReference,
								  const float					result,
								  const bool					isFixedPointDepth)
{
	DE_ASSERT(0.0f <= fBounds.x() && fBounds.x() <= fBounds.y() && fBounds.y() <= 1.0f);

	const float			d0			= depths[0];
	const float			d1			= depths[1];

	const CmpResultSet	cmp0		= execCompare(compareMode, d0, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp1		= execCompare(compareMode, d1, cmpReference, prec.referenceBits, isFixedPointDepth);

	const deUint32		isTrue		= (deUint32(cmp0.isTrue)<<0)
									| (deUint32(cmp1.isTrue)<<1);
	const deUint32		isFalse		= (deUint32(cmp0.isFalse)<<0)
									| (deUint32(cmp1.isFalse)<<1);

	// Interpolation parameters
	const float			f0			= fBounds.x();
	const float			f1			= fBounds.y();

	// Error parameters
	const float			pcfErr		= computeFixedPointError(prec.pcfBits);
	const float			resErr		= computeFixedPointError(prec.resultBits);
	const float			totalErr	= pcfErr+resErr;

	// Iterate over all valid combinations.
	for (deUint32 comb = 0; comb < (1<<2); comb++)
	{
		// Filter out invalid combinations.
		if (((comb & isTrue) | (~comb & isFalse)) != (1<<2)-1)
			continue;

		const bool		cmp0True	= ((comb>>0)&1) != 0;
		const bool		cmp1True	= ((comb>>1)&1) != 0;

		const float		ref0		= cmp0True ? 1.0f : 0.0f;
		const float		ref1		= cmp1True ? 1.0f : 0.0f;

		const float		v0			= ref0*(1.0f-f0) + ref1*f0;
		const float		v1			= ref0*(1.0f-f1) + ref1*f1;
		const float		minV		= de::min(v0, v1);
		const float		maxV		= de::max(v0, v1);
		const float		minR		= minV-totalErr;
		const float		maxR		= maxV+totalErr;

		if (de::inRange(result, minR, maxR))
			return true;
	}

	return false;
}

static inline BVec4 extractBVec4 (const deUint32 val, int offset)
{
	return BVec4(((val>>(offset+0))&1) != 0,
				 ((val>>(offset+1))&1) != 0,
				 ((val>>(offset+2))&1) != 0,
				 ((val>>(offset+3))&1) != 0);
}

static bool isBilinearAnyCompareValid (const Sampler::CompareMode	compareMode,
									   const TexComparePrecision&	prec,
									   const Vec4&					depths,
									   const float					cmpReference,
									   const float					result,
									   const bool					isFixedPointDepth)
{
	DE_ASSERT(prec.pcfBits == 0);

	const float			d0			= depths[0];
	const float			d1			= depths[1];
	const float			d2			= depths[2];
	const float			d3			= depths[3];

	const CmpResultSet	cmp0		= execCompare(compareMode, d0, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp1		= execCompare(compareMode, d1, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp2		= execCompare(compareMode, d2, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp3		= execCompare(compareMode, d3, cmpReference, prec.referenceBits, isFixedPointDepth);

	const bool			canBeTrue	= cmp0.isTrue || cmp1.isTrue || cmp2.isTrue || cmp3.isTrue;
	const bool			canBeFalse	= cmp0.isFalse || cmp1.isFalse || cmp2.isFalse || cmp3.isFalse;

	const float			resErr		= computeFixedPointError(prec.resultBits);

	const float			minBound	= canBeFalse ? 0.0f : 1.0f;
	const float			maxBound	= canBeTrue ? 1.0f : 0.0f;

	return de::inRange(result, minBound-resErr, maxBound+resErr);
}

static bool isBilinearPCFCompareValid (const Sampler::CompareMode	compareMode,
									   const TexComparePrecision&	prec,
									   const Vec4&					depths,
									   const Vec2&					xBounds,
									   const Vec2&					yBounds,
									   const float					cmpReference,
									   const float					result,
									   const bool					isFixedPointDepth)
{
	DE_ASSERT(0.0f <= xBounds.x() && xBounds.x() <= xBounds.y() && xBounds.y() <= 1.0f);
	DE_ASSERT(0.0f <= yBounds.x() && yBounds.x() <= yBounds.y() && yBounds.y() <= 1.0f);
	DE_ASSERT(prec.pcfBits > 0);

	const float			d0			= depths[0];
	const float			d1			= depths[1];
	const float			d2			= depths[2];
	const float			d3			= depths[3];

	const CmpResultSet	cmp0		= execCompare(compareMode, d0, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp1		= execCompare(compareMode, d1, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp2		= execCompare(compareMode, d2, cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp3		= execCompare(compareMode, d3, cmpReference, prec.referenceBits, isFixedPointDepth);

	const deUint32		isTrue		= (deUint32(cmp0.isTrue)<<0)
									| (deUint32(cmp1.isTrue)<<1)
									| (deUint32(cmp2.isTrue)<<2)
									| (deUint32(cmp3.isTrue)<<3);
	const deUint32		isFalse		= (deUint32(cmp0.isFalse)<<0)
									| (deUint32(cmp1.isFalse)<<1)
									| (deUint32(cmp2.isFalse)<<2)
									| (deUint32(cmp3.isFalse)<<3);

	// Interpolation parameters
	const float			x0			= xBounds.x();
	const float			x1			= xBounds.y();
	const float			y0			= yBounds.x();
	const float			y1			= yBounds.y();

	// Error parameters
	const float			pcfErr		= computeFixedPointError(prec.pcfBits);
	const float			resErr		= computeFixedPointError(prec.resultBits);
	const float			totalErr	= pcfErr+resErr;

	// Iterate over all valid combinations.
	// \note It is not enough to compute minmax over all possible result sets, as ranges may
	//		 not necessarily overlap, i.e. there are gaps between valid ranges.
	for (deUint32 comb = 0; comb < (1<<4); comb++)
	{
		// Filter out invalid combinations:
		//  1) True bit is set in comb but not in isTrue => sample can not be true
		//  2) True bit is NOT set in comb and not in isFalse => sample can not be false
		if (((comb & isTrue) | (~comb & isFalse)) != (1<<4)-1)
			continue;

		const BVec4		cmpTrue		= extractBVec4(comb, 0);
		const Vec4		refVal		= select(Vec4(1.0f), Vec4(0.0f), cmpTrue);

		const float		v0			= bilinearInterpolate(refVal, x0, y0);
		const float		v1			= bilinearInterpolate(refVal, x1, y0);
		const float		v2			= bilinearInterpolate(refVal, x0, y1);
		const float		v3			= bilinearInterpolate(refVal, x1, y1);
		const float		minV		= de::min(v0, de::min(v1, de::min(v2, v3)));
		const float		maxV		= de::max(v0, de::max(v1, de::max(v2, v3)));
		const float		minR		= minV-totalErr;
		const float		maxR		= maxV+totalErr;

		if (de::inRange(result, minR, maxR))
			return true;
	}

	return false;
}

static bool isBilinearCompareValid (const Sampler::CompareMode	compareMode,
									const TexComparePrecision&	prec,
									const Vec4&					depths,
									const Vec2&					xBounds,
									const Vec2&					yBounds,
									const float					cmpReference,
									const float					result,
									const bool					isFixedPointDepth)
{
	if (prec.pcfBits > 0)
		return isBilinearPCFCompareValid(compareMode, prec, depths, xBounds, yBounds, cmpReference, result, isFixedPointDepth);
	else
		return isBilinearAnyCompareValid(compareMode, prec, depths, cmpReference, result, isFixedPointDepth);
}

static bool isTrilinearAnyCompareValid (const Sampler::CompareMode	compareMode,
										const TexComparePrecision&	prec,
										const Vec4&					depths0,
										const Vec4&					depths1,
										const float					cmpReference,
										const float					result,
										const bool					isFixedPointDepth)
{
	DE_ASSERT(prec.pcfBits == 0);

	const CmpResultSet	cmp00		= execCompare(compareMode, depths0[0], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp01		= execCompare(compareMode, depths0[1], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp02		= execCompare(compareMode, depths0[2], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp03		= execCompare(compareMode, depths0[3], cmpReference, prec.referenceBits, isFixedPointDepth);

	const CmpResultSet	cmp10		= execCompare(compareMode, depths1[0], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp11		= execCompare(compareMode, depths1[1], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp12		= execCompare(compareMode, depths1[2], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp13		= execCompare(compareMode, depths1[3], cmpReference, prec.referenceBits, isFixedPointDepth);

	const bool			canBeTrue	= cmp00.isTrue ||
									  cmp01.isTrue ||
									  cmp02.isTrue ||
									  cmp03.isTrue ||
									  cmp10.isTrue ||
									  cmp11.isTrue ||
									  cmp12.isTrue ||
									  cmp13.isTrue;
	const bool			canBeFalse	= cmp00.isFalse ||
									  cmp01.isFalse ||
									  cmp02.isFalse ||
									  cmp03.isFalse ||
									  cmp10.isFalse ||
									  cmp11.isFalse ||
									  cmp12.isFalse ||
									  cmp13.isFalse;

	const float			resErr		= computeFixedPointError(prec.resultBits);

	const float			minBound	= canBeFalse ? 0.0f : 1.0f;
	const float			maxBound	= canBeTrue ? 1.0f : 0.0f;

	return de::inRange(result, minBound-resErr, maxBound+resErr);
}

static bool isTrilinearPCFCompareValid (const Sampler::CompareMode	compareMode,
										const TexComparePrecision&	prec,
										const Vec4&					depths0,
										const Vec4&					depths1,
										const Vec2&					xBounds0,
										const Vec2&					yBounds0,
										const Vec2&					xBounds1,
										const Vec2&					yBounds1,
										const Vec2&					fBounds,
										const float					cmpReference,
										const float					result,
										const bool					isFixedPointDepth)
{
	DE_ASSERT(0.0f <= xBounds0.x() && xBounds0.x() <= xBounds0.y() && xBounds0.y() <= 1.0f);
	DE_ASSERT(0.0f <= yBounds0.x() && yBounds0.x() <= yBounds0.y() && yBounds0.y() <= 1.0f);
	DE_ASSERT(0.0f <= xBounds1.x() && xBounds1.x() <= xBounds1.y() && xBounds1.y() <= 1.0f);
	DE_ASSERT(0.0f <= yBounds1.x() && yBounds1.x() <= yBounds1.y() && yBounds1.y() <= 1.0f);
	DE_ASSERT(0.0f <= fBounds.x() && fBounds.x() <= fBounds.y() && fBounds.y() <= 1.0f);
	DE_ASSERT(prec.pcfBits > 0);

	const CmpResultSet	cmp00		= execCompare(compareMode, depths0[0], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp01		= execCompare(compareMode, depths0[1], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp02		= execCompare(compareMode, depths0[2], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp03		= execCompare(compareMode, depths0[3], cmpReference, prec.referenceBits, isFixedPointDepth);

	const CmpResultSet	cmp10		= execCompare(compareMode, depths1[0], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp11		= execCompare(compareMode, depths1[1], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp12		= execCompare(compareMode, depths1[2], cmpReference, prec.referenceBits, isFixedPointDepth);
	const CmpResultSet	cmp13		= execCompare(compareMode, depths1[3], cmpReference, prec.referenceBits, isFixedPointDepth);

	const deUint32		isTrue		= (deUint32(cmp00.isTrue)<<0)
									| (deUint32(cmp01.isTrue)<<1)
									| (deUint32(cmp02.isTrue)<<2)
									| (deUint32(cmp03.isTrue)<<3)
									| (deUint32(cmp10.isTrue)<<4)
									| (deUint32(cmp11.isTrue)<<5)
									| (deUint32(cmp12.isTrue)<<6)
									| (deUint32(cmp13.isTrue)<<7);
	const deUint32		isFalse		= (deUint32(cmp00.isFalse)<<0)
									| (deUint32(cmp01.isFalse)<<1)
									| (deUint32(cmp02.isFalse)<<2)
									| (deUint32(cmp03.isFalse)<<3)
									| (deUint32(cmp10.isFalse)<<4)
									| (deUint32(cmp11.isFalse)<<5)
									| (deUint32(cmp12.isFalse)<<6)
									| (deUint32(cmp13.isFalse)<<7);

	// Error parameters
	const float			pcfErr		= computeFixedPointError(prec.pcfBits);
	const float			resErr		= computeFixedPointError(prec.resultBits);
	const float			totalErr	= pcfErr+resErr;

	// Iterate over all valid combinations.
	for (deUint32 comb = 0; comb < (1<<8); comb++)
	{
		// Filter out invalid combinations.
		if (((comb & isTrue) | (~comb & isFalse)) != (1<<8)-1)
			continue;

		const BVec4		cmpTrue0	= extractBVec4(comb, 0);
		const BVec4		cmpTrue1	= extractBVec4(comb, 4);
		const Vec4		refVal0		= select(Vec4(1.0f), Vec4(0.0f), cmpTrue0);
		const Vec4		refVal1		= select(Vec4(1.0f), Vec4(0.0f), cmpTrue1);

		// Bilinear interpolation within levels.
		const float		v00			= bilinearInterpolate(refVal0, xBounds0.x(), yBounds0.x());
		const float		v01			= bilinearInterpolate(refVal0, xBounds0.y(), yBounds0.x());
		const float		v02			= bilinearInterpolate(refVal0, xBounds0.x(), yBounds0.y());
		const float		v03			= bilinearInterpolate(refVal0, xBounds0.y(), yBounds0.y());
		const float		minV0		= de::min(v00, de::min(v01, de::min(v02, v03)));
		const float		maxV0		= de::max(v00, de::max(v01, de::max(v02, v03)));

		const float		v10			= bilinearInterpolate(refVal1, xBounds1.x(), yBounds1.x());
		const float		v11			= bilinearInterpolate(refVal1, xBounds1.y(), yBounds1.x());
		const float		v12			= bilinearInterpolate(refVal1, xBounds1.x(), yBounds1.y());
		const float		v13			= bilinearInterpolate(refVal1, xBounds1.y(), yBounds1.y());
		const float		minV1		= de::min(v10, de::min(v11, de::min(v12, v13)));
		const float		maxV1		= de::max(v10, de::max(v11, de::max(v12, v13)));

		// Compute min-max bounds by filtering between minimum bounds and maximum bounds between levels.
		// HW can end up choosing pretty much any of samples between levels, and thus interpolating
		// between minimums should yield lower bound for range, and same for upper bound.
		// \todo [2013-07-17 pyry] This seems separable? Can this be optimized? At least ranges could be pre-computed and later combined.
		const float		minF0		= minV0*(1.0f-fBounds.x()) + minV1*fBounds.x();
		const float		minF1		= minV0*(1.0f-fBounds.y()) + minV1*fBounds.y();
		const float		maxF0		= maxV0*(1.0f-fBounds.x()) + maxV1*fBounds.x();
		const float		maxF1		= maxV0*(1.0f-fBounds.y()) + maxV1*fBounds.y();

		const float		minF		= de::min(minF0, minF1);
		const float		maxF		= de::max(maxF0, maxF1);

		const float		minR		= minF-totalErr;
		const float		maxR		= maxF+totalErr;

		if (de::inRange(result, minR, maxR))
			return true;
	}

	return false;
}

static bool isTrilinearCompareValid (const Sampler::CompareMode	compareMode,
									 const TexComparePrecision&	prec,
									 const Vec4&				depths0,
									 const Vec4&				depths1,
									 const Vec2&				xBounds0,
									 const Vec2&				yBounds0,
									 const Vec2&				xBounds1,
									 const Vec2&				yBounds1,
									 const Vec2&				fBounds,
									 const float				cmpReference,
									 const float				result,
									 const bool					isFixedPointDepth)
{
	if (prec.pcfBits > 0)
		return isTrilinearPCFCompareValid(compareMode, prec, depths0, depths1, xBounds0, yBounds0, xBounds1, yBounds1, fBounds, cmpReference, result, isFixedPointDepth);
	else
		return isTrilinearAnyCompareValid(compareMode, prec, depths0, depths1, cmpReference, result, isFixedPointDepth);
}

static bool isNearestCompareResultValid (const ConstPixelBufferAccess&		level,
										 const Sampler&						sampler,
										 const TexComparePrecision&			prec,
										 const Vec2&						coord,
										 const int							coordZ,
										 const float						cmpReference,
										 const float						result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(level.getFormat());
	const Vec2	uBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getWidth(),	coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getHeight(),	coord.y(), prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinates - without wrap mode
	const int	minI		= deFloorFloatToInt32(uBounds.x());
	const int	maxI		= deFloorFloatToInt32(uBounds.y());
	const int	minJ		= deFloorFloatToInt32(vBounds.x());
	const int	maxJ		= deFloorFloatToInt32(vBounds.y());

	for (int j = minJ; j <= maxJ; j++)
	{
		for (int i = minI; i <= maxI; i++)
		{
			const int			x		= wrap(sampler.wrapS, i, level.getWidth());
			const int			y		= wrap(sampler.wrapT, j, level.getHeight());
			const float			depth	= lookupDepth(level, sampler, x, y, coordZ);
			const CmpResultSet	resSet	= execCompare(sampler.compare, depth, cmpReference, prec.referenceBits, isFixedPointDepth);

			if (isResultInSet(resSet, result, prec.resultBits))
				return true;
		}
	}

	return false;
}

static bool isLinearCompareResultValid (const ConstPixelBufferAccess&		level,
										const Sampler&						sampler,
										const TexComparePrecision&			prec,
										const Vec2&							coord,
										const int							coordZ,
										const float							cmpReference,
										const float							result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(level.getFormat());
	const Vec2	uBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getWidth(),	coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, level.getHeight(),	coord.y(), prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinate bounds for (x0,y0) - without wrap mode
	const int	minI		= deFloorFloatToInt32(uBounds.x()-0.5f);
	const int	maxI		= deFloorFloatToInt32(uBounds.y()-0.5f);
	const int	minJ		= deFloorFloatToInt32(vBounds.x()-0.5f);
	const int	maxJ		= deFloorFloatToInt32(vBounds.y()-0.5f);

	const int	w			= level.getWidth();
	const int	h			= level.getHeight();

	// \todo [2013-07-03 pyry] This could be optimized by first computing ranges based on wrap mode.

	for (int j = minJ; j <= maxJ; j++)
	{
		for (int i = minI; i <= maxI; i++)
		{
			// Wrapped coordinates
			const int	x0		= wrap(sampler.wrapS, i  , w);
			const int	x1		= wrap(sampler.wrapS, i+1, w);
			const int	y0		= wrap(sampler.wrapT, j  , h);
			const int	y1		= wrap(sampler.wrapT, j+1, h);

			// Bounds for filtering factors
			const float	minA	= de::clamp((uBounds.x()-0.5f)-float(i), 0.0f, 1.0f);
			const float	maxA	= de::clamp((uBounds.y()-0.5f)-float(i), 0.0f, 1.0f);
			const float	minB	= de::clamp((vBounds.x()-0.5f)-float(j), 0.0f, 1.0f);
			const float	maxB	= de::clamp((vBounds.y()-0.5f)-float(j), 0.0f, 1.0f);

			const Vec4	depths	(lookupDepth(level, sampler, x0, y0, coordZ),
								 lookupDepth(level, sampler, x1, y0, coordZ),
								 lookupDepth(level, sampler, x0, y1, coordZ),
								 lookupDepth(level, sampler, x1, y1, coordZ));

			if (isBilinearCompareValid(sampler.compare, prec, depths, Vec2(minA, maxA), Vec2(minB, maxB), cmpReference, result, isFixedPointDepth))
				return true;
		}
	}

	return false;
}

static bool isLevelCompareResultValid (const ConstPixelBufferAccess&	level,
									   const Sampler&					sampler,
									   const Sampler::FilterMode		filterMode,
									   const TexComparePrecision&		prec,
									   const Vec2&						coord,
									   const int						coordZ,
									   const float						cmpReference,
									   const float						result)
{
	if (filterMode == Sampler::LINEAR)
		return isLinearCompareResultValid(level, sampler, prec, coord, coordZ, cmpReference, result);
	else
		return isNearestCompareResultValid(level, sampler, prec, coord, coordZ, cmpReference, result);
}

static bool isNearestMipmapLinearCompareResultValid (const ConstPixelBufferAccess&	level0,
													 const ConstPixelBufferAccess&	level1,
													 const Sampler&					sampler,
													 const TexComparePrecision&		prec,
													 const Vec2&					coord,
													 const int						coordZ,
													 const Vec2&					fBounds,
													 const float					cmpReference,
													 const float					result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(level0.getFormat());

	const int	w0					= level0.getWidth();
	const int	w1					= level1.getWidth();
	const int	h0					= level0.getHeight();
	const int	h1					= level1.getHeight();

	const Vec2	uBounds0			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, w0,	coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	uBounds1			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, w1,	coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds0			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, h0,	coord.y(), prec.coordBits.y(), prec.uvwBits.y());
	const Vec2	vBounds1			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, h1,	coord.y(), prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinates - without wrap mode
	const int	minI0				= deFloorFloatToInt32(uBounds0.x());
	const int	maxI0				= deFloorFloatToInt32(uBounds0.y());
	const int	minI1				= deFloorFloatToInt32(uBounds1.x());
	const int	maxI1				= deFloorFloatToInt32(uBounds1.y());
	const int	minJ0				= deFloorFloatToInt32(vBounds0.x());
	const int	maxJ0				= deFloorFloatToInt32(vBounds0.y());
	const int	minJ1				= deFloorFloatToInt32(vBounds1.x());
	const int	maxJ1				= deFloorFloatToInt32(vBounds1.y());

	for (int j0 = minJ0; j0 <= maxJ0; j0++)
	{
		for (int i0 = minI0; i0 <= maxI0; i0++)
		{
			const float	depth0	= lookupDepth(level0, sampler, wrap(sampler.wrapS, i0, w0), wrap(sampler.wrapT, j0, h0), coordZ);

			for (int j1 = minJ1; j1 <= maxJ1; j1++)
			{
				for (int i1 = minI1; i1 <= maxI1; i1++)
				{
					const float	depth1	= lookupDepth(level1, sampler, wrap(sampler.wrapS, i1, w1), wrap(sampler.wrapT, j1, h1), coordZ);

					if (isLinearCompareValid(sampler.compare, prec, Vec2(depth0, depth1), fBounds, cmpReference, result, isFixedPointDepth))
						return true;
				}
			}
		}
	}

	return false;
}

static bool isLinearMipmapLinearCompareResultValid (const ConstPixelBufferAccess&	level0,
													const ConstPixelBufferAccess&	level1,
													const Sampler&					sampler,
													const TexComparePrecision&		prec,
													const Vec2&						coord,
													const int						coordZ,
													const Vec2&						fBounds,
													const float						cmpReference,
													const float						result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(level0.getFormat());

	// \todo [2013-07-04 pyry] This is strictly not correct as coordinates between levels should be dependent.
	//						   Right now this allows pairing any two valid bilinear quads.

	const int	w0					= level0.getWidth();
	const int	w1					= level1.getWidth();
	const int	h0					= level0.getHeight();
	const int	h1					= level1.getHeight();

	const Vec2	uBounds0			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, w0,	coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	uBounds1			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, w1,	coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds0			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, h0,	coord.y(), prec.coordBits.y(), prec.uvwBits.y());
	const Vec2	vBounds1			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, h1,	coord.y(), prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinates - without wrap mode
	const int	minI0				= deFloorFloatToInt32(uBounds0.x()-0.5f);
	const int	maxI0				= deFloorFloatToInt32(uBounds0.y()-0.5f);
	const int	minI1				= deFloorFloatToInt32(uBounds1.x()-0.5f);
	const int	maxI1				= deFloorFloatToInt32(uBounds1.y()-0.5f);
	const int	minJ0				= deFloorFloatToInt32(vBounds0.x()-0.5f);
	const int	maxJ0				= deFloorFloatToInt32(vBounds0.y()-0.5f);
	const int	minJ1				= deFloorFloatToInt32(vBounds1.x()-0.5f);
	const int	maxJ1				= deFloorFloatToInt32(vBounds1.y()-0.5f);

	for (int j0 = minJ0; j0 <= maxJ0; j0++)
	{
		for (int i0 = minI0; i0 <= maxI0; i0++)
		{
			const float	minA0	= de::clamp((uBounds0.x()-0.5f)-float(i0), 0.0f, 1.0f);
			const float	maxA0	= de::clamp((uBounds0.y()-0.5f)-float(i0), 0.0f, 1.0f);
			const float	minB0	= de::clamp((vBounds0.x()-0.5f)-float(j0), 0.0f, 1.0f);
			const float	maxB0	= de::clamp((vBounds0.y()-0.5f)-float(j0), 0.0f, 1.0f);
			Vec4		depths0;

			{
				const int	x0		= wrap(sampler.wrapS, i0  , w0);
				const int	x1		= wrap(sampler.wrapS, i0+1, w0);
				const int	y0		= wrap(sampler.wrapT, j0  , h0);
				const int	y1		= wrap(sampler.wrapT, j0+1, h0);

				depths0[0] = lookupDepth(level0, sampler, x0, y0, coordZ);
				depths0[1] = lookupDepth(level0, sampler, x1, y0, coordZ);
				depths0[2] = lookupDepth(level0, sampler, x0, y1, coordZ);
				depths0[3] = lookupDepth(level0, sampler, x1, y1, coordZ);
			}

			for (int j1 = minJ1; j1 <= maxJ1; j1++)
			{
				for (int i1 = minI1; i1 <= maxI1; i1++)
				{
					const float	minA1	= de::clamp((uBounds1.x()-0.5f)-float(i1), 0.0f, 1.0f);
					const float	maxA1	= de::clamp((uBounds1.y()-0.5f)-float(i1), 0.0f, 1.0f);
					const float	minB1	= de::clamp((vBounds1.x()-0.5f)-float(j1), 0.0f, 1.0f);
					const float	maxB1	= de::clamp((vBounds1.y()-0.5f)-float(j1), 0.0f, 1.0f);
					Vec4		depths1;

					{
						const int	x0		= wrap(sampler.wrapS, i1  , w1);
						const int	x1		= wrap(sampler.wrapS, i1+1, w1);
						const int	y0		= wrap(sampler.wrapT, j1  , h1);
						const int	y1		= wrap(sampler.wrapT, j1+1, h1);

						depths1[0] = lookupDepth(level1, sampler, x0, y0, coordZ);
						depths1[1] = lookupDepth(level1, sampler, x1, y0, coordZ);
						depths1[2] = lookupDepth(level1, sampler, x0, y1, coordZ);
						depths1[3] = lookupDepth(level1, sampler, x1, y1, coordZ);
					}

					if (isTrilinearCompareValid(sampler.compare, prec, depths0, depths1,
												Vec2(minA0, maxA0), Vec2(minB0, maxB0),
												Vec2(minA1, maxA1), Vec2(minB1, maxB1),
												fBounds, cmpReference, result, isFixedPointDepth))
						return true;
				}
			}
		}
	}

	return false;
}

static bool isMipmapLinearCompareResultValid (const ConstPixelBufferAccess&		level0,
											  const ConstPixelBufferAccess&		level1,
											  const Sampler&					sampler,
											  const Sampler::FilterMode			levelFilter,
											  const TexComparePrecision&		prec,
											  const Vec2&						coord,
											  const int							coordZ,
											  const Vec2&						fBounds,
											  const float						cmpReference,
											  const float						result)
{
	if (levelFilter == Sampler::LINEAR)
		return isLinearMipmapLinearCompareResultValid(level0, level1, sampler, prec, coord, coordZ, fBounds, cmpReference, result);
	else
		return isNearestMipmapLinearCompareResultValid(level0, level1, sampler, prec, coord, coordZ, fBounds, cmpReference, result);
}

bool isTexCompareResultValid (const Texture2DView&			texture,
							  const Sampler&				sampler,
							  const TexComparePrecision&	prec,
							  const Vec2&					coord,
							  const Vec2&					lodBounds,
							  const float					cmpReference,
							  const float					result)
{
	const float		minLod			= lodBounds.x();
	const float		maxLod			= lodBounds.y();
	const bool		canBeMagnified	= minLod <= sampler.lodThreshold;
	const bool		canBeMinified	= maxLod > sampler.lodThreshold;

	DE_ASSERT(isSamplerSupported(sampler));

	if (canBeMagnified)
	{
		if (isLevelCompareResultValid(texture.getLevel(0), sampler, sampler.magFilter, prec, coord, 0, cmpReference, result))
			return true;
	}

	if (canBeMinified)
	{
		const bool	isNearestMipmap	= isNearestMipmapFilter(sampler.minFilter);
		const bool	isLinearMipmap	= isLinearMipmapFilter(sampler.minFilter);
		const int	minTexLevel		= 0;
		const int	maxTexLevel		= texture.getNumLevels()-1;

		DE_ASSERT(minTexLevel < maxTexLevel);

		if (isLinearMipmap)
		{
			const int		minLevel		= de::clamp((int)deFloatFloor(minLod), minTexLevel, maxTexLevel-1);
			const int		maxLevel		= de::clamp((int)deFloatFloor(maxLod), minTexLevel, maxTexLevel-1);

			DE_ASSERT(minLevel <= maxLevel);

			for (int level = minLevel; level <= maxLevel; level++)
			{
				const float		minF	= de::clamp(minLod - float(level), 0.0f, 1.0f);
				const float		maxF	= de::clamp(maxLod - float(level), 0.0f, 1.0f);

				if (isMipmapLinearCompareResultValid(texture.getLevel(level), texture.getLevel(level+1), sampler, getLevelFilter(sampler.minFilter), prec, coord, 0, Vec2(minF, maxF), cmpReference, result))
					return true;
			}
		}
		else if (isNearestMipmap)
		{
			// \note The accurate formula for nearest mipmapping is level = ceil(lod + 0.5) - 1 but Khronos has made
			//		 decision to allow floor(lod + 0.5) as well.
			const int		minLevel		= de::clamp((int)deFloatCeil(minLod + 0.5f) - 1,	minTexLevel, maxTexLevel);
			const int		maxLevel		= de::clamp((int)deFloatFloor(maxLod + 0.5f),		minTexLevel, maxTexLevel);

			DE_ASSERT(minLevel <= maxLevel);

			for (int level = minLevel; level <= maxLevel; level++)
			{
				if (isLevelCompareResultValid(texture.getLevel(level), sampler, getLevelFilter(sampler.minFilter), prec, coord, 0, cmpReference, result))
					return true;
			}
		}
		else
		{
			if (isLevelCompareResultValid(texture.getLevel(0), sampler, sampler.minFilter, prec, coord, 0, cmpReference, result))
				return true;
		}
	}

	return false;
}

static bool isSeamplessLinearMipmapLinearCompareResultValid (const TextureCubeView&			texture,
															 const int						baseLevelNdx,
															 const Sampler&					sampler,
															 const TexComparePrecision&		prec,
															 const CubeFaceFloatCoords&		coords,
															 const Vec2&					fBounds,
															 const float					cmpReference,
															 const float					result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(texture.getLevelFace(baseLevelNdx, CUBEFACE_NEGATIVE_X).getFormat());
	const int	size0				= texture.getLevelFace(baseLevelNdx,	coords.face).getWidth();
	const int	size1				= texture.getLevelFace(baseLevelNdx+1,	coords.face).getWidth();

	const Vec2	uBounds0			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size0,	coords.s, prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	uBounds1			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size1,	coords.s, prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds0			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size0,	coords.t, prec.coordBits.y(), prec.uvwBits.y());
	const Vec2	vBounds1			= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size1,	coords.t, prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinates - without wrap mode
	const int	minI0				= deFloorFloatToInt32(uBounds0.x()-0.5f);
	const int	maxI0				= deFloorFloatToInt32(uBounds0.y()-0.5f);
	const int	minI1				= deFloorFloatToInt32(uBounds1.x()-0.5f);
	const int	maxI1				= deFloorFloatToInt32(uBounds1.y()-0.5f);
	const int	minJ0				= deFloorFloatToInt32(vBounds0.x()-0.5f);
	const int	maxJ0				= deFloorFloatToInt32(vBounds0.y()-0.5f);
	const int	minJ1				= deFloorFloatToInt32(vBounds1.x()-0.5f);
	const int	maxJ1				= deFloorFloatToInt32(vBounds1.y()-0.5f);

	tcu::ConstPixelBufferAccess faces0[CUBEFACE_LAST];
	tcu::ConstPixelBufferAccess faces1[CUBEFACE_LAST];

	for (int face = 0; face < CUBEFACE_LAST; face++)
	{
		faces0[face] = texture.getLevelFace(baseLevelNdx,	CubeFace(face));
		faces1[face] = texture.getLevelFace(baseLevelNdx+1,	CubeFace(face));
	}

	for (int j0 = minJ0; j0 <= maxJ0; j0++)
	{
		for (int i0 = minI0; i0 <= maxI0; i0++)
		{
			const float	minA0	= de::clamp((uBounds0.x()-0.5f)-float(i0), 0.0f, 1.0f);
			const float	maxA0	= de::clamp((uBounds0.y()-0.5f)-float(i0), 0.0f, 1.0f);
			const float	minB0	= de::clamp((vBounds0.x()-0.5f)-float(j0), 0.0f, 1.0f);
			const float	maxB0	= de::clamp((vBounds0.y()-0.5f)-float(j0), 0.0f, 1.0f);
			Vec4		depths0;

			{
				const CubeFaceIntCoords	c00	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i0+0, j0+0)), size0);
				const CubeFaceIntCoords	c10	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i0+1, j0+0)), size0);
				const CubeFaceIntCoords	c01	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i0+0, j0+1)), size0);
				const CubeFaceIntCoords	c11	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i0+1, j0+1)), size0);

				// If any of samples is out of both edges, implementations can do pretty much anything according to spec.
				// \todo [2013-07-08 pyry] Test the special case where all corner pixels have exactly the same color.
				if (c00.face == CUBEFACE_LAST || c01.face == CUBEFACE_LAST || c10.face == CUBEFACE_LAST || c11.face == CUBEFACE_LAST)
					return true;

				depths0[0] = lookupDepthNoBorder(faces0[c00.face], sampler, c00.s, c00.t);
				depths0[1] = lookupDepthNoBorder(faces0[c10.face], sampler, c10.s, c10.t);
				depths0[2] = lookupDepthNoBorder(faces0[c01.face], sampler, c01.s, c01.t);
				depths0[3] = lookupDepthNoBorder(faces0[c11.face], sampler, c11.s, c11.t);
			}

			for (int j1 = minJ1; j1 <= maxJ1; j1++)
			{
				for (int i1 = minI1; i1 <= maxI1; i1++)
				{
					const float	minA1	= de::clamp((uBounds1.x()-0.5f)-float(i1), 0.0f, 1.0f);
					const float	maxA1	= de::clamp((uBounds1.y()-0.5f)-float(i1), 0.0f, 1.0f);
					const float	minB1	= de::clamp((vBounds1.x()-0.5f)-float(j1), 0.0f, 1.0f);
					const float	maxB1	= de::clamp((vBounds1.y()-0.5f)-float(j1), 0.0f, 1.0f);
					Vec4		depths1;

					{
						const CubeFaceIntCoords	c00	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i1+0, j1+0)), size1);
						const CubeFaceIntCoords	c10	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i1+1, j1+0)), size1);
						const CubeFaceIntCoords	c01	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i1+0, j1+1)), size1);
						const CubeFaceIntCoords	c11	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i1+1, j1+1)), size1);

						if (c00.face == CUBEFACE_LAST || c01.face == CUBEFACE_LAST || c10.face == CUBEFACE_LAST || c11.face == CUBEFACE_LAST)
							return true;

						depths1[0] = lookupDepthNoBorder(faces1[c00.face], sampler, c00.s, c00.t);
						depths1[1] = lookupDepthNoBorder(faces1[c10.face], sampler, c10.s, c10.t);
						depths1[2] = lookupDepthNoBorder(faces1[c01.face], sampler, c01.s, c01.t);
						depths1[3] = lookupDepthNoBorder(faces1[c11.face], sampler, c11.s, c11.t);
					}


					if (isTrilinearCompareValid(sampler.compare, prec, depths0, depths1,
												Vec2(minA0, maxA0), Vec2(minB0, maxB0),
												Vec2(minA1, maxA1), Vec2(minB1, maxB1),
												fBounds, cmpReference, result, isFixedPointDepth))
						return true;
				}
			}
		}
	}

	return false;
}

static bool isCubeMipmapLinearCompareResultValid (const TextureCubeView&		texture,
												  const int						baseLevelNdx,
												  const Sampler&				sampler,
												  const Sampler::FilterMode		levelFilter,
												  const TexComparePrecision&	prec,
												  const CubeFaceFloatCoords&	coords,
												  const Vec2&					fBounds,
												  const float					cmpReference,
												  const float					result)
{
	if (levelFilter == Sampler::LINEAR)
	{
		if (sampler.seamlessCubeMap)
			return isSeamplessLinearMipmapLinearCompareResultValid(texture, baseLevelNdx, sampler, prec, coords, fBounds, cmpReference, result);
		else
			return isLinearMipmapLinearCompareResultValid(texture.getLevelFace(baseLevelNdx,	coords.face),
														  texture.getLevelFace(baseLevelNdx+1,	coords.face),
														  sampler, prec, Vec2(coords.s, coords.t), 0, fBounds, cmpReference, result);
	}
	else
		return isNearestMipmapLinearCompareResultValid(texture.getLevelFace(baseLevelNdx,	coords.face),
													   texture.getLevelFace(baseLevelNdx+1,	coords.face),
													   sampler, prec, Vec2(coords.s, coords.t), 0, fBounds, cmpReference, result);
}

static bool isSeamlessLinearCompareResultValid (const TextureCubeView&		texture,
												const int					levelNdx,
												const Sampler&				sampler,
												const TexComparePrecision&	prec,
												const CubeFaceFloatCoords&	coords,
												const float					cmpReference,
												const float					result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(texture.getLevelFace(levelNdx, CUBEFACE_NEGATIVE_X).getFormat());
	const int	size				= texture.getLevelFace(levelNdx, coords.face).getWidth();

	const Vec2	uBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size, coords.s, prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size, coords.t, prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinate bounds for (x0,y0) - without wrap mode
	const int	minI				= deFloorFloatToInt32(uBounds.x()-0.5f);
	const int	maxI				= deFloorFloatToInt32(uBounds.y()-0.5f);
	const int	minJ				= deFloorFloatToInt32(vBounds.x()-0.5f);
	const int	maxJ				= deFloorFloatToInt32(vBounds.y()-0.5f);

	// Face accesses
	ConstPixelBufferAccess faces[CUBEFACE_LAST];
	for (int face = 0; face < CUBEFACE_LAST; face++)
		faces[face] = texture.getLevelFace(levelNdx, CubeFace(face));

	for (int j = minJ; j <= maxJ; j++)
	{
		for (int i = minI; i <= maxI; i++)
		{
			const CubeFaceIntCoords	c00	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i+0, j+0)), size);
			const CubeFaceIntCoords	c10	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i+1, j+0)), size);
			const CubeFaceIntCoords	c01	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i+0, j+1)), size);
			const CubeFaceIntCoords	c11	= remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, IVec2(i+1, j+1)), size);

			// If any of samples is out of both edges, implementations can do pretty much anything according to spec.
			// \todo [2013-07-08 pyry] Test the special case where all corner pixels have exactly the same color.
			if (c00.face == CUBEFACE_LAST || c01.face == CUBEFACE_LAST || c10.face == CUBEFACE_LAST || c11.face == CUBEFACE_LAST)
				return true;

			// Bounds for filtering factors
			const float	minA	= de::clamp((uBounds.x()-0.5f)-float(i), 0.0f, 1.0f);
			const float	maxA	= de::clamp((uBounds.y()-0.5f)-float(i), 0.0f, 1.0f);
			const float	minB	= de::clamp((vBounds.x()-0.5f)-float(j), 0.0f, 1.0f);
			const float	maxB	= de::clamp((vBounds.y()-0.5f)-float(j), 0.0f, 1.0f);

			Vec4 depths;
			depths[0] = lookupDepthNoBorder(faces[c00.face], sampler, c00.s, c00.t);
			depths[1] = lookupDepthNoBorder(faces[c10.face], sampler, c10.s, c10.t);
			depths[2] = lookupDepthNoBorder(faces[c01.face], sampler, c01.s, c01.t);
			depths[3] = lookupDepthNoBorder(faces[c11.face], sampler, c11.s, c11.t);

			if (isBilinearCompareValid(sampler.compare, prec, depths, Vec2(minA, maxA), Vec2(minB, maxB), cmpReference, result, isFixedPointDepth))
				return true;
		}
	}

	return false;
}

static bool isCubeLevelCompareResultValid (const TextureCubeView&			texture,
										   const int						levelNdx,
										   const Sampler&					sampler,
										   const Sampler::FilterMode		filterMode,
										   const TexComparePrecision&		prec,
										   const CubeFaceFloatCoords&		coords,
										   const float						cmpReference,
										   const float						result)
{
	if (filterMode == Sampler::LINEAR)
	{
		if (sampler.seamlessCubeMap)
			return isSeamlessLinearCompareResultValid(texture, levelNdx, sampler, prec, coords, cmpReference, result);
		else
			return isLinearCompareResultValid(texture.getLevelFace(levelNdx, coords.face), sampler, prec, Vec2(coords.s, coords.t), 0, cmpReference, result);
	}
	else
		return isNearestCompareResultValid(texture.getLevelFace(levelNdx, coords.face), sampler, prec, Vec2(coords.s, coords.t), 0, cmpReference, result);
}

bool isTexCompareResultValid (const TextureCubeView& texture, const Sampler& sampler, const TexComparePrecision& prec, const Vec3& coord, const Vec2& lodBounds, const float cmpReference, const float result)
{
	int			numPossibleFaces				= 0;
	CubeFace	possibleFaces[CUBEFACE_LAST];

	DE_ASSERT(isSamplerSupported(sampler));

	getPossibleCubeFaces(coord, prec.coordBits, &possibleFaces[0], numPossibleFaces);

	if (numPossibleFaces == 0)
		return true; // Result is undefined.

	for (int tryFaceNdx = 0; tryFaceNdx < numPossibleFaces; tryFaceNdx++)
	{
		const CubeFaceFloatCoords	faceCoords		(possibleFaces[tryFaceNdx], projectToFace(possibleFaces[tryFaceNdx], coord));
		const float					minLod			= lodBounds.x();
		const float					maxLod			= lodBounds.y();
		const bool					canBeMagnified	= minLod <= sampler.lodThreshold;
		const bool					canBeMinified	= maxLod > sampler.lodThreshold;

		if (canBeMagnified)
		{
			if (isCubeLevelCompareResultValid(texture, 0, sampler, sampler.magFilter, prec, faceCoords, cmpReference, result))
				return true;
		}

		if (canBeMinified)
		{
			const bool	isNearestMipmap	= isNearestMipmapFilter(sampler.minFilter);
			const bool	isLinearMipmap	= isLinearMipmapFilter(sampler.minFilter);
			const int	minTexLevel		= 0;
			const int	maxTexLevel		= texture.getNumLevels()-1;

			DE_ASSERT(minTexLevel < maxTexLevel);

			if (isLinearMipmap)
			{
				const int		minLevel		= de::clamp((int)deFloatFloor(minLod), minTexLevel, maxTexLevel-1);
				const int		maxLevel		= de::clamp((int)deFloatFloor(maxLod), minTexLevel, maxTexLevel-1);

				DE_ASSERT(minLevel <= maxLevel);

				for (int level = minLevel; level <= maxLevel; level++)
				{
					const float		minF	= de::clamp(minLod - float(level), 0.0f, 1.0f);
					const float		maxF	= de::clamp(maxLod - float(level), 0.0f, 1.0f);

					if (isCubeMipmapLinearCompareResultValid(texture, level, sampler, getLevelFilter(sampler.minFilter), prec, faceCoords, Vec2(minF, maxF), cmpReference, result))
						return true;
				}
			}
			else if (isNearestMipmap)
			{
				// \note The accurate formula for nearest mipmapping is level = ceil(lod + 0.5) - 1 but Khronos has made
				//		 decision to allow floor(lod + 0.5) as well.
				const int		minLevel		= de::clamp((int)deFloatCeil(minLod + 0.5f) - 1,	minTexLevel, maxTexLevel);
				const int		maxLevel		= de::clamp((int)deFloatFloor(maxLod + 0.5f),		minTexLevel, maxTexLevel);

				DE_ASSERT(minLevel <= maxLevel);

				for (int level = minLevel; level <= maxLevel; level++)
				{
					if (isCubeLevelCompareResultValid(texture, level, sampler, getLevelFilter(sampler.minFilter), prec, faceCoords, cmpReference, result))
						return true;
				}
			}
			else
			{
				if (isCubeLevelCompareResultValid(texture, 0, sampler, sampler.minFilter, prec, faceCoords, cmpReference, result))
					return true;
			}
		}
	}

	return false;
}

bool isTexCompareResultValid (const Texture2DArrayView& texture, const Sampler& sampler, const TexComparePrecision& prec, const Vec3& coord, const Vec2& lodBounds, const float cmpReference, const float result)
{
	const float		depthErr	= computeFloatingPointError(coord.z(), prec.coordBits.z()) + computeFixedPointError(prec.uvwBits.z());
	const float		minZ		= coord.z()-depthErr;
	const float		maxZ		= coord.z()+depthErr;
	const int		minLayer	= de::clamp(deFloorFloatToInt32(minZ + 0.5f), 0, texture.getNumLayers()-1);
	const int		maxLayer	= de::clamp(deFloorFloatToInt32(maxZ + 0.5f), 0, texture.getNumLayers()-1);

	DE_ASSERT(isSamplerSupported(sampler));

	for (int layer = minLayer; layer <= maxLayer; layer++)
	{
		const float		minLod			= lodBounds.x();
		const float		maxLod			= lodBounds.y();
		const bool		canBeMagnified	= minLod <= sampler.lodThreshold;
		const bool		canBeMinified	= maxLod > sampler.lodThreshold;

		if (canBeMagnified)
		{
			if (isLevelCompareResultValid(texture.getLevel(0), sampler, sampler.magFilter, prec, coord.swizzle(0,1), layer, cmpReference, result))
				return true;
		}

		if (canBeMinified)
		{
			const bool	isNearestMipmap	= isNearestMipmapFilter(sampler.minFilter);
			const bool	isLinearMipmap	= isLinearMipmapFilter(sampler.minFilter);
			const int	minTexLevel		= 0;
			const int	maxTexLevel		= texture.getNumLevels()-1;

			DE_ASSERT(minTexLevel < maxTexLevel);

			if (isLinearMipmap)
			{
				const int		minLevel		= de::clamp((int)deFloatFloor(minLod), minTexLevel, maxTexLevel-1);
				const int		maxLevel		= de::clamp((int)deFloatFloor(maxLod), minTexLevel, maxTexLevel-1);

				DE_ASSERT(minLevel <= maxLevel);

				for (int level = minLevel; level <= maxLevel; level++)
				{
					const float		minF	= de::clamp(minLod - float(level), 0.0f, 1.0f);
					const float		maxF	= de::clamp(maxLod - float(level), 0.0f, 1.0f);

					if (isMipmapLinearCompareResultValid(texture.getLevel(level), texture.getLevel(level+1), sampler, getLevelFilter(sampler.minFilter), prec, coord.swizzle(0,1), layer, Vec2(minF, maxF), cmpReference, result))
						return true;
				}
			}
			else if (isNearestMipmap)
			{
				// \note The accurate formula for nearest mipmapping is level = ceil(lod + 0.5) - 1 but Khronos has made
				//		 decision to allow floor(lod + 0.5) as well.
				const int		minLevel		= de::clamp((int)deFloatCeil(minLod + 0.5f) - 1,	minTexLevel, maxTexLevel);
				const int		maxLevel		= de::clamp((int)deFloatFloor(maxLod + 0.5f),		minTexLevel, maxTexLevel);

				DE_ASSERT(minLevel <= maxLevel);

				for (int level = minLevel; level <= maxLevel; level++)
				{
					if (isLevelCompareResultValid(texture.getLevel(level), sampler, getLevelFilter(sampler.minFilter), prec, coord.swizzle(0,1), layer, cmpReference, result))
						return true;
				}
			}
			else
			{
				if (isLevelCompareResultValid(texture.getLevel(0), sampler, sampler.minFilter, prec, coord.swizzle(0,1), layer, cmpReference, result))
					return true;
			}
		}
	}

	return false;
}

static bool isGatherOffsetsCompareResultValid (const ConstPixelBufferAccess&	texture,
											   const Sampler&					sampler,
											   const TexComparePrecision&		prec,
											   const Vec2&						coord,
											   int								coordZ,
											   const IVec2						(&offsets)[4],
											   float							cmpReference,
											   const Vec4&						result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(texture.getFormat());
	const Vec2	uBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, texture.getWidth(),		coord.x(), prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, texture.getHeight(),	coord.y(), prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinate bounds for (x0, y0) - without wrap mode
	const int	minI				= deFloorFloatToInt32(uBounds.x()-0.5f);
	const int	maxI				= deFloorFloatToInt32(uBounds.y()-0.5f);
	const int	minJ				= deFloorFloatToInt32(vBounds.x()-0.5f);
	const int	maxJ				= deFloorFloatToInt32(vBounds.y()-0.5f);

	const int	w					= texture.getWidth();
	const int	h					= texture.getHeight();

	for (int j = minJ; j <= maxJ; j++)
	{
		for (int i = minI; i <= maxI; i++)
		{
			bool isCurrentPixelValid = true;

			for (int offNdx = 0; offNdx < 4 && isCurrentPixelValid; offNdx++)
			{
				// offNdx-th coordinate offset and then wrapped.
				const int			x		= wrap(sampler.wrapS, i+offsets[offNdx].x(), w);
				const int			y		= wrap(sampler.wrapT, j+offsets[offNdx].y(), h);
				const float			depth	= lookupDepth(texture, sampler, x, y, coordZ);
				const CmpResultSet	resSet	= execCompare(sampler.compare, depth, cmpReference, prec.referenceBits, isFixedPointDepth);

				if (!isResultInSet(resSet, result[offNdx], prec.resultBits))
					isCurrentPixelValid = false;
			}

			if (isCurrentPixelValid)
				return true;
		}
	}

	return false;
}

bool isGatherOffsetsCompareResultValid (const Texture2DView&		texture,
										const Sampler&				sampler,
										const TexComparePrecision&	prec,
										const Vec2&					coord,
										const IVec2					(&offsets)[4],
										float						cmpReference,
										const Vec4&					result)
{
	DE_ASSERT(isSamplerSupported(sampler));

	return isGatherOffsetsCompareResultValid(texture.getLevel(0), sampler, prec, coord, 0, offsets, cmpReference, result);
}

bool isGatherOffsetsCompareResultValid (const Texture2DArrayView&	texture,
										const Sampler&				sampler,
										const TexComparePrecision&	prec,
										const Vec3&					coord,
										const IVec2					(&offsets)[4],
										float						cmpReference,
										const Vec4&					result)
{
	const float		depthErr	= computeFloatingPointError(coord.z(), prec.coordBits.z()) + computeFixedPointError(prec.uvwBits.z());
	const float		minZ		= coord.z()-depthErr;
	const float		maxZ		= coord.z()+depthErr;
	const int		minLayer	= de::clamp(deFloorFloatToInt32(minZ + 0.5f), 0, texture.getNumLayers()-1);
	const int		maxLayer	= de::clamp(deFloorFloatToInt32(maxZ + 0.5f), 0, texture.getNumLayers()-1);

	DE_ASSERT(isSamplerSupported(sampler));

	for (int layer = minLayer; layer <= maxLayer; layer++)
	{
		if (isGatherOffsetsCompareResultValid(texture.getLevel(0), sampler, prec, coord.swizzle(0,1), layer, offsets, cmpReference, result))
			return true;
	}
	return false;
}

static bool isGatherCompareResultValid (const TextureCubeView&		texture,
										const Sampler&				sampler,
										const TexComparePrecision&	prec,
										const CubeFaceFloatCoords&	coords,
										float						cmpReference,
										const Vec4&					result)
{
	const bool	isFixedPointDepth	= isFixedPointDepthTextureFormat(texture.getLevelFace(0, coords.face).getFormat());
	const int	size				= texture.getLevelFace(0, coords.face).getWidth();
	const Vec2	uBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size, coords.s, prec.coordBits.x(), prec.uvwBits.x());
	const Vec2	vBounds				= computeNonNormalizedCoordBounds(sampler.normalizedCoords, size, coords.t, prec.coordBits.y(), prec.uvwBits.y());

	// Integer coordinate bounds for (x0,y0) - without wrap mode
	const int	minI				= deFloorFloatToInt32(uBounds.x()-0.5f);
	const int	maxI				= deFloorFloatToInt32(uBounds.y()-0.5f);
	const int	minJ				= deFloorFloatToInt32(vBounds.x()-0.5f);
	const int	maxJ				= deFloorFloatToInt32(vBounds.y()-0.5f);

	// Face accesses
	ConstPixelBufferAccess faces[CUBEFACE_LAST];
	for (int face = 0; face < CUBEFACE_LAST; face++)
		faces[face] = texture.getLevelFace(0, CubeFace(face));

	for (int j = minJ; j <= maxJ; j++)
	{
		for (int i = minI; i <= maxI; i++)
		{
			static const IVec2 offsets[4] =
			{
				IVec2(0, 1),
				IVec2(1, 1),
				IVec2(1, 0),
				IVec2(0, 0)
			};

			bool isCurrentPixelValid = true;

			for (int offNdx = 0; offNdx < 4 && isCurrentPixelValid; offNdx++)
			{
				const CubeFaceIntCoords c = remapCubeEdgeCoords(CubeFaceIntCoords(coords.face, i+offsets[offNdx].x(), j+offsets[offNdx].y()), size);
				// If any of samples is out of both edges, implementations can do pretty much anything according to spec.
				// \todo [2014-06-05 nuutti] Test the special case where all corner pixels have exactly the same color.
				//							 See also isSeamlessLinearCompareResultValid and similar.
				if (c.face == CUBEFACE_LAST)
					return true;

				const float			depth	= lookupDepthNoBorder(faces[c.face], sampler, c.s, c.t);
				const CmpResultSet	resSet	= execCompare(sampler.compare, depth, cmpReference, prec.referenceBits, isFixedPointDepth);

				if (!isResultInSet(resSet, result[offNdx], prec.resultBits))
					isCurrentPixelValid = false;
			}

			if (isCurrentPixelValid)
				return true;
		}
	}

	return false;
}

bool isGatherCompareResultValid (const TextureCubeView&			texture,
								 const Sampler&					sampler,
								 const TexComparePrecision&		prec,
								 const Vec3&					coord,
								 float							cmpReference,
								 const Vec4&					result)
{
	int			numPossibleFaces				= 0;
	CubeFace	possibleFaces[CUBEFACE_LAST];

	DE_ASSERT(isSamplerSupported(sampler));

	getPossibleCubeFaces(coord, prec.coordBits, &possibleFaces[0], numPossibleFaces);

	if (numPossibleFaces == 0)
		return true; // Result is undefined.

	for (int tryFaceNdx = 0; tryFaceNdx < numPossibleFaces; tryFaceNdx++)
	{
		const CubeFaceFloatCoords faceCoords(possibleFaces[tryFaceNdx], projectToFace(possibleFaces[tryFaceNdx], coord));

		if (isGatherCompareResultValid(texture, sampler, prec, faceCoords, cmpReference, result))
			return true;
	}

	return false;
}

} // tcu
