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

#include "es3fFloatStateQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "es3fApiCase.hpp"
#include "gluRenderContext.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuFormatUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "glwEnums.hpp"

#include <limits>

using namespace glw; // GLint and other GL types
using namespace deqp::gls;
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;

namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace FloatStateQueryVerifiers
{
namespace
{

const int FLOAT_EXPANSION_E		= 0x03FF; // 10 bits error allowed, requires 22 accurate bits
const int FLOAT_EXPANSION_E_64	= 0x07FF;

GLint64 expandGLFloatToInteger (GLfloat f)
{
	const GLuint64 referenceValue = (GLint64)(f * 2147483647.0);
	return referenceValue;
}

GLint clampToGLint (GLint64 val)
{
	return (GLint)de::clamp<GLint64>(val, std::numeric_limits<GLint>::min(), std::numeric_limits<GLint>::max());
}

} // anonymous

// StateVerifier

class StateVerifier : protected glu::CallLogWrapper
{
public:
						StateVerifier					(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
	virtual				~StateVerifier					(); // make GCC happy

	const char*			getTestNamePostfix				(void)																																													const;

	virtual void		verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference)																																		= DE_NULL;

	// "Expanded" == Float to int conversion converts from [-1.0 to 1.0] -> [MIN_INT MAX_INT]
	virtual void		verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference)																																		= DE_NULL;
	virtual void		verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)																												= DE_NULL;
	virtual void		verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)																		= DE_NULL;

	// verify that the given range is completely whitin the GL state range
	virtual void		verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)																																= DE_NULL;
	virtual void		verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference)																																		= DE_NULL;

private:
	const char*	const	m_testNamePostfix;
};

StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
	: glu::CallLogWrapper	(gl, log)
	, m_testNamePostfix		(testNamePostfix)
{
	enableLogging(true);
}

StateVerifier::~StateVerifier ()
{
}

const char* StateVerifier::getTestNamePostfix (void) const
{
	return m_testNamePostfix;
}

// GetBooleanVerifier

class GetBooleanVerifier : public StateVerifier
{
public:
			GetBooleanVerifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
};

GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getboolean")
{
}

void GetBooleanVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean> state;
	glGetBooleanv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLboolean expectedGLState = reference != 0.0f ? GL_TRUE : GL_FALSE;

	if (state != expectedGLState)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (expectedGLState==GL_TRUE ? "GL_TRUE" : "GL_FALSE") << "; got " << (state == GL_TRUE ? "GL_TRUE" : (state == GL_FALSE ? "GL_FALSE" : "non-boolean")) << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

void GetBooleanVerifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
	verifyFloat(testCtx, name, reference);
}

void GetBooleanVerifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
{
	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));

	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean[2]> boolVector2;
	glGetBooleanv(name, boolVector2);

	if (!boolVector2.verifyValidity(testCtx))
		return;

	const GLboolean referenceAsGLBoolean[] =
	{
		reference0 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference1 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
	};

	if (boolVector2[0] != referenceAsGLBoolean[0] ||
		boolVector2[1] != referenceAsGLBoolean[1])
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
			<< (boolVector2[0] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (boolVector2[1] ? "GL_TRUE" : "GL_FALSE") << " "
			<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

void GetBooleanVerifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4;
	glGetBooleanv(name, boolVector4);

	if (!boolVector4.verifyValidity(testCtx))
		return;

	const GLboolean referenceAsGLBoolean[] =
	{
		reference0 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference1 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference2 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference3 != 0.0f ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
	};

	if (boolVector4[0] != referenceAsGLBoolean[0] ||
		boolVector4[1] != referenceAsGLBoolean[1] ||
		boolVector4[2] != referenceAsGLBoolean[2] ||
		boolVector4[3] != referenceAsGLBoolean[3])
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
			<< (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (referenceAsGLBoolean[3] ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

void GetBooleanVerifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean[2]> range;
	glGetBooleanv(name, range);

	if (!range.verifyValidity(testCtx))
		return;

	if (range[0] == GL_FALSE)
	{
		if (max < 0 || min < 0)
		{
			testCtx.getLog() << TestLog::Message << "// ERROR: range [" << min << ", " << max << "] is not in range [" << (range[0] == GL_TRUE ? "GL_TRUE" : (range[0] == GL_FALSE ? "GL_FALSE" : "non-boolean")) << ", " << (range[1] == GL_TRUE ? "GL_TRUE" : (range[1] == GL_FALSE ? "GL_FALSE" : "non-boolean")) << "]"  << TestLog::EndMessage;
			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean range");
			return;
		}
	}
	if (range[1] == GL_FALSE)
	{
		if (max > 0 || min > 0)
		{
			testCtx.getLog() << TestLog::Message << "// ERROR: range [" << min << ", " << max << "] is not in range [" << (range[0] == GL_TRUE ? "GL_TRUE" : (range[0] == GL_FALSE ? "GL_FALSE" : "non-boolean")) << ", " << (range[1] == GL_TRUE ? "GL_TRUE" : (range[1] == GL_FALSE ? "GL_FALSE" : "non-boolean")) << "]"  << TestLog::EndMessage;
			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean range");
			return;
		}
	}
}

void GetBooleanVerifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean> state;
	glGetBooleanv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct)
		return;

	if (state == GL_FALSE) // state is zero
	{
		if (reference > 0) // and reference is greater than zero?
		{
			testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
		}
	}
	else
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

//GetIntegerVerifier

class GetIntegerVerifier : public StateVerifier
{
public:
			GetIntegerVerifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
};

GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getinteger")
{
}

void GetIntegerVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	const GLint expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(reference);
	const GLint expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);

	StateQueryMemoryWriteGuard<GLint> state;
	glGetIntegerv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state < expectedGLStateMin || state > expectedGLStateMax)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected rounding to the nearest integer, valid range [" << expectedGLStateMin << "," << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetIntegerVerifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));

	using tcu::TestLog;
	using tcu::toHex;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetIntegerv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLint expectedGLStateMax = clampToGLint(expandGLFloatToInteger(reference) + FLOAT_EXPANSION_E);
	const GLint expectedGLStateMin = clampToGLint(expandGLFloatToInteger(reference) - FLOAT_EXPANSION_E);

	if (state < expectedGLStateMin || state > expectedGLStateMax)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << toHex(expectedGLStateMin) << "," << toHex(expectedGLStateMax) << "]; got " << toHex((GLint)state) << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetIntegerVerifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
{
	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));

	using tcu::TestLog;
	using tcu::toHex;

	StateQueryMemoryWriteGuard<GLint[2]> floatVector2;
	glGetIntegerv(name, floatVector2);

	if (!floatVector2.verifyValidity(testCtx))
		return;

	const GLint referenceAsGLintMin[] =
	{
		clampToGLint(expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E)
	};
	const GLint referenceAsGLintMax[] =
	{
		clampToGLint(expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E)
	};

	if (floatVector2[0] < referenceAsGLintMin[0] || floatVector2[0] > referenceAsGLintMax[0] ||
		floatVector2[1] < referenceAsGLintMin[1] || floatVector2[1] > referenceAsGLintMax[1])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: expected in ranges "
			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "]"
			<< "; got "
			<< toHex(floatVector2[0]) << ", "
			<< toHex(floatVector2[1]) << " "<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetIntegerVerifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
	using tcu::TestLog;
	using tcu::toHex;

	StateQueryMemoryWriteGuard<GLint[4]> floatVector4;
	glGetIntegerv(name, floatVector4);

	if (!floatVector4.verifyValidity(testCtx))
		return;

	const GLint referenceAsGLintMin[] =
	{
		clampToGLint(expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference2) - FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference3) - FLOAT_EXPANSION_E)
	};
	const GLint referenceAsGLintMax[] =
	{
		clampToGLint(expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference2) + FLOAT_EXPANSION_E),
		clampToGLint(expandGLFloatToInteger(reference3) + FLOAT_EXPANSION_E)
	};

	if (floatVector4[0] < referenceAsGLintMin[0] || floatVector4[0] > referenceAsGLintMax[0] ||
		floatVector4[1] < referenceAsGLintMin[1] || floatVector4[1] > referenceAsGLintMax[1] ||
		floatVector4[2] < referenceAsGLintMin[2] || floatVector4[2] > referenceAsGLintMax[2] ||
		floatVector4[3] < referenceAsGLintMin[3] || floatVector4[3] > referenceAsGLintMax[3])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: expected in ranges "
			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "], "
			<< "[" << toHex(referenceAsGLintMin[2]) << " " << toHex(referenceAsGLintMax[2]) << "], "
			<< "[" << toHex(referenceAsGLintMin[3]) << " " << toHex(referenceAsGLintMax[3]) << "]"
			<< "; got "
			<< toHex(floatVector4[0]) << ", "
			<< toHex(floatVector4[1]) << ", "
			<< toHex(floatVector4[2]) << ", "
			<< toHex(floatVector4[3]) << " "<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetIntegerVerifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[2]> range;
	glGetIntegerv(name, range);

	if (!range.verifyValidity(testCtx))
		return;

	const GLint testRangeAsGLint[] =
	{
		StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(min),
		StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(max)
	};

	// check if test range outside of gl state range
	if (testRangeAsGLint[0] < range[0] ||
		testRangeAsGLint[1] > range[1])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: range ["
			<< testRangeAsGLint[0] << ", "
			<< testRangeAsGLint[1] << "]"
			<< " is not in range ["
			<< range[0] << ", "
			<< range[1] << "]" << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer range");
	}
}

void GetIntegerVerifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetIntegerv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLint referenceAsInt = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);

	if (state < referenceAsInt)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected expected greater or equal to " << referenceAsInt << "; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

//GetInteger64Verifier

class GetInteger64Verifier : public StateVerifier
{
public:
			GetInteger64Verifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
};

GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getinteger64")
{
}

void GetInteger64Verifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	const GLint64 expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint64>(reference);
	const GLint64 expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(reference);

	StateQueryMemoryWriteGuard<GLint64> state;
	glGetInteger64v(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state < expectedGLStateMin || state > expectedGLStateMax)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected rounding to the nearest integer, valid range [" << expectedGLStateMin << "," << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetInteger64Verifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));

	using tcu::TestLog;
	using tcu::toHex;

	StateQueryMemoryWriteGuard<GLint64> state;
	glGetInteger64v(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLint64 expectedGLStateMax = expandGLFloatToInteger(reference) + FLOAT_EXPANSION_E_64;
	const GLint64 expectedGLStateMin = expandGLFloatToInteger(reference) - FLOAT_EXPANSION_E_64;

	if (state < expectedGLStateMin || state > expectedGLStateMax)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << toHex(expectedGLStateMin) << "," << toHex(expectedGLStateMax) << "]; got " << toHex((GLint64)state) << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetInteger64Verifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
{
	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));

	using tcu::TestLog;
	using tcu::toHex;

	StateQueryMemoryWriteGuard<GLint64[2]> floatVector2;
	glGetInteger64v(name, floatVector2);

	if (!floatVector2.verifyValidity(testCtx))
		return;

	const GLint64 referenceAsGLintMin[] =
	{
		expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E_64
	};
	const GLint64 referenceAsGLintMax[] =
	{
		expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E_64
	};

	if (floatVector2[0] < referenceAsGLintMin[0] || floatVector2[0] > referenceAsGLintMax[0] ||
		floatVector2[1] < referenceAsGLintMin[1] || floatVector2[1] > referenceAsGLintMax[1])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: expected in ranges "
			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "]"
			<< "; got "
			<< toHex(floatVector2[0]) << ", "
			<< toHex(floatVector2[1]) << " "<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetInteger64Verifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
	using tcu::TestLog;
	using tcu::toHex;

	StateQueryMemoryWriteGuard<GLint64[4]> floatVector4;
	glGetInteger64v(name, floatVector4);

	if (!floatVector4.verifyValidity(testCtx))
		return;

	const GLint64 referenceAsGLintMin[] =
	{
		expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference2) - FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference3) - FLOAT_EXPANSION_E_64
	};
	const GLint64 referenceAsGLintMax[] =
	{
		expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference2) + FLOAT_EXPANSION_E_64,
		expandGLFloatToInteger(reference3) + FLOAT_EXPANSION_E_64
	};

	if (floatVector4[0] < referenceAsGLintMin[0] || floatVector4[0] > referenceAsGLintMax[0] ||
		floatVector4[1] < referenceAsGLintMin[1] || floatVector4[1] > referenceAsGLintMax[1] ||
		floatVector4[2] < referenceAsGLintMin[2] || floatVector4[2] > referenceAsGLintMax[2] ||
		floatVector4[3] < referenceAsGLintMin[3] || floatVector4[3] > referenceAsGLintMax[3])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: expected in ranges "
			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "], "
			<< "[" << toHex(referenceAsGLintMin[2]) << " " << toHex(referenceAsGLintMax[2]) << "], "
			<< "[" << toHex(referenceAsGLintMin[3]) << " " << toHex(referenceAsGLintMax[3]) << "]"
			<< "; got "
			<< toHex(floatVector4[0]) << ", "
			<< toHex(floatVector4[1]) << ", "
			<< toHex(floatVector4[2]) << ", "
			<< toHex(floatVector4[3]) << " "<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetInteger64Verifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint64[2]> range;
	glGetInteger64v(name, range);

	if (!range.verifyValidity(testCtx))
		return;

	const GLint64 testRangeAsGLint[] =
	{
		StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint64>(min),
		StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(max)
	};

	// check if test range outside of gl state range
	if (testRangeAsGLint[0] < range[0] ||
		testRangeAsGLint[1] > range[1])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: range ["
			<< testRangeAsGLint[0] << ", "
			<< testRangeAsGLint[1] << "]"
			<< " is not in range ["
			<< range[0] << ", "
			<< range[1] << "]" << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer range");
	}
}

void GetInteger64Verifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint64> state;
	glGetInteger64v(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLint64 referenceAsInt = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(reference);

	if (state < referenceAsInt)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected expected greater or equal to " << referenceAsInt << "; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

//GetFloatVerifier

class GetFloatVerifier : public StateVerifier
{
public:
			GetFloatVerifier			(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
};

GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getfloat")
{
}

void GetFloatVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat> state;
	glGetFloatv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

void GetFloatVerifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
	verifyFloat(testCtx, name, reference);
}

void GetFloatVerifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
{
	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));

	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
	glGetFloatv(name, floatVector2);

	if (!floatVector2.verifyValidity(testCtx))
		return;

	if (floatVector2[0] != reference0 ||
		floatVector2[1] != reference1)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference0 << ", " << reference1 << "; got " << floatVector2[0] << " " << floatVector2[1] << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

void GetFloatVerifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[4]> floatVector4;
	glGetFloatv(name, floatVector4);

	if (!floatVector4.verifyValidity(testCtx))
		return;

	if (floatVector4[0] != reference0 ||
		floatVector4[1] != reference1 ||
		floatVector4[2] != reference2 ||
		floatVector4[3] != reference3)
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: expected "<< reference0 << ", " << reference1 << ", " << reference2 << ", " << reference3
			<< "; got " << floatVector4[0] << ", " << floatVector4[1] << ", " << floatVector4[2] << ", " << floatVector4[3]
			<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

void GetFloatVerifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
	glGetFloatv(name, floatVector2);

	if (!floatVector2.verifyValidity(testCtx))
		return;

	if (floatVector2[0] > min ||
		floatVector2[1] < max)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << min << ", " << max << "]; got [" << floatVector2[0] << " " << floatVector2[1]  << "]" << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float range");
	}
}

void GetFloatVerifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat> state;
	glGetFloatv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state < reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}


} // FloatStateQueryVerifiers

namespace
{

using namespace FloatStateQueryVerifiers;

class DepthRangeCase : public ApiCase
{
public:
	DepthRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, 0.0f, 1.0f);
		expectError(GL_NO_ERROR);

		const struct FixedTest
		{
			float n, f;
		} fixedTests[] =
		{
			{ 0.5f, 1.0f },
			{ 0.0f, 0.5f },
			{ 0.0f, 0.0f },
			{ 1.0f, 1.0f }
		};
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
		{
			glDepthRangef(fixedTests[ndx].n, fixedTests[ndx].f);

			m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, fixedTests[ndx].n, fixedTests[ndx].f);
			expectError(GL_NO_ERROR);
		}

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			GLfloat n	= rnd.getFloat(0, 1);
			GLfloat f	= rnd.getFloat(0, 1);

			glDepthRangef(n, f);
			m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, n, f);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class LineWidthCase : public ApiCase
{
public:
	LineWidthCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloat(m_testCtx, GL_LINE_WIDTH, 1.0f);
		expectError(GL_NO_ERROR);

		GLfloat range[2] = {1};
		glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
		expectError(GL_NO_ERROR);

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLfloat reference = rnd.getFloat(range[0], range[1]);

			glLineWidth(reference);
			m_verifier->verifyFloat(m_testCtx, GL_LINE_WIDTH, reference);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class PolygonOffsetFactorCase : public ApiCase
{
public:
	PolygonOffsetFactorCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, 0.0f);
		expectError(GL_NO_ERROR);

		const float fixedTests[] =
		{
			0.0f, 0.5f, -0.5f, 1.5f
		};
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
		{
			glPolygonOffset(fixedTests[ndx], 0);
			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, fixedTests[ndx]);
			expectError(GL_NO_ERROR);
		}

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLfloat reference = rnd.getFloat(-64000, 64000);

			glPolygonOffset(reference, 0);
			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, reference);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class PolygonOffsetUnitsCase : public ApiCase
{
public:
	PolygonOffsetUnitsCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, 0.0f);
		expectError(GL_NO_ERROR);

		const float fixedTests[] =
		{
			0.0f, 0.5f, -0.5f, 1.5f
		};
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
		{
			glPolygonOffset(0, fixedTests[ndx]);
			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, fixedTests[ndx]);
			expectError(GL_NO_ERROR);
		}

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLfloat reference = rnd.getFloat(-64000, 64000);

			glPolygonOffset(0, reference);
			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, reference);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class SampleCoverageCase : public ApiCase
{
public:
	SampleCoverageCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, 1.0f);
		expectError(GL_NO_ERROR);

		{
			const float fixedTests[] =
			{
				0.0f, 0.5f, 0.45f, 0.55f
			};
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
			{
				glSampleCoverage(fixedTests[ndx], GL_FALSE);
				m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, fixedTests[ndx]);
				expectError(GL_NO_ERROR);
			}
		}

		{
			const float clampTests[] =
			{
				-1.0f, -1.5f, 1.45f, 3.55f
			};
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(clampTests); ++ndx)
			{
				glSampleCoverage(clampTests[ndx], GL_FALSE);
				m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, de::clamp(clampTests[ndx], 0.0f, 1.0f));
				expectError(GL_NO_ERROR);
			}
		}

		{
			const int numIterations = 120;
			for (int i = 0; i < numIterations; ++i)
			{
				GLfloat		reference	= rnd.getFloat(0, 1);
				GLboolean	invert		= rnd.getBool() ? GL_TRUE : GL_FALSE;

				glSampleCoverage(reference, invert);
				m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, reference);
				expectError(GL_NO_ERROR);
			}
		}
	}
private:
	StateVerifier*	m_verifier;
};

class BlendColorCase : public ApiCase
{
public:
	BlendColorCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, 0, 0, 0, 0);
		expectError(GL_NO_ERROR);

		const struct FixedTest
		{
			float r, g, b, a;
		} fixedTests[] =
		{
			{ 0.5f, 1.0f, 0.5f, 1.0f },
			{ 0.0f, 0.5f, 0.0f, 0.5f },
			{ 0.0f, 0.0f, 0.0f, 0.0f },
			{ 1.0f, 1.0f, 1.0f, 1.0f },
		};
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
		{
			glBlendColor(fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
			m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
			expectError(GL_NO_ERROR);
		}

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLfloat r = rnd.getFloat(0, 1);
			const GLfloat g = rnd.getFloat(0, 1);
			const GLfloat b = rnd.getFloat(0, 1);
			const GLfloat a = rnd.getFloat(0, 1);

			glBlendColor(r, g, b, a);
			m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, r, g, b, a);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class ColorClearCase : public ApiCase
{
public:
	ColorClearCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		// \note Initial color clear value check is temorarily removed. (until the framework does not alter it)
		//m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, 0, 0, 0, 0);
		//expectError(GL_NO_ERROR);

		const struct FixedTest
		{
			float r, g, b, a;
		} fixedTests[] =
		{
			{ 0.5f, 1.0f, 0.5f, 1.0f },
			{ 0.0f, 0.5f, 0.0f, 0.5f },
			{ 0.0f, 0.0f, 0.0f, 0.0f },
			{ 1.0f, 1.0f, 1.0f, 1.0f },
		};
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
		{
			glClearColor(fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
			m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
			expectError(GL_NO_ERROR);
		}

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLfloat r = rnd.getFloat(0, 1);
			const GLfloat g = rnd.getFloat(0, 1);
			const GLfloat b = rnd.getFloat(0, 1);
			const GLfloat a = rnd.getFloat(0, 1);

			glClearColor(r, g, b, a);
			m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, r, g, b, a);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class DepthClearCase : public ApiCase
{
public:
	DepthClearCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyFloatExpanded(m_testCtx, GL_DEPTH_CLEAR_VALUE, 1);
		expectError(GL_NO_ERROR);

		const int numIterations = 120;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLfloat ref = rnd.getFloat(0, 1);

			glClearDepthf(ref);
			m_verifier->verifyFloatExpanded(m_testCtx, GL_DEPTH_CLEAR_VALUE, ref);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

class MaxTextureLODBiasCase : public ApiCase
{
public:
	MaxTextureLODBiasCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		m_verifier->verifyFloatGreaterOrEqual(m_testCtx, GL_MAX_TEXTURE_LOD_BIAS, 2.0f);
		expectError(GL_NO_ERROR);
	}
private:
	StateVerifier*	m_verifier;
};

class AliasedPointSizeRangeCase : public ApiCase
{
public:
	AliasedPointSizeRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		m_verifier->verifyFloatRange(m_testCtx, GL_ALIASED_POINT_SIZE_RANGE, 1, 1);
		expectError(GL_NO_ERROR);
	}
private:
	StateVerifier*	m_verifier;
};

class AliasedLineWidthRangeCase : public ApiCase
{
public:
	AliasedLineWidthRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		m_verifier->verifyFloatRange(m_testCtx, GL_ALIASED_LINE_WIDTH_RANGE, 1, 1);
		expectError(GL_NO_ERROR);
	}
private:
	StateVerifier*	m_verifier;
};

#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
	{																							\
		StateVerifier* verifier = (VERIFIERS)[_verifierNdx];									\
		CODE_BLOCK;																				\
	}

} // anonymous

FloatStateQueryTests::FloatStateQueryTests (Context& context)
	: TestCaseGroup			(context, "floats", "Float Values")
	, m_verifierBoolean		(DE_NULL)
	, m_verifierInteger		(DE_NULL)
	, m_verifierInteger64	(DE_NULL)
	, m_verifierFloat		(DE_NULL)
{
}

FloatStateQueryTests::~FloatStateQueryTests (void)
{
	deinit();
}

void FloatStateQueryTests::init (void)
{
	DE_ASSERT(m_verifierBoolean == DE_NULL);
	DE_ASSERT(m_verifierInteger == DE_NULL);
	DE_ASSERT(m_verifierInteger64 == DE_NULL);
	DE_ASSERT(m_verifierFloat == DE_NULL);

	m_verifierBoolean		= new GetBooleanVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierInteger		= new GetIntegerVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierInteger64		= new GetInteger64Verifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierFloat			= new GetFloatVerifier		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());

	StateVerifier* verifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat};

	FOR_EACH_VERIFIER(verifiers, addChild(new DepthRangeCase				(m_context, verifier,	(std::string("depth_range")					+ verifier->getTestNamePostfix()).c_str(),	"DEPTH_RANGE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new LineWidthCase					(m_context, verifier,	(std::string("line_width")					+ verifier->getTestNamePostfix()).c_str(),	"LINE_WIDTH")));
	FOR_EACH_VERIFIER(verifiers, addChild(new PolygonOffsetFactorCase		(m_context, verifier,	(std::string("polygon_offset_factor")		+ verifier->getTestNamePostfix()).c_str(),	"POLYGON_OFFSET_FACTOR")));
	FOR_EACH_VERIFIER(verifiers, addChild(new PolygonOffsetUnitsCase		(m_context, verifier,	(std::string("polygon_offset_units")		+ verifier->getTestNamePostfix()).c_str(),	"POLYGON_OFFSET_UNITS")));
	FOR_EACH_VERIFIER(verifiers, addChild(new SampleCoverageCase			(m_context, verifier,	(std::string("sample_coverage_value")		+ verifier->getTestNamePostfix()).c_str(),	"SAMPLE_COVERAGE_VALUE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new BlendColorCase				(m_context, verifier,	(std::string("blend_color")					+ verifier->getTestNamePostfix()).c_str(),	"BLEND_COLOR")));
	FOR_EACH_VERIFIER(verifiers, addChild(new ColorClearCase				(m_context, verifier,	(std::string("color_clear_value")			+ verifier->getTestNamePostfix()).c_str(),	"COLOR_CLEAR_VALUE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new DepthClearCase				(m_context, verifier,	(std::string("depth_clear_value")			+ verifier->getTestNamePostfix()).c_str(),	"DEPTH_CLEAR_VALUE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new MaxTextureLODBiasCase			(m_context, verifier,	(std::string("max_texture_lod_bias")		+ verifier->getTestNamePostfix()).c_str(),	"MAX_TEXTURE_LOD_BIAS")));
	FOR_EACH_VERIFIER(verifiers, addChild(new AliasedPointSizeRangeCase		(m_context, verifier,	(std::string("aliased_point_size_range")	+ verifier->getTestNamePostfix()).c_str(),	"ALIASED_POINT_SIZE_RANGE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new AliasedLineWidthRangeCase		(m_context, verifier,	(std::string("aliased_line_width_range")	+ verifier->getTestNamePostfix()).c_str(),	"ALIASED_LINE_WIDTH_RANGE")));
}

void FloatStateQueryTests::deinit (void)
{
	if (m_verifierBoolean)
	{
		delete m_verifierBoolean;
		m_verifierBoolean = DE_NULL;
	}
	if (m_verifierInteger)
	{
		delete m_verifierInteger;
		m_verifierInteger = DE_NULL;
	}
	if (m_verifierInteger64)
	{
		delete m_verifierInteger64;
		m_verifierInteger64 = DE_NULL;
	}
	if (m_verifierFloat)
	{
		delete m_verifierFloat;
		m_verifierFloat = DE_NULL;
	}

	this->TestCaseGroup::deinit();
}

} // Functional
} // gles3
} // deqp
