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

#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deMemory.h"

#include <limits>

namespace tcu
{

static inline float sRGBChannelToLinear (float cs)
{
	if (cs <= 0.04045)
		return cs / 12.92f;
	else
		return deFloatPow((cs + 0.055f) / 1.055f, 2.4f);
}

static const deUint32 s_srgb8Lut[256] =
{
#include "tcuSRGB8Lut.inl"
};

static inline float sRGB8ChannelToLinear (deUint32 cs)
{
	DE_ASSERT(cs < 256);

	// \note This triggers UB, but in practice it doesn't cause any problems
	return ((const float*)s_srgb8Lut)[cs];
}

static inline float linearChannelToSRGB (float cl)
{
	if (cl <= 0.0f)
		return 0.0f;
	else if (cl < 0.0031308f)
		return 12.92f*cl;
	else if (cl < 1.0f)
		return 1.055f*deFloatPow(cl, 0.41666f) - 0.055f;
	else
		return 1.0f;
}

//! Convert sRGB to linear colorspace
Vec4 sRGBToLinear (const Vec4& cs)
{
	return Vec4(sRGBChannelToLinear(cs[0]),
				sRGBChannelToLinear(cs[1]),
				sRGBChannelToLinear(cs[2]),
				cs[3]);
}

Vec4 sRGB8ToLinear (const UVec4& cs)
{
	return Vec4(sRGB8ChannelToLinear(cs[0]),
				sRGB8ChannelToLinear(cs[1]),
				sRGB8ChannelToLinear(cs[2]),
				1.0f);
}

Vec4 sRGBA8ToLinear (const UVec4& cs)
{
	return Vec4(sRGB8ChannelToLinear(cs[0]),
				sRGB8ChannelToLinear(cs[1]),
				sRGB8ChannelToLinear(cs[2]),
				(float)cs[3] / 255.0f);
}

//! Convert from linear to sRGB colorspace
Vec4 linearToSRGB (const Vec4& cl)
{
	return Vec4(linearChannelToSRGB(cl[0]),
				linearChannelToSRGB(cl[1]),
				linearChannelToSRGB(cl[2]),
				cl[3]);
}

bool isSRGB (TextureFormat format)
{
	// make sure to update this if type table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);

	return	format.order == TextureFormat::sR		||
			format.order == TextureFormat::sRG		||
			format.order == TextureFormat::sRGB		||
			format.order == TextureFormat::sRGBA	||
			format.order == TextureFormat::sBGR		||
			format.order == TextureFormat::sBGRA;
}

tcu::Vec4 linearToSRGBIfNeeded (const TextureFormat& format, const tcu::Vec4& color)
{
	return isSRGB(format) ? linearToSRGB(color) : color;
}

bool isCombinedDepthStencilType (TextureFormat::ChannelType type)
{
	// make sure to update this if type table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 46);

	return	type == TextureFormat::UNSIGNED_INT_16_8_8			||
			type == TextureFormat::UNSIGNED_INT_24_8			||
			type == TextureFormat::UNSIGNED_INT_24_8_REV		||
			type == TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV;
}

bool hasStencilComponent (TextureFormat::ChannelOrder order)
{
	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);

	switch (order)
	{
		case TextureFormat::S:
		case TextureFormat::DS:
			return true;

		default:
			return false;
	}
}

bool hasDepthComponent (TextureFormat::ChannelOrder order)
{
	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);

	switch (order)
	{
		case TextureFormat::D:
		case TextureFormat::DS:
			return true;

		default:
			return false;
	}
}

//! Get texture channel class for format
TextureChannelClass getTextureChannelClass (TextureFormat::ChannelType channelType)
{
	// make sure this table is updated if format table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 46);

	switch (channelType)
	{
		case TextureFormat::SNORM_INT8:						return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
		case TextureFormat::SNORM_INT16:					return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
		case TextureFormat::SNORM_INT32:					return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
		case TextureFormat::UNORM_INT8:						return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_INT16:					return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_INT24:					return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_INT32:					return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_BYTE_44:					return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_SHORT_565:				return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_SHORT_555:				return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_SHORT_4444:				return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_SHORT_5551:				return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_SHORT_1555:				return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNSIGNED_BYTE_44:				return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_SHORT_565:				return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_SHORT_4444:			return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_SHORT_5551:			return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNORM_INT_101010:				return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::SNORM_INT_1010102_REV:			return TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
		case TextureFormat::UNORM_INT_1010102_REV:			return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::SIGNED_INT_1010102_REV:			return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		case TextureFormat::UNSIGNED_INT_1010102_REV:		return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:	return TEXTURECHANNELCLASS_FLOATING_POINT;
		case TextureFormat::UNSIGNED_INT_999_E5_REV:		return TEXTURECHANNELCLASS_FLOATING_POINT;
		case TextureFormat::UNSIGNED_INT_16_8_8:			return TEXTURECHANNELCLASS_LAST;					//!< packed unorm16-x8-uint8
		case TextureFormat::UNSIGNED_INT_24_8:				return TEXTURECHANNELCLASS_LAST;					//!< packed unorm24-uint8
		case TextureFormat::UNSIGNED_INT_24_8_REV:			return TEXTURECHANNELCLASS_LAST;					//!< packed unorm24-uint8
		case TextureFormat::SIGNED_INT8:					return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		case TextureFormat::SIGNED_INT16:					return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		case TextureFormat::SIGNED_INT32:					return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		case TextureFormat::UNSIGNED_INT8:					return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_INT16:					return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_INT24:					return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::UNSIGNED_INT32:					return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::HALF_FLOAT:						return TEXTURECHANNELCLASS_FLOATING_POINT;
		case TextureFormat::FLOAT:							return TEXTURECHANNELCLASS_FLOATING_POINT;
		case TextureFormat::FLOAT64:						return TEXTURECHANNELCLASS_FLOATING_POINT;
		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return TEXTURECHANNELCLASS_LAST;					//!< packed float32-pad24-uint8
		case TextureFormat::UNORM_SHORT_10:					return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::UNORM_SHORT_12:					return TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
		case TextureFormat::USCALED_INT8:					return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::USCALED_INT16:					return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::SSCALED_INT8:					return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		case TextureFormat::SSCALED_INT16:					return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		case TextureFormat::USCALED_INT_1010102_REV:		return TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		case TextureFormat::SSCALED_INT_1010102_REV:		return TEXTURECHANNELCLASS_SIGNED_INTEGER;
		default:
			DE_FATAL("Unknown channel type");
			return TEXTURECHANNELCLASS_LAST;
	}
}

bool isAccessValid (TextureFormat format, TextureAccessType type)
{
	DE_ASSERT(isValid(format));

	if (format.order == TextureFormat::DS)
	{
		// It is never allowed to access combined depth-stencil format with getPixel().
		// Instead either getPixDepth() or getPixStencil(), or effective depth- or stencil-
		// access must be used.
		return false;
	}
	else if (format.order == TextureFormat::D)
		return type == TEXTUREACCESSTYPE_FLOAT;
	else if (format.order == TextureFormat::S)
		return type == TEXTUREACCESSTYPE_UNSIGNED_INT;
	else
	{
		// A few packed color formats have access type restrictions
		if (format.type == TextureFormat::UNSIGNED_INT_11F_11F_10F_REV ||
			format.type == TextureFormat::UNSIGNED_INT_999_E5_REV)
			return type == TEXTUREACCESSTYPE_FLOAT;
		else
			return true;
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Get access to subregion of pixel buffer
 * \param access	Parent access object
 * \param x			X offset
 * \param y			Y offset
 * \param z			Z offset
 * \param width		Width
 * \param height	Height
 * \param depth		Depth
 * \return Access object that targets given subregion of parent access object
 *//*--------------------------------------------------------------------*/
ConstPixelBufferAccess getSubregion (const ConstPixelBufferAccess& access, int x, int y, int z, int width, int height, int depth)
{
	DE_ASSERT(de::inBounds(x, 0, access.getWidth()));
	DE_ASSERT(de::inRange(x+width, x+1, access.getWidth()));

	DE_ASSERT(de::inBounds(y, 0, access.getHeight()));
	DE_ASSERT(de::inRange(y+height, y+1, access.getHeight()));

	DE_ASSERT(de::inBounds(z, 0, access.getDepth()));
	DE_ASSERT(de::inRange(z+depth, z+1, access.getDepth()));

	return ConstPixelBufferAccess(access.getFormat(), tcu::IVec3(width, height, depth), access.getPitch(),
								  (const deUint8*)access.getDataPtr() + access.getPixelPitch()*x + access.getRowPitch()*y + access.getSlicePitch()*z);
}

/*--------------------------------------------------------------------*//*!
 * \brief Get access to subregion of pixel buffer
 * \param access	Parent access object
 * \param x			X offset
 * \param y			Y offset
 * \param z			Z offset
 * \param width		Width
 * \param height	Height
 * \param depth		Depth
 * \return Access object that targets given subregion of parent access object
 *//*--------------------------------------------------------------------*/
PixelBufferAccess getSubregion (const PixelBufferAccess& access, int x, int y, int z, int width, int height, int depth)
{
	DE_ASSERT(de::inBounds(x, 0, access.getWidth()));
	DE_ASSERT(de::inRange(x+width, x+1, access.getWidth()));

	DE_ASSERT(de::inBounds(y, 0, access.getHeight()));
	DE_ASSERT(de::inRange(y+height, y+1, access.getHeight()));

	DE_ASSERT(de::inBounds(z, 0, access.getDepth()));
	DE_ASSERT(de::inRange(z+depth, z+1, access.getDepth()));

	return PixelBufferAccess(access.getFormat(), tcu::IVec3(width, height, depth), access.getPitch(),
							 (deUint8*)access.getDataPtr() + access.getPixelPitch()*x + access.getRowPitch()*y + access.getSlicePitch()*z);
}

/*--------------------------------------------------------------------*//*!
 * \brief Get access to subregion of pixel buffer
 * \param access	Parent access object
 * \param x			X offset
 * \param y			Y offset
 * \param width		Width
 * \param height	Height
 * \return Access object that targets given subregion of parent access object
 *//*--------------------------------------------------------------------*/
PixelBufferAccess getSubregion (const PixelBufferAccess& access, int x, int y, int width, int height)
{
	return getSubregion(access, x, y, 0, width, height, 1);
}

/*--------------------------------------------------------------------*//*!
 * \brief Get access to subregion of pixel buffer
 * \param access	Parent access object
 * \param x			X offset
 * \param y			Y offset
 * \param width		Width
 * \param height	Height
 * \return Access object that targets given subregion of parent access object
 *//*--------------------------------------------------------------------*/
ConstPixelBufferAccess getSubregion (const ConstPixelBufferAccess& access, int x, int y, int width, int height)
{
	return getSubregion(access, x, y, 0, width, height, 1);
}

/*--------------------------------------------------------------------*//*!
 * \brief Flip rows in Y direction
 * \param access Access object
 * \return Modified access object where Y coordinates are reversed
 *//*--------------------------------------------------------------------*/
PixelBufferAccess flipYAccess (const PixelBufferAccess& access)
{
	const int			rowPitch		= access.getRowPitch();
	const int			offsetToLast	= rowPitch*(access.getHeight()-1);
	const tcu::IVec3	pitch			(access.getPixelPitch(), -rowPitch, access.getSlicePitch());

	return PixelBufferAccess(access.getFormat(), access.getSize(), pitch, (deUint8*)access.getDataPtr() + offsetToLast);
}

/*--------------------------------------------------------------------*//*!
 * \brief Flip rows in Y direction
 * \param access Access object
 * \return Modified access object where Y coordinates are reversed
 *//*--------------------------------------------------------------------*/
ConstPixelBufferAccess flipYAccess (const ConstPixelBufferAccess& access)
{
	const int			rowPitch		= access.getRowPitch();
	const int			offsetToLast	= rowPitch*(access.getHeight()-1);
	const tcu::IVec3	pitch			(access.getPixelPitch(), -rowPitch, access.getSlicePitch());

	return ConstPixelBufferAccess(access.getFormat(), access.getSize(), pitch, (deUint8*)access.getDataPtr() + offsetToLast);
}

static Vec2 getFloatChannelValueRange (TextureFormat::ChannelType channelType)
{
	// make sure this table is updated if format table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 46);

	float cMin = 0.0f;
	float cMax = 0.0f;

	switch (channelType)
	{
		// Signed normalized formats.
		case TextureFormat::SNORM_INT8:
		case TextureFormat::SNORM_INT16:
		case TextureFormat::SNORM_INT32:
		case TextureFormat::SNORM_INT_1010102_REV:			cMin = -1.0f;			cMax = 1.0f;			break;

		// Unsigned normalized formats.
		case TextureFormat::UNORM_INT8:
		case TextureFormat::UNORM_INT16:
		case TextureFormat::UNORM_INT24:
		case TextureFormat::UNORM_INT32:
		case TextureFormat::UNORM_BYTE_44:
		case TextureFormat::UNORM_SHORT_565:
		case TextureFormat::UNORM_SHORT_555:
		case TextureFormat::UNORM_SHORT_4444:
		case TextureFormat::UNORM_SHORT_5551:
		case TextureFormat::UNORM_SHORT_1555:
		case TextureFormat::UNORM_INT_101010:
		case TextureFormat::UNORM_INT_1010102_REV:
		case TextureFormat::UNORM_SHORT_10:
		case TextureFormat::UNORM_SHORT_12:					cMin = 0.0f;			cMax = 1.0f;			break;

		// Misc formats.
		case TextureFormat::SIGNED_INT8:					cMin = -128.0f;			cMax = 127.0f;			break;
		case TextureFormat::SIGNED_INT16:					cMin = -32768.0f;		cMax = 32767.0f;		break;
		case TextureFormat::SIGNED_INT32:					cMin = -2147483520.0f;	cMax = 2147483520.0f;	break; // Maximum exactly representable 31-bit integer: (2^24 - 1) * 2^7
		case TextureFormat::UNSIGNED_INT8:					cMin = 0.0f;			cMax = 255.0f;			break;
		case TextureFormat::UNSIGNED_INT16:					cMin = 0.0f;			cMax = 65535.0f;		break;
		case TextureFormat::UNSIGNED_INT24:					cMin = 0.0f;			cMax = 16777215.0f;		break;
		case TextureFormat::UNSIGNED_INT32:					cMin = 0.0f;			cMax = 4294967040.f;	break; // Maximum exactly representable 32-bit integer: (2^24 - 1) * 2^8
		case TextureFormat::HALF_FLOAT:						cMin = -1e3f;			cMax = 1e3f;			break;
		case TextureFormat::FLOAT:							cMin = -1e5f;			cMax = 1e5f;			break;
		case TextureFormat::FLOAT64:						cMin = -1e5f;			cMax = 1e5f;			break;
		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:	cMin = 0.0f;			cMax = 1e4f;			break;
		case TextureFormat::UNSIGNED_INT_999_E5_REV:		cMin = 0.0f;			cMax = 1e5f;			break;
		case TextureFormat::UNSIGNED_BYTE_44:				cMin = 0.0f;			cMax = 15.f;			break;
		case TextureFormat::UNSIGNED_SHORT_4444:			cMin = 0.0f;			cMax = 15.f;			break;
		case TextureFormat::USCALED_INT8:					cMin = 0.0f;			cMax = 255.0f;			break;
		case TextureFormat::USCALED_INT16:					cMin = 0.0f;			cMax = 65535.0f;		break;
		case TextureFormat::SSCALED_INT8:					cMin = -128.0f;			cMax = 127.0f;			break;
		case TextureFormat::SSCALED_INT16:					cMin = -32768.0f;		cMax = 32767.0f;		break;
		case TextureFormat::USCALED_INT_1010102_REV:		cMin = 0.0f;			cMax = 1023.0f;			break;
		case TextureFormat::SSCALED_INT_1010102_REV:		cMin = -512.0f;			cMax = 511.0f;			break;

		default:
			DE_ASSERT(false);
	}

	return Vec2(cMin, cMax);
}

/*--------------------------------------------------------------------*//*!
 * \brief Get standard parameters for testing texture format
 *
 * Returns TextureFormatInfo that describes good parameters for exercising
 * given TextureFormat. Parameters include value ranges per channel and
 * suitable lookup scaling and bias in order to reduce result back to
 * 0..1 range.
 *//*--------------------------------------------------------------------*/
TextureFormatInfo getTextureFormatInfo (const TextureFormat& format)
{
	// Special cases.
	if (format.type == TextureFormat::UNSIGNED_INT_1010102_REV)
		return TextureFormatInfo(Vec4(	     0.0f,		    0.0f,		    0.0f,		 0.0f),
								 Vec4(	  1023.0f,		 1023.0f,		 1023.0f,		 3.0f),
								 Vec4(1.0f/1023.f,	1.0f/1023.0f,	1.0f/1023.0f,	1.0f/3.0f),
								 Vec4(	     0.0f,		    0.0f,		    0.0f,		 0.0f));
	if (format.type == TextureFormat::SIGNED_INT_1010102_REV)
		return TextureFormatInfo(Vec4(	  -512.0f,		 -512.0f,		 -512.0f,		-2.0f),
								 Vec4(	   511.0f,		  511.0f,		  511.0f,		 1.0f),
								 Vec4(1.0f/1023.f,	1.0f/1023.0f,	1.0f/1023.0f,	1.0f/3.0f),
								 Vec4(	     0.5f,		    0.5f,		    0.5f,		 0.5f));
	else if (format.order == TextureFormat::D || format.order == TextureFormat::DS)
		return TextureFormatInfo(Vec4(0.0f,	0.0f,	0.0f,	0.0f),
								 Vec4(1.0f,	1.0f,	1.0f,	0.0f),
								 Vec4(1.0f,	1.0f,	1.0f,	1.0f),
								 Vec4(0.0f,	0.0f,	0.0f,	0.0f)); // Depth / stencil formats.
	else if (format == TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_5551))
		return TextureFormatInfo(Vec4(0.0f, 0.0f, 0.0f, 0.5f),
								 Vec4(1.0f, 1.0f, 1.0f, 1.5f),
								 Vec4(1.0f, 1.0f, 1.0f, 1.0f),
								 Vec4(0.0f, 0.0f, 0.0f, 0.0f));
	else if (format.type == TextureFormat::UNSIGNED_SHORT_5551)
		return TextureFormatInfo(Vec4(	   0.0f,		  0.0f,		  0.0f,	0.0f),
								 Vec4(	  31.0f,		 31.0f,		 31.0f,	1.0f),
								 Vec4(1.0f/31.f,	1.0f/31.0f,	1.0f/31.0f,	1.0f),
								 Vec4(	   0.0f,		  0.0f,		  0.0f,	0.0f));
	else if (format.type == TextureFormat::UNSIGNED_SHORT_565)
		return TextureFormatInfo(Vec4(	   0.0f,		  0.0f,		  0.0f,	0.0f),
								 Vec4(	  31.0f,		 63.0f,		 31.0f,	0.0f),
								 Vec4(1.0f/31.f,	1.0f/63.0f,	1.0f/31.0f,	1.0f),
								 Vec4(	   0.0f,		  0.0f,		  0.0f,	0.0f));

	const Vec2						cRange		= getFloatChannelValueRange(format.type);
	const TextureSwizzle::Channel*	map			= getChannelReadSwizzle(format.order).components;
	const BVec4						chnMask		= BVec4(deInRange32(map[0], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[1], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[2], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[3], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE);
	const float						scale		= 1.0f / (cRange[1] - cRange[0]);
	const float						bias		= -cRange[0] * scale;

	return TextureFormatInfo(select(cRange[0],	0.0f, chnMask),
							 select(cRange[1],	0.0f, chnMask),
							 select(scale,		1.0f, chnMask),
							 select(bias,		0.0f, chnMask));
}

IVec4 getFormatMinIntValue (const TextureFormat& format)
{
	DE_ASSERT(getTextureChannelClass(format.type) == TEXTURECHANNELCLASS_SIGNED_INTEGER);

	switch (format.type)
	{
		case TextureFormat::SIGNED_INT8:	return IVec4(std::numeric_limits<deInt8>::min());
		case TextureFormat::SIGNED_INT16:	return IVec4(std::numeric_limits<deInt16>::min());
		case TextureFormat::SIGNED_INT32:	return IVec4(std::numeric_limits<deInt32>::min());

		default:
			DE_FATAL("Invalid channel type");
			return IVec4(0);
	}
}

IVec4 getFormatMaxIntValue (const TextureFormat& format)
{
	DE_ASSERT(getTextureChannelClass(format.type) == TEXTURECHANNELCLASS_SIGNED_INTEGER);

	if (format == TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT_1010102_REV)  ||
		format == TextureFormat(TextureFormat::BGRA, TextureFormat::SSCALED_INT_1010102_REV) ||
		format == TextureFormat(TextureFormat::RGBA, TextureFormat::SSCALED_INT_1010102_REV) ||
		format == TextureFormat(TextureFormat::BGRA, TextureFormat::SIGNED_INT_1010102_REV))
		return IVec4(511, 511, 511, 1);

	switch (format.type)
	{
		case TextureFormat::SIGNED_INT8:	return IVec4(std::numeric_limits<deInt8>::max());
		case TextureFormat::SIGNED_INT16:	return IVec4(std::numeric_limits<deInt16>::max());
		case TextureFormat::SIGNED_INT32:	return IVec4(std::numeric_limits<deInt32>::max());

		case TextureFormat::SSCALED_INT8:	return IVec4(std::numeric_limits<deInt8>::max());
		case TextureFormat::SSCALED_INT16:	return IVec4(std::numeric_limits<deInt16>::max());

		default:
			DE_FATAL("Invalid channel type");
			return IVec4(0);
	}
}

UVec4 getFormatMaxUintValue (const TextureFormat& format)
{
	DE_ASSERT(getTextureChannelClass(format.type) == TEXTURECHANNELCLASS_UNSIGNED_INTEGER);

	if (format == TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT_1010102_REV) ||
		format == TextureFormat(TextureFormat::RGBA, TextureFormat::USCALED_INT_1010102_REV)  ||
		format == TextureFormat(TextureFormat::BGRA, TextureFormat::USCALED_INT_1010102_REV)  ||
		format == TextureFormat(TextureFormat::BGRA, TextureFormat::UNSIGNED_INT_1010102_REV))
		return UVec4(1023u, 1023u, 1023u, 3u);

	switch (format.type)
	{
		case TextureFormat::UNSIGNED_INT8:	return UVec4(std::numeric_limits<deUint8>::max());
		case TextureFormat::UNSIGNED_INT16:	return UVec4(std::numeric_limits<deUint16>::max());
		case TextureFormat::UNSIGNED_INT24:	return UVec4(0xffffffu);
		case TextureFormat::UNSIGNED_INT32:	return UVec4(std::numeric_limits<deUint32>::max());

		case TextureFormat::USCALED_INT8:	return UVec4(std::numeric_limits<deUint8>::max());
		case TextureFormat::USCALED_INT16:	return UVec4(std::numeric_limits<deUint16>::max());

		default:
			DE_FATAL("Invalid channel type");
			return UVec4(0);
	}
}

static IVec4 getChannelBitDepth (TextureFormat::ChannelType channelType)
{
	// make sure this table is updated if format table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 46);

	switch (channelType)
	{
		case TextureFormat::SNORM_INT8:						return IVec4(8);
		case TextureFormat::SNORM_INT16:					return IVec4(16);
		case TextureFormat::SNORM_INT32:					return IVec4(32);
		case TextureFormat::UNORM_INT8:						return IVec4(8);
		case TextureFormat::UNORM_INT16:					return IVec4(16);
		case TextureFormat::UNORM_INT24:					return IVec4(24);
		case TextureFormat::UNORM_INT32:					return IVec4(32);
		case TextureFormat::UNORM_BYTE_44:					return IVec4(4,4,0,0);
		case TextureFormat::UNORM_SHORT_565:				return IVec4(5,6,5,0);
		case TextureFormat::UNORM_SHORT_4444:				return IVec4(4);
		case TextureFormat::UNORM_SHORT_555:				return IVec4(5,5,5,0);
		case TextureFormat::UNORM_SHORT_5551:				return IVec4(5,5,5,1);
		case TextureFormat::UNORM_SHORT_1555:				return IVec4(1,5,5,5);
		case TextureFormat::UNSIGNED_BYTE_44:				return IVec4(4,4,0,0);
		case TextureFormat::UNSIGNED_SHORT_565:				return IVec4(5,6,5,0);
		case TextureFormat::UNSIGNED_SHORT_4444:			return IVec4(4);
		case TextureFormat::UNSIGNED_SHORT_5551:			return IVec4(5,5,5,1);
		case TextureFormat::UNORM_INT_101010:				return IVec4(10,10,10,0);
		case TextureFormat::SNORM_INT_1010102_REV:			return IVec4(10,10,10,2);
		case TextureFormat::UNORM_INT_1010102_REV:			return IVec4(10,10,10,2);
		case TextureFormat::SIGNED_INT8:					return IVec4(8);
		case TextureFormat::SIGNED_INT16:					return IVec4(16);
		case TextureFormat::SIGNED_INT32:					return IVec4(32);
		case TextureFormat::UNSIGNED_INT8:					return IVec4(8);
		case TextureFormat::UNSIGNED_INT16:					return IVec4(16);
		case TextureFormat::UNSIGNED_INT24:					return IVec4(24);
		case TextureFormat::UNSIGNED_INT32:					return IVec4(32);
		case TextureFormat::SIGNED_INT_1010102_REV:			return IVec4(10,10,10,2);
		case TextureFormat::UNSIGNED_INT_1010102_REV:		return IVec4(10,10,10,2);
		case TextureFormat::UNSIGNED_INT_16_8_8:			return IVec4(16,8,0,0);
		case TextureFormat::UNSIGNED_INT_24_8:				return IVec4(24,8,0,0);
		case TextureFormat::UNSIGNED_INT_24_8_REV:			return IVec4(24,8,0,0);
		case TextureFormat::HALF_FLOAT:						return IVec4(16);
		case TextureFormat::FLOAT:							return IVec4(32);
		case TextureFormat::FLOAT64:						return IVec4(64);
		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:	return IVec4(11,11,10,0);
		case TextureFormat::UNSIGNED_INT_999_E5_REV:		return IVec4(9,9,9,0);
		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return IVec4(32,8,0,0);
		case TextureFormat::UNORM_SHORT_10:					return IVec4(10);
		case TextureFormat::UNORM_SHORT_12:					return IVec4(12);
		case TextureFormat::USCALED_INT8:					return IVec4(8);
		case TextureFormat::USCALED_INT16:					return IVec4(16);
		case TextureFormat::SSCALED_INT8:					return IVec4(8);
		case TextureFormat::SSCALED_INT16:					return IVec4(16);
		case TextureFormat::USCALED_INT_1010102_REV:		return IVec4(10,10,10,2);
		case TextureFormat::SSCALED_INT_1010102_REV:		return IVec4(10,10,10,2);
		default:
			DE_ASSERT(false);
			return IVec4(0);
	}
}

IVec4 getTextureFormatBitDepth (const TextureFormat& format)
{
	const IVec4						chnBits		= getChannelBitDepth(format.type);
	const TextureSwizzle::Channel*	map			= getChannelReadSwizzle(format.order).components;
	const BVec4						chnMask		= BVec4(deInRange32(map[0], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[1], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[2], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[3], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE);
	const IVec4						chnSwz		= IVec4((chnMask[0]) ? ((int)map[0]) : (0),
														(chnMask[1]) ? ((int)map[1]) : (0),
														(chnMask[2]) ? ((int)map[2]) : (0),
														(chnMask[3]) ? ((int)map[3]) : (0));

	return select(chnBits.swizzle(chnSwz.x(), chnSwz.y(), chnSwz.z(), chnSwz.w()), IVec4(0), chnMask);
}

static IVec4 getChannelMantissaBitDepth (TextureFormat::ChannelType channelType)
{
	// make sure this table is updated if format table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 46);

	switch (channelType)
	{
		case TextureFormat::SNORM_INT8:
		case TextureFormat::SNORM_INT16:
		case TextureFormat::SNORM_INT32:
		case TextureFormat::UNORM_INT8:
		case TextureFormat::UNORM_INT16:
		case TextureFormat::UNORM_INT24:
		case TextureFormat::UNORM_INT32:
		case TextureFormat::UNORM_BYTE_44:
		case TextureFormat::UNORM_SHORT_565:
		case TextureFormat::UNORM_SHORT_4444:
		case TextureFormat::UNORM_SHORT_555:
		case TextureFormat::UNORM_SHORT_5551:
		case TextureFormat::UNORM_SHORT_1555:
		case TextureFormat::UNSIGNED_BYTE_44:
		case TextureFormat::UNSIGNED_SHORT_565:
		case TextureFormat::UNSIGNED_SHORT_4444:
		case TextureFormat::UNSIGNED_SHORT_5551:
		case TextureFormat::UNORM_INT_101010:
		case TextureFormat::SNORM_INT_1010102_REV:
		case TextureFormat::UNORM_INT_1010102_REV:
		case TextureFormat::SIGNED_INT8:
		case TextureFormat::SIGNED_INT16:
		case TextureFormat::SIGNED_INT32:
		case TextureFormat::UNSIGNED_INT8:
		case TextureFormat::UNSIGNED_INT16:
		case TextureFormat::UNSIGNED_INT24:
		case TextureFormat::UNSIGNED_INT32:
		case TextureFormat::SIGNED_INT_1010102_REV:
		case TextureFormat::UNSIGNED_INT_1010102_REV:
		case TextureFormat::UNSIGNED_INT_16_8_8:
		case TextureFormat::UNSIGNED_INT_24_8:
		case TextureFormat::UNSIGNED_INT_24_8_REV:
		case TextureFormat::UNSIGNED_INT_999_E5_REV:
		case TextureFormat::UNORM_SHORT_10:
		case TextureFormat::UNORM_SHORT_12:
		case TextureFormat::USCALED_INT8:
		case TextureFormat::USCALED_INT16:
		case TextureFormat::SSCALED_INT8:
		case TextureFormat::SSCALED_INT16:
		case TextureFormat::USCALED_INT_1010102_REV:
		case TextureFormat::SSCALED_INT_1010102_REV:
			return getChannelBitDepth(channelType);

		case TextureFormat::HALF_FLOAT:						return IVec4(10);
		case TextureFormat::FLOAT:							return IVec4(23);
		case TextureFormat::FLOAT64:						return IVec4(52);
		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:	return IVec4(6,6,5,0);
		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return IVec4(23,8,0,0);
		default:
			DE_ASSERT(false);
			return IVec4(0);
	}
}

IVec4 getTextureFormatMantissaBitDepth (const TextureFormat& format)
{
	const IVec4						chnBits		= getChannelMantissaBitDepth(format.type);
	const TextureSwizzle::Channel*	map			= getChannelReadSwizzle(format.order).components;
	const BVec4						chnMask		= BVec4(deInRange32(map[0], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[1], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[2], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
														deInRange32(map[3], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE);
	const IVec4						chnSwz		= IVec4((chnMask[0]) ? ((int)map[0]) : (0),
														(chnMask[1]) ? ((int)map[1]) : (0),
														(chnMask[2]) ? ((int)map[2]) : (0),
														(chnMask[3]) ? ((int)map[3]) : (0));

	return select(chnBits.swizzle(chnSwz.x(), chnSwz.y(), chnSwz.z(), chnSwz.w()), IVec4(0), chnMask);
}

BVec4 getTextureFormatChannelMask (const TextureFormat& format)
{
	const TextureSwizzle::Channel* const map = getChannelReadSwizzle(format.order).components;
	return BVec4(deInRange32(map[0], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
				 deInRange32(map[1], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
				 deInRange32(map[2], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
				 deInRange32(map[3], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE);
}

static inline float linearInterpolate (float t, float minVal, float maxVal)
{
	return minVal + (maxVal - minVal) * t;
}

static inline Vec4 linearInterpolate (float t, const Vec4& a, const Vec4& b)
{
	return a + (b - a) * t;
}

enum
{
	CLEAR_OPTIMIZE_THRESHOLD		= 128,
	CLEAR_OPTIMIZE_MAX_PIXEL_SIZE	= 8
};

inline void fillRow (const PixelBufferAccess& dst, int y, int z, int pixelSize, const deUint8* pixel)
{
	DE_ASSERT(dst.getPixelPitch() == pixelSize); // only tightly packed

	deUint8*	dstPtr	= (deUint8*)dst.getPixelPtr(0, y, z);
	int			width	= dst.getWidth();

	if (pixelSize == 8 && deIsAlignedPtr(dstPtr, pixelSize))
	{
		deUint64 val;
		memcpy(&val, pixel, sizeof(val));

		for (int i = 0; i < width; i++)
			((deUint64*)dstPtr)[i] = val;
	}
	else if (pixelSize == 4 && deIsAlignedPtr(dstPtr, pixelSize))
	{
		deUint32 val;
		memcpy(&val, pixel, sizeof(val));

		for (int i = 0; i < width; i++)
			((deUint32*)dstPtr)[i] = val;
	}
	else
	{
		for (int i = 0; i < width; i++)
			for (int j = 0; j < pixelSize; j++)
				dstPtr[i*pixelSize+j] = pixel[j];
	}
}

void clear (const PixelBufferAccess& access, const Vec4& color)
{
	const int	pixelSize				= access.getFormat().getPixelSize();
	const int	pixelPitch				= access.getPixelPitch();
	const bool	rowPixelsTightlyPacked	= (pixelSize == pixelPitch);

	if (access.getWidth()*access.getHeight()*access.getDepth() >= CLEAR_OPTIMIZE_THRESHOLD &&
		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE && rowPixelsTightlyPacked)
	{
		// Convert to destination format.
		union
		{
			deUint8		u8[CLEAR_OPTIMIZE_MAX_PIXEL_SIZE];
			deUint64	u64; // Forces 64-bit alignment.
		} pixel;
		DE_STATIC_ASSERT(sizeof(pixel) == CLEAR_OPTIMIZE_MAX_PIXEL_SIZE);
		PixelBufferAccess(access.getFormat(), 1, 1, 1, 0, 0, &pixel.u8[0]).setPixel(color, 0, 0);

		for (int z = 0; z < access.getDepth(); z++)
			for (int y = 0; y < access.getHeight(); y++)
				fillRow(access, y, z, pixelSize, &pixel.u8[0]);
	}
	else
	{
		for (int z = 0; z < access.getDepth(); z++)
			for (int y = 0; y < access.getHeight(); y++)
				for (int x = 0; x < access.getWidth(); x++)
					access.setPixel(color, x, y, z);
	}
}

void clear (const PixelBufferAccess& access, const IVec4& color)
{
	const int	pixelSize				= access.getFormat().getPixelSize();
	const int	pixelPitch				= access.getPixelPitch();
	const bool	rowPixelsTightlyPacked	= (pixelSize == pixelPitch);

	if (access.getWidth()*access.getHeight()*access.getDepth() >= CLEAR_OPTIMIZE_THRESHOLD &&
		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE && rowPixelsTightlyPacked)
	{
		// Convert to destination format.
		union
		{
			deUint8		u8[CLEAR_OPTIMIZE_MAX_PIXEL_SIZE];
			deUint64	u64; // Forces 64-bit alignment.
		} pixel;
		DE_STATIC_ASSERT(sizeof(pixel) == CLEAR_OPTIMIZE_MAX_PIXEL_SIZE);
		PixelBufferAccess(access.getFormat(), 1, 1, 1, 0, 0, &pixel.u8[0]).setPixel(color, 0, 0);

		for (int z = 0; z < access.getDepth(); z++)
			for (int y = 0; y < access.getHeight(); y++)
				fillRow(access, y, z, pixelSize, &pixel.u8[0]);
	}
	else
	{
		for (int z = 0; z < access.getDepth(); z++)
			for (int y = 0; y < access.getHeight(); y++)
				for (int x = 0; x < access.getWidth(); x++)
					access.setPixel(color, x, y, z);
	}
}

void clear (const PixelBufferAccess& access, const UVec4& color)
{
	clear(access, color.cast<deInt32>());
}

void clearDepth (const PixelBufferAccess& access, float depth)
{
	DE_ASSERT(access.getFormat().order == TextureFormat::DS || access.getFormat().order == TextureFormat::D);

	clear(getEffectiveDepthStencilAccess(access, Sampler::MODE_DEPTH), tcu::Vec4(depth, 0.0f, 0.0f, 0.0f));
}

void clearStencil (const PixelBufferAccess& access, int stencil)
{
	DE_ASSERT(access.getFormat().order == TextureFormat::DS || access.getFormat().order == TextureFormat::S);

	clear(getEffectiveDepthStencilAccess(access, Sampler::MODE_STENCIL), tcu::UVec4(stencil, 0u, 0u, 0u));
}

static void fillWithComponentGradients1D (const PixelBufferAccess& access, const Vec4& minVal, const Vec4& maxVal)
{
	DE_ASSERT(access.getHeight() == 1);
	for (int x = 0; x < access.getWidth(); x++)
	{
		float s = ((float)x + 0.5f) / (float)access.getWidth();

		float r = linearInterpolate(s, minVal.x(), maxVal.x());
		float g = linearInterpolate(s, minVal.y(), maxVal.y());
		float b = linearInterpolate(s, minVal.z(), maxVal.z());
		float a = linearInterpolate(s, minVal.w(), maxVal.w());

		access.setPixel(tcu::Vec4(r, g, b, a), x, 0);
	}
}

static void fillWithComponentGradients2D (const PixelBufferAccess& access, const Vec4& minVal, const Vec4& maxVal)
{
	for (int y = 0; y < access.getHeight(); y++)
	{
		for (int x = 0; x < access.getWidth(); x++)
		{
			float s = ((float)x + 0.5f) / (float)access.getWidth();
			float t = ((float)y + 0.5f) / (float)access.getHeight();

			float r = linearInterpolate((      s  +       t) *0.5f, minVal.x(), maxVal.x());
			float g = linearInterpolate((      s  + (1.0f-t))*0.5f, minVal.y(), maxVal.y());
			float b = linearInterpolate(((1.0f-s) +       t) *0.5f, minVal.z(), maxVal.z());
			float a = linearInterpolate(((1.0f-s) + (1.0f-t))*0.5f, minVal.w(), maxVal.w());

			access.setPixel(tcu::Vec4(r, g, b, a), x, y);
		}
	}
}

static void fillWithComponentGradients3D (const PixelBufferAccess& dst, const Vec4& minVal, const Vec4& maxVal)
{
	for (int z = 0; z < dst.getDepth(); z++)
	{
		for (int y = 0; y < dst.getHeight(); y++)
		{
			for (int x = 0; x < dst.getWidth(); x++)
			{
				float s = ((float)x + 0.5f) / (float)dst.getWidth();
				float t = ((float)y + 0.5f) / (float)dst.getHeight();
				float p = ((float)z + 0.5f) / (float)dst.getDepth();

				float r = linearInterpolate(s,						minVal.x(), maxVal.x());
				float g = linearInterpolate(t,						minVal.y(), maxVal.y());
				float b = linearInterpolate(p,						minVal.z(), maxVal.z());
				float a = linearInterpolate(1.0f - (s+t+p)/3.0f,	minVal.w(), maxVal.w());

				dst.setPixel(tcu::Vec4(r, g, b, a), x, y, z);
			}
		}
	}
}

void fillWithComponentGradients (const PixelBufferAccess& access, const Vec4& minVal, const Vec4& maxVal)
{
	if (isCombinedDepthStencilType(access.getFormat().type))
	{
		const bool hasDepth		= access.getFormat().order == tcu::TextureFormat::DS || access.getFormat().order == tcu::TextureFormat::D;
		const bool hasStencil	= access.getFormat().order == tcu::TextureFormat::DS || access.getFormat().order == tcu::TextureFormat::S;

		DE_ASSERT(hasDepth || hasStencil);

		// For combined formats, treat D and S as separate channels
		if (hasDepth)
			fillWithComponentGradients(getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_DEPTH), minVal, maxVal);
		if (hasStencil)
			fillWithComponentGradients(getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_STENCIL), minVal.swizzle(3,2,1,0), maxVal.swizzle(3,2,1,0));
	}
	else
	{
		if (access.getHeight() == 1 && access.getDepth() == 1)
			fillWithComponentGradients1D(access, minVal, maxVal);
		else if (access.getDepth() == 1)
			fillWithComponentGradients2D(access, minVal, maxVal);
		else
			fillWithComponentGradients3D(access, minVal, maxVal);
	}
}

static void fillWithGrid1D (const PixelBufferAccess& access, int cellSize, const Vec4& colorA, const Vec4& colorB)
{
	for (int x = 0; x < access.getWidth(); x++)
	{
		int mx = (x / cellSize) % 2;

		if (mx)
			access.setPixel(colorB, x, 0);
		else
			access.setPixel(colorA, x, 0);
	}
}

static void fillWithGrid2D (const PixelBufferAccess& access, int cellSize, const Vec4& colorA, const Vec4& colorB)
{
	for (int y = 0; y < access.getHeight(); y++)
	{
		for (int x = 0; x < access.getWidth(); x++)
		{
			int mx = (x / cellSize) % 2;
			int my = (y / cellSize) % 2;

			if (mx ^ my)
				access.setPixel(colorB, x, y);
			else
				access.setPixel(colorA, x, y);
		}
	}
}

static void fillWithGrid3D (const PixelBufferAccess& access, int cellSize, const Vec4& colorA, const Vec4& colorB)
{
	for (int z = 0; z < access.getDepth(); z++)
	{
		for (int y = 0; y < access.getHeight(); y++)
		{
			for (int x = 0; x < access.getWidth(); x++)
			{
				int mx = (x / cellSize) % 2;
				int my = (y / cellSize) % 2;
				int mz = (z / cellSize) % 2;

				if (mx ^ my ^ mz)
					access.setPixel(colorB, x, y, z);
				else
					access.setPixel(colorA, x, y, z);
			}
		}
	}
}

void fillWithGrid (const PixelBufferAccess& access, int cellSize, const Vec4& colorA, const Vec4& colorB)
{
	if (isCombinedDepthStencilType(access.getFormat().type))
	{
		const bool hasDepth		= access.getFormat().order == tcu::TextureFormat::DS || access.getFormat().order == tcu::TextureFormat::D;
		const bool hasStencil	= access.getFormat().order == tcu::TextureFormat::DS || access.getFormat().order == tcu::TextureFormat::S;

		DE_ASSERT(hasDepth || hasStencil);

		// For combined formats, treat D and S as separate channels
		if (hasDepth)
			fillWithGrid(getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_DEPTH), cellSize, colorA, colorB);
		if (hasStencil)
			fillWithGrid(getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_STENCIL), cellSize, colorA.swizzle(3,2,1,0), colorB.swizzle(3,2,1,0));
	}
	else
	{
		if (access.getHeight() == 1 && access.getDepth() == 1)
			fillWithGrid1D(access, cellSize, colorA, colorB);
		else if (access.getDepth() == 1)
			fillWithGrid2D(access, cellSize, colorA, colorB);
		else
			fillWithGrid3D(access, cellSize, colorA, colorB);
	}
}

void fillWithRepeatableGradient (const PixelBufferAccess& access, const Vec4& colorA, const Vec4& colorB)
{
	for (int y = 0; y < access.getHeight(); y++)
	{
		for (int x = 0; x < access.getWidth(); x++)
		{
			float s = ((float)x + 0.5f) / (float)access.getWidth();
			float t = ((float)y + 0.5f) / (float)access.getHeight();

			float a = s > 0.5f ? (2.0f - 2.0f*s) : 2.0f*s;
			float b = t > 0.5f ? (2.0f - 2.0f*t) : 2.0f*t;

			float p = deFloatClamp(deFloatSqrt(a*a + b*b), 0.0f, 1.0f);
			access.setPixel(linearInterpolate(p, colorA, colorB), x, y);
		}
	}
}

void fillWithRGBAQuads (const PixelBufferAccess& dst)
{
	TCU_CHECK_INTERNAL(dst.getDepth() == 1);
	int width	= dst.getWidth();
	int height	= dst.getHeight();
	int	left	= width/2;
	int top		= height/2;

	clear(getSubregion(dst, 0,		0,		0, left,		top,		1),	Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	clear(getSubregion(dst, left,	0,		0, width-left,	top,		1),	Vec4(0.0f, 1.0f, 0.0f, 1.0f));
	clear(getSubregion(dst, 0,		top,	0, left,		height-top,	1), Vec4(0.0f, 0.0f, 1.0f, 0.0f));
	clear(getSubregion(dst, left,	top,	0, width-left,	height-top, 1), Vec4(0.5f, 0.5f, 0.5f, 1.0f));
}

// \todo [2012-11-13 pyry] There is much better metaballs code in CL SIR value generators.
void fillWithMetaballs (const PixelBufferAccess& dst, int numBalls, deUint32 seed)
{
	TCU_CHECK_INTERNAL(dst.getDepth() == 1);
	std::vector<Vec2>	points(numBalls);
	de::Random			rnd(seed);

	for (int i = 0; i < numBalls; i++)
	{
		float x = rnd.getFloat();
		float y = rnd.getFloat();
		points[i] = (Vec2(x, y));
	}

	for (int y = 0; y < dst.getHeight(); y++)
	for (int x = 0; x < dst.getWidth(); x++)
	{
		Vec2 p((float)x/(float)dst.getWidth(), (float)y/(float)dst.getHeight());

		float sum = 0.0f;
		for (std::vector<Vec2>::const_iterator i = points.begin(); i != points.end(); i++)
		{
			Vec2	d = p - *i;
			float	f = 0.01f / (d.x()*d.x() + d.y()*d.y());

			sum += f;
		}

		dst.setPixel(Vec4(sum), x, y);
	}
}

void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
{
	DE_ASSERT(src.getSize() == dst.getSize());

	const int	width				= dst.getWidth();
	const int	height				= dst.getHeight();
	const int	depth				= dst.getDepth();

	const int	srcPixelSize		= src.getFormat().getPixelSize();
	const int	dstPixelSize		= dst.getFormat().getPixelSize();
	const int	srcPixelPitch		= src.getPixelPitch();
	const int	dstPixelPitch		= dst.getPixelPitch();
	const bool	srcTightlyPacked	= (srcPixelSize == srcPixelPitch);
	const bool	dstTightlyPacked	= (dstPixelSize == dstPixelPitch);

	const bool	srcHasDepth			= (src.getFormat().order == tcu::TextureFormat::DS || src.getFormat().order == tcu::TextureFormat::D);
	const bool	srcHasStencil		= (src.getFormat().order == tcu::TextureFormat::DS || src.getFormat().order == tcu::TextureFormat::S);
	const bool	dstHasDepth			= (dst.getFormat().order == tcu::TextureFormat::DS || dst.getFormat().order == tcu::TextureFormat::D);
	const bool	dstHasStencil		= (dst.getFormat().order == tcu::TextureFormat::DS || dst.getFormat().order == tcu::TextureFormat::S);

	if (src.getFormat() == dst.getFormat() && srcTightlyPacked && dstTightlyPacked)
	{
		// Fast-path for matching formats.
		for (int z = 0; z < depth; z++)
		for (int y = 0; y < height; y++)
			deMemcpy(dst.getPixelPtr(0, y, z), src.getPixelPtr(0, y, z), srcPixelSize*width);
	}
	else if (src.getFormat() == dst.getFormat())
	{
		// Bit-exact copy for matching formats.
		for (int z = 0; z < depth; z++)
		for (int y = 0; y < height; y++)
		for (int x = 0; x < width; x++)
			deMemcpy(dst.getPixelPtr(x, y, z), src.getPixelPtr(x, y, z), srcPixelSize);
	}
	else if (srcHasDepth || srcHasStencil || dstHasDepth || dstHasStencil)
	{
		DE_ASSERT((srcHasDepth && dstHasDepth) || (srcHasStencil && dstHasStencil)); // must have at least one common channel

		if (dstHasDepth && srcHasDepth)
		{
			for (int z = 0; z < depth; z++)
			for (int y = 0; y < height; y++)
			for (int x = 0; x < width; x++)
				dst.setPixDepth(src.getPixDepth(x, y, z), x, y, z);
		}
		else if (dstHasDepth && !srcHasDepth)
		{
			// consistency with color copies
			tcu::clearDepth(dst, 0.0f);
		}

		if (dstHasStencil && srcHasStencil)
		{
			for (int z = 0; z < depth; z++)
			for (int y = 0; y < height; y++)
			for (int x = 0; x < width; x++)
				dst.setPixStencil(src.getPixStencil(x, y, z), x, y, z);
		}
		else if (dstHasStencil && !srcHasStencil)
		{
			// consistency with color copies
			tcu::clearStencil(dst, 0u);
		}
	}
	else
	{
		TextureChannelClass		srcClass	= getTextureChannelClass(src.getFormat().type);
		TextureChannelClass		dstClass	= getTextureChannelClass(dst.getFormat().type);
		bool					srcIsInt	= srcClass == TEXTURECHANNELCLASS_SIGNED_INTEGER || srcClass == TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
		bool					dstIsInt	= dstClass == TEXTURECHANNELCLASS_SIGNED_INTEGER || dstClass == TEXTURECHANNELCLASS_UNSIGNED_INTEGER;

		if (srcIsInt && dstIsInt)
		{
			for (int z = 0; z < depth; z++)
			for (int y = 0; y < height; y++)
			for (int x = 0; x < width; x++)
				dst.setPixel(src.getPixelInt(x, y, z), x, y, z);
		}
		else
		{
			for (int z = 0; z < depth; z++)
			for (int y = 0; y < height; y++)
			for (int x = 0; x < width; x++)
				dst.setPixel(src.getPixel(x, y, z), x, y, z);
		}
	}
}

void scale (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, Sampler::FilterMode filter)
{
	DE_ASSERT(filter == Sampler::NEAREST || filter == Sampler::LINEAR);

	Sampler sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE,
					filter, filter, 0.0f, false);

	float sX = (float)src.getWidth() / (float)dst.getWidth();
	float sY = (float)src.getHeight() / (float)dst.getHeight();
	float sZ = (float)src.getDepth() / (float)dst.getDepth();

	if (dst.getDepth() == 1 && src.getDepth() == 1)
	{
		for (int y = 0; y < dst.getHeight(); y++)
		for (int x = 0; x < dst.getWidth(); x++)
			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, 0)), x, y);
	}
	else
	{
		for (int z = 0; z < dst.getDepth(); z++)
		for (int y = 0; y < dst.getHeight(); y++)
		for (int x = 0; x < dst.getWidth(); x++)
			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), x, y, z);
	}
}

void estimatePixelValueRange (const ConstPixelBufferAccess& access, Vec4& minVal, Vec4& maxVal)
{
	const TextureFormat& format = access.getFormat();

	switch (getTextureChannelClass(format.type))
	{
		case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			// Normalized unsigned formats.
			minVal = Vec4(0.0f);
			maxVal = Vec4(1.0f);
			break;

		case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			// Normalized signed formats.
			minVal = Vec4(-1.0f);
			maxVal = Vec4(+1.0f);
			break;

		default:
			// \note Samples every 4/8th pixel.
			minVal = Vec4(std::numeric_limits<float>::max());
			maxVal = Vec4(std::numeric_limits<float>::min());

			for (int z = 0; z < access.getDepth(); z += 2)
			{
				for (int y = 0; y < access.getHeight(); y += 2)
				{
					for (int x = 0; x < access.getWidth(); x += 2)
					{
						Vec4 p = access.getPixel(x, y, z);

						minVal[0] = (deFloatIsNaN(p[0]) ? minVal[0] : de::min(minVal[0], p[0]));
						minVal[1] = (deFloatIsNaN(p[1]) ? minVal[1] : de::min(minVal[1], p[1]));
						minVal[2] = (deFloatIsNaN(p[2]) ? minVal[2] : de::min(minVal[2], p[2]));
						minVal[3] = (deFloatIsNaN(p[3]) ? minVal[3] : de::min(minVal[3], p[3]));

						maxVal[0] = (deFloatIsNaN(p[0]) ? maxVal[0] : de::max(maxVal[0], p[0]));
						maxVal[1] = (deFloatIsNaN(p[1]) ? maxVal[1] : de::max(maxVal[1], p[1]));
						maxVal[2] = (deFloatIsNaN(p[2]) ? maxVal[2] : de::max(maxVal[2], p[2]));
						maxVal[3] = (deFloatIsNaN(p[3]) ? maxVal[3] : de::max(maxVal[3], p[3]));
					}
				}
			}
			break;
	}
}

void computePixelScaleBias (const ConstPixelBufferAccess& access, Vec4& scale, Vec4& bias)
{
	Vec4 minVal, maxVal;
	estimatePixelValueRange(access, minVal, maxVal);

	const float eps = 0.0001f;

	for (int c = 0; c < 4; c++)
	{
		if (maxVal[c] - minVal[c] < eps)
		{
			scale[c]	= (maxVal[c] < eps) ? 1.0f : (1.0f / maxVal[c]);
			bias[c]		= (c == 3) ? (1.0f - maxVal[c]*scale[c]) : (0.0f - minVal[c]*scale[c]);
		}
		else
		{
			scale[c]	= 1.0f / (maxVal[c] - minVal[c]);
			bias[c]		= 0.0f - minVal[c]*scale[c];
		}
	}
}

int getCubeArrayFaceIndex (CubeFace face)
{
	DE_ASSERT((int)face >= 0 && face < CUBEFACE_LAST);

	switch (face)
	{
		case CUBEFACE_POSITIVE_X:	return 0;
		case CUBEFACE_NEGATIVE_X:	return 1;
		case CUBEFACE_POSITIVE_Y:	return 2;
		case CUBEFACE_NEGATIVE_Y:	return 3;
		case CUBEFACE_POSITIVE_Z:	return 4;
		case CUBEFACE_NEGATIVE_Z:	return 5;

		default:
			return -1;
	}
}

deUint32 packRGB999E5 (const tcu::Vec4& color)
{
	const int	mBits	= 9;
	const int	eBits	= 5;
	const int	eBias	= 15;
	const int	eMax	= (1<<eBits)-1;
	const float	maxVal	= (float)(((1<<mBits) - 1) * (1<<(eMax-eBias))) / (float)(1<<mBits);

	float	rc		= deFloatClamp(color[0], 0.0f, maxVal);
	float	gc		= deFloatClamp(color[1], 0.0f, maxVal);
	float	bc		= deFloatClamp(color[2], 0.0f, maxVal);
	float	maxc	= de::max(rc, de::max(gc, bc));
	int		exps	= de::max(-eBias - 1, deFloorFloatToInt32(deFloatLog2(maxc))) + 1 + eBias;
	float	e		= deFloatPow(2.0f, (float)(exps-eBias-mBits));
	int		maxs	= deFloorFloatToInt32(maxc / e + 0.5f);

	if (maxs == (1<<mBits))
	{
		exps++;
		e *= 2.0f;
	}

	deUint32 rs = (deUint32)deFloorFloatToInt32(rc / e + 0.5f);
	deUint32 gs = (deUint32)deFloorFloatToInt32(gc / e + 0.5f);
	deUint32 bs = (deUint32)deFloorFloatToInt32(bc / e + 0.5f);

	DE_ASSERT((exps & ~((1<<5)-1)) == 0);
	DE_ASSERT((rs & ~((1<<9)-1)) == 0);
	DE_ASSERT((gs & ~((1<<9)-1)) == 0);
	DE_ASSERT((bs & ~((1<<9)-1)) == 0);

	return rs | (gs << 9) | (bs << 18) | (exps << 27);
}

// Sampler utils

static const void* addOffset (const void* ptr, int numBytes)
{
	return (const deUint8*)ptr + numBytes;
}

static void* addOffset (void* ptr, int numBytes)
{
	return (deUint8*)ptr + numBytes;
}

template <typename AccessType>
static AccessType toSamplerAccess (const AccessType& baseAccess, Sampler::DepthStencilMode mode)
{
	// make sure to update this if type table is updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELTYPE_LAST == 46);

	if (!isCombinedDepthStencilType(baseAccess.getFormat().type))
		return baseAccess;
	else
	{
#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
		const deUint32 uint32ByteOffsetBits0To8		= 0; //!< least significant byte in the lowest address
		const deUint32 uint32ByteOffsetBits0To24	= 0;
		const deUint32 uint32ByteOffsetBits8To32	= 1;
		const deUint32 uint32ByteOffsetBits16To32	= 2;
		const deUint32 uint32ByteOffsetBits24To32	= 3;
#else
		const deUint32 uint32ByteOffsetBits0To8		= 3; //!< least significant byte in the highest address
		const deUint32 uint32ByteOffsetBits0To24	= 1;
		const deUint32 uint32ByteOffsetBits8To32	= 0;
		const deUint32 uint32ByteOffsetBits16To32	= 0;
		const deUint32 uint32ByteOffsetBits24To32	= 0;
#endif

		// Sampled channel must exist
		DE_ASSERT(baseAccess.getFormat().order == TextureFormat::DS ||
				  (mode == Sampler::MODE_DEPTH && baseAccess.getFormat().order == TextureFormat::D) ||
				  (mode == Sampler::MODE_STENCIL && baseAccess.getFormat().order == TextureFormat::S));

		// combined formats have multiple channel classes, detect on sampler settings
		switch (baseAccess.getFormat().type)
		{
			case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
			{
				if (mode == Sampler::MODE_DEPTH)
				{
					// select the float component
					return AccessType(TextureFormat(TextureFormat::D, TextureFormat::FLOAT),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  baseAccess.getDataPtr());
				}
				else if (mode == Sampler::MODE_STENCIL)
				{
					// select the uint 8 component
					return AccessType(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), 4 + uint32ByteOffsetBits0To8));
				}
				else
				{
					// unknown sampler mode
					DE_ASSERT(false);
					return AccessType();
				}
			}

			case TextureFormat::UNSIGNED_INT_16_8_8:
			{
				if (mode == Sampler::MODE_DEPTH)
				{
					// select the unorm16 component
					return AccessType(TextureFormat(TextureFormat::D, TextureFormat::UNORM_INT16),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), uint32ByteOffsetBits16To32));
				}
				else if (mode == Sampler::MODE_STENCIL)
				{
					// select the uint 8 component
					return AccessType(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), uint32ByteOffsetBits0To8));
				}
				else
				{
					// unknown sampler mode
					DE_ASSERT(false);
					return AccessType();
				}
			}

			case TextureFormat::UNSIGNED_INT_24_8:
			{
				if (mode == Sampler::MODE_DEPTH)
				{
					// select the unorm24 component
					return AccessType(TextureFormat(TextureFormat::D, TextureFormat::UNORM_INT24),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), uint32ByteOffsetBits8To32));
				}
				else if (mode == Sampler::MODE_STENCIL)
				{
					// select the uint 8 component
					return AccessType(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), uint32ByteOffsetBits0To8));
				}
				else
				{
					// unknown sampler mode
					DE_ASSERT(false);
					return AccessType();
				}
			}

			case TextureFormat::UNSIGNED_INT_24_8_REV:
			{
				if (mode == Sampler::MODE_DEPTH)
				{
					// select the unorm24 component
					return AccessType(TextureFormat(TextureFormat::D, TextureFormat::UNORM_INT24),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), uint32ByteOffsetBits0To24));
				}
				else if (mode == Sampler::MODE_STENCIL)
				{
					// select the uint 8 component
					return AccessType(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8),
									  baseAccess.getSize(),
									  baseAccess.getPitch(),
									  addOffset(baseAccess.getDataPtr(), uint32ByteOffsetBits24To32));
				}
				else
				{
					// unknown sampler mode
					DE_ASSERT(false);
					return AccessType();
				}
			}

			default:
			{
				// unknown combined format
				DE_ASSERT(false);
				return AccessType();
			}
		}
	}
}

PixelBufferAccess getEffectiveDepthStencilAccess (const PixelBufferAccess& baseAccess, Sampler::DepthStencilMode mode)
{
	return toSamplerAccess<PixelBufferAccess>(baseAccess, mode);
}

ConstPixelBufferAccess getEffectiveDepthStencilAccess (const ConstPixelBufferAccess& baseAccess, Sampler::DepthStencilMode mode)
{
	return toSamplerAccess<ConstPixelBufferAccess>(baseAccess, mode);
}

TextureFormat getEffectiveDepthStencilTextureFormat (const TextureFormat& baseFormat, Sampler::DepthStencilMode mode)
{
	return toSamplerAccess(ConstPixelBufferAccess(baseFormat, IVec3(0, 0, 0), DE_NULL), mode).getFormat();
}

template <typename ViewType>
ViewType getEffectiveTView (const ViewType& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	storage.resize(src.getNumLevels());

	ViewType view = ViewType(src.getNumLevels(), &storage[0]);

	for (int levelNdx = 0; levelNdx < src.getNumLevels(); ++levelNdx)
		storage[levelNdx] = tcu::getEffectiveDepthStencilAccess(src.getLevel(levelNdx), sampler.depthStencilMode);

	return view;
}

tcu::TextureCubeView getEffectiveTView (const tcu::TextureCubeView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	storage.resize(tcu::CUBEFACE_LAST * src.getNumLevels());

	const tcu::ConstPixelBufferAccess* storagePtrs[tcu::CUBEFACE_LAST] =
	{
		&storage[0 * src.getNumLevels()],
		&storage[1 * src.getNumLevels()],
		&storage[2 * src.getNumLevels()],
		&storage[3 * src.getNumLevels()],
		&storage[4 * src.getNumLevels()],
		&storage[5 * src.getNumLevels()],
	};

	tcu::TextureCubeView view = tcu::TextureCubeView(src.getNumLevels(), storagePtrs);

	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
	for (int levelNdx = 0; levelNdx < src.getNumLevels(); ++levelNdx)
		storage[faceNdx * src.getNumLevels() + levelNdx] = tcu::getEffectiveDepthStencilAccess(src.getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), sampler.depthStencilMode);

	return view;
}

tcu::Texture1DView getEffectiveTextureView (const tcu::Texture1DView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

tcu::Texture2DView getEffectiveTextureView (const tcu::Texture2DView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

tcu::Texture3DView getEffectiveTextureView (const tcu::Texture3DView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

tcu::Texture1DArrayView getEffectiveTextureView (const tcu::Texture1DArrayView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

tcu::Texture2DArrayView getEffectiveTextureView (const tcu::Texture2DArrayView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

tcu::TextureCubeView getEffectiveTextureView (const tcu::TextureCubeView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

tcu::TextureCubeArrayView getEffectiveTextureView (const tcu::TextureCubeArrayView& src, std::vector<tcu::ConstPixelBufferAccess>& storage, const tcu::Sampler& sampler)
{
	return getEffectiveTView(src, storage, sampler);
}

//! Returns the effective swizzle of a border color. The effective swizzle is the
//! equal to first writing an RGBA color with a write swizzle and then reading
//! it back using a read swizzle, i.e. BorderSwizzle(c) == readSwizzle(writeSwizzle(C))
static const TextureSwizzle& getBorderColorReadSwizzle (TextureFormat::ChannelOrder order)
{
	// make sure to update these tables when channel orders are updated
	DE_STATIC_ASSERT(TextureFormat::CHANNELORDER_LAST == 21);

	static const TextureSwizzle INV		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
	static const TextureSwizzle R		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
	static const TextureSwizzle A		= {{ TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_3	}};
	static const TextureSwizzle I		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0	}};
	static const TextureSwizzle L		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ONE	}};
	static const TextureSwizzle LA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_3	}};
	static const TextureSwizzle RG		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
	static const TextureSwizzle RA		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_3	}};
	static const TextureSwizzle RGB		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_ONE	}};
	static const TextureSwizzle RGBA	= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_1,		TextureSwizzle::CHANNEL_2,		TextureSwizzle::CHANNEL_3	}};
	static const TextureSwizzle D		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};
	static const TextureSwizzle S		= {{ TextureSwizzle::CHANNEL_0,		TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ZERO,	TextureSwizzle::CHANNEL_ONE	}};

	const TextureSwizzle* swizzle;

	switch (order)
	{
		case TextureFormat::R:			swizzle = &R;		break;
		case TextureFormat::A:			swizzle = &A;		break;
		case TextureFormat::I:			swizzle = &I;		break;
		case TextureFormat::L:			swizzle = &L;		break;
		case TextureFormat::LA:			swizzle = &LA;		break;
		case TextureFormat::RG:			swizzle = &RG;		break;
		case TextureFormat::RA:			swizzle = &RA;		break;
		case TextureFormat::RGB:		swizzle = &RGB;		break;
		case TextureFormat::RGBA:		swizzle = &RGBA;	break;
		case TextureFormat::ARGB:		swizzle = &RGBA;	break;
		case TextureFormat::BGR:		swizzle = &RGB;		break;
		case TextureFormat::BGRA:		swizzle = &RGBA;	break;
		case TextureFormat::sR:			swizzle = &R;		break;
		case TextureFormat::sRG:		swizzle = &RG;		break;
		case TextureFormat::sRGB:		swizzle = &RGB;		break;
		case TextureFormat::sRGBA:		swizzle = &RGBA;	break;
		case TextureFormat::sBGR:		swizzle = &RGB;		break;
		case TextureFormat::sBGRA:		swizzle = &RGBA;	break;
		case TextureFormat::D:			swizzle = &D;		break;
		case TextureFormat::S:			swizzle = &S;		break;

		case TextureFormat::DS:
			DE_ASSERT(false); // combined depth-stencil border color?
			swizzle = &INV;
			break;

		default:
			DE_ASSERT(false);
			swizzle = &INV;
			break;
	}

#ifdef DE_DEBUG

	{
		// check that BorderSwizzle(c) == readSwizzle(writeSwizzle(C))
		const TextureSwizzle& readSwizzle	= getChannelReadSwizzle(order);
		const TextureSwizzle& writeSwizzle	= getChannelWriteSwizzle(order);

		for (int ndx = 0; ndx < 4; ++ndx)
		{
			TextureSwizzle::Channel writeRead = readSwizzle.components[ndx];
			if (deInRange32(writeRead, TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE)
				writeRead = writeSwizzle.components[(int)writeRead];
			DE_ASSERT(writeRead == swizzle->components[ndx]);
		}
	}

#endif

	return *swizzle;
}

static tcu::UVec4 getNBitUnsignedIntegerVec4MaxValue (const tcu::IVec4& numBits)
{
	return tcu::UVec4((numBits[0] > 0) ? (deUintMaxValue32(numBits[0])) : (0),
					  (numBits[1] > 0) ? (deUintMaxValue32(numBits[1])) : (0),
					  (numBits[2] > 0) ? (deUintMaxValue32(numBits[2])) : (0),
					  (numBits[3] > 0) ? (deUintMaxValue32(numBits[3])) : (0));
}

static tcu::IVec4 getNBitSignedIntegerVec4MaxValue (const tcu::IVec4& numBits)
{
	return tcu::IVec4((numBits[0] > 0) ? (deIntMaxValue32(numBits[0])) : (0),
					  (numBits[1] > 0) ? (deIntMaxValue32(numBits[1])) : (0),
					  (numBits[2] > 0) ? (deIntMaxValue32(numBits[2])) : (0),
					  (numBits[3] > 0) ? (deIntMaxValue32(numBits[3])) : (0));
}

static tcu::IVec4 getNBitSignedIntegerVec4MinValue (const tcu::IVec4& numBits)
{
	return tcu::IVec4((numBits[0] > 0) ? (deIntMinValue32(numBits[0])) : (0),
					  (numBits[1] > 0) ? (deIntMinValue32(numBits[1])) : (0),
					  (numBits[2] > 0) ? (deIntMinValue32(numBits[2])) : (0),
					  (numBits[3] > 0) ? (deIntMinValue32(numBits[3])) : (0));
}

static tcu::Vec4 getTextureBorderColorFloat (const TextureFormat& format, const Sampler& sampler)
{
	const tcu::TextureChannelClass	channelClass	= getTextureChannelClass(format.type);
	const TextureSwizzle::Channel*	channelMap		= getBorderColorReadSwizzle(format.order).components;
	const bool						isFloat			= channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
	const bool						isSigned		= channelClass != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
	const float						valueMin		= (isSigned) ? (-1.0f) : (0.0f);
	const float						valueMax		= 1.0f;
	Vec4							result;

	DE_ASSERT(channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT ||
			  channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
			  channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT);

	for (int c = 0; c < 4; c++)
	{
		const TextureSwizzle::Channel map = channelMap[c];
		if (map == TextureSwizzle::CHANNEL_ZERO)
			result[c] = 0.0f;
		else if (map == TextureSwizzle::CHANNEL_ONE)
			result[c] = 1.0f;
		else if (isFloat)
		{
			// floating point values are not clamped
			result[c] = sampler.borderColor.getAccess<float>()[(int)map];
		}
		else
		{
			// fixed point values are clamped to a representable range
			result[c] = de::clamp(sampler.borderColor.getAccess<float>()[(int)map], valueMin, valueMax);
		}
	}

	return result;
}

static tcu::IVec4 getTextureBorderColorInt (const TextureFormat& format, const Sampler& sampler)
{
	const tcu::TextureChannelClass	channelClass	= getTextureChannelClass(format.type);
	const TextureSwizzle::Channel*	channelMap		= getBorderColorReadSwizzle(format.order).components;
	const IVec4						channelBits		= getChannelBitDepth(format.type);
	const IVec4						valueMin		= getNBitSignedIntegerVec4MinValue(channelBits);
	const IVec4						valueMax		= getNBitSignedIntegerVec4MaxValue(channelBits);
	IVec4							result;

	DE_ASSERT(channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
	DE_UNREF(channelClass);

	for (int c = 0; c < 4; c++)
	{
		const TextureSwizzle::Channel map = channelMap[c];
		if (map == TextureSwizzle::CHANNEL_ZERO)
			result[c] = 0;
		else if (map == TextureSwizzle::CHANNEL_ONE)
			result[c] = 1;
		else
		{
			// integer values are clamped to a representable range
			result[c] = de::clamp(sampler.borderColor.getAccess<deInt32>()[(int)map], valueMin[(int)map], valueMax[(int)map]);
		}
	}

	return result;
}

static tcu::UVec4 getTextureBorderColorUint (const TextureFormat& format, const Sampler& sampler)
{
	const tcu::TextureChannelClass	channelClass	= getTextureChannelClass(format.type);
	const TextureSwizzle::Channel*	channelMap		= getBorderColorReadSwizzle(format.order).components;
	const IVec4						channelBits		= getChannelBitDepth(format.type);
	const UVec4						valueMax		= getNBitUnsignedIntegerVec4MaxValue(channelBits);
	UVec4							result;

	DE_ASSERT(channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
	DE_UNREF(channelClass);

	for (int c = 0; c < 4; c++)
	{
		const TextureSwizzle::Channel map = channelMap[c];
		if (map == TextureSwizzle::CHANNEL_ZERO)
			result[c] = 0;
		else if (map == TextureSwizzle::CHANNEL_ONE)
			result[c] = 1;
		else
		{
			// integer values are clamped to a representable range
			result[c] = de::min(sampler.borderColor.getAccess<deUint32>()[(int)map], valueMax[(int)map]);
		}
	}

	return result;
}

template <typename ScalarType>
tcu::Vector<ScalarType, 4> sampleTextureBorder (const TextureFormat& format, const Sampler& sampler)
{
	const tcu::TextureChannelClass channelClass = getTextureChannelClass(format.type);

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			return getTextureBorderColorFloat(format, sampler).cast<ScalarType>();

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			return getTextureBorderColorInt(format, sampler).cast<ScalarType>();

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			return getTextureBorderColorUint(format, sampler).cast<ScalarType>();

		default:
			DE_ASSERT(false);
			return tcu::Vector<ScalarType, 4>();
	}
}

// instantiation
template tcu::Vector<float, 4>		sampleTextureBorder (const TextureFormat& format, const Sampler& sampler);
template tcu::Vector<deInt32, 4>	sampleTextureBorder (const TextureFormat& format, const Sampler& sampler);
template tcu::Vector<deUint32, 4>	sampleTextureBorder (const TextureFormat& format, const Sampler& sampler);

} // tcu
