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