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 
expandGLFloatToInteger(GLfloat f)54 GLint64 expandGLFloatToInteger (GLfloat f)
55 {
56 	const GLuint64 referenceValue = (GLint64)(f * 2147483647.0);
57 	return referenceValue;
58 }
59 
clampToGLint(GLint64 val)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 
StateVerifier(const glw::Functions & gl,tcu::TestLog & log,const char * testNamePostfix)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 
~StateVerifier()99 StateVerifier::~StateVerifier ()
100 {
101 }
102 
getTestNamePostfix(void) const103 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 
GetBooleanVerifier(const glw::Functions & gl,tcu::TestLog & log)122 GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
123 	: StateVerifier(gl, log, "_getboolean")
124 {
125 }
126 
verifyFloat(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloatExpanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloat2Expanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1)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 
verifyFloat4Color(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1,GLfloat reference2,GLfloat reference3)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 
verifyFloatRange(tcu::TestContext & testCtx,GLenum name,GLfloat min,GLfloat max)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 
verifyFloatGreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
GetIntegerVerifier(const glw::Functions & gl,tcu::TestLog & log)295 GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
296 	: StateVerifier(gl, log, "_getinteger")
297 {
298 }
299 
verifyFloat(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloatExpanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloat2Expanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1)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 
verifyFloat4Color(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1,GLfloat reference2,GLfloat reference3)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 
verifyFloatRange(tcu::TestContext & testCtx,GLenum name,GLfloat min,GLfloat max)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 
verifyFloatGreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
GetInteger64Verifier(const glw::Functions & gl,tcu::TestLog & log)501 GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log)
502 	: StateVerifier(gl, log, "_getinteger64")
503 {
504 }
505 
verifyFloat(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloatExpanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloat2Expanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1)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 
verifyFloat4Color(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1,GLfloat reference2,GLfloat reference3)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 
verifyFloatRange(tcu::TestContext & testCtx,GLenum name,GLfloat min,GLfloat max)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 
verifyFloatGreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
GetFloatVerifier(const glw::Functions & gl,tcu::TestLog & log)707 GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
708 	: StateVerifier(gl, log, "_getfloat")
709 {
710 }
711 
verifyFloat(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloatExpanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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 
verifyFloat2Expanded(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1)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 
verifyFloat4Color(tcu::TestContext & testCtx,GLenum name,GLfloat reference0,GLfloat reference1,GLfloat reference2,GLfloat reference3)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 
verifyFloatRange(tcu::TestContext & testCtx,GLenum name,GLfloat min,GLfloat max)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 
verifyFloatGreaterOrEqual(tcu::TestContext & testCtx,GLenum name,GLfloat reference)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:
DepthRangeCase(Context & context,StateVerifier * verifier,const char * name,const char * description)833 	DepthRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
834 		: ApiCase		(context, name, description)
835 		, m_verifier	(verifier)
836 	{
837 	}
838 
test(void)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:
LineWidthCase(Context & context,StateVerifier * verifier,const char * name,const char * description)882 	LineWidthCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
883 		: ApiCase		(context, name, description)
884 		, m_verifier	(verifier)
885 	{
886 	}
887 
test(void)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:
PolygonOffsetFactorCase(Context & context,StateVerifier * verifier,const char * name,const char * description)916 	PolygonOffsetFactorCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
917 		: ApiCase		(context, name, description)
918 		, m_verifier	(verifier)
919 	{
920 	}
921 
test(void)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:
PolygonOffsetUnitsCase(Context & context,StateVerifier * verifier,const char * name,const char * description)957 	PolygonOffsetUnitsCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
958 		: ApiCase		(context, name, description)
959 		, m_verifier	(verifier)
960 	{
961 	}
962 
test(void)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:
SampleCoverageCase(Context & context,StateVerifier * verifier,const char * name,const char * description)998 	SampleCoverageCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
999 		: ApiCase		(context, name, description)
1000 		, m_verifier	(verifier)
1001 	{
1002 	}
1003 
test(void)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:
BlendColorCase(Context & context,StateVerifier * verifier,const char * name,const char * description)1057 	BlendColorCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
1058 		: ApiCase		(context, name, description)
1059 		, m_verifier	(verifier)
1060 	{
1061 	}
1062 
test(void)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:
ColorClearCase(Context & context,StateVerifier * verifier,const char * name,const char * description)1107 	ColorClearCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
1108 		: ApiCase		(context, name, description)
1109 		, m_verifier	(verifier)
1110 	{
1111 	}
1112 
test(void)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:
DepthClearCase(Context & context,StateVerifier * verifier,const char * name,const char * description)1158 	DepthClearCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
1159 		: ApiCase		(context, name, description)
1160 		, m_verifier	(verifier)
1161 	{
1162 	}
1163 
test(void)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:
MaxTextureLODBiasCase(Context & context,StateVerifier * verifier,const char * name,const char * description)1188 	MaxTextureLODBiasCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
1189 		: ApiCase		(context, name, description)
1190 		, m_verifier	(verifier)
1191 	{
1192 	}
1193 
test(void)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:
AliasedPointSizeRangeCase(Context & context,StateVerifier * verifier,const char * name,const char * description)1206 	AliasedPointSizeRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
1207 		: ApiCase		(context, name, description)
1208 		, m_verifier	(verifier)
1209 	{
1210 	}
1211 
test(void)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:
AliasedLineWidthRangeCase(Context & context,StateVerifier * verifier,const char * name,const char * description)1224 	AliasedLineWidthRangeCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
1225 		: ApiCase		(context, name, description)
1226 		, m_verifier	(verifier)
1227 	{
1228 	}
1229 
test(void)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 
FloatStateQueryTests(Context & context)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 
~FloatStateQueryTests(void)1257 FloatStateQueryTests::~FloatStateQueryTests (void)
1258 {
1259 	deinit();
1260 }
1261 
init(void)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 
deinit(void)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