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

namespace deqp
{
namespace gls
{
namespace StateQueryUtil
{

static glw::GLboolean mapBoolToGLBoolean (bool b)
{
	return (b ? GL_TRUE : GL_FALSE);
}

static bool checkError (tcu::ResultCollector& result, glu::CallLogWrapper& gl, const char* msg)
{
	const glw::GLenum errorCode = gl.glGetError();

	if (errorCode == GL_NO_ERROR)
		return true;

	result.fail(std::string(msg) + ": glGetError() returned " + glu::getErrorStr(errorCode).toString());
	return false;
}

QueriedState::QueriedState (void)
	: m_type(DATATYPE_LAST)
{
}

QueriedState::QueriedState (glw::GLint v)
	: m_type(DATATYPE_INTEGER)
{
	m_v.vInt = v;
}

QueriedState::QueriedState (glw::GLint64 v)
	: m_type(DATATYPE_INTEGER64)
{
	m_v.vInt64 = v;
}

QueriedState::QueriedState (bool v)
	: m_type(DATATYPE_BOOLEAN)
{
	m_v.vBool = v;
}

QueriedState::QueriedState (glw::GLfloat v)
	: m_type(DATATYPE_FLOAT)
{
	m_v.vFloat = v;
}

QueriedState::QueriedState (glw::GLuint v)
	: m_type(DATATYPE_UNSIGNED_INTEGER)
{
	m_v.vUint = v;
}

QueriedState::QueriedState (const GLIntVec3& v)
	: m_type(DATATYPE_INTEGER_VEC3)
{
	m_v.vIntVec3[0] = v[0];
	m_v.vIntVec3[1] = v[1];
	m_v.vIntVec3[2] = v[2];
}

QueriedState::QueriedState (void* v)
	: m_type(DATATYPE_POINTER)
{
	m_v.vPtr = v;
}

QueriedState::QueriedState (const GLIntVec4& v)
	: m_type(DATATYPE_INTEGER_VEC4)
{
	m_v.vIntVec4[0] = v[0];
	m_v.vIntVec4[1] = v[1];
	m_v.vIntVec4[2] = v[2];
	m_v.vIntVec4[3] = v[3];
}

QueriedState::QueriedState (const GLUintVec4& v)
	: m_type(DATATYPE_UNSIGNED_INTEGER_VEC4)
{
	m_v.vUintVec4[0] = v[0];
	m_v.vUintVec4[1] = v[1];
	m_v.vUintVec4[2] = v[2];
	m_v.vUintVec4[3] = v[3];
}

QueriedState::QueriedState (const GLFloatVec4& v)
	: m_type(DATATYPE_FLOAT_VEC4)
{
	m_v.vFloatVec4[0] = v[0];
	m_v.vFloatVec4[1] = v[1];
	m_v.vFloatVec4[2] = v[2];
	m_v.vFloatVec4[3] = v[3];
}

QueriedState::QueriedState (const BooleanVec4& v)
	: m_type(DATATYPE_BOOLEAN_VEC4)
{
	m_v.vBooleanVec4[0] = v[0];
	m_v.vBooleanVec4[1] = v[1];
	m_v.vBooleanVec4[2] = v[2];
	m_v.vBooleanVec4[3] = v[3];
}

QueriedState::QueriedState (const GLInt64Vec4& v)
	: m_type(DATATYPE_INTEGER64_VEC4)
{
	m_v.vInt64Vec4[0] = v[0];
	m_v.vInt64Vec4[1] = v[1];
	m_v.vInt64Vec4[2] = v[2];
	m_v.vInt64Vec4[3] = v[3];
}

bool QueriedState::isUndefined (void) const
{
	return m_type == DATATYPE_LAST;
}

DataType QueriedState::getType (void) const
{
	return m_type;
}

glw::GLint& QueriedState::getIntAccess (void)
{
	DE_ASSERT(m_type == DATATYPE_INTEGER);
	return m_v.vInt;
}

glw::GLint64& QueriedState::getInt64Access (void)
{
	DE_ASSERT(m_type == DATATYPE_INTEGER64);
	return m_v.vInt64;
}

bool& QueriedState::getBoolAccess (void)
{
	DE_ASSERT(m_type == DATATYPE_BOOLEAN);
	return m_v.vBool;
}

glw::GLfloat& QueriedState::getFloatAccess (void)
{
	DE_ASSERT(m_type == DATATYPE_FLOAT);
	return m_v.vFloat;
}

glw::GLuint& QueriedState::getUintAccess (void)
{
	DE_ASSERT(m_type == DATATYPE_UNSIGNED_INTEGER);
	return m_v.vUint;
}

QueriedState::GLIntVec3& QueriedState::getIntVec3Access (void)
{
	DE_ASSERT(m_type == DATATYPE_INTEGER_VEC3);
	return m_v.vIntVec3;
}

void*& QueriedState::getPtrAccess (void)
{
	DE_ASSERT(m_type == DATATYPE_POINTER);
	return m_v.vPtr;
}

QueriedState::GLIntVec4& QueriedState::getIntVec4Access (void)
{
	DE_ASSERT(m_type == DATATYPE_INTEGER_VEC4);
	return m_v.vIntVec4;
}

QueriedState::GLUintVec4& QueriedState::getUintVec4Access (void)
{
	DE_ASSERT(m_type == DATATYPE_UNSIGNED_INTEGER_VEC4);
	return m_v.vUintVec4;
}

QueriedState::GLFloatVec4& QueriedState::getFloatVec4Access (void)
{
	DE_ASSERT(m_type == DATATYPE_FLOAT_VEC4);
	return m_v.vFloatVec4;
}

QueriedState::BooleanVec4& QueriedState::getBooleanVec4Access (void)
{
	DE_ASSERT(m_type == DATATYPE_BOOLEAN_VEC4);
	return m_v.vBooleanVec4;
}

QueriedState::GLInt64Vec4& QueriedState::getInt64Vec4Access (void)
{
	DE_ASSERT(m_type == DATATYPE_INTEGER64_VEC4);
	return m_v.vInt64Vec4;
}

// query

static bool verifyBooleanValidity (tcu::ResultCollector& result, glw::GLboolean v)
{
	if (v == GL_TRUE || v == GL_FALSE)
		return true;
	else
	{
		std::ostringstream buf;
		buf << "Boolean value was not neither GL_TRUE nor GL_FALSE, got " << de::toString(tcu::Format::Hex<2>(v));
		result.fail(buf.str());
		return false;
	}
}

static bool verifyBooleanVec4Validity (tcu::ResultCollector& result, const glw::GLboolean v[4])
{
	bool valid = true;

	for (int i = 0; i < 4; i++)
	{
		if (v[i] != GL_TRUE && v[i] != GL_FALSE)
			valid = false;
	}

	if (!valid)
	{
		std::ostringstream buf;
		buf << "Boolean vec4 value was not neither GL_TRUE nor GL_FALSE, got (";

		for (int i = 0; i < 4; i++)
			buf << (i > 0 ? ", " : "") << de::toString(tcu::Format::Hex<2>(v[i]));

		buf << ")";

		result.fail(buf.str());
	}

	return valid;
}

void queryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, QueriedState& state)
{
	switch (type)
	{
		case QUERY_ISENABLED:
		{
			const glw::GLboolean value = gl.glIsEnabled(target);

			if (!checkError(result, gl, "glIsEnabled"))
				return;

			if (!verifyBooleanValidity(result, value))
				return;

			state = QueriedState(value == GL_TRUE);
			break;
		}

		case QUERY_BOOLEAN:
		{
			StateQueryMemoryWriteGuard<glw::GLboolean> value;
			gl.glGetBooleanv(target, &value);

			if (!checkError(result, gl, "glGetBooleanv"))
				return;

			if (!value.verifyValidity(result))
				return;
			if (!verifyBooleanValidity(result, value))
				return;

			state = QueriedState(value == GL_TRUE);
			break;
		}

		case QUERY_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetIntegerv(target, &value);

			if (!checkError(result, gl, "glGetIntegerv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		case QUERY_INTEGER64:
		{
			StateQueryMemoryWriteGuard<glw::GLint64> value;
			gl.glGetInteger64v(target, &value);

			if (!checkError(result, gl, "glGetInteger64v"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		case QUERY_FLOAT:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat> value;
			gl.glGetFloatv(target, &value);

			if (!checkError(result, gl, "glGetFloatv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void queryIndexedState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state)
{
	switch (type)
	{
		case QUERY_INDEXED_BOOLEAN_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLboolean[4]> value;
			gl.glGetBooleani_v(target, index, value);

			if (!checkError(result, gl, "glGetBooleani_v"))
				return;

			if (!value.verifyValidity(result))
				return;

			if (!verifyBooleanVec4Validity(result, value))
				return;

			{
				bool res[4];

				for (int i = 0; i < 4; i++)
					res[i] = value[i] == GL_TRUE;

				state = QueriedState(res);
			}

			break;
		}

		case QUERY_INDEXED_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
			gl.glGetIntegeri_v(target, index, value);

			if (!checkError(result, gl, "glGetIntegeri_v"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		case QUERY_INDEXED_INTEGER64_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLint64[4]> value;
			gl.glGetInteger64i_v(target, index, value);

			if (!checkError(result, gl, "glGetInteger64i_v"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		case QUERY_INDEXED_ISENABLED:
		{
			const glw::GLboolean value = gl.glIsEnabledi(target, index);

			if (!checkError(result, gl, "glIsEnabledi"))
				return;

			if (!verifyBooleanValidity(result, value))
				return;

			state = QueriedState(value == GL_TRUE);
			break;
		}

		case QUERY_INDEXED_BOOLEAN:
		{
			StateQueryMemoryWriteGuard<glw::GLboolean> value;
			gl.glGetBooleani_v(target, index, &value);

			if (!checkError(result, gl, "glGetBooleani_v"))
				return;

			if (!value.verifyValidity(result))
				return;
			if (!verifyBooleanValidity(result, value))
				return;

			state = QueriedState(value == GL_TRUE);
			break;
		}

		case QUERY_INDEXED_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetIntegeri_v(target, index, &value);

			if (!checkError(result, gl, "glGetIntegeri_v"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		case QUERY_INDEXED_INTEGER64:
		{
			StateQueryMemoryWriteGuard<glw::GLint64> value;
			gl.glGetInteger64i_v(target, index, &value);

			if (!checkError(result, gl, "glGetInteger64i_v"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void queryAttributeState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state)
{
	switch (type)
	{
		case QUERY_ATTRIBUTE_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetVertexAttribiv(index, target, &value);

			if (!checkError(result, gl, "glGetVertexAttribiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_ATTRIBUTE_FLOAT:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat> value;
			gl.glGetVertexAttribfv(index, target, &value);

			if (!checkError(result, gl, "glGetVertexAttribfv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_ATTRIBUTE_PURE_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetVertexAttribIiv(index, target, &value);

			if (!checkError(result, gl, "glGetVertexAttribIiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLuint> value;
			gl.glGetVertexAttribIuiv(index, target, &value);

			if (!checkError(result, gl, "glGetVertexAttribIuiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryFramebufferState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_FRAMEBUFFER_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetFramebufferParameteriv(target, pname, &value);

			if (!checkError(result, gl, "glGetVertexAttribiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryProgramState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_PROGRAM_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetProgramiv(program, pname, &value);

			if (!checkError(result, gl, "glGetProgramiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_PROGRAM_INTEGER_VEC3:
		{
			StateQueryMemoryWriteGuard<glw::GLint[3]> value;
			gl.glGetProgramiv(program, pname, value);

			if (!checkError(result, gl, "glGetProgramiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryPipelineState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_PIPELINE_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetProgramPipelineiv(pipeline, pname, &value);

			if (!checkError(result, gl, "glGetProgramiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryTextureParamState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_TEXTURE_PARAM_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetTexParameteriv(target, pname, &value);

			if (!checkError(result, gl, "glGetTexParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_FLOAT:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat> value;
			gl.glGetTexParameterfv(target, pname, &value);

			if (!checkError(result, gl, "glGetTexParameterfv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_PURE_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetTexParameterIiv(target, pname, &value);

			if (!checkError(result, gl, "GetTexParameterIiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLuint> value;
			gl.glGetTexParameterIuiv(target, pname, &value);

			if (!checkError(result, gl, "GetTexParameterIuiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
			gl.glGetTexParameteriv(target, pname, value);

			if (!checkError(result, gl, "glGetTexParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_FLOAT_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat[4]> value;
			gl.glGetTexParameterfv(target, pname, value);

			if (!checkError(result, gl, "glGetTexParameterfv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_PURE_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
			gl.glGetTexParameterIiv(target, pname, value);

			if (!checkError(result, gl, "GetTexParameterIiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLuint[4]> value;
			gl.glGetTexParameterIuiv(target, pname, value);

			if (!checkError(result, gl, "GetTexParameterIuiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryTextureLevelState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_TEXTURE_LEVEL_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetTexLevelParameteriv(target, level, pname, &value);

			if (!checkError(result, gl, "glGetTexLevelParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_TEXTURE_LEVEL_FLOAT:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat> value;
			gl.glGetTexLevelParameterfv(target, level, pname, &value);

			if (!checkError(result, gl, "glGetTexLevelParameterfv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryPointerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_POINTER:
		{
			StateQueryMemoryWriteGuard<void*> value;
			gl.glGetPointerv(pname, &value);

			if (!checkError(result, gl, "glGetPointerv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryObjectState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint handle, QueriedState& state)
{
	switch (type)
	{
		case QUERY_ISTEXTURE:
		{
			const glw::GLboolean value = gl.glIsTexture(handle);

			if (!checkError(result, gl, "glIsTexture"))
				return;

			if (!verifyBooleanValidity(result, value))
				return;

			state = QueriedState(value == GL_TRUE);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void queryQueryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_QUERY:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetQueryiv(target, pname, &value);

			if (!checkError(result, gl, "glGetQueryiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

void querySamplerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint sampler, glw::GLenum pname, QueriedState& state)
{
	switch (type)
	{
		case QUERY_SAMPLER_PARAM_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetSamplerParameteriv(sampler, pname, &value);

			if (!checkError(result, gl, "glGetSamplerParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_FLOAT:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat> value;
			gl.glGetSamplerParameterfv(sampler, pname, &value);

			if (!checkError(result, gl, "glGetSamplerParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_PURE_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLint> value;
			gl.glGetSamplerParameterIiv(sampler, pname, &value);

			if (!checkError(result, gl, "glGetSamplerParameterIiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER:
		{
			StateQueryMemoryWriteGuard<glw::GLuint> value;
			gl.glGetSamplerParameterIuiv(sampler, pname, &value);

			if (!checkError(result, gl, "glGetSamplerParameterIuiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
			gl.glGetSamplerParameteriv(sampler, pname, value);

			if (!checkError(result, gl, "glGetSamplerParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_FLOAT_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLfloat[4]> value;
			gl.glGetSamplerParameterfv(sampler, pname, value);

			if (!checkError(result, gl, "glGetSamplerParameteriv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_PURE_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
			gl.glGetSamplerParameterIiv(sampler, pname, value);

			if (!checkError(result, gl, "glGetSamplerParameterIiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		case QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER_VEC4:
		{
			StateQueryMemoryWriteGuard<glw::GLuint[4]> value;
			gl.glGetSamplerParameterIuiv(sampler, pname, value);

			if (!checkError(result, gl, "glGetSamplerParameterIuiv"))
				return;

			if (!value.verifyValidity(result))
				return;

			state = QueriedState(value);
			break;
		}
		default:
			DE_ASSERT(false);
	}
}

// verify

void verifyBoolean (tcu::ResultCollector& result, QueriedState& state, bool expected)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			if (state.getBoolAccess() != expected)
			{
				std::ostringstream buf;
				buf << "Expected " << glu::getBooleanStr(mapBoolToGLBoolean(expected)) << ", got " << glu::getBooleanStr(mapBoolToGLBoolean(state.getBoolAccess()));
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER:
		{
			const glw::GLint reference = expected ? 1 : 0;
			if (state.getIntAccess() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << state.getIntAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			const glw::GLint64 reference = expected ? 1 : 0;
			if (state.getInt64Access() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << state.getInt64Access();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			const glw::GLfloat reference = expected ? 1.0f : 0.0f;
			if (state.getFloatAccess() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << state.getFloatAccess();
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyInteger (tcu::ResultCollector& result, QueriedState& state, int expected)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			const bool reference = (expected != 0);
			if (state.getBoolAccess() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << glu::getBooleanStr(mapBoolToGLBoolean(reference)) << ", got " << glu::getBooleanStr(mapBoolToGLBoolean(state.getBoolAccess()));
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER:
		{
			const glw::GLint reference = expected;
			if (state.getIntAccess() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << reference << "(" << de::toString(tcu::Format::Hex<8>(reference))
					<< ") , got " << state.getIntAccess() << "(" << de::toString(tcu::Format::Hex<8>(state.getIntAccess())) << ")";
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			const glw::GLint64 reference = (glw::GLint64)expected;
			if (state.getInt64Access() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << reference << "(" << de::toString(tcu::Format::Hex<8>(reference)) << "), got "
					<< state.getInt64Access() << "(" << de::toString(tcu::Format::Hex<8>(state.getInt64Access())) << ")";
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			const glw::GLfloat refValueMin = deInt32ToFloatRoundToNegInf(expected);
			const glw::GLfloat refValueMax = deInt32ToFloatRoundToPosInf(expected);

			if (state.getFloatAccess() < refValueMin ||
				state.getFloatAccess() > refValueMax ||
				deIsNaN(state.getFloatAccess()))
			{
				std::ostringstream buf;

				if (refValueMin == refValueMax)
					buf << "Expected " << refValueMin << ", got " << state.getFloatAccess();
				else
					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getFloatAccess();

				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_UNSIGNED_INTEGER:
		{
			const glw::GLuint reference = (glw::GLuint)expected;
			if (state.getUintAccess() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << reference << "(" << de::toString(tcu::Format::Hex<8>(reference)) << "), got "
					<< state.getInt64Access() << "(" << de::toString(tcu::Format::Hex<8>(state.getInt64Access())) << ")";
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyIntegerMin (tcu::ResultCollector& result, QueriedState& state, int minValue)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			if (minValue > 0 && state.getBoolAccess() != true)
			{
				std::ostringstream buf;
				buf << "Expected GL_TRUE, got GL_FALSE";
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER:
		{
			if (state.getIntAccess() < minValue)
			{
				std::ostringstream buf;
				buf << "Expected greater or equal to " << minValue << ", got " << state.getIntAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			if (state.getInt64Access() < minValue)
			{
				std::ostringstream buf;
				buf << "Expected greater or equal to " << minValue << ", got " << state.getInt64Access();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			if (state.getFloatAccess() < deInt32ToFloatRoundToNegInf(minValue) || deIsNaN(state.getFloatAccess()))
			{
				std::ostringstream buf;
				buf << "Expected greater or equal to " << minValue << ", got " << state.getFloatAccess();
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyIntegerMax (tcu::ResultCollector& result, QueriedState& state, int maxValue)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			if (maxValue < 0 && state.getBoolAccess() != true)
			{
				std::ostringstream buf;
				buf << "Expected GL_TRUE, got GL_FALSE";
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER:
		{
			if (state.getIntAccess() > maxValue)
			{
				std::ostringstream buf;
				buf << "Expected less or equal to " << maxValue << ", got " << state.getIntAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			if (state.getInt64Access() > maxValue)
			{
				std::ostringstream buf;
				buf << "Expected less or equal to " << maxValue << ", got " << state.getInt64Access();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			if (state.getFloatAccess() > deInt32ToFloatRoundToPosInf(maxValue) || deIsNaN(state.getFloatAccess()))
			{
				std::ostringstream buf;
				buf << "Expected less or equal to " << maxValue << ", got " << state.getFloatAccess();
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyFloat (tcu::ResultCollector& result, QueriedState& state, float expected)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			const bool reference = (expected != 0.0f);

			if (state.getBoolAccess() != reference)
			{
				std::ostringstream buf;
				buf << "Expected " << glu::getBooleanStr(mapBoolToGLBoolean(reference)) << ", got " << glu::getBooleanStr(mapBoolToGLBoolean(state.getBoolAccess()));
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER:
		{
			const glw::GLint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(expected);
			const glw::GLint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(expected);

			if (state.getIntAccess() < refValueMin ||
				state.getIntAccess() > refValueMax)
			{
				std::ostringstream buf;

				if (refValueMin == refValueMax)
					buf << "Expected " << refValueMin << ", got " << state.getIntAccess();
				else
					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getIntAccess();

				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			if (state.getFloatAccess() != expected)
			{
				std::ostringstream buf;
				buf << "Expected " << expected << ", got " << state.getFloatAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			const glw::GLint64 refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(expected);
			const glw::GLint64 refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(expected);

			if (state.getInt64Access() < refValueMin ||
				state.getInt64Access() > refValueMax)
			{
				std::ostringstream buf;

				if (refValueMin == refValueMax)
					buf << "Expected " << refValueMin << ", got " << state.getInt64Access();
				else
					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getInt64Access();

				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_UNSIGNED_INTEGER:
		{
			const glw::GLuint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLuint>(expected);
			const glw::GLuint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLuint>(expected);

			if (state.getUintAccess() < refValueMin ||
				state.getUintAccess() > refValueMax)
			{
				std::ostringstream buf;

				if (refValueMin == refValueMax)
					buf << "Expected " << refValueMin << ", got " << state.getUintAccess();
				else
					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getUintAccess();

				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyFloatMin (tcu::ResultCollector& result, QueriedState& state, float minValue)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			if (minValue > 0.0f && state.getBoolAccess() != true)
				result.fail("expected GL_TRUE, got GL_FALSE");
			break;
		}

		case DATATYPE_INTEGER:
		{
			const glw::GLint refValue = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(minValue);

			if (state.getIntAccess() < refValue)
			{
				std::ostringstream buf;
				buf << "Expected greater or equal to " << refValue << ", got " << state.getIntAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			if (state.getFloatAccess() < minValue || deIsNaN(state.getFloatAccess()))
			{
				std::ostringstream buf;
				buf << "Expected greater or equal to " << minValue << ", got " << state.getFloatAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			const glw::GLint64 refValue = roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(minValue);

			if (state.getInt64Access() < refValue)
			{
				std::ostringstream buf;
				buf << "Expected greater or equal to " << refValue << ", got " << state.getInt64Access();
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyFloatMax (tcu::ResultCollector& result, QueriedState& state, float maxValue)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN:
		{
			if (maxValue < 0.0f && state.getBoolAccess() != true)
				result.fail("expected GL_TRUE, got GL_FALSE");
			break;
		}

		case DATATYPE_INTEGER:
		{
			const glw::GLint refValue = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(maxValue);

			if (state.getIntAccess() > refValue)
			{
				std::ostringstream buf;
				buf << "Expected less or equal to " << refValue << ", got " << state.getIntAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_FLOAT:
		{
			if (state.getFloatAccess() > maxValue || deIsNaN(state.getFloatAccess()))
			{
				std::ostringstream buf;
				buf << "Expected less or equal to " << maxValue << ", got " << state.getFloatAccess();
				result.fail(buf.str());
			}
			break;
		}

		case DATATYPE_INTEGER64:
		{
			const glw::GLint64 refValue = roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(maxValue);

			if (state.getInt64Access() > refValue)
			{
				std::ostringstream buf;
				buf << "Expected less or equal to " << refValue << ", got " << state.getInt64Access();
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyIntegerVec3 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected)
{
	switch (state.getType())
	{
		case DATATYPE_INTEGER_VEC3:
		{
			if (state.getIntVec3Access()[0] != expected[0] ||
				state.getIntVec3Access()[1] != expected[1] ||
				state.getIntVec3Access()[2] != expected[2])
			{
				std::ostringstream buf;
				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getIntVec3Access());
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected)
{
	switch (state.getType())
	{
		case DATATYPE_INTEGER_VEC4:
		{
			if (state.getIntVec4Access()[0] != expected[0] ||
				state.getIntVec4Access()[1] != expected[1] ||
				state.getIntVec4Access()[2] != expected[2] ||
				state.getIntVec4Access()[3] != expected[3])
			{
				std::ostringstream buf;
				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getIntVec4Access());
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyUnsignedIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::UVec4& expected)
{
	switch (state.getType())
	{
		case DATATYPE_UNSIGNED_INTEGER_VEC4:
		{
			if (state.getUintVec4Access()[0] != expected[0] ||
				state.getUintVec4Access()[1] != expected[1] ||
				state.getUintVec4Access()[2] != expected[2] ||
				state.getUintVec4Access()[3] != expected[3])
			{
				std::ostringstream buf;
				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getUintVec4Access());
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyBooleanVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::BVec4& expected)
{
	switch (state.getType())
	{
		case DATATYPE_BOOLEAN_VEC4:
		{
			const glw::GLboolean referenceVec4[4] =
			{
				mapBoolToGLBoolean(expected[0]),
				mapBoolToGLBoolean(expected[1]),
				mapBoolToGLBoolean(expected[2]),
				mapBoolToGLBoolean(expected[3])
			};

			const glw::GLboolean resultVec4[4] =
			{
				mapBoolToGLBoolean(state.getBooleanVec4Access()[0]),
				mapBoolToGLBoolean(state.getBooleanVec4Access()[1]),
				mapBoolToGLBoolean(state.getBooleanVec4Access()[2]),
				mapBoolToGLBoolean(state.getBooleanVec4Access()[3])
			};

			if (resultVec4[0] != referenceVec4[0] ||
				resultVec4[1] != referenceVec4[1] ||
				resultVec4[2] != referenceVec4[2] ||
				resultVec4[3] != referenceVec4[3])
			{
				std::ostringstream buf;
				buf << "Expected " << glu::getBooleanPointerStr(referenceVec4, 4) << ", got " << glu::getBooleanPointerStr(resultVec4, 4);
				result.fail(buf.str());
			}

			break;
		}
		case DATATYPE_FLOAT_VEC4:
		{
			const glw::GLfloat reference[4] =
			{
				(expected[0] ? 1.0f : 0.0f),
				(expected[1] ? 1.0f : 0.0f),
				(expected[2] ? 1.0f : 0.0f),
				(expected[3] ? 1.0f : 0.0f)
			};

			if (state.getFloatVec4Access()[0] != reference[0] ||
				state.getFloatVec4Access()[1] != reference[1] ||
				state.getFloatVec4Access()[2] != reference[2] ||
				state.getFloatVec4Access()[3] != reference[3])
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getFloatVec4Access());
				result.fail(buf.str());
			}
			break;
		}
		case DATATYPE_INTEGER_VEC4:
		{
			const glw::GLint reference[4] =
			{
				(expected[0] ? 1 : 0),
				(expected[1] ? 1 : 0),
				(expected[2] ? 1 : 0),
				(expected[3] ? 1 : 0)
			};

			if (state.getIntVec4Access()[0] != reference[0] ||
				state.getIntVec4Access()[1] != reference[1] ||
				state.getIntVec4Access()[2] != reference[2] ||
				state.getIntVec4Access()[3] != reference[3])
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getIntVec4Access());
				result.fail(buf.str());
			}
			break;
		}
		case DATATYPE_INTEGER64_VEC4:
		{
			const glw::GLint64 reference[4] =
			{
				(expected[0] ? 1 : 0),
				(expected[1] ? 1 : 0),
				(expected[2] ? 1 : 0),
				(expected[3] ? 1 : 0)
			};

			if (state.getInt64Vec4Access()[0] != reference[0] ||
				state.getInt64Vec4Access()[1] != reference[1] ||
				state.getInt64Vec4Access()[2] != reference[2] ||
				state.getInt64Vec4Access()[3] != reference[3])
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getInt64Vec4Access());
				result.fail(buf.str());
			}
			break;
		}
		case DATATYPE_UNSIGNED_INTEGER_VEC4:
		{
			const glw::GLuint reference[4] =
			{
				(expected[0] ? 1u : 0u),
				(expected[1] ? 1u : 0u),
				(expected[2] ? 1u : 0u),
				(expected[3] ? 1u : 0u)
			};

			if (state.getUintVec4Access()[0] != reference[0] ||
				state.getUintVec4Access()[1] != reference[1] ||
				state.getUintVec4Access()[2] != reference[2] ||
				state.getUintVec4Access()[3] != reference[3])
			{
				std::ostringstream buf;
				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getUintVec4Access());
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyFloatVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::Vec4& expected)
{
	switch (state.getType())
	{
		case DATATYPE_FLOAT_VEC4:
		{
			if (state.getFloatVec4Access()[0] != expected[0] ||
				state.getFloatVec4Access()[1] != expected[1] ||
				state.getFloatVec4Access()[2] != expected[2] ||
				state.getFloatVec4Access()[3] != expected[3])
			{
				std::ostringstream buf;
				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getFloatVec4Access());
				result.fail(buf.str());
			}
			break;
		}
		case DATATYPE_INTEGER_VEC4:
		{
			bool				anyError = false;
			std::ostringstream	expectation;

			for (int ndx = 0; ndx < 4; ++ndx)
			{
				const glw::GLint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(expected[ndx]);
				const glw::GLint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(expected[ndx]);

				if (state.getIntVec4Access()[ndx] < refValueMin ||
					state.getIntVec4Access()[ndx] > refValueMax)
				{
					std::ostringstream buf;

					if (ndx > 0)
						expectation << " ,";

					if (refValueMin == refValueMax)
						buf << refValueMin;
					else
						buf << "[" << refValueMin << ", " << refValueMax << "]";
				}
			}

			if (anyError)
			{
				std::ostringstream buf;
				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getIntVec4Access());
				result.fail(buf.str());
			}
			break;
		}
		case DATATYPE_UNSIGNED_INTEGER_VEC4:
		{
			bool				anyError = false;
			std::ostringstream	expectation;

			for (int ndx = 0; ndx < 4; ++ndx)
			{
				const glw::GLuint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLuint>(expected[ndx]);
				const glw::GLuint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLuint>(expected[ndx]);

				if (state.getUintVec4Access()[ndx] < refValueMin ||
					state.getUintVec4Access()[ndx] > refValueMax)
				{
					std::ostringstream buf;

					if (ndx > 0)
						expectation << " ,";

					if (refValueMin == refValueMax)
						buf << refValueMin;
					else
						buf << "[" << refValueMin << ", " << refValueMax << "]";
				}
			}

			if (anyError)
			{
				std::ostringstream buf;
				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getUintVec4Access());
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyPointer (tcu::ResultCollector& result, QueriedState& state, const void* expected)
{
	switch (state.getType())
	{
		case DATATYPE_POINTER:
		{
			if (state.getPtrAccess() != expected)
			{
				std::ostringstream buf;
				buf << "Expected " << expected << ", got " << state.getPtrAccess();
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

static float normalizeI32Float (deInt32 c)
{
	return de::max((float)c / float((1ul << 31) - 1u), -1.0f);
}

void verifyNormalizedI32Vec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected)
{
	// \note: normalization precision is irrelevant for these tests, we can use very large thresholds
	const float			normalizationError	= 0.1f;
	const tcu::Vec4		reference			(normalizeI32Float(expected[0]),
											 normalizeI32Float(expected[1]),
											 normalizeI32Float(expected[2]),
											 normalizeI32Float(expected[3]));
	const tcu::Vec4		validHigh			(de::min( 1.0f, reference[0] + normalizationError),
											 de::min( 1.0f, reference[1] + normalizationError),
											 de::min( 1.0f, reference[2] + normalizationError),
											 de::min( 1.0f, reference[3] + normalizationError));
	const tcu::Vec4		validLow			(de::max(-1.0f, reference[0] - normalizationError),
											 de::max(-1.0f, reference[1] - normalizationError),
											 de::max(-1.0f, reference[2] - normalizationError),
											 de::max(-1.0f, reference[3] - normalizationError));

	switch (state.getType())
	{
		case DATATYPE_FLOAT_VEC4:
		{
			bool				anyError = false;
			std::ostringstream	expectation;

			for (int ndx = 0; ndx < 4; ++ndx)
			{
				if (state.getFloatVec4Access()[ndx] < validLow[ndx] ||
					state.getFloatVec4Access()[ndx] > validHigh[ndx])
				{
					std::ostringstream buf;

					if (ndx > 0)
						expectation << " ,";
					buf << "[" << validLow[ndx] << ", " << validHigh[ndx] << "]";
				}
			}

			if (anyError)
			{
				std::ostringstream buf;
				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getFloatVec4Access());
				result.fail(buf.str());
			}
			break;
		}
		case DATATYPE_INTEGER_VEC4:
		{
			bool				anyError = false;
			std::ostringstream	expectation;

			for (int ndx = 0; ndx < 4; ++ndx)
			{
				const glw::GLint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(validHigh[ndx]);
				const glw::GLint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(validLow[ndx]);

				if (state.getIntVec4Access()[ndx] < refValueMin ||
					state.getIntVec4Access()[ndx] > refValueMax)
				{
					std::ostringstream buf;

					if (ndx > 0)
						expectation << " ,";

					if (refValueMin == refValueMax)
						buf << refValueMin;
					else
						buf << "[" << refValueMin << ", " << refValueMax << "]";
				}
			}

			if (anyError)
			{
				std::ostringstream buf;
				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getIntVec4Access());
				result.fail(buf.str());
			}
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

// helpers

void verifyStateBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, bool refValue, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyBoolean(result, state, refValue);
}

void verifyStateInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int refValue, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyInteger(result, state, refValue);
}

void verifyStateIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int minValue, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyIntegerMin(result, state, minValue);
}

void verifyStateIntegerMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int maxValue, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyIntegerMax(result, state, maxValue);
}

void verifyStateIntegerEqualToOther (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum other, QueryType type)
{
	QueriedState stateA;
	QueriedState stateB;

	queryState(result, gl, type, target, stateA);
	queryState(result, gl, type, other, stateB);

	if (stateA.isUndefined() || stateB.isUndefined())
		return;

	switch (type)
	{
		case QUERY_BOOLEAN:
		{
			if (stateA.getBoolAccess() != stateB.getBoolAccess())
				result.fail("expected equal results");
			break;
		}

		case QUERY_INTEGER:
		{
			if (stateA.getIntAccess() != stateB.getIntAccess())
				result.fail("expected equal results");
			break;
		}

		case QUERY_INTEGER64:
		{
			if (stateA.getInt64Access() != stateB.getInt64Access())
				result.fail("expected equal results");
			break;
		}

		case QUERY_FLOAT:
		{
			if (stateA.getFloatAccess() != stateB.getFloatAccess())
				result.fail("expected equal results");
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
			break;
	}
}

void verifyStateFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float reference, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyFloat(result, state, reference);
}

void verifyStateFloatMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float minValue, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyFloatMin(result, state, minValue);
}

void verifyStateFloatMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float maxValue, QueryType type)
{
	QueriedState state;

	queryState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyFloatMax(result, state, maxValue);
}

void verifyStatePointer (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, const void* expected, QueryType type)
{
	QueriedState state;

	queryPointerState(result, gl, type, target, state);

	if (!state.isUndefined())
		verifyPointer(result, state, expected);
}

void verifyStateIndexedBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, bool expected, QueryType type)
{
	QueriedState state;

	queryIndexedState(result, gl, type, target, index, state);

	if (!state.isUndefined())
		verifyBoolean(result, state, expected);
}

void verifyStateIndexedBooleanVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, const tcu::BVec4& expected, QueryType type)
{
	QueriedState state;

	queryIndexedState(result, gl, type, target, index, state);

	if (!state.isUndefined())
		verifyBooleanVec4(result, state, expected);
}

void verifyStateIndexedInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type)
{
	QueriedState state;

	queryIndexedState(result, gl, type, target, index, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateIndexedIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int minValue, QueryType type)
{
	QueriedState state;

	queryIndexedState(result, gl, type, target, index, state);

	if (!state.isUndefined())
		verifyIntegerMin(result, state, minValue);
}

void verifyStateAttributeInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type)
{
	QueriedState state;

	queryAttributeState(result, gl, type, target, index, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateFramebufferInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	queryFramebufferState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateFramebufferIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int minValue, QueryType type)
{
	QueriedState state;

	queryFramebufferState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyIntegerMin(result, state, minValue);
}

void verifyStateProgramInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	queryProgramState(result, gl, type, program, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateProgramIntegerVec3 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, const tcu::IVec3& expected, QueryType type)
{
	QueriedState state;

	queryProgramState(result, gl, type, program, pname, state);

	if (!state.isUndefined())
		verifyIntegerVec3(result, state, expected);
}

void verifyStatePipelineInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	queryPipelineState(result, gl, type, pipeline, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateTextureParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	queryTextureParamState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateTextureParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, float expected, QueryType type)
{
	QueriedState state;

	queryTextureParamState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyFloat(result, state, expected);
}

void verifyStateTextureParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::Vec4& expected, QueryType type)
{
	QueriedState state;

	queryTextureParamState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyFloatVec4(result, state, expected);
}

void verifyStateTextureParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
{
	QueriedState state;

	queryTextureParamState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyNormalizedI32Vec4(result, state, expected);
}

void verifyStateTextureParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
{
	QueriedState state;

	queryTextureParamState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyIntegerVec4(result, state, expected);
}

void verifyStateTextureParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::UVec4& expected, QueryType type)
{
	QueriedState state;

	queryTextureParamState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyUnsignedIntegerVec4(result, state, expected);
}

void verifyStateTextureLevelInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	queryTextureLevelState(result, gl, type, target, level, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateObjectBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint handle, bool expected, QueryType type)
{
	QueriedState state;

	queryObjectState(result, gl, type, handle, state);

	if (!state.isUndefined())
		verifyBoolean(result, state, expected);
}

void verifyStateQueryInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	queryQueryState(result, gl, type, target, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateSamplerParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, int expected, QueryType type)
{
	QueriedState state;

	querySamplerState(result, gl, type, sampler, pname, state);

	if (!state.isUndefined())
		verifyInteger(result, state, expected);
}

void verifyStateSamplerParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, float expected, QueryType type)
{
	QueriedState state;

	querySamplerState(result, gl, type, sampler, pname, state);

	if (!state.isUndefined())
		verifyFloat(result, state, expected);
}

void verifyStateSamplerParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::Vec4& expected, QueryType type)
{
	QueriedState state;

	querySamplerState(result, gl, type, sampler, pname, state);

	if (!state.isUndefined())
		verifyFloatVec4(result, state, expected);
}

void verifyStateSamplerParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
{
	QueriedState state;

	querySamplerState(result, gl, type, sampler, pname, state);

	if (!state.isUndefined())
		verifyNormalizedI32Vec4(result, state, expected);
}

void verifyStateSamplerParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
{
	QueriedState state;

	querySamplerState(result, gl, type, sampler, pname, state);

	if (!state.isUndefined())
		verifyIntegerVec4(result, state, expected);
}

void verifyStateSamplerParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::UVec4& expected, QueryType type)
{
	QueriedState state;

	querySamplerState(result, gl, type, sampler, pname, state);

	if (!state.isUndefined())
		verifyUnsignedIntegerVec4(result, state, expected);
}

} // StateQueryUtil
} // gls
} // deqp
