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