1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
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
22 */ /*-------------------------------------------------------------------*/
23
24 /**
25 */ /*!
26 * \file gl4cDirectStateAccessQueriesTests.cpp
27 * \brief Conformance tests for the Direct State Access feature functionality (Queries access part).
28 */ /*-----------------------------------------------------------------------------------------------------------*/
29
30 /* Includes. */
31 #include "gl4cDirectStateAccessTests.hpp"
32
33 #include "deSharedPtr.hpp"
34
35 #include "gluContextInfo.hpp"
36 #include "gluDefs.hpp"
37 #include "gluPixelTransfer.hpp"
38 #include "gluStrUtil.hpp"
39
40 #include "tcuFuzzyImageCompare.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuRenderTarget.hpp"
43 #include "tcuSurface.hpp"
44 #include "tcuTestLog.hpp"
45
46 #include "glw.h"
47 #include "glwFunctions.hpp"
48
49 /* Define OpenGL enumerations not available in framework. */
50 #ifndef GL_QUERY_TARGET
51 #define GL_QUERY_TARGET 0x82EA
52 #endif
53
54 namespace gl4cts
55 {
56 namespace DirectStateAccess
57 {
58 namespace Queries
59 {
60 /******************************** Creation Test Implementation ********************************/
61
62 /** @brief Creation Test constructor.
63 *
64 * @param [in] context OpenGL context.
65 */
CreationTest(deqp::Context & context)66 CreationTest::CreationTest(deqp::Context& context)
67 : deqp::TestCase(context, "queries_creation", "Query Objects Creation Test")
68 {
69 /* Intentionally left blank. */
70 }
71
72 /** @brief Iterate Creation Test cases.
73 *
74 * @return Iteration result.
75 */
iterate()76 tcu::TestNode::IterateResult CreationTest::iterate()
77 {
78 /* Shortcut for GL functionality. */
79 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
80
81 /* Get context setup. */
82 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
83 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
84
85 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
86 {
87 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
88
89 return STOP;
90 }
91
92 /* Running tests. */
93 bool is_ok = true;
94 bool is_error = false;
95
96 /* Query targets */
97 static const glw::GLenum targets[] = {
98 GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED,
99 GL_TIMESTAMP, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
100 };
101 static const glw::GLuint targets_count = sizeof(targets) / sizeof(targets[0]);
102
103 /* Queries objects */
104 static const glw::GLuint queries_count = 2;
105
106 glw::GLuint queries_legacy[queries_count] = {};
107 glw::GLuint queries_dsa[targets_count][queries_count] = {};
108
109 try
110 {
111 /* Check legacy state creation. */
112 gl.genQueries(queries_count, queries_legacy);
113 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries have failed");
114
115 for (glw::GLuint i = 0; i < queries_count; ++i)
116 {
117 if (gl.isQuery(queries_legacy[i]))
118 {
119 is_ok = false;
120
121 /* Log. */
122 m_context.getTestContext().getLog()
123 << tcu::TestLog::Message
124 << "GenQueries has created default objects, but it should create only a names."
125 << tcu::TestLog::EndMessage;
126 }
127 }
128
129 /* Check direct state creation. */
130 for (glw::GLuint i = 0; i < targets_count; ++i)
131 {
132 gl.createQueries(targets[i], queries_count, queries_dsa[i]);
133 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
134
135 for (glw::GLuint j = 0; j < queries_count; ++j)
136 {
137 if (!gl.isQuery(queries_dsa[i][j]))
138 {
139 is_ok = false;
140
141 /* Log. */
142 m_context.getTestContext().getLog() << tcu::TestLog::Message
143 << "CreateQueries has not created default objects."
144 << tcu::TestLog::EndMessage;
145 }
146 }
147 }
148 }
149 catch (...)
150 {
151 is_ok = false;
152 is_error = true;
153 }
154
155 /* Cleanup. */
156 for (glw::GLuint j = 0; j < queries_count; ++j)
157 {
158 if (queries_legacy[j])
159 {
160 gl.deleteQueries(1, &queries_legacy[j]);
161
162 queries_legacy[j] = 0;
163 }
164
165 for (glw::GLuint i = 0; i < targets_count; ++i)
166 {
167 if (queries_dsa[i][j])
168 {
169 gl.deleteQueries(1, &queries_dsa[i][j]);
170
171 queries_dsa[i][j] = 0;
172 }
173 }
174 }
175
176 /* Result's setup. */
177 if (is_ok)
178 {
179 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
180 }
181 else
182 {
183 if (is_error)
184 {
185 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
186 }
187 else
188 {
189 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
190 }
191 }
192
193 return STOP;
194 }
195
196 /******************************** Defaults Test Implementation ********************************/
197
198 /** @brief Defaults Test constructor.
199 *
200 * @param [in] context OpenGL context.
201 */
DefaultsTest(deqp::Context & context)202 DefaultsTest::DefaultsTest(deqp::Context& context)
203 : deqp::TestCase(context, "queries_defaults", "Queries Defaults Test"), m_query_dsa(0)
204 {
205 /* Intentionally left blank. */
206 }
207
208 /** @brief Iterate Defaults Test cases.
209 *
210 * @return Iteration result.
211 */
iterate()212 tcu::TestNode::IterateResult DefaultsTest::iterate()
213 {
214 /* Get context setup. */
215 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
216 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
217
218 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
219 {
220 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
221
222 return STOP;
223 }
224
225 /* Running tests. */
226 bool is_ok = true;
227 bool is_error = false;
228
229 /* Query targets. */
230 static const glw::GLenum targets[] = {
231 GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED,
232 GL_TIMESTAMP, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
233 };
234
235 static const glw::GLchar* target_names[] = {
236 "GL_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED_CONSERVATIVE", "GL_TIME_ELAPSED",
237 "GL_TIMESTAMP", "GL_PRIMITIVES_GENERATED", "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"
238 };
239
240 static const glw::GLuint targets_count = sizeof(targets) / sizeof(targets[0]);
241
242 try
243 {
244 /* Check direct state creation. */
245 for (glw::GLuint i = 0; i < targets_count; ++i)
246 {
247 prepare(targets[i]);
248
249 is_ok &= testQueryParameter(GL_QUERY_RESULT, GL_FALSE, target_names[i]);
250 is_ok &= testQueryParameter(GL_QUERY_RESULT_AVAILABLE, GL_TRUE, target_names[i]);
251
252 clean();
253 }
254 }
255 catch (...)
256 {
257 is_ok = false;
258 is_error = true;
259
260 clean();
261 }
262
263 /* Result's setup. */
264 if (is_ok)
265 {
266 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
267 }
268 else
269 {
270 if (is_error)
271 {
272 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
273 }
274 else
275 {
276 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
277 }
278 }
279
280 return STOP;
281 }
282
283 /** @brief Create Query Objects.
284 *
285 * @note The function may throw if unexpected error has occured.
286 *
287 * @return True if test succeeded, false otherwise.
288 */
prepare(const glw::GLenum target)289 void DefaultsTest::prepare(const glw::GLenum target)
290 {
291 /* Shortcut for GL functionality. */
292 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
293
294 /* Query object creation */
295 gl.createQueries(target, 1, &m_query_dsa);
296 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
297 }
298
299 /** @brief Test Query Integer Parameter.
300 *
301 * @note The function may throw if unexpected error has occured.
302 *
303 * @param [in] pname Parameter name to be tested.
304 * @param [in] expected_value Expected value for comparison.
305 * @param [in] target_name Target name of the tested query object - for logging purposes.
306 *
307 * @return True if test succeeded, false otherwise.
308 */
testQueryParameter(const glw::GLenum pname,const glw::GLuint expected_value,const glw::GLchar * target_name)309 bool DefaultsTest::testQueryParameter(const glw::GLenum pname, const glw::GLuint expected_value,
310 const glw::GLchar* target_name)
311 {
312 /* Shortcut for GL functionality. */
313 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
314
315 /* Get data. */
316 glw::GLuint value = 0;
317
318 gl.getQueryObjectuiv(m_query_dsa, pname, &value);
319 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv have failed");
320
321 if (expected_value != value)
322 {
323 m_context.getTestContext().getLog()
324 << tcu::TestLog::Message << "glGetQueryObjectuiv of query object with target " << target_name
325 << " with parameter " << pname << " has returned " << value << ", however " << expected_value
326 << " was expected." << tcu::TestLog::EndMessage;
327
328 return false;
329 }
330
331 return true;
332 }
333
334 /** @brief Release GL objects.
335 */
clean()336 void DefaultsTest::clean()
337 {
338 /* Shortcut for GL functionality. */
339 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
340
341 if (m_query_dsa)
342 {
343 gl.deleteQueries(1, &m_query_dsa);
344
345 m_query_dsa = 0;
346 }
347 }
348
349 /******************************** Errors Test Implementation ********************************/
350
351 /** @brief Errors Test constructor.
352 *
353 * @param [in] context OpenGL context.
354 */
ErrorsTest(deqp::Context & context)355 ErrorsTest::ErrorsTest(deqp::Context& context)
356 : deqp::TestCase(context, "queries_errors", "Queries Errors Test")
357 , m_pGetQueryBufferObjectiv(DE_NULL)
358 , m_pGetQueryBufferObjectuiv(DE_NULL)
359 , m_pGetQueryBufferObjecti64v(DE_NULL)
360 , m_pGetQueryBufferObjectui64v(DE_NULL)
361 {
362 /* Intentionally left blank. */
363 }
364
365 /** @brief Iterate Errors Test cases.
366 *
367 * @return Iteration result.
368 */
iterate()369 tcu::TestNode::IterateResult ErrorsTest::iterate()
370 {
371 /* Shortcut for GL functionality. */
372 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
373
374 /* Get context setup. */
375 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
376 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
377
378 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
379 {
380 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
381
382 return STOP;
383 }
384
385 /* Getting function pointers. */
386 m_pGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectiv;
387 m_pGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectuiv;
388 m_pGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjecti64v;
389 m_pGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectui64v;
390
391 /* Running tests. */
392 bool is_ok = true;
393 bool is_error = false;
394
395 try
396 {
397 if ((DE_NULL == m_pGetQueryBufferObjectiv) || (DE_NULL == m_pGetQueryBufferObjectuiv) ||
398 (DE_NULL == m_pGetQueryBufferObjecti64v) || (DE_NULL == m_pGetQueryBufferObjectui64v))
399 {
400 m_context.getTestContext().getLog()
401 << tcu::TestLog::Message << "Test could not get the pointers for glGetQueryBufferObject* functions."
402 << tcu::TestLog::EndMessage;
403
404 throw 0;
405 }
406
407 is_ok &= testNegativeNumberOfObjects();
408 is_ok &= testInvalidTarget();
409 is_ok &= testInvalidQueryName();
410 is_ok &= testInvalidBufferName();
411 is_ok &= testInvalidParameterName();
412 is_ok &= testBufferOverflow();
413 is_ok &= testBufferNegativeOffset();
414 }
415 catch (...)
416 {
417 is_ok = false;
418 is_error = true;
419 }
420
421 /* Result's setup. */
422 if (is_ok)
423 {
424 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
425 }
426 else
427 {
428 if (is_error)
429 {
430 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
431 }
432 else
433 {
434 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
435 }
436 }
437
438 return STOP;
439 }
440
441 /** @brief Check that CreateQueries generates INVALID_VALUE
442 * error if number of query objects to create is
443 * negative.
444 *
445 * @return True if test succeded, false otherwise.
446 */
testNegativeNumberOfObjects()447 bool ErrorsTest::testNegativeNumberOfObjects()
448 {
449 /* Shortcut for GL functionality. */
450 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
451
452 /* Test for each target. */
453 for (glw::GLuint i = 0; i < s_targets_count; ++i)
454 {
455 glw::GLuint query = 0;
456
457 gl.createQueries(s_targets[i], -1, &query); /* Create negative number of queries. */
458
459 glw::GLenum error = gl.getError();
460
461 if (GL_INVALID_VALUE != error)
462 {
463 m_context.getTestContext().getLog()
464 << tcu::TestLog::Message << "glCreateQueries called with target " << s_target_names[i]
465 << " with negative number of objects to be created (-1) has generated error " << glu::getErrorStr(error)
466 << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;
467
468 if (query)
469 {
470 gl.deleteQueries(1, &query);
471
472 while (error == gl.getError())
473 ;
474
475 m_context.getTestContext().getLog()
476 << tcu::TestLog::Message << "glCreateQueries called with target " << s_target_names[i]
477 << " with negative number of objects to be created (-1) has created at least one object."
478 << tcu::TestLog::EndMessage;
479 }
480
481 return false;
482 }
483 }
484
485 return true;
486 }
487
488 /** @brief Check that CreateQueries generates INVALID_ENUM error if target is not
489 * one of accepted values:
490 * - SAMPLES_PASSED,
491 * - ANY_SAMPLES_PASSED,
492 * - ANY_SAMPLES_PASSED_CONSERVATIVE,
493 * - TIME_ELAPSED,
494 * - TIMESTAMP,
495 * - PRIMITIVES_GENERATED or
496 * - TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN.
497 *
498 * @return True if test succeded, false otherwise.
499 */
testInvalidTarget()500 bool ErrorsTest::testInvalidTarget()
501 {
502 /* Shortcut for GL functionality. */
503 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
504
505 /* Creating invalid target. */
506 glw::GLenum invalid_target = 0;
507
508 while (isTarget(++invalid_target))
509 ;
510
511 /* Test. */
512 glw::GLuint query = 0;
513
514 gl.createQueries(invalid_target, 1, &query); /* Create negative number of queries. */
515
516 glw::GLenum error = gl.getError();
517
518 if (GL_INVALID_ENUM != error)
519 {
520 m_context.getTestContext().getLog() << tcu::TestLog::Message << "glCreateQueries called with invalid target ("
521 << invalid_target << ") has generated error " << glu::getErrorStr(error)
522 << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;
523
524 if (query)
525 {
526 gl.deleteQueries(1, &query);
527
528 while (error == gl.getError())
529 ;
530
531 m_context.getTestContext().getLog() << tcu::TestLog::Message
532 << "glCreateQueries called with invalid target (" << invalid_target
533 << ") has created an object." << tcu::TestLog::EndMessage;
534 }
535
536 return false;
537 }
538
539 return true;
540 }
541
542 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
543 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
544 * INVALID_OPERATION error if <id> is not the name of a query object, or
545 * if the query object named by <id> is currently active.
546 *
547 * @return True if test succeded, false otherwise.
548 */
testInvalidQueryName()549 bool ErrorsTest::testInvalidQueryName()
550 {
551 /* Shortcut for GL functionality. */
552 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
553
554 /* Creating invalid query name. */
555 glw::GLuint invalid_query = 0;
556
557 /* Default result. */
558 bool is_ok = true;
559 bool is_error = false;
560
561 while (gl.isQuery(++invalid_query))
562 ;
563
564 /* Test's objects. */
565 glw::GLuint buffer = 0;
566 glw::GLuint query = 0;
567
568 try
569 {
570 /* Creating buffer for the test. */
571 gl.genBuffers(1, &buffer);
572 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
573
574 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
575 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
576
577 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
578 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
579
580 /* Test invalid query object name (integer version). */
581 m_pGetQueryBufferObjectiv(invalid_query, buffer, GL_QUERY_RESULT, 0);
582
583 glw::GLenum error = gl.getError();
584
585 if (GL_INVALID_OPERATION != error)
586 {
587 m_context.getTestContext().getLog()
588 << tcu::TestLog::Message
589 << "glGetQueryBufferObjectiv called with invalid query name has generated error "
590 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
591 << tcu::TestLog::EndMessage;
592
593 is_ok = false;
594 }
595
596 /* Test invalid query object name (unsigned integer version). */
597 m_pGetQueryBufferObjectuiv(invalid_query, buffer, GL_QUERY_RESULT, 0);
598
599 error = gl.getError();
600
601 if (GL_INVALID_OPERATION != error)
602 {
603 m_context.getTestContext().getLog()
604 << tcu::TestLog::Message
605 << "glGetQueryBufferObjectuiv called with invalid query name has generated error "
606 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
607 << tcu::TestLog::EndMessage;
608
609 is_ok = false;
610 }
611
612 /* Test invalid query object name (64-bit integer version). */
613 m_pGetQueryBufferObjecti64v(invalid_query, buffer, GL_QUERY_RESULT, 0);
614
615 error = gl.getError();
616
617 if (GL_INVALID_OPERATION != error)
618 {
619 m_context.getTestContext().getLog()
620 << tcu::TestLog::Message
621 << "glGetQueryBufferObjecti64v called with invalid query name has generated error "
622 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
623 << tcu::TestLog::EndMessage;
624
625 is_ok = false;
626 }
627
628 /* Test invalid query object name (64-bit unsigned integer version). */
629 m_pGetQueryBufferObjectui64v(invalid_query, buffer, GL_QUERY_RESULT, 0);
630
631 error = gl.getError();
632
633 if (GL_INVALID_OPERATION != error)
634 {
635 m_context.getTestContext().getLog()
636 << tcu::TestLog::Message
637 << "glGetQueryBufferObjectui64v called with invalid query name has generated error "
638 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
639 << tcu::TestLog::EndMessage;
640
641 is_ok = false;
642 }
643
644 /* Create query object for the test. */
645 gl.createQueries(s_targets[0], 1, &query);
646 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
647
648 gl.beginQuery(s_targets[0], query);
649 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
650
651 /* Test query of active query object name (integer version). */
652 m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT, 0);
653
654 error = gl.getError();
655
656 if (GL_INVALID_OPERATION != error)
657 {
658 m_context.getTestContext().getLog()
659 << tcu::TestLog::Message
660 << "glGetQueryBufferObjectiv called with active query object has generated error "
661 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
662 << tcu::TestLog::EndMessage;
663
664 is_ok = false;
665 }
666
667 /* Test query of active query object name (unsigned integer version). */
668 m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT, 0);
669
670 error = gl.getError();
671
672 if (GL_INVALID_OPERATION != error)
673 {
674 m_context.getTestContext().getLog()
675 << tcu::TestLog::Message
676 << "glGetQueryBufferObjectuiv called with active query object has generated error "
677 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
678 << tcu::TestLog::EndMessage;
679
680 is_ok = false;
681 }
682
683 /* Test query of active query object name (64-bit integer version). */
684 m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT, 0);
685
686 error = gl.getError();
687
688 if (GL_INVALID_OPERATION != error)
689 {
690 m_context.getTestContext().getLog()
691 << tcu::TestLog::Message
692 << "glGetQueryBufferObjecti64v called with active query object has generated error "
693 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
694 << tcu::TestLog::EndMessage;
695
696 is_ok = false;
697 }
698
699 /* Test query of active query object name (64-bit unsigned integer version). */
700 m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT, 0);
701
702 error = gl.getError();
703
704 if (GL_INVALID_OPERATION != error)
705 {
706 m_context.getTestContext().getLog()
707 << tcu::TestLog::Message
708 << "glGetQueryBufferObjectui64v called with active query object has generated error "
709 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
710 << tcu::TestLog::EndMessage;
711
712 is_ok = false;
713 }
714 }
715 catch (...)
716 {
717 is_error = true;
718 }
719
720 /* Releasing objects. */
721 if (query)
722 {
723 gl.endQuery(s_targets[0]);
724
725 gl.deleteQueries(1, &query);
726 }
727
728 if (buffer)
729 {
730 gl.deleteBuffers(1, &buffer);
731 }
732
733 /* Error cleanup. */
734 while (gl.getError())
735 ;
736
737 if (is_error)
738 {
739 throw 0;
740 }
741
742 return is_ok;
743 }
744
745 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
746 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
747 * INVALID_OPERATION error if <buffer> is not the name of an existing
748 * buffer object.
749 *
750 * @return True if test succeded, false otherwise.
751 */
testInvalidBufferName()752 bool ErrorsTest::testInvalidBufferName()
753 {
754 /* Shortcut for GL functionality. */
755 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
756
757 /* Default result. */
758 bool is_ok = true;
759 bool is_error = false;
760
761 /* Creating invalid buffer name. */
762 glw::GLuint invalid_buffer = 0;
763
764 while (gl.isBuffer(++invalid_buffer))
765 ;
766
767 /* Test's objects. */
768 glw::GLuint query = 0;
769
770 try
771 {
772 /* Create query object for the test. */
773 gl.createQueries(s_targets[0], 1, &query);
774 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
775
776 /* Test query of invalid buffer name (integer version). */
777 m_pGetQueryBufferObjectiv(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);
778
779 glw::GLenum error = gl.getError();
780
781 if (GL_INVALID_OPERATION != error)
782 {
783 m_context.getTestContext().getLog()
784 << tcu::TestLog::Message
785 << "glGetQueryBufferObjectiv which could generate buffers overflow generated error "
786 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
787 << tcu::TestLog::EndMessage;
788
789 is_ok = false;
790 }
791
792 /* Test query of invalid buffer name (unsigned integer version). */
793 m_pGetQueryBufferObjectuiv(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);
794
795 error = gl.getError();
796
797 if (GL_INVALID_OPERATION != error)
798 {
799 m_context.getTestContext().getLog()
800 << tcu::TestLog::Message
801 << "glGetQueryBufferObjectuiv which could generate buffers overflow generated error "
802 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
803 << tcu::TestLog::EndMessage;
804
805 is_ok = false;
806 }
807
808 /* Test query of invalid buffer name (64-bit integer version). */
809 m_pGetQueryBufferObjecti64v(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);
810
811 error = gl.getError();
812
813 if (GL_INVALID_OPERATION != error)
814 {
815 m_context.getTestContext().getLog()
816 << tcu::TestLog::Message
817 << "glGetQueryBufferObjecti64v which could generate buffers overflow generated error "
818 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
819 << tcu::TestLog::EndMessage;
820
821 is_ok = false;
822 }
823
824 /* Test query of invalid buffer name (64-bit unsigned integer version). */
825 m_pGetQueryBufferObjectui64v(query, invalid_buffer, GL_QUERY_RESULT_AVAILABLE, 0);
826
827 error = gl.getError();
828
829 if (GL_INVALID_OPERATION != error)
830 {
831 m_context.getTestContext().getLog()
832 << tcu::TestLog::Message
833 << "glGetQueryBufferObjectui64v which could generate buffers overflow generated error "
834 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
835 << tcu::TestLog::EndMessage;
836
837 is_ok = false;
838 }
839 }
840 catch (...)
841 {
842 is_error = true;
843 }
844
845 /* Releasing objects. */
846 if (query)
847 {
848 gl.deleteQueries(1, &query);
849 }
850
851 /* Error cleanup. */
852 while (gl.getError())
853 ;
854
855 if (is_error)
856 {
857 throw 0;
858 }
859
860 return is_ok;
861 }
862
863 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
864 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
865 * INVALID_ENUM error if <pname> is not QUERY_RESULT,
866 * QUERY_RESULT_AVAILABLE, QUERY_RESULT_NO_WAIT or QUERY_TARGET.
867 *
868 * @return True if test succeded, false otherwise.
869 */
testInvalidParameterName()870 bool ErrorsTest::testInvalidParameterName()
871 {
872 /* Shortcut for GL functionality. */
873 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
874
875 /* Creating invalid parameter name. */
876 glw::GLuint invalid_pname = 0;
877
878 while (isParameterName(++invalid_pname))
879 ;
880
881 /* Default result. */
882 bool is_ok = true;
883 bool is_error = false;
884
885 /* Test's objects. */
886 glw::GLuint buffer = 0;
887 glw::GLuint query = 0;
888
889 try
890 {
891 /* Creating buffer for the test. */
892 gl.genBuffers(1, &buffer);
893 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
894
895 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
896 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
897
898 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
899 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
900
901 /* Create query object for the test. */
902 gl.createQueries(s_targets[0], 1, &query);
903 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
904
905 /* Test query of invalid parameter name (integer version). */
906 m_pGetQueryBufferObjectiv(query, buffer, invalid_pname, 0);
907
908 glw::GLenum error = gl.getError();
909
910 if (GL_INVALID_ENUM != error)
911 {
912 m_context.getTestContext().getLog()
913 << tcu::TestLog::Message
914 << "glGetQueryBufferObjectiv called with invalid parameter name has generated error "
915 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;
916
917 is_ok = false;
918 }
919
920 /* Test query of invalid parameter name (unsigned integer version). */
921 m_pGetQueryBufferObjectuiv(query, buffer, invalid_pname, 0);
922
923 error = gl.getError();
924
925 if (GL_INVALID_ENUM != error)
926 {
927 m_context.getTestContext().getLog()
928 << tcu::TestLog::Message
929 << "glGetQueryBufferObjectuiv called with invalid parameter name has generated error "
930 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;
931
932 is_ok = false;
933 }
934
935 /* Test query of invalid parameter name (64-bit integer version). */
936 m_pGetQueryBufferObjecti64v(query, buffer, invalid_pname, 0);
937
938 error = gl.getError();
939
940 if (GL_INVALID_ENUM != error)
941 {
942 m_context.getTestContext().getLog()
943 << tcu::TestLog::Message
944 << "glGetQueryBufferObjecti64v called with invalid parameter name has generated error "
945 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;
946
947 is_ok = false;
948 }
949
950 /* Test query of invalid parameter name (64-bit unsigned integer version). */
951 m_pGetQueryBufferObjectui64v(query, buffer, invalid_pname, 0);
952
953 error = gl.getError();
954
955 if (GL_INVALID_ENUM != error)
956 {
957 m_context.getTestContext().getLog()
958 << tcu::TestLog::Message
959 << "glGetQueryBufferObjectui64v called with invalid parameter name has generated error "
960 << glu::getErrorStr(error) << ", however GL_INVALID_ENUM was expected." << tcu::TestLog::EndMessage;
961
962 is_ok = false;
963 }
964 }
965 catch (...)
966 {
967 is_error = true;
968 }
969
970 /* Releasing objects. */
971 if (query)
972 {
973 gl.deleteQueries(1, &query);
974 }
975
976 if (buffer)
977 {
978 gl.deleteBuffers(1, &buffer);
979 }
980
981 /* Error cleanup. */
982 while (gl.getError())
983 ;
984
985 if (is_error)
986 {
987 throw 0;
988 }
989
990 return is_ok;
991 }
992
993 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
994 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
995 * INVALID_OPERATION error if the query writes to a buffer object, and the
996 * specified buffer offset would cause data to be written beyond the bounds
997 * of that buffer object.
998 *
999 * @return True if test succeded, false otherwise.
1000 */
testBufferOverflow()1001 bool ErrorsTest::testBufferOverflow()
1002 {
1003 /* Shortcut for GL functionality. */
1004 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1005
1006 /* Default result. */
1007 bool is_ok = true;
1008 bool is_error = false;
1009
1010 /* Test's objects. */
1011 glw::GLuint buffer = 0;
1012 glw::GLuint query = 0;
1013
1014 try
1015 {
1016 /* Creating buffer for the test. */
1017 gl.genBuffers(1, &buffer);
1018 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
1019
1020 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
1021 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
1022
1023 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
1024 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
1025
1026 /* Create query object for the test. */
1027 gl.createQueries(s_targets[0], 1, &query);
1028 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
1029
1030 /* Test query of buffer overflow (integer version). */
1031 m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));
1032
1033 glw::GLenum error = gl.getError();
1034
1035 if (GL_INVALID_OPERATION != error)
1036 {
1037 m_context.getTestContext().getLog()
1038 << tcu::TestLog::Message
1039 << "glGetQueryBufferObjectiv which could generate buffers overflow generated error "
1040 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
1041 << tcu::TestLog::EndMessage;
1042
1043 is_ok = false;
1044 }
1045
1046 /* Test query of buffer overflow (unsigned integer version). */
1047 m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));
1048
1049 error = gl.getError();
1050
1051 if (GL_INVALID_OPERATION != error)
1052 {
1053 m_context.getTestContext().getLog()
1054 << tcu::TestLog::Message
1055 << "glGetQueryBufferObjectuiv which could generate buffers overflow generated error "
1056 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
1057 << tcu::TestLog::EndMessage;
1058
1059 is_ok = false;
1060 }
1061
1062 /* Test query of buffer overflow (64-bit integer version). */
1063 m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));
1064
1065 error = gl.getError();
1066
1067 if (GL_INVALID_OPERATION != error)
1068 {
1069 m_context.getTestContext().getLog()
1070 << tcu::TestLog::Message
1071 << "glGetQueryBufferObjecti64v which could generate buffers overflow generated error "
1072 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
1073 << tcu::TestLog::EndMessage;
1074
1075 is_ok = false;
1076 }
1077
1078 /* Test query of buffer overflow (64-bit unsigned integer version). */
1079 m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, sizeof(glw::GLint64));
1080
1081 error = gl.getError();
1082
1083 if (GL_INVALID_OPERATION != error)
1084 {
1085 m_context.getTestContext().getLog()
1086 << tcu::TestLog::Message
1087 << "glGetQueryBufferObjectui64v which could generate buffers overflow generated error "
1088 << glu::getErrorStr(error) << ", however GL_INVALID_OPERATION was expected."
1089 << tcu::TestLog::EndMessage;
1090
1091 is_ok = false;
1092 }
1093 }
1094 catch (...)
1095 {
1096 is_error = true;
1097 }
1098
1099 /* Releasing objects. */
1100 if (query)
1101 {
1102 gl.deleteQueries(1, &query);
1103 }
1104
1105 if (buffer)
1106 {
1107 gl.deleteBuffers(1, &buffer);
1108 }
1109
1110 /* Error cleanup. */
1111 while (gl.getError())
1112 ;
1113
1114 if (is_error)
1115 {
1116 throw 0;
1117 }
1118
1119 return is_ok;
1120 }
1121
1122 /** @brief Check that GetQueryBufferObjectiv, GetQueryBufferObjectuiv,
1123 * GetQueryBufferObjecti64v and GetQueryBufferObjectui64v generate
1124 * INVALID_VALUE error if <offset> is negative.
1125 *
1126 * @return True if test succeded, false otherwise.
1127 */
testBufferNegativeOffset()1128 bool ErrorsTest::testBufferNegativeOffset()
1129 {
1130 /* Shortcut for GL functionality. */
1131 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1132
1133 /* Default result. */
1134 bool is_ok = true;
1135 bool is_error = false;
1136
1137 /* Test's objects. */
1138 glw::GLuint buffer = 0;
1139 glw::GLuint query = 0;
1140
1141 try
1142 {
1143 /* Creating buffer for the test. */
1144 gl.genBuffers(1, &buffer);
1145 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
1146
1147 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
1148 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
1149
1150 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
1151 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
1152
1153 /* Create query object for the test. */
1154 gl.createQueries(s_targets[0], 1, &query);
1155 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateQueries have failed");
1156
1157 /* Test query with negative offset (integer version). */
1158 m_pGetQueryBufferObjectiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);
1159
1160 glw::GLenum error = gl.getError();
1161
1162 if (GL_INVALID_VALUE != error)
1163 {
1164 m_context.getTestContext().getLog()
1165 << tcu::TestLog::Message << "glGetQueryBufferObjectiv called with negative offset generated error "
1166 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;
1167
1168 is_ok = false;
1169 }
1170
1171 /* Test query with negative offset (unsigned integer version). */
1172 m_pGetQueryBufferObjectuiv(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);
1173
1174 error = gl.getError();
1175
1176 if (GL_INVALID_VALUE != error)
1177 {
1178 m_context.getTestContext().getLog()
1179 << tcu::TestLog::Message << "glGetQueryBufferObjectuiv called with negative offset generated error "
1180 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;
1181
1182 is_ok = false;
1183 }
1184
1185 /* Test query with negative offset (64-bit integer version). */
1186 m_pGetQueryBufferObjecti64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);
1187
1188 error = gl.getError();
1189
1190 if (GL_INVALID_VALUE != error)
1191 {
1192 m_context.getTestContext().getLog()
1193 << tcu::TestLog::Message << "glGetQueryBufferObjecti64v called with negative offset generated error "
1194 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;
1195
1196 is_ok = false;
1197 }
1198
1199 /* Test query with negative offset (64-bit unsigned integer version). */
1200 m_pGetQueryBufferObjectui64v(query, buffer, GL_QUERY_RESULT_AVAILABLE, -1);
1201
1202 error = gl.getError();
1203
1204 if (GL_INVALID_VALUE != error)
1205 {
1206 m_context.getTestContext().getLog()
1207 << tcu::TestLog::Message << "glGetQueryBufferObjectui64v called with negative offset generated error "
1208 << glu::getErrorStr(error) << ", however GL_INVALID_VALUE was expected." << tcu::TestLog::EndMessage;
1209
1210 is_ok = false;
1211 }
1212 }
1213 catch (...)
1214 {
1215 is_error = true;
1216 }
1217
1218 /* Releasing objects. */
1219 if (query)
1220 {
1221 gl.deleteQueries(1, &query);
1222 }
1223
1224 if (buffer)
1225 {
1226 gl.deleteBuffers(1, &buffer);
1227 }
1228
1229 /* Error cleanup. */
1230 while (gl.getError())
1231 ;
1232
1233 if (is_error)
1234 {
1235 throw 0;
1236 }
1237
1238 return is_ok;
1239 }
1240
1241 /** @brief Check if argument is one of the target names:
1242 * - SAMPLES_PASSED,
1243 * - TIME_ELAPSED,
1244 * - PRIMITIVES_GENERATED,
1245 * - TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN.
1246 *
1247 * @param [in] maybe_target Target to be checked.
1248 *
1249 * @return True if argument is one of the listed targets, false otherwise.
1250 */
isTarget(glw::GLenum maybe_target)1251 bool ErrorsTest::isTarget(glw::GLenum maybe_target)
1252 {
1253 for (glw::GLuint i = 0; i < s_targets_count; ++i)
1254 {
1255 if (maybe_target == s_targets[i])
1256 {
1257 return true;
1258 }
1259 }
1260
1261 return false;
1262 }
1263
1264 /** @brief Check if argument is one of the parameter names:
1265 * - QUERY_RESULT,
1266 * - QUERY_RESULT_AVAILABLE,
1267 * - QUERY_RESULT_NO_WAIT,
1268 * - QUERY_TARGET.
1269 *
1270 * @param [in] maybe_pname Parameter name to be checked.
1271 *
1272 * @return True if argument is one of the listed parameters, false otherwise.
1273 */
isParameterName(glw::GLenum maybe_pname)1274 bool ErrorsTest::isParameterName(glw::GLenum maybe_pname)
1275 {
1276 glw::GLenum pnames[] = { GL_QUERY_RESULT, GL_QUERY_RESULT_AVAILABLE, GL_QUERY_RESULT_NO_WAIT, GL_QUERY_TARGET };
1277 glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);
1278
1279 for (glw::GLuint i = 0; i < pnames_count; ++i)
1280 {
1281 if (maybe_pname == pnames[i])
1282 {
1283 return true;
1284 }
1285 }
1286
1287 return false;
1288 }
1289
1290 /** Targets to be tested. */
1291 const glw::GLenum ErrorsTest::s_targets[] = {
1292 GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TIME_ELAPSED,
1293 GL_TIMESTAMP, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
1294 };
1295
1296 /** Names of targets to be tested. */
1297 const glw::GLchar* ErrorsTest::s_target_names[] = {
1298 "GL_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED", "GL_ANY_SAMPLES_PASSED_CONSERVATIVE", "GL_TIME_ELAPSED",
1299 "GL_TIMESTAMP", "GL_PRIMITIVES_GENERATED", "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"
1300 };
1301
1302 /** Number of targets. */
1303 const glw::GLuint ErrorsTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]);
1304
1305 /******************************** Functional Test Implementation ********************************/
1306
1307 /** @brief Functional Test constructor.
1308 *
1309 * @param [in] context OpenGL context.
1310 */
FunctionalTest(deqp::Context & context)1311 FunctionalTest::FunctionalTest(deqp::Context& context)
1312 : deqp::TestCase(context, "queries_functional", "Queries Functional Test")
1313 , m_pGetQueryBufferObjectiv(DE_NULL)
1314 , m_pGetQueryBufferObjectuiv(DE_NULL)
1315 , m_pGetQueryBufferObjecti64v(DE_NULL)
1316 , m_pGetQueryBufferObjectui64v(DE_NULL)
1317 , m_fbo(0)
1318 , m_rbo(0)
1319 , m_vao(0)
1320 , m_bo_query(0)
1321 , m_bo_xfb(0)
1322 , m_qo(DE_NULL)
1323 , m_po(0)
1324 {
1325 /* Intentionally left blank. */
1326 }
1327
1328 /** @brief Do comparison (a == b).
1329 *
1330 * @tparam Type of the values to be compared.
1331 *
1332 * @param [in] a First value to be compared.
1333 * @param [in] b Second value to be compared.
1334 *
1335 * @return Result of the comparison.
1336 */
1337 template <typename T>
equal(T a,T b)1338 bool FunctionalTest::equal(T a, T b)
1339 {
1340 return (a == b);
1341 }
1342
1343 /** @brief Do comparison (a < b).
1344 *
1345 * @tparam Type of the values to be compared.
1346 *
1347 * @param [in] a First value to be compared.
1348 * @param [in] b Second value to be compared.
1349 *
1350 * @return Result of the comparison.
1351 */
1352 template <typename T>
less(T a,T b)1353 bool FunctionalTest::less(T a, T b)
1354 {
1355 return (a < b);
1356 }
1357
1358 /** @brief Template specialization of glGetQueryBufferObject* function for GLint.
1359 * This is pass through function to glGetQueryBufferObjectiv
1360 *
1361 * @param [in] id Query object identifier.
1362 * @param [in] buffer Buffer object identifier.
1363 * @param [in] pname Parameter name to be queried.
1364 * @param [in] offset Offset of the buffer to be saved at.
1365 */
1366 template <>
GetQueryBufferObject(glw::GLuint id,glw::GLuint buffer,glw::GLenum pname,glw::GLintptr offset)1367 void FunctionalTest::GetQueryBufferObject<glw::GLint>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
1368 glw::GLintptr offset)
1369 {
1370 m_pGetQueryBufferObjectiv(id, buffer, pname, offset);
1371 }
1372
1373 /** @brief Template specialization of glGetQueryBufferObject* function for GLuint.
1374 * This is pass through function to glGetQueryBufferObjectuiv
1375 *
1376 * @param [in] id Query object identifier.
1377 * @param [in] buffer Buffer object identifier.
1378 * @param [in] pname Parameter name to be queried.
1379 * @param [in] offset Offset of the buffer to be saved at.
1380 */
1381 template <>
GetQueryBufferObject(glw::GLuint id,glw::GLuint buffer,glw::GLenum pname,glw::GLintptr offset)1382 void FunctionalTest::GetQueryBufferObject<glw::GLuint>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
1383 glw::GLintptr offset)
1384 {
1385 m_pGetQueryBufferObjectuiv(id, buffer, pname, offset);
1386 }
1387
1388 /** @brief Template specialization of glGetQueryBufferObject* function for GLint64.
1389 * This is pass through function to glGetQueryBufferObjecti64v
1390 *
1391 * @param [in] id Query object identifier.
1392 * @param [in] buffer Buffer object identifier.
1393 * @param [in] pname Parameter name to be queried.
1394 * @param [in] offset Offset of the buffer to be saved at.
1395 */
1396 template <>
GetQueryBufferObject(glw::GLuint id,glw::GLuint buffer,glw::GLenum pname,glw::GLintptr offset)1397 void FunctionalTest::GetQueryBufferObject<glw::GLint64>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
1398 glw::GLintptr offset)
1399 {
1400 m_pGetQueryBufferObjecti64v(id, buffer, pname, offset);
1401 }
1402
1403 /** @brief Template specialization of glGetQueryBufferObject* function for GLuint64.
1404 * This is pass through function to glGetQueryBufferObjectui64v
1405 *
1406 * @param [in] id Query object identifier.
1407 * @param [in] buffer Buffer object identifier.
1408 * @param [in] pname Parameter name to be queried.
1409 * @param [in] offset Offset of the buffer to be saved at.
1410 */
1411 template <>
GetQueryBufferObject(glw::GLuint id,glw::GLuint buffer,glw::GLenum pname,glw::GLintptr offset)1412 void FunctionalTest::GetQueryBufferObject<glw::GLuint64>(glw::GLuint id, glw::GLuint buffer, glw::GLenum pname,
1413 glw::GLintptr offset)
1414 {
1415 m_pGetQueryBufferObjectui64v(id, buffer, pname, offset);
1416 }
1417
1418 /** @brief Function template fetches query result to buffer object using
1419 * glGetQueryBufferObject* function (selected on the basis of template parameter).
1420 * Then buffer is mapped and the result is compared with expected_value using comparison function.
1421 *
1422 * @tparam Templated type of fetched data.
1423 * It shall be one of glw::GL[u]int[64].
1424 *
1425 * @param [in] query Query object to be queried.
1426 * @param [in] pname Parameter name to be queried.
1427 * @param [in] expected_value Reference value to be compared.
1428 * @param [in] comparison Comparison function pointer.
1429 * Comparsion function shall NOT throw.
1430 *
1431 * @note The function may throw if unexpected error has occured.
1432 *
1433 * @return True if comparison succeeded, false otherwise.
1434 */
1435 template <typename T>
checkQueryBufferObject(glw::GLuint query,glw::GLenum pname,T expected_value,bool (* comparison)(T,T))1436 bool FunctionalTest::checkQueryBufferObject(glw::GLuint query, glw::GLenum pname, T expected_value,
1437 bool (*comparison)(T, T))
1438 {
1439 /* Shortcut for GL functionality. */
1440 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1441
1442 /* Default result. */
1443 bool is_ok = true;
1444
1445 /* Saving results to buffer. */
1446 GetQueryBufferObject<T>(query, m_bo_query, pname, 0);
1447 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryBufferObject* have failed");
1448
1449 /* Mapping buffer to user space. */
1450 T* value = (T*)gl.mapBuffer(GL_QUERY_BUFFER, GL_READ_ONLY);
1451 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer have failed");
1452
1453 /* Doing test. */
1454 if (!comparison(expected_value, *value))
1455 {
1456 is_ok = false;
1457 }
1458
1459 /* Cleanup. */
1460 gl.unmapBuffer(GL_QUERY_BUFFER);
1461 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer have failed");
1462
1463 /* Return test result. */
1464 return is_ok;
1465 }
1466
1467 /** @brief Iterate Functional Test cases.
1468 *
1469 * @return Iteration result.
1470 */
iterate()1471 tcu::TestNode::IterateResult FunctionalTest::iterate()
1472 {
1473 /* Shortcut for GL functionality. */
1474 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1475
1476 /* Get context setup. */
1477 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1478 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1479
1480 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1481 {
1482 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1483
1484 return STOP;
1485 }
1486
1487 /* Fetching access point to GL functions. */
1488 m_pGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectiv;
1489 m_pGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectuiv;
1490 m_pGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjecti64v;
1491 m_pGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECT)gl.getQueryBufferObjectui64v;
1492
1493 /* Running tests. */
1494 bool is_ok = true;
1495 bool is_error = false;
1496
1497 try
1498 {
1499 if ((DE_NULL == m_pGetQueryBufferObjectiv) || (DE_NULL == m_pGetQueryBufferObjectuiv) ||
1500 (DE_NULL == m_pGetQueryBufferObjecti64v) || (DE_NULL == m_pGetQueryBufferObjectui64v))
1501 {
1502 m_context.getTestContext().getLog()
1503 << tcu::TestLog::Message << "Test could not get the pointers for glGetQueryBufferObject* functions."
1504 << tcu::TestLog::EndMessage;
1505
1506 throw 0;
1507 }
1508
1509 prepareView();
1510 prepareVertexArray();
1511 prepareBuffers();
1512 prepareQueries();
1513 prepareProgram();
1514
1515 draw();
1516
1517 /* Make sure that framebuffer and transform feedback buffer are filled with expectd data. */
1518 is_ok &= checkView();
1519 is_ok &= checkXFB();
1520
1521 /* Make comparisons for each query object. */
1522 for (glw::GLuint i = 0; i < s_targets_count; ++i)
1523 {
1524 /* Checking targets. */
1525 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
1526 &FunctionalTest::equal<glw::GLint>);
1527 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
1528 &FunctionalTest::equal<glw::GLuint>);
1529 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
1530 &FunctionalTest::equal<glw::GLint64>);
1531 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_TARGET, s_targets[i],
1532 &FunctionalTest::equal<glw::GLuint64>);
1533
1534 /* Checking result availability. */
1535 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
1536 &FunctionalTest::equal<glw::GLint>);
1537 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
1538 &FunctionalTest::equal<glw::GLuint>);
1539 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
1540 &FunctionalTest::equal<glw::GLint64>);
1541 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_AVAILABLE, GL_TRUE,
1542 &FunctionalTest::equal<glw::GLuint64>);
1543
1544 if (GL_TIME_ELAPSED == s_targets[i])
1545 {
1546 /* Checking result. */
1547 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT, (glw::GLint)s_results[i],
1548 &FunctionalTest::less<glw::GLint>);
1549 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint)s_results[i],
1550 &FunctionalTest::less<glw::GLuint>);
1551 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLint64)s_results[i],
1552 &FunctionalTest::less<glw::GLint64>);
1553 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint64)s_results[i],
1554 &FunctionalTest::less<glw::GLuint64>);
1555
1556 /* Checking result (no-wait). */
1557 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint)s_results[i],
1558 &FunctionalTest::less<glw::GLint>);
1559 is_ok &= checkQueryBufferObject<glw::GLuint>(
1560 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint)s_results[i], &FunctionalTest::less<glw::GLuint>);
1561 is_ok &= checkQueryBufferObject<glw::GLint64>(
1562 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint64)s_results[i], &FunctionalTest::less<glw::GLint64>);
1563 is_ok &=
1564 checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint64)s_results[i],
1565 &FunctionalTest::less<glw::GLuint64>);
1566 }
1567 else
1568 {
1569 /* Checking result. */
1570 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT, (glw::GLint)s_results[i],
1571 &FunctionalTest::equal<glw::GLint>);
1572 is_ok &= checkQueryBufferObject<glw::GLuint>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint)s_results[i],
1573 &FunctionalTest::equal<glw::GLuint>);
1574 is_ok &= checkQueryBufferObject<glw::GLint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLint64)s_results[i],
1575 &FunctionalTest::equal<glw::GLint64>);
1576 is_ok &= checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT, (glw::GLuint64)s_results[i],
1577 &FunctionalTest::equal<glw::GLuint64>);
1578
1579 /* Checking result (no-wait). */
1580 is_ok &= checkQueryBufferObject<glw::GLint>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint)s_results[i],
1581 &FunctionalTest::equal<glw::GLint>);
1582 is_ok &= checkQueryBufferObject<glw::GLuint>(
1583 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint)s_results[i], &FunctionalTest::equal<glw::GLuint>);
1584 is_ok &= checkQueryBufferObject<glw::GLint64>(
1585 m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLint64)s_results[i], &FunctionalTest::equal<glw::GLint64>);
1586 is_ok &=
1587 checkQueryBufferObject<glw::GLuint64>(m_qo[i], GL_QUERY_RESULT_NO_WAIT, (glw::GLuint64)s_results[i],
1588 &FunctionalTest::equal<glw::GLuint64>);
1589 }
1590 }
1591 }
1592 catch (...)
1593 {
1594 is_ok = false;
1595 is_error = true;
1596 }
1597
1598 /* Clean up. */
1599 clean();
1600
1601 /* Result's setup. */
1602 if (is_ok)
1603 {
1604 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1605 }
1606 else
1607 {
1608 if (is_error)
1609 {
1610 m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1611 }
1612 else
1613 {
1614 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1615 }
1616 }
1617
1618 return STOP;
1619 }
1620
1621 /** @brief Function prepares framebuffer with RGBA8 color attachment.
1622 * Viewport is set up. Content of the framebuffer is cleared.
1623 *
1624 * @note The function may throw if unexpected error has occured.
1625 */
prepareView()1626 void FunctionalTest::prepareView()
1627 {
1628 /* Shortcut for GL functionality. */
1629 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1630
1631 /* Prepare framebuffer. */
1632 gl.genFramebuffers(1, &m_fbo);
1633 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
1634
1635 gl.genRenderbuffers(1, &m_rbo);
1636 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
1637
1638 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1639 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
1640
1641 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
1642 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
1643
1644 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1 /* x size */, 1 /* y size */);
1645 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
1646
1647 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
1648 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
1649
1650 if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
1651 {
1652 throw 0;
1653 }
1654
1655 gl.viewport(0, 0, 1, 1);
1656 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
1657
1658 /* Clear framebuffer's content. */
1659 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
1660 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
1661
1662 gl.clear(GL_COLOR_BUFFER_BIT);
1663 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
1664 }
1665
1666 /** @brief Function creates and binds empty vertex array.
1667 *
1668 * @note The function may throw if unexpected error has occured.
1669 */
prepareVertexArray()1670 void FunctionalTest::prepareVertexArray()
1671 {
1672 /* Shortcut for GL functionality. */
1673 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1674
1675 /* Creating and binding VAO. */
1676 gl.genVertexArrays(1, &m_vao);
1677 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed");
1678
1679 gl.bindVertexArray(m_vao);
1680 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray have failed");
1681 }
1682
1683 /** @brief Function creates buffers for query and transform feedback data storage.
1684 * The storage is allocated and buffers are bound to QUERY_BUFFER and
1685 * TRANSFORM_FEEDBACK_BUFFER binding points respectively.
1686 *
1687 * @note The function may throw if unexpected error has occured.
1688 */
prepareBuffers()1689 void FunctionalTest::prepareBuffers()
1690 {
1691 /* Shortcut for GL functionality. */
1692 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1693
1694 /* Buffer for storing query's result. */
1695 gl.genBuffers(1, &m_bo_query);
1696 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
1697
1698 gl.bindBuffer(GL_QUERY_BUFFER, m_bo_query);
1699 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
1700
1701 gl.bufferData(GL_QUERY_BUFFER, sizeof(glw::GLint64), DE_NULL, GL_DYNAMIC_COPY);
1702 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
1703
1704 /* Buffer for storing transform feedback results. */
1705 gl.genBuffers(1, &m_bo_xfb);
1706 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
1707
1708 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
1709 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
1710
1711 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
1712 3 /* number of vertices per triangle */ * 2 /* number of triangles */ * sizeof(glw::GLint), DE_NULL,
1713 GL_DYNAMIC_COPY);
1714 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
1715
1716 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
1717 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase have failed");
1718 }
1719
1720 /** @brief Function creates array of query objects using DSA-style method.
1721 *
1722 * @note The function may throw if unexpected error has occured.
1723 */
prepareQueries()1724 void FunctionalTest::prepareQueries()
1725 {
1726 /* Shortcut for GL functionality. */
1727 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1728
1729 /* Allocating memory for queries array. */
1730 m_qo = new glw::GLuint[s_targets_count];
1731
1732 if (DE_NULL == m_qo)
1733 {
1734 throw 0;
1735 }
1736
1737 /* Creating query object for each target. */
1738 for (glw::GLuint i = 0; i < s_targets_count; ++i)
1739 {
1740 gl.createQueries(s_targets[i], 1, &m_qo[i]);
1741
1742 /* Error checking. */
1743 if (GL_NO_ERROR != gl.getError())
1744 {
1745 /* Remove previous. */
1746 if (i > 0)
1747 {
1748 gl.deleteQueries(i, m_qo);
1749 }
1750
1751 /* Deallocate storage. */
1752 delete[] m_qo;
1753
1754 m_qo = DE_NULL;
1755
1756 /* Signalise test failure. */
1757 throw 0;
1758 }
1759 }
1760 }
1761
1762 /** @brief Function builds test's GLSL program.
1763 * If succeded, the program will be set to be used.
1764 *
1765 * @note The function may throw if unexpected error has occured.
1766 */
prepareProgram()1767 void FunctionalTest::prepareProgram()
1768 {
1769 /* Shortcut for GL functionality */
1770 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1771
1772 struct Shader
1773 {
1774 glw::GLchar const* const source;
1775 glw::GLenum const type;
1776 glw::GLuint id;
1777 } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
1778
1779 glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
1780
1781 try
1782 {
1783 /* Create program. */
1784 m_po = gl.createProgram();
1785 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
1786
1787 /* Shader compilation. */
1788
1789 for (glw::GLuint i = 0; i < shader_count; ++i)
1790 {
1791 if (DE_NULL != shader[i].source)
1792 {
1793 shader[i].id = gl.createShader(shader[i].type);
1794
1795 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
1796
1797 gl.attachShader(m_po, shader[i].id);
1798
1799 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
1800
1801 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
1802
1803 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
1804
1805 gl.compileShader(shader[i].id);
1806
1807 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
1808
1809 glw::GLint status = GL_FALSE;
1810
1811 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
1812 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1813
1814 if (GL_FALSE == status)
1815 {
1816 glw::GLint log_size = 0;
1817 gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
1818 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1819
1820 glw::GLchar* log_text = new glw::GLchar[log_size];
1821
1822 gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
1823
1824 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
1825 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
1826 << "\n"
1827 << "Shader compilation error log:\n"
1828 << log_text << "\n"
1829 << "Shader source code:\n"
1830 << shader[i].source << "\n"
1831 << tcu::TestLog::EndMessage;
1832
1833 delete[] log_text;
1834
1835 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
1836
1837 throw 0;
1838 }
1839 }
1840 }
1841
1842 /* Transform Feedback setup. */
1843 gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying_name, GL_INTERLEAVED_ATTRIBS);
1844 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1845
1846 /* Link. */
1847 gl.linkProgram(m_po);
1848
1849 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1850
1851 glw::GLint status = GL_FALSE;
1852
1853 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
1854
1855 if (GL_TRUE == status)
1856 {
1857 for (glw::GLuint i = 0; i < shader_count; ++i)
1858 {
1859 if (shader[i].id)
1860 {
1861 gl.detachShader(m_po, shader[i].id);
1862
1863 GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
1864 }
1865 }
1866 }
1867 else
1868 {
1869 glw::GLint log_size = 0;
1870
1871 gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
1872
1873 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
1874
1875 glw::GLchar* log_text = new glw::GLchar[log_size];
1876
1877 gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
1878
1879 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
1880 << log_text << "\n"
1881 << tcu::TestLog::EndMessage;
1882
1883 delete[] log_text;
1884
1885 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
1886
1887 throw 0;
1888 }
1889 }
1890 catch (...)
1891 {
1892 if (m_po)
1893 {
1894 gl.deleteProgram(m_po);
1895
1896 m_po = 0;
1897 }
1898 }
1899
1900 for (glw::GLuint i = 0; i < shader_count; ++i)
1901 {
1902 if (0 != shader[i].id)
1903 {
1904 gl.deleteShader(shader[i].id);
1905
1906 shader[i].id = 0;
1907 }
1908 }
1909
1910 if (m_po)
1911 {
1912 gl.useProgram(m_po);
1913 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
1914 }
1915
1916 if (0 == m_po)
1917 {
1918 throw 0;
1919 }
1920 }
1921
1922 /** @brief Function draws full screen quad. Queries are measured during the process.
1923 * Also, transform feedback data is captured.
1924 *
1925 * @note The function may throw if unexpected error has occured.
1926 */
draw()1927 void FunctionalTest::draw()
1928 {
1929 /* Shortcut for GL functionality. */
1930 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1931
1932 /* Start queries. */
1933 for (glw::GLuint i = 0; i < s_targets_count; ++i)
1934 {
1935 gl.beginQuery(s_targets[i], m_qo[i]);
1936 }
1937
1938 /* Start XFB. */
1939 gl.beginTransformFeedback(GL_TRIANGLES);
1940
1941 /* Draw full screen quad. */
1942 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
1943
1944 /* Finish XFB. */
1945 gl.endTransformFeedback();
1946
1947 /* Finish queries. */
1948 for (glw::GLuint i = 0; i < s_targets_count; ++i)
1949 {
1950 gl.endQuery(s_targets[i]);
1951 }
1952
1953 /* Make sure OpenGL finished drawing. */
1954 gl.finish();
1955
1956 /* Error checking. */
1957 GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing function have failed.");
1958 }
1959
1960 /** @brief Check that framebuffer is filled with red color.
1961 */
checkView()1962 bool FunctionalTest::checkView()
1963 {
1964 /* Shortcut for GL functionality. */
1965 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1966
1967 /* Fetch framebuffer data. */
1968 glw::GLubyte pixel[4] = { 0 };
1969
1970 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
1971 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
1972
1973 /* Comparison with expected values. */
1974 if ((255 != pixel[0]) || (0 != pixel[1]) || (0 != pixel[2]) || (255 != pixel[3]))
1975 {
1976 m_context.getTestContext().getLog()
1977 << tcu::TestLog::Message << "Frameuffer content (" << (unsigned int)pixel[0] << ", "
1978 << (unsigned int)pixel[1] << ", " << (unsigned int)pixel[2] << ", " << (unsigned int)pixel[3]
1979 << ") is different than expected (255, 0, 0, 255)." << tcu::TestLog::EndMessage;
1980
1981 return false;
1982 }
1983
1984 return true;
1985 }
1986
1987 /** @brief Check that transform feedback buffer
1988 * contains values representing quad.
1989 */
checkXFB()1990 bool FunctionalTest::checkXFB()
1991 {
1992 /* Shortcut for GL functionality */
1993 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1994
1995 /* Default result. */
1996 bool is_ok = true;
1997
1998 /* Mapping buffer object to the user-space. */
1999 glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
2000 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
2001
2002 if ((0 != buffer[0]) || (1 != buffer[1]) || (2 != buffer[2]) ||
2003
2004 (2 != buffer[3]) || (1 != buffer[4]) || (3 != buffer[5]))
2005 {
2006 is_ok = false;
2007 }
2008
2009 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2010 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
2011
2012 return is_ok;
2013 }
2014
2015 /** @brief Release all created objects.
2016 */
clean()2017 void FunctionalTest::clean()
2018 {
2019 /* Shortcut for GL functionality. */
2020 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2021
2022 /* Releasing queries. */
2023 if (DE_NULL != m_qo)
2024 {
2025 gl.deleteQueries(s_targets_count, m_qo);
2026
2027 delete[] m_qo;
2028
2029 m_qo = DE_NULL;
2030 }
2031
2032 /* Release framebuffer. */
2033 if (m_fbo)
2034 {
2035 gl.deleteFramebuffers(1, &m_fbo);
2036
2037 m_fbo = 0;
2038 }
2039
2040 /* Release renderbuffer. */
2041 if (m_rbo)
2042 {
2043 gl.deleteRenderbuffers(1, &m_rbo);
2044
2045 m_rbo = 0;
2046 }
2047
2048 /* Release vertex array object. */
2049 if (m_vao)
2050 {
2051 gl.deleteVertexArrays(1, &m_vao);
2052
2053 m_vao = 0;
2054 }
2055
2056 /* Release buffer object for storing queries' results. */
2057 if (m_bo_query)
2058 {
2059 gl.deleteBuffers(1, &m_bo_query);
2060
2061 m_bo_query = 0;
2062 }
2063
2064 /* Release transform feedback buffer. */
2065 if (m_bo_xfb)
2066 {
2067 gl.deleteBuffers(1, &m_bo_xfb);
2068
2069 m_bo_xfb = 0;
2070 }
2071
2072 /* Release GLSL program. */
2073 if (m_po)
2074 {
2075 gl.useProgram(0);
2076
2077 gl.deleteProgram(m_po);
2078
2079 m_po = 0;
2080 }
2081 }
2082
2083 /** Targets to be tested. */
2084 const glw::GLenum FunctionalTest::s_targets[] = { GL_SAMPLES_PASSED, GL_TIME_ELAPSED, GL_PRIMITIVES_GENERATED,
2085 GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };
2086
2087 /** Expected result for each target. */
2088 const glw::GLint FunctionalTest::s_results[] = { 1, 0, 2, 2 };
2089
2090 /** Number of targets. */
2091 const glw::GLuint FunctionalTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]);
2092
2093 /** Vertex shader source code. */
2094 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n"
2095 "\n"
2096 "out int xfb_result;\n"
2097 "\n"
2098 "void main()\n"
2099 "{\n"
2100 " switch(gl_VertexID)\n"
2101 " {\n"
2102 " case 0:\n"
2103 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
2104 " break;\n"
2105 " case 1:\n"
2106 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
2107 " break;\n"
2108 " case 2:\n"
2109 " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
2110 " break;\n"
2111 " case 3:\n"
2112 " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
2113 " break;\n"
2114 " }\n"
2115 "\n"
2116 " xfb_result = gl_VertexID;\n"
2117 "}\n";
2118
2119 /** Fragment shader source program. */
2120 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n"
2121 "\n"
2122 "out vec4 color;\n"
2123 "\n"
2124 "void main()\n"
2125 "{\n"
2126 " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
2127 "}\n";
2128
2129 /** Name of transform feedback varying in vertex shader. */
2130 const glw::GLchar* FunctionalTest::s_xfb_varying_name = "xfb_result";
2131
2132 /******************************** Reuse Test Implementation ********************************/
2133
2134 /** @brief Reuse Test constructor.
2135 *
2136 * @param [in] context OpenGL context.
2137 */
ReuseTest(deqp::Context & context)2138 ReuseTest::ReuseTest(deqp::Context& context) : deqp::TestCase(context, "queries_reuse", "Query Objects Reuse Test")
2139 {
2140 /* Intentionally left blank. */
2141 }
2142
2143 /** @brief Iterate Reuse Test cases.
2144 *
2145 * @return Iteration result.
2146 */
iterate()2147 tcu::TestNode::IterateResult ReuseTest::iterate()
2148 {
2149 /* Shortcut for GL functionality. */
2150 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2151
2152 /* Get context setup. */
2153 bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2154 bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2155
2156 if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2157 {
2158 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2159
2160 return STOP;
2161 }
2162
2163 /* Running tests. */
2164 bool is_ok = true;
2165
2166 GLuint query_id_a = 0;
2167 GLuint query_id_b = 0;
2168 /* Allocate query object */
2169 gl.genQueries(1, &query_id_a);
2170 /* Associate object with GL_TIMESTAMP */
2171 gl.queryCounter(query_id_a, GL_TIMESTAMP);
2172 /* Deallocate query object */
2173 gl.deleteQueries(1, &query_id_a);
2174
2175 /* Allocate query object again - should result in the same id */
2176 gl.genQueries(1, &query_id_b);
2177 /* Use the id with something else */
2178 gl.beginQuery(GL_TIME_ELAPSED, query_id_b);
2179 if (gl.getError() != 0) /* Crash was reported here. */
2180 is_ok = false;
2181 gl.endQuery(GL_TIME_ELAPSED);
2182 /* Clean up */
2183 gl.deleteQueries(1, &query_id_b);
2184
2185 if (query_id_a != query_id_b)
2186 {
2187 m_context.getTestContext().getLog()
2188 << tcu::TestLog::Message << "Note: Queries got different id:s, so no actual reuse occurred."
2189 << tcu::TestLog::EndMessage;
2190 }
2191
2192 /* Result's setup. */
2193 if (is_ok)
2194 {
2195 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2196 }
2197 else
2198 {
2199 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2200 }
2201
2202 return STOP;
2203 }
2204
2205 } /* Queries namespace. */
2206 } /* DirectStateAccess namespace. */
2207 } /* gl4cts namespace. */
2208