/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Texture border clamp tests.
 *//*--------------------------------------------------------------------*/

#include "es31fTextureBorderClampTests.hpp"

#include "glsTextureTestUtil.hpp"

#include "tcuTextureUtil.hpp"
#include "tcuTexLookupVerifier.hpp"
#include "tcuTexCompareVerifier.hpp"
#include "tcuCompressedTexture.hpp"
#include "tcuResultCollector.hpp"
#include "tcuSurface.hpp"
#include "tcuSeedBuilder.hpp"
#include "tcuVectorUtil.hpp"

#include "rrGenericVector.hpp"

#include "gluContextInfo.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "gluDrawUtil.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include "deRandom.hpp"

#include <limits>


namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

enum SizeType
{
	SIZE_POT = 0,
	SIZE_NPOT
};

bool filterRequiresFilterability (deUint32 filter)
{
	switch (filter)
	{
		case GL_NEAREST:
		case GL_NEAREST_MIPMAP_NEAREST:
			return false;

		case GL_LINEAR:
		case GL_LINEAR_MIPMAP_NEAREST:
		case GL_NEAREST_MIPMAP_LINEAR:
		case GL_LINEAR_MIPMAP_LINEAR:
			return true;

		default:
			DE_ASSERT(false);
			return false;
	}
}

bool isDepthFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
{
	if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
	{
		// Unsized formats are a special case
		return false;
	}
	else if (glu::isCompressedFormat(format))
	{
		// no known compressed depth formats
		return false;
	}
	else
	{
		const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);

		if (fmt.order == tcu::TextureFormat::D)
		{
			DE_ASSERT(mode == tcu::Sampler::MODE_DEPTH);
			return true;
		}
		else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_DEPTH)
			return true;
		else
			return false;
	}
}

bool isStencilFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
{
	if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
	{
		// Unsized formats are a special case
		return false;
	}
	else if (glu::isCompressedFormat(format))
	{
		// no known compressed stencil formats
		return false;
	}
	else
	{
		const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);

		if (fmt.order == tcu::TextureFormat::S)
		{
			DE_ASSERT(mode == tcu::Sampler::MODE_STENCIL);
			return true;
		}
		else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_STENCIL)
			return true;
		else
			return false;
	}
}

tcu::TextureChannelClass getFormatChannelClass (deUint32 format, tcu::Sampler::DepthStencilMode mode)
{
	if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA)
	{
		// Unsized formats are a special c, use UNORM8
		return tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
	}
	else if (glu::isCompressedFormat(format))
	{
		const tcu::CompressedTexFormat	compressedFmt	= glu::mapGLCompressedTexFormat(format);
		const tcu::TextureFormat		uncompressedFmt	= tcu::getUncompressedFormat(compressedFmt);
		return tcu::getTextureChannelClass(uncompressedFmt.type);
	}
	else
	{
		const tcu::TextureFormat fmt			= glu::mapGLInternalFormat(format);
		const tcu::TextureFormat effectiveFmt	= tcu::getEffectiveDepthStencilTextureFormat(fmt, mode);

		return tcu::getTextureChannelClass(effectiveFmt.type);
	}
}

int getDimensionNumBlocks (int dimensionSize, int blockSize)
{
	// ceil( a / b )
	return (dimensionSize + blockSize - 1) / blockSize;
}

void generateDefaultCompressedData (tcu::CompressedTexture& dst, const tcu::CompressedTexFormat& format)
{
	const int			blockByteSize	= tcu::getBlockSize(format);
	const tcu::IVec3	blockPixelSize	= tcu::getBlockPixelSize(format);
	const tcu::IVec3	numBlocks		(getDimensionNumBlocks(dst.getWidth(),    blockPixelSize.x()),
										 getDimensionNumBlocks(dst.getHeight(),   blockPixelSize.y()),
										 getDimensionNumBlocks(dst.getDepth(),    blockPixelSize.z()));
	const int			numTotalBlocks	= numBlocks.x() * numBlocks.y() * numBlocks.z();
	const int			dataSize		= numTotalBlocks * blockByteSize;

	DE_ASSERT(dst.getDataSize() == dataSize);

	if (tcu::isAstcFormat(format))
	{
		// generate data that is valid in LDR mode
		const int		BLOCK_SIZE			= 16;
		const deUint8	block[BLOCK_SIZE]	= { 252, 253, 255, 255, 255, 255, 255, 255, 223, 251, 28, 206, 54, 251, 160, 174 };

		DE_ASSERT(blockByteSize == BLOCK_SIZE);
		for (int ndx = 0; ndx < numTotalBlocks; ++ndx)
			deMemcpy((deUint8*)dst.getData() + ndx * BLOCK_SIZE, block, BLOCK_SIZE);
	}
	else
	{
		// any data is ok
		de::Random rnd(0xabc);

		for (int ndx = 0; ndx < dataSize; ++ndx)
			((deUint8*)dst.getData())[ndx] = rnd.getUint8();
	}
}

template <typename T>
struct TextureTraits
{
};

template <>
struct TextureTraits<glu::Texture2D>
{
	typedef tcu::IVec2 SizeType;

	static de::MovePtr<glu::Texture2D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec2& size)
	{
		return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, size.x(), size.y()));
	}

	static de::MovePtr<glu::Texture2D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec2& size)
	{
		return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, type, size.x(), size.y()));
	}

	static de::MovePtr<glu::Texture2D> createTextureFromCompressedData (glu::RenderContext&					renderCtx,
																		const glu::ContextInfo&				ctxInfo,
																		const tcu::CompressedTexture&		compressedLevel,
																		const tcu::TexDecompressionParams&	decompressionParams)
	{
		return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx,
															  ctxInfo,
															  1,
															  &compressedLevel,
															  decompressionParams));
	}

	static int getTextureNumLayers (const tcu::IVec2& size)
	{
		// 2D textures have one layer
		DE_UNREF(size);
		return 1;
	}
};

template <>
struct TextureTraits<glu::Texture3D>
{
	typedef tcu::IVec3 SizeType;

	static de::MovePtr<glu::Texture3D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec3& size)
	{
		return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, size.x(), size.y(), size.z()));
	}

	static de::MovePtr<glu::Texture3D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec3& size)
	{
		return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, type, size.x(), size.y(), size.z()));
	}

	static de::MovePtr<glu::Texture3D> createTextureFromCompressedData (glu::RenderContext&					renderCtx,
																		const glu::ContextInfo&				ctxInfo,
																		const tcu::CompressedTexture&		compressedLevel,
																		const tcu::TexDecompressionParams&	decompressionParams)
	{
		return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx,
															  ctxInfo,
															  1,
															  &compressedLevel,
															  decompressionParams));
	}

	static int getTextureNumLayers (const tcu::IVec3& size)
	{
		// 3D textures have Z layers
		return size.z();
	}
};

template <typename T>
de::MovePtr<T> genDefaultTexture (glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, deUint32 texFormat, const typename TextureTraits<T>::SizeType& size)
{
	de::MovePtr<T> texture;

	if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH) || isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL))
	{
		// fill different channels with different gradients
		texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size);
		texture->getRefTexture().allocLevel(0);

		if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH))
		{
			// fill depth with 0 -> 1
			const tcu::PixelBufferAccess depthAccess = tcu::getEffectiveDepthStencilAccess(texture->getRefTexture().getLevel(0), tcu::Sampler::MODE_DEPTH);
			tcu::fillWithComponentGradients(depthAccess, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
		}

		if (isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL))
		{
			// fill stencil with 0 -> max
			const tcu::PixelBufferAccess	stencilAccess	= tcu::getEffectiveDepthStencilAccess(texture->getRefTexture().getLevel(0), tcu::Sampler::MODE_STENCIL);
			const tcu::TextureFormatInfo	texFormatInfo	= tcu::getTextureFormatInfo(stencilAccess.getFormat());

			// Flip y to make stencil and depth cases not look identical
			tcu::fillWithComponentGradients(tcu::flipYAccess(stencilAccess), texFormatInfo.valueMax, texFormatInfo.valueMin);
		}

		texture->upload();
	}
	else if (!glu::isCompressedFormat(texFormat))
	{
		if (texFormat == GL_LUMINANCE || texFormat == GL_LUMINANCE_ALPHA || texFormat == GL_ALPHA || texFormat == GL_BGRA)
			texture = TextureTraits<T>::createTextureFromFormatAndType(renderCtx, texFormat, GL_UNSIGNED_BYTE, size);
		else
			texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size);

		// Fill level 0.
		texture->getRefTexture().allocLevel(0);

		// fill with gradient min -> max
		{
			const tcu::TextureFormatInfo	texFormatInfo	= tcu::getTextureFormatInfo(texture->getRefTexture().getFormat());
			const tcu::Vec4					rampLow			= texFormatInfo.valueMin;
			const tcu::Vec4					rampHigh		= texFormatInfo.valueMax;
			tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(0), rampLow, rampHigh);
		}

		texture->upload();
	}
	else
	{
		const tcu::CompressedTexFormat	compressedFormat	= glu::mapGLCompressedTexFormat(texFormat);
		const int						numLayers			= TextureTraits<T>::getTextureNumLayers(size);
		tcu::CompressedTexture			compressedLevel		(compressedFormat, size.x(), size.y(), numLayers);
		const bool						isAstcFormat		= tcu::isAstcFormat(compressedFormat);
		tcu::TexDecompressionParams		decompressionParams	((isAstcFormat) ? (tcu::TexDecompressionParams::ASTCMODE_LDR) : (tcu::TexDecompressionParams::ASTCMODE_LAST));

		generateDefaultCompressedData(compressedLevel, compressedFormat);

		texture = TextureTraits<T>::createTextureFromCompressedData(renderCtx,
																	ctxInfo,
																	compressedLevel,
																	decompressionParams);
	}

	return texture;
}

int getNBitIntegerMaxValue (bool isSigned, int numBits)
{
	DE_ASSERT(numBits < 32);

	if (numBits == 0)
		return 0;
	else if (isSigned)
		return deIntMaxValue32(numBits);
	else
		return deUintMaxValue32(numBits);
}

int getNBitIntegerMinValue (bool isSigned, int numBits)
{
	DE_ASSERT(numBits < 32);

	if (numBits == 0)
		return 0;
	else if (isSigned)
		return deIntMinValue32(numBits);
	else
		return 0;
}

tcu::IVec4 getNBitIntegerVec4MaxValue (bool isSigned, const tcu::IVec4& numBits)
{
	return tcu::IVec4(getNBitIntegerMaxValue(isSigned, numBits[0]),
					  getNBitIntegerMaxValue(isSigned, numBits[1]),
					  getNBitIntegerMaxValue(isSigned, numBits[2]),
					  getNBitIntegerMaxValue(isSigned, numBits[3]));
}

tcu::IVec4 getNBitIntegerVec4MinValue (bool isSigned, const tcu::IVec4& numBits)
{
	return tcu::IVec4(getNBitIntegerMinValue(isSigned, numBits[0]),
					  getNBitIntegerMinValue(isSigned, numBits[1]),
					  getNBitIntegerMinValue(isSigned, numBits[2]),
					  getNBitIntegerMinValue(isSigned, numBits[3]));
}

rr::GenericVec4 mapToFormatColorUnits (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange)
{
	const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);

	switch (tcu::getTextureChannelClass(texFormat.type))
	{
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:		return rr::GenericVec4(normalizedRange);
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:		return rr::GenericVec4(normalizedRange * 2.0f - 1.0f);
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:			return rr::GenericVec4(texFormatInfo.valueMin + normalizedRange * texFormatInfo.valueMax);
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:			return rr::GenericVec4(tcu::mix(texFormatInfo.valueMin, texFormatInfo.valueMax, normalizedRange).cast<deInt32>());
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:			return rr::GenericVec4(tcu::mix(texFormatInfo.valueMin, texFormatInfo.valueMax, normalizedRange).cast<deUint32>());

		default:
			DE_ASSERT(false);
			return rr::GenericVec4();
	}
}

rr::GenericVec4 mapToFormatColorRepresentable (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange)
{
	// make sure value is representable in the target format and clear channels
	// not present in the target format.

	const rr::GenericVec4		inFormatUnits	= mapToFormatColorUnits(texFormat, normalizedRange);
	const tcu::BVec4			channelMask		= tcu::getTextureFormatChannelMask(texFormat);
	de::ArrayBuffer<deUint8, 4>	buffer			(texFormat.getPixelSize());
	tcu::PixelBufferAccess		access			(texFormat, tcu::IVec3(1, 1, 1), buffer.getPtr());

	if (tcu::isSRGB(texFormat))
	{
		DE_ASSERT(texFormat.type == tcu::TextureFormat::UNORM_INT8);

		// make sure border color (in linear space) can be converted to 8-bit sRGB space without
		// significant loss.
		const tcu::Vec4		sRGB		= tcu::linearToSRGB(normalizedRange);
		const tcu::IVec4	sRGB8		= tcu::IVec4(tcu::floatToU8(sRGB[0]),
													 tcu::floatToU8(sRGB[1]),
													 tcu::floatToU8(sRGB[2]),
													 tcu::floatToU8(sRGB[3]));
		const tcu::Vec4		linearized	= tcu::sRGBToLinear(tcu::Vec4((float)sRGB8[0] / 255.0f,
																	  (float)sRGB8[1] / 255.0f,
																	  (float)sRGB8[2] / 255.0f,
																	  (float)sRGB8[3] / 255.0f));

		return rr::GenericVec4(tcu::select(linearized, tcu::Vec4(0.0f), channelMask));
	}

	switch (tcu::getTextureChannelClass(texFormat.type))
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		{
			access.setPixel(inFormatUnits.get<float>(), 0, 0);
			return rr::GenericVec4(tcu::select(access.getPixel(0, 0), tcu::Vec4(0.0f), channelMask));
		}
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
		{
			access.setPixel(inFormatUnits.get<deInt32>(), 0, 0);
			return rr::GenericVec4(tcu::select(access.getPixelInt(0, 0), tcu::IVec4(0), channelMask));
		}
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
		{
			access.setPixel(inFormatUnits.get<deUint32>(), 0, 0);
			return rr::GenericVec4(tcu::select(access.getPixelUint(0, 0), tcu::UVec4(0u), channelMask));
		}
		default:
		{
			DE_ASSERT(false);
			return rr::GenericVec4();
		}
	}
}

bool isCoreFilterableFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode)
{
	const bool	isLuminanceOrAlpha		= (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA); // special case for luminance/alpha
	const bool	isUnsizedColorFormat	= (format == GL_BGRA);
	const bool	isCompressed			= glu::isCompressedFormat(format);
	const bool	isDepth					= isDepthFormat(format, mode);
	const bool	isStencil				= isStencilFormat(format, mode);

	// special cases
	if (isLuminanceOrAlpha || isUnsizedColorFormat || isCompressed)
		return true;
	if (isStencil || isDepth)
		return false;

	// color case
	return glu::isGLInternalColorFormatFilterable(format);
}

class TextureBorderClampTest : public TestCase
{
public:
	enum StateType
	{
		STATE_SAMPLER_PARAM = 0,
		STATE_TEXTURE_PARAM,

		STATE_LAST
	};

	enum SamplingFunction
	{
		SAMPLE_FILTER = 0,
		SAMPLE_GATHER,

		SAMPLE_LAST
	};

	enum Flag
	{
		FLAG_USE_SHADOW_SAMPLER = (1u << 0),
	};

	struct IterationConfig
	{
		tcu::Vec2		p0;
		tcu::Vec2		p1;
		rr::GenericVec4	borderColor;
		tcu::Vec4		lookupScale;
		tcu::Vec4		lookupBias;
		deUint32		minFilter;
		deUint32		magFilter;
		std::string		description;
		deUint32		sWrapMode;
		deUint32		tWrapMode;
		deUint32		compareMode;
		float			compareRef;
	};

														TextureBorderClampTest		(Context&						context,
																					 const char*					name,
																					 const char*					description,
																					 deUint32						texFormat,
																					 tcu::Sampler::DepthStencilMode	mode,
																					 StateType						stateType,
																					 int							texWidth,
																					 int							texHeight,
																					 SamplingFunction				samplingFunction,
																					 deUint32						flags				= 0);
														~TextureBorderClampTest		(void);

protected:
	void												init						(void);
	void												deinit						(void);

private:
	IterateResult										iterate						(void);

	void												logParams					(const IterationConfig&							config,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams);

	void												renderTo					(tcu::Surface&									surface,
																					 const IterationConfig&							config,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams);
	void												renderQuad					(const float*									texCoord,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams);

	void												verifyImage					(const tcu::Surface&							image,
																					 const IterationConfig&							config,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams);

	bool												verifyTextureSampleResult	(const tcu::ConstPixelBufferAccess&				renderedFrame,
																					 const float*									texCoord,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams,
																					 const tcu::LodPrecision&						lodPrecision,
																					 const tcu::LookupPrecision&					lookupPrecision);

	bool												verifyTextureCompareResult	(const tcu::ConstPixelBufferAccess&				renderedFrame,
																					 const float*									texCoord,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams,
																					 const tcu::TexComparePrecision&				texComparePrecision,
																					 const tcu::TexComparePrecision&				lowQualityTexComparePrecision,
																					 const tcu::LodPrecision&						lodPrecision,
																					 const tcu::LodPrecision&						lowQualityLodPrecision);

	bool												verifyTextureGatherResult	(const tcu::ConstPixelBufferAccess&				renderedFrame,
																					 const float*									texCoord,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams,
																					 const tcu::LookupPrecision&					lookupPrecision);

	bool												verifyTextureGatherCmpResult(const tcu::ConstPixelBufferAccess&				renderedFrame,
																					 const float*									texCoord,
																					 const glu::TextureTestUtil::ReferenceParams&	samplerParams,
																					 const tcu::TexComparePrecision&				texComparePrecision,
																					 const tcu::TexComparePrecision&				lowQualityTexComparePrecision);

	deUint32											getIterationSeed			(const IterationConfig& config) const;
	glu::TextureTestUtil::ReferenceParams				genSamplerParams			(const IterationConfig& config) const;
	glu::ShaderProgram*									genGatherProgram			(void) const;

	virtual int											getNumIterations			(void) const = 0;
	virtual IterationConfig								getIteration				(int ndx) const = 0;

protected:
	const glu::Texture2D*								getTexture						(void) const;

	const deUint32										m_texFormat;
	const tcu::Sampler::DepthStencilMode				m_sampleMode;
	const tcu::TextureChannelClass						m_channelClass;
	const StateType										m_stateType;

	const int											m_texHeight;
	const int											m_texWidth;

	const SamplingFunction								m_samplingFunction;
	const bool											m_useShadowSampler;
private:
	enum
	{
		VIEWPORT_WIDTH		= 128,
		VIEWPORT_HEIGHT		= 128,
	};

	de::MovePtr<glu::Texture2D>							m_texture;
	de::MovePtr<gls::TextureTestUtil::TextureRenderer>	m_renderer;
	de::MovePtr<glu::ShaderProgram>						m_gatherProgram;

	int													m_iterationNdx;
	tcu::ResultCollector								m_result;
};

TextureBorderClampTest::TextureBorderClampTest (Context&						context,
												const char*						name,
												const char*						description,
												deUint32						texFormat,
												tcu::Sampler::DepthStencilMode	mode,
												StateType						stateType,
												int								texWidth,
												int								texHeight,
												SamplingFunction				samplingFunction,
												deUint32						flags)
	: TestCase				(context, name, description)
	, m_texFormat			(texFormat)
	, m_sampleMode			(mode)
	, m_channelClass		(getFormatChannelClass(texFormat, mode))
	, m_stateType			(stateType)
	, m_texHeight			(texHeight)
	, m_texWidth			(texWidth)
	, m_samplingFunction	(samplingFunction)
	, m_useShadowSampler	((flags & FLAG_USE_SHADOW_SAMPLER) != 0)
	, m_iterationNdx		(0)
	, m_result				(context.getTestContext().getLog())
{
	DE_ASSERT(stateType < STATE_LAST);
	DE_ASSERT(samplingFunction < SAMPLE_LAST);
	// mode must be set for combined depth-stencil formats
	DE_ASSERT(m_channelClass != tcu::TEXTURECHANNELCLASS_LAST || mode != tcu::Sampler::MODE_LAST);
}

TextureBorderClampTest::~TextureBorderClampTest (void)
{
	deinit();
}

void TextureBorderClampTest::init (void)
{
	// requirements
	const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));

	if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
		throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");

	if (glu::isCompressedFormat(m_texFormat)													&&
		!supportsES32																			&&
		tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat))							&&
		!m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
	{
		throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
	}

	if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888"))
		throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension");

	if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
		m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
	{
		throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
	}

	// resources

	m_texture = genDefaultTexture<glu::Texture2D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, tcu::IVec2(m_texWidth, m_texHeight));

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Created texture with format " << glu::getTextureFormatName(m_texFormat)
						<< ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ")\n"
						<< "Setting sampling state using " << ((m_stateType == STATE_TEXTURE_PARAM) ? ("texture state") : ("sampler state"))
						<< tcu::TestLog::EndMessage;

	if (m_samplingFunction == SAMPLE_FILTER)
	{
		const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

		m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));
	}
	else
	{
		m_gatherProgram = de::MovePtr<glu::ShaderProgram>(genGatherProgram());

		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Using texture gather to sample texture"
							<< tcu::TestLog::EndMessage
							<< *m_gatherProgram;

		if (!m_gatherProgram->isOk())
			throw tcu::TestError("failed to build program");
	}
}

void TextureBorderClampTest::deinit (void)
{
	m_texture.clear();
	m_renderer.clear();
	m_gatherProgram.clear();
}

TextureBorderClampTest::IterateResult TextureBorderClampTest::iterate (void)
{
	const IterationConfig						iterationConfig		= getIteration(m_iterationNdx);
	const std::string							iterationDesc		= "Iteration " + de::toString(m_iterationNdx+1) + (iterationConfig.description.empty() ? ("") : (" - " + iterationConfig.description));
	const tcu::ScopedLogSection					section				(m_testCtx.getLog(), "Iteration", iterationDesc);
	tcu::Surface								renderedFrame		(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	const glu::TextureTestUtil::ReferenceParams	samplerParams		= genSamplerParams(iterationConfig);

	logParams(iterationConfig, samplerParams);
	renderTo(renderedFrame, iterationConfig, samplerParams);
	verifyImage(renderedFrame, iterationConfig, samplerParams);

	if (++m_iterationNdx == getNumIterations())
	{
		m_result.setTestContextResult(m_testCtx);
		return STOP;
	}
	return CONTINUE;
}

void TextureBorderClampTest::logParams (const IterationConfig& config, const glu::TextureTestUtil::ReferenceParams& samplerParams)
{
	const std::string				borderColorString	= (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)   ? (de::toString(config.borderColor.get<deInt32>()))
														: (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(config.borderColor.get<deUint32>()))
														:																  (de::toString(config.borderColor.get<float>()));

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Rendering full screen quad, tex coords bottom-left: " << config.p0 << ", top-right " << config.p1 << "\n"
						<< "Border color is " << borderColorString << "\n"
						<< "Texture lookup bias: " << samplerParams.colorBias << "\n"
						<< "Texture lookup scale: " << samplerParams.colorScale << "\n"
						<< "Filters: min = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.minFilter))
							<< ", mag = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.magFilter)) << "\n"
						<< "Wrap mode: s = " << glu::getRepeatModeStr(config.sWrapMode)
							<< ", t = " << glu::getRepeatModeStr(config.tWrapMode) << "\n"
						<< tcu::TestLog::EndMessage;

	if (m_sampleMode == tcu::Sampler::MODE_DEPTH)
		m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is DEPTH_COMPONENT" << tcu::TestLog::EndMessage;
	else if (m_sampleMode == tcu::Sampler::MODE_STENCIL)
		m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is STENCIL_INDEX" << tcu::TestLog::EndMessage;

	if (config.compareMode != GL_NONE)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Texture mode is COMPARE_REF_TO_TEXTURE, mode = " << glu::getCompareFuncStr(config.compareMode) << "\n"
							<< "Compare reference value = " << config.compareRef << "\n"
							<< tcu::TestLog::EndMessage;
	}
}

void TextureBorderClampTest::renderTo (tcu::Surface&								surface,
									   const IterationConfig&						config,
									   const glu::TextureTestUtil::ReferenceParams&	samplerParams)
{
	const glw::Functions&						gl			= m_context.getRenderContext().getFunctions();
	const gls::TextureTestUtil::RandomViewport	viewport	(m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getIterationSeed(config));
	std::vector<float>							texCoord;
	de::MovePtr<glu::Sampler>					sampler;

	glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	if (m_sampleMode == tcu::Sampler::MODE_DEPTH)
		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
	else if (m_sampleMode == tcu::Sampler::MODE_STENCIL)
		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);

	if (config.compareMode == GL_NONE)
	{
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
	}
	else
	{
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, config.compareMode);
	}

	if (m_stateType == STATE_TEXTURE_PARAM)
	{
		// Setup filtering and wrap modes.
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		glu::getGLWrapMode(samplerParams.sampler.wrapS));
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		glu::getGLWrapMode(samplerParams.sampler.wrapT));
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	glu::getGLFilterMode(samplerParams.sampler.minFilter));
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	glu::getGLFilterMode(samplerParams.sampler.magFilter));

		switch (m_channelClass)
		{
			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>());
				break;

			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				gl.texParameterIiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
				break;

			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				gl.texParameterIuiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
				break;

			default:
				DE_ASSERT(false);
		}
	}
	else if (m_stateType == STATE_SAMPLER_PARAM)
	{
		const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);

		// Setup filtering and wrap modes to bad values
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
		gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, blue.getPtr()); // just set some unlikely color

		// setup sampler to correct values
		sampler = de::MovePtr<glu::Sampler>(new glu::Sampler(m_context.getRenderContext()));

		gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_S,		glu::getGLWrapMode(samplerParams.sampler.wrapS));
		gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_T,		glu::getGLWrapMode(samplerParams.sampler.wrapT));
		gl.samplerParameteri(**sampler, GL_TEXTURE_MIN_FILTER,	glu::getGLFilterMode(samplerParams.sampler.minFilter));
		gl.samplerParameteri(**sampler, GL_TEXTURE_MAG_FILTER,	glu::getGLFilterMode(samplerParams.sampler.magFilter));

		switch (m_channelClass)
		{
			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				gl.samplerParameterfv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>());
				break;

			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				gl.samplerParameterIiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>());
				break;

			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				gl.samplerParameterIuiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>());
				break;

			default:
				DE_ASSERT(false);
		}

		gl.bindSampler(0, **sampler);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
	renderQuad(&texCoord[0], samplerParams);
	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess());
}

void TextureBorderClampTest::renderQuad (const float* texCoord, const glu::TextureTestUtil::ReferenceParams& samplerParams)
{
	// use TextureRenderer for basic rendering, use custom for gather
	if (m_samplingFunction == SAMPLE_FILTER)
		m_renderer->renderQuad(0, texCoord, samplerParams);
	else
	{
		static const float position[] =
		{
			-1.0f, -1.0f, 0.0f, 1.0f,
			-1.0f, +1.0f, 0.0f, 1.0f,
			+1.0f, -1.0f, 0.0f, 1.0f,
			+1.0f, +1.0f, 0.0f, 1.0f
		};
		static const deUint16 indices[] =
		{
			0, 1, 2, 2, 1, 3
		};
		const glu::VertexArrayBinding vertexArrays[] =
		{
			glu::va::Float("a_position",	4,	4, 0, &position[0]),
			glu::va::Float("a_texcoord",	2,	4, 0, texCoord)
		};

		const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
		const deUint32			progId	= m_gatherProgram->getProgram();

		gl.useProgram(progId);
		gl.uniform1i(gl.getUniformLocation(progId, "u_sampler"), 0);
		if (m_useShadowSampler)
			gl.uniform1f(gl.getUniformLocation(progId, "u_ref"), samplerParams.ref);
		gl.uniform4fv(gl.getUniformLocation(progId, "u_colorScale"), 1, samplerParams.colorScale.getPtr());
		gl.uniform4fv(gl.getUniformLocation(progId, "u_colorBias"), 1, samplerParams.colorBias.getPtr());

		glu::draw(m_context.getRenderContext(), progId, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
					glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
	}
}

void TextureBorderClampTest::verifyImage (const tcu::Surface&							renderedFrame,
										  const IterationConfig&						config,
										  const glu::TextureTestUtil::ReferenceParams&	samplerParams)
{
	const tcu::PixelFormat	pixelFormat		= m_context.getRenderTarget().getPixelFormat();

	tcu::LodPrecision		lodPrecision;
	std::vector<float>		texCoord;
	bool					verificationOk;

	glu::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1);

	lodPrecision.derivateBits		= 18;
	lodPrecision.lodBits			= 5;

	if (samplerParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE)
	{
		const tcu::TextureFormat		texFormat			= tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
		const bool						isNearestMinFilter	= samplerParams.sampler.minFilter == tcu::Sampler::NEAREST || samplerParams.sampler.minFilter == tcu::Sampler::NEAREST_MIPMAP_NEAREST;
		const bool						isNearestMagFilter	= samplerParams.sampler.magFilter == tcu::Sampler::NEAREST;
		const bool						isNearestOnly		= isNearestMinFilter && isNearestMagFilter;
		const bool						isSRGB				= texFormat.order == tcu::TextureFormat::sRGB || texFormat.order == tcu::TextureFormat::sRGBA;
		const int						colorErrorBits		= (isNearestOnly && !isSRGB) ? (1) : (2);
		const tcu::IVec4				colorBits			= tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
		tcu::LookupPrecision			lookupPrecision;

		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale;
		lookupPrecision.coordBits		= tcu::IVec3(20,20,0);
		lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
		lookupPrecision.colorMask		= glu::TextureTestUtil::getCompareMask(pixelFormat);

		if (m_samplingFunction == SAMPLE_FILTER)
		{
			verificationOk = verifyTextureSampleResult(renderedFrame.getAccess(),
													   &texCoord[0],
													   samplerParams,
													   lodPrecision,
													   lookupPrecision);
		}
		else if (m_samplingFunction == SAMPLE_GATHER)
		{
			verificationOk = verifyTextureGatherResult(renderedFrame.getAccess(),
													   &texCoord[0],
													   samplerParams,
													   lookupPrecision);
		}
		else
		{
			DE_ASSERT(false);
			verificationOk = false;
		}
	}
	else
	{
		tcu::TexComparePrecision	texComparePrecision;
		tcu::TexComparePrecision	lowQualityTexComparePrecision;
		tcu::LodPrecision			lowQualityLodPrecision			= lodPrecision;

		texComparePrecision.coordBits					= tcu::IVec3(20,20,0);
		texComparePrecision.uvwBits						= tcu::IVec3(7,7,0);
		texComparePrecision.pcfBits						= 5;
		texComparePrecision.referenceBits				= 16;
		texComparePrecision.resultBits					= de::max(0, pixelFormat.redBits - 1);

		lowQualityTexComparePrecision.coordBits			= tcu::IVec3(20,20,0);
		lowQualityTexComparePrecision.uvwBits			= tcu::IVec3(4,4,0);
		lowQualityTexComparePrecision.pcfBits			= 0;
		lowQualityTexComparePrecision.referenceBits		= 16;
		lowQualityTexComparePrecision.resultBits		= de::max(0, pixelFormat.redBits - 1);

		lowQualityLodPrecision.lodBits					= 4;

		if (m_samplingFunction == SAMPLE_FILTER)
		{
			verificationOk = verifyTextureCompareResult(renderedFrame.getAccess(),
														&texCoord[0],
														samplerParams,
														texComparePrecision,
														lowQualityTexComparePrecision,
														lodPrecision,
														lowQualityLodPrecision);
		}
		else if (m_samplingFunction == SAMPLE_GATHER)
		{
			verificationOk = verifyTextureGatherCmpResult(renderedFrame.getAccess(),
														  &texCoord[0],
														  samplerParams,
														  texComparePrecision,
														  lowQualityTexComparePrecision);
		}
		else
		{
			DE_ASSERT(false);
			verificationOk = false;
		}
	}

	if (!verificationOk)
		m_result.fail("Image verification failed");
}

bool TextureBorderClampTest::verifyTextureSampleResult (const tcu::ConstPixelBufferAccess&				renderedFrame,
														const float*									texCoord,
														const glu::TextureTestUtil::ReferenceParams&	samplerParams,
														const tcu::LodPrecision&						lodPrecision,
													    const tcu::LookupPrecision&						lookupPrecision)
{
	const tcu::PixelFormat			pixelFormat			= m_context.getRenderTarget().getPixelFormat();
	tcu::Surface					reference			(renderedFrame.getWidth(), renderedFrame.getHeight());
	tcu::Surface					errorMask			(renderedFrame.getWidth(), renderedFrame.getHeight());
	int								numFailedPixels;

	glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), texCoord, samplerParams);

	numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
																	 texCoord, samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());

	if (numFailedPixels > 0)
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
	m_testCtx.getLog()	<< tcu::TestLog::ImageSet("VerifyResult", "Verification result")
						<< tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
	if (numFailedPixels > 0)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Image("Reference", "Ideal reference image", reference)
							<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}
	m_testCtx.getLog() << tcu::TestLog::EndImageSet;

	return (numFailedPixels == 0);
}

bool TextureBorderClampTest::verifyTextureCompareResult (const tcu::ConstPixelBufferAccess&				renderedFrame,
														 const float*									texCoord,
														 const glu::TextureTestUtil::ReferenceParams&	samplerParams,
													     const tcu::TexComparePrecision&				texComparePrecision,
													     const tcu::TexComparePrecision&				lowQualityTexComparePrecision,
														 const tcu::LodPrecision&						lodPrecision,
														 const tcu::LodPrecision&						lowQualityLodPrecision)
{
	const tcu::PixelFormat						pixelFormat				= m_context.getRenderTarget().getPixelFormat();
	const int									colorErrorBits			= 1;
	const tcu::IVec4							nonShadowBits			= tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
	const tcu::Vec3								nonShadowThreshold		= tcu::computeFixedPointThreshold(nonShadowBits).swizzle(1,2,3);
	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture2DView					effectiveView			= tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);
	tcu::Surface								reference				(renderedFrame.getWidth(), renderedFrame.getHeight());
	tcu::Surface								errorMask				(renderedFrame.getWidth(), renderedFrame.getHeight());
	int											numFailedPixels;

	glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), effectiveView, texCoord, samplerParams);

	numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
																	  texCoord, samplerParams, texComparePrecision, lodPrecision, nonShadowThreshold);

	if (numFailedPixels > 0)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Warning: Verification assuming high-quality PCF filtering failed."
							<< tcu::TestLog::EndMessage;

		numFailedPixels = glu::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView,
																		  texCoord, samplerParams, lowQualityTexComparePrecision, lowQualityLodPrecision, nonShadowThreshold);

		if (numFailedPixels > 0)
			m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << tcu::TestLog::EndMessage;
		else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
	}

	if (numFailedPixels > 0)
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
	m_testCtx.getLog()	<< tcu::TestLog::ImageSet("VerifyResult", "Verification result")
						<< tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
	if (numFailedPixels > 0)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Image("Reference", "Ideal reference image", reference)
							<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}
	m_testCtx.getLog() << tcu::TestLog::EndImageSet;

	return (numFailedPixels == 0);
}

template <typename T>
static inline T triQuadInterpolate (const T (&values)[4], float xFactor, float yFactor)
{
	if (xFactor + yFactor < 1.0f)
		return values[0] + (values[2]-values[0])*xFactor		+ (values[1]-values[0])*yFactor;
	else
		return values[3] + (values[1]-values[3])*(1.0f-xFactor)	+ (values[2]-values[3])*(1.0f-yFactor);
}

bool TextureBorderClampTest::verifyTextureGatherResult (const tcu::ConstPixelBufferAccess&				renderedFrame,
														const float*									texCoordArray,
														const glu::TextureTestUtil::ReferenceParams&	samplerParams,
														const tcu::LookupPrecision&						lookupPrecision)
{
	const tcu::Vec2 texCoords[4] =
	{
		tcu::Vec2(texCoordArray[0], texCoordArray[1]),
		tcu::Vec2(texCoordArray[2], texCoordArray[3]),
		tcu::Vec2(texCoordArray[4], texCoordArray[5]),
		tcu::Vec2(texCoordArray[6], texCoordArray[7]),
	};

	const tcu::PixelFormat						pixelFormat			= m_context.getRenderTarget().getPixelFormat();
	const deUint8								fbColormask			= tcu::getColorMask(pixelFormat);

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture2DView					effectiveView		= tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);

	tcu::Surface								reference			(renderedFrame.getWidth(), renderedFrame.getHeight());
	tcu::Surface								errorMask			(renderedFrame.getWidth(), renderedFrame.getHeight());
	int											numFailedPixels		= 0;

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

	for (int py = 0; py < reference.getHeight(); ++py)
	for (int px = 0; px < reference.getWidth(); ++px)
	{
		const tcu::Vec2			viewportCoord	= (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight());
		const tcu::Vec2			texCoord		= triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
		const tcu::Vec4			referenceValue	= effectiveView.gatherOffsets(samplerParams.sampler, texCoord.x(), texCoord.y(), 0, glu::getDefaultGatherOffsets());
		const tcu::Vec4			referencePixel	= referenceValue * samplerParams.colorScale + samplerParams.colorBias;
		const tcu::Vec4			resultPixel		= renderedFrame.getPixel(px, py);
		const tcu::Vec4			resultValue		= (resultPixel - samplerParams.colorBias) / samplerParams.colorScale;

		reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));

		if (tcu::boolAny(tcu::logicalAnd(lookupPrecision.colorMask,
										 tcu::greaterThan(tcu::absDiff(resultPixel, referencePixel),
														  lookupPrecision.colorThreshold))))
		{
			if (!tcu::isGatherOffsetsResultValid(effectiveView, samplerParams.sampler, lookupPrecision, texCoord, 0, glu::getDefaultGatherOffsets(), resultValue))
			{
				errorMask.setPixel(px, py, tcu::RGBA::red());
				++numFailedPixels;
			}
		}
	}

	if (numFailedPixels > 0)
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
	m_testCtx.getLog()	<< tcu::TestLog::ImageSet("VerifyResult", "Verification result")
						<< tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
	if (numFailedPixels > 0)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Image("Reference", "Ideal reference image", reference)
							<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}
	m_testCtx.getLog() << tcu::TestLog::EndImageSet;

	return (numFailedPixels == 0);
}

bool TextureBorderClampTest::verifyTextureGatherCmpResult (const tcu::ConstPixelBufferAccess&			renderedFrame,
														   const float*									texCoordArray,
														   const glu::TextureTestUtil::ReferenceParams&	samplerParams,
														   const tcu::TexComparePrecision&				texComparePrecision,
														   const tcu::TexComparePrecision&				lowQualityTexComparePrecision)
{
	const tcu::Vec2 texCoords[4] =
	{
		tcu::Vec2(texCoordArray[0], texCoordArray[1]),
		tcu::Vec2(texCoordArray[2], texCoordArray[3]),
		tcu::Vec2(texCoordArray[4], texCoordArray[5]),
		tcu::Vec2(texCoordArray[6], texCoordArray[7]),
	};

	std::vector<tcu::ConstPixelBufferAccess>	srcLevelStorage;
	const tcu::Texture2DView					effectiveView		= tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler);

	const tcu::PixelFormat						pixelFormat			= m_context.getRenderTarget().getPixelFormat();
	const tcu::BVec4							colorMask			= glu::TextureTestUtil::getCompareMask(pixelFormat);
	const deUint8								fbColormask			= tcu::getColorMask(pixelFormat);
	tcu::Surface								reference			(renderedFrame.getWidth(), renderedFrame.getHeight());
	tcu::Surface								errorMask			(renderedFrame.getWidth(), renderedFrame.getHeight());
	int											numFailedPixels		= 0;
	bool										lowQuality			= false;

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

	for (int py = 0; py < reference.getHeight(); ++py)
	for (int px = 0; px < reference.getWidth(); ++px)
	{
		const tcu::Vec2			viewportCoord	= (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight());
		const tcu::Vec2			texCoord		= triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
		const float				refZ			= samplerParams.ref;
		const tcu::Vec4			referenceValue	= effectiveView.gatherOffsetsCompare(samplerParams.sampler, refZ, texCoord.x(), texCoord.y(), glu::getDefaultGatherOffsets());
		const tcu::Vec4			resultValue		= renderedFrame.getPixel(px, py);

		reference.setPixel(px, py, tcu::toRGBAMasked(referenceValue, fbColormask));

		if (tcu::boolAny(tcu::logicalAnd(colorMask, tcu::notEqual(referenceValue, resultValue))))
		{
			if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, texComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
			{
				lowQuality = true;

				// fall back to low quality verification
				if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, lowQualityTexComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue))
				{
					errorMask.setPixel(px, py, tcu::RGBA::red());
					++numFailedPixels;
				}
			}
		}
	}

	if (numFailedPixels > 0)
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
	else if (lowQuality)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << tcu::TestLog::EndMessage;
		m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result");
	}

	m_testCtx.getLog()	<< tcu::TestLog::ImageSet("VerifyResult", "Verification result")
						<< tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
	if (numFailedPixels > 0)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Image("Reference", "Ideal reference image", reference)
							<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}
	m_testCtx.getLog() << tcu::TestLog::EndImageSet;

	return (numFailedPixels == 0);
}

const glu::Texture2D* TextureBorderClampTest::getTexture (void) const
{
	return m_texture.get();
}

deUint32 TextureBorderClampTest::getIterationSeed (const IterationConfig& config) const
{
	tcu::SeedBuilder builder;
	builder	<< std::string(getName())
			<< m_iterationNdx
			<< m_texFormat
			<< config.minFilter << config.magFilter
			<< m_texture->getRefTexture().getWidth() << m_texture->getRefTexture().getHeight();
	return builder.get();
}

glu::TextureTestUtil::ReferenceParams TextureBorderClampTest::genSamplerParams (const IterationConfig& config) const
{
	const tcu::TextureFormat				texFormat		= tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode);
	glu::TextureTestUtil::ReferenceParams	refParams		(glu::TextureTestUtil::TEXTURETYPE_2D);

	refParams.sampler					= glu::mapGLSampler(config.sWrapMode, config.tWrapMode, config.minFilter, config.magFilter);
	refParams.sampler.borderColor		= config.borderColor;
	refParams.sampler.compare			= (!m_useShadowSampler) ? (tcu::Sampler::COMPAREMODE_NONE) : (glu::mapGLCompareFunc(config.compareMode));
	refParams.sampler.depthStencilMode	= m_sampleMode;
	refParams.lodMode					= glu::TextureTestUtil::LODMODE_EXACT;
	refParams.samplerType				= (!m_useShadowSampler) ? (glu::TextureTestUtil::getSamplerType(texFormat)) : (glu::TextureTestUtil::SAMPLERTYPE_SHADOW);
	refParams.colorScale				= config.lookupScale;
	refParams.colorBias					= config.lookupBias;
	refParams.ref						= config.compareRef;

	// compare can only be used with depth textures
	if (!isDepthFormat(m_texFormat, m_sampleMode))
		DE_ASSERT(refParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE);

	// sampler type must match compare mode
	DE_ASSERT(m_useShadowSampler == (config.compareMode != GL_NONE));

	// in gather, weird mapping is most likely an error
	if (m_samplingFunction == SAMPLE_GATHER)
	{
		DE_ASSERT(refParams.colorScale == tcu::Vec4(refParams.colorScale.x()));
		DE_ASSERT(refParams.colorBias == tcu::Vec4(refParams.colorBias.x()));
	}

	return refParams;
}

glu::ShaderProgram* TextureBorderClampTest::genGatherProgram (void) const
{
	const std::string	glslVersionDecl	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType()));
	const std::string	vtxSource		= glslVersionDecl + "\n"
										"in highp vec4 a_position;\n"
										"in highp vec2 a_texcoord;\n"
										"out highp vec2 v_texcoord;\n"
										"void main()\n"
										"{\n"
										"	gl_Position = a_position;\n"
										"	v_texcoord = a_texcoord;\n"
										"}\n";
	const char*			samplerType;
	const char*			lookup;
	std::ostringstream	fragSource;

	if (m_useShadowSampler)
	{
		samplerType	= "sampler2DShadow";
		lookup		= "textureGather(u_sampler, v_texcoord, u_ref)";
	}
	else
	{
		switch (m_channelClass)
		{
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				samplerType	= "sampler2D";
				lookup		= "textureGather(u_sampler, v_texcoord)";
				break;

			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				samplerType	= "isampler2D";
				lookup		= "vec4(textureGather(u_sampler, v_texcoord))";
				break;

			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				samplerType	= "usampler2D";
				lookup		= "vec4(textureGather(u_sampler, v_texcoord))";
				break;

			default:
				samplerType	= "";
				lookup		= "";
				DE_ASSERT(false);
		}
	}

	fragSource	<<	glslVersionDecl + "\n"
					"uniform highp " << samplerType << " u_sampler;\n"
					"uniform highp vec4 u_colorScale;\n"
					"uniform highp vec4 u_colorBias;\n"
				<<	((m_useShadowSampler) ? ("uniform highp float u_ref;\n") : (""))
				<<	"in highp vec2 v_texcoord;\n"
					"layout(location=0) out highp vec4 o_color;\n"
					"void main()\n"
					"{\n"
					"	o_color = " << lookup << " * u_colorScale + u_colorBias;\n"
					"}\n";

	return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vtxSource) << glu::FragmentSource(fragSource.str()));
}

class TextureBorderClampFormatCase : public TextureBorderClampTest
{
public:
									TextureBorderClampFormatCase	(Context&						context,
																	 const char*					name,
																	 const char*					description,
																	 deUint32						texFormat,
																	 tcu::Sampler::DepthStencilMode	mode,
																	 StateType						stateType,
																	 SizeType						sizeType,
																	 deUint32						filter,
																	 SamplingFunction				samplingFunction);

private:
	void							init							(void);

	int								getNumIterations				(void) const;
	IterationConfig					getIteration					(int ndx) const;

	const SizeType					m_sizeType;
	const deUint32					m_filter;

	std::vector<IterationConfig>	m_iterations;
};


TextureBorderClampFormatCase::TextureBorderClampFormatCase	(Context&						context,
															 const char*					name,
															 const char*					description,
															 deUint32						texFormat,
															 tcu::Sampler::DepthStencilMode	mode,
															 StateType						stateType,
															 SizeType						sizeType,
															 deUint32						filter,
															 SamplingFunction				samplingFunction)
	: TextureBorderClampTest(context,
							 name,
							 description,
							 texFormat,
							 mode,
							 stateType,
							 (sizeType == SIZE_POT) ? (32) : (17),
							 (sizeType == SIZE_POT) ? (16) : (31),
							 samplingFunction)
	, m_sizeType			(sizeType)
	, m_filter				(filter)
{
	if (m_sizeType == SIZE_POT)
		DE_ASSERT(deIsPowerOfTwo32(m_texWidth) && deIsPowerOfTwo32(m_texHeight));
	else
		DE_ASSERT(!deIsPowerOfTwo32(m_texWidth) && !deIsPowerOfTwo32(m_texHeight));

	if (glu::isCompressedFormat(texFormat))
	{
		const tcu::CompressedTexFormat	compressedFormat	= glu::mapGLCompressedTexFormat(texFormat);
		const tcu::IVec3				blockPixelSize		= tcu::getBlockPixelSize(compressedFormat);

		// is (not) multiple of a block size
		if (m_sizeType == SIZE_POT)
			DE_ASSERT((m_texWidth % blockPixelSize.x()) == 0 && (m_texHeight % blockPixelSize.y()) == 0);
		else
			DE_ASSERT((m_texWidth % blockPixelSize.x()) != 0 && (m_texHeight % blockPixelSize.y()) != 0);

		DE_UNREF(blockPixelSize);
	}
}

void TextureBorderClampFormatCase::init (void)
{
	TextureBorderClampTest::init();

	// \note TextureBorderClampTest::init() creates texture
	const tcu::TextureFormat		texFormat		= tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
	const tcu::TextureFormatInfo	texFormatInfo	= tcu::getTextureFormatInfo(texFormat);

	// iterations

	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-1.5f, -3.0f);
		iteration.p1			= tcu::Vec2( 1.5f,  2.5f);
		iteration.borderColor	= mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.3f, 0.7f, 0.2f, 0.5f));
		m_iterations.push_back(iteration);
	}
	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-0.5f, 0.75f);
		iteration.p1			= tcu::Vec2(0.25f, 1.25f);
		iteration.borderColor	= mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.9f, 0.2f, 0.4f, 0.6f));
		m_iterations.push_back(iteration);
	}

	// common parameters
	for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
	{
		IterationConfig& iteration = m_iterations[ndx];

		if (m_samplingFunction == SAMPLE_GATHER)
		{
			iteration.lookupScale	= tcu::Vec4(texFormatInfo.lookupScale.x());
			iteration.lookupBias	= tcu::Vec4(texFormatInfo.lookupBias.x());
		}
		else
		{
			iteration.lookupScale	= texFormatInfo.lookupScale;
			iteration.lookupBias	= texFormatInfo.lookupBias;
		}

		iteration.minFilter		= m_filter;
		iteration.magFilter		= m_filter;
		iteration.sWrapMode		= GL_CLAMP_TO_BORDER;
		iteration.tWrapMode		= GL_CLAMP_TO_BORDER;
		iteration.compareMode	= GL_NONE;
		iteration.compareRef	= 0.0f;
	}
}

int TextureBorderClampFormatCase::getNumIterations	(void) const
{
	return (int)m_iterations.size();
}

TextureBorderClampTest::IterationConfig TextureBorderClampFormatCase::getIteration (int ndx) const
{
	return m_iterations[ndx];
}

class TextureBorderClampRangeClampCase : public TextureBorderClampTest
{
public:
									TextureBorderClampRangeClampCase	(Context&						context,
																		 const char*					name,
																		 const char*					description,
																		 deUint32						texFormat,
																		 tcu::Sampler::DepthStencilMode	mode,
																		 deUint32						filter);

private:
	void							init								(void);

	int								getNumIterations					(void) const;
	IterationConfig					getIteration						(int ndx) const;

	const deUint32					m_filter;
	std::vector<IterationConfig>	m_iterations;
};

TextureBorderClampRangeClampCase::TextureBorderClampRangeClampCase	(Context&						context,
																	 const char*					name,
																	 const char*					description,
																	 deUint32						texFormat,
																	 tcu::Sampler::DepthStencilMode	mode,
																	 deUint32						filter)
	: TextureBorderClampTest(context, name, description, texFormat, mode, TextureBorderClampTest::STATE_TEXTURE_PARAM, 8, 32, SAMPLE_FILTER)
	, m_filter				(filter)
{
}

void TextureBorderClampRangeClampCase::init (void)
{
	TextureBorderClampTest::init();

	const tcu::TextureFormat	texFormat		= tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
	const bool					isDepth			= isDepthFormat(m_texFormat, m_sampleMode);
	const bool					isFloat			= m_channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
	const bool					isFixed			= m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
	const bool					isPureInteger	= m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;

	if (isDepth || isFloat)
	{
		// infinities are commonly used values on depth/float borders
		{
			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-1.2f, -3.0f);
			iteration.p1			= tcu::Vec2( 1.2f,  2.5f);
			iteration.borderColor	= rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity()));
			iteration.lookupScale	= tcu::Vec4(0.5f); // scale & bias to [0.25, 0.5] range to make out-of-range values visible
			iteration.lookupBias	= tcu::Vec4(0.25f);
			iteration.description	= "border value infinity";
			m_iterations.push_back(iteration);
		}
		{
			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-0.25f, -0.75f);
			iteration.p1			= tcu::Vec2( 2.25f,  1.25f);
			iteration.borderColor	= rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity()));
			iteration.lookupScale	= tcu::Vec4(0.5f);
			iteration.lookupBias	= tcu::Vec4(0.25f);
			iteration.description	= "border value negative infinity";
			m_iterations.push_back(iteration);
		}
	}
	else if (isPureInteger)
	{
		const tcu::IVec4			numBits		= tcu::getTextureFormatBitDepth(texFormat);
		const bool					isSigned	= m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;

		// can't overflow 32bit integers with 32bit integers
		for (int ndx = 0; ndx < 4; ++ndx)
			DE_ASSERT(numBits[ndx] == 0 || numBits[ndx] == 8 || numBits[ndx] == 16);

		const tcu::IVec4	minValue		= getNBitIntegerVec4MinValue(isSigned, numBits);
		const tcu::IVec4	maxValue		= getNBitIntegerVec4MaxValue(isSigned, numBits);
		const tcu::IVec4	valueRange		= maxValue - minValue;
		const tcu::IVec4	divSafeRange	((valueRange[0]==0) ? (1) : (valueRange[0]),
											 (valueRange[1]==0) ? (1) : (valueRange[1]),
											 (valueRange[2]==0) ? (1) : (valueRange[2]),
											 (valueRange[3]==0) ? (1) : (valueRange[3]));

		// format max
		{
			const tcu::IVec4 value = maxValue + tcu::IVec4(1);

			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-1.2f, -3.0f);
			iteration.p1			= tcu::Vec2( 1.2f,  2.5f);
			iteration.borderColor	= (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>()));
			iteration.lookupScale	= tcu::Vec4(0.5f) / divSafeRange.cast<float>();
			iteration.lookupBias	= (isSigned) ? (tcu::Vec4(0.5f)) : (tcu::Vec4(0.25f));
			iteration.description	= "border values one larger than maximum";
			m_iterations.push_back(iteration);
		}
		// format min
		if (isSigned)
		{
			const tcu::IVec4 value = minValue - tcu::IVec4(1);

			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-0.25f, -0.75f);
			iteration.p1			= tcu::Vec2( 2.25f,  1.25f);
			iteration.borderColor	= rr::GenericVec4(value);
			iteration.lookupScale	= tcu::Vec4(0.5f) / divSafeRange.cast<float>();
			iteration.lookupBias	= tcu::Vec4(0.5f);
			iteration.description	= "border values one less than minimum";
			m_iterations.push_back(iteration);
		}
		// (u)int32 max
		{
			const tcu::IVec4 value = (isSigned) ? (tcu::IVec4(std::numeric_limits<deInt32>::max())) : (tcu::IVec4(std::numeric_limits<deUint32>::max()));

			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-1.6f, -2.1f);
			iteration.p1			= tcu::Vec2( 1.2f,  3.5f);
			iteration.borderColor	= (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>()));
			iteration.lookupScale	= tcu::Vec4(0.5f) / divSafeRange.cast<float>();
			iteration.lookupBias	= tcu::Vec4(0.25f);
			iteration.description	= "border values 32-bit maximum";
			m_iterations.push_back(iteration);
		}
		// int32 min
		if (isSigned)
		{
			const tcu::IVec4 value = tcu::IVec4(std::numeric_limits<deInt32>::min());

			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-2.6f, -4.0f);
			iteration.p1			= tcu::Vec2( 1.1f,  1.5f);
			iteration.borderColor	= rr::GenericVec4(value);
			iteration.lookupScale	= tcu::Vec4(0.5f) / divSafeRange.cast<float>();
			iteration.lookupBias	= tcu::Vec4(0.25f);
			iteration.description	= "border values 0";
			m_iterations.push_back(iteration);
		}
	}
	else if (isFixed)
	{
		const bool		isSigned	= m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;;
		const tcu::Vec4	lookupBias	= (isSigned) ? (tcu::Vec4(0.5f))    : (tcu::Vec4(0.25f)); // scale & bias to [0.25, 0.5] range to make out-of-range values visible
		const tcu::Vec4	lookupScale	= (isSigned) ? (tcu::Vec4(0.25f))   : (tcu::Vec4(0.5f));

		{
			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-1.2f, -3.0f);
			iteration.p1			= tcu::Vec2( 1.2f,  2.5f);
			iteration.borderColor	= mapToFormatColorUnits(texFormat, tcu::Vec4(1.1f, 1.3f, 2.2f, 1.3f));
			iteration.lookupScale	= lookupScale;
			iteration.lookupBias	= lookupBias;
			iteration.description	= "border values larger than maximum";
			m_iterations.push_back(iteration);
		}
		{
			IterationConfig iteration;
			iteration.p0			= tcu::Vec2(-0.25f, -0.75f);
			iteration.p1			= tcu::Vec2( 2.25f,  1.25f);
			iteration.borderColor	= mapToFormatColorUnits(texFormat, tcu::Vec4(-0.2f, -0.9f, -2.4f, -0.6f));
			iteration.lookupScale	= lookupScale;
			iteration.lookupBias	= lookupBias;
			iteration.description	= "border values less than minimum";
			m_iterations.push_back(iteration);
		}
	}
	else
		DE_ASSERT(false);

	// common parameters
	for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
	{
		IterationConfig& iteration = m_iterations[ndx];

		iteration.minFilter		= m_filter;
		iteration.magFilter		= m_filter;
		iteration.sWrapMode		= GL_CLAMP_TO_BORDER;
		iteration.tWrapMode		= GL_CLAMP_TO_BORDER;
		iteration.compareMode	= GL_NONE;
		iteration.compareRef	= 0.0f;
	}
}

int TextureBorderClampRangeClampCase::getNumIterations	(void) const
{
	return (int)m_iterations.size();
}

TextureBorderClampTest::IterationConfig TextureBorderClampRangeClampCase::getIteration (int ndx) const
{
	return m_iterations[ndx];
}

class TextureBorderClampPerAxisCase2D : public TextureBorderClampTest
{
public:
									TextureBorderClampPerAxisCase2D	(Context&						context,
																	 const char*					name,
																	 const char*					description,
																	 deUint32						texFormat,
																	 tcu::Sampler::DepthStencilMode	mode,
																	 SizeType						sizeType,
																	 deUint32						filter,
																	 deUint32						texSWrap,
																	 deUint32						texTWrap,
																	 SamplingFunction				samplingFunction);

private:
	void							init							(void);

	int								getNumIterations				(void) const;
	IterationConfig					getIteration					(int ndx) const;

	const deUint32					m_texSWrap;
	const deUint32					m_texTWrap;
	const deUint32					m_filter;

	std::vector<IterationConfig>	m_iterations;
};

TextureBorderClampPerAxisCase2D::TextureBorderClampPerAxisCase2D (Context&							context,
																  const char*						name,
																  const char*						description,
																  deUint32							texFormat,
																  tcu::Sampler::DepthStencilMode	mode,
																  SizeType							sizeType,
																  deUint32							filter,
																  deUint32							texSWrap,
																  deUint32							texTWrap,
																  SamplingFunction					samplingFunction)
	: TextureBorderClampTest(context,
							 name,
							 description,
							 texFormat,
							 mode,
							 TextureBorderClampTest::STATE_TEXTURE_PARAM,
							 (sizeType == SIZE_POT) ? (16) : (7),
							 (sizeType == SIZE_POT) ? (8) : (9),
							 samplingFunction)
	, m_texSWrap			(texSWrap)
	, m_texTWrap			(texTWrap)
	, m_filter				(filter)
{
}

void TextureBorderClampPerAxisCase2D::init (void)
{
	TextureBorderClampTest::init();

	// \note TextureBorderClampTest::init() creates texture
	const tcu::TextureFormat		texFormat		= tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
	const tcu::TextureFormatInfo	texFormatInfo	= tcu::getTextureFormatInfo(texFormat);

	IterationConfig iteration;
	iteration.p0			= tcu::Vec2(-0.25f, -0.75f);
	iteration.p1			= tcu::Vec2( 2.25f,  1.25f);
	iteration.borderColor	= mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.4f, 0.9f, 0.1f, 0.2f));

	if (m_samplingFunction == SAMPLE_GATHER)
	{
		iteration.lookupScale	= tcu::Vec4(texFormatInfo.lookupScale.x());
		iteration.lookupBias	= tcu::Vec4(texFormatInfo.lookupBias.x());
	}
	else
	{
		iteration.lookupScale	= texFormatInfo.lookupScale;
		iteration.lookupBias	= texFormatInfo.lookupBias;
	}

	iteration.minFilter		= m_filter;
	iteration.magFilter		= m_filter;
	iteration.sWrapMode		= m_texSWrap;
	iteration.tWrapMode		= m_texTWrap;
	iteration.compareMode	= GL_NONE;
	iteration.compareRef	= 0.0f;

	m_iterations.push_back(iteration);
}

int TextureBorderClampPerAxisCase2D::getNumIterations	(void) const
{
	return (int)m_iterations.size();
}

TextureBorderClampTest::IterationConfig TextureBorderClampPerAxisCase2D::getIteration (int ndx) const
{
	return m_iterations[ndx];
}

class TextureBorderClampDepthCompareCase : public TextureBorderClampTest
{
public:
									TextureBorderClampDepthCompareCase	(Context&			context,
																		 const char*		name,
																		 const char*		description,
																		 deUint32			texFormat,
																		 SizeType			sizeType,
																		 deUint32			filter,
																		 SamplingFunction	samplingFunction);

private:
	void							init								(void);

	int								getNumIterations					(void) const;
	IterationConfig					getIteration						(int ndx) const;

	const deUint32					m_filter;
	std::vector<IterationConfig>	m_iterations;
};

TextureBorderClampDepthCompareCase::TextureBorderClampDepthCompareCase (Context&			context,
																		const char*			name,
																		const char*			description,
																		deUint32			texFormat,
																		SizeType			sizeType,
																		deUint32			filter,
																		SamplingFunction	samplingFunction)
	: TextureBorderClampTest(context,
							 name,
							 description,
							 texFormat,
							 tcu::Sampler::MODE_DEPTH,
							 TextureBorderClampTest::STATE_TEXTURE_PARAM,
							 (sizeType == SIZE_POT) ? (32) : (13),
							 (sizeType == SIZE_POT) ? (16) : (17),
							 samplingFunction,
							 FLAG_USE_SHADOW_SAMPLER)
	, m_filter				(filter)
{
}

void TextureBorderClampDepthCompareCase::init (void)
{
	TextureBorderClampTest::init();

	// 0.5 <= 0.7
	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-0.15f, -0.35f);
		iteration.p1			= tcu::Vec2( 1.25f,  1.1f);
		iteration.borderColor	= rr::GenericVec4(tcu::Vec4(0.7f, 0.0f, 0.0f, 0.0f));
		iteration.description	= "Border color in [0, 1] range";
		iteration.compareMode	= GL_LEQUAL;
		iteration.compareRef	= 0.5f;
		m_iterations.push_back(iteration);
	}

	// 1.5 <= 1.0
	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-0.15f, -0.35f);
		iteration.p1			= tcu::Vec2( 1.25f,  1.1f);
		iteration.borderColor	= rr::GenericVec4(tcu::Vec4(1.5f, 0.0f, 0.0f, 0.0f));
		iteration.description	= "Border color > 1, should be clamped";
		iteration.compareMode	= GL_LEQUAL;
		iteration.compareRef	= 1.0f;
		m_iterations.push_back(iteration);
	}

	// -0.5 >= 0.0
	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-0.15f, -0.35f);
		iteration.p1			= tcu::Vec2( 1.25f,  1.1f);
		iteration.borderColor	= rr::GenericVec4(tcu::Vec4(-0.5f, 0.0f, 0.0f, 0.0f));
		iteration.description	= "Border color < 0, should be clamped";
		iteration.compareMode	= GL_GEQUAL;
		iteration.compareRef	= 0.0f;
		m_iterations.push_back(iteration);
	}

	// inf < 1.25
	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-0.15f, -0.35f);
		iteration.p1			= tcu::Vec2( 1.25f,  1.1f);
		iteration.borderColor	= rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f));
		iteration.description	= "Border color == inf, should be clamped; ref > 1";
		iteration.compareMode	= GL_LESS;
		iteration.compareRef	= 1.25f;
		m_iterations.push_back(iteration);
	}

	// -inf > -0.5
	{
		IterationConfig iteration;
		iteration.p0			= tcu::Vec2(-0.15f, -0.35f);
		iteration.p1			= tcu::Vec2( 1.25f,  1.1f);
		iteration.borderColor	= rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f));
		iteration.description	= "Border color == inf, should be clamped; ref < 0";
		iteration.compareMode	= GL_GREATER;
		iteration.compareRef	= -0.5f;
		m_iterations.push_back(iteration);
	}

	// common parameters
	for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx)
	{
		IterationConfig& iteration = m_iterations[ndx];

		iteration.lookupScale	= tcu::Vec4(1.0);
		iteration.lookupBias	= tcu::Vec4(0.0);
		iteration.minFilter		= m_filter;
		iteration.magFilter		= m_filter;
		iteration.sWrapMode		= GL_CLAMP_TO_BORDER;
		iteration.tWrapMode		= GL_CLAMP_TO_BORDER;
	}
}

int TextureBorderClampDepthCompareCase::getNumIterations	(void) const
{
	return (int)m_iterations.size();
}

TextureBorderClampTest::IterationConfig TextureBorderClampDepthCompareCase::getIteration (int ndx) const
{
	return m_iterations[ndx];
}

class TextureBorderClampUnusedChannelCase : public TextureBorderClampTest
{
public:
									TextureBorderClampUnusedChannelCase	(Context&						context,
																		 const char*					name,
																		 const char*					description,
																		 deUint32						texFormat,
																		 tcu::Sampler::DepthStencilMode	depthStencilMode);

private:
	void							init								(void);

	int								getNumIterations					(void) const;
	IterationConfig					getIteration						(int ndx) const;

	std::vector<IterationConfig>	m_iterations;
};

TextureBorderClampUnusedChannelCase::TextureBorderClampUnusedChannelCase (Context&							context,
																		  const char*						name,
																		  const char*						description,
																		  deUint32							texFormat,
																		  tcu::Sampler::DepthStencilMode	depthStencilMode)
	: TextureBorderClampTest(context,
							 name,
							 description,
							 texFormat,
							 depthStencilMode,
							 TextureBorderClampTest::STATE_TEXTURE_PARAM,
							 8,
							 8,
							 SAMPLE_FILTER)
{
}

static rr::GenericVec4 selectComponents (const rr::GenericVec4& trueComponents, const rr::GenericVec4& falseComponents, const tcu::BVec4& m)
{
	return rr::GenericVec4(tcu::select(trueComponents.get<deUint32>(), falseComponents.get<deUint32>(), m));
}

void TextureBorderClampUnusedChannelCase::init (void)
{
	TextureBorderClampTest::init();

	// \note TextureBorderClampTest::init() creates texture
	const tcu::TextureFormat		texFormat			= tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode);
	const tcu::TextureFormatInfo	texFormatInfo		= tcu::getTextureFormatInfo(texFormat);
	const tcu::BVec4				channelMask			= tcu::getTextureFormatChannelMask(texFormat);
	const float						maxChannelValue		= (channelMask[0]) ? (texFormatInfo.valueMax[0])
														: (channelMask[1]) ? (texFormatInfo.valueMax[1])
														: (channelMask[2]) ? (texFormatInfo.valueMax[2])
														:                    (texFormatInfo.valueMax[3]);

	const rr::GenericVec4			effectiveColors		= mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.6f));
	rr::GenericVec4					nonEffectiveColors;

	switch (m_channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f));
			break;

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deInt32>());
			break;

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deUint32>());
			break;
		default:
			DE_ASSERT(false);
	}

	IterationConfig iteration;
	iteration.p0			= tcu::Vec2(-0.25f, -0.75f);
	iteration.p1			= tcu::Vec2( 2.25f,  1.25f);
	iteration.borderColor	= selectComponents(effectiveColors, nonEffectiveColors, channelMask);
	iteration.lookupScale	= texFormatInfo.lookupScale;
	iteration.lookupBias	= texFormatInfo.lookupBias;
	iteration.minFilter		= GL_NEAREST;
	iteration.magFilter		= GL_NEAREST;
	iteration.sWrapMode		= GL_CLAMP_TO_BORDER;
	iteration.tWrapMode		= GL_CLAMP_TO_BORDER;
	iteration.compareMode	= GL_NONE;
	iteration.compareRef	= 0.0f;
	iteration.description	= "Setting values to unused border color components";

	m_iterations.push_back(iteration);
}

int TextureBorderClampUnusedChannelCase::getNumIterations	(void) const
{
	return (int)m_iterations.size();
}

TextureBorderClampTest::IterationConfig TextureBorderClampUnusedChannelCase::getIteration (int ndx) const
{
	return m_iterations[ndx];
}

class TextureBorderClampPerAxisCase3D : public TestCase
{
public:
														TextureBorderClampPerAxisCase3D	(Context&		context,
																						 const char*	name,
																						 const char*	description,
																						 deUint32		texFormat,
																						 SizeType		size,
																						 deUint32		filter,
																						 deUint32		sWrap,
																						 deUint32		tWrap,
																						 deUint32		rWrap);

private:
	void												init							(void);
	void												deinit							(void);
	IterateResult										iterate							(void);

	void												renderTo						(tcu::Surface&									surface,
																						 const glu::TextureTestUtil::ReferenceParams&	samplerParams);

	void												logParams						(const glu::TextureTestUtil::ReferenceParams&	samplerParams);

	void												verifyImage						(const tcu::Surface&							image,
																						 const glu::TextureTestUtil::ReferenceParams&	samplerParams);

	glu::TextureTestUtil::ReferenceParams				getSamplerParams				(void) const;
	deUint32											getCaseSeed						(void) const;

	enum
	{
		VIEWPORT_WIDTH		= 128,
		VIEWPORT_HEIGHT		= 128,
	};

	const deUint32										m_texFormat;
	const tcu::TextureChannelClass						m_channelClass;
	const tcu::IVec3									m_size;
	const deUint32										m_filter;
	const deUint32										m_sWrap;
	const deUint32										m_tWrap;
	const deUint32										m_rWrap;

	de::MovePtr<glu::Texture3D>							m_texture;
	de::MovePtr<gls::TextureTestUtil::TextureRenderer>	m_renderer;

	rr::GenericVec4										m_borderColor;
	std::vector<float>									m_texCoords;
	tcu::Vec4											m_lookupScale;
	tcu::Vec4											m_lookupBias;
};

TextureBorderClampPerAxisCase3D::TextureBorderClampPerAxisCase3D (Context&		context,
																  const char*	name,
																  const char*	description,
																  deUint32		texFormat,
																  SizeType		size,
																  deUint32		filter,
																  deUint32		sWrap,
																  deUint32		tWrap,
																  deUint32		rWrap)
	: TestCase			(context, name, description)
	, m_texFormat		(texFormat)
	, m_channelClass	(getFormatChannelClass(texFormat, tcu::Sampler::MODE_LAST))
	, m_size			((size == SIZE_POT) ? (tcu::IVec3(8, 16, 4)) : (tcu::IVec3(13, 5, 7)))
	, m_filter			(filter)
	, m_sWrap			(sWrap)
	, m_tWrap			(tWrap)
	, m_rWrap			(rWrap)
{
}

void TextureBorderClampPerAxisCase3D::init (void)
{
	const bool				supportsES32	= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
	const glu::GLSLVersion	glslVersion		= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp"))
		throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension");

	if (glu::isCompressedFormat(m_texFormat)													&&
		!supportsES32																			&&
		tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat))							&&
		!m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
	{
		throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension");
	}
	if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888"))
		throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension");
	if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH ||
		m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT)
	{
		throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport");
	}

	// resources
	m_texture = genDefaultTexture<glu::Texture3D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, m_size);
	m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glslVersion, glu::PRECISION_HIGHP));

	// texture info
	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Created 3D texture with format " << glu::getTextureFormatName(m_texFormat)
						<< ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ", " << m_texture->getRefTexture().getDepth() << ")\n"
						<< tcu::TestLog::EndMessage;

	// tex coord
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Setting tex coords bottom-left: (-1, -1, -1.5), top-right (2, 2, 2.5)\n"
							<< tcu::TestLog::EndMessage;

		m_texCoords.resize(4*3);

		m_texCoords[0] = -1.0f; m_texCoords[ 1] = -1.0f; m_texCoords[ 2] = -1.5f;
		m_texCoords[3] = -1.0f; m_texCoords[ 4] =  2.0f; m_texCoords[ 5] = 0.5f;
		m_texCoords[6] =  2.0f; m_texCoords[ 7] = -1.0f; m_texCoords[ 8] = 0.5f;
		m_texCoords[9] =  2.0f; m_texCoords[10] =  2.0f; m_texCoords[11] =  2.5f;
	}

	// set render params
	{
		const tcu::TextureFormat		texFormat		= m_texture->getRefTexture().getFormat();
		const tcu::TextureFormatInfo	texFormatInfo	= tcu::getTextureFormatInfo(texFormat);

		m_borderColor	= mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.2f, 0.6f, 0.9f, 0.4f));

		m_lookupScale	= texFormatInfo.lookupScale;
		m_lookupBias	= texFormatInfo.lookupBias;
	}
}

void TextureBorderClampPerAxisCase3D::deinit (void)
{
	m_texture.clear();
	m_renderer.clear();
}

TextureBorderClampPerAxisCase3D::IterateResult TextureBorderClampPerAxisCase3D::iterate (void)
{
	tcu::Surface								renderedFrame		(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	const glu::TextureTestUtil::ReferenceParams	samplerParams		= getSamplerParams();

	logParams(samplerParams);
	renderTo(renderedFrame, samplerParams);
	verifyImage(renderedFrame, samplerParams);

	return STOP;
}

void TextureBorderClampPerAxisCase3D::logParams (const glu::TextureTestUtil::ReferenceParams& samplerParams)
{
	const std::string	borderColorString	= (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)   ? (de::toString(m_borderColor.get<deInt32>()))
											: (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(m_borderColor.get<deUint32>()))
											:																  (de::toString(m_borderColor.get<float>()));

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "Border color is " << borderColorString << "\n"
						<< "Texture lookup bias: " << samplerParams.colorBias << "\n"
						<< "Texture lookup scale: " << samplerParams.colorScale << "\n"
						<< "Filter: " << glu::getTextureFilterName(m_filter) << "\n"
						<< "Wrap mode: s = " << glu::getRepeatModeStr(m_sWrap)
							<< ", t = " << glu::getRepeatModeStr(m_tWrap)
							<< ", r = " << glu::getRepeatModeStr(m_rWrap) << "\n"
						<< tcu::TestLog::EndMessage;
}

void TextureBorderClampPerAxisCase3D::renderTo (tcu::Surface&									surface,
												const glu::TextureTestUtil::ReferenceParams&	samplerParams)
{
	const glw::Functions&						gl			= m_context.getRenderContext().getFunctions();
	const gls::TextureTestUtil::RandomViewport	viewport	(m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getCaseSeed());

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture());

	// Setup filtering and wrap modes.
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		glu::getGLWrapMode(samplerParams.sampler.wrapS));
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		glu::getGLWrapMode(samplerParams.sampler.wrapT));
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		glu::getGLWrapMode(samplerParams.sampler.wrapR));
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	glu::getGLFilterMode(samplerParams.sampler.minFilter));
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,	glu::getGLFilterMode(samplerParams.sampler.magFilter));

	switch (m_channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<float>());
			break;

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			gl.texParameterIiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deInt32>());
			break;

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			gl.texParameterIuiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deUint32>());
			break;

		default:
			DE_ASSERT(false);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
	m_renderer->renderQuad(0, &m_texCoords[0], samplerParams);
	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess());
}

void TextureBorderClampPerAxisCase3D::verifyImage (const tcu::Surface&							renderedFrame,
												   const glu::TextureTestUtil::ReferenceParams&	samplerParams)
{
	const tcu::PixelFormat			pixelFormat			= m_context.getRenderTarget().getPixelFormat();
	const int						colorErrorBits		= 2;
	const tcu::IVec4				colorBits			= tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0));
	tcu::Surface					reference			(renderedFrame.getWidth(), renderedFrame.getHeight());
	tcu::Surface					errorMask			(renderedFrame.getWidth(), renderedFrame.getHeight());
	tcu::LodPrecision				lodPrecision;
	tcu::LookupPrecision			lookupPrecision;
	int								numFailedPixels;

	lodPrecision.derivateBits		= 18;
	lodPrecision.lodBits			= 5;

	lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale;
	lookupPrecision.coordBits		= tcu::IVec3(20,20,0);
	lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
	lookupPrecision.colorMask		= glu::TextureTestUtil::getCompareMask(pixelFormat);

	glu::TextureTestUtil::sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), &m_texCoords[0], samplerParams);

	numFailedPixels = glu::TextureTestUtil::computeTextureLookupDiff(renderedFrame.getAccess(), reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(),
																	 &m_texCoords[0], samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog());

	if (numFailedPixels > 0)
		m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage;
	m_testCtx.getLog()	<< tcu::TestLog::ImageSet("VerifyResult", "Verification result")
						<< tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame);
	if (numFailedPixels > 0)
	{
		m_testCtx.getLog()	<< tcu::TestLog::Image("Reference", "Ideal reference image", reference)
							<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
	}
	m_testCtx.getLog() << tcu::TestLog::EndImageSet;

	if (numFailedPixels == 0)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
}

glu::TextureTestUtil::ReferenceParams TextureBorderClampPerAxisCase3D::getSamplerParams (void) const
{
	const tcu::TextureFormat				texFormat		= m_texture->getRefTexture().getFormat();
	glu::TextureTestUtil::ReferenceParams	refParams		(glu::TextureTestUtil::TEXTURETYPE_3D);

	refParams.sampler					= glu::mapGLSampler(m_sWrap, m_tWrap, m_rWrap, m_filter, m_filter);
	refParams.sampler.borderColor		= m_borderColor;
	refParams.lodMode					= glu::TextureTestUtil::LODMODE_EXACT;
	refParams.samplerType				= glu::TextureTestUtil::getSamplerType(texFormat);
	refParams.colorScale				= m_lookupScale;
	refParams.colorBias					= m_lookupBias;

	return refParams;
}

deUint32 TextureBorderClampPerAxisCase3D::getCaseSeed (void) const
{
	tcu::SeedBuilder builder;
	builder	<< std::string(getName())
			<< m_texFormat
			<< m_filter
			<< m_sWrap
			<< m_tWrap
			<< m_rWrap
			<< m_texture->getRefTexture().getWidth()
			<< m_texture->getRefTexture().getHeight()
			<< m_texture->getRefTexture().getDepth();
	return builder.get();
}

} // anonymous

TextureBorderClampTests::TextureBorderClampTests (Context& context)
	: TestCaseGroup(context, "border_clamp", "EXT_texture_border_clamp tests")
{
}

TextureBorderClampTests::~TextureBorderClampTests (void)
{
}

void TextureBorderClampTests::init (void)
{
	static const struct
	{
		const char*									name;
		deUint32									filter;
		TextureBorderClampTest::SamplingFunction	sampling;
	} s_filters[] =
	{
		{ "nearest",	GL_NEAREST,	TextureBorderClampTest::SAMPLE_FILTER	},
		{ "linear",		GL_LINEAR,	TextureBorderClampTest::SAMPLE_FILTER	},
		{ "gather",		GL_NEAREST,	TextureBorderClampTest::SAMPLE_GATHER	},
	};

	// .formats
	{
		static const struct
		{
			const char*						name;
			deUint32						format;
			tcu::Sampler::DepthStencilMode	mode;
		} formats[] =
		{
			{ "luminance",									GL_LUMINANCE,									tcu::Sampler::MODE_LAST		},
			{ "alpha",										GL_ALPHA,										tcu::Sampler::MODE_LAST		},
			{ "luminance_alpha",							GL_LUMINANCE_ALPHA,								tcu::Sampler::MODE_LAST		},
			{ "bgra",										GL_BGRA,										tcu::Sampler::MODE_LAST		},
			{ "r8",											GL_R8,											tcu::Sampler::MODE_LAST		},
			{ "r8_snorm",									GL_R8_SNORM,									tcu::Sampler::MODE_LAST		},
			{ "rg8",										GL_RG8,											tcu::Sampler::MODE_LAST		},
			{ "rg8_snorm",									GL_RG8_SNORM,									tcu::Sampler::MODE_LAST		},
			{ "rgb8",										GL_RGB8,										tcu::Sampler::MODE_LAST		},
			{ "rgb8_snorm",									GL_RGB8_SNORM,									tcu::Sampler::MODE_LAST		},
			{ "rgb565",										GL_RGB565,										tcu::Sampler::MODE_LAST		},
			{ "rgba4",										GL_RGBA4,										tcu::Sampler::MODE_LAST		},
			{ "rgb5_a1",									GL_RGB5_A1,										tcu::Sampler::MODE_LAST		},
			{ "rgba8",										GL_RGBA8,										tcu::Sampler::MODE_LAST		},
			{ "rgba8_snorm",								GL_RGBA8_SNORM,									tcu::Sampler::MODE_LAST		},
			{ "rgb10_a2",									GL_RGB10_A2,									tcu::Sampler::MODE_LAST		},
			{ "rgb10_a2ui",									GL_RGB10_A2UI,									tcu::Sampler::MODE_LAST		},
			{ "srgb8",										GL_SRGB8,										tcu::Sampler::MODE_LAST		},
			{ "srgb8_alpha8",								GL_SRGB8_ALPHA8,								tcu::Sampler::MODE_LAST		},
			{ "r16f",										GL_R16F,										tcu::Sampler::MODE_LAST		},
			{ "rg16f",										GL_RG16F,										tcu::Sampler::MODE_LAST		},
			{ "rgb16f",										GL_RGB16F,										tcu::Sampler::MODE_LAST		},
			{ "rgba16f",									GL_RGBA16F,										tcu::Sampler::MODE_LAST		},
			{ "r32f",										GL_R32F,										tcu::Sampler::MODE_LAST		},
			{ "rg32f",										GL_RG32F,										tcu::Sampler::MODE_LAST		},
			{ "rgb32f",										GL_RGB32F,										tcu::Sampler::MODE_LAST		},
			{ "rgba32f",									GL_RGBA32F,										tcu::Sampler::MODE_LAST		},
			{ "r11f_g11f_b10f",								GL_R11F_G11F_B10F,								tcu::Sampler::MODE_LAST		},
			{ "rgb9_e5",									GL_RGB9_E5,										tcu::Sampler::MODE_LAST		},
			{ "r8i",										GL_R8I,											tcu::Sampler::MODE_LAST		},
			{ "r8ui",										GL_R8UI,										tcu::Sampler::MODE_LAST		},
			{ "r16i",										GL_R16I,										tcu::Sampler::MODE_LAST		},
			{ "r16ui",										GL_R16UI,										tcu::Sampler::MODE_LAST		},
			{ "r32i",										GL_R32I,										tcu::Sampler::MODE_LAST		},
			{ "r32ui",										GL_R32UI,										tcu::Sampler::MODE_LAST		},
			{ "rg8i",										GL_RG8I,										tcu::Sampler::MODE_LAST		},
			{ "rg8ui",										GL_RG8UI,										tcu::Sampler::MODE_LAST		},
			{ "rg16i",										GL_RG16I,										tcu::Sampler::MODE_LAST		},
			{ "rg16ui",										GL_RG16UI,										tcu::Sampler::MODE_LAST		},
			{ "rg32i",										GL_RG32I,										tcu::Sampler::MODE_LAST		},
			{ "rg32ui",										GL_RG32UI,										tcu::Sampler::MODE_LAST		},
			{ "rgb8i",										GL_RGB8I,										tcu::Sampler::MODE_LAST		},
			{ "rgb8ui",										GL_RGB8UI,										tcu::Sampler::MODE_LAST		},
			{ "rgb16i",										GL_RGB16I,										tcu::Sampler::MODE_LAST		},
			{ "rgb16ui",									GL_RGB16UI,										tcu::Sampler::MODE_LAST		},
			{ "rgb32i",										GL_RGB32I,										tcu::Sampler::MODE_LAST		},
			{ "rgb32ui",									GL_RGB32UI,										tcu::Sampler::MODE_LAST		},
			{ "rgba8i",										GL_RGBA8I,										tcu::Sampler::MODE_LAST		},
			{ "rgba8ui",									GL_RGBA8UI,										tcu::Sampler::MODE_LAST		},
			{ "rgba16i",									GL_RGBA16I,										tcu::Sampler::MODE_LAST		},
			{ "rgba16ui",									GL_RGBA16UI,									tcu::Sampler::MODE_LAST		},
			{ "rgba32i",									GL_RGBA32I,										tcu::Sampler::MODE_LAST		},
			{ "rgba32ui",									GL_RGBA32UI,									tcu::Sampler::MODE_LAST		},
			{ "depth_component16",							GL_DEPTH_COMPONENT16,							tcu::Sampler::MODE_DEPTH	},
			{ "depth_component24",							GL_DEPTH_COMPONENT24,							tcu::Sampler::MODE_DEPTH	},
			{ "depth_component32f",							GL_DEPTH_COMPONENT32F,							tcu::Sampler::MODE_DEPTH	},
			{ "stencil_index8",								GL_STENCIL_INDEX8,								tcu::Sampler::MODE_STENCIL	},
			{ "depth24_stencil8_sample_depth",				GL_DEPTH24_STENCIL8,							tcu::Sampler::MODE_DEPTH	},
			{ "depth32f_stencil8_sample_depth",				GL_DEPTH32F_STENCIL8,							tcu::Sampler::MODE_DEPTH	},
			{ "depth24_stencil8_sample_stencil",			GL_DEPTH24_STENCIL8,							tcu::Sampler::MODE_STENCIL	},
			{ "depth32f_stencil8_sample_stencil",			GL_DEPTH32F_STENCIL8,							tcu::Sampler::MODE_STENCIL	},
			{ "compressed_r11_eac",							GL_COMPRESSED_R11_EAC,							tcu::Sampler::MODE_LAST		},
			{ "compressed_signed_r11_eac",					GL_COMPRESSED_SIGNED_R11_EAC,					tcu::Sampler::MODE_LAST		},
			{ "compressed_rg11_eac",						GL_COMPRESSED_RG11_EAC,							tcu::Sampler::MODE_LAST		},
			{ "compressed_signed_rg11_eac",					GL_COMPRESSED_SIGNED_RG11_EAC,					tcu::Sampler::MODE_LAST		},
			{ "compressed_rgb8_etc2",						GL_COMPRESSED_RGB8_ETC2,						tcu::Sampler::MODE_LAST		},
			{ "compressed_srgb8_etc2",						GL_COMPRESSED_SRGB8_ETC2,						tcu::Sampler::MODE_LAST		},
			{ "compressed_rgb8_punchthrough_alpha1_etc2",	GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,	tcu::Sampler::MODE_LAST		},
			{ "compressed_srgb8_punchthrough_alpha1_etc2",	GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,	tcu::Sampler::MODE_LAST		},
			{ "compressed_rgba8_etc2_eac",					GL_COMPRESSED_RGBA8_ETC2_EAC,					tcu::Sampler::MODE_LAST		},
			{ "compressed_srgb8_alpha8_etc2_eac",			GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,			tcu::Sampler::MODE_LAST		},
		};

		tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "Format tests");
		addChild(formatsGroup);

		// .format
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
		{
			const deUint32							format			= formats[formatNdx].format;
			const tcu::Sampler::DepthStencilMode	sampleMode		= formats[formatNdx].mode;
			const bool								isCompressed	= glu::isCompressedFormat(format);
			const bool								coreFilterable	= isCoreFilterableFormat(format, sampleMode);
			tcu::TestCaseGroup* const				formatGroup		= new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");

			formatsGroup->addChild(formatGroup);

			// .nearest
			// .linear
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
			{
				// [not-compressed]
				// .size_pot
				// .size_npot
				// [compressed]
				// .size_tile_multiple (also pot)
				// .size_not_tile_multiple (also npot)
				for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
				{
					const bool				isNpotCase		= (sizeNdx == 1);
					const char* const		sizePotName		= (!isCompressed) ? ("size_pot") : ("size_tile_multiple");
					const char* const		sizeNpotName	= (!isCompressed) ? ("size_npot") : ("size_not_tile_multiple");
					const char* const		sizeName		= (isNpotCase) ? (sizeNpotName) : (sizePotName);
					const SizeType			sizeType		= (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
					const std::string		caseName		= std::string() + s_filters[filterNdx].name + "_" + sizeName;
					const deUint32			filter			= s_filters[filterNdx].filter;

					if (coreFilterable || !filterRequiresFilterability(filter))
						formatGroup->addChild(new TextureBorderClampFormatCase(m_context,
																			   caseName.c_str(),
																			   "",
																			   format,
																			   sampleMode,
																			   TextureBorderClampFormatCase::STATE_TEXTURE_PARAM,
																			   sizeType,
																			   filter,
																			   s_filters[filterNdx].sampling));
				}
			}
		}
	}

	// .range_clamp
	{
		static const struct
		{
			const char*						name;
			deUint32						format;
			tcu::Sampler::DepthStencilMode	mode;
		} formats[] =
		{
			{ "unorm_color",								GL_R8,					tcu::Sampler::MODE_LAST		},
			{ "snorm_color",								GL_R8_SNORM,			tcu::Sampler::MODE_LAST		},
			{ "float_color",								GL_RG32F,				tcu::Sampler::MODE_LAST		},
			{ "int_color",									GL_R8I,					tcu::Sampler::MODE_LAST		},
			{ "uint_color",									GL_R16UI,				tcu::Sampler::MODE_LAST		},
			{ "srgb_color",									GL_SRGB8_ALPHA8,		tcu::Sampler::MODE_LAST		},
			{ "unorm_depth",								GL_DEPTH_COMPONENT24,	tcu::Sampler::MODE_DEPTH	},
			{ "float_depth",								GL_DEPTH_COMPONENT32F,	tcu::Sampler::MODE_DEPTH	},
			{ "uint_stencil",								GL_STENCIL_INDEX8,		tcu::Sampler::MODE_STENCIL	},
			{ "float_depth_uint_stencil_sample_depth",		GL_DEPTH32F_STENCIL8,	tcu::Sampler::MODE_DEPTH	},
			{ "float_depth_uint_stencil_sample_stencil",	GL_DEPTH32F_STENCIL8,	tcu::Sampler::MODE_STENCIL	},
			{ "unorm_depth_uint_stencil_sample_depth",		GL_DEPTH24_STENCIL8,	tcu::Sampler::MODE_DEPTH	},
			{ "unorm_depth_uint_stencil_sample_stencil",	GL_DEPTH24_STENCIL8,	tcu::Sampler::MODE_STENCIL	},
			{ "compressed_color",							GL_COMPRESSED_RG11_EAC,	tcu::Sampler::MODE_LAST		},
		};

		tcu::TestCaseGroup* const rangeClampGroup = new tcu::TestCaseGroup(m_testCtx, "range_clamp", "Range clamp tests");
		addChild(rangeClampGroup);

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
		for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
		{
			const deUint32							format			= formats[formatNdx].format;
			const tcu::Sampler::DepthStencilMode	sampleMode		= formats[formatNdx].mode;
			const std::string						caseName		= std::string() + s_filters[filterNdx].name + "_" + formats[formatNdx].name;
			const deUint32							filter			= s_filters[filterNdx].filter;
			const bool								coreFilterable	= isCoreFilterableFormat(format, sampleMode);

			if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER)
				continue;

			if (coreFilterable || !filterRequiresFilterability(filter))
				rangeClampGroup->addChild(new TextureBorderClampRangeClampCase(m_context, caseName.c_str(), "", format, sampleMode, filter));
		}
	}

	// .sampler
	{
		static const struct
		{
			const char*						name;
			deUint32						format;
			tcu::Sampler::DepthStencilMode	mode;
		} formats[] =
		{
			{ "unorm_color",		GL_R8,					tcu::Sampler::MODE_LAST		},
			{ "snorm_color",		GL_R8_SNORM,			tcu::Sampler::MODE_LAST		},
			{ "float_color",		GL_RG32F,				tcu::Sampler::MODE_LAST		},
			{ "int_color",			GL_R8I,					tcu::Sampler::MODE_LAST		},
			{ "uint_color",			GL_R16UI,				tcu::Sampler::MODE_LAST		},
			{ "unorm_depth",		GL_DEPTH_COMPONENT24,	tcu::Sampler::MODE_DEPTH	},
			{ "float_depth",		GL_DEPTH_COMPONENT32F,	tcu::Sampler::MODE_DEPTH	},
			{ "uint_stencil",		GL_STENCIL_INDEX8,		tcu::Sampler::MODE_STENCIL	},
			{ "compressed_color",	GL_COMPRESSED_RG11_EAC,	tcu::Sampler::MODE_LAST		},
		};

		tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler param tests");
		addChild(samplerGroup);

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
		{
			const deUint32							format		= formats[formatNdx].format;
			const tcu::Sampler::DepthStencilMode	sampleMode	= formats[formatNdx].mode;
			const char*								caseName	= formats[formatNdx].name;

			samplerGroup->addChild(new TextureBorderClampFormatCase(m_context,
																	caseName,
																	"",
																	format,
																	sampleMode,
																	TextureBorderClampFormatCase::STATE_SAMPLER_PARAM,
																	SIZE_POT,
																	GL_NEAREST,
																	TextureBorderClampFormatCase::SAMPLE_FILTER));
		}
	}

	// .per_axis_wrap_mode
	{
		static const struct
		{
			const char*						name;
			bool							is3D;
		} targets[] =
		{
			{ "texture_2d", false	},
			{ "texture_3d", true	},
		};
		static const struct
		{
			const char*						name;
			deUint32						format;
			tcu::Sampler::DepthStencilMode	mode;
			bool							supports3D;
		} formats[] =
		{
			{ "unorm_color",		GL_RG8,						tcu::Sampler::MODE_LAST,	true	},
			{ "snorm_color",		GL_RG8_SNORM,				tcu::Sampler::MODE_LAST,	true	},
			{ "float_color",		GL_R32F,					tcu::Sampler::MODE_LAST,	true	},
			{ "int_color",			GL_RG16I,					tcu::Sampler::MODE_LAST,	true	},
			{ "uint_color",			GL_R8UI,					tcu::Sampler::MODE_LAST,	true	},
			{ "unorm_depth",		GL_DEPTH_COMPONENT16,		tcu::Sampler::MODE_DEPTH,	false	},
			{ "float_depth",		GL_DEPTH32F_STENCIL8,		tcu::Sampler::MODE_DEPTH,	false	},
			{ "uint_stencil",		GL_DEPTH32F_STENCIL8,		tcu::Sampler::MODE_STENCIL,	false	},
			{ "compressed_color",	GL_COMPRESSED_RGB8_ETC2,	tcu::Sampler::MODE_LAST,	false	},
		};
		static const struct
		{
			const char*	name;
			deUint32	sWrap;
			deUint32	tWrap;
			deUint32	rWrap;
			bool		is3D;
		} wrapConfigs[] =
		{
			// 2d configs
			{ "s_clamp_to_edge_t_clamp_to_border",						GL_CLAMP_TO_EDGE,	GL_CLAMP_TO_BORDER,	GL_NONE,			false	},
			{ "s_repeat_t_clamp_to_border",								GL_REPEAT,			GL_CLAMP_TO_BORDER,	GL_NONE,			false	},
			{ "s_mirrored_repeat_t_clamp_to_border",					GL_MIRRORED_REPEAT,	GL_CLAMP_TO_BORDER,	GL_NONE,			false	},

			// 3d configs
			{ "s_clamp_to_border_t_clamp_to_border_r_clamp_to_border",	GL_CLAMP_TO_BORDER,	GL_CLAMP_TO_BORDER,	GL_CLAMP_TO_BORDER,	true	},
			{ "s_clamp_to_border_t_clamp_to_border_r_repeat",			GL_CLAMP_TO_BORDER,	GL_CLAMP_TO_BORDER,	GL_REPEAT,			true	},
			{ "s_mirrored_repeat_t_clamp_to_border_r_repeat",			GL_MIRRORED_REPEAT,	GL_CLAMP_TO_BORDER,	GL_REPEAT,			true	},
			{ "s_repeat_t_mirrored_repeat_r_clamp_to_border",			GL_REPEAT,			GL_MIRRORED_REPEAT,	GL_CLAMP_TO_BORDER,	true	},
		};

		tcu::TestCaseGroup* const perAxisGroup = new tcu::TestCaseGroup(m_testCtx, "per_axis_wrap_mode", "Per-axis wrapping modes");
		addChild(perAxisGroup);

		// .texture_nd
		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx)
		{
			tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, targets[targetNdx].name, "Texture target test");
			perAxisGroup->addChild(targetGroup);

			// .format
			for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
			{
				if (targets[targetNdx].is3D && !formats[formatNdx].supports3D)
					continue;
				else
				{
					const deUint32							format			= formats[formatNdx].format;
					const tcu::Sampler::DepthStencilMode	sampleMode		= formats[formatNdx].mode;
					const bool								coreFilterable	= isCoreFilterableFormat(format, sampleMode);
					tcu::TestCaseGroup* const				formatGroup		= new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");
					targetGroup->addChild(formatGroup);

					// .linear
					// .nearest
					// .gather
					for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
					{
						const deUint32 filter = s_filters[filterNdx].filter;

						if (!coreFilterable && filterRequiresFilterability(filter))
						{
							// skip linear on pure integers
							continue;
						}
						else if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER && targets[targetNdx].is3D)
						{
							// skip gather on 3d
							continue;
						}
						else
						{
							tcu::TestCaseGroup* const filteringGroup = new tcu::TestCaseGroup(m_testCtx, s_filters[filterNdx].name, "Tests with specific filter");
							formatGroup->addChild(filteringGroup);

							// .s_XXX_t_XXX(_r_XXX)
							for (int wrapNdx = 0; wrapNdx < DE_LENGTH_OF_ARRAY(wrapConfigs); ++wrapNdx)
							{
								if (wrapConfigs[wrapNdx].is3D != targets[targetNdx].is3D)
									continue;
								else
								{
									for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
									{
										const char* const		wrapName			= wrapConfigs[wrapNdx].name;
										const bool				isNpotCase			= (sizeNdx == 1);
										const char* const		sizeNameExtension	= (isNpotCase) ? ("_npot") : ("_pot");
										const SizeType			size				= (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);

										if (!targets[targetNdx].is3D)
											filteringGroup->addChild(new TextureBorderClampPerAxisCase2D(m_context,
																										 (std::string() + wrapName + sizeNameExtension).c_str(),
																										 "",
																										 format,
																										 sampleMode,
																										 size,
																										 filter,
																										 wrapConfigs[wrapNdx].sWrap,
																										 wrapConfigs[wrapNdx].tWrap,
																										 s_filters[filterNdx].sampling));
										else
										{
											DE_ASSERT(sampleMode == tcu::Sampler::MODE_LAST);
											filteringGroup->addChild(new TextureBorderClampPerAxisCase3D(m_context,
																										 (std::string() + wrapName + sizeNameExtension).c_str(),
																										 "",
																										 format,
																										 size,
																										 filter,
																										 wrapConfigs[wrapNdx].sWrap,
																										 wrapConfigs[wrapNdx].tWrap,
																										 wrapConfigs[wrapNdx].rWrap));
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}

	// .depth_compare_mode
	{
		static const struct
		{
			const char*						name;
			deUint32						format;
		} formats[] =
		{
			{ "depth_component16",		GL_DEPTH_COMPONENT16	},
			{ "depth_component24",		GL_DEPTH_COMPONENT24	},
			{ "depth24_stencil8",		GL_DEPTH24_STENCIL8		},
			{ "depth32f_stencil8",		GL_DEPTH32F_STENCIL8	},
		};

		tcu::TestCaseGroup* const compareGroup = new tcu::TestCaseGroup(m_testCtx, "depth_compare_mode", "Tests depth compare mode");
		addChild(compareGroup);

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
		{
			const deUint32							format			= formats[formatNdx].format;
			tcu::TestCaseGroup* const				formatGroup		= new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test");

			compareGroup->addChild(formatGroup);

			// (format).(linear|nearest|gather)_(pot|npot)
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx)
			for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx)
			{
					const bool				isNpotCase		= (sizeNdx == 1);
					const char* const		sizeName		= (isNpotCase) ? ("size_npot") : ("size_pot");
					const SizeType			sizeType		= (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT);
					const std::string		caseName		= std::string() + s_filters[filterNdx].name + "_" + sizeName;
					const deUint32			filter			= s_filters[filterNdx].filter;

					formatGroup->addChild(new TextureBorderClampDepthCompareCase(m_context,
																				 caseName.c_str(),
																				 "",
																				 format,
																				 sizeType,
																				 filter,
																				 s_filters[filterNdx].sampling));
			}
		}
	}

	// unused channels (A in rgb, G in stencil etc.)
	{
		static const struct
		{
			const char*						name;
			deUint32						format;
			tcu::Sampler::DepthStencilMode	mode;
		} formats[] =
		{
			{ "r8",										GL_R8,						tcu::Sampler::MODE_LAST		},
			{ "rg8_snorm",								GL_RG8_SNORM,				tcu::Sampler::MODE_LAST		},
			{ "rgb8",									GL_RGB8,					tcu::Sampler::MODE_LAST		},
			{ "rg32f",									GL_RG32F,					tcu::Sampler::MODE_LAST		},
			{ "r16i",									GL_RG16I,					tcu::Sampler::MODE_LAST		},
			{ "luminance",								GL_LUMINANCE,				tcu::Sampler::MODE_LAST		},
			{ "alpha",									GL_ALPHA,					tcu::Sampler::MODE_LAST		},
			{ "luminance_alpha",						GL_LUMINANCE_ALPHA,			tcu::Sampler::MODE_LAST		},
			{ "depth_component16",						GL_DEPTH_COMPONENT16,		tcu::Sampler::MODE_DEPTH	},
			{ "depth_component32f",						GL_DEPTH_COMPONENT32F,		tcu::Sampler::MODE_DEPTH	},
			{ "stencil_index8",							GL_STENCIL_INDEX8,			tcu::Sampler::MODE_STENCIL	},
			{ "depth32f_stencil8_sample_depth",			GL_DEPTH32F_STENCIL8,		tcu::Sampler::MODE_DEPTH	},
			{ "depth32f_stencil8_sample_stencil",		GL_DEPTH32F_STENCIL8,		tcu::Sampler::MODE_STENCIL	},
			{ "depth24_stencil8_sample_depth",			GL_DEPTH24_STENCIL8,		tcu::Sampler::MODE_DEPTH	},
			{ "depth24_stencil8_sample_stencil",		GL_DEPTH24_STENCIL8,		tcu::Sampler::MODE_STENCIL	},
			{ "compressed_r11_eac",						GL_COMPRESSED_R11_EAC,		tcu::Sampler::MODE_LAST		},
		};

		tcu::TestCaseGroup* const unusedGroup = new tcu::TestCaseGroup(m_testCtx, "unused_channels", "Tests channels that are not present in the internal format");
		addChild(unusedGroup);

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
		{
			unusedGroup->addChild(new TextureBorderClampUnusedChannelCase(m_context,
																		  formats[formatNdx].name,
																		  "",
																		  formats[formatNdx].format,
																		  formats[formatNdx].mode));
		}
	}
}

} // Functional
} // gles31
} // deqp
