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