/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 * 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 Mipmapping tests.
 *//*--------------------------------------------------------------------*/

#include "vktTextureMipmapTests.hpp"

#include "deRandom.hpp"
#include "deString.h"
#include "gluShaderUtil.hpp"
#include "gluTextureTestUtil.hpp"
#include "tcuMatrix.hpp"
#include "tcuMatrixUtil.hpp"
#include "tcuPixelFormat.hpp"
#include "tcuTexLookupVerifier.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "vkImageUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTextureTestUtil.hpp"

using namespace vk;

namespace vkt
{
namespace texture
{
namespace
{

using std::string;
using std::vector;
using tcu::TestLog;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec3;
using tcu::IVec4;
using tcu::Sampler;
using tcu::TextureFormat;
using namespace texture::util;
using namespace glu::TextureTestUtil;

float getMinLodForCell (int cellNdx)
{
	static const float s_values[] =
	{
		1.0f,
		3.5f,
		2.0f,
		-2.0f,
		0.0f,
		3.0f,
		10.0f,
		4.8f,
		5.8f,
		5.7f,
		-1.9f,
		4.0f,
		6.5f,
		7.1f,
		-1e10,
		1000.f
	};
	return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
}

float getMaxLodForCell (int cellNdx)
{
	static const float s_values[] =
	{
		0.0f,
		0.2f,
		0.7f,
		0.4f,
		1.3f,
		0.0f,
		0.5f,
		1.2f,
		-2.0f,
		1.0f,
		0.1f,
		0.3f,
		2.7f,
		1.2f,
		10.0f,
		-1000.f,
		1e10f
	};
	return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
}

enum CoordType
{
	COORDTYPE_BASIC,		//!< texCoord = translateScale(position).
	COORDTYPE_BASIC_BIAS,	//!< Like basic, but with bias values.
	COORDTYPE_AFFINE,		//!< texCoord = translateScaleRotateShear(position).
	COORDTYPE_PROJECTED,	//!< Projected coordinates, w != 1

	COORDTYPE_LAST
};

struct TextureMipmapCommonTestCaseParameters
{
							TextureMipmapCommonTestCaseParameters		(void);
	CoordType				coordType;
	const char*				minFilterName;
};

TextureMipmapCommonTestCaseParameters::TextureMipmapCommonTestCaseParameters (void)
	: coordType						(COORDTYPE_BASIC)
	, minFilterName					(NULL)
{
}

struct Texture2DMipmapTestCaseParameters : public Texture2DTestCaseParameters, public TextureMipmapCommonTestCaseParameters
{
};

struct TextureCubeMipmapTestCaseParameters : public TextureCubeTestCaseParameters, public TextureMipmapCommonTestCaseParameters
{
};

struct Texture3DMipmapTestCaseParameters : public Texture3DTestCaseParameters, public TextureMipmapCommonTestCaseParameters
{
};

// Texture2DMipmapTestInstance
class Texture2DMipmapTestInstance : public TestInstance
{
public:
	typedef Texture2DMipmapTestCaseParameters	ParameterType;

									Texture2DMipmapTestInstance		(Context& context, const ParameterType& testParameters);
									~Texture2DMipmapTestInstance	(void);

	virtual tcu::TestStatus			iterate							(void);

private:
									Texture2DMipmapTestInstance		(const Texture2DMipmapTestInstance& other);
	Texture2DMipmapTestInstance&	operator=						(const Texture2DMipmapTestInstance& other);

	const ParameterType				m_testParameters;
	TestTexture2DSp					m_texture;
	TextureRenderer					m_renderer;
};

Texture2DMipmapTestInstance::Texture2DMipmapTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
	: TestInstance		(context)
	, m_testParameters	(testParameters)
	, m_renderer		(context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4)
{
	TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));

	m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height));

	const int numLevels = deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1;

	// Fill texture with colored grid.
	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		const deUint32	step	= 0xff / (numLevels-1);
		const deUint32	inc		= deClamp32(step*levelNdx, 0x00, 0xff);
		const deUint32	dec		= 0xff - inc;
		const deUint32	rgb		= (inc << 16) | (dec << 8) | 0xff;
		const deUint32	color	= 0xff000000 | rgb;

		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
	}

	// Upload texture data.
	m_renderer.add2DTexture(m_texture, testParameters.aspectMask);
}

Texture2DMipmapTestInstance::~Texture2DMipmapTestInstance (void)
{
}

static void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx)
{
	static const struct
	{
		const Vec2	bottomLeft;
		const Vec2	topRight;
	} s_basicCoords[] =
	{
		{ Vec2(-0.1f,  0.1f), Vec2( 0.8f,  1.0f) },
		{ Vec2(-0.3f, -0.6f), Vec2( 0.7f,  0.4f) },
		{ Vec2(-0.3f,  0.6f), Vec2( 0.7f, -0.9f) },
		{ Vec2(-0.8f,  0.6f), Vec2( 0.7f, -0.9f) },

		{ Vec2(-0.5f, -0.5f), Vec2( 1.5f,  1.5f) },
		{ Vec2( 1.0f, -1.0f), Vec2(-1.3f,  1.0f) },
		{ Vec2( 1.2f, -1.0f), Vec2(-1.3f,  1.6f) },
		{ Vec2( 2.2f, -1.1f), Vec2(-1.3f,  0.8f) },

		{ Vec2(-1.5f,  1.6f), Vec2( 1.7f, -1.4f) },
		{ Vec2( 2.0f,  1.6f), Vec2( 2.3f, -1.4f) },
		{ Vec2( 1.3f, -2.6f), Vec2(-2.7f,  2.9f) },
		{ Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) },

		{ Vec2( -8.0f,   9.0f), Vec2(  8.3f,  -7.0f) },
		{ Vec2(-16.0f,  10.0f), Vec2( 18.3f,  24.0f) },
		{ Vec2( 30.2f,  55.0f), Vec2(-24.3f,  -1.6f) },
		{ Vec2(-33.2f,  64.1f), Vec2( 32.1f, -64.1f) },
	};

	DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));

	const Vec2& bottomLeft	= s_basicCoords[cellNdx].bottomLeft;
	const Vec2& topRight	= s_basicCoords[cellNdx].topRight;

	computeQuadTexCoord2D(dst, bottomLeft, topRight);
}

static void getBasicTexCoord2DImageViewMinLodIntTexCoord (std::vector<float>& dst)
{
	computeQuadTexCoord2D(dst, Vec2(0.0f), Vec2(1.0f));
}

static void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx)
{
	// Use basic coords as base.
	getBasicTexCoord2D(dst, cellNdx);

	// Rotate based on cell index.
	const float		angle		= 2.0f*DE_PI * ((float)cellNdx / 16.0f);
	const tcu::Mat2	rotMatrix	= tcu::rotationMatrix(angle);

	// Second and third row are sheared.
	const float		shearX		= de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f;
	const tcu::Mat2	shearMatrix	= tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));

	const tcu::Mat2	transform	= rotMatrix * shearMatrix;
	const Vec2		p0			= transform * Vec2(dst[0], dst[1]);
	const Vec2		p1			= transform * Vec2(dst[2], dst[3]);
	const Vec2		p2			= transform * Vec2(dst[4], dst[5]);
	const Vec2		p3			= transform * Vec2(dst[6], dst[7]);

	dst[0] = p0.x();	dst[1] = p0.y();
	dst[2] = p1.x();	dst[3] = p1.y();
	dst[4] = p2.x();	dst[5] = p2.y();
	dst[6] = p3.x();	dst[7] = p3.y();
}

tcu::TestStatus Texture2DMipmapTestInstance::iterate (void)
{
	const Sampler::FilterMode	magFilter		= Sampler::NEAREST;
	const int					viewportWidth	= m_renderer.getRenderWidth();
	const int					viewportHeight	= m_renderer.getRenderHeight();

	ReferenceParams				refParams		(TEXTURETYPE_2D);
	vector<float>				texCoord;

	const bool					isProjected		= m_testParameters.coordType == COORDTYPE_PROJECTED;
	const bool					useLodBias		= m_testParameters.coordType == COORDTYPE_BASIC_BIAS;

	tcu::Surface				renderedFrame	(viewportWidth, viewportHeight);

	// Viewport is divided into 4x4 grid.
	const int					gridWidth		= 4;
	const int					gridHeight		= 4;
	const int					cellWidth		= viewportWidth / gridWidth;
	const int					cellHeight		= viewportHeight / gridHeight;

	// Sampling parameters.
	refParams.sampler		= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter);
	refParams.samplerType	= getSamplerType(vk::mapVkFormat(m_testParameters.format));
	refParams.flags			= (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
	refParams.lodMode		= LODMODE_EXACT; // Use ideal lod.

	// Bias values.
	static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };

	// Projection values.
	static const Vec4 s_projections[] =
	{
		Vec4(1.2f, 1.0f, 0.7f, 1.0f),
		Vec4(1.3f, 0.8f, 0.6f, 2.0f),
		Vec4(0.8f, 1.0f, 1.7f, 0.6f),
		Vec4(1.2f, 1.0f, 1.7f, 1.5f)
	};

	// Render cells.
	for (int gridY = 0; gridY < gridHeight; gridY++)
	{
		for (int gridX = 0; gridX < gridWidth; gridX++)
		{
			const int	curX		= cellWidth*gridX;
			const int	curY		= cellHeight*gridY;
			const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
			const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
			const int	cellNdx		= gridY*gridWidth + gridX;

			// Compute texcoord.
			switch (m_testParameters.coordType)
			{
				case COORDTYPE_BASIC_BIAS:	// Fall-through.
				case COORDTYPE_PROJECTED:
				case COORDTYPE_BASIC:		getBasicTexCoord2D	(texCoord, cellNdx);	break;
				case COORDTYPE_AFFINE:		getAffineTexCoord2D	(texCoord, cellNdx);	break;
				default:					DE_ASSERT(DE_FALSE);
			}

			if (isProjected)
				refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];

			if (useLodBias)
				refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];

			m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
			m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
		}
	}

	// Compare and log.
	{
		const tcu::IVec4		formatBitDepth	= getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		const tcu::PixelFormat	pixelFormat		(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
		const bool				isTrilinear		= m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
		tcu::Surface			referenceFrame	(viewportWidth, viewportHeight);
		tcu::Surface			errorMask		(viewportWidth, viewportHeight);
		tcu::LookupPrecision	lookupPrec;
		tcu::LodPrecision		lodPrec;
		int						numFailedPixels	= 0;

		lookupPrec.coordBits		= tcu::IVec3(20, 20, 0);
		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
		lookupPrec.colorMask		= getCompareMask(pixelFormat);
		lodPrec.derivateBits		= 10;
		lodPrec.lodBits				= isProjected ? 6 : 8;

		for (int gridY = 0; gridY < gridHeight; gridY++)
		{
			for (int gridX = 0; gridX < gridWidth; gridX++)
			{
				const int	curX		= cellWidth*gridX;
				const int	curY		= cellHeight*gridY;
				const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
				const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
				const int	cellNdx		= gridY*gridWidth + gridX;

				// Compute texcoord.
				switch (m_testParameters.coordType)
				{
					case COORDTYPE_BASIC_BIAS:	// Fall-through.
					case COORDTYPE_PROJECTED:
					case COORDTYPE_BASIC:		getBasicTexCoord2D	(texCoord, cellNdx);	break;
					case COORDTYPE_AFFINE:		getAffineTexCoord2D	(texCoord, cellNdx);	break;
					default:					DE_ASSERT(DE_FALSE);
				}

				if (isProjected)
					refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];

				if (useLodBias)
					refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];

				// Render ideal result
				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
							  m_texture->getTexture(), &texCoord[0], refParams);

				// Compare this cell
				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
															m_texture->getTexture(), &texCoord[0], refParams,
															lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
			}
		}

		if (numFailedPixels > 0)
			m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;

		m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
											<< TestLog::Image("Rendered", "Rendered image", renderedFrame);

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
												<< TestLog::Image("ErrorMask", "Error mask", errorMask);
		}

		m_context.getTestContext().getLog() << TestLog::EndImageSet;

		{
			const bool isOk = numFailedPixels == 0;
			return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
		}
	}
}

// TextureCubeMipmapTestInstance
class TextureCubeMipmapTestInstance : public TestInstance
{
public:
	typedef	TextureCubeMipmapTestCaseParameters	ParameterType;

									TextureCubeMipmapTestInstance	(Context& context, const ParameterType& testParameters);
									~TextureCubeMipmapTestInstance	(void);

	virtual tcu::TestStatus			iterate							(void);

private:
									TextureCubeMipmapTestInstance	(const TextureCubeMipmapTestInstance& other);
	TextureCubeMipmapTestInstance&	operator=						(const TextureCubeMipmapTestInstance& other);

	const ParameterType				m_testParameters;
	TestTextureCubeSp				m_texture;
	TextureRenderer					m_renderer;
};

TextureCubeMipmapTestInstance::TextureCubeMipmapTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
	: TestInstance		(context)
	, m_testParameters	(testParameters)
	, m_renderer		(context, m_testParameters.sampleCount, m_testParameters.size*2, m_testParameters.size*2)
{
	TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));

	m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size));

	const int numLevels = deLog2Floor32(m_testParameters.size)+1;

	// Fill texture with colored grid.
	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
	{
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			const deUint32	step	= 0xff / (numLevels-1);
			const deUint32	inc		= deClamp32(step*levelNdx, 0x00, 0xff);
			const deUint32	dec		= 0xff - inc;
			deUint32		rgb		= 0;

			switch (faceNdx)
			{
				case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
				case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
				case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
				case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
				case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
				case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
			}

			const deUint32	color	= 0xff000000 | rgb;
			tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
		}
	}

	m_renderer.addCubeTexture(m_texture, testParameters.aspectMask);
}

TextureCubeMipmapTestInstance::~TextureCubeMipmapTestInstance (void)
{
}

static void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height)
{
	const int	minWidth	= 8;
	const int	minHeight	= 8;

	const bool	partition	= rnd.getFloat() > 0.4f;
	const bool	partitionX	= partition && width > minWidth && rnd.getBool();
	const bool	partitionY	= partition && height > minHeight && !partitionX;

	if (partitionX)
	{
		const int split = width/2 + rnd.getInt(-width/4, +width/4);
		randomPartition(dst, rnd, x, y, split, height);
		randomPartition(dst, rnd, x+split, y, width-split, height);
	}
	else if (partitionY)
	{
		const int split = height/2 + rnd.getInt(-height/4, +height/4);
		randomPartition(dst, rnd, x, y, width, split);
		randomPartition(dst, rnd, x, y+split, width, height-split);
	}
	else
		dst.push_back(IVec4(x, y, width, height));
}

static void computeGridLayout (vector<IVec4>& dst, int width, int height)
{
	de::Random rnd(7);
	randomPartition(dst, rnd, 0, 0, width, height);
}

tcu::TestStatus TextureCubeMipmapTestInstance::iterate (void)
{
	const int			viewportWidth	= m_renderer.getRenderWidth();
	const int			viewportHeight	= m_renderer.getRenderHeight();

	const bool			isProjected		= m_testParameters.coordType == COORDTYPE_PROJECTED;
	const bool			useLodBias		= m_testParameters.coordType == COORDTYPE_BASIC_BIAS;

	ReferenceParams		refParams		(TEXTURETYPE_CUBE);
	vector<float>		texCoord;
	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);

	refParams.sampler		= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
	refParams.samplerType	= getSamplerType(vk::mapVkFormat(m_testParameters.format));
	refParams.flags			= (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
	refParams.lodMode		= LODMODE_EXACT; // Use ideal lod.

	// Compute grid.
	vector<IVec4> gridLayout;
	computeGridLayout(gridLayout, viewportWidth, viewportHeight);

	// Bias values.
	static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };

	// Projection values \note Less agressive than in 2D case due to smaller quads.
	static const Vec4 s_projections[] =
	{
		Vec4(1.2f, 1.0f, 0.7f, 1.0f),
		Vec4(1.3f, 0.8f, 0.6f, 1.1f),
		Vec4(0.8f, 1.0f, 1.2f, 0.8f),
		Vec4(1.2f, 1.0f, 1.3f, 0.9f)
	};

	// Render with GL
	for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
	{
		const float			curX		= (float)gridLayout[cellNdx].x();
		const float			curY		= (float)gridLayout[cellNdx].y();
		const float			curW		= (float)gridLayout[cellNdx].z();
		const float			curH		= (float)gridLayout[cellNdx].w();
		const tcu::CubeFace	cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);

		DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported.
		computeQuadTexCoordCube(texCoord, cubeFace);

		if (isProjected)
		{
			refParams.flags	|= ReferenceParams::PROJECTED;
			refParams.w		 = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
		}

		if (useLodBias)
		{
			refParams.flags	|= ReferenceParams::USE_BIAS;
			refParams.bias	 = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
		}

		// Render
		m_renderer.setViewport(curX, curY, curW, curH);
		m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
	}

	// Render reference and compare
	{
		const tcu::IVec4		formatBitDepth		= getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		const tcu::PixelFormat	pixelFormat			(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
		tcu::Surface			referenceFrame		(viewportWidth, viewportHeight);
		tcu::Surface			errorMask			(viewportWidth, viewportHeight);
		int						numFailedPixels		= 0;
		tcu::LookupPrecision	lookupPrec;
		tcu::LodPrecision		lodPrec;

		// Params for rendering reference
		refParams.sampler					= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
		refParams.sampler.seamlessCubeMap	= true;
		refParams.lodMode					= LODMODE_EXACT;

		// Comparison parameters
		lookupPrec.colorMask		= getCompareMask(pixelFormat);
		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, tcu::IVec4(0)));
		lookupPrec.coordBits		= isProjected ? tcu::IVec3(8) : tcu::IVec3(10);
		lookupPrec.uvwBits			= tcu::IVec3(5,5,0);
		lodPrec.derivateBits		= 10;
		lodPrec.lodBits				= isProjected ? 3 : 6;

		for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
		{
			const int				curX		= gridLayout[cellNdx].x();
			const int				curY		= gridLayout[cellNdx].y();
			const int				curW		= gridLayout[cellNdx].z();
			const int				curH		= gridLayout[cellNdx].w();
			const tcu::CubeFace		cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);

			DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported.
			computeQuadTexCoordCube(texCoord, cubeFace);

			if (isProjected)
			{
				refParams.flags	|= ReferenceParams::PROJECTED;
				refParams.w		 = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
			}

			if (useLodBias)
			{
				refParams.flags	|= ReferenceParams::USE_BIAS;
				refParams.bias	 = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
			}

			// Render ideal reference.
			{
				tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH);
				sampleTexture(idealDst, m_texture->getTexture(), &texCoord[0], refParams);
			}

			// Compare this cell
			numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
														tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
														tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
														m_texture->getTexture(), &texCoord[0], refParams,
														lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
		}

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
		}

		m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
											<< TestLog::Image("Rendered", "Rendered image", renderedFrame);

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
												<< TestLog::Image("ErrorMask", "Error mask", errorMask);
		}

		m_context.getTestContext().getLog() << TestLog::EndImageSet;

		{
			const bool isOk = numFailedPixels == 0;
			return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
		}
	}
}

// Texture3DMipmapTestInstance
class Texture3DMipmapTestInstance : public TestInstance
{
public:
	typedef Texture3DMipmapTestCaseParameters	ParameterType;

									Texture3DMipmapTestInstance		(Context& context, const ParameterType& testParameters);
									~Texture3DMipmapTestInstance	(void);

	virtual tcu::TestStatus			iterate							(void);

private:
									Texture3DMipmapTestInstance		(const Texture3DMipmapTestInstance& other);
	Texture3DMipmapTestInstance&	operator=						(const Texture3DMipmapTestInstance& other);

	const ParameterType				m_testParameters;
	TestTexture3DSp					m_texture;
	TextureRenderer					m_renderer;
};

Texture3DMipmapTestInstance::Texture3DMipmapTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
	: TestInstance		(context)
	, m_testParameters	(testParameters)
	, m_renderer		(context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4)
{
	TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));

	const tcu::TextureFormat&	texFmt		= mapVkFormat(testParameters.format);
	tcu::TextureFormatInfo		fmtInfo		= tcu::getTextureFormatInfo(texFmt);
	const tcu::Vec4&			cScale		= fmtInfo.lookupScale;
	const tcu::Vec4&			cBias		= fmtInfo.lookupBias;
	const int					numLevels	= deLog2Floor32(de::max(de::max(testParameters.width, testParameters.height), testParameters.depth))+1;

	m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.depth));

	// Fill texture with colored grid.
	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		const deUint32	step	= 0xff / (numLevels-1);
		const deUint32	inc		= deClamp32(step*levelNdx, 0x00, 0xff);
		const deUint32	dec		= 0xff - inc;
		const deUint32	rgb		= (0xff << 16) | (dec << 8) | inc;
		const deUint32	color	= 0xff000000 | rgb;

		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
	}

	m_renderer.add3DTexture(m_texture, testParameters.aspectMask);
}

Texture3DMipmapTestInstance::~Texture3DMipmapTestInstance (void)
{
}

static void getBasicTexCoord3D (std::vector<float>& dst, int cellNdx)
{
	static const struct
	{
		const float sScale;
		const float sBias;
		const float tScale;
		const float tBias;
		const float rScale;
		const float rBias;
	} s_params[] =
	{
	//		sScale	sBias	tScale	tBias	rScale	rBias
		{	 0.9f,	-0.1f,	 0.7f,	 0.3f,	 0.8f,	 0.9f	},
		{	 1.2f,	-0.1f,	 1.1f,	 0.3f,	 1.0f,	 0.9f	},
		{	 1.5f,	 0.7f,	 0.9f,	-0.3f,	 1.1f,	 0.1f	},
		{	 1.2f,	 0.7f,	-2.3f,	-0.3f,	 1.1f,	 0.2f	},
		{	 1.1f,	 0.8f,	-1.3f,	-0.3f,	 2.9f,	 0.9f	},
		{	 3.4f,	 0.8f,	 4.0f,	 0.0f,	-3.3f,	-1.0f	},
		{	-3.4f,	-0.1f,	-4.0f,	 0.0f,	-5.1f,	 1.0f	},
		{	-4.0f,	-0.1f,	 3.4f,	 0.1f,	 5.7f,	 0.0f	},
		{	-5.6f,	 0.0f,	 0.5f,	 1.2f,	 3.9f,	 4.0f	},
		{	 5.0f,	-2.0f,	 3.1f,	 1.2f,	 5.1f,	 0.2f	},
		{	 2.5f,	-2.0f,	 6.3f,	 3.0f,	 5.1f,	 0.2f	},
		{	-8.3f,	 0.0f,	 7.1f,	 3.0f,	 2.0f,	 0.2f	},
		{	 3.8f,	 0.0f,	 9.7f,	 1.0f,	 7.0f,	 0.7f	},
		{	13.3f,	 0.0f,	 7.1f,	 3.0f,	 2.0f,	 0.2f	},
		{	16.0f,	 8.0f,	12.7f,	 1.0f,	17.1f,	 0.7f	},
		{	15.3f,	 0.0f,	20.1f,	 3.0f,	33.0f,	 3.2f	}
	};

	const float sScale	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sScale;
	const float sBias	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sBias;
	const float tScale	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tScale;
	const float tBias	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tBias;
	const float rScale	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rScale;
	const float rBias	= s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rBias;

	dst.resize(3*4);

	dst[0] = sBias;			dst[ 1] = tBias;			dst[ 2] = rBias;
	dst[3] = sBias;			dst[ 4] = tBias+tScale;		dst[ 5] = rBias+rScale*0.5f;
	dst[6] = sBias+sScale;	dst[ 7] = tBias;			dst[ 8] = rBias+rScale*0.5f;
	dst[9] = sBias+sScale;	dst[10] = tBias+tScale;		dst[11] = rBias+rScale;
}

static void getBasicTexCoord3DImageViewMinlodIntTexCoord (std::vector<float>& dst)
{
	const float sScale	= 1.0f;
	const float sBias	= 0.0f;
	const float tScale	= 1.0f;
	const float tBias	= 0.0f;
	const float rScale	= 1.0f;
	const float rBias	= 0.0f;

	dst.resize(3*4);

	dst[0] = sBias;			dst[ 1] = tBias;			dst[ 2] = rBias;
	dst[3] = sBias;			dst[ 4] = tBias+tScale;		dst[ 5] = rBias+rScale*0.5f;
	dst[6] = sBias+sScale;	dst[ 7] = tBias;			dst[ 8] = rBias+rScale*0.5f;
	dst[9] = sBias+sScale;	dst[10] = tBias+tScale;		dst[11] = rBias+rScale;
}

static void getAffineTexCoord3D (std::vector<float>& dst, int cellNdx)
{
	// Use basic coords as base.
	getBasicTexCoord3D(dst, cellNdx);

	// Rotate based on cell index.
	const float		angleX		= 0.0f + 2.0f*DE_PI * ((float)cellNdx / 16.0f);
	const float		angleY		= 1.0f + 2.0f*DE_PI * ((float)cellNdx / 32.0f);
	const tcu::Mat3	rotMatrix	= tcu::rotationMatrixX(angleX) * tcu::rotationMatrixY(angleY);

	const Vec3		p0			= rotMatrix * Vec3(dst[0], dst[ 1], dst[ 2]);
	const Vec3		p1			= rotMatrix * Vec3(dst[3], dst[ 4], dst[ 5]);
	const Vec3		p2			= rotMatrix * Vec3(dst[6], dst[ 7], dst[ 8]);
	const Vec3		p3			= rotMatrix * Vec3(dst[9], dst[10], dst[11]);

	dst[0] = p0.x();	dst[ 1] = p0.y();	dst[ 2] = p0.z();
	dst[3] = p1.x();	dst[ 4] = p1.y();	dst[ 5] = p1.z();
	dst[6] = p2.x();	dst[ 7] = p2.y();	dst[ 8] = p2.z();
	dst[9] = p3.x();	dst[10] = p3.y();	dst[11] = p3.z();
}

tcu::TestStatus Texture3DMipmapTestInstance::iterate (void)
{
	const tcu::TextureFormat&		texFmt			= m_texture->getTextureFormat();
	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
	const Sampler::FilterMode		magFilter		= Sampler::NEAREST;
	const int						viewportWidth	= m_renderer.getRenderWidth();
	const int						viewportHeight	= m_renderer.getRenderHeight();

	const bool						isProjected		= m_testParameters.coordType == COORDTYPE_PROJECTED;
	const bool						useLodBias		= m_testParameters.coordType == COORDTYPE_BASIC_BIAS;

	// Viewport is divided into 4x4 grid.
	const int						gridWidth		= 4;
	const int						gridHeight		= 4;
	const int						cellWidth		= viewportWidth / gridWidth;
	const int						cellHeight		= viewportHeight / gridHeight;

	ReferenceParams					refParams		(TEXTURETYPE_3D);

	tcu::Surface					renderedFrame	(viewportWidth, viewportHeight);
	vector<float>					texCoord;

	// Sampling parameters.
	refParams.sampler		= util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter);
	refParams.samplerType	= getSamplerType(texFmt);

	refParams.colorBias		= fmtInfo.lookupBias;
	refParams.colorScale	= fmtInfo.lookupScale;
	refParams.flags			= (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);

	// Bias values.
	static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };

	// Projection values.
	static const Vec4 s_projections[] =
	{
		Vec4(1.2f, 1.0f, 0.7f, 1.0f),
		Vec4(1.3f, 0.8f, 0.6f, 2.0f),
		Vec4(0.8f, 1.0f, 1.7f, 0.6f),
		Vec4(1.2f, 1.0f, 1.7f, 1.5f)
	};

	// Render cells.
	for (int gridY = 0; gridY < gridHeight; gridY++)
	{
		for (int gridX = 0; gridX < gridWidth; gridX++)
		{
			const int	curX		= cellWidth*gridX;
			const int	curY		= cellHeight*gridY;
			const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
			const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
			const int	cellNdx		= gridY*gridWidth + gridX;

			// Compute texcoord.
			switch (m_testParameters.coordType)
			{
				case COORDTYPE_BASIC_BIAS:	// Fall-through.
				case COORDTYPE_PROJECTED:
				case COORDTYPE_BASIC:		getBasicTexCoord3D	(texCoord, cellNdx);	break;
				case COORDTYPE_AFFINE:		getAffineTexCoord3D	(texCoord, cellNdx);	break;
				default:					DE_ASSERT(DE_FALSE);
			}

			// Set projection.
			if (isProjected)
				refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];

			// Set LOD bias.
			if (useLodBias)
				refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];

			m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
			m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
		}
	}

	// Compare and log
	{
		const tcu::IVec4		formatBitDepth	= getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		const tcu::PixelFormat	pixelFormat		(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
		const bool				isTrilinear		= m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
		tcu::Surface			referenceFrame	(viewportWidth, viewportHeight);
		tcu::Surface			errorMask		(viewportWidth, viewportHeight);
		tcu::LookupPrecision	lookupPrec;
		tcu::LodPrecision		lodPrec;
		int						numFailedPixels	= 0;

		lookupPrec.coordBits		= tcu::IVec3(20, 20, 20);
		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
		lookupPrec.colorMask		= getCompareMask(pixelFormat);
		lodPrec.derivateBits		= 10;
		lodPrec.lodBits				= isProjected ? 6 : 8;

		for (int gridY = 0; gridY < gridHeight; gridY++)
		{
			for (int gridX = 0; gridX < gridWidth; gridX++)
			{
				const int	curX		= cellWidth*gridX;
				const int	curY		= cellHeight*gridY;
				const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
				const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
				const int	cellNdx		= gridY*gridWidth + gridX;

				switch (m_testParameters.coordType)
				{
					case COORDTYPE_BASIC_BIAS:	// Fall-through.
					case COORDTYPE_PROJECTED:
					case COORDTYPE_BASIC:		getBasicTexCoord3D	(texCoord, cellNdx);	break;
					case COORDTYPE_AFFINE:		getAffineTexCoord3D	(texCoord, cellNdx);	break;
					default:					DE_ASSERT(DE_FALSE);
				}

				if (isProjected)
					refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];

				if (useLodBias)
					refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];

				// Render ideal result
				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
							  m_texture->getTexture(), &texCoord[0], refParams);

				// Compare this cell
				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
															m_texture->getTexture(), &texCoord[0], refParams,
															lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
			}
		}

		if (numFailedPixels > 0)
			m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;

		m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
											<< TestLog::Image("Rendered", "Rendered image", renderedFrame);

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
												<< TestLog::Image("ErrorMask", "Error mask", errorMask);
		}

		m_context.getTestContext().getLog() << TestLog::EndImageSet;

		{
			const bool isOk = numFailedPixels == 0;
			return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
		}
	}
}

// Texture2DLodControlTestInstance
class Texture2DLodControlTestInstance : public TestInstance
{
public:
	typedef Texture2DMipmapTestCaseParameters	ParameterType;

										Texture2DLodControlTestInstance		(Context& context, const ParameterType& testParameters);
										~Texture2DLodControlTestInstance	(void);

	virtual tcu::TestStatus				iterate								(void);

protected:
	virtual void						getReferenceParams					(ReferenceParams& params, int cellNdx) = 0;

	const int							m_texWidth;
	const int							m_texHeight;

private:
										Texture2DLodControlTestInstance		(const Texture2DLodControlTestInstance& other);
	Texture2DLodControlTestInstance&	operator=							(const Texture2DLodControlTestInstance& other);

	const ParameterType					m_testParameters;
	tcu::Sampler::FilterMode			m_minFilter;
	TestTexture2DSp						m_texture;
	TextureRenderer						m_renderer;
};

Texture2DLodControlTestInstance::Texture2DLodControlTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
	: TestInstance		(context)
	, m_texWidth		(64) //64
	, m_texHeight		(64)//64
	, m_testParameters	(testParameters)
	, m_minFilter		(testParameters.minFilter)
	, m_texture			(DE_NULL)
	, m_renderer		(context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4, vk::makeComponentMappingRGBA(), testParameters.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD)
{
	const VkFormat	format		= VK_FORMAT_R8G8B8A8_UNORM;
	const int		numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;

	m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(format), m_texWidth, m_texHeight));

	// Fill texture with colored grid.
	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		const deUint32	step	= 0xff / (numLevels-1);
		const deUint32	inc		= deClamp32(step*levelNdx, 0x00, 0xff);
		const deUint32	dec		= 0xff - inc;
		const deUint32	rgb		= (inc << 16) | (dec << 8) | 0xff;
		const deUint32	color	= 0xff000000 | rgb;

		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
	}

	m_renderer.add2DTexture(m_texture, testParameters.aspectMask);
}

Texture2DLodControlTestInstance::~Texture2DLodControlTestInstance (void)
{
}

tcu::TestStatus Texture2DLodControlTestInstance::iterate (void)
{
	const tcu::Sampler::WrapMode	wrapS			= Sampler::REPEAT_GL;
	const tcu::Sampler::WrapMode	wrapT			= Sampler::REPEAT_GL;
	const tcu::Sampler::FilterMode	magFilter		= Sampler::NEAREST;

	const tcu::Texture2D&			refTexture		= m_texture->getTexture();

	const int						viewportWidth	= m_renderer.getRenderWidth();
	const int						viewportHeight	= m_renderer.getRenderHeight();

	tcu::Sampler					sampler			= util::createSampler(wrapS, wrapT, m_minFilter, magFilter);

	ReferenceParams					refParams		(TEXTURETYPE_2D, sampler);
	vector<float>					texCoord;
	tcu::Surface					renderedFrame	(viewportWidth, viewportHeight);

	// Viewport is divided into 4x4 grid.
	const int						gridWidth		= 4;
	const int						gridHeight		= 4;
	const int						cellWidth		= viewportWidth / gridWidth;
	const int						cellHeight		= viewportHeight / gridHeight;

	refParams.maxLevel = deLog2Floor32(de::max(m_texWidth, m_texHeight));

	// Render cells.
	for (int gridY = 0; gridY < gridHeight; gridY++)
	{
		for (int gridX = 0; gridX < gridWidth; gridX++)
		{
			const int	curX		= cellWidth*gridX;
			const int	curY		= cellHeight*gridY;
			const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
			const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
			const int	cellNdx		= gridY*gridWidth + gridX;

			getReferenceParams(refParams,cellNdx);

			// Compute texcoord.
			getBasicTexCoord2D(texCoord, cellNdx);
			// Render
			m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
			m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel, refParams.imageViewMinLod);
			m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
		}
	}

	// Compare and log.
	{
		const tcu::IVec4		formatBitDepth	= getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		const tcu::PixelFormat	pixelFormat		(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
		const bool				isTrilinear		= m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
		tcu::Surface			referenceFrame	(viewportWidth, viewportHeight);
		tcu::Surface			errorMask		(viewportWidth, viewportHeight);
		tcu::LookupPrecision	lookupPrec;
		tcu::LodPrecision		lodPrec;
		int						numFailedPixels	= 0;

		lookupPrec.coordBits		= tcu::IVec3(20, 20, 0);
		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
		lookupPrec.colorMask		= getCompareMask(pixelFormat);
		lodPrec.derivateBits		= 10;
		lodPrec.lodBits				= 8;

		for (int gridY = 0; gridY < gridHeight; gridY++)
		{
			for (int gridX = 0; gridX < gridWidth; gridX++)
			{
				const int	curX		= cellWidth*gridX;
				const int	curY		= cellHeight*gridY;
				const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
				const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
				const int	cellNdx		= gridY*gridWidth + gridX;

				getReferenceParams(refParams,cellNdx);

				// Compute texcoord.
				if (refParams.samplerType == glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT)
					getBasicTexCoord2DImageViewMinLodIntTexCoord(texCoord);
				else
					getBasicTexCoord2D(texCoord, cellNdx);

				// Render ideal result
				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
							  refTexture, &texCoord[0], refParams);

				// Compare this cell
				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
															m_texture->getTexture(), &texCoord[0], refParams,
															lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
			}
		}

		if (numFailedPixels > 0)
			m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;

		m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
											<< TestLog::Image("Rendered", "Rendered image", renderedFrame);

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
												<< TestLog::Image("ErrorMask", "Error mask", errorMask);
		}

		m_context.getTestContext().getLog() << TestLog::EndImageSet;

		{
			const bool isOk = numFailedPixels == 0;
			return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
		}
	}
}

class Texture2DMinLodTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DMinLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
	{
	}

protected:
	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.minLod = getMinLodForCell(cellNdx);
	}
};

class Texture2DMaxLodTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DMaxLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
	{
	}

protected:
	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.maxLod = getMaxLodForCell(cellNdx);
	}
};

class Texture2DBaseLevelTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DBaseLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture2DMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;

		return baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
	}
};

class Texture2DMaxLevelTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DMaxLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture2DMipmapTestCaseParameters m_testParam;

	int getMaxLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
		const int	maxLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x82cfa4e) % numLevels;

		return maxLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.maxLevel = getMaxLevel(cellNdx);
	}
};

// TextureCubeLodControlTestInstance
class TextureCubeLodControlTestInstance : public TestInstance
{
public:
	typedef TextureCubeMipmapTestCaseParameters	ParameterType;

										TextureCubeLodControlTestInstance	(Context& context, const ParameterType& testParameters);
										~TextureCubeLodControlTestInstance	(void);

	virtual tcu::TestStatus				iterate								(void);

protected:
	virtual void						getReferenceParams					(ReferenceParams& params, int cellNdx)	= DE_NULL;

	const int							m_texSize;

private:
										TextureCubeLodControlTestInstance	(const TextureCubeLodControlTestInstance& other);
	TextureCubeLodControlTestInstance&	operator=							(const TextureCubeLodControlTestInstance& other);

	const ParameterType					m_testParameters;
	tcu::Sampler::FilterMode			m_minFilter;
	TestTextureCubeSp					m_texture;
	TextureRenderer						m_renderer;
};

TextureCubeLodControlTestInstance::TextureCubeLodControlTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
	: TestInstance		(context)
	, m_texSize			(64)
	, m_testParameters	(testParameters)
	, m_minFilter		(testParameters.minFilter)
	, m_texture			(DE_NULL)

	, m_renderer		(context, testParameters.sampleCount, m_texSize*2, m_texSize*2)
{
	const VkFormat	format		= VK_FORMAT_R8G8B8A8_UNORM;
	const int		numLevels	= deLog2Floor32(m_texSize)+1;

	m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(format), m_texSize));

	// Fill texture with colored grid.
	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
	{
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			const deUint32	step	= 0xff / (numLevels-1);
			const deUint32	inc		= deClamp32(step*levelNdx, 0x00, 0xff);
			const deUint32	dec		= 0xff - inc;
			deUint32		rgb		= 0;

			switch (faceNdx)
			{
				case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
				case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
				case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
				case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
				case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
				case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
			}

			const deUint32	color	= 0xff000000 | rgb;

			tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
		}
	}

	m_renderer.addCubeTexture(m_texture, testParameters.aspectMask);
}

TextureCubeLodControlTestInstance::~TextureCubeLodControlTestInstance (void)
{
}

tcu::TestStatus TextureCubeLodControlTestInstance::iterate (void)
{
	const tcu::Sampler::WrapMode	wrapS			= Sampler::CLAMP_TO_EDGE;
	const tcu::Sampler::WrapMode	wrapT			= Sampler::CLAMP_TO_EDGE;
	const tcu::Sampler::FilterMode	magFilter		= Sampler::NEAREST;

	const tcu::TextureCube&			refTexture		= m_texture->getTexture();
	const int						viewportWidth	= m_renderer.getRenderWidth();
	const int						viewportHeight	= m_renderer.getRenderHeight();

	tcu::Sampler					sampler			= util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
	ReferenceParams					refParams		(TEXTURETYPE_CUBE, sampler);
	vector<float>					texCoord;
	tcu::Surface					renderedFrame	(viewportWidth, viewportHeight);

	refParams.maxLevel = deLog2Floor32(m_texSize);

	// Compute grid.
	vector<tcu::IVec4> gridLayout;
	computeGridLayout(gridLayout, viewportWidth, viewportHeight);

	for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
	{
		const int			curX		= gridLayout[cellNdx].x();
		const int			curY		= gridLayout[cellNdx].y();
		const int			curW		= gridLayout[cellNdx].z();
		const int			curH		= gridLayout[cellNdx].w();
		const tcu::CubeFace	cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);

		computeQuadTexCoordCube(texCoord, cubeFace);
		getReferenceParams(refParams, cellNdx);

		// Render with GL.
		m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
		m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel, refParams.imageViewMinLod);
		m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
	}

	// Render reference and compare
	{
		const tcu::IVec4		formatBitDepth		= getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		const tcu::PixelFormat	pixelFormat			(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
		tcu::Surface			referenceFrame		(viewportWidth, viewportHeight);
		tcu::Surface			errorMask			(viewportWidth, viewportHeight);
		int						numFailedPixels		= 0;
		tcu::LookupPrecision	lookupPrec;
		tcu::LodPrecision		lodPrec;

		// Params for rendering reference
		refParams.sampler					= util::createSampler(wrapS, wrapT, m_testParameters.minFilter, magFilter);
		refParams.sampler.seamlessCubeMap	= true;
		refParams.lodMode					= LODMODE_EXACT;

		// Comparison parameters
		lookupPrec.colorMask				= getCompareMask(pixelFormat);
		lookupPrec.colorThreshold			= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, IVec4(0)));
		lookupPrec.coordBits				= tcu::IVec3(10);
		lookupPrec.uvwBits					= tcu::IVec3(5,5,0);
		lodPrec.derivateBits				= 10;
		lodPrec.lodBits						= 6;

		for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
		{
			const int				curX		= gridLayout[cellNdx].x();
			const int				curY		= gridLayout[cellNdx].y();
			const int				curW		= gridLayout[cellNdx].z();
			const int				curH		= gridLayout[cellNdx].w();
			const tcu::CubeFace		cubeFace	= (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);

			computeQuadTexCoordCube(texCoord, cubeFace);
			getReferenceParams(refParams, cellNdx);

			// Render ideal reference.
			{
				tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH);
				sampleTexture(idealDst, refTexture, &texCoord[0], refParams);
			}

			// Compare this cell
			numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
														tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
														tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
														m_texture->getTexture(), &texCoord[0], refParams,
														lookupPrec, lodPrec,  m_context.getTestContext().getWatchDog());
		}

		if (numFailedPixels > 0)
			 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;

		 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
											 << TestLog::Image("Rendered", "Rendered image", renderedFrame);

		if (numFailedPixels > 0)
		{
			 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
												 << TestLog::Image("ErrorMask", "Error mask", errorMask);
		}

		 m_context.getTestContext().getLog() << TestLog::EndImageSet;

		{
			const bool isOk = numFailedPixels == 0;
			return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
		}
	}
}

class TextureCubeMinLodTestInstance : public TextureCubeLodControlTestInstance
{
public:
	TextureCubeMinLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
		: TextureCubeLodControlTestInstance(context, testParameters)
	{
	}

protected:
	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.minLod = getMinLodForCell(cellNdx);
	}
};

class TextureCubeMaxLodTestInstance : public TextureCubeLodControlTestInstance
{
public:
	TextureCubeMaxLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
		: TextureCubeLodControlTestInstance(context, testParameters)
	{
	}

protected:
	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.maxLod = getMaxLodForCell(cellNdx);
	}
};

class TextureCubeBaseLevelTestInstance : public TextureCubeLodControlTestInstance
{
public:
	TextureCubeBaseLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
		: TextureCubeLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const TextureCubeMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(m_texSize)+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x23fae13) % numLevels;

		return baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
	}
};

class TextureCubeMaxLevelTestInstance : public TextureCubeLodControlTestInstance
{
public:
	TextureCubeMaxLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
		: TextureCubeLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const TextureCubeMipmapTestCaseParameters m_testParam;
	int getMaxLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(m_texSize)+1;
		const int	maxLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x974e21) % numLevels;

		return maxLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.maxLevel = getMaxLevel(cellNdx);
	}
};

// Texture3DLodControlTestInstance
class Texture3DLodControlTestInstance : public TestInstance
{
public:
	typedef Texture3DMipmapTestCaseParameters	ParameterType;

										Texture3DLodControlTestInstance		(Context& context, const ParameterType& testParameters);
										~Texture3DLodControlTestInstance	(void);

	virtual tcu::TestStatus				iterate								(void);

protected:
	virtual void						getReferenceParams					(ReferenceParams& params, int cellNdx)	= DE_NULL;

	const int							m_texWidth;
	const int							m_texHeight;
	const int							m_texDepth;

private:
										Texture3DLodControlTestInstance		(const Texture3DLodControlTestInstance& other);
	Texture3DLodControlTestInstance&	operator=							(const Texture3DLodControlTestInstance& other);

	const ParameterType					m_testParameters;
	tcu::Sampler::FilterMode			m_minFilter;
	TestTexture3DSp						m_texture;
	TextureRenderer						m_renderer;
};

Texture3DLodControlTestInstance::Texture3DLodControlTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
	: TestInstance		(context)
	, m_texWidth		(32)
	, m_texHeight		(32)
	, m_texDepth		(32)
	, m_testParameters	(testParameters)
	, m_minFilter		(testParameters.minFilter)
	, m_texture			(DE_NULL)
	, m_renderer		(context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4, vk::makeComponentMappingRGBA(), testParameters.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD)
{
	const VkFormat			format		= VK_FORMAT_R8G8B8A8_UNORM;
	tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(mapVkFormat(format));
	const tcu::Vec4&		cScale		= fmtInfo.lookupScale;
	const tcu::Vec4&		cBias		= fmtInfo.lookupBias;
	const int				numLevels	= deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth))+1;

	m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(format), m_texWidth, m_texHeight, m_texDepth));

	// Fill texture with colored grid.
	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		const deUint32	step	= 0xff / (numLevels-1);
		const deUint32	inc		= deClamp32(step*levelNdx, 0x00, 0xff);
		const deUint32	dec		= 0xff - inc;
		const deUint32	rgb		= (inc << 16) | (dec << 8) | 0xff;
		const deUint32	color	= 0xff000000 | rgb;

		tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
	}

	m_renderer.add3DTexture(m_texture, testParameters.aspectMask);
}

Texture3DLodControlTestInstance::~Texture3DLodControlTestInstance (void)
{
}

tcu::TestStatus Texture3DLodControlTestInstance::iterate (void)
{
	const tcu::Sampler::WrapMode	wrapS			= Sampler::CLAMP_TO_EDGE;
	const tcu::Sampler::WrapMode	wrapT			= Sampler::CLAMP_TO_EDGE;
	const tcu::Sampler::WrapMode	wrapR			= Sampler::CLAMP_TO_EDGE;
	const tcu::Sampler::FilterMode	magFilter		= Sampler::NEAREST;

	const tcu::Texture3D&			refTexture		= m_texture->getTexture();
	const tcu::TextureFormat&		texFmt			= refTexture.getFormat();
	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
	const int						viewportWidth	= m_renderer.getRenderWidth();
	const int						viewportHeight	= m_renderer.getRenderHeight();

	tcu::Sampler					sampler			= util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
	ReferenceParams					refParams		(TEXTURETYPE_3D, sampler);
	vector<float>					texCoord;
	tcu::Surface					renderedFrame	(viewportWidth, viewportHeight);

	// Viewport is divided into 4x4 grid.
	const int						gridWidth		= 4;
	const int						gridHeight		= 4;
	const int						cellWidth		= viewportWidth / gridWidth;
	const int						cellHeight		= viewportHeight / gridHeight;

	// Sampling parameters.
	refParams.sampler		= util::createSampler(wrapS, wrapT, wrapR, m_testParameters.minFilter, magFilter);
	refParams.samplerType	= getSamplerType(texFmt);
	refParams.colorBias		= fmtInfo.lookupBias;
	refParams.colorScale	= fmtInfo.lookupScale;
	refParams.maxLevel		= deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth));

	// Render cells.
	for (int gridY = 0; gridY < gridHeight; gridY++)
	{
		for (int gridX = 0; gridX < gridWidth; gridX++)
		{
			const int	curX		= cellWidth*gridX;
			const int	curY		= cellHeight*gridY;
			const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
			const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
			const int	cellNdx		= gridY*gridWidth + gridX;

			// Compute texcoord.
			getBasicTexCoord3D(texCoord, cellNdx);

			getReferenceParams(refParams,cellNdx);
			//Render
			m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
			m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel, refParams.imageViewMinLod);
			m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
		}
	}

	// Compare and log
	{
		const tcu::IVec4		formatBitDepth	= getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		const tcu::PixelFormat	pixelFormat		(formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
		const bool				isTrilinear		= m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
		tcu::Surface			referenceFrame	(viewportWidth, viewportHeight);
		tcu::Surface			errorMask		(viewportWidth, viewportHeight);
		tcu::LookupPrecision	lookupPrec;
		tcu::LodPrecision		lodPrec;
		int						numFailedPixels	= 0;

		lookupPrec.coordBits		= tcu::IVec3(20, 20, 20);
		lookupPrec.uvwBits			= tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
		lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
		lookupPrec.colorMask		= getCompareMask(pixelFormat);
		lodPrec.derivateBits		= 10;
		lodPrec.lodBits				= 8;

		for (int gridY = 0; gridY < gridHeight; gridY++)
		{
			for (int gridX = 0; gridX < gridWidth; gridX++)
			{
				const int	curX		= cellWidth*gridX;
				const int	curY		= cellHeight*gridY;
				const int	curW		= gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
				const int	curH		= gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
				const int	cellNdx		= gridY*gridWidth + gridX;

				getReferenceParams(refParams, cellNdx);

				// Compute texcoord.
				if (refParams.samplerType == glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT)
					getBasicTexCoord3DImageViewMinlodIntTexCoord(texCoord);
				else
					getBasicTexCoord3D(texCoord, cellNdx);

				// Render ideal result
				sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
							  refTexture, &texCoord[0], refParams);

				// Compare this cell
				numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
															tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
															m_texture->getTexture(), &texCoord[0], refParams,
															lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
			}
		}

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
		}

		m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
											<< TestLog::Image("Rendered", "Rendered image", renderedFrame);

		if (numFailedPixels > 0)
		{
			m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
												<< TestLog::Image("ErrorMask", "Error mask", errorMask);
		}

		m_context.getTestContext().getLog() << TestLog::EndImageSet;

		{
			const bool isOk = numFailedPixels == 0;
			return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
		}
	}
}

class Texture3DMinLodTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DMinLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
	{
	}

protected:
	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.minLod = getMinLodForCell(cellNdx);
	}
};

class Texture3DMaxLodTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DMaxLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
	{
	}

protected:
	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.maxLod = getMaxLodForCell(cellNdx);
	}
};

class Texture3DBaseLevelTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DBaseLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
		,m_testParam (testParameters)
	{
	}

protected:
	const Texture3DMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;

		return baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
	}
};

class Texture3DMaxLevelTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DMaxLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
		,m_testParam (testParameters)
	{
	}

protected:
	const Texture3DMipmapTestCaseParameters m_testParam;

	int getMaxLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
		const int	maxLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x9111e7) % numLevels;

		return maxLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.maxLevel = getMaxLevel(cellNdx);
	}
};

class Texture2DImageViewMinLodTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DImageViewMinLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
	{
	}

protected:

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minBaseLevel = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minBaseLevel, (float)maxLevel);
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.minLod = getMinLodForCell(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture2DImageViewMinLodBaseLevelTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DImageViewMinLodBaseLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture2DMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;

		return baseLevel;
	}

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture3DImageViewMinLodTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DImageViewMinLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
	{
	}

protected:
	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.minLod = getMinLodForCell(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture3DImageViewMinLodBaseLevelTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DImageViewMinLodBaseLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture3DMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;

		return baseLevel;
	}

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);

	}
};

class TextureCubeImageViewMinLodTestInstance : public TextureCubeLodControlTestInstance
{
public:
	TextureCubeImageViewMinLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
		: TextureCubeLodControlTestInstance(context, testParameters)
	{
	}

protected:
	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.minLod = getMinLodForCell(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class TextureCubeImageViewMinLodBaseLevelTestInstance : public TextureCubeLodControlTestInstance
{
public:
	TextureCubeImageViewMinLodBaseLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
		: TextureCubeLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const TextureCubeMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(m_texSize)+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x23fae13) % numLevels;

		return baseLevel;
	}

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture2DImageViewMinLodIntTexCoordTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DImageViewMinLodIntTexCoordTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture2DMipmapTestCaseParameters m_testParam;

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);
		return rnd.getInt(baseLevel, maxLevel) - baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
		params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
		params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance : public Texture2DLodControlTestInstance
{
public:
	Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
		: Texture2DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture2DMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;

		return baseLevel;
	}

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);
		return rnd.getInt(baseLevel, maxLevel) - baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
		params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
		params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture2DImageViewMinLodIntTexCoordTest : public vkt::TestCase
{
public:
	Texture2DImageViewMinLodIntTexCoordTest						(tcu::TestContext&							testContext,
																 const string&								name,
																 const string&								description,
																 const Texture2DMipmapTestCaseParameters&	params);
	~Texture2DImageViewMinLodIntTexCoordTest					(void);
	void						initPrograms					(SourceCollections& sourceCollections) const;
	TestInstance*				createInstance					(Context& context) const;
	void						checkSupport					(Context& context) const;

protected:
	const Texture2DMipmapTestCaseParameters	m_params;
};

Texture2DImageViewMinLodIntTexCoordTest::Texture2DImageViewMinLodIntTexCoordTest (tcu::TestContext&							testContext,
																				  const string&								name,
																				  const string&								description,
																				  const Texture2DMipmapTestCaseParameters&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

Texture2DImageViewMinLodIntTexCoordTest::~Texture2DImageViewMinLodIntTexCoordTest (void)
{
}

void Texture2DImageViewMinLodIntTexCoordTest::initPrograms(SourceCollections& sourceCollections) const
{
	static const char* vertShader =
		"#version 450\n"
		"layout(location = 0) in vec4 a_position;\n"
		"layout(location = 1) in vec2 a_texCoord;\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"}\n";

	static const char* fragShader =
		"#version 450\n"
		"layout(location = 0) out vec4 outColor;\n"
		"layout (set=0, binding=0, std140) uniform Block \n"
		"{\n"
		"  float u_bias;\n"
		"  float u_ref;\n"
		"  vec4 u_colorScale;\n"
		"  vec4 u_colorBias;\n"
		"  int u_lod;\n"
		"};\n\n"
		"layout (set=1, binding=0) uniform sampler2D u_sampler;\n"
		"void main (void)\n"
		"{\n"
		"  ivec2 texCoord = ivec2(0,0);\n" // Sampling always from the same coord, we are only interested on the lod.
		"  outColor = texelFetch(u_sampler, texCoord, u_lod) * u_colorScale + u_colorBias;\n"
		"}\n";
	sourceCollections.glslSources.add("vertex_2D_FETCH_LOD") << glu::VertexSource(vertShader);
	sourceCollections.glslSources.add("fragment_2D_FETCH_LOD") << glu::FragmentSource(fragShader);
}

void Texture2DImageViewMinLodIntTexCoordTest::checkSupport(Context& context) const
{
	DE_ASSERT(m_params.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD);

	context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
	context.requireDeviceFunctionality("VK_EXT_robustness2");
	vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
	imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
	imageViewMinLodFeatures.pNext = DE_NULL;

	VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features;
	robustness2Features.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
	robustness2Features.pNext = &imageViewMinLodFeatures;
	vk::VkPhysicalDeviceFeatures2 features2;

	features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	features2.pNext = &robustness2Features;

	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);

	if (imageViewMinLodFeatures.minLod == DE_FALSE)
		TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");

	if (robustness2Features.robustImageAccess2 == DE_FALSE)
		TCU_THROW(NotSupportedError, "VK_EXT_robustness2 robustImageAccess2 feature not supported");
}

TestInstance* Texture2DImageViewMinLodIntTexCoordTest::createInstance(Context& context) const
{
	if (m_params.testType == util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD)
		return new Texture2DImageViewMinLodIntTexCoordTestInstance(context, m_params);
	else
	   return new Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance(context, m_params);
}

class Texture3DImageViewMinLodIntTexCoordTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DImageViewMinLodIntTexCoordTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture3DMipmapTestCaseParameters m_testParam;

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);
		return rnd.getInt(baseLevel, maxLevel) - baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
		params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
		params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance : public Texture3DLodControlTestInstance
{
public:
	Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
		: Texture3DLodControlTestInstance(context, testParameters)
		, m_testParam (testParameters)
	{
	}

protected:
	const Texture3DMipmapTestCaseParameters m_testParam;

	int getBaseLevel (int cellNdx) const
	{
		const int	numLevels	= deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
		const int	baseLevel	= (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;

		return baseLevel;
	}

	float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);

		// baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
		float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
		return rnd.getFloat(minValue, (float)maxLevel);
	}

	int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
	{
		de::Random rnd(cellNdx + 1);
		return rnd.getInt(baseLevel, maxLevel) - baseLevel;
	}

	void getReferenceParams (ReferenceParams& params, int cellNdx)
	{
		params.baseLevel = getBaseLevel(cellNdx);
		params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
		params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
		params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
	}
};

class Texture3DImageViewMinLodIntTexCoordTest : public vkt::TestCase
{
public:
	Texture3DImageViewMinLodIntTexCoordTest						(tcu::TestContext&							testContext,
																 const string&								name,
																 const string&								description,
																 const Texture3DMipmapTestCaseParameters&	params);
	~Texture3DImageViewMinLodIntTexCoordTest					(void);
	void						initPrograms					(SourceCollections& sourceCollections) const;
	TestInstance*				createInstance					(Context& context) const;
	void						checkSupport					(Context& context) const;

protected:
	const Texture3DMipmapTestCaseParameters	m_params;
};

Texture3DImageViewMinLodIntTexCoordTest::Texture3DImageViewMinLodIntTexCoordTest (tcu::TestContext&							testContext,
																				  const string&								name,
																				  const string&								description,
																				  const Texture3DMipmapTestCaseParameters&	params)
	: vkt::TestCase	(testContext, name, description)
	, m_params		(params)
{
}

Texture3DImageViewMinLodIntTexCoordTest::~Texture3DImageViewMinLodIntTexCoordTest (void)
{
}

void Texture3DImageViewMinLodIntTexCoordTest::initPrograms(SourceCollections& sourceCollections) const
{
	static const char* vertShader =
		"#version 450\n"
		"layout(location = 0) in vec4 a_position;\n"
		"layout(location = 1) in vec3 a_texCoord;\n"
		"out gl_PerVertex { vec4 gl_Position; };\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"}\n";

	static const char* fragShader =
		"#version 450\n"
		"layout(location = 0) out vec4 outColor;\n"
		"layout (set=0, binding=0, std140) uniform Block \n"
		"{\n"
		"  float u_bias;\n"
		"  float u_ref;\n"
		"  vec4 u_colorScale;\n"
		"  vec4 u_colorBias;\n"
		"  int u_lod;\n"
		"};\n\n"
		"layout (set=1, binding=0) uniform sampler3D u_sampler;\n"
		"void main (void)\n"
		"{\n"
		"  ivec3 texCoord = ivec3(0,0,0);\n" // Sampling always from the same coord, we are only interested on the lod.
		"  outColor = texelFetch(u_sampler, texCoord, u_lod) * u_colorScale + u_colorBias;\n"
		"}\n";
	sourceCollections.glslSources.add("vertex_3D_FETCH_LOD") << glu::VertexSource(vertShader);
	sourceCollections.glslSources.add("fragment_3D_FETCH_LOD") << glu::FragmentSource(fragShader);
}

void Texture3DImageViewMinLodIntTexCoordTest::checkSupport(Context& context) const
{
	DE_ASSERT(m_params.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD);

	context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
	context.requireDeviceFunctionality("VK_EXT_robustness2");
	vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
	imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
	imageViewMinLodFeatures.pNext = DE_NULL;

	VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features;
	robustness2Features.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
	robustness2Features.pNext = &imageViewMinLodFeatures;
	vk::VkPhysicalDeviceFeatures2 features2;

	features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	features2.pNext = &robustness2Features;

	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);

	if (imageViewMinLodFeatures.minLod == DE_FALSE)
		TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");

	if (robustness2Features.robustImageAccess2 == DE_FALSE)
		TCU_THROW(NotSupportedError, "VK_EXT_robustness2 robustImageAccess2 feature not supported");
}

TestInstance* Texture3DImageViewMinLodIntTexCoordTest::createInstance(Context& context) const
{
	if (m_params.testType == util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD)
		return new Texture3DImageViewMinLodIntTexCoordTestInstance(context, m_params);
	else
	   return new Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance(context, m_params);
}

} // anonymous

namespace util {

template <>
void checkTextureSupport (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
{
	if (testParameters.testType != TextureCommonTestCaseParameters::TEST_NORMAL)
	{
		context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
		vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
		imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
		imageViewMinLodFeatures.pNext = DE_NULL;

		vk::VkPhysicalDeviceFeatures2 features2;

		features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
		features2.pNext = &imageViewMinLodFeatures;

		context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);

		if (imageViewMinLodFeatures.minLod == DE_FALSE)
			TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
	}
}

template <>
void checkTextureSupport (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
{
	if (testParameters.testType != TextureCommonTestCaseParameters::TEST_NORMAL)
	{
		context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
		vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
		imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
		imageViewMinLodFeatures.pNext = DE_NULL;

		vk::VkPhysicalDeviceFeatures2 features2;

		features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
		features2.pNext = &imageViewMinLodFeatures;

		context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);

		if (imageViewMinLodFeatures.minLod == DE_FALSE)
			TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
	}
}

template <>
void checkTextureSupport (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
{
	if (testParameters.testType != TextureCommonTestCaseParameters::TEST_NORMAL)
	{
		context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
		vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
		imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
		imageViewMinLodFeatures.pNext = DE_NULL;

		vk::VkPhysicalDeviceFeatures2 features2;

		features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
		features2.pNext = &imageViewMinLodFeatures;

		context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);

		if (imageViewMinLodFeatures.minLod == DE_FALSE)
			TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
	}
}

} // util

void populateTextureMipmappingTests (tcu::TestCaseGroup* textureMipmappingTests)
{
	tcu::TestContext&	testCtx		= textureMipmappingTests->getTestContext();

	static const struct
	{
		const char*				name;
		const Sampler::WrapMode	mode;
	} wrapModes[] =
	{
		{ "clamp",		Sampler::CLAMP_TO_EDGE		},
		{ "repeat",		Sampler::REPEAT_GL			},
		{ "mirror",		Sampler::MIRRORED_REPEAT_GL	}
	};

	static const struct
	{
		const char*					name;
		const Sampler::FilterMode	mode;
	} minFilterModes[] =
	{
		{ "nearest_nearest",	Sampler::NEAREST_MIPMAP_NEAREST	},
		{ "linear_nearest",		Sampler::LINEAR_MIPMAP_NEAREST	},
		{ "nearest_linear",		Sampler::NEAREST_MIPMAP_LINEAR	},
		{ "linear_linear",		Sampler::LINEAR_MIPMAP_LINEAR	}
	};

	static const struct
	{
		const char*					name;
		const Sampler::FilterMode	mode;
	} magFilterModes[] =
	{
		{ "nearest",	Sampler::NEAREST},
		{ "linear",		Sampler::LINEAR}
	};


	static const struct
	{
		const CoordType		type;
		const char*			name;
		const char*			desc;
	} coordTypes[] =
	{
		{ COORDTYPE_BASIC,		"basic",		"Mipmapping with translated and scaled coordinates" },
		{ COORDTYPE_AFFINE,		"affine",		"Mipmapping with affine coordinate transform"		},
		{ COORDTYPE_PROJECTED,	"projected",	"Mipmapping with perspective projection"			}
	};

	static const struct
	{
		const char*		name;
		const int		width;
		const int		height;
	} tex2DSizes[] =
	{
		{ DE_NULL,		64, 64 }, // Default.
		{ "npot",		63, 57 },
		{ "non_square",	32, 64 }
	};

	static const struct
	{
		const char*		name;
		const int		width;
		const int		height;
		const int		depth;
	} tex3DSizes[] =
	{
		{ DE_NULL,		32, 32, 32 }, // Default.
		{ "npot",		33, 29, 27 }
	};

	const int cubeMapSize = 64;

	static const struct
	{
		const CoordType		type;
		const char*			name;
		const char*			desc;
	} cubeCoordTypes[] =
	{
		{ COORDTYPE_BASIC,		"basic",		"Mipmapping with translated and scaled coordinates" },
		{ COORDTYPE_PROJECTED,	"projected",	"Mipmapping with perspective projection"			},
		{ COORDTYPE_BASIC_BIAS,	"bias",			"User-supplied bias value"							}
	};

	// 2D cases.
	{
		de::MovePtr<tcu::TestCaseGroup>	group2D				(new tcu::TestCaseGroup(testCtx, "2d", "2D Mipmap Filtering"));

		de::MovePtr<tcu::TestCaseGroup>	biasGroup2D			(new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value"));
		de::MovePtr<tcu::TestCaseGroup>	minLodGroup2D		(new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
		de::MovePtr<tcu::TestCaseGroup>	maxLodGroup2D		(new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
		de::MovePtr<tcu::TestCaseGroup>	baseLevelGroup2D	(new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
		de::MovePtr<tcu::TestCaseGroup>	maxLevelGroup2D		(new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));

		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodExtGroup2D	(new tcu::TestCaseGroup(testCtx, "image_view_min_lod", "VK_EXT_image_view_min_lod tests"));
		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodGroup2D	(new tcu::TestCaseGroup(testCtx, "min_lod", "ImageView's minLod"));
		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodBaseLevelGroup2D	(new tcu::TestCaseGroup(testCtx, "base_level", "ImageView's minLod with base level different than one"));

		for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
		{
			de::MovePtr<tcu::TestCaseGroup>	coordTypeGroup		(new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc));

			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
				{
					// Add non_square variants to basic cases only.
					int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1;

					for (int size = 0; size < sizeEnd; size++)
					{
						Texture2DMipmapTestCaseParameters	testParameters;

						testParameters.coordType	= coordTypes[coordType].type;
						testParameters.minFilter	= minFilterModes[minFilter].mode;
						testParameters.wrapS		= wrapModes[wrapMode].mode;
						testParameters.wrapT		= wrapModes[wrapMode].mode;
						testParameters.format		= VK_FORMAT_R8G8B8A8_UNORM;
						testParameters.width		= tex2DSizes[size].width;
						testParameters.height		= tex2DSizes[size].height;
						testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
						testParameters.programs.push_back(PROGRAM_2D_FLOAT);

						std::ostringstream name;
						name << minFilterModes[minFilter].name
							 << "_" << wrapModes[wrapMode].name;

						if (tex2DSizes[size].name)
							name << "_" << tex2DSizes[size].name;

						coordTypeGroup->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
					}
				}
			}

			group2D->addChild(coordTypeGroup.release());
		}

		// 2D bias variants.
		{
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;

				testParameters.coordType	= COORDTYPE_BASIC_BIAS;
				testParameters.minFilter	= minFilterModes[minFilter].mode;
				testParameters.magFilter	= minFilterModes[minFilter].mode;
				testParameters.wrapS		= Sampler::REPEAT_GL;
				testParameters.wrapT		= Sampler::REPEAT_GL;
				testParameters.format		= VK_FORMAT_R8G8B8A8_UNORM;
				testParameters.width		= tex2DSizes[0].width;
				testParameters.height		= tex2DSizes[0].height;
				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT_BIAS);

				std::ostringstream name;
				name << minFilterModes[minFilter].name;

				biasGroup2D->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
			}
		}

		// 2D LOD controls.
		{
			// MIN_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter	= minFilterModes[minFilter].mode;
				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT);

				minLodGroup2D->addChild(new TextureTestCase<Texture2DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// MAX_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter	= minFilterModes[minFilter].mode;
				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT);

				maxLodGroup2D->addChild(new TextureTestCase<Texture2DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		{
			// BASE_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter		= minFilterModes[minFilter].mode;
				testParameters.minFilterName	= minFilterModes[minFilter].name;
				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT);

				baseLevelGroup2D->addChild(new TextureTestCase<Texture2DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// MAX_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter		= minFilterModes[minFilter].mode;
				testParameters.minFilterName	= minFilterModes[minFilter].name;
				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT);

				maxLevelGroup2D->addChild(new TextureTestCase<Texture2DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		// 2D VK_EXT_image_view_min_lod.
		{
			// MIN_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;

				imageViewMinLodGroup2D->addChild(new TextureTestCase<Texture2DImageViewMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));

				std::ostringstream name;
				name << minFilterModes[minFilter].name << "_integer_texel_coord";
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD;
				imageViewMinLodGroup2D->addChild(new Texture2DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
			}

			// BASE_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture2DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.minFilterName		= minFilterModes[minFilter].name;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_2D_FLOAT);
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;

				imageViewMinLodBaseLevelGroup2D->addChild(new TextureTestCase<Texture2DImageViewMinLodBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));

				std::ostringstream name;
				name << minFilterModes[minFilter].name << "_integer_texel_coord";
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD_BASELEVEL;
				imageViewMinLodBaseLevelGroup2D->addChild(new Texture2DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
			}

			imageViewMinLodExtGroup2D->addChild(imageViewMinLodGroup2D.release());
			imageViewMinLodExtGroup2D->addChild(imageViewMinLodBaseLevelGroup2D.release());
		}

		group2D->addChild(biasGroup2D.release());
		group2D->addChild(minLodGroup2D.release());
		group2D->addChild(maxLodGroup2D.release());
		group2D->addChild(baseLevelGroup2D.release());
		group2D->addChild(maxLevelGroup2D.release());
		group2D->addChild(imageViewMinLodExtGroup2D.release());

		textureMipmappingTests->addChild(group2D.release());
	}

	// Cubemap cases.
	{
		de::MovePtr<tcu::TestCaseGroup>	groupCube			(new tcu::TestCaseGroup(testCtx, "cubemap", "Cube Mipmap Filtering"));

		de::MovePtr<tcu::TestCaseGroup>	minLodGroupCube		(new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
		de::MovePtr<tcu::TestCaseGroup>	maxLodGroupCube		(new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
		de::MovePtr<tcu::TestCaseGroup>	baseLevelGroupCube	(new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
		de::MovePtr<tcu::TestCaseGroup>	maxLevelGroupCube	(new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));

		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodExtGroupCube	(new tcu::TestCaseGroup(testCtx, "image_view_min_lod", "VK_EXT_image_view_min_lod tests"));
		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodGroupCube	(new tcu::TestCaseGroup(testCtx, "min_lod", "ImageView's minLod"));
		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodBaseLevelGroupCube	(new tcu::TestCaseGroup(testCtx, "base_level", "ImageView's minLod with base level different than one"));

		for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
		{
			de::MovePtr<tcu::TestCaseGroup>	coordTypeGroup	(new tcu::TestCaseGroup(testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc));

			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				for (int magFilter = 0; magFilter < DE_LENGTH_OF_ARRAY(magFilterModes); magFilter++)
				{
					for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
					{
						TextureCubeMipmapTestCaseParameters	testParameters;

						testParameters.coordType		= cubeCoordTypes[coordType].type;
						testParameters.minFilter		= minFilterModes[minFilter].mode;
						testParameters.magFilter		= magFilterModes[magFilter].mode;
						testParameters.minFilterName	= minFilterModes[minFilter].name;
						testParameters.wrapS			= wrapModes[wrapMode].mode;
						testParameters.wrapT			= wrapModes[wrapMode].mode;
						testParameters.format			= VK_FORMAT_R8G8B8A8_UNORM;
						testParameters.size				= cubeMapSize;
						testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;

						if (testParameters.coordType == COORDTYPE_BASIC_BIAS)
							testParameters.programs.push_back(PROGRAM_CUBE_FLOAT_BIAS);
						else
							testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);

						std::ostringstream name;
						name << minFilterModes[minFilter].name
							 << "_" << magFilterModes[magFilter].name
							 << "_" << wrapModes[wrapMode].name;

						coordTypeGroup->addChild(new TextureTestCase<TextureCubeMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
					}
				}
			}

			groupCube->addChild(coordTypeGroup.release());
		}

		// Cubemap LOD controls.
		{
			// MIN_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				TextureCubeMipmapTestCaseParameters	testParameters;
				testParameters.minFilter	= minFilterModes[minFilter].mode;
				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);

				minLodGroupCube->addChild(new TextureTestCase<TextureCubeMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// MAX_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				TextureCubeMipmapTestCaseParameters	testParameters;
				testParameters.minFilter	= minFilterModes[minFilter].mode;
				testParameters.aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);

				maxLodGroupCube->addChild(new TextureTestCase<TextureCubeMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		{
			// BASE_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				TextureCubeMipmapTestCaseParameters	testParameters;
				testParameters.minFilter		= minFilterModes[minFilter].mode;
				testParameters.minFilterName	= minFilterModes[minFilter].name;
				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);

				baseLevelGroupCube->addChild(new TextureTestCase<TextureCubeBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// MAX_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				TextureCubeMipmapTestCaseParameters	testParameters;
				testParameters.minFilter		= minFilterModes[minFilter].mode;
				testParameters.minFilterName	= minFilterModes[minFilter].name;
				testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);

				maxLevelGroupCube->addChild(new TextureTestCase<TextureCubeMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		// Cube VK_EXT_image_view_min_lod.
		{
			// MIN_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				TextureCubeMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;

				imageViewMinLodGroupCube->addChild(new TextureTestCase<TextureCubeImageViewMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// BASE_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				TextureCubeMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.minFilterName		= minFilterModes[minFilter].name;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;

				imageViewMinLodBaseLevelGroupCube->addChild(new TextureTestCase<TextureCubeImageViewMinLodBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			imageViewMinLodExtGroupCube->addChild(imageViewMinLodGroupCube.release());
			imageViewMinLodExtGroupCube->addChild(imageViewMinLodBaseLevelGroupCube.release());
		}

		groupCube->addChild(minLodGroupCube.release());
		groupCube->addChild(maxLodGroupCube.release());
		groupCube->addChild(baseLevelGroupCube.release());
		groupCube->addChild(maxLevelGroupCube.release());
		groupCube->addChild(imageViewMinLodExtGroupCube.release());

		textureMipmappingTests->addChild(groupCube.release());
	}

	// 3D cases.
	{
		de::MovePtr<tcu::TestCaseGroup>	group3D				(new tcu::TestCaseGroup(testCtx, "3d", "3D Mipmap Filtering"));

		de::MovePtr<tcu::TestCaseGroup>	biasGroup3D			(new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value"));
		de::MovePtr<tcu::TestCaseGroup>	minLodGroup3D		(new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
		de::MovePtr<tcu::TestCaseGroup>	maxLodGroup3D		(new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
		de::MovePtr<tcu::TestCaseGroup>	baseLevelGroup3D	(new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
		de::MovePtr<tcu::TestCaseGroup>	maxLevelGroup3D		(new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));

		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodExtGroup3D	(new tcu::TestCaseGroup(testCtx, "image_view_min_lod", "VK_EXT_image_view_min_lod tests"));
		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodGroup3D	(new tcu::TestCaseGroup(testCtx, "min_lod", "ImageView's minLod"));
		de::MovePtr<tcu::TestCaseGroup> imageViewMinLodBaseLevelGroup3D	(new tcu::TestCaseGroup(testCtx, "base_level", "ImageView's minLod with base level different than one"));

		for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
		{
			de::MovePtr<tcu::TestCaseGroup>	coordTypeGroup	(new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc));

			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
				{
					// Add other size variants to basic cases only.
					int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex3DSizes) : 1;

					Texture3DMipmapTestCaseParameters	testParameters;

					testParameters.coordType		= coordTypes[coordType].type;
					testParameters.minFilter		= minFilterModes[minFilter].mode;
					testParameters.minFilterName	= minFilterModes[minFilter].name;
					testParameters.wrapR			= wrapModes[wrapMode].mode;
					testParameters.wrapS			= wrapModes[wrapMode].mode;
					testParameters.wrapT			= wrapModes[wrapMode].mode;
					testParameters.format			= VK_FORMAT_R8G8B8A8_UNORM;
					testParameters.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
					testParameters.programs.push_back(PROGRAM_3D_FLOAT);

					for (int size = 0; size < sizeEnd; size++)
					{
						testParameters.width			= tex3DSizes[size].width;
						testParameters.height			= tex3DSizes[size].height;
						testParameters.depth			= tex3DSizes[size].depth;

						std::ostringstream name;
						name << minFilterModes[minFilter].name
							 << "_" << wrapModes[wrapMode].name;

						if (tex3DSizes[size].name)
							name << "_" << tex3DSizes[size].name;

						coordTypeGroup->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
					}
				}
			}

			group3D->addChild(coordTypeGroup.release());
		}

		// 3D bias variants.
		{
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.coordType			= COORDTYPE_BASIC_BIAS;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.wrapR				= Sampler::REPEAT_GL;
				testParameters.wrapS				= Sampler::REPEAT_GL;
				testParameters.wrapT				= Sampler::REPEAT_GL;
				testParameters.format				= VK_FORMAT_R8G8B8A8_UNORM;
				testParameters.width				= tex3DSizes[0].width;
				testParameters.height				= tex3DSizes[0].height;
				testParameters.depth				= tex3DSizes[0].depth;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT_BIAS);

				biasGroup3D->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		// 3D LOD controls.
		{
			// MIN_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT);

				minLodGroup3D->addChild(new TextureTestCase<Texture3DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// MAX_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT);

				maxLodGroup3D->addChild(new TextureTestCase<Texture3DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		{
			// BASE_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.minFilterName		= minFilterModes[minFilter].name;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT);

				baseLevelGroup3D->addChild(new TextureTestCase<Texture3DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}

			// MAX_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter			= minFilterModes[minFilter].mode;
				testParameters.minFilterName		= minFilterModes[minFilter].name;
				testParameters.aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT);

				maxLevelGroup3D->addChild(new TextureTestCase<Texture3DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
			}
		}

		// 3D VK_EXT_image_view_min_lod.
		{
			// MIN_LOD
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter				= minFilterModes[minFilter].mode;
				testParameters.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;

				imageViewMinLodGroup3D->addChild(new TextureTestCase<Texture3DImageViewMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));

				std::ostringstream name;
				name << minFilterModes[minFilter].name << "_integer_texel_coord";
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD;
				imageViewMinLodGroup3D->addChild(new Texture3DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
			}

			// BASE_LEVEL
			for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
			{
				Texture3DMipmapTestCaseParameters	testParameters;
				testParameters.minFilter				= minFilterModes[minFilter].mode;
				testParameters.minFilterName			= minFilterModes[minFilter].name;
				testParameters.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
				testParameters.programs.push_back(PROGRAM_3D_FLOAT);
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;


				imageViewMinLodBaseLevelGroup3D->addChild(new TextureTestCase<Texture3DImageViewMinLodBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));

				std::ostringstream name;
				name << minFilterModes[minFilter].name << "_integer_texel_coord";
				testParameters.testType				= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD_BASELEVEL;
				imageViewMinLodBaseLevelGroup3D->addChild(new Texture3DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
			}

			imageViewMinLodExtGroup3D->addChild(imageViewMinLodGroup3D.release());
			imageViewMinLodExtGroup3D->addChild(imageViewMinLodBaseLevelGroup3D.release());
		}

		group3D->addChild(biasGroup3D.release());
		group3D->addChild(minLodGroup3D.release());
		group3D->addChild(maxLodGroup3D.release());
		group3D->addChild(baseLevelGroup3D.release());
		group3D->addChild(maxLevelGroup3D.release());
		group3D->addChild(imageViewMinLodExtGroup3D.release());

		textureMipmappingTests->addChild(group3D.release());
	}
}

tcu::TestCaseGroup* createTextureMipmappingTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "mipmap", "Texture mipmapping tests.", populateTextureMipmappingTests);
}

} // texture
} // vkt
