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 */
38gl4cts::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. */
45void 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 */
57gl4cts::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 */
67tcu::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 */
140void 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 */
158void 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 */
179bool 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 */
220gl4cts::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 */
235tcu::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 */
360void 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 */
470void 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 */
508void 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 */
520void 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 */
536void 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 */
555void 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 */
590bool 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 */
615glw::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 */
630void 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 */
646void 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 */
661void 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 */
691void 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
701const 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
723const 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
740const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_color_uniform_name[] = "color";
741
742const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_pass_switch_uniform_name[] = "shall_pass";
743
744const 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 */
754const 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 */
794const 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