• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /* Includes. */
25 #include "gl4cConditionalRenderInvertedTests.hpp"
26 #include "gluContextInfo.hpp"
27 #include "gluDefs.hpp"
28 #include "gluRenderContext.hpp"
29 #include "gluStrUtil.hpp"
30 #include "tcuTestLog.hpp"
31 
32 /******************************** Test Group Implementation       ********************************/
33 
34 /** @brief Context Flush Control tests group constructor.
35  *
36  *  @param [in] context     OpenGL context.
37  */
Tests(deqp::Context & context)38 gl4cts::ConditionalRenderInverted::Tests::Tests(deqp::Context& context)
39 	: TestCaseGroup(context, "conditional_render_inverted", "Conditional Render Inverted Test Suite")
40 {
41 	/* Intentionally left blank */
42 }
43 
44 /** @brief Context Flush Control tests initializer. */
init()45 void gl4cts::ConditionalRenderInverted::Tests::init()
46 {
47 	addChild(new gl4cts::ConditionalRenderInverted::CoverageTest(m_context));
48 	addChild(new gl4cts::ConditionalRenderInverted::FunctionalTest(m_context));
49 }
50 
51 /******************************** Coverage Tests Implementation   ********************************/
52 
53 /** @brief API coverage tests constructor.
54  *
55  *  @param [in] context     OpenGL context.
56  */
CoverageTest(deqp::Context & context)57 gl4cts::ConditionalRenderInverted::CoverageTest::CoverageTest(deqp::Context& context)
58 	: deqp::TestCase(context, "coverage", "Conditional Render Inverted Coverage Test"), m_qo_id(0)
59 {
60 	/* Intentionally left blank. */
61 }
62 
63 /** @brief Iterate API coverage tests.
64  *
65  *  @return Iteration result.
66  */
iterate()67 tcu::TestNode::IterateResult gl4cts::ConditionalRenderInverted::CoverageTest::iterate()
68 {
69 	/* OpenGL support query. */
70 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
71 	bool is_arb_conditional_render_inverted =
72 		m_context.getContextInfo().isExtensionSupported("GL_ARB_conditional_render_inverted");
73 
74 	/* Running tests. */
75 	bool is_ok	= true;
76 	bool is_error = false;
77 
78 	/* This test should only be executed if we're running a GL4.5 context or related extension is available */
79 	try
80 	{
81 		if (is_at_least_gl_45 || is_arb_conditional_render_inverted)
82 		{
83 			/* Prepare common objects. */
84 			createQueryObject();
85 
86 			/* Test cases. */
87 			static const glw::GLenum modes[] = { GL_QUERY_WAIT_INVERTED, GL_QUERY_NO_WAIT_INVERTED,
88 												 GL_QUERY_BY_REGION_WAIT_INVERTED,
89 												 GL_QUERY_BY_REGION_NO_WAIT_INVERTED };
90 
91 			static const glw::GLuint modes_count = sizeof(modes) / sizeof(modes[0]);
92 
93 			/* Iterate over the test cases. */
94 			for (glw::GLuint i = 0; i < modes_count; ++i)
95 			{
96 				is_ok &= test(modes[i]);
97 			}
98 		}
99 	}
100 	catch (...)
101 	{
102 		is_ok	= false;
103 		is_error = true;
104 	}
105 
106 	/* Cleanup. */
107 	clean();
108 
109 	/* Result's setup. */
110 	if (is_ok)
111 	{
112 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
113 	}
114 	else
115 	{
116 		if (is_error)
117 		{
118 			m_context.getTestContext().getLog()
119 				<< tcu::TestLog::Message
120 				<< "Internal error has occured during Conditional Render Inverted Coverage Test."
121 				<< tcu::TestLog::EndMessage;
122 
123 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Test error.");
124 		}
125 		else
126 		{
127 			m_context.getTestContext().getLog() << tcu::TestLog::Message
128 												<< "The Conditional Render Inverted Coverage Test has failed."
129 												<< tcu::TestLog::EndMessage;
130 
131 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
132 		}
133 	}
134 
135 	return STOP;
136 }
137 
138 /** @brief Create query object.
139  */
createQueryObject()140 void gl4cts::ConditionalRenderInverted::CoverageTest::createQueryObject()
141 {
142 	/* Shortcut for GL functionality. */
143 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
144 
145 	/* Create valid query object. */
146 	gl.genQueries(1, &m_qo_id);
147 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries() call failed.");
148 
149 	gl.beginQuery(GL_SAMPLES_PASSED, m_qo_id);
150 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery() call failed.");
151 
152 	gl.endQuery(GL_SAMPLES_PASSED);
153 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery() call failed.");
154 }
155 
156 /** @brief Clean query object and error values.
157  */
clean()158 void gl4cts::ConditionalRenderInverted::CoverageTest::clean()
159 {
160 	/* Shortcut for GL functionality. */
161 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
162 
163 	/* Clean query object. */
164 	gl.deleteQueries(1, &m_qo_id);
165 
166 	m_qo_id = 0;
167 
168 	/* Make sure no errors are left. */
169 	while (gl.getError())
170 		;
171 }
172 
173 /** @brief Test that glBeginConditionalRender accept mode.
174  *
175  *  @param [in] mode    Render condition mode.
176  *
177  *  @return True if glBeginConditionalRender did not generate an error, false otherwise.
178  */
test(glw::GLenum mode)179 bool gl4cts::ConditionalRenderInverted::CoverageTest::test(glw::GLenum mode)
180 {
181 	/* Shortcut for GL functionality. */
182 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
183 
184 	/* Default return value;*/
185 	bool is_no_error = true;
186 
187 	/* Test. */
188 	gl.beginConditionalRender(m_qo_id, mode);
189 
190 	while (GL_NO_ERROR != gl.getError())
191 	{
192 		is_no_error = false;
193 	}
194 
195 	/* Clean up. */
196 	if (is_no_error)
197 	{
198 		gl.endConditionalRender();
199 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndConditionalRender() call failed.");
200 	}
201 
202 	/* Logging. */
203 	if (!is_no_error)
204 	{
205 		m_context.getTestContext().getLog() << tcu::TestLog::Message
206 											<< "glBeginConditionalRender failed when used with mode "
207 											<< Utilities::modeToChars(mode) << "." << tcu::TestLog::EndMessage;
208 	}
209 
210 	/* Return test result. */
211 	return is_no_error;
212 }
213 
214 /******************************** Functional Test Implementation   ********************************/
215 
216 /** @brief Functional test constructor.
217  *
218  *  @param [in] context     OpenGL context.
219  */
FunctionalTest(deqp::Context & context)220 gl4cts::ConditionalRenderInverted::FunctionalTest::FunctionalTest(deqp::Context& context)
221 	: deqp::TestCase(context, "functional", "Conditional Render Inverted Functional Test")
222 	, m_fbo_id(0)
223 	, m_rbo_id(0)
224 	, m_vao_id(0)
225 	, m_po_id(0)
226 	, m_qo_id(0)
227 {
228 	/* Intentionally left blank. */
229 }
230 
231 /** @brief Iterate Functional test cases.
232  *
233  *  @return Iteration result.
234  */
iterate()235 tcu::TestNode::IterateResult gl4cts::ConditionalRenderInverted::FunctionalTest::iterate()
236 {
237 	/* OpenGL support query. */
238 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
239 	bool is_arb_conditional_render_inverted =
240 		m_context.getContextInfo().isExtensionSupported("GL_ARB_conditional_render_inverted");
241 
242 	/* Running tests. */
243 	bool is_ok	= true;
244 	bool is_error = false;
245 
246 	/* This test should only be executed if we're running a GL4.5 context or related extension is available */
247 	try
248 	{
249 		if (is_at_least_gl_45 || is_arb_conditional_render_inverted)
250 		{
251 			/* Test cases. */
252 			static const bool render_cases[] = { false, true };
253 
254 			static const glw::GLuint render_cases_count = sizeof(render_cases) / sizeof(render_cases[0]);
255 
256 			static const glw::GLenum query_cases[] = { GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED };
257 
258 			static const glw::GLuint query_cases_count = sizeof(query_cases) / sizeof(query_cases[0]);
259 
260 			static const glw::GLenum modes[] = { GL_QUERY_WAIT_INVERTED, GL_QUERY_NO_WAIT_INVERTED,
261 												 GL_QUERY_BY_REGION_WAIT_INVERTED,
262 												 GL_QUERY_BY_REGION_NO_WAIT_INVERTED };
263 
264 			static const glw::GLuint modes_count = sizeof(modes) / sizeof(modes[0]);
265 
266 			/* Creating common objects. */
267 			createProgram();
268 			createView();
269 			createVertexArrayObject();
270 
271 			/* Iterating over test cases. */
272 			for (glw::GLuint i = 0; i < render_cases_count; ++i)
273 			{
274 				for (glw::GLuint j = 0; j < query_cases_count; ++j)
275 				{
276 					for (glw::GLuint k = 0; k < modes_count; ++k)
277 					{
278 						createQueryObject();
279 
280 						setupColor(1.f);
281 						setupPassSwitch(render_cases[i]);
282 						clearView();
283 						draw(false, query_cases[j]);
284 
285 						if (render_cases[i] == fragmentsPassed())
286 						{
287 							setupColor(0.f);
288 							setupPassSwitch(true);
289 							draw(true, modes[k]);
290 
291 							glw::GLfloat expected_value = (render_cases[i]) ? 1.f : 0.f;
292 							glw::GLfloat resulted_value = readPixel();
293 
294 							if (de::abs(expected_value - resulted_value) > 0.0078125f /* Precission (1/128) */)
295 							{
296 								m_context.getTestContext().getLog()
297 									<< tcu::TestLog::Message << "The functional test's expected value ("
298 									<< expected_value << ") is different than resulted value (" << resulted_value
299 									<< "). The tested mode was " << Utilities::modeToChars(modes[k])
300 									<< ". Query was done for target " << Utilities::queryTargetToChars(query_cases[j])
301 									<< ", and the test was prepared to " << ((render_cases[i]) ? "pass" : "discard")
302 									<< " all fragments." << tcu::TestLog::EndMessage;
303 
304 								is_ok = false;
305 							}
306 						}
307 						else
308 						{
309 							is_ok = false;
310 						}
311 
312 						cleanQueryObject();
313 					}
314 				}
315 			}
316 		}
317 	}
318 	catch (...)
319 	{
320 		is_ok	= false;
321 		is_error = true;
322 
323 		cleanQueryObject();
324 	}
325 
326 	/* Clean-up. */
327 	cleanProgramViewAndVAO();
328 
329 	/* Result's setup. */
330 	if (is_ok)
331 	{
332 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
333 	}
334 	else
335 	{
336 		if (is_error)
337 		{
338 			m_context.getTestContext().getLog()
339 				<< tcu::TestLog::Message
340 				<< "Internal error has occured during Conditional Render Inverted Functional Test."
341 				<< tcu::TestLog::EndMessage;
342 
343 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Test error.");
344 		}
345 		else
346 		{
347 			m_context.getTestContext().getLog() << tcu::TestLog::Message
348 												<< "The Conditional Render Inverted Functional Test has failed."
349 												<< tcu::TestLog::EndMessage;
350 
351 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail.");
352 		}
353 	}
354 
355 	return STOP;
356 }
357 
358 /** @brief Compile and link test's GLSL program.
359  */
createProgram()360 void gl4cts::ConditionalRenderInverted::FunctionalTest::createProgram()
361 {
362 	/* Shortcut for GL functionality. */
363 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
364 
365 	struct Shader
366 	{
367 		glw::GLchar const* const source;
368 		glw::GLenum const		 type;
369 		glw::GLuint				 id;
370 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
371 
372 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
373 
374 	try
375 	{
376 		/* Create program. */
377 		m_po_id = gl.createProgram();
378 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
379 
380 		/* Shader compilation. */
381 
382 		for (glw::GLuint i = 0; i < shader_count; ++i)
383 		{
384 			if (DE_NULL != shader[i].source)
385 			{
386 				shader[i].id = gl.createShader(shader[i].type);
387 
388 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
389 
390 				gl.attachShader(m_po_id, shader[i].id);
391 
392 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
393 
394 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
395 
396 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
397 
398 				gl.compileShader(shader[i].id);
399 
400 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
401 
402 				glw::GLint status = GL_FALSE;
403 
404 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
405 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
406 
407 				if (GL_FALSE == status)
408 				{
409 					throw 0;
410 				}
411 			}
412 		}
413 
414 		/* Link. */
415 		gl.linkProgram(m_po_id);
416 
417 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
418 
419 		glw::GLint status = GL_FALSE;
420 
421 		gl.getProgramiv(m_po_id, GL_LINK_STATUS, &status);
422 
423 		if (GL_TRUE == status)
424 		{
425 			for (glw::GLuint i = 0; i < shader_count; ++i)
426 			{
427 				if (shader[i].id)
428 				{
429 					gl.detachShader(m_po_id, shader[i].id);
430 
431 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
432 				}
433 			}
434 		}
435 		else
436 		{
437 			throw 0;
438 		}
439 	}
440 	catch (...)
441 	{
442 		if (m_po_id)
443 		{
444 			gl.deleteProgram(m_po_id);
445 
446 			m_po_id = 0;
447 		}
448 	}
449 
450 	for (glw::GLuint i = 0; i < shader_count; ++i)
451 	{
452 		if (0 != shader[i].id)
453 		{
454 			gl.deleteShader(shader[i].id);
455 
456 			shader[i].id = 0;
457 		}
458 	}
459 
460 	if (m_po_id)
461 	{
462 		gl.useProgram(m_po_id);
463 
464 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
465 	}
466 }
467 
468 /** @brief Create and bind framebuffer with renderbuffer color attachment.
469  */
createView()470 void gl4cts::ConditionalRenderInverted::FunctionalTest::createView()
471 {
472 	/* Shortcut for GL functionality. */
473 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
474 
475 	/* Prepare framebuffer. */
476 	gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
477 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
478 
479 	gl.genFramebuffers(1, &m_fbo_id);
480 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
481 
482 	gl.genRenderbuffers(1, &m_rbo_id);
483 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
484 
485 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
486 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
487 
488 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
490 
491 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
492 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
493 
494 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
495 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
496 
497 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
498 	{
499 		throw 0;
500 	}
501 
502 	gl.viewport(0, 0, s_view_size, s_view_size);
503 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
504 }
505 
506 /** @brief Create test's query object.
507  */
createQueryObject()508 void gl4cts::ConditionalRenderInverted::FunctionalTest::createQueryObject()
509 {
510 	/* Shortcut for GL functionality. */
511 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
512 
513 	/* Create valid query object. */
514 	gl.genQueries(1, &m_qo_id);
515 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries() call failed.");
516 }
517 
518 /** @brief Setup color uniform of the test's program.
519  */
setupColor(const glw::GLfloat red)520 void gl4cts::ConditionalRenderInverted::FunctionalTest::setupColor(const glw::GLfloat red)
521 {
522 	/* Shortcut for GL functionality. */
523 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
524 
525 	/* Fetch where to set. */
526 	glw::GLuint location = gl.getUniformLocation(m_po_id, s_color_uniform_name);
527 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
528 
529 	/* Set. */
530 	gl.uniform1f(location, red);
531 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
532 }
533 
534 /** @brief Setup pass or discard switch uniform of the test's program.
535  */
setupPassSwitch(const bool shall_pass)536 void gl4cts::ConditionalRenderInverted::FunctionalTest::setupPassSwitch(const bool shall_pass)
537 {
538 	/* Shortcut for GL functionality. */
539 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
540 
541 	/* Fetch where to set. */
542 	glw::GLuint location = gl.getUniformLocation(m_po_id, s_pass_switch_uniform_name);
543 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
544 
545 	/* Set. */
546 	gl.uniform1i(location, (int)shall_pass);
547 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
548 }
549 
550 /** @brief Draw full screen within query or conditional block.
551  *
552  *  @param [in] conditional_or_query_draw       If true draw will be done in conditional rendering block, otherwise in query block.
553  *  @param [in] condition_mode_or_query_target  The param needed by query or conditional block - target or mode.
554  */
draw(const bool conditional_or_query_draw,const glw::GLenum condition_mode_or_query_target)555 void gl4cts::ConditionalRenderInverted::FunctionalTest::draw(const bool		   conditional_or_query_draw,
556 															 const glw::GLenum condition_mode_or_query_target)
557 {
558 	/* Shortcut for GL functionality. */
559 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
560 
561 	if (conditional_or_query_draw)
562 	{
563 		gl.beginConditionalRender(m_qo_id, condition_mode_or_query_target);
564 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginConditionalRender() call failed.");
565 	}
566 	else
567 	{
568 		gl.beginQuery(condition_mode_or_query_target, m_qo_id);
569 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery() call failed.");
570 	}
571 
572 	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
573 
574 	if (conditional_or_query_draw)
575 	{
576 		gl.endConditionalRender();
577 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndConditionalRender() call failed.");
578 	}
579 	else
580 	{
581 		gl.endQuery(condition_mode_or_query_target);
582 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery() call failed.");
583 	}
584 }
585 
586 /** @brief Check if any fragments have passed rendering.
587  *
588  *  @return True if any sample passed, false otherwise.
589  */
fragmentsPassed()590 bool gl4cts::ConditionalRenderInverted::FunctionalTest::fragmentsPassed()
591 {
592 	/* Shortcut for GL functionality. */
593 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
594 
595 	/* Fetch result. */
596 	glw::GLint result = -1;
597 
598 	gl.getQueryObjectiv(m_qo_id, GL_QUERY_RESULT, &result);
599 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectiv() call failed.");
600 
601 	/* Check for unusual errors. */
602 	if (-1 == result)
603 	{
604 		throw 0;
605 	}
606 
607 	/* Return results. */
608 	return (result > 0);
609 }
610 
611 /** @brief Read framebuffer's first pixel red component (left, bottom).
612  *
613  *  @return Red value of the pixel.
614  */
readPixel()615 glw::GLfloat gl4cts::ConditionalRenderInverted::FunctionalTest::readPixel()
616 {
617 	/* Shortcut for GL functionality. */
618 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
619 
620 	glw::GLfloat red = -1.f;
621 
622 	gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &red);
623 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
624 
625 	return red;
626 }
627 
628 /** @brief Destroy test's query object.
629  */
cleanQueryObject()630 void gl4cts::ConditionalRenderInverted::FunctionalTest::cleanQueryObject()
631 {
632 	/* Shortcut for GL functionality. */
633 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
634 
635 	/* Clean query object. */
636 	if (m_qo_id)
637 	{
638 		gl.deleteQueries(1, &m_qo_id);
639 
640 		m_qo_id = 0;
641 	}
642 }
643 
644 /** @brief Create test's empty Vertex Array Object.
645  */
createVertexArrayObject()646 void gl4cts::ConditionalRenderInverted::FunctionalTest::createVertexArrayObject()
647 {
648 	/* Shortcut for GL functionality. */
649 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
650 
651 	/* Create and bind vertex array. */
652 	gl.genVertexArrays(1, &m_vao_id);
653 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
654 
655 	gl.bindVertexArray(m_vao_id);
656 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
657 }
658 
659 /** @brief Destroy test's Vertex Array Object.
660  */
cleanProgramViewAndVAO()661 void gl4cts::ConditionalRenderInverted::FunctionalTest::cleanProgramViewAndVAO()
662 {
663 	/* Shortcut for GL functionality. */
664 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
665 
666 	/* Deleting view. */
667 	if (m_fbo_id)
668 	{
669 		gl.deleteFramebuffers(1, &m_fbo_id);
670 
671 		m_fbo_id = 0;
672 	}
673 
674 	if (m_rbo_id)
675 	{
676 		gl.deleteRenderbuffers(1, &m_rbo_id);
677 
678 		m_rbo_id = 0;
679 	}
680 
681 	if (m_vao_id)
682 	{
683 		gl.deleteVertexArrays(1, &m_vao_id);
684 
685 		m_vao_id = 0;
686 	}
687 }
688 
689 /** @brief Destroy test's framebuffer with related objects.
690  */
clearView()691 void gl4cts::ConditionalRenderInverted::FunctionalTest::clearView()
692 {
693 	/* Shortcut for GL functionality. */
694 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
695 
696 	/* Clear screen. */
697 	gl.clear(GL_COLOR_BUFFER_BIT);
698 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
699 }
700 
701 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_vertex_shader[] =
702 	"#version 130\n"
703 	"\n"
704 	"void main()\n"
705 	"{\n"
706 	"    switch(gl_VertexID % 4)\n"
707 	"    {\n"
708 	"    case 0:\n"
709 	"       gl_Position = vec4(-1.0, -1.0,  0.0,  1.0);\n"
710 	"       break;\n"
711 	"    case 1:\n"
712 	"       gl_Position = vec4( 1.0, -1.0,  0.0,  1.0);\n"
713 	"       break;\n"
714 	"    case 2:\n"
715 	"       gl_Position = vec4(-1.0,  1.0,  0.0,  1.0);\n"
716 	"       break;\n"
717 	"    case 3:\n"
718 	"       gl_Position = vec4( 1.0,  1.0,  0.0,  1.0);\n"
719 	"       break;\n"
720 	"    }\n"
721 	"}\n";
722 
723 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_fragment_shader[] = "#version 130\n"
724 																						   "\n"
725 																						   "uniform float color;\n"
726 																						   "uniform int   shall_pass;\n"
727 																						   "\n"
728 																						   "out vec4 pixel;\n"
729 																						   "\n"
730 																						   "void main()\n"
731 																						   "{\n"
732 																						   "    if(0 == shall_pass)\n"
733 																						   "    {\n"
734 																						   "        discard;\n"
735 																						   "    }\n"
736 																						   "\n"
737 																						   "    pixel = vec4(color);\n"
738 																						   "}\n";
739 
740 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_color_uniform_name[] = "color";
741 
742 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_pass_switch_uniform_name[] = "shall_pass";
743 
744 const glw::GLuint gl4cts::ConditionalRenderInverted::FunctionalTest::s_view_size = 1;
745 
746 /******************************** Utilities Implementation   ********************************/
747 
748 /** @brief Return string representation of condional rendering mode.
749  *
750  *  @param [in] mode    Render condition mode.
751  *
752  *  @return Constant C-String representation of mode.
753  */
modeToChars(glw::GLenum mode)754 const glw::GLchar* gl4cts::ConditionalRenderInverted::Utilities::modeToChars(glw::GLenum mode)
755 {
756 	/* Const name values. */
757 	static const glw::GLchar* query_wait_inverted_mode_name				 = "GL_QUERY_WAIT_INVERTED";
758 	static const glw::GLchar* query_no_wait_inverted_mode_name			 = "GL_QUERY_NO_WAIT_INVERTED";
759 	static const glw::GLchar* query_by_region_wait_inverted_mode_name	= "GL_QUERY_BY_REGION_WAIT_INVERTED";
760 	static const glw::GLchar* query_by_region_no_wait_inverted_mode_name = "GL_QUERY_BY_REGION_NO_WAIT_INVERTED";
761 	static const glw::GLchar* invalid_mode_name							 = "unknow mode";
762 
763 	/* Return proper value. */
764 	if (GL_QUERY_WAIT_INVERTED == mode)
765 	{
766 		return query_wait_inverted_mode_name;
767 	}
768 
769 	if (GL_QUERY_NO_WAIT_INVERTED == mode)
770 	{
771 		return query_no_wait_inverted_mode_name;
772 	}
773 
774 	if (GL_QUERY_BY_REGION_WAIT_INVERTED == mode)
775 	{
776 		return query_by_region_wait_inverted_mode_name;
777 	}
778 
779 	if (GL_QUERY_BY_REGION_NO_WAIT_INVERTED == mode)
780 	{
781 		return query_by_region_no_wait_inverted_mode_name;
782 	}
783 
784 	/* If not, return invalid name. */
785 	return invalid_mode_name;
786 }
787 
788 /** @brief Return string representation of glBeginQuery's target.
789  *
790  *  @param [in] mode    Render condition mode.
791  *
792  *  @return Constant C-String representation of mode.
793  */
queryTargetToChars(glw::GLenum mode)794 const glw::GLchar* gl4cts::ConditionalRenderInverted::Utilities::queryTargetToChars(glw::GLenum mode)
795 {
796 	/* Const name values. */
797 	static const glw::GLchar* any_samples_name	= "GL_ANY_SAMPLES_PASSED";
798 	static const glw::GLchar* samples_name		  = "GL_SAMPLES_PASSED";
799 	static const glw::GLchar* invalid_target_name = "unknow mode";
800 
801 	/* Return proper value. */
802 	if (GL_ANY_SAMPLES_PASSED == mode)
803 	{
804 		return any_samples_name;
805 	}
806 
807 	if (GL_SAMPLES_PASSED == mode)
808 	{
809 		return samples_name;
810 	}
811 
812 	/* If not, return invalid name. */
813 	return invalid_target_name;
814 }
815