es31fShaderIntegerFunctionTests.cpp revision 8852c82a1ffa4760985c17cc6875d5d521daf343
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Integer built-in function tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fShaderIntegerFunctionTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderExecUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFormatUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace gls::ShaderExecUtil;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec3;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::UVec2;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::UVec3;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::UVec4;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Utilities
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct HexFloat
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float value;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HexFloat (const float value_) : value(value_) {}
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const HexFloat& v)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << v.value << " / " << tcu::toHex(tcu::Float32(v.value).bits());
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VarValue
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::VarType&	type;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const void*			value;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue (const glu::VarType& type_, const void* value_) : type(type_), value(value_) {}
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const VarValue& varValue)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(varValue.type.isBasicType());
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		basicType		= varValue.type.getBasicType();
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		scalarType		= glu::getDataTypeScalarType(basicType);
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numComponents	= glu::getDataTypeScalarSize(basicType);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numComponents > 1)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << glu::getDataTypeName(basicType) << "(";
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int compNdx = 0; compNdx < numComponents; compNdx++)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (compNdx != 0)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << ", ";
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (scalarType)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_FLOAT:	str << HexFloat(((const float*)varValue.value)[compNdx]);						break;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT:		str << ((const deInt32*)varValue.value)[compNdx];								break;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT:	str << tcu::toHex(((const deUint32*)varValue.value)[compNdx]);					break;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_BOOL:	str << (((const deUint32*)varValue.value)[compNdx] != 0 ? "true" : "false");	break;
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numComponents > 1)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << ")";
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getShaderUintBitCount (glu::ShaderType shaderType, glu::Precision precision)
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2013-10-31 pyry] Query from GL for vertex and fragment shaders.
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(shaderType);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int bitCounts[] = { 8, 16, 32 };
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(bitCounts) == glu::PRECISION_LAST);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return bitCounts[precision];
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// IntegerFunctionCase
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IntegerFunctionCase : public TestCase
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							IntegerFunctionCase		(Context& context, const char* name, const char* description, glu::ShaderType shaderType);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~IntegerFunctionCase	(void);
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init					(void);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					deinit					(void);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate					(void);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							IntegerFunctionCase		(const IntegerFunctionCase& other);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IntegerFunctionCase&	operator=				(const IntegerFunctionCase& other);
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			getInputValues			(int numValues, void* const* values) const = 0;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool			compare					(const void* const* inputs, const void* const* outputs) = 0;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderType			m_shaderType;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderSpec				m_spec;
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_numValues;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream		m_failMsg;				//!< Comparison failure help message.
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderExecutor*			m_executor;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIntegerFunctionCase::IntegerFunctionCase (Context& context, const char* name, const char* description, glu::ShaderType shaderType)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase		(context, name, description)
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_shaderType	(shaderType)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numValues	(100)
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_executor	(DE_NULL)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_spec.version = glu::GLSL_VERSION_310_ES;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIntegerFunctionCase::~IntegerFunctionCase (void)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IntegerFunctionCase::deinit();
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IntegerFunctionCase::init (void)
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_executor);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_executor = createExecutor(m_context.getRenderContext(), m_shaderType, m_spec);
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << m_executor;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_executor->isOk())
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Compile failed");
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IntegerFunctionCase::deinit (void)
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_executor;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_executor = DE_NULL;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<int> getScalarSizes (const vector<Symbol>& symbols)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<int> sizes(symbols.size());
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < (int)symbols.size(); ++ndx)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sizes[ndx] = symbols[ndx].varType.getScalarSize();
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sizes;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int computeTotalScalarSize (const vector<Symbol>& symbols)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int totalSize = 0;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Symbol>::const_iterator sym = symbols.begin(); sym != symbols.end(); ++sym)
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		totalSize += sym->varType.getScalarSize();
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return totalSize;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<void*> getInputOutputPointers (const vector<Symbol>& symbols, vector<deUint32>& data, const int numValues)
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<void*>	pointers		(symbols.size());
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				curScalarOffset	= 0;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int varNdx = 0; varNdx < (int)symbols.size(); ++varNdx)
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Symbol&	var				= symbols[varNdx];
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		scalarSize		= var.varType.getScalarSize();
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Uses planar layout as input/output specs do not support strides.
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		pointers[varNdx] = &data[curScalarOffset];
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		curScalarOffset += scalarSize*numValues;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(curScalarOffset == (int)data.size());
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return pointers;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIntegerFunctionCase::IterateResult IntegerFunctionCase::iterate (void)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numInputScalars			= computeTotalScalarSize(m_spec.inputs);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numOutputScalars		= computeTotalScalarSize(m_spec.outputs);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>		inputData				(numInputScalars * m_numValues);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>		outputData				(numOutputScalars * m_numValues);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<void*>		inputPointers			= getInputOutputPointers(m_spec.inputs, inputData, m_numValues);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<void*>		outputPointers			= getInputOutputPointers(m_spec.outputs, outputData, m_numValues);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize input data.
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getInputValues(m_numValues, &inputPointers[0]);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Execute shader.
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_executor->useProgram();
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_executor->execute(m_numValues, &inputPointers[0], &outputPointers[0]);
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare results.
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<int>		inScalarSizes		= getScalarSizes(m_spec.inputs);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<int>		outScalarSizes		= getScalarSizes(m_spec.outputs);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<void*>			curInputPtr			(inputPointers.size());
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<void*>			curOutputPtr		(outputPointers.size());
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						numFailed			= 0;
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int valNdx = 0; valNdx < m_numValues; valNdx++)
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Set up pointers for comparison.
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int inNdx = 0; inNdx < (int)curInputPtr.size(); ++inNdx)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				curInputPtr[inNdx] = (deUint32*)inputPointers[inNdx] + inScalarSizes[inNdx]*valNdx;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); ++outNdx)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				curOutputPtr[outNdx] = (deUint32*)outputPointers[outNdx] + outScalarSizes[outNdx]*valNdx;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!compare(&curInputPtr[0], &curOutputPtr[0]))
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \todo [2013-08-08 pyry] We probably want to log reference value as well?
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "ERROR: comparison failed for value " << valNdx << ":\n  " << m_failMsg.str() << TestLog::EndMessage;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "  inputs:" << TestLog::EndMessage;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int inNdx = 0; inNdx < (int)curInputPtr.size(); inNdx++)
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.getLog() << TestLog::Message << "    " << m_spec.inputs[inNdx].name << " = "
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														   << VarValue(m_spec.inputs[inNdx].varType, curInputPtr[inNdx])
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << TestLog::EndMessage;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << TestLog::Message << "  outputs:" << TestLog::EndMessage;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int outNdx = 0; outNdx < (int)curOutputPtr.size(); outNdx++)
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_testCtx.getLog() << TestLog::Message << "    " << m_spec.outputs[outNdx].name << " = "
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														   << VarValue(m_spec.outputs[outNdx].varType, curOutputPtr[outNdx])
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									   << TestLog::EndMessage;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg.str("");
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg.clear();
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailed += 1;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << (m_numValues - numFailed) << " / " << m_numValues << " values passed" << TestLog::EndMessage;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								numFailed == 0 ? "Pass"					: "Result comparison failed");
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getPrecisionPostfix (glu::Precision precision)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_postfix[] =
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_lowp",
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_mediump",
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_highp"
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_postfix) == glu::PRECISION_LAST);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_postfix[precision];
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getShaderTypePostfix (glu::ShaderType shaderType)
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_postfix[] =
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_vertex",
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_fragment",
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_geometry",
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_tess_control",
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_tess_eval",
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"_compute"
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds<int>(shaderType, 0, DE_LENGTH_OF_ARRAY(s_postfix)));
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_postfix[shaderType];
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::string getIntegerFuncCaseName (glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return string(glu::getDataTypeName(baseType)) + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UaddCarryCase : public IntegerFunctionCase
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UaddCarryCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "uaddCarry", shaderType)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("sum", glu::VarType(baseType, precision)));
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("carry", glu::VarType(baseType, glu::PRECISION_LOWP)));
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "sum = uaddCarry(x, y, carry);";
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x235facu);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		const glu::Precision	precision	= m_spec.inputs[0].varType.getPrecision();
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in0			= (deUint32*)values[0];
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in1			= (deUint32*)values[1];
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	x;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	y;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} easyCases[] =
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000000u,	0x00000000u },
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xfffffffeu,	0x00000001u },
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000001u,	0xfffffffeu },
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0x00000001u },
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000001u,	0xffffffffu },
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xfffffffeu,	0x00000002u },
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000002u,	0xfffffffeu },
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0xffffffffu }
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = rnd.getUint32();
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = rnd.getUint32();
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMasks0[]		= { 0xffu, 0xffffu, 0xffffffffu };
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMasks1[]		= { 0xfffffff0u, 0xfffffff0u, 0xffffffffu };
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			mask0			= cmpMasks0[precision];
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			mask1			= cmpMasks1[precision];
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	in0		= ((const deUint32*)inputs[0])[compNdx];
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	in1		= ((const deUint32*)inputs[1])[compNdx];
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out0	= ((const deUint32*)outputs[0])[compNdx];
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out1	= ((const deUint32*)outputs[1])[compNdx];
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref0	= in0+in1;
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref1	= (deUint64(in0)+deUint64(in1)) > 0xffffffffu ? 1u : 0u;
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (((out0&mask0) != (ref0&mask0)) || ((out1&mask1) != (ref1&mask1)))
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UsubBorrowCase : public IntegerFunctionCase
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UsubBorrowCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "usubBorrow", shaderType)
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("diff", glu::VarType(baseType, precision)));
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("carry", glu::VarType(baseType, glu::PRECISION_LOWP)));
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "diff = usubBorrow(x, y, carry);";
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x235facu);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		const glu::Precision	precision	= m_spec.inputs[0].varType.getPrecision();
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in0			= (deUint32*)values[0];
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in1			= (deUint32*)values[1];
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	x;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	y;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} easyCases[] =
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000000u,	0x00000000u },
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000001u,	0x00000001u },
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000001u,	0x00000002u },
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000001u,	0xffffffffu },
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xfffffffeu,	0xffffffffu },
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0xffffffffu },
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = rnd.getUint32();
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = rnd.getUint32();
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMasks0[]		= { 0xffu, 0xffffu, 0xffffffffu };
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMasks1[]		= { 0xfffffff0u, 0xfffffff0u, 0xffffffffu };
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			mask0			= cmpMasks0[precision];
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			mask1			= cmpMasks1[precision];
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	in0		= ((const deUint32*)inputs[0])[compNdx];
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	in1		= ((const deUint32*)inputs[1])[compNdx];
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out0	= ((const deUint32*)outputs[0])[compNdx];
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out1	= ((const deUint32*)outputs[1])[compNdx];
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref0	= in0-in1;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref1	= in0 >= in1 ? 0u : 1u;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (((out0&mask0) != (ref0&mask0)) || ((out1&mask1) != (ref1&mask1)))
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UmulExtendedCase : public IntegerFunctionCase
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UmulExtendedCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "umulExtended", shaderType)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("msb", glu::VarType(baseType, precision)));
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("lsb", glu::VarType(baseType, precision)));
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "umulExtended(x, y, msb, lsb);";
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x235facu);
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		const glu::Precision	precision	= m_spec.inputs[0].varType.getPrecision();
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in0			= (deUint32*)values[0];
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in1			= (deUint32*)values[1];
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	x;
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	y;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} easyCases[] =
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000000u,	0x00000000u },
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0x00000001u },
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0x00000002u },
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000001u,	0xffffffffu },
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000002u,	0xffffffffu },
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0xffffffffu },
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].x;
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = easyCases[easyCaseNdx].y;
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	base0	= rnd.getUint32();
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32	base1	= rnd.getUint32();
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		adj0	= rnd.getInt(0, 20);
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		adj1	= rnd.getInt(0, 20);
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = base0 >> adj0;
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = base1 >> adj1;
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	in0		= ((const deUint32*)inputs[0])[compNdx];
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	in1		= ((const deUint32*)inputs[1])[compNdx];
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out0	= ((const deUint32*)outputs[0])[compNdx];
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out1	= ((const deUint32*)outputs[1])[compNdx];
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint64	mul64	= deUint64(in0)*deUint64(in1);
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref0	= deUint32(mul64 >> 32);
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref1	= deUint32(mul64 & 0xffffffffu);
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (out0 != ref0 || out1 != ref1)
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ImulExtendedCase : public IntegerFunctionCase
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ImulExtendedCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "imulExtended", shaderType)
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("x", glu::VarType(baseType, precision)));
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("y", glu::VarType(baseType, precision)));
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("msb", glu::VarType(baseType, precision)));
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("lsb", glu::VarType(baseType, precision)));
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "imulExtended(x, y, msb, lsb);";
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x224fa1u);
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		const glu::Precision	precision	= m_spec.inputs[0].varType.getPrecision();
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in0			= (deUint32*)values[0];
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				in1			= (deUint32*)values[1];
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	x;
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deUint32	y;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} easyCases[] =
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x00000000u,	0x00000000u },
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0x00000002u },
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x7fffffffu,	0x00000001u },
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x7fffffffu,	0x00000002u },
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x7fffffffu,	0x7fffffffu },
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0xffffffffu,	0xffffffffu },
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ 0x7fffffffu,	0xfffffffeu },
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int easyCaseNdx = 0; easyCaseNdx < DE_LENGTH_OF_ARRAY(easyCases); easyCaseNdx++)
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = (deInt32)easyCases[easyCaseNdx].x;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = (deInt32)easyCases[easyCaseNdx].y;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deInt32	base0	= (deInt32)rnd.getUint32();
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deInt32	base1	= (deInt32)rnd.getUint32();
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		adj0	= rnd.getInt(0, 20);
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		adj1	= rnd.getInt(0, 20);
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in0[valueNdx*scalarSize + compNdx] = base0 >> adj0;
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				in1[valueNdx*scalarSize + compNdx] = base1 >> adj1;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	in0		= ((const deInt32*)inputs[0])[compNdx];
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	in1		= ((const deInt32*)inputs[1])[compNdx];
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	out0	= ((const deInt32*)outputs[0])[compNdx];
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	out1	= ((const deInt32*)outputs[1])[compNdx];
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt64	mul64	= deInt64(in0)*deInt64(in1);
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	ref0	= deInt32(mul64 >> 32);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	ref1	= deInt32(mul64 & 0xffffffffu);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (out0 != ref0 || out1 != ref1)
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref0) << ", " << tcu::toHex(ref1);
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BitfieldExtractCase : public IntegerFunctionCase
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BitfieldExtractCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldExtract", shaderType)
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("offset", glu::VarType(glu::TYPE_INT, precision)));
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("bits", glu::VarType(glu::TYPE_INT, precision)));
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("extracted", glu::VarType(baseType, precision)));
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "extracted = bitfieldExtract(value, offset, bits);";
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0xa113fca2u);
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision	= m_spec.inputs[0].varType.getPrecision();
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				ignoreSign	= precision != glu::PRECISION_HIGHP && glu::isDataTypeIntOrIVec(type);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numBits		= getShaderUintBitCount(m_shaderType, precision) - (ignoreSign ? 1 : 0);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inValue		= (deUint32*)values[0];
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int*					inOffset	= (int*)values[1];
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int*					inBits		= (int*)values[2];
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		bits	= rnd.getInt(0, numBits);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		offset	= rnd.getInt(0, numBits-bits);
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inOffset[valueNdx]	= offset;
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inBits[valueNdx]	= bits;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue[valueNdx*scalarSize + compNdx] = rnd.getUint32();
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isSigned		= glu::isDataTypeIntOrIVec(type);
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				offset			= *((const int*)inputs[1]);
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bits			= *((const int*)inputs[2]);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	value	= ((const deUint32*)inputs[0])[compNdx];
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	out		= ((const deUint32*)outputs[0])[compNdx];
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	valMask	= (bits == 32 ? ~0u : ((1u<<bits)-1u));
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	baseVal	= (value >> offset) & valMask;
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref		= baseVal | ((isSigned && (baseVal & (1<<(bits-1)))) ? ~valMask : 0u);
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (out != ref)
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BitfieldInsertCase : public IntegerFunctionCase
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BitfieldInsertCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldInsert", shaderType)
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("base", glu::VarType(baseType, precision)));
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("insert", glu::VarType(baseType, precision)));
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("offset", glu::VarType(glu::TYPE_INT, precision)));
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("bits", glu::VarType(glu::TYPE_INT, precision)));
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("result", glu::VarType(baseType, precision)));
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "result = bitfieldInsert(base, insert, offset, bits);";
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x12c2acff);
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision	= m_spec.inputs[0].varType.getPrecision();
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numBits		= getShaderUintBitCount(m_shaderType, precision);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inBase		= (deUint32*)values[0];
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inInsert	= (deUint32*)values[1];
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int*					inOffset	= (int*)values[2];
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int*					inBits		= (int*)values[3];
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		bits	= rnd.getInt(0, numBits);
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		offset	= rnd.getInt(0, numBits-bits);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inOffset[valueNdx]	= offset;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inBits[valueNdx]	= bits;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inBase[valueNdx*scalarSize + compNdx]	= rnd.getUint32();
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inInsert[valueNdx*scalarSize + compNdx]	= rnd.getUint32();
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMasks[]		= { 0xffu, 0xffffu, 0xffffffffu };
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMask			= cmpMasks[precision];
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				offset			= *((const int*)inputs[2]);
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				bits			= *((const int*)inputs[3]);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	base	= ((const deUint32*)inputs[0])[compNdx];
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	insert	= ((const deUint32*)inputs[1])[compNdx];
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	out		= ((const deUint32*)outputs[0])[compNdx];
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	mask	= bits == 32 ? ~0u : (1u<<bits)-1;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref		= (base & ~(mask<<offset)) | ((insert & mask)<<offset);
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((out&cmpMask) != (ref&cmpMask))
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline deUint32 reverseBits (deUint32 v)
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	v = (((v & 0xaaaaaaaa) >> 1) | ((v & 0x55555555) << 1));
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	v = (((v & 0xcccccccc) >> 2) | ((v & 0x33333333) << 2));
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	v = (((v & 0xf0f0f0f0) >> 4) | ((v & 0x0f0f0f0f) << 4));
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	v = (((v & 0xff00ff00) >> 8) | ((v & 0x00ff00ff) << 8));
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return((v >> 16) | (v << 16));
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BitfieldReverseCase : public IntegerFunctionCase
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BitfieldReverseCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitfieldReverse", shaderType)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("result", glu::VarType(baseType, glu::PRECISION_HIGHP)));
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "result = bitfieldReverse(value);";
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0xff23a4);
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inValue		= (deUint32*)values[0];
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue[valueNdx*scalarSize + compNdx] = rnd.getUint32();
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMasks[]		= { 0xff000000u, 0xffff0000u, 0xffffffffu };
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			cmpMask			= cmpMasks[precision];
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	value	= ((const deUint32*)inputs[0])[compNdx];
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deInt32	out		= ((const deUint32*)outputs[0])[compNdx];
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	ref		= reverseBits(value);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((out&cmpMask) != (ref&cmpMask))
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] = " << tcu::toHex(ref);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BitCountCase : public IntegerFunctionCase
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BitCountCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "bitCount", shaderType)
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			vecSize		= glu::getDataTypeScalarSize(baseType);
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType	intType		= vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("count", glu::VarType(intType, glu::PRECISION_LOWP)));
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "count = bitCount(value);";
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0xab2cca4);
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inValue		= (deUint32*)values[0];
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue[valueNdx*scalarSize + compNdx] = rnd.getUint32();
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			countMasks[]	= { 0xffu, 0xffffu, 0xffffffffu };
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			countMask		= countMasks[precision];
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	value	= ((const deUint32*)inputs[0])[compNdx];
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		out		= ((const int*)outputs[0])[compNdx];
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		minRef	= dePop32(value&countMask);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		maxRef	= dePop32(value);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inRange(out, minRef, maxRef))
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int findLSB (deUint32 value)
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 32; i++)
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (value & (1u<<i))
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return i;
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return -1;
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FindLSBCase : public IntegerFunctionCase
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FindLSBCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "findLSB", shaderType)
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			vecSize		= glu::getDataTypeScalarSize(baseType);
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType	intType		= vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("lsb", glu::VarType(intType, glu::PRECISION_LOWP)));
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "lsb = findLSB(value);";
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x9923c2af);
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inValue		= (deUint32*)values[0];
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue[valueNdx*scalarSize + compNdx] = rnd.getUint32();
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			masks[]			= { 0xffu, 0xffffu, 0xffffffffu };
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32			mask			= masks[precision];
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	value	= ((const deUint32*)inputs[0])[compNdx];
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		out		= ((const int*)outputs[0])[compNdx];
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		minRef	= findLSB(value&mask);
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		maxRef	= findLSB(value);
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inRange(out, minRef, maxRef))
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int findMSB (int value)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (value > 0)
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 31 - deClz32((deUint32)value);
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (value < 0)
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 31 - deClz32(~(deUint32)value);
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int findMSB (deUint32 value)
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (value > 0)
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 31 - deClz32(value);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic int toPrecision (deUint32 value, glu::Precision precision)
10288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
10298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	switch (precision)
10308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
10318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::PRECISION_LOWP:		return value&0xffu;
10328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::PRECISION_MEDIUMP:	return value&0xffffu;
10338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::PRECISION_HIGHP:		return value;
10348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		default:
10358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			DE_ASSERT(false);
10368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			return 0;
10378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
10388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
10398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
10408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic int toPrecision (int value, glu::Precision precision)
10418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
10428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	switch (precision)
10438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
10448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::PRECISION_LOWP:		return (deInt8)value;
10458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::PRECISION_MEDIUMP:	return (deInt16)value;
10468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::PRECISION_HIGHP:		return value;
10478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		default:
10488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			DE_ASSERT(false);
10498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			return 0;
10508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
10518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
10528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FindMSBCase : public IntegerFunctionCase
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FindMSBCase (Context& context, glu::DataType baseType, glu::Precision precision, glu::ShaderType shaderType)
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IntegerFunctionCase(context, getIntegerFuncCaseName(baseType, precision, shaderType).c_str(), "findMSB", shaderType)
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			vecSize		= glu::getDataTypeScalarSize(baseType);
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType	intType		= vecSize == 1 ? glu::TYPE_INT : glu::getDataTypeIntVec(vecSize);
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.inputs.push_back(Symbol("value", glu::VarType(baseType, precision)));
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.outputs.push_back(Symbol("msb", glu::VarType(intType, glu::PRECISION_LOWP)));
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_spec.source = "msb = findMSB(value);";
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void getInputValues (int numValues, void* const* values) const
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random				rnd			(deStringHash(getName()) ^ 0x742ac4e);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= m_spec.inputs[0].varType.getBasicType();
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize	= glu::getDataTypeScalarSize(type);
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32*				inValue		= (deUint32*)values[0];
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int						valueNdx	= 0;
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		while (valueNdx < numValues)
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int compNdx = 0; compNdx < scalarSize; compNdx++)
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue[valueNdx*scalarSize + compNdx] = rnd.getUint32();
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueNdx += 1;
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool compare (const void* const* inputs, const void* const* outputs)
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type			= m_spec.inputs[0].varType.getBasicType();
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision		= m_spec.inputs[0].varType.getPrecision();
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isSigned		= glu::isDataTypeIntOrIVec(type);
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				scalarSize		= glu::getDataTypeScalarSize(type);
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compNdx = 0; compNdx < scalarSize; compNdx++)
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32	value	= ((const deUint32*)inputs[0])[compNdx];
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int		out		= ((const int*)outputs[0])[compNdx];
10958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const int		minRef	= isSigned ? findMSB(toPrecision(int(value), precision))	: findMSB(toPrecision(value, precision));
10968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const int		maxRef	= isSigned ? findMSB(int(value))							: findMSB(value);
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inRange(out, minRef, maxRef))
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_failMsg << "Expected [" << compNdx << "] in range [" << minRef << ", " << maxRef << "]";
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIntegerFunctionTests::ShaderIntegerFunctionTests (Context& context)
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "integer", "Integer function tests")
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIntegerFunctionTests::~ShaderIntegerFunctionTests (void)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<class TestClass>
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void addFunctionCases (TestCaseGroup* parent, const char* functionName, bool intTypes, bool uintTypes, bool allPrec, deUint32 shaderBits)
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* group = new tcu::TestCaseGroup(parent->getTestContext(), functionName, functionName);
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	parent->addChild(group);
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType scalarTypes[] =
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::TYPE_INT,
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::TYPE_UINT
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int scalarTypeNdx = 0; scalarTypeNdx < DE_LENGTH_OF_ARRAY(scalarTypes); scalarTypeNdx++)
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType scalarType = scalarTypes[scalarTypeNdx];
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((!intTypes && scalarType == glu::TYPE_INT) || (!uintTypes && scalarType == glu::TYPE_UINT))
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int vecSize = 1; vecSize <= 4; vecSize++)
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int prec = glu::PRECISION_LOWP; prec <= glu::PRECISION_HIGHP; prec++)
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (prec != glu::PRECISION_HIGHP && !allPrec)
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderTypeNdx = 0; shaderTypeNdx < glu::SHADERTYPE_LAST; shaderTypeNdx++)
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (shaderBits & (1<<shaderTypeNdx))
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						group->addChild(new TestClass(parent->getContext(), glu::DataType(scalarType + vecSize - 1), glu::Precision(prec), glu::ShaderType(shaderTypeNdx)));
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderIntegerFunctionTests::init (void)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VS = (1<<glu::SHADERTYPE_VERTEX),
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FS = (1<<glu::SHADERTYPE_FRAGMENT),
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CS = (1<<glu::SHADERTYPE_COMPUTE),
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GS = (1<<glu::SHADERTYPE_GEOMETRY),
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TC = (1<<glu::SHADERTYPE_TESSELLATION_CONTROL),
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TE = (1<<glu::SHADERTYPE_TESSELLATION_EVALUATION),
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ALL_SHADERS = VS|TC|TE|GS|FS|CS
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//																		Int?	Uint?	AllPrec?	Shaders
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<UaddCarryCase>				(this,	"uaddcarry",		false,	true,	true,		ALL_SHADERS);
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<UsubBorrowCase>			(this,	"usubborrow",		false,	true,	true,		ALL_SHADERS);
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<UmulExtendedCase>			(this,	"umulextended",		false,	true,	false,		ALL_SHADERS);
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<ImulExtendedCase>			(this,	"imulextended",		true,	false,	false,		ALL_SHADERS);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<BitfieldExtractCase>		(this,	"bitfieldextract",	true,	true,	true,		ALL_SHADERS);
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<BitfieldInsertCase>		(this,	"bitfieldinsert",	true,	true,	true,		ALL_SHADERS);
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<BitfieldReverseCase>		(this,	"bitfieldreverse",	true,	true,	true,		ALL_SHADERS);
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<BitCountCase>				(this,	"bitcount",			true,	true,	true,		ALL_SHADERS);
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<FindLSBCase>				(this,	"findlsb",			true,	true,	true,		ALL_SHADERS);
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addFunctionCases<FindMSBCase>				(this,	"findmsb",			true,	true,	true,		ALL_SHADERS);
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1184