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