/*-------------------------------------------------------------------------
 * 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 generateDummyCompressedData (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> genDummyTexture (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));

		generateDummyCompressedData(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 supportsGL45			= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
	const bool supportsES32orGL45	= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || supportsGL45;

	if (!supportsES32orGL45 && !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)													&&
		!supportsES32orGL45																		&&
		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 = genDummyTexture<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)
{
	auto		ctxType						= m_context.getRenderContext().getType();
	const bool	isES32orGL45				= glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
											  glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
	const glu::GLSLVersion	glslVersion		= glu::getContextTypeGLSLVersion(ctxType);

	if (!isES32orGL45 && !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)													&&
		!isES32orGL45																			&&
		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 = genDummyTexture<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();
}

static bool isFormatSupported(deUint32 format, bool isGL45)
{
	if (isGL45 && (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA))
		return false;

	return true;
}

} // anonymous

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

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)) && isFormatSupported(format, m_isGL45))
						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)
		{
			if (isFormatSupported(formats[formatNdx].format, m_isGL45))
			{
				unusedGroup->addChild(new TextureBorderClampUnusedChannelCase(m_context,
																			  formats[formatNdx].name,
																			  "",
																			  formats[formatNdx].format,
																			  formats[formatNdx].mode));
			}
		}
	}
}

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