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