xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cContextFlushControlTests.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 "gl4cContextFlushControlTests.hpp"
26 #include "deClock.h"
27 #include "gluContextInfo.hpp"
28 #include "gluDefs.hpp"
29 #include "gluPlatform.hpp"
30 #include "gluRenderContext.hpp"
31 #include "gluStrUtil.hpp"
32 #include "tcuTestLog.hpp"
33 
34 #ifndef GL_CONTEXT_RELEASE_BEHAVIOR
35 #define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
36 #endif
37 
38 #ifndef GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH
39 #define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
40 #endif
41 
42 #define CONTEXT_FLUSH_CONTROL_FUNCTIONAL_TEST_DRAW_COUNT 1024
43 
44 /******************************** Test Group Implementation       ********************************/
45 
46 /** @brief Context Flush Control tests group constructor.
47  *
48  *  @param [in] context     OpenGL context.
49  */
Tests(deqp::Context & context)50 gl4cts::ContextFlushControl::Tests::Tests(deqp::Context &context)
51     : TestCaseGroup(context, "context_flush_control", "Context Flush Control Test Suite")
52 {
53     /* Intentionally left blank */
54 }
55 
56 /** @brief Context Flush Control tests initializer. */
init()57 void gl4cts::ContextFlushControl::Tests::init()
58 {
59     addChild(new gl4cts::ContextFlushControl::CoverageTest(m_context));
60     addChild(new gl4cts::ContextFlushControl::FunctionalTest(m_context));
61 }
62 
63 /******************************** Coverage Tests Implementation   ********************************/
64 
65 /** @brief API coverage tests constructor.
66  *
67  *  @param [in] context     OpenGL context.
68  */
CoverageTest(deqp::Context & context)69 gl4cts::ContextFlushControl::CoverageTest::CoverageTest(deqp::Context &context)
70     : deqp::TestCase(context, "coverage", "Context Flush Control API Coverage Test")
71 {
72     /* Intentionally left blank. */
73 }
74 
75 /** @brief Iterate API coverage tests.
76  *
77  *  @return Iteration result.
78  */
iterate()79 tcu::TestNode::IterateResult gl4cts::ContextFlushControl::CoverageTest::iterate()
80 {
81     /* OpenGL support query. */
82     bool is_at_least_gl_44 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 4)));
83     bool is_khr_context_flush_control = m_context.getContextInfo().isExtensionSupported("GL_KHR_context_flush_control");
84 
85     /* Running tests. */
86     bool is_ok = true;
87 
88     /* This test should only be executed if we're running a GL4.4 context or related extension is available */
89     if (is_at_least_gl_44 || is_khr_context_flush_control)
90     {
91         /* Test deafult context which shall use implicit flush when swapped. */
92         is_ok = is_ok && testQuery(m_context.getRenderContext(), GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH);
93 
94         /* Create context which shall swap without flush. */
95         glu::RenderContext *no_flush_context = createNoFlushContext();
96 
97         /* Proceed only if such context has been created. */
98         if (DE_NULL != no_flush_context)
99         {
100             /* Test no-flush context. */
101             no_flush_context->makeCurrent();
102 
103             is_ok = is_ok && testQuery(*no_flush_context, GL_NONE);
104 
105             /* Release no-flush context. */
106             m_context.getRenderContext().makeCurrent();
107 
108             delete no_flush_context;
109         }
110     }
111 
112     /* Result's setup. */
113     if (is_ok)
114     {
115         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
116     }
117     else
118     {
119         m_context.getTestContext().getLog()
120             << tcu::TestLog::Message << "The Context Flush Control Coverage test have failed."
121             << tcu::TestLog::EndMessage;
122 
123         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
124     }
125 
126     return STOP;
127 }
128 
129 /** @brief Test getter coverage for the given GL context.
130  *
131  *  This function tests following GL query functions:
132  *      glGetIntegerv,
133  *      glGetFloatv,
134  *      glGetBooleanv,
135  *      glGetDoublev,
136  *      glGetInteger64v.
137  *  Expected value is clamped to <0, 1> range flor glGetBooleanv.
138  *  For reference see KHR_context_flush_control extension.
139  *
140  *  @param [in] context         Render context to be used with the test.
141  *  @param [in] expected_value  Expected value to be returned by glGet*v function.
142  *
143  *  @return True if all tested functions returned expected value, false otherwise.
144  */
testQuery(glu::RenderContext & context,glw::GLenum expected_value)145 bool gl4cts::ContextFlushControl::CoverageTest::testQuery(glu::RenderContext &context, glw::GLenum expected_value)
146 {
147     /* Shortcut for GL functionality. */
148     const glw::Functions &gl = context.getFunctions();
149 
150     /* Variables for query. */
151     glw::GLint value_i     = -1;
152     glw::GLint64 value_i64 = -1;
153     glw::GLfloat value_f   = -1;
154     glw::GLdouble value_d  = -1;
155     glw::GLboolean value_b = -1;
156 
157     glw::GLboolean expected_bool_value = (glw::GLboolean)de::min((glw::GLint)expected_value, (glw::GLint)1);
158 
159     /* Test. */
160     try
161     {
162         /* Fetch data. */
163         gl.getIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &value_i);
164         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
165 
166         gl.getInteger64v(GL_CONTEXT_RELEASE_BEHAVIOR, &value_i64);
167         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInteger64v call failed.");
168 
169         gl.getFloatv(GL_CONTEXT_RELEASE_BEHAVIOR, &value_f);
170         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv call failed.");
171 
172         gl.getDoublev(GL_CONTEXT_RELEASE_BEHAVIOR, &value_d);
173         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetDoublev call failed.");
174 
175         gl.getBooleanv(GL_CONTEXT_RELEASE_BEHAVIOR, &value_b);
176         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv call failed.");
177 
178         /* Check result. */
179         if ((expected_value == value_i) && (expected_value == value_i64) && (expected_value == value_f) &&
180             (expected_value == value_d) && (expected_bool_value == value_b))
181         {
182             return true;
183         }
184     }
185     catch (...)
186     {
187         return false;
188     }
189 
190     return false;
191 }
192 
193 /** @brief Create render context with CONTEXT_RELEASE_BEHAVIOR set as NONE.
194  *
195  *  @return Render context pointer if creation succeeded, DE_NULL otherwise.
196  */
createNoFlushContext()197 glu::RenderContext *gl4cts::ContextFlushControl::CoverageTest::createNoFlushContext()
198 {
199     /* Get current platform.*/
200     glu::Platform &platform = dynamic_cast<glu::Platform &>(m_context.getTestContext().getPlatform());
201 
202     /* Context to be returned (NULL if failed). */
203     glu::RenderContext *context = DE_NULL;
204 
205     /* Get context related attributes needed to create no-flush context. */
206     const int *attributes = platform.getContextFlushControlContextAttributes();
207 
208     /* Proceed only if it is possible to make no-flush context. */
209     if (DE_NULL != attributes)
210     {
211         glu::ContextType renderContextType = m_context.getRenderContext().getType();
212 
213         /* Create no-flush context. */
214         context = platform.createRenderContext(renderContextType, m_context.getTestContext().getCommandLine(),
215                                                0 /* shared_context */, attributes);
216     }
217 
218     return context;
219 }
220 
221 /******************************** Functional Test Implementation   ********************************/
222 
223 /** @brief Functional test constructor.
224  *
225  *  @param [in] context     OpenGL context.
226  */
FunctionalTest(deqp::Context & context)227 gl4cts::ContextFlushControl::FunctionalTest::FunctionalTest(deqp::Context &context)
228     : deqp::TestCase(context, "functional", "Context Flush Control Functional Test")
229 {
230     /* Intentionally left blank. */
231 }
232 
233 /** @brief Iterate Functional test cases.
234  *
235  *  @return Iteration result.
236  */
iterate()237 tcu::TestNode::IterateResult gl4cts::ContextFlushControl::FunctionalTest::iterate()
238 {
239     /* Shortcut for GL functionality. */
240     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
241 
242     /* Get current platform.*/
243     glu::Platform &platform = dynamic_cast<glu::Platform &>(m_context.getTestContext().getPlatform());
244 
245     /* OpenGL support query. */
246     bool is_at_least_gl_44 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 4)));
247     bool is_khr_context_flush_control = m_context.getContextInfo().isExtensionSupported("GL_KHR_context_flush_control");
248 
249     /* Running tests. */
250     bool is_ok    = true;
251     bool is_error = false;
252 
253     /* This test should only be executed if we're running a GL4.4 context or related extension is available */
254     try
255     {
256         if ((is_at_least_gl_44 || is_khr_context_flush_control) &&
257             (DE_NULL != platform.getContextFlushControlContextAttributes()))
258         {
259             glw::GLfloat test_time_no_flush = testTime(false);
260             glw::GLfloat test_time_flush    = testTime(true);
261 
262             is_ok = (test_time_no_flush < test_time_flush);
263         }
264         else
265         {
266             is_error = true;
267         }
268     }
269     catch (...)
270     {
271         is_ok    = false;
272         is_error = true;
273     }
274 
275     /* Result's setup. */
276     if (is_ok)
277     {
278         if (is_error)
279         {
280             m_context.getTestContext().getLog()
281                 << tcu::TestLog::Message << "The context does not support No-Flush behavior."
282                 << tcu::TestLog::EndMessage;
283 
284             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported.");
285         }
286         else
287         {
288             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
289         }
290     }
291     else
292     {
293         if (is_error)
294         {
295             m_context.getTestContext().getLog()
296                 << tcu::TestLog::Message << "Internal error has occured during Context Flush Control Functional test."
297                 << tcu::TestLog::EndMessage;
298 
299             m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Test error.");
300         }
301         else
302         {
303             m_context.getTestContext().getLog()
304                 << tcu::TestLog::Message
305                 << "The running time of no-flush context switches has been slower than flush "
306                    "behavior context switching case. "
307                 << "This is not expected from quality implementation." << tcu::TestLog::EndMessage;
308 
309             m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Quality warning.");
310         }
311     }
312 
313     return STOP;
314 }
315 
316 /** @brief This function measures time of loop consisting of draw and switch context,
317  *         which shall or shall not flush on switch.
318  *
319  *  The test is based on KHR_context_flush_control extension overview, that the main reason
320  *  for no-flush context is to increase the performance of the implementation.
321  *
322  *  @param [in] shall_flush_on_release      Flag indicating that contexts shall flush when switched.
323  *
324  *  @return Run-time of the test loop.
325  */
testTime(bool shall_flush_on_release)326 glw::GLfloat gl4cts::ContextFlushControl::FunctionalTest::testTime(bool shall_flush_on_release)
327 {
328     /* Create two contexts to be switched during test. */
329     DrawSetup draw_context_setup[2] = {DrawSetup(m_context, shall_flush_on_release),
330                                        DrawSetup(m_context, shall_flush_on_release)};
331 
332     /* Check starting time. */
333     uint64_t start_time = deGetMicroseconds();
334 
335     /* Loop over draw-switch context. */
336     for (glw::GLuint i = 0; i < 1024; ++i)
337     {
338         draw_context_setup[i % 2].makeCurrent();
339         draw_context_setup[i % 2].draw();
340     }
341 
342     /* Check end time. */
343     uint64_t end_time = deGetMicroseconds();
344 
345     /* Return resulting run-time. */
346     return (glw::GLfloat)(end_time - start_time);
347 }
348 
349 /** @brief Make context current.
350  */
makeCurrent()351 void gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::makeCurrent()
352 {
353     /* Switch context to this. */
354     m_context->makeCurrent();
355 }
356 
357 /** @brief Use program and draw full screen quad.
358  */
draw()359 void gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::draw()
360 {
361     /* Shortcut for GL functionality. */
362     const glw::Functions &gl = m_context->getFunctions();
363 
364     /* Use GLSL program. */
365     gl.useProgram(m_po);
366     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
367 
368     /* Clear. */
369     gl.clear(GL_COLOR_BUFFER_BIT);
370     GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
371 
372     /* Draw. */
373     gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4 /* quad */);
374     GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
375 }
376 
377 /** @brief Draw Setup object constructor.
378  *
379  *  The constructor will throw on error.
380  *
381  *  @param [in] test_context                Test context for platform, logging and switching to default context on destruction.
382  *  @param [in] shall_flush_on_release      Flag indicating that contexts shall flush when switched.
383  */
DrawSetup(deqp::Context & test_context,bool shall_flush_on_release)384 gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::DrawSetup(deqp::Context &test_context,
385                                                                   bool shall_flush_on_release)
386     : m_test_context(test_context)
387     , m_fbo(0)
388     , m_rbo(0)
389     , m_vao(0)
390     , m_po(0)
391 {
392     createContext(shall_flush_on_release);
393 
394     if (DE_NULL == m_context)
395     {
396         throw 0;
397     }
398 
399     createGeometry();
400 
401     if (0 == m_vao)
402     {
403         throw 0;
404     }
405 
406     createView();
407 
408     if ((0 == m_fbo) || (0 == m_rbo))
409     {
410         throw 0;
411     }
412 
413     createProgram();
414 
415     if (0 == m_po)
416     {
417         throw 0;
418     }
419 }
420 
421 /** @brief Draw Setup object destructor.
422  */
~DrawSetup()423 gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::~DrawSetup()
424 {
425     if (m_context)
426     {
427         /* Make sure context is current. */
428         makeCurrent();
429 
430         /* Shortcut for GL functionality. */
431         const glw::Functions &gl = m_context->getFunctions();
432 
433         /* Cleanup. */
434         if (m_vao)
435         {
436             gl.deleteVertexArrays(1, &m_vao);
437 
438             m_vao = 0;
439         }
440 
441         if (m_fbo)
442         {
443             gl.deleteFramebuffers(1, &m_fbo);
444 
445             m_fbo = 0;
446         }
447 
448         if (m_rbo)
449         {
450             gl.deleteRenderbuffers(1, &m_rbo);
451 
452             m_rbo = 0;
453         }
454 
455         if (m_po)
456         {
457             gl.deleteProgram(m_po);
458 
459             m_po = 0;
460         }
461 
462         /* Make default context current. */
463         m_test_context.getRenderContext().makeCurrent();
464 
465         /* Cleanup context. */
466         delete m_context;
467     }
468 }
469 
470 /** @brief Create render context with CONTEXT_RELEASE_BEHAVIOR set to NONE or CONTEXT_RELEASE_BEHAVIOR_FLUSH.
471  *
472  *  @return Render context pointer if creation succeeded, DE_NULL otherwise.
473  */
createContext(bool shall_flush_on_release)474 void gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::createContext(bool shall_flush_on_release)
475 {
476     /* Get current platform.*/
477     glu::Platform &platform = dynamic_cast<glu::Platform &>(m_test_context.getTestContext().getPlatform());
478 
479     /* Get context related attributes needed to create no-flush context. */
480     const int *attributes = DE_NULL;
481 
482     if (!shall_flush_on_release)
483     {
484         attributes = platform.getContextFlushControlContextAttributes();
485     }
486 
487     /* Proceed only if it is possible to make no-flush context. */
488     glu::ContextType renderContextType = m_test_context.getRenderContext().getType();
489 
490     /* Create no-flush context. */
491     m_context = platform.createRenderContext(renderContextType, m_test_context.getTestContext().getCommandLine(),
492                                              0 /* shared_context */, attributes);
493 }
494 
495 /** @brief Create RGBA8 framebuffer with attached renderbuffer.
496  */
createView()497 void gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::createView()
498 {
499     /* Shortcut for GL functionality. */
500     const glw::Functions &gl = m_context->getFunctions();
501 
502     /* Prepare framebuffer. */
503     gl.clearColor(0.f, 0.f, 0.f, 1.f);
504     GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
505 
506     gl.genFramebuffers(1, &m_fbo);
507     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
508 
509     gl.genRenderbuffers(1, &m_rbo);
510     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
511 
512     gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
513     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
514 
515     gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
516     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
517 
518     gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_view_size, s_view_size);
519     GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
520 
521     gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
522     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
523 
524     if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
525     {
526         throw 0;
527     }
528 
529     gl.viewport(0, 0, s_view_size, s_view_size);
530     GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
531 }
532 
533 /** @brief Create and bind empty vertex array object.
534  */
createGeometry()535 void gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::createGeometry()
536 {
537     /* Shortcut for GL functionality. */
538     const glw::Functions &gl = m_context->getFunctions();
539 
540     /* Create and bind vertex array. */
541     gl.genVertexArrays(1, &m_vao);
542     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
543 
544     gl.bindVertexArray(m_vao);
545     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
546 }
547 
548 /** @brief Compile and link shader program.
549  */
createProgram()550 void gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::createProgram()
551 {
552     /* Shortcut for GL functionality. */
553     const glw::Functions &gl = m_context->getFunctions();
554 
555     struct Shader
556     {
557         glw::GLchar const *const source;
558         glw::GLenum const type;
559         glw::GLuint id;
560     } shader[] = {{s_vertex_shader, GL_VERTEX_SHADER, 0}, {s_fragment_shader, GL_FRAGMENT_SHADER, 0}};
561 
562     glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
563 
564     try
565     {
566         /* Create program. */
567         m_po = gl.createProgram();
568         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
569 
570         /* Shader compilation. */
571 
572         for (glw::GLuint i = 0; i < shader_count; ++i)
573         {
574             if (DE_NULL != shader[i].source)
575             {
576                 shader[i].id = gl.createShader(shader[i].type);
577 
578                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
579 
580                 gl.attachShader(m_po, shader[i].id);
581 
582                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
583 
584                 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
585 
586                 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
587 
588                 gl.compileShader(shader[i].id);
589 
590                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
591 
592                 glw::GLint status = GL_FALSE;
593 
594                 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
595                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
596 
597                 if (GL_FALSE == status)
598                 {
599                     throw 0;
600                 }
601             }
602         }
603 
604         /* Link. */
605         gl.linkProgram(m_po);
606 
607         GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
608 
609         glw::GLint status = GL_FALSE;
610 
611         gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
612 
613         if (GL_TRUE == status)
614         {
615             for (glw::GLuint i = 0; i < shader_count; ++i)
616             {
617                 if (shader[i].id)
618                 {
619                     gl.detachShader(m_po, shader[i].id);
620 
621                     GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
622                 }
623             }
624         }
625         else
626         {
627             throw 0;
628         }
629     }
630     catch (...)
631     {
632         if (m_po)
633         {
634             gl.deleteProgram(m_po);
635 
636             m_po = 0;
637         }
638     }
639 
640     for (glw::GLuint i = 0; i < shader_count; ++i)
641     {
642         if (0 != shader[i].id)
643         {
644             gl.deleteShader(shader[i].id);
645 
646             shader[i].id = 0;
647         }
648     }
649 }
650 
651 const glw::GLuint gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::s_view_size = 256;
652 
653 const glw::GLchar gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::s_vertex_shader[] =
654     "#version 130\n"
655     "\n"
656     "void main()\n"
657     "{\n"
658     "    switch(gl_VertexID % 4)\n"
659     "    {\n"
660     "    case 0:\n"
661     "       gl_Position = vec4(-1.0, -1.0,  0.0,  1.0);\n"
662     "       break;\n"
663     "    case 1:\n"
664     "       gl_Position = vec4( 1.0, -1.0,  0.0,  1.0);\n"
665     "       break;\n"
666     "    case 2:\n"
667     "       gl_Position = vec4(-1.0,  1.0,  0.0,  1.0);\n"
668     "       break;\n"
669     "    case 3:\n"
670     "       gl_Position = vec4( 1.0,  1.0,  0.0,  1.0);\n"
671     "       break;\n"
672     "    }\n"
673     "}\n";
674 
675 const glw::GLchar gl4cts::ContextFlushControl::FunctionalTest::DrawSetup::s_fragment_shader[] =
676     "#version 130\n"
677     "\n"
678     "out vec4 pixel;\n"
679     "\n"
680     "void main()\n"
681     "{\n"
682     "    pixel = vec4(1.0);\n"
683     "}\n";
684