/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Imagination Technologies Ltd.
 *
 * 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 Sampler Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineSamplerTests.hpp"
#include "vktPipelineImageSamplingInstance.hpp"
#ifndef CTS_USES_VULKANSC
#include "vktPipelineSamplerBorderSwizzleTests.hpp"
#endif // CTS_USES_VULKANSC
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktTestCase.hpp"

#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkPrograms.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBufferWithMemory.hpp"

#include "tcuPlatform.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuMaybe.hpp"

#include "deStringUtil.hpp"
#include "deMemory.h"

#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <memory>
#include <utility>
#include <algorithm>

namespace vkt
{
namespace pipeline
{

using namespace vk;
using de::MovePtr;

namespace
{

class SamplerViewType
{
public:
	SamplerViewType (vk::VkImageViewType type, bool normalized = true)
		: m_viewType(type), m_normalized(normalized)
	{
		if (!normalized)
			DE_ASSERT(type == vk::VK_IMAGE_VIEW_TYPE_2D || type == vk::VK_IMAGE_VIEW_TYPE_1D);
	}

	operator vk::VkImageViewType () const
	{
		return m_viewType;
	}

	bool isNormalized () const
	{
		return m_normalized;
	}

private:
	vk::VkImageViewType m_viewType;
	bool				m_normalized;
};

class SamplerTest : public vkt::TestCase
{
public:
										SamplerTest						(tcu::TestContext&	testContext,
																		 const char*		name,
																		 const char*		description,
																		 SamplerViewType	imageViewType,
																		 VkFormat			imageFormat,
																		 int				imageSize,
																		 float				samplerLod,
																		 bool				separateStencilUsage);
	virtual								~SamplerTest					(void) {}

	virtual ImageSamplingInstanceParams	getImageSamplingInstanceParams	(SamplerViewType	imageViewType,
																		 VkFormat			imageFormat,
																		 int				imageSize,
																		 float				samplerLod,
																		 bool				separateStencilUsage) const;

	tcu::Vec4							swizzle							(tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const;
	virtual void						initPrograms					(SourceCollections& sourceCollections) const;
	virtual void						checkSupport					(Context& context) const;
	virtual TestInstance*				createInstance					(Context& context) const;
	virtual tcu::UVec2					getRenderSize					(SamplerViewType viewType) const;
	virtual std::vector<Vertex4Tex4>	createVertices					(void) const;
	virtual VkSamplerCreateInfo			getSamplerCreateInfo			(void) const;
	virtual VkComponentMapping			getComponentMapping				(void) const;

	static std::string					getGlslSamplerType				(const tcu::TextureFormat& format, SamplerViewType type);
	static tcu::IVec3					getImageSize					(SamplerViewType viewType, int size);
	static int							getArraySize					(SamplerViewType viewType);

protected:
	SamplerViewType						m_imageViewType;
	VkFormat							m_imageFormat;
	int									m_imageSize;
	float								m_samplerLod;
	bool								m_separateStencilUsage;
};

class SamplerMagFilterTest : public SamplerTest
{
public:
									SamplerMagFilterTest	(tcu::TestContext&	testContext,
															 const char*		name,
															 const char*		description,
															 SamplerViewType	imageViewType,
															 VkFormat			imageFormat,
															 VkFilter			magFilter,
															 bool				separateStencilUsage);
	virtual							~SamplerMagFilterTest	(void) {}
	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;

private:
	VkFilter						m_magFilter;
};

class SamplerMinFilterTest : public SamplerTest
{
public:
									SamplerMinFilterTest	(tcu::TestContext&	testContext,
															 const char*		name,
															 const char*		description,
															 SamplerViewType	imageViewType,
															 VkFormat			imageFormat,
															 VkFilter			minFilter,
															 bool				separateStencilUsage);
	virtual							~SamplerMinFilterTest	(void) {}
	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;

private:
	VkFilter						m_minFilter;
};

class SamplerMagReduceFilterTest : public SamplerMagFilterTest
{
public:
												SamplerMagReduceFilterTest	(tcu::TestContext&			testContext,
																			const char*					name,
																			const char*					description,
																			SamplerViewType				imageViewType,
																			VkFormat					imageFormat,
																			VkComponentMapping			componentMapping,
																			VkSamplerReductionMode		reductionMode,
																			bool						separateStencilUsage);

	virtual										~SamplerMagReduceFilterTest	(void) {}
	virtual VkSamplerCreateInfo					getSamplerCreateInfo		(void) const;
	virtual VkComponentMapping					getComponentMapping			(void) const;

private:
	const VkSamplerReductionModeCreateInfo		m_reductionCreaterInfo;
	VkComponentMapping							m_componentMapping;
};

class SamplerMinReduceFilterTest : public SamplerMinFilterTest
{
public:
												SamplerMinReduceFilterTest	(tcu::TestContext&			testContext,
																			 const char*				name,
																			 const char*				description,
																			 SamplerViewType			imageViewType,
																			 VkFormat					imageFormat,
																			 VkComponentMapping			componentMapping,
																			 VkSamplerReductionMode		reductionMode,
																			 bool						separateStencilUsage);

	virtual										~SamplerMinReduceFilterTest	(void) {}
	virtual VkSamplerCreateInfo					getSamplerCreateInfo		(void) const;
	virtual VkComponentMapping					getComponentMapping			(void) const;

private:
	const VkSamplerReductionModeCreateInfo		m_reductionCreaterInfo;
	VkComponentMapping							m_componentMapping;
};

class SamplerLodTest : public SamplerTest
{
public:
									SamplerLodTest			(tcu::TestContext&		testContext,
															 const char*			name,
															 const char*			description,
															 SamplerViewType		imageViewType,
															 VkFormat				imageFormat,
															 VkSamplerMipmapMode	mipmapMode,
															 float					minLod,
															 float					maxLod,
															 float					mipLodBias,
															 float					samplerLod,
															 bool					separateStencilUsage);
	virtual							~SamplerLodTest			(void) {}
	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
	virtual void					checkSupport			(Context& context) const;

private:
	VkSamplerMipmapMode				m_mipmapMode;
	float							m_minLod;
	float							m_maxLod;
	float							m_mipLodBias;
};

void SamplerLodTest::checkSupport (Context& context) const
{
	SamplerTest::checkSupport(context);

#ifndef CTS_USES_VULKANSC
	if (m_mipLodBias != 0.0f && context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
		!context.getPortabilitySubsetFeatures().samplerMipLodBias)
	{
		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Sampler mipmap LOD bias is not supported by this implementation");
	}
#endif // CTS_USES_VULKANSC
}

class SamplerAddressModesTest : public SamplerTest
{
public:
										SamplerAddressModesTest		(tcu::TestContext&		testContext,
																	 const char*			name,
																	 const char*			description,
																	 SamplerViewType		imageViewType,
																	 VkFormat				imageFormat,
																	 VkSamplerAddressMode	addressU,
																	 VkSamplerAddressMode	addressV,
																	 VkSamplerAddressMode	addressW,
																	 VkBorderColor			borderColor,
																	 rr::GenericVec4		customBorderColorValue,
																	 bool					customBorderColorFormatless,
																	 bool					separateStencilUsage);
	virtual								~SamplerAddressModesTest	(void) {}
	virtual tcu::UVec2					getRenderSize				(SamplerViewType viewType) const;
	virtual std::vector<Vertex4Tex4>	createVertices				(void) const;
	virtual VkSamplerCreateInfo			getSamplerCreateInfo		(void) const;

	VkSamplerCustomBorderColorCreateInfoEXT	getSamplerCustomBorderColorCreateInfo	(VkFormat format, rr::GenericVec4 customBorderColorValue, bool customBorderColorFormatless) const;

private:
	VkSamplerAddressMode				m_addressU;
	VkSamplerAddressMode				m_addressV;
	VkSamplerAddressMode				m_addressW;
	VkBorderColor						m_borderColor;

	const VkSamplerCustomBorderColorCreateInfoEXT	m_customBorderColorCreateInfo;
};


// SamplerTest

SamplerTest::SamplerTest	(tcu::TestContext&	testContext,
							 const char*		name,
							 const char*		description,
							 SamplerViewType	imageViewType,
							 VkFormat			imageFormat,
							 int				imageSize,
							 float				samplerLod,
							 bool				separateStencilUsage)
	: vkt::TestCase					(testContext, name, description)
	, m_imageViewType				(imageViewType)
	, m_imageFormat					(imageFormat)
	, m_imageSize					(imageSize)
	, m_samplerLod					(samplerLod)
	, m_separateStencilUsage		(separateStencilUsage)
{
}

ImageSamplingInstanceParams SamplerTest::getImageSamplingInstanceParams (SamplerViewType	imageViewType,
																		 VkFormat			imageFormat,
																		 int				imageSize,
																		 float				samplerLod,
																		 bool				separateStencilUsage) const
{
	const tcu::UVec2				renderSize			= getRenderSize(imageViewType);
	const std::vector<Vertex4Tex4>	vertices			= createVertices();
	const VkSamplerCreateInfo		samplerParams		= getSamplerCreateInfo();
	const VkComponentMapping		componentMapping	= getComponentMapping();

	const VkImageAspectFlags		imageAspect			= (!isCompressedFormat(imageFormat) && hasDepthComponent(mapVkFormat(imageFormat).order)) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
	const deUint32					mipLevels			= (imageViewType.isNormalized() ? static_cast<deUint32>(deLog2Floor32(imageSize)) + 1u : 1u);

	const VkImageSubresourceRange	subresourceRange	=
	{
		imageAspect,										// VkImageAspectFlags	aspectMask;
		0u,													// deUint32				baseMipLevel;
		mipLevels,											// deUint32				mipLevels;
		0u,													// deUint32				baseArrayLayer;
		(deUint32)SamplerTest::getArraySize(imageViewType)	// deUint32				arraySize;
	};

	return ImageSamplingInstanceParams(renderSize, imageViewType, imageFormat,
									   getImageSize(imageViewType, imageSize),
									   getArraySize(imageViewType),
									   componentMapping, subresourceRange,
									   samplerParams, samplerLod, vertices, separateStencilUsage);
}

void SamplerTest::checkSupport (Context& context) const
{
	checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_samplerLod, m_separateStencilUsage));
}

tcu::Vec4 SamplerTest::swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const
{
	// Remove VK_COMPONENT_SWIZZLE_IDENTITY to avoid addressing channelValues[0]
	const vk::VkComponentMapping nonIdentityMapping =
	{
		componentMapping.r == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_R : componentMapping.r,
		componentMapping.g == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_G : componentMapping.g,
		componentMapping.b == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_B : componentMapping.b,
		componentMapping.a == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_A : componentMapping.a

	};
	// array map with enum VkComponentSwizzle
	const float channelValues[] =
	{
		-1.0f,					// impossible
		zeroOrOneValue,			// SWIZZLE_0
		zeroOrOneValue,			// SWIZZLE_1
		inputData.x(),
		inputData.y(),
		inputData.z(),
		inputData.w(),
		-1.0f
	};

	return tcu::Vec4(channelValues[nonIdentityMapping.r],
					 channelValues[nonIdentityMapping.g],
					 channelValues[nonIdentityMapping.b],
					 channelValues[nonIdentityMapping.a]);
}

void SamplerTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream				vertexSrc;
	std::ostringstream				fragmentSrc;
	const char*						texCoordSwizzle	= DE_NULL;
	tcu::TextureFormat				format			= (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
																						  : mapVkFormat(m_imageFormat);
	tcu::Vec4						lookupScale;
	tcu::Vec4						lookupBias;

	getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);

	tcu::Vec4						swizzledScale	= swizzle(lookupScale,	getComponentMapping(), 1.0f);
	tcu::Vec4						swizzledBias	= swizzle(lookupBias,	getComponentMapping(), 0.0f);

	switch (m_imageViewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D:
			texCoordSwizzle = "x";
			break;
		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
		case VK_IMAGE_VIEW_TYPE_2D:
			texCoordSwizzle = "xy";
			break;
		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
		case VK_IMAGE_VIEW_TYPE_3D:
		case VK_IMAGE_VIEW_TYPE_CUBE:
			texCoordSwizzle = "xyz";
			break;
		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			texCoordSwizzle = "xyzw";
			break;
		default:
			DE_ASSERT(false);
			break;
	}

	vertexSrc << "#version 440\n"
			  << "layout(location = 0) in vec4 position;\n"
			  << "layout(location = 1) in vec4 texCoords;\n"
			  << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
			  << "out gl_PerVertex {\n"
			  << "	vec4 gl_Position;\n"
			  << "};\n"
			  << "void main (void)\n"
			  << "{\n"
			  << "	gl_Position = position;\n"
			  << "	vtxTexCoords = texCoords;\n"
			  << "}\n";

	fragmentSrc << "#version 440\n"
				<< "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
				<< "layout(location = 0) in highp vec4 vtxTexCoords;\n"
				<< "layout(location = 0) out highp vec4 fragColor;\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "	fragColor = ";

	if (m_samplerLod > 0.0f || !m_imageViewType.isNormalized())
	{
		DE_ASSERT(m_imageViewType.isNormalized() || (m_samplerLod == 0.0f && !m_imageViewType.isNormalized()));
		fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed <<  m_samplerLod << ")";
	}
	else
	{
		fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
	}

	fragmentSrc << " * vec4" << std::scientific << swizzledScale << " + vec4" << swizzledBias << ";\n"
				<< "}\n";

	sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
	sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
}

TestInstance* SamplerTest::createInstance (Context& context) const
{
	return new ImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_samplerLod, m_separateStencilUsage));
}

tcu::UVec2 SamplerTest::getRenderSize (SamplerViewType viewType) const
{
	if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
	{
		return tcu::UVec2(16u, 16u);
	}
	else
	{
		return tcu::UVec2(16u * 3u, 16u * 2u);
	}
}

std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
{
	std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
	// Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
	// TODO: Would be nice to base this on number of texels and subtexel precision. But this
	// seems to work.
	for (unsigned int i = 0; i < vertices.size(); ++i) {
		vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
		if (!m_imageViewType.isNormalized()) {
			const float imageSize = static_cast<float>(m_imageSize);
			for (int j = 0; j < tcu::Vec4::SIZE; ++j)
				vertices[i].texCoord[j] *= imageSize;
		}
	}
	return vertices;
}

VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
{
	const VkSamplerCreateInfo defaultSamplerParams =
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,									// VkStructureType			sType;
		DE_NULL,																// const void*				pNext;
		0u,																		// VkSamplerCreateFlags		flags;
		VK_FILTER_NEAREST,														// VkFilter					magFilter;
		VK_FILTER_NEAREST,														// VkFilter					minFilter;
		VK_SAMPLER_MIPMAP_MODE_NEAREST,											// VkSamplerMipmapMode		mipmapMode;
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeU;
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeV;
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeW;
		0.0f,																	// float					mipLodBias;
		VK_FALSE,																// VkBool32					anisotropyEnable;
		1.0f,																	// float					maxAnisotropy;
		false,																	// VkBool32					compareEnable;
		VK_COMPARE_OP_NEVER,													// VkCompareOp				compareOp;
		0.0f,																	// float					minLod;
		(m_imageViewType.isNormalized() ? 0.25f : 0.0f),						// float					maxLod;
		getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat),	// VkBorderColor			borderColor;
		!m_imageViewType.isNormalized(),										// VkBool32					unnormalizedCoordinates;
	};

	return defaultSamplerParams;
}

VkComponentMapping SamplerTest::getComponentMapping (void) const
{
	const VkComponentMapping	componentMapping	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	return componentMapping;
}

std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type)
{
	std::ostringstream samplerType;

	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
		samplerType << "u";
	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
		samplerType << "i";

	switch (type)
	{
		case VK_IMAGE_VIEW_TYPE_1D:
			samplerType << "sampler1D";
			break;

		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
			samplerType << "sampler1DArray";
			break;

		case VK_IMAGE_VIEW_TYPE_2D:
			samplerType << "sampler2D";
			break;

		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
			samplerType << "sampler2DArray";
			break;

		case VK_IMAGE_VIEW_TYPE_3D:
			samplerType << "sampler3D";
			break;

		case VK_IMAGE_VIEW_TYPE_CUBE:
			samplerType << "samplerCube";
			break;

		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			samplerType << "samplerCubeArray";
			break;

		default:
			DE_FATAL("Unknown image view type");
			break;
	}

	return samplerType.str();
}

tcu::IVec3 SamplerTest::getImageSize (SamplerViewType viewType, int size)
{
	switch (viewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D:
		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
			return tcu::IVec3(size, 1, 1);

		case VK_IMAGE_VIEW_TYPE_3D:
			return tcu::IVec3(size, size, 4);

		default:
			break;
	}

	return tcu::IVec3(size, size, 1);
}

int SamplerTest::getArraySize (SamplerViewType viewType)
{
	switch (viewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
		case VK_IMAGE_VIEW_TYPE_CUBE:
			return 6;

		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			return 36;

		default:
			break;
	}

	return 1;
}


// SamplerMagFilterTest

SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext&	testContext,
											const char*			name,
											const char*			description,
											SamplerViewType		imageViewType,
											VkFormat			imageFormat,
											VkFilter			magFilter,
											bool				separateStencilUsage)
	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 8, 0.0f, separateStencilUsage)
	, m_magFilter	(magFilter)
{
}

VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
{
	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
	samplerParams.magFilter = m_magFilter;

	return samplerParams;
}


// SamplerMinFilterTest

SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext&	testContext,
											const char*			name,
											const char*			description,
											SamplerViewType		imageViewType,
											VkFormat			imageFormat,
											VkFilter			minFilter,
											bool				separateStencilUsage)
	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 32, 0.0f, separateStencilUsage)
	, m_minFilter	(minFilter)
{
}

VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
{
	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
	samplerParams.minFilter = m_minFilter;
	// set minLod to epsilon, to force use of the minFilter
	samplerParams.minLod = 0.01f;

	return samplerParams;
}


namespace
{

VkSamplerReductionModeCreateInfo getSamplerReductionCreateInfo (VkSamplerReductionMode reductionMode)
{
	const VkSamplerReductionModeCreateInfo ret =
	{
		VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,		// VkStructureType				sType
		DE_NULL,													// const void*					pNext
		reductionMode												// VkSamplerReductionMode		reductionMode
	};
	return ret;
}

}


// SamplerMagReduceFilterTest

SamplerMagReduceFilterTest::SamplerMagReduceFilterTest (tcu::TestContext&			testContext,
														const char*					name,
														const char*					description,
														SamplerViewType				imageViewType,
														VkFormat					imageFormat,
														VkComponentMapping			componentMapping,
														VkSamplerReductionMode		reductionMode,
														bool						separateStencilUsage)
	: SamplerMagFilterTest		(testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage)
	, m_reductionCreaterInfo	(getSamplerReductionCreateInfo(reductionMode))
	, m_componentMapping		(componentMapping)
{
}

VkSamplerCreateInfo SamplerMagReduceFilterTest::getSamplerCreateInfo (void) const
{
	VkSamplerCreateInfo samplerParams	= SamplerMagFilterTest::getSamplerCreateInfo();

	samplerParams.pNext					= &m_reductionCreaterInfo;

	return samplerParams;
}

VkComponentMapping SamplerMagReduceFilterTest::getComponentMapping (void) const
{
	return m_componentMapping;
}

// SamplerMinReduceFilterTest

SamplerMinReduceFilterTest::SamplerMinReduceFilterTest (tcu::TestContext&			testContext,
														const char*					name,
														const char*					description,
														SamplerViewType				imageViewType,
														VkFormat					imageFormat,
														VkComponentMapping			componentMapping,
														VkSamplerReductionMode		reductionMode,
														bool						separateStencilUsage)
	: SamplerMinFilterTest		(testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage)
	, m_reductionCreaterInfo	(getSamplerReductionCreateInfo(reductionMode))
	, m_componentMapping		(componentMapping)
{
}

VkSamplerCreateInfo SamplerMinReduceFilterTest::getSamplerCreateInfo (void) const
{
	VkSamplerCreateInfo samplerParams	= SamplerMinFilterTest::getSamplerCreateInfo();

	samplerParams.pNext					= &m_reductionCreaterInfo;

	return samplerParams;
}

VkComponentMapping SamplerMinReduceFilterTest::getComponentMapping (void) const
{
	return m_componentMapping;
}

// SamplerLodTest

SamplerLodTest::SamplerLodTest (tcu::TestContext&	testContext,
								const char*			name,
								const char*			description,
								SamplerViewType		imageViewType,
								VkFormat			imageFormat,
								VkSamplerMipmapMode	mipmapMode,
								float				minLod,
								float				maxLod,
								float				mipLodBias,
								float				samplerLod,
								bool				separateStencilUsage)
	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 32, samplerLod, separateStencilUsage)
	, m_mipmapMode	(mipmapMode)
	, m_minLod		(minLod)
	, m_maxLod		(maxLod)
	, m_mipLodBias	(mipLodBias)
{
}

VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
{
	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();

	samplerParams.mipmapMode	= m_mipmapMode;
	samplerParams.minLod		= m_minLod;
	samplerParams.maxLod		= m_maxLod;
	samplerParams.mipLodBias	= m_mipLodBias;

	return samplerParams;
}


// SamplerAddressModesTest

SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext&		testContext,
												  const char*			name,
												  const char*			description,
												  SamplerViewType		imageViewType,
												  VkFormat				imageFormat,
												  VkSamplerAddressMode	addressU,
												  VkSamplerAddressMode	addressV,
												  VkSamplerAddressMode	addressW,
												  VkBorderColor			borderColor,
												  rr::GenericVec4		customBorderColorValue,
												  bool					customBorderColorFormatless,
												  bool					separateStencilUsage)
	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 8, 0.0f, separateStencilUsage)
	, m_addressU	(addressU)
	, m_addressV	(addressV)
	, m_addressW	(addressW)
	, m_borderColor	(borderColor)
	, m_customBorderColorCreateInfo	(getSamplerCustomBorderColorCreateInfo(imageFormat, customBorderColorValue, customBorderColorFormatless))
{
}

tcu::UVec2 SamplerAddressModesTest::getRenderSize (SamplerViewType viewType) const
{
	return 4u * SamplerTest::getRenderSize(viewType);
}

std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
{
	std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();

	switch (m_imageViewType)
	{
		case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
				vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;

			break;

		case VK_IMAGE_VIEW_TYPE_2D:
		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
				vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;

			break;

		case VK_IMAGE_VIEW_TYPE_3D:
			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
				vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;

			break;

		case VK_IMAGE_VIEW_TYPE_CUBE:
		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
			break;

		default:
			DE_ASSERT(false);
	}

	return vertices;
}

VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
{
	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
	samplerParams.addressModeU	= m_addressU;
	samplerParams.addressModeV	= m_addressV;
	samplerParams.addressModeW	= m_addressW;
	samplerParams.borderColor	= m_borderColor;

	if (m_borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
		m_borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT)
	{
		samplerParams.pNext = &m_customBorderColorCreateInfo;
	}

	return samplerParams;
}

VkSamplerCustomBorderColorCreateInfoEXT	SamplerAddressModesTest::getSamplerCustomBorderColorCreateInfo	(VkFormat format, rr::GenericVec4 customBorderColorValue, bool customBorderColorFormatless) const
{
	const VkSamplerCustomBorderColorCreateInfoEXT defaultSamplerCustomBorderColorParams =
	{
		VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
		DE_NULL,
		mapVkColor(customBorderColorValue),
		customBorderColorFormatless ? VK_FORMAT_UNDEFINED : format
	};

	return defaultSamplerCustomBorderColorParams;
}


// Utilities to create test nodes

std::string getFormatCaseName (const VkFormat format)
{
	const std::string fullName = getFormatName(format);

	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));

	return de::toLower(fullName.substr(10));
}

MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
{
	MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));

	if (imageViewType.isNormalized() && (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat))))
		samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage));
	samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST, separateStencilUsage));

	return samplerMagFilterTests;
}

MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
{
	MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));

	if (imageViewType.isNormalized() && (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat))))
		samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage));
	samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST, separateStencilUsage));

	return samplerMinFilterTests;
}

const VkComponentMapping reduceFilterComponentMappings[]	=
{
	// filterMinmaxImageComponentMapping  == false - compatible mappings:
	{ VK_COMPONENT_SWIZZLE_IDENTITY,	VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,		VK_COMPONENT_SWIZZLE_ZERO	},
	{ VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,		VK_COMPONENT_SWIZZLE_ZERO	},

	// other mappings
	{ VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_B,			VK_COMPONENT_SWIZZLE_A		},
	{ VK_COMPONENT_SWIZZLE_B,			VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_A		},
	{ VK_COMPONENT_SWIZZLE_ONE,			VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_R		},
};

static std::string getShortComponentSwizzleName (VkComponentSwizzle componentSwizzle)
{
	const std::string	fullName	= getComponentSwizzleName(componentSwizzle);
	const char*			prefix		= "VK_COMPONENT_SWIZZLE_";

	DE_ASSERT(de::beginsWith(fullName, prefix));

	return de::toLower(fullName.substr(deStrnlen(prefix, -1)));
}

static std::string getComponentMappingGroupName (const VkComponentMapping& componentMapping)
{
	std::ostringstream name;

	name << "comp_";

	name << getShortComponentSwizzleName(componentMapping.r) << "_"
		 << getShortComponentSwizzleName(componentMapping.g) << "_"
		 << getShortComponentSwizzleName(componentMapping.b) << "_"
		 << getShortComponentSwizzleName(componentMapping.a);

	return name.str();
}

MovePtr<tcu::TestCaseGroup> createSamplerMagReduceFilterTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
{
	MovePtr<tcu::TestCaseGroup> samplerMagReduceFilterTests (new tcu::TestCaseGroup(testCtx, "mag_reduce", "Tests for magnification reduce filter"));

	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
	{
		const VkComponentMapping&	mapping		= reduceFilterComponentMappings[i];

		MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));

		if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
		{
			componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "average", "Magnifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, separateStencilUsage));
		}
		componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "min", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN, separateStencilUsage));
		componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "max", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX, separateStencilUsage));
		samplerMagReduceFilterTests->addChild(componentGroup.release());
	}
	return samplerMagReduceFilterTests;
}

MovePtr<tcu::TestCaseGroup> createSamplerMinReduceFilterTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
{
	MovePtr<tcu::TestCaseGroup> samplerMinReduceFilterTests (new tcu::TestCaseGroup(testCtx, "min_reduce", "Tests for minification reduce filter"));

	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
	{
		const VkComponentMapping&	mapping = reduceFilterComponentMappings[i];

		MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));

		if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
		{
			componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "average", "Minifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, separateStencilUsage));
		}
		componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "min", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN, separateStencilUsage));
		componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "max", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX, separateStencilUsage));
		samplerMinReduceFilterTests->addChild(componentGroup.release());
	}
	return samplerMinReduceFilterTests;
}

MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode, bool separateStencilUsage)
{
	struct TestCaseConfig
	{
		const char*	name;
		const char*	description;
		float		minLod;
		float		maxLod;
		float		mipLodBias;
		float		lod;
	};

	TestCaseConfig testCaseConfigs [] =
	{
		{ "equal_min_3_max_3",		"minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0",		3.0f, 3.0f, 0.0f, 0.0f },
		{ "select_min_1",			"minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0",		1.0f, 5.0f, 0.0f, 0.0f },
		{ "select_max_4",			"minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5",		0.0f, 4.0f, 0.0f, 5.0f },
		{ "select_bias_2_1",		"minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0",	0.0f, 2.1f, 5.0f, 0.0f },
		{ "select_bias_2_5",		"minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0",	0.0f, 5.0f, 2.5f, 0.00001f },
		{ "select_bias_3_1",		"minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0",	0.0f, 5.0f, -0.9f, 4.0f },
		{ "select_bias_3_7",		"minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7",	0.0f, 5.0f, 3.0f, 0.7f },
	};

	MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));

	for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
	{
		const TestCaseConfig& config = testCaseConfigs[configNdx];

		samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod, separateStencilUsage));
	}

	return samplerLodTests;
}

MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
{
	MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));

	// Mipmap mode: nearest
	MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
	mipmapNearestTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST, separateStencilUsage).release());
	samplerMipmapTests->addChild(mipmapNearestTests.release());

	// Mipmap mode: linear
	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
	{
		MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
		mipmapLinearTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR, separateStencilUsage).release());
		samplerMipmapTests->addChild(mipmapLinearTests.release());
	}

	return samplerMipmapTests;
}

std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border, tcu::IVec4 customIntValue, bool formatless)
{
	static const char* borderColorNames[BORDER_COLOR_COUNT] =
	{
		"opaque_black",
		"opaque_white",
		"transparent_black",
		"custom"
	};

	std::ostringstream caseName;

	if (u == v && v == w)
	{
		const std::string fullName = getSamplerAddressModeName(u);
		DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));

		caseName << "all_";
		caseName << de::toLower(fullName.substr(19));

		if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
		{
			caseName << "_" << borderColorNames[border];
		}
	}
	else
	{
		const std::string fullNameU = getSamplerAddressModeName(u);
		const std::string fullNameV = getSamplerAddressModeName(v);
		const std::string fullNameW = getSamplerAddressModeName(w);

		DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
		DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
		DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));

		caseName << "uvw"
				 << "_" << de::toLower(fullNameU.substr(19))
				 << "_" << de::toLower(fullNameV.substr(19))
				 << "_" << de::toLower(fullNameW.substr(19));
	}

	if (border == BORDER_COLOR_CUSTOM)
	{
		caseName << "_";
		for (int i = 0; i < 4; i++)
			caseName << customIntValue[i];

		if (formatless)
			caseName << "_formatless";

	}
	return caseName.str();
}

MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
{
	struct TestCaseConfig
	{
		TestCaseConfig	(VkSamplerAddressMode	_u,
						 VkSamplerAddressMode	_v,
						 VkSamplerAddressMode	_w,
						 BorderColor			_border,
						 bool					_customColorFormatless	= false,
						 tcu::Vec4				_customColorValueFloat	= tcu::Vec4(),
						 tcu::IVec4				_customColorValueInt	= tcu::IVec4())
			: u(_u), v(_v), w(_w), border(_border), customColorFormatless(_customColorFormatless)
			, customColorValueFloat(_customColorValueFloat), customColorValueInt(_customColorValueInt)
		{

		}

		VkSamplerAddressMode	u;
		VkSamplerAddressMode	v;
		VkSamplerAddressMode	w;
		BorderColor				border;
		bool					customColorFormatless;
		tcu::Vec4				customColorValueFloat;
		tcu::IVec4				customColorValueInt;
	};

	const TestCaseConfig testCaseConfigs[] =
	{
		// All address modes equal
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_TRANSPARENT_BLACK },
		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_TRANSPARENT_BLACK },
		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_TRANSPARENT_BLACK },
		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_TRANSPARENT_BLACK },

		// All address modes equal using border color
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_TRANSPARENT_BLACK },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_BLACK },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },

		// Pairwise combinations of address modes not covered by previous tests
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE},
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },

		// Custom border color tests
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			false,	tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),	tcu::IVec4(0, 0, 0, 0) },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			false,	tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),	tcu::IVec4(0, 0, 1, 1) },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			false,	tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),	tcu::IVec4(1, 0, 0, 0) },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			false,	tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),	tcu::IVec4(1, 0, 0, 1) },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			false,	tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),	tcu::IVec4(1, 0, 1, 1) },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			false,	tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),	tcu::IVec4(1, 1, 0, 1) },

		// Custom border color formatless
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			true,	tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),	tcu::IVec4(1, 0, 1, 1) },
		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_CUSTOM,
			true,	tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),	tcu::IVec4(1, 1, 0, 1) },
	};

	MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));

	for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
	{
		const TestCaseConfig& config = testCaseConfigs[configNdx];

		if (!imageViewType.isNormalized() &&
			((config.u != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE && config.u != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
			 (config.v != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE && config.v != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)))
			 continue;

		// VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_B5G6R5_UNORM_PACK16 and VK_FORMAT_B5G5R5A1_UNORM_PACK16 are forbidden
		// for non-formatless custom border color.
		if ((imageFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16 ||
			 imageFormat == VK_FORMAT_B5G6R5_UNORM_PACK16   ||
			 imageFormat == VK_FORMAT_B5G5R5A1_UNORM_PACK16)  && config.border == BORDER_COLOR_CUSTOM && config.customColorFormatless)
			continue;

		samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
																	   getAddressModesCaseName(config.u, config.v, config.w, config.border, config.customColorValueInt, config.customColorFormatless).c_str(),
																	   "",
																	   imageViewType,
																	   imageFormat,
																	   config.u, config.v, config.w,
																	   getFormatBorderColor(config.border, imageFormat),
																	   getFormatCustomBorderColor(config.customColorValueFloat, config.customColorValueInt, imageFormat),
																	   config.customColorFormatless,
																	   separateStencilUsage));
	}

	return samplerAddressModesTests;
}

// Exact sampling case:
//	1) Create a texture and a framebuffer image of the same size.
//	2) Draw a full screen quad with the texture and VK_FILTER_NEAREST.
//	3) Verify the rendered image matches the texture exactly.
class ExactSamplingCase : public vkt::TestCase
{
public:
	struct Params
	{
		vk::VkFormat		format;
		bool				unnormalizedCoordinates;
		bool				solidColor;
		tcu::Maybe<float>	offsetSign; // -1.0 or 1.0
	};

	struct PushConstants
	{
		float texWidth;
		float texHeight;
	};

	struct VertexData
	{
		tcu::Vec2 vtxCoords;
		tcu::Vec2 texCoords;

		static vk::VkVertexInputBindingDescription					getBindingDescription		(void);
		static std::vector<vk::VkVertexInputAttributeDescription>	getAttributeDescriptions	(void);
	};

									ExactSamplingCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params);
	virtual							~ExactSamplingCase		(void) {}

	virtual void					initPrograms			(vk::SourceCollections& programCollection) const;
	virtual TestInstance*			createInstance			(Context& context) const;
	virtual void					checkSupport			(Context& context) const;

private:
	Params m_params;
};

class ExactSamplingInstance : public vkt::TestInstance
{
public:
	using Params = ExactSamplingCase::Params;

								ExactSamplingInstance	(Context& context, const Params& params);
	virtual						~ExactSamplingInstance	(void) {}

	virtual tcu::TestStatus		iterate					(void);

	vk::VkExtent3D				getTextureExtent		(void) const;

private:
	Params m_params;
};

vk::VkVertexInputBindingDescription ExactSamplingCase::VertexData::getBindingDescription (void)
{
	static const vk::VkVertexInputBindingDescription desc =
	{
		0u,																// deUint32				binding;
		static_cast<deUint32>(sizeof(ExactSamplingCase::VertexData)),	// deUint32				stride;
		vk::VK_VERTEX_INPUT_RATE_VERTEX,								// VkVertexInputRate	inputRate;
	};

	return desc;
}

std::vector<vk::VkVertexInputAttributeDescription> ExactSamplingCase::VertexData::getAttributeDescriptions (void)
{
	static const std::vector<vk::VkVertexInputAttributeDescription> desc =
	{
		{
			0u,																			// deUint32	location;
			0u,																			// deUint32	binding;
			vk::VK_FORMAT_R32G32_SFLOAT,												// VkFormat	format;
			static_cast<deUint32>(offsetof(ExactSamplingCase::VertexData, vtxCoords)),	// deUint32	offset;
		},
		{
			1u,																			// deUint32	location;
			0u,																			// deUint32	binding;
			vk::VK_FORMAT_R32G32_SFLOAT,												// VkFormat	format;
			static_cast<deUint32>(offsetof(ExactSamplingCase::VertexData, texCoords)),	// deUint32	offset;
		},
	};

	return desc;
}


ExactSamplingCase::ExactSamplingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params)
	: vkt::TestCase{testCtx, name, description}, m_params(params)
{
}

void ExactSamplingCase::initPrograms (vk::SourceCollections& programCollection) const
{
	std::ostringstream vertexShader;

	std::string texCoordX = "inTexCoord.x";
	std::string texCoordY = "inTexCoord.y";

	if (m_params.unnormalizedCoordinates)
	{
		texCoordX += " * pushc.texWidth";
		texCoordY += " * pushc.texHeight";
	}

	vertexShader
		<< "#version 450\n"
		<< "\n"
		<< "layout(push_constant, std430) uniform PushConstants\n"
		<< "{\n"
		<< "    float texWidth;\n"
		<< "    float texHeight;\n"
		<< "} pushc;\n"
		<< "\n"
		<< "layout(location = 0) in vec2 inPosition;\n"
		<< "layout(location = 1) in vec2 inTexCoord;\n"
		<< "\n"
		<< "layout(location = 0) out vec2 fragTexCoord;\n"
		<< "\n"
		<< "void main() {\n"
		<< "    gl_Position = vec4(inPosition, 0.0, 1.0);\n"
		<< "    fragTexCoord = vec2(" << texCoordX << ", " << texCoordY << ");\n"
		<< "}\n"
		;

	programCollection.glslSources.add("vert") << glu::VertexSource{vertexShader.str()};

	std::ostringstream fragmentShader;

	std::string typePrefix;
	if (vk::isIntFormat(m_params.format))
		typePrefix = "i";
	else if (vk::isUintFormat(m_params.format))
		typePrefix = "u";

	const std::string samplerType = typePrefix + "sampler2D";
	const std::string colorType = typePrefix + "vec4";

	fragmentShader
		<< "#version 450\n"
		<< "\n"
		<< "layout(set = 0, binding = 0) uniform " << samplerType << " texSampler;\n"
		<< "\n"
		<< "layout(location = 0) in vec2 fragTexCoord;\n"
		<< "\n"
		<< "layout(location = 0) out " << colorType << " outColor;\n"
		<< "\n"
		<< "void main() {\n";

	if (m_params.unnormalizedCoordinates)
	{
		fragmentShader << "    outColor = textureLod(texSampler, fragTexCoord, 0.0f);";
	}
	else
	{
		fragmentShader << "    outColor = texture(texSampler, fragTexCoord);\n";
	}

	fragmentShader << "}\n";

	programCollection.glslSources.add("frag") << glu::FragmentSource{fragmentShader.str()};
}

TestInstance* ExactSamplingCase::createInstance (Context& context) const
{
	return new ExactSamplingInstance{context, m_params};
}

void ExactSamplingCase::checkSupport (Context& context) const
{
	const auto&						vki					= context.getInstanceInterface();
	const auto						physicalDevice		= context.getPhysicalDevice();
	const auto						props				= vk::getPhysicalDeviceFormatProperties(vki, physicalDevice, m_params.format);
	const vk::VkFormatFeatureFlags	requiredFeatures	=
		(vk::VK_FORMAT_FEATURE_TRANSFER_DST_BIT
		|vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
		|vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
		|vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
		|(m_params.solidColor ? vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT : 0)
		);

	if ((props.optimalTilingFeatures & requiredFeatures) != requiredFeatures)
		TCU_THROW(NotSupportedError, "Selected format does not support the required features");
}

ExactSamplingInstance::ExactSamplingInstance (Context& context, const Params& params)
	: vkt::TestInstance{context}, m_params(params)
{
}

vk::VkExtent3D ExactSamplingInstance::getTextureExtent (void) const
{
	return vk::makeExtent3D(256u, 256u, 1u);
}

tcu::TestStatus ExactSamplingInstance::iterate (void)
{
	const auto&	vkd			= m_context.getDeviceInterface();
	const auto	device		= m_context.getDevice();
	auto&		allocator	= m_context.getDefaultAllocator();
	const auto	queue		= m_context.getUniversalQueue();
	const auto	queueIndex	= m_context.getUniversalQueueFamilyIndex();

	const auto	tcuFormat	= vk::mapVkFormat(m_params.format);
	const auto	formatInfo	= tcu::getTextureFormatInfo(tcuFormat);
	const auto	texExtent	= getTextureExtent();
	const auto	texUsage	= (vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT);
	const auto	fbUsage		= (vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
	const auto	descType	= vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
	const auto	texLayout	= vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
	const bool&	unnorm		= m_params.unnormalizedCoordinates;

	// Some code below depends on this.
	DE_ASSERT(texExtent.depth == 1u);

	const vk::VkImageCreateInfo texImgCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
		nullptr,									// const void*				pNext;
		0u,											// VkImageCreateFlags		flags;
		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType;
		m_params.format,							// VkFormat					format;
		texExtent,									// VkExtent3D				extent;
		1u,											// deUint32					mipLevels;
		1u,											// deUint32					arrayLayers;
		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
		texUsage,									// VkImageUsageFlags		usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
		1u,											// deUint32					queueFamilyIndexCount;
		&queueIndex,								// const deUint32*			pQueueFamilyIndices;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			initialLayout;
	};

	const vk::VkImageCreateInfo fbImgCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
		nullptr,									// const void*				pNext;
		0u,											// VkImageCreateFlags		flags;
		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType;
		m_params.format,							// VkFormat					format;
		texExtent,									// VkExtent3D				extent;
		1u,											// deUint32					mipLevels;
		1u,											// deUint32					arrayLayers;
		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
		fbUsage,									// VkImageUsageFlags		usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
		1u,											// deUint32					queueFamilyIndexCount;
		&queueIndex,								// const deUint32*			pQueueFamilyIndices;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			initialLayout;
	};

	// Create main and framebuffer images.
	const vk::ImageWithMemory texImage	{vkd, device, allocator, texImgCreateInfo,	vk::MemoryRequirement::Any};
	const vk::ImageWithMemory fbImage	{vkd, device, allocator, fbImgCreateInfo,	vk::MemoryRequirement::Any};

	// Corresponding image views.
	const auto colorSubresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto texView					= vk::makeImageView(vkd, device, texImage.get(),	vk::VK_IMAGE_VIEW_TYPE_2D, m_params.format, colorSubresourceRange);
	const auto fbView					= vk::makeImageView(vkd, device, fbImage.get(),		vk::VK_IMAGE_VIEW_TYPE_2D, m_params.format, colorSubresourceRange);

	// Buffers to create the texture and verify results.
	const vk::VkDeviceSize		texBufferSize		= static_cast<vk::VkDeviceSize>(static_cast<deUint32>(tcu::getPixelSize(tcuFormat)) * texExtent.width * texExtent.height * texExtent.depth);
	const auto					texBufferInfo		= vk::makeBufferCreateInfo(texBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	const auto					resultsBufferInfo	= vk::makeBufferCreateInfo(texBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const vk::BufferWithMemory	texBuffer			{vkd, device, allocator, texBufferInfo, vk::MemoryRequirement::HostVisible};
	const vk::BufferWithMemory	resultsBuffer		{vkd, device, allocator, resultsBufferInfo, vk::MemoryRequirement::HostVisible};

	// Create texture.
	const tcu::IVec2					iImgSize		{static_cast<int>(texExtent.width), static_cast<int>(texExtent.height)};
	auto&								texBufferAlloc	= texBuffer.getAllocation();
	auto								texBufferPtr	= reinterpret_cast<char*>(texBufferAlloc.getHostPtr()) + texBufferAlloc.getOffset();
	const tcu::PixelBufferAccess		texPixels		{tcuFormat, iImgSize[0], iImgSize[1], 1, texBufferPtr};

	const int W = texPixels.getWidth();
	const int H = texPixels.getHeight();
	const int D = texPixels.getDepth();

	const float divX = static_cast<float>(W - 1);
	const float divY = static_cast<float>(H - 1);

	tcu::Vec4 texColor;

	for (int x = 0; x < W; ++x)
	for (int y = 0; y < H; ++y)
	for (int z = 0; z < D; ++z)
	{
		if (m_params.solidColor)
		{
			// Texture with solid color for filtered sampling.
			texColor = tcu::Vec4{0.5f, 0.25f, 0.7529411764705882f, 1.0f};
		}
		else
		{
			// Use a color gradient otherwise.
			const float colorX = static_cast<float>(x) / divX;
			const float colorY = static_cast<float>(y) / divY;
			const float colorZ = std::min(colorX, colorY);

			texColor = tcu::Vec4{colorX, colorY, colorZ, 1.0f};
		}
		const tcu::Vec4 finalColor = (texColor - formatInfo.lookupBias) / formatInfo.lookupScale;
		texPixels.setPixel(finalColor, x, y, z);
	}

	vk::flushAlloc(vkd, device, texBufferAlloc);

	float minU = 0.0f;
	float maxU = 1.0f;
	float minV = 0.0f;
	float maxV = 1.0f;

	// When testing the edges, apply a texture offset of almost half a texel, so the sample location is very close to the texel border.
	if (m_params.offsetSign)
	{
		const float sign			= m_params.offsetSign.get(); DE_ASSERT(sign == 1.0f || sign == -1.0f);
		const float offsetWidth		= 0.499f / static_cast<float>(texExtent.width);
		const float offsetHeight	= 0.499f / static_cast<float>(texExtent.height);

		minU += sign * offsetWidth;
		maxU += sign * offsetWidth;
		minV += sign * offsetHeight;
		maxV += sign * offsetHeight;
	}

	const std::vector<ExactSamplingCase::VertexData> fullScreenQuad =
	{
		{{  1.f, -1.f }, { maxU, minV }, },
		{{ -1.f, -1.f }, { minU, minV }, },
		{{ -1.f,  1.f }, { minU, maxV }, },
		{{ -1.f,  1.f }, { minU, maxV }, },
		{{  1.f, -1.f }, { maxU, minV }, },
		{{  1.f,  1.f }, { maxU, maxV }, },
	};

	// Vertex buffer.
	const vk::VkDeviceSize		vertexBufferSize	= static_cast<vk::VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
	const auto					vertexBufferInfo	= vk::makeBufferCreateInfo(vertexBufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
	const vk::BufferWithMemory	vertexBuffer		{vkd, device, allocator, vertexBufferInfo, vk::MemoryRequirement::HostVisible};

	// Copy data to vertex buffer.
	const auto&	vertexAlloc		= vertexBuffer.getAllocation();
	const auto	vertexDataPtr	= reinterpret_cast<char*>(vertexAlloc.getHostPtr()) + vertexAlloc.getOffset();
	deMemcpy(vertexDataPtr, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
	vk::flushAlloc(vkd, device, vertexAlloc);

	// Descriptor set layout.
	vk::DescriptorSetLayoutBuilder layoutBuilder;
	layoutBuilder.addSingleBinding(descType, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
	const auto descriptorSetLayout = layoutBuilder.build(vkd, device);

	// Descriptor pool.
	vk::DescriptorPoolBuilder poolBuilder;
	poolBuilder.addType(descType);
	const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	// Descriptor set.
	const auto descriptorSet = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());

	// Texture sampler. When using a solid color, test linear filtering. Linear filtering may incur in a small precission loss, but
	// it should be minimal and we should get the same color when converting back to the original format.
	const auto	minMagFilter			= (m_params.solidColor ? vk::VK_FILTER_LINEAR : vk::VK_FILTER_NEAREST);
	const auto	addressMode				= (unnorm ? vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : vk::VK_SAMPLER_ADDRESS_MODE_REPEAT);
	const auto	unnormalizedCoordinates	= (unnorm ? VK_TRUE : VK_FALSE);

	const vk::VkSamplerCreateInfo samplerCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType		sType;
		nullptr,										// const void*			pNext;
		0u,												// VkSamplerCreateFlags	flags;
		minMagFilter,									// VkFilter				magFilter;
		minMagFilter,									// VkFilter				minFilter;
		vk::VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode	mipmapMode;
		addressMode,									// VkSamplerAddressMode	addressModeU;
		addressMode,									// VkSamplerAddressMode	addressModeV;
		addressMode,									// VkSamplerAddressMode	addressModeW;
		0.0f,											// float				mipLodBias;
		VK_FALSE,										// VkBool32				anisotropyEnable;
		1.0f,											// float				maxAnisotropy;
		VK_FALSE,										// VkBool32				compareEnable;
		vk::VK_COMPARE_OP_NEVER,						// VkCompareOp			compareOp;
		0.0f,											// float				minLod;
		0.0f,											// float				maxLod;
		vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor		borderColor;
		unnormalizedCoordinates,						// VkBool32				unnormalizedCoordinates;
	};
	const auto texSampler = vk::createSampler(vkd, device, &samplerCreateInfo);

	// Update descriptor set with the descriptor.
	vk::DescriptorSetUpdateBuilder updateBuilder;
	const auto descriptorImageInfo = vk::makeDescriptorImageInfo(texSampler.get(), texView.get(), texLayout);
	updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), descType, &descriptorImageInfo);
	updateBuilder.update(vkd, device);

	// Shader modules.
	const auto vertexModule	= vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
	const auto fragModule	= vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);

	// Render pass.
	const vk::VkAttachmentDescription fbAttachment =
	{
		0u,												// VkAttachmentDescriptionFlags	flags;
		m_params.format,								// VkFormat						format;
		vk::VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits		samples;
		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp			loadOp;
		vk::VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp			storeOp;
		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp			stencilLoadOp;
		vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp			stencilStoreOp;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout				initialLayout;
		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout				finalLayout;
	};

	const vk::VkAttachmentReference colorRef =
	{
		0u,												// deUint32			attachment;
		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout	layout;
	};

	const vk::VkSubpassDescription subpass =
	{
		0u,										// VkSubpassDescriptionFlags		flags;
		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint				pipelineBindPoint;
		0u,										// deUint32							inputAttachmentCount;
		nullptr,								// const VkAttachmentReference*		pInputAttachments;
		1u,										// deUint32							colorAttachmentCount;
		&colorRef,								// const VkAttachmentReference*		pColorAttachments;
		0u,										// const VkAttachmentReference*		pResolveAttachments;
		nullptr,								// const VkAttachmentReference*		pDepthStencilAttachment;
		0u,										// deUint32							preserveAttachmentCount;
		nullptr,								// const deUint32*					pPreserveAttachments;
	};

	const vk::VkRenderPassCreateInfo renderPassInfo =
	{
		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
		nullptr,										// const void*						pNext;
		0u,												// VkRenderPassCreateFlags			flags;
		1u,												// deUint32							attachmentCount;
		&fbAttachment,									// const VkAttachmentDescription*	pAttachments;
		1u,												// deUint32							subpassCount;
		&subpass,										// const VkSubpassDescription*		pSubpasses;
		0u,												// deUint32							dependencyCount;
		nullptr,										// const VkSubpassDependency*		pDependencies;
	};
	const auto renderPass = vk::createRenderPass(vkd, device, &renderPassInfo);

	// Framebuffer.
	std::vector<vk::VkImageView> attachments;
	attachments.push_back(fbView.get());
	const auto framebuffer = vk::makeFramebuffer(vkd, device, renderPass.get(), 1u, &fbView.get(), texExtent.width, texExtent.height, texExtent.depth);

	// Push constant range.
	const vk::VkPushConstantRange pcRange =
	{
		vk::VK_SHADER_STAGE_VERTEX_BIT,										// VkShaderStageFlags	stageFlags;
		0u,																	// deUint32				offset;
		static_cast<deUint32>(sizeof(ExactSamplingCase::PushConstants)),	// deUint32				size;
	};

	// Pipeline layout.
	const vk::VkPipelineLayoutCreateInfo pipelineLayoutInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
		nullptr,											// const void*						pNext;
		0u,													// VkPipelineLayoutCreateFlags		flags;
		1u,													// deUint32							setLayoutCount;
		&descriptorSetLayout.get(),							// const VkDescriptorSetLayout*		pSetLayouts;
		1u,													// deUint32							pushConstantRangeCount;
		&pcRange,											// const VkPushConstantRange*		pPushConstantRanges;
	};
	const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);

	// Graphics pipeline.
	const std::vector<vk::VkViewport>	viewports	(1u, vk::makeViewport(texExtent));
	const vk::VkRect2D					renderArea	= vk::makeRect2D(texExtent);
	const std::vector<vk::VkRect2D>		scissors	(1u, renderArea);

	const auto vtxBindingDescription	= ExactSamplingCase::VertexData::getBindingDescription();
	const auto vtxAttributeDescriptions	= ExactSamplingCase::VertexData::getAttributeDescriptions();

	const vk::VkPipelineVertexInputStateCreateInfo vertexInputInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType
		nullptr,														// const void*                                 pNext
		0u,																// VkPipelineVertexInputStateCreateFlags       flags
		1u,																// deUint32                                    vertexBindingDescriptionCount
		&vtxBindingDescription,											// const VkVertexInputBindingDescription*      pVertexBindingDescriptions
		static_cast<deUint32>(vtxAttributeDescriptions.size()),			// deUint32                                    vertexAttributeDescriptionCount
		vtxAttributeDescriptions.data(),								// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
	};

	const auto pipeline = vk::makeGraphicsPipeline(
		vkd, device, pipelineLayout.get(),
		vertexModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(),
		renderPass.get(), viewports, scissors,
		vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u, &vertexInputInfo);

	// Command pool and command buffer.
	const auto cmdPool		= vk::createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueIndex);
	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	// Draw quad.
	const ExactSamplingCase::PushConstants pushConstants =
	{
		static_cast<float>(texExtent.width),
		static_cast<float>(texExtent.height),
	};

	const tcu::Vec4			clearFbColor		(0.0f, 0.0f, 0.0f, 1.0f);
	const vk::VkDeviceSize	vertexBufferOffset	= 0ull;

	const auto vertexBufferBarrier	= vk::makeBufferMemoryBarrier(vk::VK_ACCESS_HOST_WRITE_BIT, vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, vertexBuffer.get(), 0ull, vertexBufferSize);
	const auto preBufferCopyBarrier	= vk::makeBufferMemoryBarrier(vk::VK_ACCESS_HOST_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, texBuffer.get(), 0ull, texBufferSize);
	const auto preTexCopyBarrier	= vk::makeImageMemoryBarrier(0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texImage.get(), colorSubresourceRange);
	const auto postTexCopyBarrier	= vk::makeImageMemoryBarrier(vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texLayout, texImage.get(), colorSubresourceRange);
	const auto texCopyRange			= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const auto texImageCopy			= vk::makeBufferImageCopy(texExtent, texCopyRange);

	vk::beginCommandBuffer(vkd, cmdBuffer);

	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0u, 0u, nullptr, 1u, &vertexBufferBarrier, 0u, nullptr);
	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 1u, &preBufferCopyBarrier, 0u, nullptr);
	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &preTexCopyBarrier);
	vkd.cmdCopyBufferToImage(cmdBuffer, texBuffer.get(), texImage.get(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &texImageCopy);
	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &postTexCopyBarrier);

	vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), renderArea, clearFbColor);
	vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
	vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), vk::VK_SHADER_STAGE_VERTEX_BIT, 0u, static_cast<deUint32>(sizeof(pushConstants)), &pushConstants);
	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
	vk::endRenderPass(vkd, cmdBuffer);

	vk::copyImageToBuffer(vkd, cmdBuffer, fbImage.get(), resultsBuffer.get(), iImgSize);

	vk::endCommandBuffer(vkd, cmdBuffer);
	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Check results.
	const auto& resultsBufferAlloc = resultsBuffer.getAllocation();
	vk::invalidateAlloc(vkd, device, resultsBufferAlloc);

	const auto							resultsBufferPtr	= reinterpret_cast<const char*>(resultsBufferAlloc.getHostPtr()) + resultsBufferAlloc.getOffset();
	const tcu::ConstPixelBufferAccess	resultPixels		{tcuFormat, iImgSize[0], iImgSize[1], 1, resultsBufferPtr};

	const tcu::TextureFormat			diffFormat			{tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
	const auto							diffBytes			= tcu::getPixelSize(diffFormat) * iImgSize[0] * iImgSize[1];
	std::unique_ptr<deUint8[]>			diffData			{new deUint8[diffBytes]};
	const tcu::PixelBufferAccess		diffImg				{diffFormat, iImgSize[0], iImgSize[1], 1, diffData.get()};

	const tcu::Vec4						colorRed			{1.0f, 0.0f, 0.0f, 1.0f};
	const tcu::Vec4						colorGreen			{0.0f, 1.0f, 0.0f, 1.0f};

	// Clear diff image.
	deMemset(diffData.get(), 0, static_cast<size_t>(diffBytes));

	bool pass = true;
	for (int x = 0; x < W; ++x)
	for (int y = 0; y < H; ++y)
	for (int z = 0; z < D; ++z)
	{
		const auto inPix	= texPixels.getPixel(x, y, z);
		const auto outPix	= resultPixels.getPixel(x, y, z);
		if (inPix == outPix)
		{
			diffImg.setPixel(colorGreen, x, y, z);
		}
		else
		{
			pass = false;
			diffImg.setPixel(colorRed, x, y, z);
		}
	}

	tcu::TestStatus status = tcu::TestStatus::pass("Pass");
	if (!pass)
	{
		auto& log = m_context.getTestContext().getLog();
		log << tcu::TestLog::Image("input", "Input texture", texPixels);
		log << tcu::TestLog::Image("output", "Rendered image", resultPixels);
		log << tcu::TestLog::Image("diff", "Mismatched pixels in red", diffImg);
		status = tcu::TestStatus::fail("Pixel mismatch; please check the rendered image");
	}

	return status;
}

} // anonymous

tcu::TestCaseGroup* createAllFormatsSamplerTests (tcu::TestContext& testCtx, bool separateStencilUsage = false)
{
	const struct
	{
		SamplerViewType		type;
		const char*			name;
	}
	imageViewTypes[] =
	{
		{ VK_IMAGE_VIEW_TYPE_1D,			"1d" },
		{ { VK_IMAGE_VIEW_TYPE_1D, false },	"1d_unnormalized" },
		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		"1d_array" },
		{ VK_IMAGE_VIEW_TYPE_2D,			"2d" },
		{ { VK_IMAGE_VIEW_TYPE_2D, false },	"2d_unnormalized" },
		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		"2d_array" },
		{ VK_IMAGE_VIEW_TYPE_3D,			"3d" },
		{ VK_IMAGE_VIEW_TYPE_CUBE,			"cube" },
		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	"cube_array" }
	};

	const VkFormat formats[] =
	{
		// Packed formats
		VK_FORMAT_R4G4_UNORM_PACK8,
		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2R10G10B10_UINT_PACK32,
		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,

		// Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
		VK_FORMAT_R8_SRGB,
		VK_FORMAT_R8G8B8_UINT,
		VK_FORMAT_B8G8R8A8_SINT,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_B8G8R8_SNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8_SRGB,
		VK_FORMAT_R8G8_SRGB,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_B8G8R8_SINT,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_B8G8R8_UNORM,
		VK_FORMAT_R8_UNORM,

		// Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32_UINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R16G16B16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R16G16B16_SFLOAT,
		VK_FORMAT_R16G16_SINT,

		// More 16/32-bit formats required for testing VK_EXT_sampler_filter_minmax
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R32_SFLOAT,

		// Scaled formats
		VK_FORMAT_R8G8B8A8_SSCALED,
		VK_FORMAT_A2R10G10B10_USCALED_PACK32,

		// Compressed formats
		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
		VK_FORMAT_EAC_R11_UNORM_BLOCK,
		VK_FORMAT_EAC_R11_SNORM_BLOCK,
		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,

		// Depth formats required for testing VK_EXT_sampler_filter_minmax
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_X8_D24_UNORM_PACK32,
		VK_FORMAT_D32_SFLOAT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT,
	};

	de::MovePtr<tcu::TestCaseGroup> viewTypeTests		(new tcu::TestCaseGroup(testCtx, "view_type", ""));

	for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
	{
		const SamplerViewType			viewType		= imageViewTypes[viewTypeNdx].type;
		de::MovePtr<tcu::TestCaseGroup>	viewTypeGroup	(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
		de::MovePtr<tcu::TestCaseGroup>	formatTests		(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));

		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
		{
			const VkFormat	format			= formats[formatNdx];
			const bool		isCompressed	= isCompressedFormat(format);
			const bool		isDepthStencil	= !isCompressed
											  && tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order);
			if (isCompressed)
			{
				// Do not use compressed formats with 1D and 1D array textures.
				if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
					break;
			}

			if (separateStencilUsage && !isDepthStencil)
				continue;

			de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx,
																				getFormatCaseName(format).c_str(),
																				(std::string("Samples a texture of format ") + getFormatName(format)).c_str()));

			if (!isCompressed && viewType.isNormalized())
			{
				// Do not include minFilter tests with compressed formats.
				// Randomly generated compressed textures are too noisy and will derive in false positives.
				de::MovePtr<tcu::TestCaseGroup>	minFilterTests			= createSamplerMinFilterTests(testCtx, viewType, format, separateStencilUsage);
				de::MovePtr<tcu::TestCaseGroup>	minReduceFilterTests	= createSamplerMinReduceFilterTests(testCtx, viewType, format, separateStencilUsage);
				formatGroup->addChild(minFilterTests.release());
				formatGroup->addChild(minReduceFilterTests.release());
			}

			de::MovePtr<tcu::TestCaseGroup>	magFilterTests = createSamplerMagFilterTests(testCtx, viewType, format, separateStencilUsage);
			formatGroup->addChild(magFilterTests.release());

			if (viewType.isNormalized())
			{
				de::MovePtr<tcu::TestCaseGroup> magReduceFilterTests	= createSamplerMagReduceFilterTests(testCtx, viewType, format, separateStencilUsage);
				de::MovePtr<tcu::TestCaseGroup> mipmapTests				= createSamplerMipmapTests(testCtx, viewType, format, separateStencilUsage);

				formatGroup->addChild(magReduceFilterTests.release());
				formatGroup->addChild(mipmapTests.release());
			}

			if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
			{
				de::MovePtr<tcu::TestCaseGroup>	addressModesTests	= createSamplerAddressModesTests(testCtx, viewType, format, separateStencilUsage);
				formatGroup->addChild(addressModesTests.release());
			}

			formatTests->addChild(formatGroup.release());
		}

		viewTypeGroup->addChild(formatTests.release());
		viewTypeTests->addChild(viewTypeGroup.release());
	}

	return viewTypeTests.release();
}

tcu::TestCaseGroup* createExactSamplingTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> exactSamplingTests(new tcu::TestCaseGroup(testCtx, "exact_sampling", "Exact sampling tests"));

	static const std::vector<vk::VkFormat> formats =
	{
		vk::VK_FORMAT_R8_SRGB,
		vk::VK_FORMAT_R8G8B8_UINT,
		vk::VK_FORMAT_B8G8R8A8_SINT,
		vk::VK_FORMAT_R8G8_UNORM,
		vk::VK_FORMAT_B8G8R8_SNORM,
		vk::VK_FORMAT_R8G8B8A8_SNORM,
		vk::VK_FORMAT_R8G8_UINT,
		vk::VK_FORMAT_R8_SINT,
		vk::VK_FORMAT_R8G8B8A8_SRGB,
		vk::VK_FORMAT_R8G8B8A8_UNORM,
		vk::VK_FORMAT_B8G8R8A8_UNORM,
		vk::VK_FORMAT_B8G8R8_SRGB,
		vk::VK_FORMAT_R8G8_SRGB,
		vk::VK_FORMAT_R8_UINT,
		vk::VK_FORMAT_R8G8B8A8_UINT,
		vk::VK_FORMAT_R8G8_SINT,
		vk::VK_FORMAT_R8_SNORM,
		vk::VK_FORMAT_B8G8R8_SINT,
		vk::VK_FORMAT_R8G8_SNORM,
		vk::VK_FORMAT_B8G8R8_UNORM,
		vk::VK_FORMAT_R8_UNORM,

		vk::VK_FORMAT_R32G32_SFLOAT,
		vk::VK_FORMAT_R32G32B32_UINT,
		vk::VK_FORMAT_R16G16B16A16_SFLOAT,
		vk::VK_FORMAT_R16G16_UINT,
		vk::VK_FORMAT_R32G32B32A32_SINT,
		vk::VK_FORMAT_R16G16B16_SINT,
		vk::VK_FORMAT_R16_SFLOAT,
		vk::VK_FORMAT_R32_SINT,
		vk::VK_FORMAT_R32_UINT,
		vk::VK_FORMAT_R16G16B16_SFLOAT,
		vk::VK_FORMAT_R16G16_SINT,

		vk::VK_FORMAT_R16_SNORM,
		vk::VK_FORMAT_R32_SFLOAT,
	};

	static const struct
	{
		const bool			unnormalized;
		const std::string	name;
		const std::string	desc;
	} unnormalizedCoordinates[] =
	{
		{ false,	"normalized_coords",	"Normalized coordinates"	},
		{ true,		"unnormalized_coords",	"Unnormalized coordinates"	},
	};

	static const struct
	{
		const tcu::Maybe<float>	offset;
		const std::string		name;
		const std::string		desc;
	} testEdges[] =
	{
		{ tcu::Nothing,				"centered",		"Sampling points centered in texel"		},
		{ tcu::just<float>(-1.0f),	"edge_left",	"Sampling points near left edge"		},
		{ tcu::just<float>(+1.0f),	"edge_right",	"Sampling points near right edge"		},
	};

	static const std::vector<std::pair<bool, std::string>> solidColor =
	{
		{ false,	"gradient"		},
		{ true,		"solid_color"	},
	};

	for (const auto format : formats)
	{
		const std::string formatName	= getFormatCaseName(format);
		const std::string description	= std::string("Exact sampling tests with image format ") + getFormatName(format);

		de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str(), description.c_str()));

		for (const auto& solid : solidColor)
		{
			de::MovePtr<tcu::TestCaseGroup> solidColorGroup(new tcu::TestCaseGroup(testCtx, solid.second.c_str(), ""));

			for (int unIdx = 0; unIdx < DE_LENGTH_OF_ARRAY(unnormalizedCoordinates); ++unIdx)
			{
				const auto&						unnorm		= unnormalizedCoordinates[unIdx];
				de::MovePtr<tcu::TestCaseGroup> coordGroup	(new tcu::TestCaseGroup(testCtx, unnorm.name.c_str(), unnorm.desc.c_str()));

				for (int edgeIdx = 0; edgeIdx < DE_LENGTH_OF_ARRAY(testEdges); ++edgeIdx)
				{
					const auto&						edges	= testEdges[edgeIdx];
					const ExactSamplingCase::Params	params	= { format, unnorm.unnormalized, solid.first, edges.offset };
					coordGroup->addChild(new ExactSamplingCase{testCtx, edges.name, edges.desc, params});
				}

				solidColorGroup->addChild(coordGroup.release());
			}

			formatGroup->addChild(solidColorGroup.release());
		}

		exactSamplingTests->addChild(formatGroup.release());
	}

	return exactSamplingTests.release();
}

tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> samplerTests(new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
	{
		samplerTests->addChild(createAllFormatsSamplerTests(testCtx));
		samplerTests->addChild(createExactSamplingTests(testCtx));
	}

	// tests for VK_EXT_separate_stencil_usage
	de::MovePtr<tcu::TestCaseGroup> separateStencilUsageSamplerTests (new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "testing VK_EXT_separate_stencil_uasge"));
	{
		separateStencilUsageSamplerTests->addChild(createAllFormatsSamplerTests(testCtx, true));
		samplerTests->addChild(separateStencilUsageSamplerTests.release());
	}

#ifndef CTS_USES_VULKANSC
	// Border color swizzle tests.
	samplerTests->addChild(createSamplerBorderSwizzleTests(testCtx));
#endif // CTS_USES_VULKANSC

	return samplerTests.release();
}

} // pipeline
} // vkt
