/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 * Copyright (c) 2016 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 Floating-point packing and unpacking function tests.
 *//*--------------------------------------------------------------------*/

#include "vktShaderPackingFunctionTests.hpp"
#include "vktShaderExecutor.hpp"
#include "tcuTestLog.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuFloat.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"
#include "deSharedPtr.hpp"

namespace vkt
{
namespace shaderexecutor
{

using namespace shaderexecutor;

using std::string;
using tcu::TestLog;

namespace
{

inline deUint32 getUlpDiff (float a, float b)
{
	const deUint32	aBits	= tcu::Float32(a).bits();
	const deUint32	bBits	= tcu::Float32(b).bits();
	return aBits > bBits ? aBits - bBits : bBits - aBits;
}

struct HexFloat
{
	const float value;
	HexFloat (const float value_) : value(value_) {}
};

std::ostream& operator<< (std::ostream& str, const HexFloat& v)
{
	return str << v.value << " / " << tcu::toHex(tcu::Float32(v.value).bits());
}

static const char* getPrecisionPostfix (glu::Precision precision)
{
	static const char* s_postfix[] =
	{
		"_lowp",
		"_mediump",
		"_highp"
	};
	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_postfix) == glu::PRECISION_LAST);
	DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
	return s_postfix[precision];
}

static const char* getShaderTypePostfix (glu::ShaderType shaderType)
{
	static const char* s_postfix[] =
	{
		"_vertex",
		"_fragment",
		"_geometry",
		"_tess_control",
		"_tess_eval",
		"_compute"
	};
	DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
	return s_postfix[shaderType];
}

} // anonymous

// ShaderPackingFunctionCase

class ShaderPackingFunctionCase : public TestCase
{
public:
										ShaderPackingFunctionCase			(tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType);
										~ShaderPackingFunctionCase			(void);

	virtual	void						initPrograms						(vk::SourceCollections& programCollection) const
										{
											generateSources(m_shaderType, m_spec, programCollection);
										}

protected:
	const glu::ShaderType				m_shaderType;
	ShaderSpec							m_spec;

private:
										ShaderPackingFunctionCase			(const ShaderPackingFunctionCase& other);
	ShaderPackingFunctionCase&			operator=							(const ShaderPackingFunctionCase& other);
};

ShaderPackingFunctionCase::ShaderPackingFunctionCase (tcu::TestContext& testCtx, const char* name, const char* description, glu::ShaderType shaderType)
	: TestCase		(testCtx, name, description)
	, m_shaderType	(shaderType)
{
}

ShaderPackingFunctionCase::~ShaderPackingFunctionCase (void)
{
}

// ShaderPackingFunctionTestInstance

class ShaderPackingFunctionTestInstance : public TestInstance
{
public:
										ShaderPackingFunctionTestInstance	(Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
											: TestInstance	(context)
											, m_testCtx		(context.getTestContext())
											, m_shaderType	(shaderType)
											, m_spec		(spec)
											, m_name		(name)
											, m_executor	(createExecutor(context, m_shaderType, m_spec))
										{
										}
	virtual tcu::TestStatus				iterate								(void) = 0;
protected:
	tcu::TestContext&					m_testCtx;
	const glu::ShaderType				m_shaderType;
	ShaderSpec							m_spec;
	const char*							m_name;
	de::UniquePtr<ShaderExecutor>		m_executor;
};

// Test cases

class PackSnorm2x16CaseInstance: public ShaderPackingFunctionTestInstance
{
public:
	PackSnorm2x16CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, glu::Precision precision, const char* name)
		: ShaderPackingFunctionTestInstance	(context, shaderType, spec, name)
		, m_precision						(precision)
	{
	}

	tcu::TestStatus iterate (void)
	{
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<tcu::Vec2>		inputs;
		std::vector<deUint32>		outputs;
		const int					maxDiff		= m_precision == glu::PRECISION_HIGHP	? 1		:		// Rounding only.
												  m_precision == glu::PRECISION_MEDIUMP	? 33	:		// (2^-10) * (2^15) + 1
												  m_precision == glu::PRECISION_LOWP	? 129	: 0;	// (2^-8) * (2^15) + 1

		// Special values to check.
		inputs.push_back(tcu::Vec2(0.0f, 0.0f));
		inputs.push_back(tcu::Vec2(-1.0f, 1.0f));
		inputs.push_back(tcu::Vec2(0.5f, -0.5f));
		inputs.push_back(tcu::Vec2(-1.5f, 1.5f));
		inputs.push_back(tcu::Vec2(0.25f, -0.75f));

		// Random values, mostly in range.
		for (int ndx = 0; ndx < 15; ndx++)
		{
			const float x = rnd.getFloat()*2.5f - 1.25f;
			const float y = rnd.getFloat()*2.5f - 1.25f;
			inputs.push_back(tcu::Vec2(x, y));
		}

		// Large random values.
		for (int ndx = 0; ndx < 80; ndx++)
		{
			const float x = rnd.getFloat()*1e6f - 0.5e6f;
			const float y = rnd.getFloat()*1e6f - 0.5e6f;
			inputs.push_back(tcu::Vec2(x, y));
		}

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < numValues; valNdx++)
			{
				const deUint16	ref0	= (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 32767.0f), -(1<<15), (1<<15)-1);
				const deUint16	ref1	= (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 32767.0f), -(1<<15), (1<<15)-1);
				const deUint32	ref		= (ref1 << 16) | ref0;
				const deUint32	res		= outputs[valNdx];
				const deUint16	res0	= (deUint16)(res & 0xffff);
				const deUint16	res1	= (deUint16)(res >> 16);
				const int		diff0	= de::abs((int)ref0 - (int)res0);
				const int		diff1	= de::abs((int)ref1 - (int)res1);

				if (diff0 > maxDiff || diff1 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
															   << ", expected packSnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
															   << ", got " << tcu::toHex(res)
															   << "\n  diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}

private:
	const glu::Precision m_precision;
};

class PackSnorm2x16Case : public ShaderPackingFunctionCase
{
public:
	PackSnorm2x16Case (tcu::TestContext& testCtx, glu::ShaderType shaderType, glu::Precision precision)
		: ShaderPackingFunctionCase	(testCtx, (string("packsnorm2x16") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packSnorm2x16", shaderType)
		, m_precision				(precision)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, precision)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = packSnorm2x16(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new PackSnorm2x16CaseInstance(ctx, m_shaderType, m_spec, m_precision, getName());
	}

private:
	const glu::Precision m_precision;
};

class UnpackSnorm2x16CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	UnpackSnorm2x16CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
	: ShaderPackingFunctionTestInstance (context, shaderType, spec, name)
	{
	}

	tcu::TestStatus iterate (void)
	{
		const deUint32				maxDiff		= 1; // Rounding error.
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<deUint32>		inputs;
		std::vector<tcu::Vec2>		outputs;

		inputs.push_back(0x00000000u);
		inputs.push_back(0x7fff8000u);
		inputs.push_back(0x80007fffu);
		inputs.push_back(0xffffffffu);
		inputs.push_back(0x0001fffeu);

		// Random values.
		for (int ndx = 0; ndx < 95; ndx++)
			inputs.push_back(rnd.getUint32());

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deInt16	in0			= (deInt16)(deUint16)(inputs[valNdx] & 0xffff);
				const deInt16	in1			= (deInt16)(deUint16)(inputs[valNdx] >> 16);
				const float		ref0		= de::clamp(float(in0) / 32767.f, -1.0f, 1.0f);
				const float		ref1		= de::clamp(float(in1) / 32767.f, -1.0f, 1.0f);
				const float		res0		= outputs[valNdx].x();
				const float		res1		= outputs[valNdx].y();

				const deUint32	diff0	= getUlpDiff(ref0, res0);
				const deUint32	diff1	= getUlpDiff(ref1, res1);

				if (diff0 > maxDiff || diff1 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
															   << "  expected unpackSnorm2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
															   << "vec2(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ")"
															   << ", got vec2(" << HexFloat(res0) << ", " << HexFloat(res1) << ")"
															   << "\n  ULP diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}
};

class UnpackSnorm2x16Case : public ShaderPackingFunctionCase
{
public:
	UnpackSnorm2x16Case (tcu::TestContext& testCtx, glu::ShaderType shaderType)
		: ShaderPackingFunctionCase	(testCtx, (string("unpacksnorm2x16") + getShaderTypePostfix(shaderType)).c_str(), "unpackSnorm2x16", shaderType)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = unpackSnorm2x16(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new UnpackSnorm2x16CaseInstance(ctx, m_shaderType, m_spec, getName());
	}
};

class PackUnorm2x16CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	PackUnorm2x16CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, glu::Precision precision, const char* name)
	: ShaderPackingFunctionTestInstance	(context, shaderType, spec, name)
	, m_precision						(precision)
	{
	}

	tcu::TestStatus iterate (void)
	{
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<tcu::Vec2>		inputs;
		std::vector<deUint32>		outputs;
		const int					maxDiff		= m_precision == glu::PRECISION_HIGHP	? 1		:		// Rounding only.
												  m_precision == glu::PRECISION_MEDIUMP	? 65	:		// (2^-10) * (2^16) + 1
												  m_precision == glu::PRECISION_LOWP	? 257	: 0;	// (2^-8) * (2^16) + 1

		// Special values to check.
		inputs.push_back(tcu::Vec2(0.0f, 0.0f));
		inputs.push_back(tcu::Vec2(0.5f, 1.0f));
		inputs.push_back(tcu::Vec2(1.0f, 0.5f));
		inputs.push_back(tcu::Vec2(-0.5f, 1.5f));
		inputs.push_back(tcu::Vec2(0.25f, 0.75f));

		// Random values, mostly in range.
		for (int ndx = 0; ndx < 15; ndx++)
		{
			const float x = rnd.getFloat()*1.25f;
			const float y = rnd.getFloat()*1.25f;
			inputs.push_back(tcu::Vec2(x, y));
		}

		// Large random values.
		for (int ndx = 0; ndx < 80; ndx++)
		{
			const float x = rnd.getFloat()*1e6f - 1e5f;
			const float y = rnd.getFloat()*1e6f - 1e5f;
			inputs.push_back(tcu::Vec2(x, y));
		}

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deUint16	ref0	= (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), 0.0f, 1.0f) * 65535.0f), 0, (1<<16)-1);
				const deUint16	ref1	= (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), 0.0f, 1.0f) * 65535.0f), 0, (1<<16)-1);
				const deUint32	ref		= (ref1 << 16) | ref0;
				const deUint32	res		= outputs[valNdx];
				const deUint16	res0	= (deUint16)(res & 0xffff);
				const deUint16	res1	= (deUint16)(res >> 16);
				const int		diff0	= de::abs((int)ref0 - (int)res0);
				const int		diff1	= de::abs((int)ref1 - (int)res1);

				if (diff0 > maxDiff || diff1 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
															   << ", expected packUnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
															   << ", got " << tcu::toHex(res)
															   << "\n  diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}

private:
	const glu::Precision m_precision;
};

class PackUnorm2x16Case : public ShaderPackingFunctionCase
{
public:
	PackUnorm2x16Case (tcu::TestContext& testCtx, glu::ShaderType shaderType, glu::Precision precision)
		: ShaderPackingFunctionCase	(testCtx, (string("packunorm2x16") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packUnorm2x16", shaderType)
		, m_precision				(precision)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, precision)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = packUnorm2x16(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new PackUnorm2x16CaseInstance(ctx, m_shaderType, m_spec, m_precision, getName());
	}

private:
	const glu::Precision m_precision;
};

class UnpackUnorm2x16CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	UnpackUnorm2x16CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
		: ShaderPackingFunctionTestInstance (context, shaderType, spec, name)
	{
	}

	tcu::TestStatus iterate (void)
	{
		const deUint32				maxDiff		= 1; // Rounding error.
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<deUint32>		inputs;
		std::vector<tcu::Vec2>		outputs;

		inputs.push_back(0x00000000u);
		inputs.push_back(0x7fff8000u);
		inputs.push_back(0x80007fffu);
		inputs.push_back(0xffffffffu);
		inputs.push_back(0x0001fffeu);

		// Random values.
		for (int ndx = 0; ndx < 95; ndx++)
			inputs.push_back(rnd.getUint32());

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deUint16	in0			= (deUint16)(inputs[valNdx] & 0xffff);
				const deUint16	in1			= (deUint16)(inputs[valNdx] >> 16);
				const float		ref0		= float(in0) / 65535.0f;
				const float		ref1		= float(in1) / 65535.0f;
				const float		res0		= outputs[valNdx].x();
				const float		res1		= outputs[valNdx].y();

				const deUint32	diff0		= getUlpDiff(ref0, res0);
				const deUint32	diff1		= getUlpDiff(ref1, res1);

				if (diff0 > maxDiff || diff1 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
															   << "  expected unpackUnorm2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
															   << "vec2(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ")"
															   << ", got vec2(" << HexFloat(res0) << ", " << HexFloat(res1) << ")"
															   << "\n  ULP diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}
};


class UnpackUnorm2x16Case : public ShaderPackingFunctionCase
{
public:
	UnpackUnorm2x16Case (tcu::TestContext& testCtx, glu::ShaderType shaderType)
		: ShaderPackingFunctionCase(testCtx, (string("unpackunorm2x16") + getShaderTypePostfix(shaderType)).c_str(), "unpackUnorm2x16", shaderType)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = unpackUnorm2x16(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new UnpackUnorm2x16CaseInstance(ctx, m_shaderType, m_spec, getName());
	}

};

class PackHalf2x16CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	PackHalf2x16CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
	: ShaderPackingFunctionTestInstance (context, shaderType, spec, name)
	{
	}

	tcu::TestStatus iterate (void)
	{
		const int					maxDiff		= 0; // Values can be represented exactly in mediump.
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<tcu::Vec2>		inputs;
		std::vector<deUint32>		outputs;

		// Special values to check.
		inputs.push_back(tcu::Vec2(0.0f, 0.0f));
		inputs.push_back(tcu::Vec2(0.5f, 1.0f));
		inputs.push_back(tcu::Vec2(1.0f, 0.5f));
		inputs.push_back(tcu::Vec2(-0.5f, 1.5f));
		inputs.push_back(tcu::Vec2(0.25f, 0.75f));

		// Random values.
		{
			const int	minExp	= -14;
			const int	maxExp	= 15;

			for (int ndx = 0; ndx < 95; ndx++)
			{
				tcu::Vec2 v;
				for (int c = 0; c < 2; c++)
				{
					const int		s			= rnd.getBool() ? 1 : -1;
					const int		exp			= rnd.getInt(minExp, maxExp);
					const deUint32	mantissa	= rnd.getUint32() & ((1<<23)-1);

					v[c] = tcu::Float32::construct(s, exp ? exp : 1 /* avoid denormals */, (1u<<23) | mantissa).asFloat();
				}
				inputs.push_back(v);
			}
		}

		// Convert input values to fp16 and back to make sure they can be represented exactly in mediump.
		for (std::vector<tcu::Vec2>::iterator inVal = inputs.begin(); inVal != inputs.end(); ++inVal)
			*inVal = tcu::Vec2(tcu::Float16(inVal->x()).asFloat(), tcu::Float16(inVal->y()).asFloat());

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deUint16	ref0	= (deUint16)tcu::Float16(inputs[valNdx].x()).bits();
				const deUint16	ref1	= (deUint16)tcu::Float16(inputs[valNdx].y()).bits();
				const deUint32	ref		= (ref1 << 16) | ref0;
				const deUint32	res		= outputs[valNdx];
				const deUint16	res0	= (deUint16)(res & 0xffff);
				const deUint16	res1	= (deUint16)(res >> 16);
				const int		diff0	= de::abs((int)ref0 - (int)res0);
				const int		diff1	= de::abs((int)ref1 - (int)res1);

				if (diff0 > maxDiff || diff1 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
															   << ", expected packHalf2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
															   << ", got " << tcu::toHex(res)
															   << "\n  diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}
};

class PackHalf2x16Case : public ShaderPackingFunctionCase
{
public:
	PackHalf2x16Case (tcu::TestContext& testCtx, glu::ShaderType shaderType)
		: ShaderPackingFunctionCase	(testCtx, (string("packhalf2x16") + getShaderTypePostfix(shaderType)).c_str(), "packHalf2x16", shaderType)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = packHalf2x16(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new PackHalf2x16CaseInstance(ctx, m_shaderType, m_spec, getName());
	}

};

class UnpackHalf2x16CaseInstance : public ShaderPackingFunctionTestInstance
{
	enum Sign
	{
		POSITIVE								= 0,
		NEGATIVE
	};
	enum SubnormalizedConversionType
	{
		UNKNOWN									= 0,
		CONVERTED,
		ZERO_FLUSHED,
	};
public:
	UnpackHalf2x16CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
	: ShaderPackingFunctionTestInstance (context, shaderType, spec, name)
	{
	}

	tcu::TestStatus iterate (void)
	{
		const int					minExp		= -14;
		const int					maxExp		= 15;
		const int					mantBits	= 10;
		const deUint32				mantBitMask = (1u << mantBits) - 1u;
		tcu::TestLog&				log			= m_testCtx.getLog();

		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<deUint32>		inputs;
		std::vector<tcu::Vec2>		outputs;

		// Special values.
		inputs.push_back((tcu::Float16( 0.0f).bits() << 16) | tcu::Float16( 1.0f).bits());
		inputs.push_back((tcu::Float16( 1.0f).bits() << 16) | tcu::Float16( 0.0f).bits());
		inputs.push_back((tcu::Float16(-1.0f).bits() << 16) | tcu::Float16( 0.5f).bits());
		inputs.push_back((tcu::Float16( 0.5f).bits() << 16) | tcu::Float16(-0.5f).bits());
		// Special subnormal value: single lowest bit set
		inputs.push_back((tcu::Float16(composeHalfFloat(POSITIVE, 0u, 1u)).bits() << 16)
						| tcu::Float16(composeHalfFloat(NEGATIVE, 0u, 1u)).bits());
		// Special subnormal value: single highest fraction bit set
		inputs.push_back((tcu::Float16(composeHalfFloat(NEGATIVE, 0u, 1u << (mantBits - 1u))).bits() << 16)
						| tcu::Float16(composeHalfFloat(POSITIVE, 0u, 1u << (mantBits - 1u))).bits());
		// Special subnormal value: all fraction bits set
		inputs.push_back((tcu::Float16(composeHalfFloat(POSITIVE, 0u, mantBitMask)).bits() << 16)
						| tcu::Float16(composeHalfFloat(NEGATIVE, 0u, mantBitMask)).bits());

		// Construct random values.
		for (int ndx = 0; ndx < 90; ndx++)
		{
			deUint32 inVal = 0;
			for (int c = 0; c < 2; c++)
			{
				const int		s			= rnd.getBool() ? 1 : -1;
				const int		exp			= rnd.getInt(minExp, maxExp);
				const deUint32	mantissa	= rnd.getUint32() & mantBitMask;
				const deUint16	value		= tcu::Float16::construct(s, exp != 0 ? exp : 1 /* avoid denorm */, static_cast<deUint16>((1u<<10) | mantissa)).bits();

				inVal |= value << (16u * c);
			}
			inputs.push_back(inVal);
		}
		for (int ndx = 0; ndx < 15; ndx++)
		{
			deUint32 inVal = 0;
			for (int c = 0; c < 2; c++)
			{
				const Sign		sign		= rnd.getBool()? POSITIVE : NEGATIVE;
				const deUint32	mantissa	= rnd.getUint32() & mantBitMask;
				const deUint16	value		= tcu::Float16(composeHalfFloat(sign, 0u /* force denorm */, mantissa)).bits();

				inVal |= value << (16u * c);
			}
			inputs.push_back(inVal);
		}

		outputs.resize(inputs.size());

		log << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int					numValues	= (int)inputs.size();
			const int					maxPrints	= 10;
			int							numFailed	= 0;
			SubnormalizedConversionType conversion	= UNKNOWN;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deUint16			in0			= (deUint16)(inputs[valNdx] & 0xffff);
				const deUint16			in1			= (deUint16)(inputs[valNdx] >> 16);
				const float				res0		= outputs[valNdx].x();
				const float				res1		= outputs[valNdx].y();

				const deBool			value0		= checkValue(in0, res0, conversion);
				// note: do not avoid calling checkValue for in1 if it failed for in0 by using && laziness
				// checkValue may potentially change 'conversion' parameter if it was set to UNKNOWN so far
				const deBool			value1		= checkValue(in1, res1, conversion);
				const deBool			valuesOK	= value0 && value1;

				if (!valuesOK)
				{
					if (numFailed < maxPrints)
						printErrorMessage(log, valNdx, in0, in1, res0, res1);
					else if (numFailed == maxPrints)
						log << TestLog::Message << "..." << TestLog::EndMessage;
					++numFailed;
				}
			}

			log << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");
		}
	}
private:
	deBool checkValue (deUint16 inValue, float outValue, SubnormalizedConversionType& conversion)
	{
		const tcu::Float16		temp			= tcu::Float16(inValue);
		const float				ref				= temp.asFloat();
		const deUint32			refBits			= tcu::Float32(ref).bits();
		const deUint32			resBits			= tcu::Float32(outValue).bits();
		const deBool			bitMatch		= (refBits ^ resBits) == 0u;
		const deBool			denorm			= temp.isDenorm();

		if (conversion != CONVERTED && denorm)
		{
			if (resBits == 0 || (ref < 0 && resBits == 0x80000000UL))
			{
				conversion = ZERO_FLUSHED;
				return DE_TRUE;
			}
			if (conversion != ZERO_FLUSHED && bitMatch)
			{
				conversion = CONVERTED;
				return DE_TRUE;
			}
			return DE_FALSE;
		}
		else if (bitMatch)
			return DE_TRUE;
		return DE_FALSE;
	}
	void printErrorMessage (tcu::TestLog& log, deUint32 valNdx, deUint16 in0, deUint16 in1, float out0, float out1)
	{
		const float			ref0		= tcu::Float16(in0).asFloat();
		const deUint32		refBits0	= tcu::Float32(ref0).bits();
		const deUint32		resBits0	= tcu::Float32(out0).bits();
		const float			ref1		= tcu::Float16(in1).asFloat();
		const deUint32		refBits1	= tcu::Float32(ref1).bits();
		const deUint32		resBits1	= tcu::Float32(out1).bits();
		log << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
			<< "  expected unpackHalf2x16(" << tcu::toHex((in1 << 16u) | in0) << ") = "
			<< "vec2(" << ref0 << " / " << tcu::toHex(refBits0) << ", " << ref1 << " / " << tcu::toHex(refBits1) << ")"
			<< ", got vec2(" << out0 << " / " << tcu::toHex(resBits0) << ", " << out1 << " / " << tcu::toHex(resBits1) << ")"
			<< TestLog::EndMessage;
	}
	deUint16 composeHalfFloat (Sign sign, deUint32 exponent, deUint32 significand)
	{
		const deUint32		BitMask_05	= (1u << 5u)  - 1u;
		const deUint32		BitMask_10	= (1u << 10u) - 1u;
		const deUint32		BitMask_16	= (1u << 16u) - 1u;
		DE_UNREF(BitMask_05);
		DE_UNREF(BitMask_10);
		DE_UNREF(BitMask_16);
		DE_ASSERT((exponent & ~BitMask_05) == 0u);
		DE_ASSERT((significand & ~BitMask_10) == 0u);
		const deUint32		value		= (((sign == NEGATIVE ? 1u : 0u) << 5u | exponent) << 10u) | significand;
		DE_ASSERT((value & ~BitMask_16) == 0u);
		return static_cast<deUint16>(value);
	}
};

class UnpackHalf2x16Case : public ShaderPackingFunctionCase
{
public:
	UnpackHalf2x16Case (tcu::TestContext& testCtx, glu::ShaderType shaderType)
		: ShaderPackingFunctionCase	(testCtx, (string("unpackhalf2x16") + getShaderTypePostfix(shaderType)).c_str(), "unpackHalf2x16", shaderType)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_MEDIUMP)));

		m_spec.source = "out0 = unpackHalf2x16(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new UnpackHalf2x16CaseInstance(ctx, m_shaderType, m_spec, getName());
	}

};

class PackSnorm4x8CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	PackSnorm4x8CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, glu::Precision precision, const char* name)
		: ShaderPackingFunctionTestInstance	(context, shaderType, spec, name)
		, m_precision						(precision)
	{
	}

	tcu::TestStatus iterate (void)
	{
		de::Random					rnd			(deStringHash(m_name) ^ 0x42f2c0);
		std::vector<tcu::Vec4>		inputs;
		std::vector<deUint32>		outputs;
		const int					maxDiff		= m_precision == glu::PRECISION_HIGHP	? 1	:		// Rounding only.
												  m_precision == glu::PRECISION_MEDIUMP	? 1	:		// (2^-10) * (2^7) + 1
												  m_precision == glu::PRECISION_LOWP	? 2	: 0;	// (2^-8) * (2^7) + 1

		// Special values to check.
		inputs.push_back(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		inputs.push_back(tcu::Vec4(-1.0f, 1.0f, -1.0f, 1.0f));
		inputs.push_back(tcu::Vec4(0.5f, -0.5f, -0.5f, 0.5f));
		inputs.push_back(tcu::Vec4(-1.5f, 1.5f, -1.5f, 1.5f));
		inputs.push_back(tcu::Vec4(0.25f, -0.75f, -0.25f, 0.75f));

		// Random values, mostly in range.
		for (int ndx = 0; ndx < 15; ndx++)
		{
			const float x = rnd.getFloat()*2.5f - 1.25f;
			const float y = rnd.getFloat()*2.5f - 1.25f;
			const float z = rnd.getFloat()*2.5f - 1.25f;
			const float w = rnd.getFloat()*2.5f - 1.25f;
			inputs.push_back(tcu::Vec4(x, y, z, w));
		}

		// Large random values.
		for (int ndx = 0; ndx < 80; ndx++)
		{
			const float x = rnd.getFloat()*1e6f - 0.5e6f;
			const float y = rnd.getFloat()*1e6f - 0.5e6f;
			const float z = rnd.getFloat()*1e6f - 0.5e6f;
			const float w = rnd.getFloat()*1e6f - 0.5e6f;
			inputs.push_back(tcu::Vec4(x, y, z, w));
		}

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < numValues; valNdx++)
			{
				const deUint16	ref0	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
				const deUint16	ref1	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
				const deUint16	ref2	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].z(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
				const deUint16	ref3	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].w(), -1.0f, 1.0f) * 127.0f), -(1<<7), (1<<7)-1);
				const deUint32	ref		= (deUint32(ref3) << 24) | (deUint32(ref2) << 16) | (deUint32(ref1) << 8) | deUint32(ref0);
				const deUint32	res		= outputs[valNdx];
				const deUint16	res0	= (deUint8)(res & 0xff);
				const deUint16	res1	= (deUint8)((res >> 8) & 0xff);
				const deUint16	res2	= (deUint8)((res >> 16) & 0xff);
				const deUint16	res3	= (deUint8)((res >> 24) & 0xff);
				const int		diff0	= de::abs((int)ref0 - (int)res0);
				const int		diff1	= de::abs((int)ref1 - (int)res1);
				const int		diff2	= de::abs((int)ref2 - (int)res2);
				const int		diff3	= de::abs((int)ref3 - (int)res3);

				if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
															   << ", expected packSnorm4x8(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
															   << ", got " << tcu::toHex(res)
															   << "\n  diffs = " << tcu::IVec4(diff0, diff1, diff2, diff3) << ", max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}

private:
	const glu::Precision m_precision;
};

class PackSnorm4x8Case : public ShaderPackingFunctionCase
{
public:
	PackSnorm4x8Case (tcu::TestContext& testCtx, glu::ShaderType shaderType, glu::Precision precision)
		: ShaderPackingFunctionCase	(testCtx, (string("packsnorm4x8") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packSnorm4x8", shaderType)
		, m_precision				(precision)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC4, precision)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = packSnorm4x8(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new PackSnorm4x8CaseInstance(ctx, m_shaderType, m_spec, m_precision, getName());
	}

private:
	const glu::Precision m_precision;
};

class UnpackSnorm4x8CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	UnpackSnorm4x8CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
		: ShaderPackingFunctionTestInstance	(context, shaderType, spec, name)
	{
	}

	tcu::TestStatus iterate (void)
	{
		const deUint32				maxDiff		= 1; // Rounding error.
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<deUint32>		inputs;
		std::vector<tcu::Vec4>		outputs;

		inputs.push_back(0x00000000u);
		inputs.push_back(0x7fff8000u);
		inputs.push_back(0x80007fffu);
		inputs.push_back(0xffffffffu);
		inputs.push_back(0x0001fffeu);

		// Random values.
		for (int ndx = 0; ndx < 95; ndx++)
			inputs.push_back(rnd.getUint32());

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deInt8	in0		= (deInt8)(deUint8)(inputs[valNdx] & 0xff);
				const deInt8	in1		= (deInt8)(deUint8)((inputs[valNdx] >> 8) & 0xff);
				const deInt8	in2		= (deInt8)(deUint8)((inputs[valNdx] >> 16) & 0xff);
				const deInt8	in3		= (deInt8)(deUint8)(inputs[valNdx] >> 24);
				const float		ref0	= de::clamp(float(in0) / 127.f, -1.0f, 1.0f);
				const float		ref1	= de::clamp(float(in1) / 127.f, -1.0f, 1.0f);
				const float		ref2	= de::clamp(float(in2) / 127.f, -1.0f, 1.0f);
				const float		ref3	= de::clamp(float(in3) / 127.f, -1.0f, 1.0f);
				const float		res0	= outputs[valNdx].x();
				const float		res1	= outputs[valNdx].y();
				const float		res2	= outputs[valNdx].z();
				const float		res3	= outputs[valNdx].w();

				const deUint32	diff0	= getUlpDiff(ref0, res0);
				const deUint32	diff1	= getUlpDiff(ref1, res1);
				const deUint32	diff2	= getUlpDiff(ref2, res2);
				const deUint32	diff3	= getUlpDiff(ref3, res3);

				if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
															   << "  expected unpackSnorm4x8(" << tcu::toHex(inputs[valNdx]) << ") = "
															   << "vec4(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ", " << HexFloat(ref2) << ", " << HexFloat(ref3) << ")"
															   << ", got vec4(" << HexFloat(res0) << ", " << HexFloat(res1) << ", " << HexFloat(res2) << ", " << HexFloat(res3) << ")"
															   << "\n  ULP diffs = (" << diff0 << ", " << diff1 << ", " << diff2 << ", " << diff3 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}
};


class UnpackSnorm4x8Case : public ShaderPackingFunctionCase
{
public:
	UnpackSnorm4x8Case (tcu::TestContext& testCtx, glu::ShaderType shaderType)
		: ShaderPackingFunctionCase	(testCtx, (string("unpacksnorm4x8") + getShaderTypePostfix(shaderType)).c_str(), "unpackSnorm4x8", shaderType)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = unpackSnorm4x8(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new UnpackSnorm4x8CaseInstance(ctx, m_shaderType, m_spec, getName());
	}

};

class PackUnorm4x8CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	PackUnorm4x8CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, glu::Precision precision, const char* name)
		: ShaderPackingFunctionTestInstance	(context, shaderType, spec, name)
		, m_precision						(precision)
	{
	}

	tcu::TestStatus iterate (void)
	{
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<tcu::Vec4>		inputs;
		std::vector<deUint32>		outputs;
		const int					maxDiff		= m_precision == glu::PRECISION_HIGHP	? 1	:		// Rounding only.
												  m_precision == glu::PRECISION_MEDIUMP	? 1	:		// (2^-10) * (2^8) + 1
												  m_precision == glu::PRECISION_LOWP	? 2	: 0;	// (2^-8) * (2^8) + 1

		// Special values to check.
		inputs.push_back(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
		inputs.push_back(tcu::Vec4(-1.0f, 1.0f, -1.0f, 1.0f));
		inputs.push_back(tcu::Vec4(0.5f, -0.5f, -0.5f, 0.5f));
		inputs.push_back(tcu::Vec4(-1.5f, 1.5f, -1.5f, 1.5f));
		inputs.push_back(tcu::Vec4(0.25f, -0.75f, -0.25f, 0.75f));

		// Random values, mostly in range.
		for (int ndx = 0; ndx < 15; ndx++)
		{
			const float x = rnd.getFloat()*1.25f - 0.125f;
			const float y = rnd.getFloat()*1.25f - 0.125f;
			const float z = rnd.getFloat()*1.25f - 0.125f;
			const float w = rnd.getFloat()*1.25f - 0.125f;
			inputs.push_back(tcu::Vec4(x, y, z, w));
		}

		// Large random values.
		for (int ndx = 0; ndx < 80; ndx++)
		{
			const float x = rnd.getFloat()*1e6f - 1e5f;
			const float y = rnd.getFloat()*1e6f - 1e5f;
			const float z = rnd.getFloat()*1e6f - 1e5f;
			const float w = rnd.getFloat()*1e6f - 1e5f;
			inputs.push_back(tcu::Vec4(x, y, z, w));
		}

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deUint16	ref0	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
				const deUint16	ref1	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
				const deUint16	ref2	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].z(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
				const deUint16	ref3	= (deUint8)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].w(), 0.0f, 1.0f) * 255.0f), 0, (1<<8)-1);
				const deUint32	ref		= (deUint32(ref3) << 24) | (deUint32(ref2) << 16) | (deUint32(ref1) << 8) | deUint32(ref0);
				const deUint32	res		= outputs[valNdx];
				const deUint16	res0	= (deUint8)(res & 0xff);
				const deUint16	res1	= (deUint8)((res >> 8) & 0xff);
				const deUint16	res2	= (deUint8)((res >> 16) & 0xff);
				const deUint16	res3	= (deUint8)((res >> 24) & 0xff);
				const int		diff0	= de::abs((int)ref0 - (int)res0);
				const int		diff1	= de::abs((int)ref1 - (int)res1);
				const int		diff2	= de::abs((int)ref2 - (int)res2);
				const int		diff3	= de::abs((int)ref3 - (int)res3);

				if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
															   << ", expected packUnorm4x8(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
															   << ", got " << tcu::toHex(res)
															   << "\n  diffs = " << tcu::IVec4(diff0, diff1, diff2, diff3) << ", max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}

private:
	const glu::Precision m_precision;
};

class PackUnorm4x8Case : public ShaderPackingFunctionCase
{
public:
	PackUnorm4x8Case (tcu::TestContext& testCtx, glu::ShaderType shaderType, glu::Precision precision)
		: ShaderPackingFunctionCase	(testCtx, (string("packunorm4x8") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(), "packUnorm4x8", shaderType)
		, m_precision				(precision)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC4, precision)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = packUnorm4x8(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new PackUnorm4x8CaseInstance(ctx, m_shaderType, m_spec, m_precision, getName());
	}

private:
	const glu::Precision m_precision;
};

class UnpackUnorm4x8CaseInstance : public ShaderPackingFunctionTestInstance
{
public:
	UnpackUnorm4x8CaseInstance (Context& context, glu::ShaderType shaderType, const ShaderSpec& spec, const char* name)
		: ShaderPackingFunctionTestInstance	(context, shaderType, spec, name)
	{
	}

	tcu::TestStatus iterate (void)
	{
		const deUint32				maxDiff		= 1; // Rounding error.
		de::Random					rnd			(deStringHash(m_name) ^ 0x776002);
		std::vector<deUint32>		inputs;
		std::vector<tcu::Vec4>		outputs;

		inputs.push_back(0x00000000u);
		inputs.push_back(0x7fff8000u);
		inputs.push_back(0x80007fffu);
		inputs.push_back(0xffffffffu);
		inputs.push_back(0x0001fffeu);

		// Random values.
		for (int ndx = 0; ndx < 95; ndx++)
			inputs.push_back(rnd.getUint32());

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
			{
				const deUint8	in0		= (deUint8)(inputs[valNdx] & 0xff);
				const deUint8	in1		= (deUint8)((inputs[valNdx] >> 8) & 0xff);
				const deUint8	in2		= (deUint8)((inputs[valNdx] >> 16) & 0xff);
				const deUint8	in3		= (deUint8)(inputs[valNdx] >> 24);
				const float		ref0	= de::clamp(float(in0) / 255.f, 0.0f, 1.0f);
				const float		ref1	= de::clamp(float(in1) / 255.f, 0.0f, 1.0f);
				const float		ref2	= de::clamp(float(in2) / 255.f, 0.0f, 1.0f);
				const float		ref3	= de::clamp(float(in3) / 255.f, 0.0f, 1.0f);
				const float		res0	= outputs[valNdx].x();
				const float		res1	= outputs[valNdx].y();
				const float		res2	= outputs[valNdx].z();
				const float		res3	= outputs[valNdx].w();

				const deUint32	diff0	= getUlpDiff(ref0, res0);
				const deUint32	diff1	= getUlpDiff(ref1, res1);
				const deUint32	diff2	= getUlpDiff(ref2, res2);
				const deUint32	diff3	= getUlpDiff(ref3, res3);

				if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
															   << "  expected unpackUnorm4x8(" << tcu::toHex(inputs[valNdx]) << ") = "
															   << "vec4(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ", " << HexFloat(ref2) << ", " << HexFloat(ref3) << ")"
															   << ", got vec4(" << HexFloat(res0) << ", " << HexFloat(res1) << ", " << HexFloat(res2) << ", " << HexFloat(res3) << ")"
															   << "\n  ULP diffs = (" << diff0 << ", " << diff1 << ", " << diff2 << ", " << diff3 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			if (numFailed == 0)
				return tcu::TestStatus::pass("Pass");
			else
				return tcu::TestStatus::fail("Result comparison failed");

		}
	}
};

class UnpackUnorm4x8Case : public ShaderPackingFunctionCase
{
public:
	UnpackUnorm4x8Case (tcu::TestContext& testCtx, glu::ShaderType shaderType)
		: ShaderPackingFunctionCase	(testCtx, (string("unpackunorm4x8") + getShaderTypePostfix(shaderType)).c_str(), "unpackUnorm4x8", shaderType)
	{
		m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
		m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));

		m_spec.source = "out0 = unpackUnorm4x8(in0);";
	}

	TestInstance* createInstance (Context& ctx) const
	{
		return new UnpackUnorm4x8CaseInstance(ctx, m_shaderType, m_spec, getName());
	}

};

ShaderPackingFunctionTests::ShaderPackingFunctionTests (tcu::TestContext& testCtx)
	: tcu::TestCaseGroup	(testCtx, "pack_unpack", "Floating-point pack and unpack function tests")
{
}

ShaderPackingFunctionTests::~ShaderPackingFunctionTests (void)
{
}

void ShaderPackingFunctionTests::init (void)
{
	// New built-in functions in GLES 3.1
	{
		const glu::ShaderType allShaderTypes[] =
		{
			glu::SHADERTYPE_VERTEX,
			glu::SHADERTYPE_TESSELLATION_CONTROL,
			glu::SHADERTYPE_TESSELLATION_EVALUATION,
			glu::SHADERTYPE_GEOMETRY,
			glu::SHADERTYPE_FRAGMENT,
			glu::SHADERTYPE_COMPUTE
		};

		// packSnorm4x8
		for (int prec = glu::PRECISION_MEDIUMP; prec < glu::PRECISION_LAST; prec++)
		{
			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
				addChild(new PackSnorm4x8Case(m_testCtx, allShaderTypes[shaderTypeNdx], glu::Precision(prec)));
		}

		// unpackSnorm4x8
		for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
			addChild(new UnpackSnorm4x8Case(m_testCtx, allShaderTypes[shaderTypeNdx]));

		// packUnorm4x8
		for (int prec = glu::PRECISION_MEDIUMP; prec < glu::PRECISION_LAST; prec++)
		{
			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
				addChild(new PackUnorm4x8Case(m_testCtx, allShaderTypes[shaderTypeNdx], glu::Precision(prec)));
		}

		// unpackUnorm4x8
		for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
			addChild(new UnpackUnorm4x8Case(m_testCtx, allShaderTypes[shaderTypeNdx]));
	}

	// GLES 3 functions in new shader types.
	{
		const glu::ShaderType newShaderTypes[] =
		{
			glu::SHADERTYPE_GEOMETRY,
			glu::SHADERTYPE_COMPUTE
		};

		// packSnorm2x16
		for (int prec = glu::PRECISION_MEDIUMP; prec < glu::PRECISION_LAST; prec++)
		{
			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
				addChild(new PackSnorm2x16Case(m_testCtx, newShaderTypes[shaderTypeNdx], glu::Precision(prec)));
		}

		// unpackSnorm2x16
		for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
			addChild(new UnpackSnorm2x16Case(m_testCtx, newShaderTypes[shaderTypeNdx]));

		// packUnorm2x16
		for (int prec = glu::PRECISION_MEDIUMP; prec < glu::PRECISION_LAST; prec++)
		{
			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
				addChild(new PackUnorm2x16Case(m_testCtx, newShaderTypes[shaderTypeNdx], glu::Precision(prec)));
		}

		// unpackUnorm2x16
		for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
			addChild(new UnpackUnorm2x16Case(m_testCtx, newShaderTypes[shaderTypeNdx]));

		// packHalf2x16
		for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
			addChild(new PackHalf2x16Case(m_testCtx, newShaderTypes[shaderTypeNdx]));

		// unpackHalf2x16
		for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
			addChild(new UnpackHalf2x16Case(m_testCtx, newShaderTypes[shaderTypeNdx]));
	}
}

} // shaderexecutor
} // vkt
