xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cConditionalRenderInvertedTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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")
59     , m_qo_id(0)
60 {
61     /* Intentionally left blank. */
62 }
63 
64 /** @brief Iterate API coverage tests.
65  *
66  *  @return Iteration result.
67  */
iterate()68 tcu::TestNode::IterateResult gl4cts::ConditionalRenderInverted::CoverageTest::iterate()
69 {
70     /* OpenGL support query. */
71     bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
72     bool is_arb_conditional_render_inverted =
73         m_context.getContextInfo().isExtensionSupported("GL_ARB_conditional_render_inverted");
74 
75     /* Running tests. */
76     bool is_ok    = true;
77     bool is_error = false;
78 
79     /* This test should only be executed if we're running a GL4.5 context or related extension is available */
80     try
81     {
82         if (is_at_least_gl_45 || is_arb_conditional_render_inverted)
83         {
84             /* Prepare common objects. */
85             createQueryObject();
86 
87             /* Test cases. */
88             static const glw::GLenum modes[] = {GL_QUERY_WAIT_INVERTED, GL_QUERY_NO_WAIT_INVERTED,
89                                                 GL_QUERY_BY_REGION_WAIT_INVERTED, 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()
128                 << tcu::TestLog::Message << "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()
206             << tcu::TestLog::Message << "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, GL_QUERY_BY_REGION_NO_WAIT_INVERTED};
262 
263             static const glw::GLuint modes_count = sizeof(modes) / sizeof(modes[0]);
264 
265             /* Creating common objects. */
266             createProgram();
267             createView();
268             createVertexArrayObject();
269 
270             /* Iterating over test cases. */
271             for (glw::GLuint i = 0; i < render_cases_count; ++i)
272             {
273                 for (glw::GLuint j = 0; j < query_cases_count; ++j)
274                 {
275                     for (glw::GLuint k = 0; k < modes_count; ++k)
276                     {
277                         createQueryObject();
278 
279                         setupColor(1.f);
280                         setupPassSwitch(render_cases[i]);
281                         clearView();
282                         draw(false, query_cases[j]);
283 
284                         if (render_cases[i] == fragmentsPassed())
285                         {
286                             setupColor(0.f);
287                             setupPassSwitch(true);
288                             draw(true, modes[k]);
289 
290                             glw::GLfloat expected_value = (render_cases[i]) ? 1.f : 0.f;
291                             glw::GLfloat resulted_value = readPixel();
292 
293                             if (de::abs(expected_value - resulted_value) > 0.0078125f /* Precission (1/128) */)
294                             {
295                                 m_context.getTestContext().getLog()
296                                     << tcu::TestLog::Message << "The functional test's expected value ("
297                                     << expected_value << ") is different than resulted value (" << resulted_value
298                                     << "). The tested mode was " << Utilities::modeToChars(modes[k])
299                                     << ". Query was done for target " << Utilities::queryTargetToChars(query_cases[j])
300                                     << ", and the test was prepared to " << ((render_cases[i]) ? "pass" : "discard")
301                                     << " all fragments." << tcu::TestLog::EndMessage;
302 
303                                 is_ok = false;
304                             }
305                         }
306                         else
307                         {
308                             is_ok = false;
309                         }
310 
311                         cleanQueryObject();
312                     }
313                 }
314             }
315         }
316     }
317     catch (...)
318     {
319         is_ok    = false;
320         is_error = true;
321 
322         cleanQueryObject();
323     }
324 
325     /* Clean-up. */
326     cleanProgramViewAndVAO();
327 
328     /* Result's setup. */
329     if (is_ok)
330     {
331         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
332     }
333     else
334     {
335         if (is_error)
336         {
337             m_context.getTestContext().getLog()
338                 << tcu::TestLog::Message
339                 << "Internal error has occured during Conditional Render Inverted Functional Test."
340                 << tcu::TestLog::EndMessage;
341 
342             m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Test error.");
343         }
344         else
345         {
346             m_context.getTestContext().getLog()
347                 << tcu::TestLog::Message << "The Conditional Render Inverted Functional Test has failed."
348                 << tcu::TestLog::EndMessage;
349 
350             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail.");
351         }
352     }
353 
354     return STOP;
355 }
356 
357 /** @brief Compile and link test's GLSL program.
358  */
createProgram()359 void gl4cts::ConditionalRenderInverted::FunctionalTest::createProgram()
360 {
361     /* Shortcut for GL functionality. */
362     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
363 
364     struct Shader
365     {
366         glw::GLchar const *const source;
367         glw::GLenum const type;
368         glw::GLuint id;
369     } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};
370 
371     glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
372 
373     try
374     {
375         /* Create program. */
376         m_po_id = gl.createProgram();
377         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
378 
379         /* Shader compilation. */
380 
381         for (glw::GLuint i = 0; i < shader_count; ++i)
382         {
383             if (DE_NULL != shader[i].source)
384             {
385                 shader[i].id = gl.createShader(shader[i].type);
386 
387                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
388 
389                 gl.attachShader(m_po_id, shader[i].id);
390 
391                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
392 
393                 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
394 
395                 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
396 
397                 gl.compileShader(shader[i].id);
398 
399                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
400 
401                 glw::GLint status = GL_FALSE;
402 
403                 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
404                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
405 
406                 if (GL_FALSE == status)
407                 {
408                     throw 0;
409                 }
410             }
411         }
412 
413         /* Link. */
414         gl.linkProgram(m_po_id);
415 
416         GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
417 
418         glw::GLint status = GL_FALSE;
419 
420         gl.getProgramiv(m_po_id, GL_LINK_STATUS, &status);
421 
422         if (GL_TRUE == status)
423         {
424             for (glw::GLuint i = 0; i < shader_count; ++i)
425             {
426                 if (shader[i].id)
427                 {
428                     gl.detachShader(m_po_id, shader[i].id);
429 
430                     GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
431                 }
432             }
433         }
434         else
435         {
436             throw 0;
437         }
438     }
439     catch (...)
440     {
441         if (m_po_id)
442         {
443             gl.deleteProgram(m_po_id);
444 
445             m_po_id = 0;
446         }
447     }
448 
449     for (glw::GLuint i = 0; i < shader_count; ++i)
450     {
451         if (0 != shader[i].id)
452         {
453             gl.deleteShader(shader[i].id);
454 
455             shader[i].id = 0;
456         }
457     }
458 
459     if (m_po_id)
460     {
461         gl.useProgram(m_po_id);
462 
463         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
464     }
465 }
466 
467 /** @brief Create and bind framebuffer with renderbuffer color attachment.
468  */
createView()469 void gl4cts::ConditionalRenderInverted::FunctionalTest::createView()
470 {
471     /* Shortcut for GL functionality. */
472     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
473 
474     /* Prepare framebuffer. */
475     gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
476     GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
477 
478     gl.genFramebuffers(1, &m_fbo_id);
479     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
480 
481     gl.genRenderbuffers(1, &m_rbo_id);
482     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
483 
484     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
485     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
486 
487     gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
488     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
489 
490     gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
491     GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
492 
493     gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
494     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
495 
496     if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
497     {
498         throw 0;
499     }
500 
501     gl.viewport(0, 0, s_view_size, s_view_size);
502     GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
503 }
504 
505 /** @brief Create test's query object.
506  */
createQueryObject()507 void gl4cts::ConditionalRenderInverted::FunctionalTest::createQueryObject()
508 {
509     /* Shortcut for GL functionality. */
510     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
511 
512     /* Create valid query object. */
513     gl.genQueries(1, &m_qo_id);
514     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries() call failed.");
515 }
516 
517 /** @brief Setup color uniform of the test's program.
518  */
setupColor(const glw::GLfloat red)519 void gl4cts::ConditionalRenderInverted::FunctionalTest::setupColor(const glw::GLfloat red)
520 {
521     /* Shortcut for GL functionality. */
522     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
523 
524     /* Fetch where to set. */
525     glw::GLuint location = gl.getUniformLocation(m_po_id, s_color_uniform_name);
526     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
527 
528     /* Set. */
529     gl.uniform1f(location, red);
530     GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
531 }
532 
533 /** @brief Setup pass or discard switch uniform of the test's program.
534  */
setupPassSwitch(const bool shall_pass)535 void gl4cts::ConditionalRenderInverted::FunctionalTest::setupPassSwitch(const bool shall_pass)
536 {
537     /* Shortcut for GL functionality. */
538     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
539 
540     /* Fetch where to set. */
541     glw::GLuint location = gl.getUniformLocation(m_po_id, s_pass_switch_uniform_name);
542     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
543 
544     /* Set. */
545     gl.uniform1i(location, (int)shall_pass);
546     GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
547 }
548 
549 /** @brief Draw full screen within query or conditional block.
550  *
551  *  @param [in] conditional_or_query_draw       If true draw will be done in conditional rendering block, otherwise in query block.
552  *  @param [in] condition_mode_or_query_target  The param needed by query or conditional block - target or mode.
553  */
draw(const bool conditional_or_query_draw,const glw::GLenum condition_mode_or_query_target)554 void gl4cts::ConditionalRenderInverted::FunctionalTest::draw(const bool conditional_or_query_draw,
555                                                              const glw::GLenum condition_mode_or_query_target)
556 {
557     /* Shortcut for GL functionality. */
558     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
559 
560     if (conditional_or_query_draw)
561     {
562         gl.beginConditionalRender(m_qo_id, condition_mode_or_query_target);
563         GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginConditionalRender() call failed.");
564     }
565     else
566     {
567         gl.beginQuery(condition_mode_or_query_target, m_qo_id);
568         GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery() call failed.");
569     }
570 
571     gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
572 
573     if (conditional_or_query_draw)
574     {
575         gl.endConditionalRender();
576         GLU_EXPECT_NO_ERROR(gl.getError(), "glEndConditionalRender() call failed.");
577     }
578     else
579     {
580         gl.endQuery(condition_mode_or_query_target);
581         GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery() call failed.");
582     }
583 }
584 
585 /** @brief Check if any fragments have passed rendering.
586  *
587  *  @return True if any sample passed, false otherwise.
588  */
fragmentsPassed()589 bool gl4cts::ConditionalRenderInverted::FunctionalTest::fragmentsPassed()
590 {
591     /* Shortcut for GL functionality. */
592     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
593 
594     /* Fetch result. */
595     glw::GLint result = -1;
596 
597     gl.getQueryObjectiv(m_qo_id, GL_QUERY_RESULT, &result);
598     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectiv() call failed.");
599 
600     /* Check for unusual errors. */
601     if (-1 == result)
602     {
603         throw 0;
604     }
605 
606     /* Return results. */
607     return (result > 0);
608 }
609 
610 /** @brief Read framebuffer's first pixel red component (left, bottom).
611  *
612  *  @return Red value of the pixel.
613  */
readPixel()614 glw::GLfloat gl4cts::ConditionalRenderInverted::FunctionalTest::readPixel()
615 {
616     /* Shortcut for GL functionality. */
617     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
618 
619     glw::GLfloat red = -1.f;
620 
621     gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &red);
622     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
623 
624     return red;
625 }
626 
627 /** @brief Destroy test's query object.
628  */
cleanQueryObject()629 void gl4cts::ConditionalRenderInverted::FunctionalTest::cleanQueryObject()
630 {
631     /* Shortcut for GL functionality. */
632     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
633 
634     /* Clean query object. */
635     if (m_qo_id)
636     {
637         gl.deleteQueries(1, &m_qo_id);
638 
639         m_qo_id = 0;
640     }
641 }
642 
643 /** @brief Create test's empty Vertex Array Object.
644  */
createVertexArrayObject()645 void gl4cts::ConditionalRenderInverted::FunctionalTest::createVertexArrayObject()
646 {
647     /* Shortcut for GL functionality. */
648     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
649 
650     /* Create and bind vertex array. */
651     gl.genVertexArrays(1, &m_vao_id);
652     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
653 
654     gl.bindVertexArray(m_vao_id);
655     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
656 }
657 
658 /** @brief Destroy test's Vertex Array Object.
659  */
cleanProgramViewAndVAO()660 void gl4cts::ConditionalRenderInverted::FunctionalTest::cleanProgramViewAndVAO()
661 {
662     /* Shortcut for GL functionality. */
663     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
664 
665     /* Deleting view. */
666     if (m_fbo_id)
667     {
668         gl.deleteFramebuffers(1, &m_fbo_id);
669 
670         m_fbo_id = 0;
671     }
672 
673     if (m_rbo_id)
674     {
675         gl.deleteRenderbuffers(1, &m_rbo_id);
676 
677         m_rbo_id = 0;
678     }
679 
680     if (m_vao_id)
681     {
682         gl.deleteVertexArrays(1, &m_vao_id);
683 
684         m_vao_id = 0;
685     }
686 }
687 
688 /** @brief Destroy test's framebuffer with related objects.
689  */
clearView()690 void gl4cts::ConditionalRenderInverted::FunctionalTest::clearView()
691 {
692     /* Shortcut for GL functionality. */
693     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
694 
695     /* Clear screen. */
696     gl.clear(GL_COLOR_BUFFER_BIT);
697     GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
698 }
699 
700 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_vertex_shader[] =
701     "#version 130\n"
702     "\n"
703     "void main()\n"
704     "{\n"
705     "    switch(gl_VertexID % 4)\n"
706     "    {\n"
707     "    case 0:\n"
708     "       gl_Position = vec4(-1.0, -1.0,  0.0,  1.0);\n"
709     "       break;\n"
710     "    case 1:\n"
711     "       gl_Position = vec4( 1.0, -1.0,  0.0,  1.0);\n"
712     "       break;\n"
713     "    case 2:\n"
714     "       gl_Position = vec4(-1.0,  1.0,  0.0,  1.0);\n"
715     "       break;\n"
716     "    case 3:\n"
717     "       gl_Position = vec4( 1.0,  1.0,  0.0,  1.0);\n"
718     "       break;\n"
719     "    }\n"
720     "}\n";
721 
722 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_fragment_shader[] = "#version 130\n"
723                                                                                            "\n"
724                                                                                            "uniform float color;\n"
725                                                                                            "uniform int   shall_pass;\n"
726                                                                                            "\n"
727                                                                                            "out vec4 pixel;\n"
728                                                                                            "\n"
729                                                                                            "void main()\n"
730                                                                                            "{\n"
731                                                                                            "    if(0 == shall_pass)\n"
732                                                                                            "    {\n"
733                                                                                            "        discard;\n"
734                                                                                            "    }\n"
735                                                                                            "\n"
736                                                                                            "    pixel = vec4(color);\n"
737                                                                                            "}\n";
738 
739 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_color_uniform_name[] = "color";
740 
741 const glw::GLchar gl4cts::ConditionalRenderInverted::FunctionalTest::s_pass_switch_uniform_name[] = "shall_pass";
742 
743 const glw::GLuint gl4cts::ConditionalRenderInverted::FunctionalTest::s_view_size = 1;
744 
745 /******************************** Utilities Implementation   ********************************/
746 
747 /** @brief Return string representation of condional rendering mode.
748  *
749  *  @param [in] mode    Render condition mode.
750  *
751  *  @return Constant C-String representation of mode.
752  */
modeToChars(glw::GLenum mode)753 const glw::GLchar *gl4cts::ConditionalRenderInverted::Utilities::modeToChars(glw::GLenum mode)
754 {
755     /* Const name values. */
756     static const glw::GLchar *query_wait_inverted_mode_name              = "GL_QUERY_WAIT_INVERTED";
757     static const glw::GLchar *query_no_wait_inverted_mode_name           = "GL_QUERY_NO_WAIT_INVERTED";
758     static const glw::GLchar *query_by_region_wait_inverted_mode_name    = "GL_QUERY_BY_REGION_WAIT_INVERTED";
759     static const glw::GLchar *query_by_region_no_wait_inverted_mode_name = "GL_QUERY_BY_REGION_NO_WAIT_INVERTED";
760     static const glw::GLchar *invalid_mode_name                          = "unknow mode";
761 
762     /* Return proper value. */
763     if (GL_QUERY_WAIT_INVERTED == mode)
764     {
765         return query_wait_inverted_mode_name;
766     }
767 
768     if (GL_QUERY_NO_WAIT_INVERTED == mode)
769     {
770         return query_no_wait_inverted_mode_name;
771     }
772 
773     if (GL_QUERY_BY_REGION_WAIT_INVERTED == mode)
774     {
775         return query_by_region_wait_inverted_mode_name;
776     }
777 
778     if (GL_QUERY_BY_REGION_NO_WAIT_INVERTED == mode)
779     {
780         return query_by_region_no_wait_inverted_mode_name;
781     }
782 
783     /* If not, return invalid name. */
784     return invalid_mode_name;
785 }
786 
787 /** @brief Return string representation of glBeginQuery's target.
788  *
789  *  @param [in] mode    Render condition mode.
790  *
791  *  @return Constant C-String representation of mode.
792  */
queryTargetToChars(glw::GLenum mode)793 const glw::GLchar *gl4cts::ConditionalRenderInverted::Utilities::queryTargetToChars(glw::GLenum mode)
794 {
795     /* Const name values. */
796     static const glw::GLchar *any_samples_name    = "GL_ANY_SAMPLES_PASSED";
797     static const glw::GLchar *samples_name        = "GL_SAMPLES_PASSED";
798     static const glw::GLchar *invalid_target_name = "unknow mode";
799 
800     /* Return proper value. */
801     if (GL_ANY_SAMPLES_PASSED == mode)
802     {
803         return any_samples_name;
804     }
805 
806     if (GL_SAMPLES_PASSED == mode)
807     {
808         return samples_name;
809     }
810 
811     /* If not, return invalid name. */
812     return invalid_target_name;
813 }
814