/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * 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 Utility functions and structures for texture tests. This code
 * is originated from the modules/glshared/glsTextureTestUtil.hpp and it
 * is tightly coupled with the GLES and Vulkan texture tests!
 *//*--------------------------------------------------------------------*/

#include "gluTextureTestUtil.hpp"

#include "tcuFloat.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"

#include "deMath.h"
#include "deStringUtil.hpp"

#include <string>

using std::string;

namespace glu
{

namespace TextureTestUtil
{

enum
{
	MIN_SUBPIXEL_BITS	= 4
};

SamplerType getSamplerType (tcu::TextureFormat format)
{
	using tcu::TextureFormat;

	switch (format.type)
	{
		case TextureFormat::SIGNED_INT8:
		case TextureFormat::SIGNED_INT16:
		case TextureFormat::SIGNED_INT32:
			return SAMPLERTYPE_INT;

		case TextureFormat::UNSIGNED_INT8:
		case TextureFormat::UNSIGNED_INT32:
		case TextureFormat::UNSIGNED_INT_1010102_REV:
			return SAMPLERTYPE_UINT;

		// Texture formats used in depth/stencil textures.
		case TextureFormat::UNSIGNED_INT16:
		case TextureFormat::UNSIGNED_INT_24_8:
			return (format.order == TextureFormat::D || format.order == TextureFormat::DS) ? SAMPLERTYPE_FLOAT : SAMPLERTYPE_UINT;

		default:
			return SAMPLERTYPE_FLOAT;
	}
}

SamplerType getFetchSamplerType (tcu::TextureFormat format)
{
	using tcu::TextureFormat;

	switch (format.type)
	{
		case TextureFormat::SIGNED_INT8:
		case TextureFormat::SIGNED_INT16:
		case TextureFormat::SIGNED_INT32:
			return SAMPLERTYPE_FETCH_INT;

		case TextureFormat::UNSIGNED_INT8:
		case TextureFormat::UNSIGNED_INT32:
		case TextureFormat::UNSIGNED_INT_1010102_REV:
			return SAMPLERTYPE_FETCH_UINT;

		// Texture formats used in depth/stencil textures.
		case TextureFormat::UNSIGNED_INT16:
		case TextureFormat::UNSIGNED_INT_24_8:
			return (format.order == TextureFormat::D || format.order == TextureFormat::DS) ? SAMPLERTYPE_FETCH_FLOAT : SAMPLERTYPE_FETCH_UINT;

		default:
			return SAMPLERTYPE_FETCH_FLOAT;
	}
}

static tcu::Texture1DView getSubView (const tcu::Texture1DView& view, int baseLevel, int maxLevel, tcu::ImageViewMinLodParams* minLodParams DE_UNUSED_ATTR)
{
	const int	clampedBase	= de::clamp(baseLevel, 0, view.getNumLevels()-1);
	const int	clampedMax	= de::clamp(maxLevel, clampedBase, view.getNumLevels()-1);
	const int	numLevels	= clampedMax-clampedBase+1;
	return tcu::Texture1DView(numLevels, view.getLevels()+clampedBase);
}

static tcu::Texture2DView getSubView (const tcu::Texture2DView& view, int baseLevel, int maxLevel, tcu::ImageViewMinLodParams* minLodParams = DE_NULL)
{
	const int	clampedBase	= de::clamp(baseLevel, 0, view.getNumLevels()-1);
	const int	clampedMax	= de::clamp(maxLevel, clampedBase, view.getNumLevels()-1);
	const int	numLevels	= clampedMax-clampedBase+1;
	return tcu::Texture2DView(numLevels, view.getLevels()+clampedBase, view.isES2(), minLodParams);
}

static tcu::TextureCubeView getSubView (const tcu::TextureCubeView& view, int baseLevel, int maxLevel, tcu::ImageViewMinLodParams* minLodParams = DE_NULL)
{
	const int							clampedBase	= de::clamp(baseLevel, 0, view.getNumLevels()-1);
	const int							clampedMax	= de::clamp(maxLevel, clampedBase, view.getNumLevels()-1);
	const int							numLevels	= clampedMax-clampedBase+1;
	const tcu::ConstPixelBufferAccess*	levels[tcu::CUBEFACE_LAST];

	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
		levels[face] = view.getFaceLevels((tcu::CubeFace)face) + clampedBase;

	return tcu::TextureCubeView(numLevels, levels, false, minLodParams);
}

static tcu::Texture3DView getSubView (const tcu::Texture3DView& view, int baseLevel, int maxLevel, tcu::ImageViewMinLodParams* minLodParams = DE_NULL)
{
	const int	clampedBase	= de::clamp(baseLevel, 0, view.getNumLevels()-1);
	const int	clampedMax	= de::clamp(maxLevel, clampedBase, view.getNumLevels()-1);
	const int	numLevels	= clampedMax-clampedBase+1;
	return tcu::Texture3DView(numLevels, view.getLevels()+clampedBase, false, minLodParams);
}

static tcu::TextureCubeArrayView getSubView (const tcu::TextureCubeArrayView& view, int baseLevel, int maxLevel, tcu::ImageViewMinLodParams* minLodParams DE_UNUSED_ATTR = DE_NULL)
{
	const int	clampedBase	= de::clamp(baseLevel, 0, view.getNumLevels()-1);
	const int	clampedMax	= de::clamp(maxLevel, clampedBase, view.getNumLevels()-1);
	const int	numLevels	= clampedMax-clampedBase+1;
	return tcu::TextureCubeArrayView(numLevels, view.getLevels()+clampedBase);
}

inline float linearInterpolate (float t, float minVal, float maxVal)
{
	return minVal + (maxVal - minVal) * t;
}

inline tcu::Vec4 linearInterpolate (float t, const tcu::Vec4& a, const tcu::Vec4& b)
{
	return a + (b - a) * t;
}

inline float bilinearInterpolate (float x, float y, const tcu::Vec4& quad)
{
	float w00 = (1.0f-x)*(1.0f-y);
	float w01 = (1.0f-x)*y;
	float w10 = x*(1.0f-y);
	float w11 = x*y;
	return quad.x()*w00 + quad.y()*w10 + quad.z()*w01 + quad.w()*w11;
}

float triangleInterpolate (float v0, float v1, float v2, float x, float y)
{
	return v0 + (v2-v0)*x + (v1-v0)*y;
}

float triangleInterpolate (const tcu::Vec3& v, float x, float y)
{
	return triangleInterpolate(v.x(), v.y(), v.z(), x, y);
}

// 1D lookup LOD computation.

float computeLodFromDerivates (LodMode mode, float dudx, float dudy)
{
	float p = 0.0f;
	switch (mode)
	{
		// \note [mika] Min and max bounds equal to exact with 1D textures
		case LODMODE_EXACT:
		case LODMODE_MIN_BOUND:
		case LODMODE_MAX_BOUND:
			p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
			break;

		default:
			DE_ASSERT(DE_FALSE);
	}

	return deFloatLog2(p);
}

float computeNonProjectedTriLod (LodMode mode, const tcu::IVec2& dstSize, deInt32 srcSize, const tcu::Vec3& sq)
{
	float dux	= (sq.z() - sq.x()) * (float)srcSize;
	float duy	= (sq.y() - sq.x()) * (float)srcSize;
	float dx	= (float)dstSize.x();
	float dy	= (float)dstSize.y();

	return computeLodFromDerivates(mode, dux/dx, duy/dy);
}

// 2D lookup LOD computation.

float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
{
	float p = 0.0f;
	switch (mode)
	{
		case LODMODE_EXACT:
			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx), deFloatSqrt(dudy*dudy + dvdy*dvdy));
			break;

		case LODMODE_MIN_BOUND:
		case LODMODE_MAX_BOUND:
		{
			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));

			p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
	}

	return deFloatLog2(p);
}

float computeNonProjectedTriLod (LodMode mode, const tcu::IVec2& dstSize, const tcu::IVec2& srcSize, const tcu::Vec3& sq, const tcu::Vec3& tq)
{
	float dux	= (sq.z() - sq.x()) * (float)srcSize.x();
	float duy	= (sq.y() - sq.x()) * (float)srcSize.x();
	float dvx	= (tq.z() - tq.x()) * (float)srcSize.y();
	float dvy	= (tq.y() - tq.x()) * (float)srcSize.y();
	float dx	= (float)dstSize.x();
	float dy	= (float)dstSize.y();

	return computeLodFromDerivates(mode, dux/dx, dvx/dx, duy/dy, dvy/dy);
}

// 3D lookup LOD computation.

float computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
{
	float p = 0.0f;
	switch (mode)
	{
		case LODMODE_EXACT:
			p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx + dwdx*dwdx), deFloatSqrt(dudy*dudy + dvdy*dvdy + dwdy*dwdy));
			break;

		case LODMODE_MIN_BOUND:
		case LODMODE_MAX_BOUND:
		{
			float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
			float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
			float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));

			p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
	}

	return deFloatLog2(p);
}

float computeNonProjectedTriLod (LodMode mode, const tcu::IVec2& dstSize, const tcu::IVec3& srcSize, const tcu::Vec3& sq, const tcu::Vec3& tq, const tcu::Vec3& rq)
{
	float dux	= (sq.z() - sq.x()) * (float)srcSize.x();
	float duy	= (sq.y() - sq.x()) * (float)srcSize.x();
	float dvx	= (tq.z() - tq.x()) * (float)srcSize.y();
	float dvy	= (tq.y() - tq.x()) * (float)srcSize.y();
	float dwx	= (rq.z() - rq.x()) * (float)srcSize.z();
	float dwy	= (rq.y() - rq.x()) * (float)srcSize.z();
	float dx	= (float)dstSize.x();
	float dy	= (float)dstSize.y();

	return computeLodFromDerivates(mode, dux/dx, dvx/dx, dwx/dx, duy/dy, dvy/dy, dwy/dy);
}

static inline float projectedTriInterpolate (const tcu::Vec3& s, const tcu::Vec3& w, float nx, float ny)
{
	return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
}

static inline float triDerivateX (const tcu::Vec3& s, const tcu::Vec3& w, float wx, float width, float ny)
{
	float d = w[1]*w[2]*(width*(ny - 1.0f) + wx) - w[0]*(w[2]*width*ny + w[1]*wx);
	return (w[0]*w[1]*w[2]*width * (w[1]*(s[0] - s[2])*(ny - 1.0f) + ny*(w[2]*(s[1] - s[0]) + w[0]*(s[2] - s[1])))) / (d*d);
}

static inline float triDerivateY (const tcu::Vec3& s, const tcu::Vec3& w, float wy, float height, float nx)
{
	float d = w[1]*w[2]*(height*(nx - 1.0f) + wy) - w[0]*(w[1]*height*nx + w[2]*wy);
	return (w[0]*w[1]*w[2]*height * (w[2]*(s[0] - s[1])*(nx - 1.0f) + nx*(w[0]*(s[1] - s[2]) + w[1]*(s[2] - s[0])))) / (d*d);
}

// 1D lookup LOD.
static float computeProjectedTriLod (LodMode mode, const tcu::Vec3& u, const tcu::Vec3& projection, float wx, float wy, float width, float height)
{
	// Exact derivatives.
	float dudx	= triDerivateX(u, projection, wx, width, wy/height);
	float dudy	= triDerivateY(u, projection, wy, height, wx/width);

	return computeLodFromDerivates(mode, dudx, dudy);
}

// 2D lookup LOD.
static float computeProjectedTriLod (LodMode mode, const tcu::Vec3& u, const tcu::Vec3& v, const tcu::Vec3& projection, float wx, float wy, float width, float height)
{
	// Exact derivatives.
	float dudx	= triDerivateX(u, projection, wx, width, wy/height);
	float dvdx	= triDerivateX(v, projection, wx, width, wy/height);
	float dudy	= triDerivateY(u, projection, wy, height, wx/width);
	float dvdy	= triDerivateY(v, projection, wy, height, wx/width);

	return computeLodFromDerivates(mode, dudx, dvdx, dudy, dvdy);
}

// 3D lookup LOD.
static float computeProjectedTriLod (LodMode mode, const tcu::Vec3& u, const tcu::Vec3& v, const tcu::Vec3& w, const tcu::Vec3& projection, float wx, float wy, float width, float height)
{
	// Exact derivatives.
	float dudx	= triDerivateX(u, projection, wx, width, wy/height);
	float dvdx	= triDerivateX(v, projection, wx, width, wy/height);
	float dwdx	= triDerivateX(w, projection, wx, width, wy/height);
	float dudy	= triDerivateY(u, projection, wy, height, wx/width);
	float dvdy	= triDerivateY(v, projection, wy, height, wx/width);
	float dwdy	= triDerivateY(w, projection, wy, height, wx/width);

	return computeLodFromDerivates(mode, dudx, dvdx, dwdx, dudy, dvdy, dwdy);
}

static inline tcu::Vec4 execSample (const tcu::Texture1DView& src, const ReferenceParams& params, float s, float lod)
{
	if (params.samplerType == SAMPLERTYPE_SHADOW)
		return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, lod), 0.0, 0.0, 1.0f);
	else
		return src.sample(params.sampler, s, lod);
}

static inline tcu::Vec4 execSample (const tcu::Texture2DView& src, const ReferenceParams& params, float s, float t, float lod)
{
	if (params.samplerType == SAMPLERTYPE_SHADOW)
		return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, lod), 0.0, 0.0, 1.0f);
	else
		return src.sample(params.sampler, s, t, lod);
}

static inline tcu::Vec4 execSample (const tcu::TextureCubeView& src, const ReferenceParams& params, float s, float t, float r, float lod)
{
	if (params.samplerType == SAMPLERTYPE_SHADOW)
		return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, lod), 0.0, 0.0, 1.0f);
	else
		return src.sample(params.sampler, s, t, r, lod);
}

static inline tcu::Vec4 execSample (const tcu::Texture2DArrayView& src, const ReferenceParams& params, float s, float t, float r, float lod)
{
	if (params.samplerType == SAMPLERTYPE_SHADOW)
		return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, lod), 0.0, 0.0, 1.0f);
	else
		return src.sample(params.sampler, s, t, r, lod);
}

static inline tcu::Vec4 execSample (const tcu::TextureCubeArrayView& src, const ReferenceParams& params, float s, float t, float r, float q, float lod)
{
	if (params.samplerType == SAMPLERTYPE_SHADOW)
		return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, q, lod), 0.0, 0.0, 1.0f);
	else
		return src.sample(params.sampler, s, t, r, q, lod);
}

static inline tcu::Vec4 execSample (const tcu::Texture1DArrayView& src, const ReferenceParams& params, float s, float t, float lod)
{
	if (params.samplerType == SAMPLERTYPE_SHADOW)
		return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, lod), 0.0, 0.0, 1.0f);
	else
		return src.sample(params.sampler, s, t, lod);
}

static void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture1DView& rawSrc, const tcu::Vec4& sq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture1DView					src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;

	tcu::IVec2									dstSize				= tcu::IVec2(dst.getWidth(), dst.getHeight());
	int											srcSize				= src.getWidth();

	// Coordinates and lod per triangle.
	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	float										triLod[2]			= { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0]) + lodBias, params.minLod, params.maxLod),
																		de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1]) + lodBias, params.minLod, params.maxLod) };

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			float	yf		= ((float)y + 0.5f) / (float)dst.getHeight();
			float	xf		= ((float)x + 0.5f) / (float)dst.getWidth();

			int		triNdx	= xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
			float	triX	= triNdx ? 1.0f-xf : xf;
			float	triY	= triNdx ? 1.0f-yf : yf;

			float	s		= triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
			float	lod		= triLod[triNdx];

			dst.setPixel(execSample(src, params, s, lod) * params.colorScale + params.colorBias, x, y);
		}
	}
}

template<class PixelAccess>
static void sampleTextureNonProjected (const PixelAccess& dst, const tcu::Texture2DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	tcu::Texture2DView							src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;

	tcu::IVec2									dstSize				= tcu::IVec2(dst.getWidth(), dst.getHeight());
	tcu::IVec2									srcSize				= tcu::IVec2(src.getWidth(), src.getHeight());

	// Coordinates and lod per triangle.
	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	float										triLod[2]			= { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias, params.minLod, params.maxLod),
																		de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias, params.minLod, params.maxLod) };

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			float	yf		= ((float)y + 0.5f) / (float)dst.getHeight();
			float	xf		= ((float)x + 0.5f) / (float)dst.getWidth();

			int		triNdx	= xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
			float	triX	= triNdx ? 1.0f-xf : xf;
			float	triY	= triNdx ? 1.0f-yf : yf;

			float	s		= triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
			float	t		= triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
			float	lod		= triLod[triNdx];

			if (params.imageViewMinLod != 0.0f && params.samplerType == SAMPLERTYPE_FETCH_FLOAT)
				lod = (float)params.lodTexelFetch;

			if (params.float16TexCoord)
			{
				s   = tcu::Float16(s, tcu::ROUND_TO_ZERO).asFloat();
				t   = tcu::Float16(t, tcu::ROUND_TO_ZERO).asFloat();
			}

			dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, x, y);
		}
	}
}

static void sampleTextureProjected (const tcu::SurfaceAccess& dst, const tcu::Texture1DView& rawSrc, const tcu::Vec4& sq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture1DView					src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
	float										dstW				= (float)dst.getWidth();
	float										dstH				= (float)dst.getHeight();

	tcu::Vec4									uq					= sq * (float)src.getWidth();

	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triU[2]				= { uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1) };
	tcu::Vec3									triW[2]				= { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) };

	for (int py = 0; py < dst.getHeight(); py++)
	{
		for (int px = 0; px < dst.getWidth(); px++)
		{
			float	wx		= (float)px + 0.5f;
			float	wy		= (float)py + 0.5f;
			float	nx		= wx / dstW;
			float	ny		= wy / dstH;

			int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
			float	triWx	= triNdx ? dstW - wx : wx;
			float	triWy	= triNdx ? dstH - wy : wy;
			float	triNx	= triNdx ? 1.0f - nx : nx;
			float	triNy	= triNdx ? 1.0f - ny : ny;

			float	s		= projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
			float	lod		= computeProjectedTriLod(params.lodMode, triU[triNdx], triW[triNdx], triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight())
							+ lodBias;

			dst.setPixel(execSample(src, params, s, lod) * params.colorScale + params.colorBias, px, py);
		}
	}
}

template<class PixelAccess>
static void sampleTextureProjected (const PixelAccess& dst, const tcu::Texture2DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture2DView					src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
	float										dstW				= (float)dst.getWidth();
	float										dstH				= (float)dst.getHeight();

	tcu::Vec4									uq					= sq * (float)src.getWidth();
	tcu::Vec4									vq					= tq * (float)src.getHeight();

	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	tcu::Vec3									triU[2]				= { uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1) };
	tcu::Vec3									triV[2]				= { vq.swizzle(0, 1, 2), vq.swizzle(3, 2, 1) };
	tcu::Vec3									triW[2]				= { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) };

	for (int py = 0; py < dst.getHeight(); py++)
	{
		for (int px = 0; px < dst.getWidth(); px++)
		{
			float	wx		= (float)px + 0.5f;
			float	wy		= (float)py + 0.5f;
			float	nx		= wx / dstW;
			float	ny		= wy / dstH;

			int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
			float	triWx	= triNdx ? dstW - wx : wx;
			float	triWy	= triNdx ? dstH - wy : wy;
			float	triNx	= triNdx ? 1.0f - nx : nx;
			float	triNy	= triNdx ? 1.0f - ny : ny;

			float	s		= projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
			float	t		= projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy);
			float	lod		= computeProjectedTriLod(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight())
							+ lodBias;

			dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, px, py);
		}
	}
}

void sampleTexture (const tcu::PixelBufferAccess& dst, const tcu::Texture2DView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::ImageViewMinLodParams	minLodParams =
	{
		params.baseLevel,								// int		baseLevel;
		{
			params.imageViewMinLod,							// float	minLod;
			params.imageViewMinLodMode,						// ImageViewMinLodMode
		},
		params.samplerType == SAMPLERTYPE_FETCH_FLOAT	// bool	intTexCoord;
	};

	const tcu::Texture2DView	view	= getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
	const tcu::Vec4				sq		= tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	const tcu::Vec4				tq		= tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	if (params.flags & ReferenceParams::PROJECTED)
		sampleTextureProjected(dst, view, sq, tq, params);
	else
		sampleTextureNonProjected(dst, view, sq, tq, params);
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture2DView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::ImageViewMinLodParams	minLodParams =
	{
		params.baseLevel,								// int		baseLevel;
		{
			params.imageViewMinLod,							// float	minLod;
			params.imageViewMinLodMode,						// ImageViewMinLodMode
		},
		params.samplerType == SAMPLERTYPE_FETCH_FLOAT	// bool		intTexCoord;
	};

	const tcu::Texture2DView	view	= getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
	const tcu::Vec4				sq		= tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	const tcu::Vec4				tq		= tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	if (params.flags & ReferenceParams::PROJECTED)
		sampleTextureProjected(dst, view, sq, tq, params);
	else
		sampleTextureNonProjected(dst, view, sq, tq, params);
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture1DView& src, const float* texCoord, const ReferenceParams& params)
{
	const tcu::Texture1DView	view	= getSubView(src, params.baseLevel, params.maxLevel, DE_NULL);
	const tcu::Vec4				sq		= tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);

	if (params.flags & ReferenceParams::PROJECTED)
		sampleTextureProjected(dst, view, sq, params);
	else
		sampleTextureNonProjected(dst, view, sq, params);
}

static float computeCubeLodFromDerivates (LodMode lodMode, const tcu::Vec3& coord, const tcu::Vec3& coordDx, const tcu::Vec3& coordDy, const int faceSize)
{
	const tcu::CubeFace	face	= tcu::selectCubeFace(coord);
	int					maNdx	= 0;
	int					sNdx	= 0;
	int					tNdx	= 0;

	// \note Derivate signs don't matter when computing lod
	switch (face)
	{
		case tcu::CUBEFACE_NEGATIVE_X:
		case tcu::CUBEFACE_POSITIVE_X: maNdx = 0; sNdx = 2; tNdx = 1; break;
		case tcu::CUBEFACE_NEGATIVE_Y:
		case tcu::CUBEFACE_POSITIVE_Y: maNdx = 1; sNdx = 0; tNdx = 2; break;
		case tcu::CUBEFACE_NEGATIVE_Z:
		case tcu::CUBEFACE_POSITIVE_Z: maNdx = 2; sNdx = 0; tNdx = 1; break;
		default:
			DE_ASSERT(DE_FALSE);
	}

	{
		const float		sc		= coord[sNdx];
		const float		tc		= coord[tNdx];
		const float		ma		= de::abs(coord[maNdx]);
		const float		scdx	= coordDx[sNdx];
		const float		tcdx	= coordDx[tNdx];
		const float		madx	= de::abs(coordDx[maNdx]);
		const float		scdy	= coordDy[sNdx];
		const float		tcdy	= coordDy[tNdx];
		const float		mady	= de::abs(coordDy[maNdx]);
		const float		dudx	= float(faceSize) * 0.5f * (scdx*ma - sc*madx) / (ma*ma);
		const float		dvdx	= float(faceSize) * 0.5f * (tcdx*ma - tc*madx) / (ma*ma);
		const float		dudy	= float(faceSize) * 0.5f * (scdy*ma - sc*mady) / (ma*ma);
		const float		dvdy	= float(faceSize) * 0.5f * (tcdy*ma - tc*mady) / (ma*ma);

		return computeLodFromDerivates(lodMode, dudx, dvdx, dudy, dvdy);
	}
}

static void sampleTextureCube (const tcu::SurfaceAccess& dst, const tcu::TextureCubeView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::TextureCubeView					src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	const tcu::IVec2							dstSize				= tcu::IVec2(dst.getWidth(), dst.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const int									srcSize				= src.getSize();

	// Coordinates per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) };

	const float									lodBias				((params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f);

	for (int py = 0; py < dst.getHeight(); py++)
	{
		for (int px = 0; px < dst.getWidth(); px++)
		{
			const float		wx		= (float)px + 0.5f;
			const float		wy		= (float)py + 0.5f;
			const float		nx		= wx / dstW;
			const float		ny		= wy / dstH;

			const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
			const float		triNx	= triNdx ? 1.0f - nx : nx;
			const float		triNy	= triNdx ? 1.0f - ny : ny;

			const tcu::Vec3	coord		(triangleInterpolate(triS[triNdx], triNx, triNy),
										 triangleInterpolate(triT[triNdx], triNx, triNy),
										 triangleInterpolate(triR[triNdx], triNx, triNy));
			const tcu::Vec3	coordDx		(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
										 triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
										 triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
			const tcu::Vec3	coordDy		(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
										 triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
										 triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));

			const float		lod			= de::clamp(computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, srcSize) + lodBias, params.minLod, params.maxLod);

			dst.setPixel(execSample(src, params, coord.x(), coord.y(), coord.z(), lod) * params.colorScale + params.colorBias, px, py);
		}
	}
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::TextureCubeView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::ImageViewMinLodParams	minLodParams =
	{
		params.baseLevel,								// int		baseLevel;
		{
			params.imageViewMinLod,							// float	minLod;
			params.imageViewMinLodMode,						// ImageViewMinLodMode
		},
		params.samplerType == SAMPLERTYPE_FETCH_FLOAT	// bool	intTexCoord;
	};

	const tcu::TextureCubeView	view	= getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
	const tcu::Vec4				sq		= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4				tq		= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4				rq		= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	return sampleTextureCube(dst, view, sq, tq, rq, params);
}

static void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture2DArrayView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture2DArrayView				src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;

	tcu::IVec2									dstSize				= tcu::IVec2(dst.getWidth(), dst.getHeight());
	tcu::IVec2									srcSize				= tcu::IVec2(src.getWidth(), src.getHeight());

	// Coordinates and lod per triangle.
	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	tcu::Vec3									triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	float										triLod[2]			= { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias, params.minLod, params.maxLod),
																		de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias, params.minLod, params.maxLod) };

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			float	yf		= ((float)y + 0.5f) / (float)dst.getHeight();
			float	xf		= ((float)x + 0.5f) / (float)dst.getWidth();

			int		triNdx	= xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
			float	triX	= triNdx ? 1.0f-xf : xf;
			float	triY	= triNdx ? 1.0f-yf : yf;

			float	s		= triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
			float	t		= triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
			float	r		= triangleInterpolate(triR[triNdx].x(), triR[triNdx].y(), triR[triNdx].z(), triX, triY);
			float	lod		= triLod[triNdx];

			dst.setPixel(execSample(src, params, s, t, r, lod) * params.colorScale + params.colorBias, x, y);
		}
	}
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture2DArrayView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	DE_ASSERT(!(params.flags & ReferenceParams::PROJECTED)); // \todo [2012-02-17 pyry] Support projected lookups.
	sampleTextureNonProjected(dst, src, sq, tq, rq, params);
}

static void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture1DArrayView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture1DArrayView				src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;

	tcu::IVec2									dstSize				= tcu::IVec2(dst.getWidth(), dst.getHeight());
	deInt32										srcSize				= src.getWidth();

	// Coordinates and lod per triangle.
	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	float										triLod[2]			= { computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0]) + lodBias,
																		computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1]) + lodBias};

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			float	yf		= ((float)y + 0.5f) / (float)dst.getHeight();
			float	xf		= ((float)x + 0.5f) / (float)dst.getWidth();

			int		triNdx	= xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
			float	triX	= triNdx ? 1.0f-xf : xf;
			float	triY	= triNdx ? 1.0f-yf : yf;

			float	s		= triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
			float	t		= triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
			float	lod		= triLod[triNdx];

			dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, x, y);
		}
	}
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture1DArrayView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	DE_ASSERT(!(params.flags & ReferenceParams::PROJECTED)); // \todo [2014-06-09 mika] Support projected lookups.
	sampleTextureNonProjected(dst, src, sq, tq, params);
}

static void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture3DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture3DView					src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;

	tcu::IVec2									dstSize				= tcu::IVec2(dst.getWidth(), dst.getHeight());
	tcu::IVec3									srcSize				= tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth());

	// Coordinates and lod per triangle.
	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	tcu::Vec3									triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	float										triLod[2]			= { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0], triR[0]) + lodBias, params.minLod, params.maxLod),
																		de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1], triR[1]) + lodBias, params.minLod, params.maxLod) };

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			float	yf		= ((float)y + 0.5f) / (float)dst.getHeight();
			float	xf		= ((float)x + 0.5f) / (float)dst.getWidth();

			int		triNdx	= xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
			float	triX	= triNdx ? 1.0f-xf : xf;
			float	triY	= triNdx ? 1.0f-yf : yf;

			float	s		= triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
			float	t		= triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
			float	r		= triangleInterpolate(triR[triNdx].x(), triR[triNdx].y(), triR[triNdx].z(), triX, triY);
			float	lod		= triLod[triNdx];

			if (params.imageViewMinLod != 0.0f && params.samplerType == SAMPLERTYPE_FETCH_FLOAT)
				lod = (float)params.lodTexelFetch;

			dst.setPixel(src.sample(params.sampler, s, t, r, lod) * params.colorScale + params.colorBias, x, y);
		}
	}
}

static void sampleTextureProjected (const tcu::SurfaceAccess& dst, const tcu::Texture3DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture3DView					src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	float										lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
	float										dstW				= (float)dst.getWidth();
	float										dstH				= (float)dst.getHeight();

	tcu::Vec4									uq					= sq * (float)src.getWidth();
	tcu::Vec4									vq					= tq * (float)src.getHeight();
	tcu::Vec4									wq					= rq * (float)src.getDepth();

	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	tcu::Vec3									triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	tcu::Vec3									triU[2]				= { uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1) };
	tcu::Vec3									triV[2]				= { vq.swizzle(0, 1, 2), vq.swizzle(3, 2, 1) };
	tcu::Vec3									triW[2]				= { wq.swizzle(0, 1, 2), wq.swizzle(3, 2, 1) };
	tcu::Vec3									triP[2]				= { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) };

	for (int py = 0; py < dst.getHeight(); py++)
	{
		for (int px = 0; px < dst.getWidth(); px++)
		{
			float	wx		= (float)px + 0.5f;
			float	wy		= (float)py + 0.5f;
			float	nx		= wx / dstW;
			float	ny		= wy / dstH;

			int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
			float	triWx	= triNdx ? dstW - wx : wx;
			float	triWy	= triNdx ? dstH - wy : wy;
			float	triNx	= triNdx ? 1.0f - nx : nx;
			float	triNy	= triNdx ? 1.0f - ny : ny;

			float	s		= projectedTriInterpolate(triS[triNdx], triP[triNdx], triNx, triNy);
			float	t		= projectedTriInterpolate(triT[triNdx], triP[triNdx], triNx, triNy);
			float	r		= projectedTriInterpolate(triR[triNdx], triP[triNdx], triNx, triNy);
			float	lod		= computeProjectedTriLod(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triP[triNdx], triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight())
							+ lodBias;

			dst.setPixel(src.sample(params.sampler, s, t, r, lod) * params.colorScale + params.colorBias, px, py);
		}
	}
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture3DView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::ImageViewMinLodParams	minLodParams =
	{
		params.baseLevel,								// int		baseLevel;
		{
			params.imageViewMinLod,							// float	minLod;
			params.imageViewMinLodMode,						// ImageViewMinLodMode
		},
		params.samplerType == SAMPLERTYPE_FETCH_FLOAT	// bool	intTexCoord;
	};

	const tcu::Texture3DView	view	= getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
	const tcu::Vec4				sq		= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4				tq		= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4				rq		= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	if (params.flags & ReferenceParams::PROJECTED)
		sampleTextureProjected(dst, view, sq, tq, rq, params);
	else
		sampleTextureNonProjected(dst, view, sq, tq, rq, params);
}

static void sampleTextureCubeArray (const tcu::SurfaceAccess& dst, const tcu::TextureCubeArrayView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const tcu::Vec4& qq, const ReferenceParams& params)
{
	// Separate combined DS formats
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::TextureCubeArrayView				src					= getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);

	const float									dstW				= (float)dst.getWidth();
	const float									dstH				= (float)dst.getHeight();

	// Coordinates per triangle.
	tcu::Vec3									triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	tcu::Vec3									triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	tcu::Vec3									triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	tcu::Vec3									triQ[2]				= { qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) };

	const float									lodBias				= (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;

	for (int py = 0; py < dst.getHeight(); py++)
	{
		for (int px = 0; px < dst.getWidth(); px++)
		{
			const float		wx		= (float)px + 0.5f;
			const float		wy		= (float)py + 0.5f;
			const float		nx		= wx / dstW;
			const float		ny		= wy / dstH;

			const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
			const float		triNx	= triNdx ? 1.0f - nx : nx;
			const float		triNy	= triNdx ? 1.0f - ny : ny;

			const tcu::Vec3	coord	(triangleInterpolate(triS[triNdx], triNx, triNy),
									 triangleInterpolate(triT[triNdx], triNx, triNy),
									 triangleInterpolate(triR[triNdx], triNx, triNy));

			const float		coordQ	= triangleInterpolate(triQ[triNdx], triNx, triNy);

			const tcu::Vec3	coordDx	(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
									 triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
									 triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
			const tcu::Vec3	coordDy	(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
									 triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
									 triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));

			const float		lod		= de::clamp(computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, src.getSize()) + lodBias, params.minLod, params.maxLod);

			dst.setPixel(execSample(src, params, coord.x(), coord.y(), coord.z(), coordQ, lod) * params.colorScale + params.colorBias, px, py);
		}
	}
}

void sampleTexture (const tcu::SurfaceAccess& dst, const tcu::TextureCubeArrayView& src, const float* texCoord, const ReferenceParams& params)
{
	tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[4+0], texCoord[8+0], texCoord[12+0]);
	tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[4+1], texCoord[8+1], texCoord[12+1]);
	tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[4+2], texCoord[8+2], texCoord[12+2]);
	tcu::Vec4 qq = tcu::Vec4(texCoord[0+3], texCoord[4+3], texCoord[8+3], texCoord[12+3]);

	sampleTextureCubeArray(dst, src, sq, tq, rq, qq, params);
}

void fetchTexture (const tcu::SurfaceAccess& dst, const tcu::ConstPixelBufferAccess& src, const float* texCoord, const tcu::Vec4& colorScale, const tcu::Vec4& colorBias)
{
	const tcu::Vec4		sq			= tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);
	const tcu::Vec3		triS[2]		= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			const float	yf		= ((float)y + 0.5f) / (float)dst.getHeight();
			const float	xf		= ((float)x + 0.5f) / (float)dst.getWidth();

			const int	triNdx	= xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
			const float	triX	= triNdx ? 1.0f-xf : xf;
			const float	triY	= triNdx ? 1.0f-yf : yf;

			const float	s		= triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);

			dst.setPixel(src.getPixel((int)s, 0) * colorScale + colorBias, x, y);
		}
	}
}

bool compareImages (tcu::TestLog& log, const tcu::Surface& reference, const tcu::Surface& rendered, tcu::RGBA threshold)
{
	return tcu::pixelThresholdCompare(log, "Result", "Image comparison result", reference, rendered, threshold, tcu::COMPARE_LOG_RESULT);
}

bool compareImages (tcu::TestLog& log, const char* name, const char* desc, const tcu::Surface& reference, const tcu::Surface& rendered, tcu::RGBA threshold)
{
	return tcu::pixelThresholdCompare(log, name, desc, reference, rendered, threshold, tcu::COMPARE_LOG_RESULT);
}

int measureAccuracy (tcu::TestLog& log, const tcu::Surface& reference, const tcu::Surface& rendered, int bestScoreDiff, int worstScoreDiff)
{
	return tcu::measurePixelDiffAccuracy(log, "Result", "Image comparison result", reference, rendered, bestScoreDiff, worstScoreDiff, tcu::COMPARE_LOG_EVERYTHING);
}

inline int rangeDiff (int x, int a, int b)
{
	if (x < a)
		return a-x;
	else if (x > b)
		return x-b;
	else
		return 0;
}

inline tcu::RGBA rangeDiff (tcu::RGBA p, tcu::RGBA a, tcu::RGBA b)
{
	int rMin = de::min(a.getRed(),		b.getRed());
	int rMax = de::max(a.getRed(),		b.getRed());
	int gMin = de::min(a.getGreen(),	b.getGreen());
	int gMax = de::max(a.getGreen(),	b.getGreen());
	int bMin = de::min(a.getBlue(),		b.getBlue());
	int bMax = de::max(a.getBlue(),		b.getBlue());
	int aMin = de::min(a.getAlpha(),	b.getAlpha());
	int aMax = de::max(a.getAlpha(),	b.getAlpha());

	return tcu::RGBA(rangeDiff(p.getRed(),		rMin, rMax),
					 rangeDiff(p.getGreen(),	gMin, gMax),
					 rangeDiff(p.getBlue(),		bMin, bMax),
					 rangeDiff(p.getAlpha(),	aMin, aMax));
}

inline bool rangeCompare (tcu::RGBA p, tcu::RGBA a, tcu::RGBA b, tcu::RGBA threshold)
{
	tcu::RGBA diff = rangeDiff(p, a, b);
	return diff.getRed()	<= threshold.getRed() &&
		   diff.getGreen()	<= threshold.getGreen() &&
		   diff.getBlue()	<= threshold.getBlue() &&
		   diff.getAlpha()	<= threshold.getAlpha();
}

void computeQuadTexCoord1D (std::vector<float>& dst, float left, float right)
{
	dst.resize(4);

	dst[0] = left;
	dst[1] = left;
	dst[2] = right;
	dst[3] = right;
}

void computeQuadTexCoord1DArray (std::vector<float>& dst, int layerNdx, float left, float right)
{
	dst.resize(4*2);

	dst[0] = left;	dst[1] = (float)layerNdx;
	dst[2] = left;	dst[3] = (float)layerNdx;
	dst[4] = right;	dst[5] = (float)layerNdx;
	dst[6] = right;	dst[7] = (float)layerNdx;
}

void computeQuadTexCoord2D (std::vector<float>& dst, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight)
{
	dst.resize(4*2);

	dst[0] = bottomLeft.x();	dst[1] = bottomLeft.y();
	dst[2] = bottomLeft.x();	dst[3] = topRight.y();
	dst[4] = topRight.x();		dst[5] = bottomLeft.y();
	dst[6] = topRight.x();		dst[7] = topRight.y();
}

void computeQuadTexCoord2DArray (std::vector<float>& dst, int layerNdx, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight)
{
	dst.resize(4*3);

	dst[0] = bottomLeft.x();	dst[ 1] = bottomLeft.y();	dst[ 2] = (float)layerNdx;
	dst[3] = bottomLeft.x();	dst[ 4] = topRight.y();		dst[ 5] = (float)layerNdx;
	dst[6] = topRight.x();		dst[ 7] = bottomLeft.y();	dst[ 8] = (float)layerNdx;
	dst[9] = topRight.x();		dst[10] = topRight.y();		dst[11] = (float)layerNdx;
}

void computeQuadTexCoord3D (std::vector<float>& dst, const tcu::Vec3& p0, const tcu::Vec3& p1, const tcu::IVec3& dirSwz)
{
	tcu::Vec3 f0 = tcu::Vec3(0.0f, 0.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
	tcu::Vec3 f1 = tcu::Vec3(0.0f, 1.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
	tcu::Vec3 f2 = tcu::Vec3(1.0f, 0.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
	tcu::Vec3 f3 = tcu::Vec3(1.0f, 1.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);

	tcu::Vec3 v0 = p0 + (p1-p0)*f0;
	tcu::Vec3 v1 = p0 + (p1-p0)*f1;
	tcu::Vec3 v2 = p0 + (p1-p0)*f2;
	tcu::Vec3 v3 = p0 + (p1-p0)*f3;

	dst.resize(4*3);

	dst[0] = v0.x(); dst[ 1] = v0.y(); dst[ 2] = v0.z();
	dst[3] = v1.x(); dst[ 4] = v1.y(); dst[ 5] = v1.z();
	dst[6] = v2.x(); dst[ 7] = v2.y(); dst[ 8] = v2.z();
	dst[9] = v3.x(); dst[10] = v3.y(); dst[11] = v3.z();
}

void computeQuadTexCoordCube (std::vector<float>& dst, tcu::CubeFace face)
{
	static const float texCoordNegX[] =
	{
		-1.0f,  1.0f, -1.0f,
		-1.0f, -1.0f, -1.0f,
		-1.0f,  1.0f,  1.0f,
		-1.0f, -1.0f,  1.0f
	};
	static const float texCoordPosX[] =
	{
		+1.0f,  1.0f,  1.0f,
		+1.0f, -1.0f,  1.0f,
		+1.0f,  1.0f, -1.0f,
		+1.0f, -1.0f, -1.0f
	};
	static const float texCoordNegY[] =
	{
		-1.0f, -1.0f,  1.0f,
		-1.0f, -1.0f, -1.0f,
		 1.0f, -1.0f,  1.0f,
		 1.0f, -1.0f, -1.0f
	};
	static const float texCoordPosY[] =
	{
		-1.0f, +1.0f, -1.0f,
		-1.0f, +1.0f,  1.0f,
		 1.0f, +1.0f, -1.0f,
		 1.0f, +1.0f,  1.0f
	};
	static const float texCoordNegZ[] =
	{
		 1.0f,  1.0f, -1.0f,
		 1.0f, -1.0f, -1.0f,
		-1.0f,  1.0f, -1.0f,
		-1.0f, -1.0f, -1.0f
	};
	static const float texCoordPosZ[] =
	{
		-1.0f,  1.0f, +1.0f,
		-1.0f, -1.0f, +1.0f,
		 1.0f,  1.0f, +1.0f,
		 1.0f, -1.0f, +1.0f
	};

	const float*	texCoord		= DE_NULL;
	int				texCoordSize	= DE_LENGTH_OF_ARRAY(texCoordNegX);

	switch (face)
	{
		case tcu::CUBEFACE_NEGATIVE_X: texCoord = texCoordNegX; break;
		case tcu::CUBEFACE_POSITIVE_X: texCoord = texCoordPosX; break;
		case tcu::CUBEFACE_NEGATIVE_Y: texCoord = texCoordNegY; break;
		case tcu::CUBEFACE_POSITIVE_Y: texCoord = texCoordPosY; break;
		case tcu::CUBEFACE_NEGATIVE_Z: texCoord = texCoordNegZ; break;
		case tcu::CUBEFACE_POSITIVE_Z: texCoord = texCoordPosZ; break;
		default:
			DE_ASSERT(DE_FALSE);
			return;
	}

	dst.resize(texCoordSize);
	std::copy(texCoord, texCoord+texCoordSize, dst.begin());
}

void computeQuadTexCoordCube (std::vector<float>& dst, tcu::CubeFace face, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight)
{
	int		sRow		= 0;
	int		tRow		= 0;
	int		mRow		= 0;
	float	sSign		= 1.0f;
	float	tSign		= 1.0f;
	float	mSign		= 1.0f;

	switch (face)
	{
		case tcu::CUBEFACE_NEGATIVE_X: mRow = 0; sRow = 2; tRow = 1; mSign = -1.0f;				   tSign = -1.0f;	break;
		case tcu::CUBEFACE_POSITIVE_X: mRow = 0; sRow = 2; tRow = 1;				sSign = -1.0f; tSign = -1.0f;	break;
		case tcu::CUBEFACE_NEGATIVE_Y: mRow = 1; sRow = 0; tRow = 2; mSign = -1.0f;				   tSign = -1.0f;	break;
		case tcu::CUBEFACE_POSITIVE_Y: mRow = 1; sRow = 0; tRow = 2;												break;
		case tcu::CUBEFACE_NEGATIVE_Z: mRow = 2; sRow = 0; tRow = 1; mSign = -1.0f; sSign = -1.0f; tSign = -1.0f;	break;
		case tcu::CUBEFACE_POSITIVE_Z: mRow = 2; sRow = 0; tRow = 1;							   tSign = -1.0f;	break;
		default:
			DE_ASSERT(DE_FALSE);
			return;
	}

	dst.resize(3*4);

	dst[0+mRow] = mSign;
	dst[3+mRow] = mSign;
	dst[6+mRow] = mSign;
	dst[9+mRow] = mSign;

	dst[0+sRow] = sSign * bottomLeft.x();
	dst[3+sRow] = sSign * bottomLeft.x();
	dst[6+sRow] = sSign * topRight.x();
	dst[9+sRow] = sSign * topRight.x();

	dst[0+tRow] = tSign * bottomLeft.y();
	dst[3+tRow] = tSign * topRight.y();
	dst[6+tRow] = tSign * bottomLeft.y();
	dst[9+tRow] = tSign * topRight.y();
}

void computeQuadTexCoordCubeArray (std::vector<float>& dst, tcu::CubeFace face, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight, const tcu::Vec2& layerRange)
{
	int			sRow	= 0;
	int			tRow	= 0;
	int			mRow	= 0;
	const int	qRow	= 3;
	float		sSign	= 1.0f;
	float		tSign	= 1.0f;
	float		mSign	= 1.0f;
	const float	l0		= layerRange.x();
	const float	l1		= layerRange.y();

	switch (face)
	{
		case tcu::CUBEFACE_NEGATIVE_X: mRow = 0; sRow = 2; tRow = 1; mSign = -1.0f;				   tSign = -1.0f;	break;
		case tcu::CUBEFACE_POSITIVE_X: mRow = 0; sRow = 2; tRow = 1;				sSign = -1.0f; tSign = -1.0f;	break;
		case tcu::CUBEFACE_NEGATIVE_Y: mRow = 1; sRow = 0; tRow = 2; mSign = -1.0f;				   tSign = -1.0f;	break;
		case tcu::CUBEFACE_POSITIVE_Y: mRow = 1; sRow = 0; tRow = 2;												break;
		case tcu::CUBEFACE_NEGATIVE_Z: mRow = 2; sRow = 0; tRow = 1; mSign = -1.0f; sSign = -1.0f; tSign = -1.0f;	break;
		case tcu::CUBEFACE_POSITIVE_Z: mRow = 2; sRow = 0; tRow = 1;							   tSign = -1.0f;	break;
		default:
			DE_ASSERT(DE_FALSE);
			return;
	}

	dst.resize(4*4);

	dst[ 0+mRow] = mSign;
	dst[ 4+mRow] = mSign;
	dst[ 8+mRow] = mSign;
	dst[12+mRow] = mSign;

	dst[ 0+sRow] = sSign * bottomLeft.x();
	dst[ 4+sRow] = sSign * bottomLeft.x();
	dst[ 8+sRow] = sSign * topRight.x();
	dst[12+sRow] = sSign * topRight.x();

	dst[ 0+tRow] = tSign * bottomLeft.y();
	dst[ 4+tRow] = tSign * topRight.y();
	dst[ 8+tRow] = tSign * bottomLeft.y();
	dst[12+tRow] = tSign * topRight.y();

	if (l0 != l1)
	{
		dst[ 0+qRow] = l0;
		dst[ 4+qRow] = l0*0.5f + l1*0.5f;
		dst[ 8+qRow] = l0*0.5f + l1*0.5f;
		dst[12+qRow] = l1;
	}
	else
	{
		dst[ 0+qRow] = l0;
		dst[ 4+qRow] = l0;
		dst[ 8+qRow] = l0;
		dst[12+qRow] = l0;
	}
}

// Texture result verification

//! Verifies texture lookup results and returns number of failed pixels.
int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::Texture1DView&				baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture1DView					src					= getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel, DE_NULL), srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const int									srcSize				= src.getWidth();

	// Coordinates and lod per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const float		coord		= projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
				const float		coordDx		= triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * float(srcSize);
				const float		coordDy		= triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * float(srcSize);

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const float	coordDxo	= triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * float(srcSize);
					const float	coordDyo	= triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * float(srcSize);
					const tcu::Vec2	lodO	= tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::Texture2DView&				baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	tcu::ImageViewMinLodParams	minLodParams =
	{
		sampleParams.baseLevel,								// int		baseLevel;
		{
			sampleParams.imageViewMinLod,							// float	minLod;
			sampleParams.imageViewMinLodMode,						// ImageViewMinLodMode
		},
		sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT	// bool	intTexCoord;
	};

	const tcu::Texture2DView					view				= getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel, sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);

	const tcu::Texture2DView					src					= getEffectiveTextureView(view, srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	const tcu::Vec4								tq					= tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const tcu::IVec2							srcSize				= tcu::IVec2(src.getWidth(), src.getHeight());

	// Coordinates and lod per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	// imageViewMinLodRel is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled.
	// The value is relative to baseLevel as the Texture*View 'src' was created as the baseLevel being level[0].
	const float									imageViewMinLodRel	= sampleParams.imageViewMinLod - (float)sampleParams.baseLevel;
	// We need to adapt ImageView's minLod value to the mipmap mdoe (i.e. nearest or linear) so we clamp with the right minLod value later.
	const float									imageViewMinLodRelMode = tcu::isSamplerMipmapModeLinear(sampleParams.sampler.minFilter) ? deFloatFloor(imageViewMinLodRel) : (float)deClamp32((int)deFloatCeil(imageViewMinLodRel + 0.5f) - 1, sampleParams.baseLevel, sampleParams.maxLevel);
	const float									minLod				= (sampleParams.imageViewMinLod != 0.0f) ? de::max(imageViewMinLodRelMode, sampleParams.minLod) : sampleParams.minLod;

	const float									posEps				= 1.0f / float(1<<MIN_SUBPIXEL_BITS);

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const bool		tri0	= (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f;
				const bool		tri1	= (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f;

				bool			isOk	= false;

				DE_ASSERT(tri0 || tri1);

				// Pixel can belong to either of the triangles if it lies close enough to the edge.
				for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++)
				{
					const float		triWx	= triNdx ? dstW - wx : wx;
					const float		triWy	= triNdx ? dstH - wy : wy;
					const float		triNx	= triNdx ? 1.0f - nx : nx;
					const float		triNy	= triNdx ? 1.0f - ny : ny;

					const tcu::Vec2	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
					const tcu::Vec2	coordDx		= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
															triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat();
					const tcu::Vec2	coordDy		= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
															triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat();

					tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);

					// Compute lod bounds across lodOffsets range.
					for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
					{
						const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
						const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
						const float		nxo		= wxo/dstW;
						const float		nyo		= wyo/dstH;

						const tcu::Vec2	coordDxo	= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
																triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat();
						const tcu::Vec2	coordDyo	= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
																triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat();
						const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec);

						lodBounds.x() = de::min(lodBounds.x(), lodO.x());
						lodBounds.y() = de::max(lodBounds.y(), lodO.y());
					}

					const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
					if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
					{
						isOk = true;
						break;
					}
				}

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::Texture1DView&				src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::Texture2DView&				src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

//! Verifies texture lookup results and returns number of failed pixels.
int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::TextureCubeView&			baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	tcu::ImageViewMinLodParams	minLodParams =
	{
		sampleParams.baseLevel,								// int		baseLevel;
		{
			sampleParams.imageViewMinLod,					// float	minLod;
			sampleParams.imageViewMinLodMode,				// ImageViewMinLodMode
		},
		sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT	// bool	intTexCoord;
	};

	const tcu::TextureCubeView					src					= getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel, sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL), srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4								tq					= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4								rq					= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const int									srcSize				= src.getSize();

	// Coordinates per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	const float									posEps				= 1.0f / float(1<<MIN_SUBPIXEL_BITS);

	// imageViewMinLodRel is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled.
	// The value is relative to baseLevel as the Texture*View 'src' was created as the baseLevel being level[0].
	const float									imageViewMinLodRel	= sampleParams.imageViewMinLod - (float)sampleParams.baseLevel;
	// We need to adapt ImageView's minLod value to the mipmap mdoe (i.e. nearest or linear) so we clamp with the right minLod value later.
	const float									imageViewMinLodRelMode = tcu::isSamplerMipmapModeLinear(sampleParams.sampler.minFilter) ? deFloatFloor(imageViewMinLodRel) : (float)deClamp32((int)deFloatCeil(imageViewMinLodRel + 0.5f) - 1, sampleParams.baseLevel, sampleParams.maxLevel);
	const float									minLod				= (sampleParams.imageViewMinLod != 0.0f) ? de::max(imageViewMinLodRelMode, sampleParams.minLod) : sampleParams.minLod;

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),

		// \note Not strictly allowed by spec, but implementations do this in practice.
		tcu::Vec2(-1, -1),
		tcu::Vec2(-1, +1),
		tcu::Vec2(+1, -1),
		tcu::Vec2(+1, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const bool		tri0	= (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f;
				const bool		tri1	= (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f;

				bool			isOk	= false;

				DE_ASSERT(tri0 || tri1);

				// Pixel can belong to either of the triangles if it lies close enough to the edge.
				for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++)
				{
					const float		triWx	= triNdx ? dstW - wx : wx;
					const float		triWy	= triNdx ? dstH - wy : wy;
					const float		triNx	= triNdx ? 1.0f - nx : nx;
					const float		triNy	= triNdx ? 1.0f - ny : ny;

					const tcu::Vec3	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
					const tcu::Vec3	coordDx		(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
												 triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
												 triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
					const tcu::Vec3	coordDy		(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
												 triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
												 triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));

					tcu::Vec2		lodBounds	= tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec);

					// Compute lod bounds across lodOffsets range.
					for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
					{
						const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
						const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
						const float		nxo		= wxo/dstW;
						const float		nyo		= wyo/dstH;

						const tcu::Vec3	coordO		(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
													 projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
													 projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
						const tcu::Vec3	coordDxo	(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
													 triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
													 triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
						const tcu::Vec3	coordDyo	(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
													 triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
													 triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
						const tcu::Vec2	lodO		= tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);

						lodBounds.x() = de::min(lodBounds.x(), lodO.x());
						lodBounds.y() = de::max(lodBounds.y(), lodO.y());
					}

					const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);

					if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
					{
						isOk = true;
						break;
					}
				}

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::TextureCubeView&			src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

//! Verifies texture lookup results and returns number of failed pixels.
int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::Texture3DView&				baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	tcu::ImageViewMinLodParams	minLodParams =
	{
		sampleParams.baseLevel,									// int		baseLevel;
		{
			sampleParams.imageViewMinLod,						// float	minLod;
			sampleParams.imageViewMinLodMode,					// ImageViewMinLodMode
		},
		sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT		// bool	intTexCoord;
	};

	const tcu::Texture3DView					src					= getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel, sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL), srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4								tq					= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4								rq					= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const tcu::IVec3							srcSize				= tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth());

	// Coordinates and lod per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	// imageViewMinLodRel is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled.
	// The value is relative to baseLevel as the Texture*View 'src' was created as the baseLevel being level[0].
	const float									imageViewMinLodRel	= sampleParams.imageViewMinLod - (float)sampleParams.baseLevel;
	// We need to adapt ImageView's minLod value to the mipmap mdoe (i.e. nearest or linear) so we clamp with the right minLod value later.
	const float									imageViewMinLodRelMode = tcu::isSamplerMipmapModeLinear(sampleParams.sampler.minFilter) ? deFloatFloor(imageViewMinLodRel) : (float)deClamp32((int)deFloatCeil(imageViewMinLodRel + 0.5f) - 1, sampleParams.baseLevel, sampleParams.maxLevel);
	const float									minLod				= (sampleParams.imageViewMinLod != 0.0f) ? de::max(imageViewMinLodRelMode, sampleParams.minLod) : sampleParams.minLod;

	const float									posEps				= 1.0f / float(1<<MIN_SUBPIXEL_BITS);

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const bool		tri0	= (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f;
				const bool		tri1	= (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f;

				bool			isOk	= false;

				DE_ASSERT(tri0 || tri1);

				// Pixel can belong to either of the triangles if it lies close enough to the edge.
				for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++)
				{
					const float		triWx	= triNdx ? dstW - wx : wx;
					const float		triWy	= triNdx ? dstH - wy : wy;
					const float		triNx	= triNdx ? 1.0f - nx : nx;
					const float		triNy	= triNdx ? 1.0f - ny : ny;

					const tcu::Vec3	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
					const tcu::Vec3	coordDx		= tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
															triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
															triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat();
					const tcu::Vec3	coordDy		= tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
															triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
															triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat();

					tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDx.z(), coordDy.x(), coordDy.y(), coordDy.z(), lodPrec);

					// Compute lod bounds across lodOffsets range.
					for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
					{
						const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
						const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
						const float		nxo		= wxo/dstW;
						const float		nyo		= wyo/dstH;

						const tcu::Vec3	coordDxo	= tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
																triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
																triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat();
						const tcu::Vec3	coordDyo	= tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
																triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
																triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat();
						const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDxo.z(), coordDyo.x(), coordDyo.y(), coordDyo.z(), lodPrec);

						lodBounds.x() = de::min(lodBounds.x(), lodO.x());
						lodBounds.y() = de::max(lodBounds.y(), lodO.y());
					}

					const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);

					if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
					{
						isOk = true;
						break;
					}
				}

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::Texture3DView&				src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

//! Verifies texture lookup results and returns number of failed pixels.
int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::Texture1DArrayView&		baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture1DArrayView				src					= getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	const tcu::Vec4								tq					= tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const float									srcSize				= float(src.getWidth()); // For lod computation, thus #layers is ignored.

	// Coordinates and lod per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec2	coord	(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
										 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
				const float	coordDx		= triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize;
				const float	coordDy		= triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * srcSize;

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const float	coordDxo		= triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize;
					const float	coordDyo		= triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize;
					const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

//! Verifies texture lookup results and returns number of failed pixels.
int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::Texture2DArrayView&		baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture2DArrayView				src					= getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4								tq					= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4								rq					= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const tcu::Vec2								srcSize				= tcu::IVec2(src.getWidth(), src.getHeight()).asFloat(); // For lod computation, thus #layers is ignored.

	// Coordinates and lod per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec3	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
				const tcu::Vec2	coordDx		= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
														triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize;
				const tcu::Vec2	coordDy		= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
														triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize;

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const tcu::Vec2	coordDxo	= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
															triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize;
					const tcu::Vec2	coordDyo	= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
															triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize;
					const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::Texture1DArrayView&		src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::Texture2DArrayView&		src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

//! Verifies texture lookup results and returns number of failed pixels.
int computeTextureLookupDiff (const tcu::ConstPixelBufferAccess&	result,
							  const tcu::ConstPixelBufferAccess&	reference,
							  const tcu::PixelBufferAccess&			errorMask,
							  const tcu::TextureCubeArrayView&		baseView,
							  const float*							texCoord,
							  const ReferenceParams&				sampleParams,
							  const tcu::LookupPrecision&			lookupPrec,
							  const tcu::IVec4&						coordBits,
							  const tcu::LodPrecision&				lodPrec,
							  qpWatchDog*							watchDog)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	tcu::ImageViewMinLodParams	minLodParams =
	{
		sampleParams.baseLevel,									// int		baseLevel;
		{
			sampleParams.imageViewMinLod,							// float	minLod;
			sampleParams.imageViewMinLodMode,						// ImageViewMinLodMode
		},
		sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT		// bool	intTexCoord;
	};

	const tcu::TextureCubeArrayView				src					= getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel, sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL), srcLevelStorage, sampleParams.sampler);

	const tcu::Vec4								sq					= tcu::Vec4(texCoord[0+0], texCoord[4+0], texCoord[8+0], texCoord[12+0]);
	const tcu::Vec4								tq					= tcu::Vec4(texCoord[0+1], texCoord[4+1], texCoord[8+1], texCoord[12+1]);
	const tcu::Vec4								rq					= tcu::Vec4(texCoord[0+2], texCoord[4+2], texCoord[8+2], texCoord[12+2]);
	const tcu::Vec4								qq					= tcu::Vec4(texCoord[0+3], texCoord[4+3], texCoord[8+3], texCoord[12+3]);

	const tcu::IVec2							dstSize				= tcu::IVec2(result.getWidth(), result.getHeight());
	const float									dstW				= float(dstSize.x());
	const float									dstH				= float(dstSize.y());
	const int									srcSize				= src.getSize();

	// Coordinates per triangle.
	const tcu::Vec3								triS[2]				= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3								triT[2]				= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3								triR[2]				= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3								triQ[2]				= { qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1) };
	const tcu::Vec3								triW[2]				= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2								lodBias				((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	const float									posEps				= 1.0f / float((1<<4) + 1); // ES3 requires at least 4 subpixel bits.

	int											numFailed			= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),

		// \note Not strictly allowed by spec, but implementations do this in practice.
		tcu::Vec2(-1, -1),
		tcu::Vec2(-1, +1),
		tcu::Vec2(+1, -1),
		tcu::Vec2(+1, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		// Ugly hack, validation can take way too long at the moment.
		if (watchDog)
			qpWatchDog_touch(watchDog);

		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= (result.getPixel(px, py)		- sampleParams.colorBias) / sampleParams.colorScale;
			const tcu::Vec4	refPix	= (reference.getPixel(px, py)	- sampleParams.colorBias) / sampleParams.colorScale;

			// Try comparison to ideal reference first, and if that fails use slower verificator.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const bool		tri0	= nx + ny - posEps <= 1.0f;
				const bool		tri1	= nx + ny + posEps >= 1.0f;

				bool			isOk	= false;

				DE_ASSERT(tri0 || tri1);

				// Pixel can belong to either of the triangles if it lies close enough to the edge.
				for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++)
				{
					const float		triWx		= triNdx ? dstW - wx : wx;
					const float		triWy		= triNdx ? dstH - wy : wy;
					const float		triNx		= triNdx ? 1.0f - nx : nx;
					const float		triNy		= triNdx ? 1.0f - ny : ny;

					const tcu::Vec4	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy),
												 projectedTriInterpolate(triQ[triNdx], triW[triNdx], triNx, triNy));
					const tcu::Vec3	coordDx		(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
												 triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
												 triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
					const tcu::Vec3	coordDy		(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
												 triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
												 triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));

					tcu::Vec2		lodBounds	= tcu::computeCubeLodBoundsFromDerivates(coord.toWidth<3>(), coordDx, coordDy, srcSize, lodPrec);

					// Compute lod bounds across lodOffsets range.
					for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
					{
						const float		wxo			= triWx + lodOffsets[lodOffsNdx].x();
						const float		wyo			= triWy + lodOffsets[lodOffsNdx].y();
						const float		nxo			= wxo/dstW;
						const float		nyo			= wyo/dstH;

						const tcu::Vec3	coordO		(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
													 projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
													 projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
						const tcu::Vec3	coordDxo	(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
													 triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
													 triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
						const tcu::Vec3	coordDyo	(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
													 triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
													 triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
						const tcu::Vec2	lodO		= tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);

						lodBounds.x() = de::min(lodBounds.x(), lodO.x());
						lodBounds.y() = de::max(lodBounds.y(), lodO.y());
					}

					const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);

					if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coordBits, coord, clampedLod, resPix))
					{
						isOk = true;
						break;
					}
				}

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

bool verifyTextureResult (tcu::TestContext&						testCtx,
						  const tcu::ConstPixelBufferAccess&	result,
						  const tcu::TextureCubeArrayView&		src,
						  const float*							texCoord,
						  const ReferenceParams&				sampleParams,
						  const tcu::LookupPrecision&			lookupPrec,
						  const tcu::IVec4&						coordBits,
						  const tcu::LodPrecision&				lodPrec,
						  const tcu::PixelFormat&				pixelFormat)
{
	tcu::TestLog&	log				= testCtx.getLog();
	tcu::Surface	reference		(result.getWidth(), result.getHeight());
	tcu::Surface	errorMask		(result.getWidth(), result.getHeight());
	int				numFailedPixels;

	DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);

	sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
	numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, coordBits, lodPrec, testCtx.getWatchDog());

	if (numFailedPixels > 0)
		log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;

	log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
		<< tcu::TestLog::Image("Rendered", "Rendered image", result);

	if (numFailedPixels > 0)
	{
		log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}

	log << tcu::TestLog::EndImageSet;

	return numFailedPixels == 0;
}

// Shadow lookup verification

int computeTextureCompareDiff (const tcu::ConstPixelBufferAccess&	result,
							   const tcu::ConstPixelBufferAccess&	reference,
							   const tcu::PixelBufferAccess&		errorMask,
							   const tcu::Texture2DView&			src,
							   const float*							texCoord,
							   const ReferenceParams&				sampleParams,
							   const tcu::TexComparePrecision&		comparePrec,
							   const tcu::LodPrecision&				lodPrec,
							   const tcu::Vec3&						nonShadowThreshold)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	const tcu::Vec4		sq				= tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	const tcu::Vec4		tq				= tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	const tcu::IVec2	dstSize			= tcu::IVec2(result.getWidth(), result.getHeight());
	const float			dstW			= float(dstSize.x());
	const float			dstH			= float(dstSize.y());
	const tcu::IVec2	srcSize			= tcu::IVec2(src.getWidth(), src.getHeight());

	// Coordinates and lod per triangle.
	const tcu::Vec3		triS[2]			= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3		triT[2]			= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3		triW[2]			= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2		lodBias			((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	const float			minLod			= (sampleParams.imageViewMinLod != 0.0f) ? de::max(deFloatFloor(sampleParams.imageViewMinLod), sampleParams.minLod) : sampleParams.minLod;

	int					numFailed		= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= result.getPixel(px, py);
			const tcu::Vec4	refPix	= reference.getPixel(px, py);

			// Other channels should trivially match to reference.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
			{
				errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
				numFailed += 1;
				continue;
			}

			// Reference result is known to be a valid result, we can
			// skip verification if thes results are equal
			if (resPix.x() != refPix.x())
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec2	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
				const tcu::Vec2	coordDx		= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
														triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat();
				const tcu::Vec2	coordDy		= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
														triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat();

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const tcu::Vec2	coordDxo	= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
															triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat();
					const tcu::Vec2	coordDyo	= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
															triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat();
					const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x());

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

int computeTextureCompareDiff (const tcu::ConstPixelBufferAccess&	result,
							   const tcu::ConstPixelBufferAccess&	reference,
							   const tcu::PixelBufferAccess&		errorMask,
							   const tcu::TextureCubeView&			src,
							   const float*							texCoord,
							   const ReferenceParams&				sampleParams,
							   const tcu::TexComparePrecision&		comparePrec,
							   const tcu::LodPrecision&				lodPrec,
							   const tcu::Vec3&						nonShadowThreshold)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	const tcu::Vec4		sq				= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4		tq				= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4		rq				= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	const tcu::IVec2	dstSize			= tcu::IVec2(result.getWidth(), result.getHeight());
	const float			dstW			= float(dstSize.x());
	const float			dstH			= float(dstSize.y());
	const int			srcSize			= src.getSize();

	// Coordinates per triangle.
	const tcu::Vec3		triS[2]			= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3		triT[2]			= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3		triR[2]			= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3		triW[2]			= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2		lodBias			((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	const float			minLod			= (sampleParams.imageViewMinLod != 0.0f) ? de::max(deFloatFloor(sampleParams.imageViewMinLod), sampleParams.minLod) : sampleParams.minLod;

	int					numFailed		= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= result.getPixel(px, py);
			const tcu::Vec4	refPix	= reference.getPixel(px, py);

			// Other channels should trivially match to reference.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
			{
				errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
				numFailed += 1;
				continue;
			}

			// Reference result is known to be a valid result, we can
			// skip verification if thes results are equal
			if (resPix.x() != refPix.x())
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec3	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
				const tcu::Vec3	coordDx		(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
											 triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
											 triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
				const tcu::Vec3	coordDy		(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
											 triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
											 triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));

				tcu::Vec2		lodBounds	= tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const tcu::Vec3	coordO		(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
												 projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
												 projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
					const tcu::Vec3	coordDxo	(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
												 triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
												 triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
					const tcu::Vec3	coordDyo	(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
												 triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
												 triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
					const tcu::Vec2	lodO		= tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x());

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

int computeTextureCompareDiff (const tcu::ConstPixelBufferAccess&	result,
							   const tcu::ConstPixelBufferAccess&	reference,
							   const tcu::PixelBufferAccess&		errorMask,
							   const tcu::Texture2DArrayView&		src,
							   const float*							texCoord,
							   const ReferenceParams&				sampleParams,
							   const tcu::TexComparePrecision&		comparePrec,
							   const tcu::LodPrecision&				lodPrec,
							   const tcu::Vec3&						nonShadowThreshold)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	const tcu::Vec4		sq				= tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]);
	const tcu::Vec4		tq				= tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]);
	const tcu::Vec4		rq				= tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]);

	const tcu::IVec2	dstSize			= tcu::IVec2(result.getWidth(), result.getHeight());
	const float			dstW			= float(dstSize.x());
	const float			dstH			= float(dstSize.y());
	const tcu::IVec2	srcSize			= tcu::IVec2(src.getWidth(), src.getHeight());

	// Coordinates and lod per triangle.
	const tcu::Vec3		triS[2]			= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3		triT[2]			= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3		triR[2]			= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3		triW[2]			= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2		lodBias			((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int					numFailed		= 0;

	const tcu::Vec2 lodOffsets[] =
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= result.getPixel(px, py);
			const tcu::Vec4	refPix	= reference.getPixel(px, py);

			// Other channels should trivially match to reference.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
			{
				errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
				numFailed += 1;
				continue;
			}

			// Reference result is known to be a valid result, we can
			// skip verification if thes results are equal
			if (resPix.x() != refPix.x())
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec3	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
				const tcu::Vec2	coordDx		= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
														triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat();
				const tcu::Vec2	coordDy		= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
														triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat();

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const tcu::Vec2	coordDxo	= tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
															triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat();
					const tcu::Vec2	coordDyo	= tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
															triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat();
					const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x());

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

int computeTextureCompareDiff (const tcu::ConstPixelBufferAccess&	result,
							   const tcu::ConstPixelBufferAccess&	reference,
							   const tcu::PixelBufferAccess&		errorMask,
							   const tcu::Texture1DView&			src,
							   const float*							texCoord,
							   const ReferenceParams&				sampleParams,
							   const tcu::TexComparePrecision&		comparePrec,
							   const tcu::LodPrecision&				lodPrec,
							   const tcu::Vec3&						nonShadowThreshold)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
	DE_ASSERT(result.getHeight() == 1);

	const tcu::Vec4		sq				= tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);

	const tcu::IVec2	dstSize			= tcu::IVec2(result.getWidth(), 1);
	const float			dstW			= float(dstSize.x());
	const float			dstH			= float(dstSize.y());
	const float			srcSize			= float(src.getWidth());

	// Coordinates and lod per triangle.
	const tcu::Vec3		triS[2]			= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3		triW[2]			= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2		lodBias			((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int					numFailed		= 0;

	const tcu::Vec2		lodOffsets[]	=
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	const int py = 0;
	{
		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= result.getPixel(px, py);
			const tcu::Vec4	refPix	= reference.getPixel(px, py);

			// Other channels should trivially match to reference.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
			{
				errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
				numFailed += 1;
				continue;
			}

			// Reference result is known to be a valid result, we can
			// skip verification if thes results are equal
			if (resPix.x() != refPix.x())
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const float		coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy));
				const float		coordDx		= triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize;

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx, coordDx, lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const float		coordDxo	= triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize;
					const float		coordDyo	= triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize;
					const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, tcu::Vec1(coord), clampedLod, sampleParams.ref, resPix.x());

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

int computeTextureCompareDiff (const tcu::ConstPixelBufferAccess&	result,
							   const tcu::ConstPixelBufferAccess&	reference,
							   const tcu::PixelBufferAccess&		errorMask,
							   const tcu::Texture1DArrayView&		src,
							   const float*							texCoord,
							   const ReferenceParams&				sampleParams,
							   const tcu::TexComparePrecision&		comparePrec,
							   const tcu::LodPrecision&				lodPrec,
							   const tcu::Vec3&						nonShadowThreshold)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
	DE_ASSERT(result.getHeight() == 1);

	const tcu::Vec4		sq				= tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]);
	const tcu::Vec4		tq				= tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]);

	const tcu::IVec2	dstSize			= tcu::IVec2(result.getWidth(), 1);
	const float			dstW			= float(dstSize.x());
	const float			dstH			= float(dstSize.y());
	const float			srcSize			= float(src.getWidth());

	// Coordinates and lod per triangle.
	const tcu::Vec3		triS[2]			= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3		triT[2]			= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3		triW[2]			= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2		lodBias			((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int					numFailed		= 0;

	const tcu::Vec2		lodOffsets[]	=
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	const int py = 0;
	{
		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= result.getPixel(px, py);
			const tcu::Vec4	refPix	= reference.getPixel(px, py);

			// Other channels should trivially match to reference.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
			{
				errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
				numFailed += 1;
				continue;
			}

			// Reference result is known to be a valid result, we can
			// skip verification if these results are equal
			if (resPix.x() != refPix.x())
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec2	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
				const float		coordDx		= triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize;

				tcu::Vec2		lodBounds	= tcu::computeLodBoundsFromDerivates(coordDx, coordDx, lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const float		coordDxo	= triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize;
					const float		coordDyo	= triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize;
					const tcu::Vec2	lodO		= tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x());

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

int computeTextureCompareDiff (const tcu::ConstPixelBufferAccess&	result,
							   const tcu::ConstPixelBufferAccess&	reference,
							   const tcu::PixelBufferAccess&		errorMask,
							   const tcu::TextureCubeArrayView&		src,
							   const float*							texCoord,
							   const ReferenceParams&				sampleParams,
							   const tcu::TexComparePrecision&		comparePrec,
							   const tcu::LodPrecision&				lodPrec,
							   const tcu::Vec3&						nonShadowThreshold)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
	DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());

	const tcu::Vec4		sq				= tcu::Vec4(texCoord[0+0], texCoord[4+0], texCoord[8+0], texCoord[12+0]);
	const tcu::Vec4		tq				= tcu::Vec4(texCoord[0+1], texCoord[4+1], texCoord[8+1], texCoord[12+1]);
	const tcu::Vec4		rq				= tcu::Vec4(texCoord[0+2], texCoord[4+2], texCoord[8+2], texCoord[12+2]);
	const tcu::Vec4		qq				= tcu::Vec4(texCoord[0+3], texCoord[4+3], texCoord[8+3], texCoord[12+3]);

	const tcu::IVec2	dstSize			= tcu::IVec2(result.getWidth(), result.getHeight());
	const float			dstW			= float(dstSize.x());
	const float			dstH			= float(dstSize.y());
	const int			srcSize			= src.getSize();

	// Coordinates per triangle.
	const tcu::Vec3		triS[2]			= { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) };
	const tcu::Vec3		triT[2]			= { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) };
	const tcu::Vec3		triR[2]			= { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) };
	const tcu::Vec3		triQ[2]			= { qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1) };
	const tcu::Vec3		triW[2]			= { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) };

	const tcu::Vec2		lodBias			((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);

	int					numFailed		= 0;

	const tcu::Vec2		lodOffsets[]	=
	{
		tcu::Vec2(-1,  0),
		tcu::Vec2(+1,  0),
		tcu::Vec2( 0, -1),
		tcu::Vec2( 0, +1),
	};

	tcu::clear(errorMask, tcu::RGBA::green().toVec());

	for (int py = 0; py < result.getHeight(); py++)
	{
		for (int px = 0; px < result.getWidth(); px++)
		{
			const tcu::Vec4	resPix	= result.getPixel(px, py);
			const tcu::Vec4	refPix	= reference.getPixel(px, py);

			// Other channels should trivially match to reference.
			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
			{
				errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
				numFailed += 1;
				continue;
			}

			// Reference result is known to be a valid result, we can
			// skip verification if thes results are equal
			if (resPix.x() != refPix.x())
			{
				const float		wx		= (float)px + 0.5f;
				const float		wy		= (float)py + 0.5f;
				const float		nx		= wx / dstW;
				const float		ny		= wy / dstH;

				const int		triNdx	= nx + ny >= 1.0f ? 1 : 0;
				const float		triWx	= triNdx ? dstW - wx : wx;
				const float		triWy	= triNdx ? dstH - wy : wy;
				const float		triNx	= triNdx ? 1.0f - nx : nx;
				const float		triNy	= triNdx ? 1.0f - ny : ny;

				const tcu::Vec4	coord		(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy),
											 projectedTriInterpolate(triQ[triNdx], triW[triNdx], triNx, triNy));
				const tcu::Vec3	coordDx		(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
											 triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
											 triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
				const tcu::Vec3	coordDy		(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
											 triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
											 triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));

				tcu::Vec2		lodBounds	= tcu::computeCubeLodBoundsFromDerivates(coord.swizzle(0,1,2), coordDx, coordDy, srcSize, lodPrec);

				// Compute lod bounds across lodOffsets range.
				for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
				{
					const float		wxo		= triWx + lodOffsets[lodOffsNdx].x();
					const float		wyo		= triWy + lodOffsets[lodOffsNdx].y();
					const float		nxo		= wxo/dstW;
					const float		nyo		= wyo/dstH;

					const tcu::Vec3	coordO		(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
												 projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
												 projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
					const tcu::Vec3	coordDxo	(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
												 triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
												 triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
					const tcu::Vec3	coordDyo	(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
												 triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
												 triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
					const tcu::Vec2	lodO		= tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);

					lodBounds.x() = de::min(lodBounds.x(), lodO.x());
					lodBounds.y() = de::max(lodBounds.y(), lodO.y());
				}

				const tcu::Vec2	clampedLod	= tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
				const bool		isOk		= tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x());

				if (!isOk)
				{
					errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
					numFailed += 1;
				}
			}
		}
	}

	return numFailed;
}

// Mipmap generation comparison.

static int compareGenMipmapBilinear (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision)
{
	DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures.

	const float		dstW		= float(dst.getWidth());
	const float		dstH		= float(dst.getHeight());
	const float		srcW		= float(src.getWidth());
	const float		srcH		= float(src.getHeight());
	int				numFailed	= 0;

	// Translation to lookup verification parameters.
	const tcu::Sampler		sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
										 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */);
	tcu::LookupPrecision	lookupPrec;

	lookupPrec.colorThreshold	= precision.colorThreshold;
	lookupPrec.colorMask		= precision.colorMask;
	lookupPrec.coordBits		= tcu::IVec3(22);
	lookupPrec.uvwBits			= precision.filterBits;

	for (int y = 0; y < dst.getHeight(); y++)
	for (int x = 0; x < dst.getWidth(); x++)
	{
		const tcu::Vec4	result	= dst.getPixel(x, y);
		const float		cx		= (float(x)+0.5f) / dstW * srcW;
		const float		cy		= (float(y)+0.5f) / dstH * srcH;
		const bool		isOk	= tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result);

		errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y);
		if (!isOk)
			numFailed += 1;
	}

	return numFailed;
}

static int compareGenMipmapBox (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision)
{
	DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures.

	const float		dstW		= float(dst.getWidth());
	const float		dstH		= float(dst.getHeight());
	const float		srcW		= float(src.getWidth());
	const float		srcH		= float(src.getHeight());
	int				numFailed	= 0;

	// Translation to lookup verification parameters.
	const tcu::Sampler		sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
										 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */);
	tcu::LookupPrecision	lookupPrec;

	lookupPrec.colorThreshold	= precision.colorThreshold;
	lookupPrec.colorMask		= precision.colorMask;
	lookupPrec.coordBits		= tcu::IVec3(22);
	lookupPrec.uvwBits			= precision.filterBits;

	for (int y = 0; y < dst.getHeight(); y++)
	for (int x = 0; x < dst.getWidth(); x++)
	{
		const tcu::Vec4	result	= dst.getPixel(x, y);
		const float		cx		= deFloatFloor(float(x) / dstW * srcW) + 1.0f;
		const float		cy		= deFloatFloor(float(y) / dstH * srcH) + 1.0f;
		const bool		isOk	= tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result);

		errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y);
		if (!isOk)
			numFailed += 1;
	}

	return numFailed;
}

static int compareGenMipmapVeryLenient (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision)
{
	DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures.
	DE_UNREF(precision);

	const float		dstW		= float(dst.getWidth());
	const float		dstH		= float(dst.getHeight());
	const float		srcW		= float(src.getWidth());
	const float		srcH		= float(src.getHeight());
	int				numFailed	= 0;

	for (int y = 0; y < dst.getHeight(); y++)
	for (int x = 0; x < dst.getWidth(); x++)
	{
		const tcu::Vec4	result	= dst.getPixel(x, y);
		const int		minX		= deFloorFloatToInt32(((float)x-0.5f) / dstW * srcW);
		const int		minY		= deFloorFloatToInt32(((float)y-0.5f) / dstH * srcH);
		const int		maxX		= deCeilFloatToInt32(((float)x+1.5f) / dstW * srcW);
		const int		maxY		= deCeilFloatToInt32(((float)y+1.5f) / dstH * srcH);
		tcu::Vec4		minVal, maxVal;
		bool			isOk;

		DE_ASSERT(minX < maxX && minY < maxY);

		for (int ky = minY; ky <= maxY; ky++)
		{
			for (int kx = minX; kx <= maxX; kx++)
			{
				const int		sx		= de::clamp(kx, 0, src.getWidth()-1);
				const int		sy		= de::clamp(ky, 0, src.getHeight()-1);
				const tcu::Vec4	sample	= src.getPixel(sx, sy);

				if (ky == minY && kx == minX)
				{
					minVal = sample;
					maxVal = sample;
				}
				else
				{
					minVal = min(sample, minVal);
					maxVal = max(sample, maxVal);
				}
			}
		}

		isOk = boolAll(logicalAnd(lessThanEqual(minVal, result), lessThanEqual(result, maxVal)));

		errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y);
		if (!isOk)
			numFailed += 1;
	}

	return numFailed;
}

qpTestResult compareGenMipmapResult (tcu::TestLog& log, const tcu::Texture2D& resultTexture, const tcu::Texture2D& level0Reference, const GenMipmapPrecision& precision)
{
	qpTestResult result = QP_TEST_RESULT_PASS;

	// Special comparison for level 0.
	{
		const tcu::Vec4		threshold	= select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask);
		const bool			level0Ok	= tcu::floatThresholdCompare(log, "Level0", "Level 0", level0Reference.getLevel(0), resultTexture.getLevel(0), threshold, tcu::COMPARE_LOG_RESULT);

		if (!level0Ok)
		{
			log << tcu::TestLog::Message << "ERROR: Level 0 comparison failed!" << tcu::TestLog::EndMessage;
			result = QP_TEST_RESULT_FAIL;
		}
	}

	for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++)
	{
		const tcu::ConstPixelBufferAccess	src			= resultTexture.getLevel(levelNdx-1);
		const tcu::ConstPixelBufferAccess	dst			= resultTexture.getLevel(levelNdx);
		tcu::Surface						errorMask	(dst.getWidth(), dst.getHeight());
		bool								levelOk		= false;

		// Try different comparisons in quality order.

		if (!levelOk)
		{
			const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision);
			if (numFailed == 0)
				levelOk = true;
			else
				log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << " comparison to bilinear method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage;
		}

		if (!levelOk)
		{
			const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision);
			if (numFailed == 0)
				levelOk = true;
			else
				log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << " comparison to box method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage;
		}

		// At this point all high-quality methods have been used.
		if (!levelOk && result == QP_TEST_RESULT_PASS)
			result = QP_TEST_RESULT_QUALITY_WARNING;

		if (!levelOk)
		{
			const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision);
			if (numFailed == 0)
				levelOk = true;
			else
				log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << " appears to contain " << numFailed << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage;
		}

		if (!levelOk)
			result = QP_TEST_RESULT_FAIL;

		log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx), string("Level ") + de::toString(levelNdx) + " result")
			<< tcu::TestLog::Image("Result", "Result", dst);

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

		log << tcu::TestLog::EndImageSet;
	}

	return result;
}

qpTestResult compareGenMipmapResult (tcu::TestLog& log, const tcu::TextureCube& resultTexture, const tcu::TextureCube& level0Reference, const GenMipmapPrecision& precision)
{
	qpTestResult result = QP_TEST_RESULT_PASS;

	static const char* s_faceNames[] = { "-X", "+X", "-Y", "+Y", "-Z", "+Z" };
	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_faceNames) == tcu::CUBEFACE_LAST);

	// Special comparison for level 0.
	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
	{
		const tcu::CubeFace	face		= tcu::CubeFace(faceNdx);
		const tcu::Vec4		threshold	= select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask);
		const bool			level0Ok	= tcu::floatThresholdCompare(log,
																	 ("Level0Face" + de::toString(faceNdx)).c_str(),
																	 (string("Level 0, face ") + s_faceNames[face]).c_str(),
																	 level0Reference.getLevelFace(0, face),
																	 resultTexture.getLevelFace(0, face),
																	 threshold, tcu::COMPARE_LOG_RESULT);

		if (!level0Ok)
		{
			log << tcu::TestLog::Message << "ERROR: Level 0, face " << s_faceNames[face] << " comparison failed!" << tcu::TestLog::EndMessage;
			result = QP_TEST_RESULT_FAIL;
		}
	}

	for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++)
	{
		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
		{
			const tcu::CubeFace					face		= tcu::CubeFace(faceNdx);
			const char*							faceName	= s_faceNames[face];
			const tcu::ConstPixelBufferAccess	src			= resultTexture.getLevelFace(levelNdx-1,	face);
			const tcu::ConstPixelBufferAccess	dst			= resultTexture.getLevelFace(levelNdx,		face);
			tcu::Surface						errorMask	(dst.getWidth(), dst.getHeight());
			bool								levelOk		= false;

			// Try different comparisons in quality order.

			if (!levelOk)
			{
				const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision);
				if (numFailed == 0)
					levelOk = true;
				else
					log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName << " comparison to bilinear method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage;
			}

			if (!levelOk)
			{
				const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision);
				if (numFailed == 0)
					levelOk = true;
				else
					log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName <<" comparison to box method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage;
			}

			// At this point all high-quality methods have been used.
			if (!levelOk && result == QP_TEST_RESULT_PASS)
				result = QP_TEST_RESULT_QUALITY_WARNING;

			if (!levelOk)
			{
				const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision);
				if (numFailed == 0)
					levelOk = true;
				else
					log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << ", face " << faceName << " appears to contain " << numFailed << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage;
			}

			if (!levelOk)
				result = QP_TEST_RESULT_FAIL;

			log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx) + "Face" + de::toString(faceNdx), string("Level ") + de::toString(levelNdx) + ", face " + string(faceName) + " result")
				<< tcu::TestLog::Image("Result", "Result", dst);

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

			log << tcu::TestLog::EndImageSet;
		}
	}

	return result;
}

// Logging utilities.

std::ostream& operator<< (std::ostream& str, const LogGradientFmt& fmt)
{
	return str << "(R: " << fmt.valueMin->x() << " -> " << fmt.valueMax->x() << ", "
			   <<  "G: " << fmt.valueMin->y() << " -> " << fmt.valueMax->y() << ", "
			   <<  "B: " << fmt.valueMin->z() << " -> " << fmt.valueMax->z() << ", "
			   <<  "A: " << fmt.valueMin->w() << " -> " << fmt.valueMax->w() << ")";
}

} // TextureTestUtil
} // glu
