Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Float State Query tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fFloatStateQueryTests.hpp"
     25 #include "glsStateQueryUtil.hpp"
     26 #include "es3fApiCase.hpp"
     27 #include "gluRenderContext.hpp"
     28 #include "tcuRenderTarget.hpp"
     29 #include "tcuFormatUtil.hpp"
     30 #include "deRandom.hpp"
     31 #include "deMath.h"
     32 #include "glwEnums.hpp"
     33 
     34 #include <limits>
     35 
     36 using namespace glw; // GLint and other GL types
     37 using namespace deqp::gls;
     38 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
     39 
     40 namespace deqp
     41 {
     42 namespace gles3
     43 {
     44 namespace Functional
     45 {
     46 namespace FloatStateQueryVerifiers
     47 {
     48 namespace
     49 {
     50 
     51 const int FLOAT_EXPANSION_E = 0x03FF;
     52 
     53 GLint64 expandGLFloatToInteger (GLfloat f)
     54 {
     55 	const GLuint64 referenceValue = (GLint64)(f * 2147483647.0);
     56 	return referenceValue;
     57 }
     58 
     59 GLint clampToGLint (GLint64 val)
     60 {
     61 	return (GLint)de::clamp<GLint64>(val, std::numeric_limits<GLint>::min(), std::numeric_limits<GLint>::max());
     62 }
     63 
     64 } // anonymous
     65 
     66 // StateVerifier
     67 
     68 class StateVerifier : protected glu::CallLogWrapper
     69 {
     70 public:
     71 						StateVerifier					(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
     72 	virtual				~StateVerifier					(); // make GCC happy
     73 
     74 	const char*			getTestNamePostfix				(void)																																													const;
     75 
     76 	virtual void		verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference)																																		= DE_NULL;
     77 
     78 	// "Expanded" == Float to int conversion converts from [-1.0 to 1.0] -> [MIN_INT MAX_INT]
     79 	virtual void		verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference)																																		= DE_NULL;
     80 	virtual void		verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)																												= DE_NULL;
     81 	virtual void		verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)																		= DE_NULL;
     82 
     83 	// verify that the given range is completely whitin the GL state range
     84 	virtual void		verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)																																= DE_NULL;
     85 	virtual void		verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference)																																		= DE_NULL;
     86 
     87 private:
     88 	const char*	const	m_testNamePostfix;
     89 };
     90 
     91 StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
     92 	: glu::CallLogWrapper	(gl, log)
     93 	, m_testNamePostfix		(testNamePostfix)
     94 {
     95 	enableLogging(true);
     96 }
     97 
     98 StateVerifier::~StateVerifier ()
     99 {
    100 }
    101 
    102 const char* StateVerifier::getTestNamePostfix (void) const
    103 {
    104 	return m_testNamePostfix;
    105 }
    106 
    107 // GetBooleanVerifier
    108 
    109 class GetBooleanVerifier : public StateVerifier
    110 {
    111 public:
    112 			GetBooleanVerifier		(const glw::Functions& gl, tcu::TestLog& log);
    113 	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    114 	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    115 	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
    116 	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
    117 	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
    118 	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    119 };
    120 
    121 GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
    122 	: StateVerifier(gl, log, "_getboolean")
    123 {
    124 }
    125 
    126 void GetBooleanVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    127 {
    128 	using tcu::TestLog;
    129 
    130 	StateQueryMemoryWriteGuard<GLboolean> state;
    131 	glGetBooleanv(name, &state);
    132 
    133 	if (!state.verifyValidity(testCtx))
    134 		return;
    135 
    136 	const GLboolean expectedGLState = reference ? GL_TRUE : GL_FALSE;
    137 
    138 	if (state != expectedGLState)
    139 	{
    140 		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;
    141 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    142 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    143 	}
    144 }
    145 
    146 void GetBooleanVerifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    147 {
    148 	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
    149 	verifyFloat(testCtx, name, reference);
    150 }
    151 
    152 void GetBooleanVerifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
    153 {
    154 	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
    155 	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
    156 
    157 	using tcu::TestLog;
    158 
    159 	StateQueryMemoryWriteGuard<GLboolean[2]> boolVector2;
    160 	glGetBooleanv(name, boolVector2);
    161 
    162 	if (!boolVector2.verifyValidity(testCtx))
    163 		return;
    164 
    165 	const GLboolean referenceAsGLBoolean[] =
    166 	{
    167 		reference0 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    168 		reference1 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    169 	};
    170 
    171 	if (boolVector2[0] != referenceAsGLBoolean[0] ||
    172 		boolVector2[1] != referenceAsGLBoolean[1])
    173 	{
    174 		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
    175 			<< (boolVector2[0] ? "GL_TRUE" : "GL_FALSE") << " "
    176 			<< (boolVector2[1] ? "GL_TRUE" : "GL_FALSE") << " "
    177 			<< TestLog::EndMessage;
    178 
    179 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    180 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    181 	}
    182 }
    183 
    184 void GetBooleanVerifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
    185 {
    186 	using tcu::TestLog;
    187 
    188 	StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4;
    189 	glGetBooleanv(name, boolVector4);
    190 
    191 	if (!boolVector4.verifyValidity(testCtx))
    192 		return;
    193 
    194 	const GLboolean referenceAsGLBoolean[] =
    195 	{
    196 		reference0 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    197 		reference1 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    198 		reference2 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    199 		reference3 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    200 	};
    201 
    202 	if (boolVector4[0] != referenceAsGLBoolean[0] ||
    203 		boolVector4[1] != referenceAsGLBoolean[1] ||
    204 		boolVector4[2] != referenceAsGLBoolean[2] ||
    205 		boolVector4[3] != referenceAsGLBoolean[3])
    206 	{
    207 		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
    208 			<< (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") << " "
    209 			<< (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") << " "
    210 			<< (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") << " "
    211 			<< (referenceAsGLBoolean[3] ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
    212 
    213 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    214 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    215 	}
    216 }
    217 
    218 void GetBooleanVerifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
    219 {
    220 	using tcu::TestLog;
    221 
    222 	StateQueryMemoryWriteGuard<GLboolean[2]> range;
    223 	glGetBooleanv(name, range);
    224 
    225 	if (!range.verifyValidity(testCtx))
    226 		return;
    227 
    228 	if (range[0] == GL_FALSE)
    229 	{
    230 		if (max < 0 || min < 0)
    231 		{
    232 			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;
    233 			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    234 				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean range");
    235 			return;
    236 		}
    237 	}
    238 	if (range[1] == GL_FALSE)
    239 	{
    240 		if (max > 0 || min > 0)
    241 		{
    242 			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;
    243 			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    244 				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean range");
    245 			return;
    246 		}
    247 	}
    248 }
    249 
    250 void GetBooleanVerifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    251 {
    252 	using tcu::TestLog;
    253 
    254 	StateQueryMemoryWriteGuard<GLboolean> state;
    255 	glGetBooleanv(name, &state);
    256 
    257 	if (!state.verifyValidity(testCtx))
    258 		return;
    259 
    260 	if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct)
    261 		return;
    262 
    263 	if (state == GL_FALSE) // state is zero
    264 	{
    265 		if (reference > 0) // and reference is greater than zero?
    266 		{
    267 			testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
    268 			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    269 				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    270 		}
    271 	}
    272 	else
    273 	{
    274 		testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
    275 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    276 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    277 	}
    278 }
    279 
    280 //GetIntegerVerifier
    281 
    282 class GetIntegerVerifier : public StateVerifier
    283 {
    284 public:
    285 			GetIntegerVerifier		(const glw::Functions& gl, tcu::TestLog& log);
    286 	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    287 	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    288 	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
    289 	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
    290 	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
    291 	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    292 };
    293 
    294 GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
    295 	: StateVerifier(gl, log, "_getinteger")
    296 {
    297 }
    298 
    299 void GetIntegerVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    300 {
    301 	using tcu::TestLog;
    302 
    303 	const GLint expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(reference);
    304 	const GLint expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);
    305 
    306 	StateQueryMemoryWriteGuard<GLint> state;
    307 	glGetIntegerv(name, &state);
    308 
    309 	if (!state.verifyValidity(testCtx))
    310 		return;
    311 
    312 	if (state < expectedGLStateMin || state > expectedGLStateMax)
    313 	{
    314 		testCtx.getLog() << TestLog::Message << "// ERROR: expected rounding to the nearest integer, valid range [" << expectedGLStateMin << "," << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;
    315 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    316 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    317 	}
    318 }
    319 
    320 void GetIntegerVerifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    321 {
    322 	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
    323 
    324 	using tcu::TestLog;
    325 	using tcu::toHex;
    326 
    327 	StateQueryMemoryWriteGuard<GLint> state;
    328 	glGetIntegerv(name, &state);
    329 
    330 	if (!state.verifyValidity(testCtx))
    331 		return;
    332 
    333 	const GLint expectedGLStateMax = clampToGLint(expandGLFloatToInteger(reference) + FLOAT_EXPANSION_E);
    334 	const GLint expectedGLStateMin = clampToGLint(expandGLFloatToInteger(reference) - FLOAT_EXPANSION_E);
    335 
    336 	if (state < expectedGLStateMin || state > expectedGLStateMax)
    337 	{
    338 		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << toHex(expectedGLStateMin) << "," << toHex(expectedGLStateMax) << "]; got " << toHex((GLint)state) << TestLog::EndMessage;
    339 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    340 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    341 	}
    342 }
    343 
    344 void GetIntegerVerifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
    345 {
    346 	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
    347 	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
    348 
    349 	using tcu::TestLog;
    350 	using tcu::toHex;
    351 
    352 	StateQueryMemoryWriteGuard<GLint[2]> floatVector2;
    353 	glGetIntegerv(name, floatVector2);
    354 
    355 	if (!floatVector2.verifyValidity(testCtx))
    356 		return;
    357 
    358 	const GLint referenceAsGLintMin[] =
    359 	{
    360 		clampToGLint(expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E),
    361 		clampToGLint(expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E)
    362 	};
    363 	const GLint referenceAsGLintMax[] =
    364 	{
    365 		clampToGLint(expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E),
    366 		clampToGLint(expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E)
    367 	};
    368 
    369 	if (floatVector2[0] < referenceAsGLintMin[0] || floatVector2[0] > referenceAsGLintMax[0] ||
    370 		floatVector2[1] < referenceAsGLintMin[1] || floatVector2[1] > referenceAsGLintMax[1])
    371 	{
    372 		testCtx.getLog() << TestLog::Message
    373 			<< "// ERROR: expected in ranges "
    374 			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
    375 			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "]"
    376 			<< "; got "
    377 			<< toHex(floatVector2[0]) << ", "
    378 			<< toHex(floatVector2[1]) << " "<< TestLog::EndMessage;
    379 
    380 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    381 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    382 	}
    383 }
    384 
    385 void GetIntegerVerifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
    386 {
    387 	using tcu::TestLog;
    388 	using tcu::toHex;
    389 
    390 	StateQueryMemoryWriteGuard<GLint[4]> floatVector4;
    391 	glGetIntegerv(name, floatVector4);
    392 
    393 	if (!floatVector4.verifyValidity(testCtx))
    394 		return;
    395 
    396 	const GLint referenceAsGLintMin[] =
    397 	{
    398 		clampToGLint(expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E),
    399 		clampToGLint(expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E),
    400 		clampToGLint(expandGLFloatToInteger(reference2) - FLOAT_EXPANSION_E),
    401 		clampToGLint(expandGLFloatToInteger(reference3) - FLOAT_EXPANSION_E)
    402 	};
    403 	const GLint referenceAsGLintMax[] =
    404 	{
    405 		clampToGLint(expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E),
    406 		clampToGLint(expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E),
    407 		clampToGLint(expandGLFloatToInteger(reference2) + FLOAT_EXPANSION_E),
    408 		clampToGLint(expandGLFloatToInteger(reference3) + FLOAT_EXPANSION_E)
    409 	};
    410 
    411 	if (floatVector4[0] < referenceAsGLintMin[0] || floatVector4[0] > referenceAsGLintMax[0] ||
    412 		floatVector4[1] < referenceAsGLintMin[1] || floatVector4[1] > referenceAsGLintMax[1] ||
    413 		floatVector4[2] < referenceAsGLintMin[2] || floatVector4[2] > referenceAsGLintMax[2] ||
    414 		floatVector4[3] < referenceAsGLintMin[3] || floatVector4[3] > referenceAsGLintMax[3])
    415 	{
    416 		testCtx.getLog() << TestLog::Message
    417 			<< "// ERROR: expected in ranges "
    418 			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
    419 			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "], "
    420 			<< "[" << toHex(referenceAsGLintMin[2]) << " " << toHex(referenceAsGLintMax[2]) << "], "
    421 			<< "[" << toHex(referenceAsGLintMin[3]) << " " << toHex(referenceAsGLintMax[3]) << "]"
    422 			<< "; got "
    423 			<< toHex(floatVector4[0]) << ", "
    424 			<< toHex(floatVector4[1]) << ", "
    425 			<< toHex(floatVector4[2]) << ", "
    426 			<< toHex(floatVector4[3]) << " "<< TestLog::EndMessage;
    427 
    428 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    429 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    430 	}
    431 }
    432 
    433 void GetIntegerVerifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
    434 {
    435 	using tcu::TestLog;
    436 
    437 	StateQueryMemoryWriteGuard<GLint[2]> range;
    438 	glGetIntegerv(name, range);
    439 
    440 	if (!range.verifyValidity(testCtx))
    441 		return;
    442 
    443 	const GLint testRangeAsGLint[] =
    444 	{
    445 		StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(min),
    446 		StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(max)
    447 	};
    448 
    449 	// check if test range outside of gl state range
    450 	if (testRangeAsGLint[0] < range[0] ||
    451 		testRangeAsGLint[1] > range[1])
    452 	{
    453 		testCtx.getLog() << TestLog::Message
    454 			<< "// ERROR: range ["
    455 			<< testRangeAsGLint[0] << ", "
    456 			<< testRangeAsGLint[1] << "]"
    457 			<< " is not in range ["
    458 			<< range[0] << ", "
    459 			<< range[1] << "]" << TestLog::EndMessage;
    460 
    461 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    462 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer range");
    463 	}
    464 }
    465 
    466 void GetIntegerVerifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    467 {
    468 	using tcu::TestLog;
    469 
    470 	StateQueryMemoryWriteGuard<GLint> state;
    471 	glGetIntegerv(name, &state);
    472 
    473 	if (!state.verifyValidity(testCtx))
    474 		return;
    475 
    476 	const GLint referenceAsInt = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);
    477 
    478 	if (state < referenceAsInt)
    479 	{
    480 		testCtx.getLog() << TestLog::Message << "// ERROR: expected expected greater or equal to " << referenceAsInt << "; got " << state << TestLog::EndMessage;
    481 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    482 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    483 	}
    484 }
    485 
    486 //GetInteger64Verifier
    487 
    488 class GetInteger64Verifier : public StateVerifier
    489 {
    490 public:
    491 			GetInteger64Verifier		(const glw::Functions& gl, tcu::TestLog& log);
    492 	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    493 	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    494 	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
    495 	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
    496 	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
    497 	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    498 };
    499 
    500 GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log)
    501 	: StateVerifier(gl, log, "_getinteger64")
    502 {
    503 }
    504 
    505 void GetInteger64Verifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    506 {
    507 	using tcu::TestLog;
    508 
    509 	const GLint64 expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint64>(reference);
    510 	const GLint64 expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(reference);
    511 
    512 	StateQueryMemoryWriteGuard<GLint64> state;
    513 	glGetInteger64v(name, &state);
    514 
    515 	if (!state.verifyValidity(testCtx))
    516 		return;
    517 
    518 	if (state < expectedGLStateMin || state > expectedGLStateMax)
    519 	{
    520 		testCtx.getLog() << TestLog::Message << "// ERROR: expected rounding to the nearest integer, valid range [" << expectedGLStateMin << "," << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;
    521 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    522 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    523 	}
    524 }
    525 
    526 void GetInteger64Verifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    527 {
    528 	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
    529 
    530 	using tcu::TestLog;
    531 	using tcu::toHex;
    532 
    533 	StateQueryMemoryWriteGuard<GLint64> state;
    534 	glGetInteger64v(name, &state);
    535 
    536 	if (!state.verifyValidity(testCtx))
    537 		return;
    538 
    539 	const GLint64 expectedGLStateMax = expandGLFloatToInteger(reference) + FLOAT_EXPANSION_E;
    540 	const GLint64 expectedGLStateMin = expandGLFloatToInteger(reference) - FLOAT_EXPANSION_E;
    541 
    542 	if (state < expectedGLStateMin || state > expectedGLStateMax)
    543 	{
    544 		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << toHex(expectedGLStateMin) << "," << toHex(expectedGLStateMax) << "]; got " << toHex((GLint64)state) << TestLog::EndMessage;
    545 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    546 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    547 	}
    548 }
    549 
    550 void GetInteger64Verifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
    551 {
    552 	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
    553 	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
    554 
    555 	using tcu::TestLog;
    556 	using tcu::toHex;
    557 
    558 	StateQueryMemoryWriteGuard<GLint64[2]> floatVector2;
    559 	glGetInteger64v(name, floatVector2);
    560 
    561 	if (!floatVector2.verifyValidity(testCtx))
    562 		return;
    563 
    564 	const GLint64 referenceAsGLintMin[] =
    565 	{
    566 		expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E,
    567 		expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E
    568 	};
    569 	const GLint64 referenceAsGLintMax[] =
    570 	{
    571 		expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E,
    572 		expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E
    573 	};
    574 
    575 	if (floatVector2[0] < referenceAsGLintMin[0] || floatVector2[0] > referenceAsGLintMax[0] ||
    576 		floatVector2[1] < referenceAsGLintMin[1] || floatVector2[1] > referenceAsGLintMax[1])
    577 	{
    578 		testCtx.getLog() << TestLog::Message
    579 			<< "// ERROR: expected in ranges "
    580 			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
    581 			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "]"
    582 			<< "; got "
    583 			<< toHex(floatVector2[0]) << ", "
    584 			<< toHex(floatVector2[1]) << " "<< TestLog::EndMessage;
    585 
    586 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    587 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    588 	}
    589 }
    590 
    591 void GetInteger64Verifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
    592 {
    593 	using tcu::TestLog;
    594 	using tcu::toHex;
    595 
    596 	StateQueryMemoryWriteGuard<GLint64[4]> floatVector4;
    597 	glGetInteger64v(name, floatVector4);
    598 
    599 	if (!floatVector4.verifyValidity(testCtx))
    600 		return;
    601 
    602 	const GLint64 referenceAsGLintMin[] =
    603 	{
    604 		expandGLFloatToInteger(reference0) - FLOAT_EXPANSION_E,
    605 		expandGLFloatToInteger(reference1) - FLOAT_EXPANSION_E,
    606 		expandGLFloatToInteger(reference2) - FLOAT_EXPANSION_E,
    607 		expandGLFloatToInteger(reference3) - FLOAT_EXPANSION_E
    608 	};
    609 	const GLint64 referenceAsGLintMax[] =
    610 	{
    611 		expandGLFloatToInteger(reference0) + FLOAT_EXPANSION_E,
    612 		expandGLFloatToInteger(reference1) + FLOAT_EXPANSION_E,
    613 		expandGLFloatToInteger(reference2) + FLOAT_EXPANSION_E,
    614 		expandGLFloatToInteger(reference3) + FLOAT_EXPANSION_E
    615 	};
    616 
    617 	if (floatVector4[0] < referenceAsGLintMin[0] || floatVector4[0] > referenceAsGLintMax[0] ||
    618 		floatVector4[1] < referenceAsGLintMin[1] || floatVector4[1] > referenceAsGLintMax[1] ||
    619 		floatVector4[2] < referenceAsGLintMin[2] || floatVector4[2] > referenceAsGLintMax[2] ||
    620 		floatVector4[3] < referenceAsGLintMin[3] || floatVector4[3] > referenceAsGLintMax[3])
    621 	{
    622 		testCtx.getLog() << TestLog::Message
    623 			<< "// ERROR: expected in ranges "
    624 			<< "[" << toHex(referenceAsGLintMin[0]) << " " << toHex(referenceAsGLintMax[0]) << "], "
    625 			<< "[" << toHex(referenceAsGLintMin[1]) << " " << toHex(referenceAsGLintMax[1]) << "], "
    626 			<< "[" << toHex(referenceAsGLintMin[2]) << " " << toHex(referenceAsGLintMax[2]) << "], "
    627 			<< "[" << toHex(referenceAsGLintMin[3]) << " " << toHex(referenceAsGLintMax[3]) << "]"
    628 			<< "; got "
    629 			<< toHex(floatVector4[0]) << ", "
    630 			<< toHex(floatVector4[1]) << ", "
    631 			<< toHex(floatVector4[2]) << ", "
    632 			<< toHex(floatVector4[3]) << " "<< TestLog::EndMessage;
    633 
    634 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    635 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    636 	}
    637 }
    638 
    639 void GetInteger64Verifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
    640 {
    641 	using tcu::TestLog;
    642 
    643 	StateQueryMemoryWriteGuard<GLint64[2]> range;
    644 	glGetInteger64v(name, range);
    645 
    646 	if (!range.verifyValidity(testCtx))
    647 		return;
    648 
    649 	const GLint64 testRangeAsGLint[] =
    650 	{
    651 		StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint64>(min),
    652 		StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(max)
    653 	};
    654 
    655 	// check if test range outside of gl state range
    656 	if (testRangeAsGLint[0] < range[0] ||
    657 		testRangeAsGLint[1] > range[1])
    658 	{
    659 		testCtx.getLog() << TestLog::Message
    660 			<< "// ERROR: range ["
    661 			<< testRangeAsGLint[0] << ", "
    662 			<< testRangeAsGLint[1] << "]"
    663 			<< " is not in range ["
    664 			<< range[0] << ", "
    665 			<< range[1] << "]" << TestLog::EndMessage;
    666 
    667 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    668 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer range");
    669 	}
    670 }
    671 
    672 void GetInteger64Verifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    673 {
    674 	using tcu::TestLog;
    675 
    676 	StateQueryMemoryWriteGuard<GLint64> state;
    677 	glGetInteger64v(name, &state);
    678 
    679 	if (!state.verifyValidity(testCtx))
    680 		return;
    681 
    682 	const GLint64 referenceAsInt = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint64>(reference);
    683 
    684 	if (state < referenceAsInt)
    685 	{
    686 		testCtx.getLog() << TestLog::Message << "// ERROR: expected expected greater or equal to " << referenceAsInt << "; got " << state << TestLog::EndMessage;
    687 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    688 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    689 	}
    690 }
    691 
    692 //GetFloatVerifier
    693 
    694 class GetFloatVerifier : public StateVerifier
    695 {
    696 public:
    697 			GetFloatVerifier			(const glw::Functions& gl, tcu::TestLog& log);
    698 	void	verifyFloat						(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    699 	void	verifyFloatExpanded				(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    700 	void	verifyFloat2Expanded			(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1);
    701 	void	verifyFloat4Color				(tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3);
    702 	void	verifyFloatRange				(tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max);
    703 	void	verifyFloatGreaterOrEqual		(tcu::TestContext& testCtx, GLenum name, GLfloat reference);
    704 };
    705 
    706 GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
    707 	: StateVerifier(gl, log, "_getfloat")
    708 {
    709 }
    710 
    711 void GetFloatVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    712 {
    713 	using tcu::TestLog;
    714 
    715 	StateQueryMemoryWriteGuard<GLfloat> state;
    716 	glGetFloatv(name, &state);
    717 
    718 	if (!state.verifyValidity(testCtx))
    719 		return;
    720 
    721 	if (state != reference)
    722 	{
    723 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
    724 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    725 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    726 	}
    727 }
    728 
    729 void GetFloatVerifier::verifyFloatExpanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    730 {
    731 	DE_ASSERT(de::inRange(reference, -1.0f, 1.0f));
    732 	verifyFloat(testCtx, name, reference);
    733 }
    734 
    735 void GetFloatVerifier::verifyFloat2Expanded (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1)
    736 {
    737 	DE_ASSERT(de::inRange(reference0, -1.0f, 1.0f));
    738 	DE_ASSERT(de::inRange(reference1, -1.0f, 1.0f));
    739 
    740 	using tcu::TestLog;
    741 
    742 	StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
    743 	glGetFloatv(name, floatVector2);
    744 
    745 	if (!floatVector2.verifyValidity(testCtx))
    746 		return;
    747 
    748 	if (floatVector2[0] != reference0 ||
    749 		floatVector2[1] != reference1)
    750 	{
    751 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference0 << ", " << reference1 << "; got " << floatVector2[0] << " " << floatVector2[1] << TestLog::EndMessage;
    752 
    753 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    754 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    755 	}
    756 }
    757 
    758 void GetFloatVerifier::verifyFloat4Color (tcu::TestContext& testCtx, GLenum name, GLfloat reference0, GLfloat reference1, GLfloat reference2, GLfloat reference3)
    759 {
    760 	using tcu::TestLog;
    761 
    762 	StateQueryMemoryWriteGuard<GLfloat[4]> floatVector4;
    763 	glGetFloatv(name, floatVector4);
    764 
    765 	if (!floatVector4.verifyValidity(testCtx))
    766 		return;
    767 
    768 	if (floatVector4[0] != reference0 ||
    769 		floatVector4[1] != reference1 ||
    770 		floatVector4[2] != reference2 ||
    771 		floatVector4[3] != reference3)
    772 	{
    773 		testCtx.getLog() << TestLog::Message
    774 			<< "// ERROR: expected "<< reference0 << ", " << reference1 << ", " << reference2 << ", " << reference3
    775 			<< "; got " << floatVector4[0] << ", " << floatVector4[1] << ", " << floatVector4[2] << ", " << floatVector4[3]
    776 			<< TestLog::EndMessage;
    777 
    778 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    779 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    780 	}
    781 }
    782 
    783 void GetFloatVerifier::verifyFloatRange (tcu::TestContext& testCtx, GLenum name, GLfloat min, GLfloat max)
    784 {
    785 	using tcu::TestLog;
    786 
    787 	StateQueryMemoryWriteGuard<GLfloat[2]> floatVector2;
    788 	glGetFloatv(name, floatVector2);
    789 
    790 	if (!floatVector2.verifyValidity(testCtx))
    791 		return;
    792 
    793 	if (floatVector2[0] > min ||
    794 		floatVector2[1] < max)
    795 	{
    796 		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << min << ", " << max << "]; got [" << floatVector2[0] << " " << floatVector2[1]  << "]" << TestLog::EndMessage;
    797 
    798 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    799 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float range");
    800 	}
    801 }
    802 
    803 void GetFloatVerifier::verifyFloatGreaterOrEqual (tcu::TestContext& testCtx, GLenum name, GLfloat reference)
    804 {
    805 	using tcu::TestLog;
    806 
    807 	StateQueryMemoryWriteGuard<GLfloat> state;
    808 	glGetFloatv(name, &state);
    809 
    810 	if (!state.verifyValidity(testCtx))
    811 		return;
    812 
    813 	if (state < reference)
    814 	{
    815 		testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got " << state << TestLog::EndMessage;
    816 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    817 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    818 	}
    819 }
    820 
    821 
    822 } // FloatStateQueryVerifiers
    823 
    824 namespace
    825 {
    826 
    827 using namespace FloatStateQueryVerifiers;
    828 
    829 class DepthRangeCase : public ApiCase
    830 {
    831 public:
    832 	DepthRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    833 		: ApiCase		(context, name, description)
    834 		, m_verifier	(verifier)
    835 	{
    836 	}
    837 
    838 	void test (void)
    839 	{
    840 		de::Random rnd(0xabcdef);
    841 
    842 		m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, 0.0f, 1.0f);
    843 		expectError(GL_NO_ERROR);
    844 
    845 		const struct FixedTest
    846 		{
    847 			float n, f;
    848 		} fixedTests[] =
    849 		{
    850 			{ 0.5f, 1.0f },
    851 			{ 0.0f, 0.5f },
    852 			{ 0.0f, 0.0f },
    853 			{ 1.0f, 1.0f }
    854 		};
    855 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
    856 		{
    857 			glDepthRangef(fixedTests[ndx].n, fixedTests[ndx].f);
    858 
    859 			m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, fixedTests[ndx].n, fixedTests[ndx].f);
    860 			expectError(GL_NO_ERROR);
    861 		}
    862 
    863 		const int numIterations = 120;
    864 		for (int i = 0; i < numIterations; ++i)
    865 		{
    866 			GLfloat n	= rnd.getFloat(0, 1);
    867 			GLfloat f	= rnd.getFloat(0, 1);
    868 
    869 			glDepthRangef(n, f);
    870 			m_verifier->verifyFloat2Expanded(m_testCtx, GL_DEPTH_RANGE, n, f);
    871 			expectError(GL_NO_ERROR);
    872 		}
    873 	}
    874 private:
    875 	StateVerifier*	m_verifier;
    876 };
    877 
    878 class LineWidthCase : public ApiCase
    879 {
    880 public:
    881 	LineWidthCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    882 		: ApiCase		(context, name, description)
    883 		, m_verifier	(verifier)
    884 	{
    885 	}
    886 
    887 	void test (void)
    888 	{
    889 		de::Random rnd(0xabcdef);
    890 
    891 		m_verifier->verifyFloat(m_testCtx, GL_LINE_WIDTH, 1.0f);
    892 		expectError(GL_NO_ERROR);
    893 
    894 		GLfloat range[2] = {1};
    895 		glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
    896 		expectError(GL_NO_ERROR);
    897 
    898 		const int numIterations = 120;
    899 		for (int i = 0; i < numIterations; ++i)
    900 		{
    901 			const GLfloat reference = rnd.getFloat(range[0], range[1]);
    902 
    903 			glLineWidth(reference);
    904 			m_verifier->verifyFloat(m_testCtx, GL_LINE_WIDTH, reference);
    905 			expectError(GL_NO_ERROR);
    906 		}
    907 	}
    908 private:
    909 	StateVerifier*	m_verifier;
    910 };
    911 
    912 class PolygonOffsetFactorCase : public ApiCase
    913 {
    914 public:
    915 	PolygonOffsetFactorCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    916 		: ApiCase		(context, name, description)
    917 		, m_verifier	(verifier)
    918 	{
    919 	}
    920 
    921 	void test (void)
    922 	{
    923 		de::Random rnd(0xabcdef);
    924 
    925 		m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, 0.0f);
    926 		expectError(GL_NO_ERROR);
    927 
    928 		const float fixedTests[] =
    929 		{
    930 			0.0f, 0.5f, -0.5f, 1.5f
    931 		};
    932 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
    933 		{
    934 			glPolygonOffset(fixedTests[ndx], 0);
    935 			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, fixedTests[ndx]);
    936 			expectError(GL_NO_ERROR);
    937 		}
    938 
    939 		const int numIterations = 120;
    940 		for (int i = 0; i < numIterations; ++i)
    941 		{
    942 			const GLfloat reference = rnd.getFloat(-64000, 64000);
    943 
    944 			glPolygonOffset(reference, 0);
    945 			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_FACTOR, reference);
    946 			expectError(GL_NO_ERROR);
    947 		}
    948 	}
    949 private:
    950 	StateVerifier*	m_verifier;
    951 };
    952 
    953 class PolygonOffsetUnitsCase : public ApiCase
    954 {
    955 public:
    956 	PolygonOffsetUnitsCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    957 		: ApiCase		(context, name, description)
    958 		, m_verifier	(verifier)
    959 	{
    960 	}
    961 
    962 	void test (void)
    963 	{
    964 		de::Random rnd(0xabcdef);
    965 
    966 		m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, 0.0f);
    967 		expectError(GL_NO_ERROR);
    968 
    969 		const float fixedTests[] =
    970 		{
    971 			0.0f, 0.5f, -0.5f, 1.5f
    972 		};
    973 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
    974 		{
    975 			glPolygonOffset(0, fixedTests[ndx]);
    976 			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, fixedTests[ndx]);
    977 			expectError(GL_NO_ERROR);
    978 		}
    979 
    980 		const int numIterations = 120;
    981 		for (int i = 0; i < numIterations; ++i)
    982 		{
    983 			const GLfloat reference = rnd.getFloat(-64000, 64000);
    984 
    985 			glPolygonOffset(0, reference);
    986 			m_verifier->verifyFloat(m_testCtx, GL_POLYGON_OFFSET_UNITS, reference);
    987 			expectError(GL_NO_ERROR);
    988 		}
    989 	}
    990 private:
    991 	StateVerifier*	m_verifier;
    992 };
    993 
    994 class SampleCoverageCase : public ApiCase
    995 {
    996 public:
    997 	SampleCoverageCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    998 		: ApiCase		(context, name, description)
    999 		, m_verifier	(verifier)
   1000 	{
   1001 	}
   1002 
   1003 	void test (void)
   1004 	{
   1005 		de::Random rnd(0xabcdef);
   1006 
   1007 		m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, 1.0f);
   1008 		expectError(GL_NO_ERROR);
   1009 
   1010 		{
   1011 			const float fixedTests[] =
   1012 			{
   1013 				0.0f, 0.5f, 0.45f, 0.55f
   1014 			};
   1015 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
   1016 			{
   1017 				glSampleCoverage(fixedTests[ndx], GL_FALSE);
   1018 				m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, fixedTests[ndx]);
   1019 				expectError(GL_NO_ERROR);
   1020 			}
   1021 		}
   1022 
   1023 		{
   1024 			const float clampTests[] =
   1025 			{
   1026 				-1.0f, -1.5f, 1.45f, 3.55f
   1027 			};
   1028 			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(clampTests); ++ndx)
   1029 			{
   1030 				glSampleCoverage(clampTests[ndx], GL_FALSE);
   1031 				m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, de::clamp(clampTests[ndx], 0.0f, 1.0f));
   1032 				expectError(GL_NO_ERROR);
   1033 			}
   1034 		}
   1035 
   1036 		{
   1037 			const int numIterations = 120;
   1038 			for (int i = 0; i < numIterations; ++i)
   1039 			{
   1040 				GLfloat		reference	= rnd.getFloat(0, 1);
   1041 				GLboolean	invert		= rnd.getBool() ? GL_TRUE : GL_FALSE;
   1042 
   1043 				glSampleCoverage(reference, invert);
   1044 				m_verifier->verifyFloat(m_testCtx, GL_SAMPLE_COVERAGE_VALUE, reference);
   1045 				expectError(GL_NO_ERROR);
   1046 			}
   1047 		}
   1048 	}
   1049 private:
   1050 	StateVerifier*	m_verifier;
   1051 };
   1052 
   1053 class BlendColorCase : public ApiCase
   1054 {
   1055 public:
   1056 	BlendColorCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
   1057 		: ApiCase		(context, name, description)
   1058 		, m_verifier	(verifier)
   1059 	{
   1060 	}
   1061 
   1062 	void test (void)
   1063 	{
   1064 		de::Random rnd(0xabcdef);
   1065 
   1066 		m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, 0, 0, 0, 0);
   1067 		expectError(GL_NO_ERROR);
   1068 
   1069 		const struct FixedTest
   1070 		{
   1071 			float r, g, b, a;
   1072 		} fixedTests[] =
   1073 		{
   1074 			{ 0.5f, 1.0f, 0.5f, 1.0f },
   1075 			{ 0.0f, 0.5f, 0.0f, 0.5f },
   1076 			{ 0.0f, 0.0f, 0.0f, 0.0f },
   1077 			{ 1.0f, 1.0f, 1.0f, 1.0f },
   1078 		};
   1079 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
   1080 		{
   1081 			glBlendColor(fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
   1082 			m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
   1083 			expectError(GL_NO_ERROR);
   1084 		}
   1085 
   1086 		const int numIterations = 120;
   1087 		for (int i = 0; i < numIterations; ++i)
   1088 		{
   1089 			const GLfloat r = rnd.getFloat(0, 1);
   1090 			const GLfloat g = rnd.getFloat(0, 1);
   1091 			const GLfloat b = rnd.getFloat(0, 1);
   1092 			const GLfloat a = rnd.getFloat(0, 1);
   1093 
   1094 			glBlendColor(r, g, b, a);
   1095 			m_verifier->verifyFloat4Color(m_testCtx, GL_BLEND_COLOR, r, g, b, a);
   1096 			expectError(GL_NO_ERROR);
   1097 		}
   1098 	}
   1099 private:
   1100 	StateVerifier*	m_verifier;
   1101 };
   1102 
   1103 class ColorClearCase : public ApiCase
   1104 {
   1105 public:
   1106 	ColorClearCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
   1107 		: ApiCase		(context, name, description)
   1108 		, m_verifier	(verifier)
   1109 	{
   1110 	}
   1111 
   1112 	void test (void)
   1113 	{
   1114 		de::Random rnd(0xabcdef);
   1115 
   1116 		// \note Initial color clear value check is temorarily removed. (until the framework does not alter it)
   1117 		//m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, 0, 0, 0, 0);
   1118 		//expectError(GL_NO_ERROR);
   1119 
   1120 		const struct FixedTest
   1121 		{
   1122 			float r, g, b, a;
   1123 		} fixedTests[] =
   1124 		{
   1125 			{ 0.5f, 1.0f, 0.5f, 1.0f },
   1126 			{ 0.0f, 0.5f, 0.0f, 0.5f },
   1127 			{ 0.0f, 0.0f, 0.0f, 0.0f },
   1128 			{ 1.0f, 1.0f, 1.0f, 1.0f },
   1129 		};
   1130 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(fixedTests); ++ndx)
   1131 		{
   1132 			glClearColor(fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
   1133 			m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, fixedTests[ndx].r, fixedTests[ndx].g, fixedTests[ndx].b, fixedTests[ndx].a);
   1134 			expectError(GL_NO_ERROR);
   1135 		}
   1136 
   1137 		const int numIterations = 120;
   1138 		for (int i = 0; i < numIterations; ++i)
   1139 		{
   1140 			const GLfloat r = rnd.getFloat(0, 1);
   1141 			const GLfloat g = rnd.getFloat(0, 1);
   1142 			const GLfloat b = rnd.getFloat(0, 1);
   1143 			const GLfloat a = rnd.getFloat(0, 1);
   1144 
   1145 			glClearColor(r, g, b, a);
   1146 			m_verifier->verifyFloat4Color(m_testCtx, GL_COLOR_CLEAR_VALUE, r, g, b, a);
   1147 			expectError(GL_NO_ERROR);
   1148 		}
   1149 	}
   1150 private:
   1151 	StateVerifier*	m_verifier;
   1152 };
   1153 
   1154 class DepthClearCase : public ApiCase
   1155 {
   1156 public:
   1157 	DepthClearCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
   1158 		: ApiCase		(context, name, description)
   1159 		, m_verifier	(verifier)
   1160 	{
   1161 	}
   1162 
   1163 	void test (void)
   1164 	{
   1165 		de::Random rnd(0xabcdef);
   1166 
   1167 		m_verifier->verifyFloatExpanded(m_testCtx, GL_DEPTH_CLEAR_VALUE, 1);
   1168 		expectError(GL_NO_ERROR);
   1169 
   1170 		const int numIterations = 120;
   1171 		for (int i = 0; i < numIterations; ++i)
   1172 		{
   1173 			const GLfloat ref = rnd.getFloat(0, 1);
   1174 
   1175 			glClearDepthf(ref);
   1176 			m_verifier->verifyFloatExpanded(m_testCtx, GL_DEPTH_CLEAR_VALUE, ref);
   1177 			expectError(GL_NO_ERROR);
   1178 		}
   1179 	}
   1180 private:
   1181 	StateVerifier*	m_verifier;
   1182 };
   1183 
   1184 class MaxTextureLODBiasCase : public ApiCase
   1185 {
   1186 public:
   1187 	MaxTextureLODBiasCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
   1188 		: ApiCase		(context, name, description)
   1189 		, m_verifier	(verifier)
   1190 	{
   1191 	}
   1192 
   1193 	void test (void)
   1194 	{
   1195 		m_verifier->verifyFloatGreaterOrEqual(m_testCtx, GL_MAX_TEXTURE_LOD_BIAS, 2.0f);
   1196 		expectError(GL_NO_ERROR);
   1197 	}
   1198 private:
   1199 	StateVerifier*	m_verifier;
   1200 };
   1201 
   1202 class AliasedPointSizeRangeCase : public ApiCase
   1203 {
   1204 public:
   1205 	AliasedPointSizeRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
   1206 		: ApiCase		(context, name, description)
   1207 		, m_verifier	(verifier)
   1208 	{
   1209 	}
   1210 
   1211 	void test (void)
   1212 	{
   1213 		m_verifier->verifyFloatRange(m_testCtx, GL_ALIASED_POINT_SIZE_RANGE, 1, 1);
   1214 		expectError(GL_NO_ERROR);
   1215 	}
   1216 private:
   1217 	StateVerifier*	m_verifier;
   1218 };
   1219 
   1220 class AliasedLineWidthRangeCase : public ApiCase
   1221 {
   1222 public:
   1223 	AliasedLineWidthRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
   1224 		: ApiCase		(context, name, description)
   1225 		, m_verifier	(verifier)
   1226 	{
   1227 	}
   1228 
   1229 	void test (void)
   1230 	{
   1231 		m_verifier->verifyFloatRange(m_testCtx, GL_ALIASED_LINE_WIDTH_RANGE, 1, 1);
   1232 		expectError(GL_NO_ERROR);
   1233 	}
   1234 private:
   1235 	StateVerifier*	m_verifier;
   1236 };
   1237 
   1238 #define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
   1239 	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
   1240 	{																							\
   1241 		StateVerifier* verifier = VERIFIERS[_verifierNdx];										\
   1242 		CODE_BLOCK;																				\
   1243 	}
   1244 
   1245 } // anonymous
   1246 
   1247 FloatStateQueryTests::FloatStateQueryTests (Context& context)
   1248 	: TestCaseGroup			(context, "floats", "Float Values")
   1249 	, m_verifierBoolean		(DE_NULL)
   1250 	, m_verifierInteger		(DE_NULL)
   1251 	, m_verifierInteger64	(DE_NULL)
   1252 	, m_verifierFloat		(DE_NULL)
   1253 {
   1254 }
   1255 
   1256 FloatStateQueryTests::~FloatStateQueryTests (void)
   1257 {
   1258 	deinit();
   1259 }
   1260 
   1261 void FloatStateQueryTests::init (void)
   1262 {
   1263 	DE_ASSERT(m_verifierBoolean == DE_NULL);
   1264 	DE_ASSERT(m_verifierInteger == DE_NULL);
   1265 	DE_ASSERT(m_verifierInteger64 == DE_NULL);
   1266 	DE_ASSERT(m_verifierFloat == DE_NULL);
   1267 
   1268 	m_verifierBoolean		= new GetBooleanVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
   1269 	m_verifierInteger		= new GetIntegerVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
   1270 	m_verifierInteger64		= new GetInteger64Verifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
   1271 	m_verifierFloat			= new GetFloatVerifier		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
   1272 
   1273 	StateVerifier* verifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat};
   1274 
   1275 	FOR_EACH_VERIFIER(verifiers, addChild(new DepthRangeCase				(m_context, verifier,	(std::string("depth_range")					+ verifier->getTestNamePostfix()).c_str(),	"DEPTH_RANGE")));
   1276 	FOR_EACH_VERIFIER(verifiers, addChild(new LineWidthCase					(m_context, verifier,	(std::string("line_width")					+ verifier->getTestNamePostfix()).c_str(),	"LINE_WIDTH")));
   1277 	FOR_EACH_VERIFIER(verifiers, addChild(new PolygonOffsetFactorCase		(m_context, verifier,	(std::string("polygon_offset_factor")		+ verifier->getTestNamePostfix()).c_str(),	"POLYGON_OFFSET_FACTOR")));
   1278 	FOR_EACH_VERIFIER(verifiers, addChild(new PolygonOffsetUnitsCase		(m_context, verifier,	(std::string("polygon_offset_units")		+ verifier->getTestNamePostfix()).c_str(),	"POLYGON_OFFSET_UNITS")));
   1279 	FOR_EACH_VERIFIER(verifiers, addChild(new SampleCoverageCase			(m_context, verifier,	(std::string("sample_coverage_value")		+ verifier->getTestNamePostfix()).c_str(),	"SAMPLE_COVERAGE_VALUE")));
   1280 	FOR_EACH_VERIFIER(verifiers, addChild(new BlendColorCase				(m_context, verifier,	(std::string("blend_color")					+ verifier->getTestNamePostfix()).c_str(),	"BLEND_COLOR")));
   1281 	FOR_EACH_VERIFIER(verifiers, addChild(new ColorClearCase				(m_context, verifier,	(std::string("color_clear_value")			+ verifier->getTestNamePostfix()).c_str(),	"COLOR_CLEAR_VALUE")));
   1282 	FOR_EACH_VERIFIER(verifiers, addChild(new DepthClearCase				(m_context, verifier,	(std::string("depth_clear_value")			+ verifier->getTestNamePostfix()).c_str(),	"DEPTH_CLEAR_VALUE")));
   1283 	FOR_EACH_VERIFIER(verifiers, addChild(new MaxTextureLODBiasCase			(m_context, verifier,	(std::string("max_texture_lod_bias")		+ verifier->getTestNamePostfix()).c_str(),	"MAX_TEXTURE_LOD_BIAS")));
   1284 	FOR_EACH_VERIFIER(verifiers, addChild(new AliasedPointSizeRangeCase		(m_context, verifier,	(std::string("aliased_point_size_range")	+ verifier->getTestNamePostfix()).c_str(),	"ALIASED_POINT_SIZE_RANGE")));
   1285 	FOR_EACH_VERIFIER(verifiers, addChild(new AliasedLineWidthRangeCase		(m_context, verifier,	(std::string("aliased_line_width_range")	+ verifier->getTestNamePostfix()).c_str(),	"ALIASED_LINE_WIDTH_RANGE")));
   1286 }
   1287 
   1288 void FloatStateQueryTests::deinit (void)
   1289 {
   1290 	if (m_verifierBoolean)
   1291 	{
   1292 		delete m_verifierBoolean;
   1293 		m_verifierBoolean = DE_NULL;
   1294 	}
   1295 	if (m_verifierInteger)
   1296 	{
   1297 		delete m_verifierInteger;
   1298 		m_verifierInteger = DE_NULL;
   1299 	}
   1300 	if (m_verifierInteger64)
   1301 	{
   1302 		delete m_verifierInteger64;
   1303 		m_verifierInteger64 = DE_NULL;
   1304 	}
   1305 	if (m_verifierFloat)
   1306 	{
   1307 		delete m_verifierFloat;
   1308 		m_verifierFloat = DE_NULL;
   1309 	}
   1310 
   1311 	this->TestCaseGroup::deinit();
   1312 }
   1313 
   1314 } // Functional
   1315 } // gles3
   1316 } // deqp
   1317