/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Texture filtering tests with explicit LOD instructions
 *//*--------------------------------------------------------------------*/

#include "vktTextureFilteringExplicitLodTests.hpp"

#include "vkDefs.hpp"

#include "vktSampleVerifier.hpp"
#include "vktShaderExecutor.hpp"
#include "vktTestCaseUtil.hpp"

#include "vkDeviceUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkPlatform.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkStrUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkCmdUtil.hpp"

#include "tcuTexLookupVerifier.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVector.hpp"

#include "deClock.h"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include "deSharedPtr.hpp"

#include <sstream>
#include <string>
#include <vector>

namespace vkt
{
namespace texture
{

using namespace tcu;
using namespace vk;
using std::string;

namespace
{

std::vector<de::SharedPtr<tcu::FloatFormat>> getPrecision (VkFormat format, int fpPrecisionDelta)
{
	std::vector<de::SharedPtr<tcu::FloatFormat>>	floatFormats;
	de::SharedPtr<tcu::FloatFormat>					fp16			(new tcu::FloatFormat(-14, 15, std::max(0, 10 + fpPrecisionDelta), false, tcu::YES));
	de::SharedPtr<tcu::FloatFormat>					fp32			(new tcu::FloatFormat(-126, 127, std::max(0, 23 + fpPrecisionDelta), true));
	const tcu::TextureFormat						tcuFormat		= mapVkFormat(format);
	const tcu::TextureChannelClass					channelClass	= tcu::getTextureChannelClass(tcuFormat.type);
	const tcu::IVec4								channelDepth	= tcu::getTextureFormatBitDepth(tcuFormat);

	for (int channelIdx = 0; channelIdx < 4; channelIdx++)
	{
		switch(channelClass)
		{
			case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
				floatFormats.push_back(de::SharedPtr<tcu::FloatFormat>(new tcu::NormalizedFormat(std::max(0,channelDepth[channelIdx] + fpPrecisionDelta - 1))));
				break;

			case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				floatFormats.push_back(de::SharedPtr<tcu::FloatFormat>(new tcu::NormalizedFormat(std::max(0,channelDepth[channelIdx] + fpPrecisionDelta))));
				break;

			case TEXTURECHANNELCLASS_FLOATING_POINT:
				if (channelDepth[channelIdx] == 16)
				{
					floatFormats.push_back(fp16);
				}
				else
				{
					DE_ASSERT(channelDepth[channelIdx] == 32 || channelDepth[channelIdx] == 0);
					floatFormats.push_back(fp32);
				}
				break;

			default:
				DE_FATAL("Unexpected channel class.");
			break;
		};
	}

	return floatFormats;
}

using namespace shaderexecutor;

string genSamplerDeclaration(const ImageViewParameters& imParams,
							 const SamplerParameters&	samplerParams)
{
	string result = "sampler";

	switch (imParams.dim)
	{
		case IMG_DIM_1D:
			result += "1D";
			break;

		case IMG_DIM_2D:
			result += "2D";
			break;

		case IMG_DIM_3D:
			result += "3D";
			break;

		case IMG_DIM_CUBE:
			result += "Cube";
			break;

		default:
			break;
	}

	if (imParams.isArrayed)
	{
		result += "Array";
	}

	if (samplerParams.isCompare)
	{
		result += "Shadow";
	}

	return result;
}

string genLookupCode(const ImageViewParameters&		imParams,
					 const SamplerParameters&		samplerParams,
					 const SampleLookupSettings&	lookupSettings)
{
	int dim = -1;

	switch (imParams.dim)
	{
		case IMG_DIM_1D:
			dim = 1;
			break;

		case IMG_DIM_2D:
			dim = 2;
			break;

		case IMG_DIM_3D:
			dim = 3;
			break;

		case IMG_DIM_CUBE:
			dim = 3;
			break;

		default:
			dim = 0;
			break;
	}

	DE_ASSERT(dim >= 1 && dim <= 3);

	int numCoordComp = dim;

	if (lookupSettings.isProjective)
	{
		++numCoordComp;
	}

	int numArgComp = numCoordComp;
	bool hasSeparateCompare = false;

	if (imParams.isArrayed)
	{
		DE_ASSERT(!lookupSettings.isProjective && "Can't do a projective lookup on an arrayed image!");

		++numArgComp;
	}

	if (samplerParams.isCompare && numCoordComp == 4)
	{
		hasSeparateCompare = true;
	}
	else if (samplerParams.isCompare)
	{
		++numArgComp;
	}

	// Build coordinate input to texture*() function

	string arg	= "vec";
	arg += (char) (numArgComp + '0');
	arg += "(vec";
	arg += (char) (numCoordComp + '0');
	arg += "(coord)";

    int numZero = numArgComp - numCoordComp;

	if (imParams.isArrayed)
	{
		arg += ", layer";
		--numZero;
	}

	if (samplerParams.isCompare && !hasSeparateCompare)
	{
		arg += ", dRef";
		--numZero;
	}

	for (int ndx = 0; ndx < numZero; ++ndx)
	{
		arg += ", 0.0";
	}

	arg += ")";

	// Build call to texture*() function

	string code;

	code += "result = texture";

	if (lookupSettings.isProjective)
	{
		code += "Proj";
	}

	if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES)
	{
		code += "Grad";
	}
	else if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_LOD)
	{
		code += "Lod";
	}

	code += "(testSampler, ";
	code += arg;

	if (samplerParams.isCompare && hasSeparateCompare)
	{
		code += ", dRef";
	}

	if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES)
	{
		code += ", vec";
		code += (char) (numCoordComp + '0');
		code += "(dPdx), ";
		code += "vec";
		code += (char) (numCoordComp + '0');
		code += "(dPdy)";
	}
	else if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_LOD)
	{
		code += ", lod";
	}

	code += ");";

	return code;
}

void initializeImage(Context& ctx, VkImage im, const ConstPixelBufferAccess* pba, ImageViewParameters imParams)
{
	const DeviceInterface& vkd = ctx.getDeviceInterface();
	const VkDevice dev = ctx.getDevice();
	const deUint32 uqfi = ctx.getUniversalQueueFamilyIndex();

	const VkDeviceSize bufSize =
		getPixelSize(mapVkFormat(imParams.format))
		* imParams.arrayLayers
		* imParams.size[0]
		* imParams.size[1]
		* imParams.size[2]
		* 2;

    const VkBufferCreateInfo bufCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
		DE_NULL,								// pNext
		0,										// flags
		bufSize,								// size
		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// usage
		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
		1,										// queueFamilyIndexCount
		&uqfi									// pQueueFamilyIndices
	};

	Unique<VkBuffer> buf(createBuffer(vkd, dev, &bufCreateInfo));

	VkMemoryRequirements bufMemReq;
	vkd.getBufferMemoryRequirements(dev, buf.get(), &bufMemReq);

	de::UniquePtr<Allocation> bufMem(ctx.getDefaultAllocator().allocate(bufMemReq, MemoryRequirement::HostVisible));
	VK_CHECK(vkd.bindBufferMemory(dev, buf.get(), bufMem->getMemory(), bufMem->getOffset()));

	std::vector<VkBufferImageCopy> copyRegions;

	deUint8* const bufMapPtr = reinterpret_cast<deUint8*>(bufMem->getHostPtr());
	deUint8* bufCurPtr = bufMapPtr;

	for (int level = 0; level < imParams.levels; ++level)
	{
		const IVec3 curLevelSize = pba[level].getSize();

		const std::size_t copySize =
			getPixelSize(mapVkFormat(imParams.format))
			* curLevelSize[0] * curLevelSize[1] * curLevelSize[2]
			* imParams.arrayLayers;

		deMemcpy(bufCurPtr, pba[level].getDataPtr(), copySize);

		const VkImageSubresourceLayers curSubresource =
		{
			VK_IMAGE_ASPECT_COLOR_BIT,
			(deUint32)level,
			0,
			(deUint32)imParams.arrayLayers
		};

		const VkBufferImageCopy curRegion =
		{
			(VkDeviceSize) (bufCurPtr - bufMapPtr),
			0,
			0,
			curSubresource,
			{0U, 0U, 0U},
			{(deUint32)curLevelSize[0], (deUint32)curLevelSize[1], (deUint32)curLevelSize[2]}
		};

		copyRegions.push_back(curRegion);

		bufCurPtr += copySize;
	}

	flushAlloc(vkd, dev, *bufMem);

	copyBufferToImage(vkd, dev, ctx.getUniversalQueue(), ctx.getUniversalQueueFamilyIndex(), buf.get(), bufSize, copyRegions, DE_NULL, VK_IMAGE_ASPECT_COLOR_BIT, imParams.levels, imParams.arrayLayers, im);
}

struct TestCaseData
{
	std::vector<ConstPixelBufferAccess>	pba;
	ImageViewParameters					imParams;
	SamplerParameters					samplerParams;
	SampleLookupSettings				sampleLookupSettings;
	glu::ShaderType						shaderType;
};

VkSamplerCreateInfo mapSamplerCreateInfo (const SamplerParameters& samplerParams)
{
	VkSamplerCreateInfo samplerCreateInfo =
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,				// sType
		DE_NULL,											// pNext
		0U,													// flags
	    samplerParams.magFilter,							// magFilter
		samplerParams.minFilter,							// minFilter
		samplerParams.mipmapFilter,							// mipmapMode
	    samplerParams.wrappingModeU,						// addressModeU
	    samplerParams.wrappingModeV,						// addressModeV
	    samplerParams.wrappingModeW,						// addressMoveW
		samplerParams.lodBias,								// mipLodBias
		VK_FALSE,											// anisotropyEnable
		1.0f,												// maxAnisotropy
		VK_FALSE,											// compareEnable
		VK_COMPARE_OP_NEVER,								// compareOp
		samplerParams.minLod,								// minLod
		samplerParams.maxLod,								// maxLod
	    samplerParams.borderColor,							// borderColor
		samplerParams.isUnnormalized ? VK_TRUE : VK_FALSE,	// unnormalizedCoordinates
	};

	if (samplerParams.isCompare)
	{
		samplerCreateInfo.compareEnable = VK_TRUE;

	    DE_FATAL("Not implemented");
	}

	return samplerCreateInfo;
}

VkImageType mapImageType (ImgDim dim)
{
	VkImageType imType;

	switch (dim)
	{
		case IMG_DIM_1D:
			imType = VK_IMAGE_TYPE_1D;
			break;

		case IMG_DIM_2D:
		case IMG_DIM_CUBE:
			imType = VK_IMAGE_TYPE_2D;
			break;

		case IMG_DIM_3D:
			imType = VK_IMAGE_TYPE_3D;
			break;

		default:
			imType = VK_IMAGE_TYPE_LAST;
			break;
	}

	return imType;
}

VkImageViewType mapImageViewType (const ImageViewParameters& imParams)
{
	VkImageViewType imViewType;

	if (imParams.isArrayed)
	{
		switch (imParams.dim)
		{
			case IMG_DIM_1D:
				imViewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
				break;

			case IMG_DIM_2D:
				imViewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
				break;

			case IMG_DIM_CUBE:
				imViewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
				break;

			default:
				imViewType = VK_IMAGE_VIEW_TYPE_LAST;
				break;
		}
	}
	else
	{
		switch (imParams.dim)
		{
			case IMG_DIM_1D:
				imViewType = VK_IMAGE_VIEW_TYPE_1D;
				break;

			case IMG_DIM_2D:
				imViewType = VK_IMAGE_VIEW_TYPE_2D;
				break;

			case IMG_DIM_3D:
				imViewType = VK_IMAGE_VIEW_TYPE_3D;
				break;

			case IMG_DIM_CUBE:
				imViewType = VK_IMAGE_VIEW_TYPE_CUBE;
				break;

			default:
				imViewType = VK_IMAGE_VIEW_TYPE_LAST;
				break;
		}
	}

	return imViewType;
}

class DataGenerator
{
public:
	virtual										~DataGenerator	(void) {}

	virtual bool								generate		(void) = 0;

	virtual std::vector<ConstPixelBufferAccess> getPba			(void) const = 0;
	virtual std::vector<SampleArguments>		getSampleArgs	(void) const = 0;

protected:
												DataGenerator	(void) {}
};

class TextureFilteringTestInstance : public TestInstance
{
public:
										TextureFilteringTestInstance	(Context&					ctx,
																		 const TestCaseData&		testCaseData,
																		 const ShaderSpec&			shaderSpec,
																		 de::MovePtr<DataGenerator>	gen);

	virtual TestStatus					iterate							(void) { return runTest(); }

protected:
	TestStatus							runTest							(void);
	bool								isSupported						(void);
	void								createResources					(void);
	void								execute							(void);
	TestStatus							verify							(void);

	tcu::Sampler						mapTcuSampler					(void) const;

	const glu::ShaderType				m_shaderType;
	const ShaderSpec					m_shaderSpec;
	const ImageViewParameters			m_imParams;
	const SamplerParameters				m_samplerParams;
	const SampleLookupSettings			m_sampleLookupSettings;

	std::vector<SampleArguments>		m_sampleArguments;
	deUint32							m_numSamples;

	de::MovePtr<Allocation>				m_imAllocation;
	Move<VkImage>						m_im;
	Move<VkImageView>					m_imView;
	Move<VkSampler>						m_sampler;

	Move<VkDescriptorSetLayout>			m_extraResourcesLayout;
	Move<VkDescriptorPool>				m_extraResourcesPool;
	Move<VkDescriptorSet>				m_extraResourcesSet;

	de::MovePtr<ShaderExecutor>			m_executor;

	std::vector<ConstPixelBufferAccess> m_levels;
	de::MovePtr<DataGenerator>			m_gen;

	std::vector<Vec4>					m_resultSamples;
	std::vector<Vec4>					m_resultCoords;
};

TextureFilteringTestInstance::TextureFilteringTestInstance (Context&					ctx,
															const TestCaseData&			testCaseData,
															const ShaderSpec&			shaderSpec,
															de::MovePtr<DataGenerator>	gen)
	: TestInstance				(ctx)
	, m_shaderType				(testCaseData.shaderType)
	, m_shaderSpec				(shaderSpec)
	, m_imParams				(testCaseData.imParams)
	, m_samplerParams			(testCaseData.samplerParams)
	, m_sampleLookupSettings	(testCaseData.sampleLookupSettings)
	, m_levels					(testCaseData.pba)
	, m_gen						(gen.release())
{
	for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
		DE_ASSERT(m_imParams.size[compNdx] > 0);
}

TestStatus TextureFilteringTestInstance::runTest (void)
{
	if (!isSupported())
	    TCU_THROW(NotSupportedError, "Unsupported combination of filtering and image format");

	TCU_CHECK(m_gen->generate());
	m_levels = m_gen->getPba();

	m_sampleArguments = m_gen->getSampleArgs();
	m_numSamples = (deUint32)m_sampleArguments.size();

	createResources();
	initializeImage(m_context, m_im.get(), &m_levels[0], m_imParams);

	deUint64 startTime, endTime;

	startTime = deGetMicroseconds();
	execute();
	endTime = deGetMicroseconds();

	m_context.getTestContext().getLog() << TestLog::Message
										<< "Execution time: "
										<< endTime - startTime
										<< "us"
										<< TestLog::EndMessage;

    startTime = deGetMicroseconds();
	TestStatus result = verify();
    endTime = deGetMicroseconds();

	m_context.getTestContext().getLog() << TestLog::Message
										<< "Verification time: "
										<< endTime - startTime
										<< "us"
										<< TestLog::EndMessage;

	return result;
}

TestStatus TextureFilteringTestInstance::verify (void)
{
	// \todo [2016-06-24 collinbaker] Handle cubemaps

	const int										coordBits			= (int)m_context.getDeviceProperties().limits.subTexelPrecisionBits;
	const int										mipmapBits			= (int)m_context.getDeviceProperties().limits.mipmapPrecisionBits;
	const int										maxPrintedFailures	= 5;
	int												failCount			= 0;
	int												warningCount		= 0;
	const tcu::TextureFormat						tcuFormat			= mapVkFormat(m_imParams.format);
	std::vector<de::SharedPtr<tcu::FloatFormat>>	strictPrecision		= getPrecision(m_imParams.format, 0);
	std::vector<de::SharedPtr<tcu::FloatFormat>>	relaxedPrecision	= tcuFormat.type == tcu::TextureFormat::HALF_FLOAT ? getPrecision(m_imParams.format, -6) : getPrecision(m_imParams.format, -2);
	const bool										allowRelaxedPrecision	= (tcuFormat.type == tcu::TextureFormat::HALF_FLOAT || tcuFormat.type == tcu::TextureFormat::SNORM_INT8) &&
		(m_samplerParams.minFilter == VK_FILTER_LINEAR || m_samplerParams.magFilter == VK_FILTER_LINEAR);

	const SampleVerifier			verifier			(m_imParams,
														 m_samplerParams,
														 m_sampleLookupSettings,
														 coordBits,
														 mipmapBits,
														 strictPrecision,
														 strictPrecision,
														 m_levels);

	const SampleVerifier			relaxedVerifier		(m_imParams,
														 m_samplerParams,
														 m_sampleLookupSettings,
														 coordBits,
														 mipmapBits,
														 strictPrecision,
														 relaxedPrecision,
														 m_levels);

	for (deUint32 sampleNdx = 0; sampleNdx < m_numSamples; ++sampleNdx)
	{
		bool compareOK = verifier.verifySample(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx]);
		if (compareOK)
			continue;
		if (allowRelaxedPrecision)
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "Warning: Strict validation failed, re-trying with lower precision for SNORM8 format or half float"
				<< tcu::TestLog::EndMessage;

			compareOK = relaxedVerifier.verifySample(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx]);
			if (compareOK)
			{
				warningCount++;
				continue;
			}
		}
		if ( failCount++ < maxPrintedFailures )
		{
			// Re-run with report logging
			std::string report;
			verifier.verifySampleReport(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx], report);

			m_context.getTestContext().getLog()
				<< TestLog::Section("Failed sample", "Failed sample")
				<< TestLog::Message
				<< "Sample " << sampleNdx << ".\n"
				<< "\tCoordinate: " << m_sampleArguments[sampleNdx].coord << "\n"
				<< "\tLOD: " << m_sampleArguments[sampleNdx].lod << "\n"
				<< "\tGPU Result: " << m_resultSamples[sampleNdx] << "\n\n"
				<< "Failure report:\n" << report << "\n"
				<< TestLog::EndMessage
				<< TestLog::EndSection;
		}
	}

	m_context.getTestContext().getLog()
		<< TestLog::Message
		<< "Passed " << m_numSamples - failCount << " out of " << m_numSamples << "."
		<< TestLog::EndMessage;

	if (failCount > 0)
		return TestStatus::fail("Verification failed");
	else if (warningCount > 0)
		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Inaccurate filtering results");

	return TestStatus::pass("Success");
}

void TextureFilteringTestInstance::execute (void)
{
	std::vector<float> coords, layers, dRefs, dPdxs, dPdys, lods;

	for (deUint32 ndx = 0; ndx < m_numSamples; ++ndx)
	{
		const SampleArguments& sampleArgs = m_sampleArguments[ndx];

		for (deUint8 compNdx = 0; compNdx < 4; ++compNdx)
		{
			coords.push_back(sampleArgs.coord[compNdx]);
			dPdxs .push_back(sampleArgs.dPdx[compNdx]);
			dPdys .push_back(sampleArgs.dPdy[compNdx]);
		}

		layers.push_back(sampleArgs.layer);
		dRefs .push_back(sampleArgs.dRef);
		lods  .push_back(sampleArgs.lod);
	}

	const void* inputs[6] =
	{
		reinterpret_cast<const void*>(&coords[0]),
		reinterpret_cast<const void*>(&layers[0]),
		reinterpret_cast<const void*>(&dRefs[0]),
		reinterpret_cast<const void*>(&dPdxs[0]),
		reinterpret_cast<const void*>(&dPdys[0]),
		reinterpret_cast<const void*>(&lods[0])
	};

	// Staging buffers; data will be copied into vectors of Vec4
	// \todo [2016-06-24 collinbaker] Figure out if I actually need to
	// use staging buffers
	std::vector<float> resultSamplesTemp(m_numSamples * 4);
	std::vector<float> resultCoordsTemp (m_numSamples * 4);

	void* outputs[2] =
	{
		reinterpret_cast<void*>(&resultSamplesTemp[0]),
		reinterpret_cast<void*>(&resultCoordsTemp[0])
	};

	m_executor->execute(m_numSamples, inputs, outputs, *m_extraResourcesSet);

	m_resultSamples.resize(m_numSamples);
	m_resultCoords .resize(m_numSamples);

	for (deUint32 ndx = 0; ndx < m_numSamples; ++ndx)
	{
		m_resultSamples[ndx] = Vec4(resultSamplesTemp[4 * ndx + 0],
									resultSamplesTemp[4 * ndx + 1],
									resultSamplesTemp[4 * ndx + 2],
									resultSamplesTemp[4 * ndx + 3]);

		m_resultCoords [ndx] = Vec4(resultCoordsTemp [4 * ndx + 0],
									resultCoordsTemp [4 * ndx + 1],
									resultCoordsTemp [4 * ndx + 2],
									resultCoordsTemp [4 * ndx + 3]);
	}
}

void TextureFilteringTestInstance::createResources (void)
{
	// Create VkImage

	const DeviceInterface&		vkd				= m_context.getDeviceInterface();
	const VkDevice				device			= m_context.getDevice();

	const deUint32				queueFamily		= m_context.getUniversalQueueFamilyIndex();
	const VkImageCreateFlags	imCreateFlags	=(m_imParams.dim == IMG_DIM_CUBE) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;

	const VkImageCreateInfo		imCreateInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		DE_NULL,
		imCreateFlags,
	    mapImageType(m_imParams.dim),
	    m_imParams.format,
		makeExtent3D(m_imParams.size[0], m_imParams.size[1], m_imParams.size[2]),
	    (deUint32)m_imParams.levels,
	    (deUint32)m_imParams.arrayLayers,
		VK_SAMPLE_COUNT_1_BIT,
		VK_IMAGE_TILING_OPTIMAL,
		VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
		VK_SHARING_MODE_EXCLUSIVE,
		1,
		&queueFamily,
		VK_IMAGE_LAYOUT_UNDEFINED
	};

    m_im = createImage(vkd, device, &imCreateInfo);

	// Allocate memory for image

	VkMemoryRequirements imMemReq;
	vkd.getImageMemoryRequirements(device, m_im.get(), &imMemReq);

	m_imAllocation = m_context.getDefaultAllocator().allocate(imMemReq, MemoryRequirement::Any);
	VK_CHECK(vkd.bindImageMemory(device, m_im.get(), m_imAllocation->getMemory(), m_imAllocation->getOffset()));

	// Create VkImageView

	// \todo [2016-06-23 collinbaker] Pick aspectMask based on image type (i.e. support depth and/or stencil images)
	DE_ASSERT(m_imParams.dim != IMG_DIM_CUBE); // \todo Support cube maps
	const VkImageSubresourceRange imViewSubresourceRange =
	{
		VK_IMAGE_ASPECT_COLOR_BIT,			// aspectMask
		0,									// baseMipLevel
		(deUint32)m_imParams.levels,		// levelCount
		0,									// baseArrayLayer
		(deUint32)m_imParams.arrayLayers	// layerCount
	};

	const VkComponentMapping imViewCompMap =
	{
		VK_COMPONENT_SWIZZLE_R,
		VK_COMPONENT_SWIZZLE_G,
		VK_COMPONENT_SWIZZLE_B,
		VK_COMPONENT_SWIZZLE_A
	};

	const VkImageViewCreateInfo imViewCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// sType
		DE_NULL,									// pNext
		0,											// flags
		m_im.get(),									// image
		mapImageViewType(m_imParams),				// viewType
	    m_imParams.format,							// format
	    imViewCompMap,								// components
		imViewSubresourceRange						// subresourceRange
	};

	m_imView = createImageView(vkd, device, &imViewCreateInfo);

	// Create VkSampler

	const VkSamplerCreateInfo samplerCreateInfo = mapSamplerCreateInfo(m_samplerParams);
	m_sampler = createSampler(vkd, device, &samplerCreateInfo);

	// Create additional descriptors

	{
		const VkDescriptorSetLayoutBinding		bindings[]	=
		{
			{ 0u,	VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	1u,		VK_SHADER_STAGE_ALL,	DE_NULL		},
		};
		const VkDescriptorSetLayoutCreateInfo	layoutInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
			DE_NULL,
			(VkDescriptorSetLayoutCreateFlags)0u,
			DE_LENGTH_OF_ARRAY(bindings),
			bindings,
		};

		m_extraResourcesLayout = createDescriptorSetLayout(vkd, device, &layoutInfo);
	}

	{
		const VkDescriptorPoolSize			poolSizes[]	=
		{
			{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	1u	},
		};
		const VkDescriptorPoolCreateInfo	poolInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
			DE_NULL,
			(VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
			1u,		// maxSets
			DE_LENGTH_OF_ARRAY(poolSizes),
			poolSizes,
		};

		m_extraResourcesPool = createDescriptorPool(vkd, device, &poolInfo);
	}

	{
		const VkDescriptorSetAllocateInfo	allocInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
			DE_NULL,
			*m_extraResourcesPool,
			1u,
			&m_extraResourcesLayout.get(),
		};

		m_extraResourcesSet = allocateDescriptorSet(vkd, device, &allocInfo);
	}

	{
		const VkDescriptorImageInfo		imageInfo			=
		{
			*m_sampler,
			*m_imView,
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
		};
		const VkWriteDescriptorSet		descriptorWrite		=
		{
			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
			DE_NULL,
			*m_extraResourcesSet,
			0u,		// dstBinding
			0u,		// dstArrayElement
			1u,
			VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
			&imageInfo,
			(const VkDescriptorBufferInfo*)DE_NULL,
			(const VkBufferView*)DE_NULL,
		};

		vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
	}

	m_executor = de::MovePtr<ShaderExecutor>(createExecutor(m_context, m_shaderType, m_shaderSpec, *m_extraResourcesLayout));
}

VkFormatFeatureFlags getRequiredFormatFeatures (const SamplerParameters& samplerParams)
{
	VkFormatFeatureFlags	features	= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;

	if (samplerParams.minFilter	 == VK_FILTER_LINEAR ||
		samplerParams.magFilter	 == VK_FILTER_LINEAR ||
		samplerParams.mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
	{
		features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
	}

	return features;
}

bool TextureFilteringTestInstance::isSupported (void)
{
	const VkImageCreateFlags		imCreateFlags		= (m_imParams.dim == IMG_DIM_CUBE) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
	const VkFormatFeatureFlags		reqImFeatures		= getRequiredFormatFeatures(m_samplerParams);

	const VkImageFormatProperties	imFormatProperties	= getPhysicalDeviceImageFormatProperties(m_context.getInstanceInterface(),
																								 m_context.getPhysicalDevice(),
																								 m_imParams.format,
																								 mapImageType(m_imParams.dim),
																								 VK_IMAGE_TILING_OPTIMAL,
																								 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
																								 imCreateFlags);
	const VkFormatProperties		formatProperties	= getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(),
																							m_context.getPhysicalDevice(),
																							m_imParams.format);

	// \todo [2016-06-23 collinbaker] Check image parameters against imFormatProperties
	DE_UNREF(imFormatProperties);

	return (formatProperties.optimalTilingFeatures & reqImFeatures) == reqImFeatures;
}

class TextureFilteringTestCase : public TestCase
{
public:
	TextureFilteringTestCase (tcu::TestContext&	testCtx,
							  const char*		name,
							  const char*		description)
		: TestCase(testCtx, name, description)
	{
	}

	void initSpec (void);

	virtual void initPrograms (vk::SourceCollections& programCollection) const
	{
		generateSources(m_testCaseData.shaderType, m_shaderSpec, programCollection);
	}

	virtual de::MovePtr<DataGenerator> createGenerator (void) const = 0;

	virtual TestInstance* createInstance (Context& ctx) const
	{
		return new TextureFilteringTestInstance(ctx, m_testCaseData, m_shaderSpec, createGenerator());
	}

protected:
	de::MovePtr<ShaderExecutor> m_executor;
	TestCaseData				m_testCaseData;
	ShaderSpec					m_shaderSpec;
};

void TextureFilteringTestCase::initSpec (void)
{
	m_shaderSpec.source = genLookupCode(m_testCaseData.imParams,
										m_testCaseData.samplerParams,
										m_testCaseData.sampleLookupSettings);
	m_shaderSpec.source += "\nsampledCoord = coord;";

	m_shaderSpec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
	m_shaderSpec.outputs.push_back(Symbol("sampledCoord", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
	m_shaderSpec.inputs .push_back(Symbol("coord", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
	m_shaderSpec.inputs .push_back(Symbol("layer", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP)));
	m_shaderSpec.inputs .push_back(Symbol("dRef", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP)));
	m_shaderSpec.inputs .push_back(Symbol("dPdx", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
	m_shaderSpec.inputs .push_back(Symbol("dPdy", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
	m_shaderSpec.inputs .push_back(Symbol("lod", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP)));

	m_shaderSpec.globalDeclarations = "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=0) uniform highp ";
	m_shaderSpec.globalDeclarations += genSamplerDeclaration(m_testCaseData.imParams,
														   m_testCaseData.samplerParams);
	m_shaderSpec.globalDeclarations += " testSampler;";
}

class Texture2DGradientTestCase : public TextureFilteringTestCase
{
public:
	Texture2DGradientTestCase (TestContext&			testCtx,
							   const char*			name,
							   const char*			desc,
							   TextureFormat		format,
							   IVec3				dimensions,
							   VkFilter				magFilter,
							   VkFilter				minFilter,
							   VkSamplerMipmapMode	mipmapFilter,
							   VkSamplerAddressMode	wrappingMode,
							   bool					useDerivatives)

		: TextureFilteringTestCase	(testCtx, name, desc)
		, m_format					(format)
		, m_dimensions				(dimensions)
		, m_magFilter				(magFilter)
		, m_minFilter				(minFilter)
		, m_mipmapFilter			(mipmapFilter)
		, m_wrappingMode			(wrappingMode)
		, m_useDerivatives			(useDerivatives)
	{
		m_testCaseData = genTestCaseData();
		initSpec();
	}

protected:
	class Generator;

	virtual de::MovePtr<DataGenerator> createGenerator (void) const;

	TestCaseData genTestCaseData()
	{
		// Generate grid

		const SampleLookupSettings sampleLookupSettings =
		{
			m_useDerivatives ? LOOKUP_LOD_MODE_DERIVATIVES : LOOKUP_LOD_MODE_LOD, // lookupLodMode
			false, // hasLodBias
			false, // isProjective
		};

		const SamplerParameters samplerParameters =
		{
			m_magFilter,
			m_minFilter,
			m_mipmapFilter,
			m_wrappingMode,
			m_wrappingMode,
			m_wrappingMode,
			VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
			0.0f,
			-1.0f,
			50.0f,
			false,
			false
		};

		const deUint8 numLevels = (deUint8) (1 + deLog2Floor32(de::max(m_dimensions[0],
																	   m_dimensions[1])));

		const ImageViewParameters imParameters =
		{
			IMG_DIM_2D,
			mapTextureFormat(m_format),
			m_dimensions,
			numLevels,
			false,
			1,
		};

		const TestCaseData data =
		{
			std::vector<ConstPixelBufferAccess>(),
			imParameters,
			samplerParameters,
			sampleLookupSettings,
			glu::SHADERTYPE_FRAGMENT
		};

		return data;
	}

private:
	const TextureFormat			m_format;
	const IVec3					m_dimensions;
	const VkFilter				m_magFilter;
	const VkFilter				m_minFilter;
	const VkSamplerMipmapMode	m_mipmapFilter;
	const VkSamplerAddressMode	m_wrappingMode;
	const bool					m_useDerivatives;
};

class Texture2DGradientTestCase::Generator : public DataGenerator
{
public:
	Generator (const Texture2DGradientTestCase* testCase) : m_testCase(testCase) {}

	virtual ~Generator (void)
	{
		delete m_tex.release();
	}

	virtual bool generate (void)
	{
		m_tex = de::MovePtr<Texture2D>(new Texture2D(m_testCase->m_format,
													 m_testCase->m_dimensions[0],
													 m_testCase->m_dimensions[1]));

		const deUint8 numLevels = (deUint8) (1 + deLog2Floor32(de::max(m_testCase->m_dimensions[0],
																	   m_testCase->m_dimensions[1])));

		const TextureFormatInfo fmtInfo = getTextureFormatInfo(m_testCase->m_format);

		const Vec4 cBias  = fmtInfo.valueMin;
		const Vec4 cScale = fmtInfo.valueMax - fmtInfo.valueMin;

		for (deUint8 levelNdx = 0; levelNdx < numLevels; ++levelNdx)
		{
			const Vec4 gMin = Vec4(0.0f, 0.0f, 0.0f, 1.0f) * cScale + cBias;
			const Vec4 gMax = Vec4(1.0f, 1.0f, 1.0f, 0.0f) * cScale + cBias;

			m_tex->allocLevel(levelNdx);
			fillWithComponentGradients(m_tex->getLevel(levelNdx), gMin, gMax);
		}

		return true;
	}

	virtual std::vector<ConstPixelBufferAccess> getPba (void) const
	{
		std::vector<ConstPixelBufferAccess> pba;

		const deUint8 numLevels = (deUint8) m_tex->getNumLevels();

		for (deUint8 levelNdx = 0; levelNdx < numLevels; ++levelNdx)
		{
			pba.push_back(m_tex->getLevel(levelNdx));
		}

		return pba;
	}

	virtual std::vector<SampleArguments> getSampleArgs (void) const
	{
		std::vector<SampleArguments> args;

		if (m_testCase->m_useDerivatives)
		{
			struct
			{
				Vec4 dPdx;
				Vec4 dPdy;
			}
			derivativePairs[] =
			{
				{Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(0.0f, 0.0f, 0.0f, 0.0f)},
				{Vec4(1.0f, 1.0f, 1.0f, 0.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)},
				{Vec4(0.0f, 0.0f, 0.0f, 0.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)},
				{Vec4(1.0f, 1.0f, 1.0f, 0.0f), Vec4(0.0f, 0.0f, 0.0f, 0.0f)},
				{Vec4(2.0f, 2.0f, 2.0f, 0.0f), Vec4(2.0f, 2.0f, 2.0f, 0.0f)}
			};

			for (deInt32 i = 0; i < 2 * m_testCase->m_dimensions[0] + 1; ++i)
			{
				for (deInt32 j = 0; j < 2 * m_testCase->m_dimensions[1] + 1; ++j)
				{
				    for (deUint32 derivNdx = 0; derivNdx < DE_LENGTH_OF_ARRAY(derivativePairs); ++derivNdx)
					{
						SampleArguments cur = SampleArguments();
						cur.coord = Vec4((float)i / (float)(2 * m_testCase->m_dimensions[0]),
										 (float)j / (float)(2 * m_testCase->m_dimensions[1]),
										 0.0f, 0.0f);
						cur.dPdx = derivativePairs[derivNdx].dPdx;
						cur.dPdy = derivativePairs[derivNdx].dPdy;

						args.push_back(cur);
					}
				}
			}
		}
		else
		{
			const float lodList[] = {-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0};

			for (deInt32 i = 0; i < 2 * m_testCase->m_dimensions[0] + 1; ++i)
			{
				for (deInt32 j = 0; j < 2 * m_testCase->m_dimensions[1] + 1; ++j)
				{
					for (deUint32 lodNdx = 0; lodNdx < DE_LENGTH_OF_ARRAY(lodList); ++lodNdx)
					{
						SampleArguments cur = SampleArguments();
						cur.coord = Vec4((float)i / (float)(2 * m_testCase->m_dimensions[0]),
										 (float)j / (float)(2 * m_testCase->m_dimensions[1]),
										 0.0f, 0.0f);
						cur.lod = lodList[lodNdx];

						args.push_back(cur);
					}
				}
			}
		}

		return args;
	}

private:
	const Texture2DGradientTestCase*	m_testCase;
	de::MovePtr<Texture2D>				m_tex;
};

de::MovePtr<DataGenerator> Texture2DGradientTestCase::createGenerator (void) const
{
	return de::MovePtr<DataGenerator>(new Generator(this));
}

TestCaseGroup* create2DFormatTests (TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> tests(
		new TestCaseGroup(testCtx, "formats", "Various image formats"));

    const VkFormat formats[] =
	{
	    VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
//		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
//		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
//		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
//		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
//		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32
	};

	const IVec3 size(32, 32, 1);

	for (deUint32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
	{
		const std::string prefix = de::toLower(std::string(getFormatName(formats[formatNdx])).substr(10));

		Texture2DGradientTestCase* testCaseNearest =
			new Texture2DGradientTestCase(
				testCtx,
			    (prefix + "_nearest").c_str(),
				"...",
				mapVkFormat(formats[formatNdx]),
				size,
				VK_FILTER_NEAREST,
				VK_FILTER_NEAREST,
				VK_SAMPLER_MIPMAP_MODE_NEAREST,
				VK_SAMPLER_ADDRESS_MODE_REPEAT,
				false);

		tests->addChild(testCaseNearest);

	    Texture2DGradientTestCase* testCaseLinear =
			new Texture2DGradientTestCase(
				testCtx,
			    (prefix + "_linear").c_str(),
				"...",
				mapVkFormat(formats[formatNdx]),
				size,
				VK_FILTER_LINEAR,
				VK_FILTER_LINEAR,
				VK_SAMPLER_MIPMAP_MODE_LINEAR,
				VK_SAMPLER_ADDRESS_MODE_REPEAT,
				false);

		tests->addChild(testCaseLinear);
	}

	return tests.release();
}

TestCaseGroup* create2DDerivTests (TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> tests(
		new TestCaseGroup(testCtx, "derivatives", "Explicit derivative tests"));

	const VkFormat				format		 = VK_FORMAT_R8G8B8A8_UNORM;
	const VkSamplerAddressMode	wrappingMode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
	const IVec3					size		 = IVec3(16, 16, 1);

	const VkFilter filters[2] =
	{
		VK_FILTER_NEAREST,
		VK_FILTER_LINEAR
	};

	const VkSamplerMipmapMode mipmapFilters[2] =
	{
		VK_SAMPLER_MIPMAP_MODE_NEAREST,
		VK_SAMPLER_MIPMAP_MODE_LINEAR,
	};

	for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(filters); ++magFilterNdx)
	{
		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(filters); ++minFilterNdx)
		{
			for (int mipmapFilterNdx = 0; mipmapFilterNdx < DE_LENGTH_OF_ARRAY(mipmapFilters); ++mipmapFilterNdx)
			{
				std::ostringstream caseName;

				switch (filters[magFilterNdx])
				{
					case VK_FILTER_NEAREST:
						caseName << "nearest";
						break;

					case VK_FILTER_LINEAR:
						caseName << "linear";
						break;

					default:
						break;
				}

				switch (filters[minFilterNdx])
				{
					case VK_FILTER_NEAREST:
						caseName << "_nearest";
						break;

					case VK_FILTER_LINEAR:
						caseName << "_linear";
						break;

					default:
						break;
				}

				caseName << "_mipmap";

				switch (mipmapFilters[mipmapFilterNdx])
				{
					case VK_SAMPLER_MIPMAP_MODE_NEAREST:
						caseName << "_nearest";
						break;

					case VK_SAMPLER_MIPMAP_MODE_LINEAR:
						caseName << "_linear";
						break;

					default:
						break;
				}

				Texture2DGradientTestCase* testCase =
					new Texture2DGradientTestCase(
						testCtx,
						caseName.str().c_str(),
						"...",
						mapVkFormat(format),
						size,
						filters[magFilterNdx],
						filters[minFilterNdx],
						mipmapFilters[mipmapFilterNdx],
						wrappingMode,
						true);

				tests->addChild(testCase);
			}
		}
	}

	return tests.release();
}

TestCaseGroup* create2DSizeTests (TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> tests(
		new TestCaseGroup(testCtx, "sizes", "Various size and filtering combinations"));

	const VkFilter filters[2] =
	{
		VK_FILTER_NEAREST,
		VK_FILTER_LINEAR
	};

	const VkSamplerMipmapMode mipmapFilters[2] =
	{
		VK_SAMPLER_MIPMAP_MODE_NEAREST,
		VK_SAMPLER_MIPMAP_MODE_LINEAR
	};

	const VkSamplerAddressMode wrappingModes[2] =
	{
		VK_SAMPLER_ADDRESS_MODE_REPEAT,
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
	};

	const IVec3 sizes[] =
	{
		IVec3(2, 2, 1),
		IVec3(2, 3, 1),
		IVec3(3, 7, 1),
		IVec3(4, 8, 1),
		IVec3(31, 55, 1),
		IVec3(32, 32, 1),
		IVec3(32, 64, 1),
		IVec3(57, 35, 1),
		IVec3(128, 128, 1)
	};


	for (deUint32 sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
	{
		for (deUint32 magFilterNdx = 0; magFilterNdx < 2; ++magFilterNdx)
		{
			for (deUint32 minFilterNdx = 0; minFilterNdx < 2; ++minFilterNdx)
			{
				for (deUint32 mipmapFilterNdx = 0; mipmapFilterNdx < 2; ++mipmapFilterNdx)
				{
					for (deUint32 wrappingModeNdx = 0; wrappingModeNdx < 2; ++wrappingModeNdx)
					{
						std::ostringstream caseName;

						caseName << sizes[sizeNdx][0] << "x" << sizes[sizeNdx][1];

						switch (filters[magFilterNdx])
						{
							case VK_FILTER_NEAREST:
								caseName << "_nearest";
								break;

							case VK_FILTER_LINEAR:
								caseName << "_linear";
								break;

							default:
								break;
						}

						switch (filters[minFilterNdx])
						{
							case VK_FILTER_NEAREST:
								caseName << "_nearest";
								break;

							case VK_FILTER_LINEAR:
								caseName << "_linear";
								break;

							default:
								break;
						}

						switch (mipmapFilters[mipmapFilterNdx])
						{
							case VK_SAMPLER_MIPMAP_MODE_NEAREST:
								caseName << "_mipmap_nearest";
								break;

							case VK_SAMPLER_MIPMAP_MODE_LINEAR:
								caseName << "_mipmap_linear";
								break;

							default:
								break;
						}

						switch (wrappingModes[wrappingModeNdx])
						{
							case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
								caseName << "_clamp";
								break;

							case VK_SAMPLER_ADDRESS_MODE_REPEAT:
								caseName << "_repeat";
								break;

							default:
								break;
						}

						Texture2DGradientTestCase* testCase =
							new Texture2DGradientTestCase(
								testCtx,
								caseName.str().c_str(),
								"...",
								mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM),
								sizes[sizeNdx],
								filters[magFilterNdx],
								filters[minFilterNdx],
								mipmapFilters[mipmapFilterNdx],
								wrappingModes[wrappingModeNdx],
								false);

						tests->addChild(testCase);
					}
				}
			}
		}
	}

	return tests.release();
}

TestCaseGroup* create2DTests (TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> tests(
		new TestCaseGroup(testCtx, "2d", "2D Image filtering tests"));

	tests->addChild(create2DSizeTests(testCtx));
	tests->addChild(create2DFormatTests(testCtx));
	tests->addChild(create2DDerivTests(testCtx));

	return tests.release();
}

} // anonymous

TestCaseGroup* createExplicitLodTests (TestContext& testCtx)
{
	de::MovePtr<TestCaseGroup> tests(
		new TestCaseGroup(testCtx, "explicit_lod", "Texture filtering with explicit LOD"));

	tests->addChild(create2DTests(testCtx));

	return tests.release();
}

} // texture
} // vkt
