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