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