Fix sample_mask_in.bit_count_per_two_samples tests for 2x MSAA. am: ea5589c748 am...
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl4cDirectStateAccessSamplersTests.cpp
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 /**
25  */ /*!
26  * \file  gl4cDirectStateAccessXFBTests.cpp
27  * \brief Conformance tests for the Direct State Access feature functionality (Transform Feedbeck access part).
28  */ /*-----------------------------------------------------------------------------------------------------------*/
29
30 /* Includes. */
31 #include "gl4cDirectStateAccessTests.hpp"
32
33 #include "deSharedPtr.hpp"
34
35 #include "gluContextInfo.hpp"
36 #include "gluDefs.hpp"
37 #include "gluPixelTransfer.hpp"
38 #include "gluStrUtil.hpp"
39
40 #include "tcuFuzzyImageCompare.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuRenderTarget.hpp"
43 #include "tcuSurface.hpp"
44 #include "tcuTestLog.hpp"
45
46 #include "glw.h"
47 #include "glwFunctions.hpp"
48
49 namespace gl4cts
50 {
51 namespace DirectStateAccess
52 {
53 namespace Samplers
54 {
55 /******************************** Creation Test Implementation   ********************************/
56
57 /** @brief Creation Test constructor.
58  *
59  *  @param [in] context     OpenGL context.
60  */
61 CreationTest::CreationTest(deqp::Context& context)
62         : deqp::TestCase(context, "samplers_creation", "Sampler Objects Creation Test")
63 {
64         /* Intentionally left blank. */
65 }
66
67 /** @brief Iterate Creation Test cases.
68  *
69  *  @return Iteration result.
70  */
71 tcu::TestNode::IterateResult CreationTest::iterate()
72 {
73         /* Shortcut for GL functionality */
74         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
75
76         /* Get context setup. */
77         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
78         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
79
80         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
81         {
82                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
83
84                 return STOP;
85         }
86
87         /* Running tests. */
88         bool is_ok      = true;
89         bool is_error = false;
90
91         /* Samplers objects */
92         static const glw::GLuint samplers_count = 2;
93
94         glw::GLuint samplers_dsa[samplers_count] = {};
95
96         try
97         {
98                 /* Check direct state creation. */
99                 gl.createSamplers(samplers_count, samplers_dsa);
100                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateSamplers have failed");
101
102                 for (glw::GLuint i = 0; i < samplers_count; ++i)
103                 {
104                         if (!gl.isSampler(samplers_dsa[i]))
105                         {
106                                 is_ok = false;
107
108                                 /* Log. */
109                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
110                                                                                                         << "CreateSamplers has not created defualt objects."
111                                                                                                         << tcu::TestLog::EndMessage;
112                         }
113                 }
114         }
115         catch (...)
116         {
117                 is_ok   = false;
118                 is_error = true;
119         }
120
121         /* Cleanup. */
122         for (glw::GLuint i = 0; i < samplers_count; ++i)
123         {
124                 if (samplers_dsa[i])
125                 {
126                         gl.deleteSamplers(1, &samplers_dsa[i]);
127
128                         samplers_dsa[i] = 0;
129                 }
130         }
131
132         /* Result's setup. */
133         if (is_ok)
134         {
135                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
136         }
137         else
138         {
139                 if (is_error)
140                 {
141                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
142                 }
143                 else
144                 {
145                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
146                 }
147         }
148
149         return STOP;
150 }
151
152 /******************************** Defaults Test Implementation   ********************************/
153
154 /** @brief Defaults Test constructor.
155  *
156  *  @param [in] context     OpenGL context.
157  */
158 DefaultsTest::DefaultsTest(deqp::Context& context)
159         : deqp::TestCase(context, "samplers_defaults", "Samplers Defaults Test"), m_sampler_dsa(0)
160 {
161         /* Intentionally left blank. */
162 }
163
164 /** @brief Iterate Defaults Test cases.
165  *
166  *  @return Iteration result.
167  */
168 tcu::TestNode::IterateResult DefaultsTest::iterate()
169 {
170         /* Get context setup. */
171         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
172         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
173
174         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
175         {
176                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
177
178                 return STOP;
179         }
180
181         /* Running tests. */
182         bool is_ok      = true;
183         bool is_error = false;
184
185         try
186         {
187                 prepare();
188
189                 glw::GLfloat expected_vector[4] = { 0.0, 0.0, 0.0, 0.0 };
190
191                 is_ok &= testSamplerFloatVectorParameter(GL_TEXTURE_BORDER_COLOR, expected_vector);
192                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
193                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_COMPARE_MODE, GL_NONE);
194                 is_ok &= testSamplerFloatParameter(GL_TEXTURE_LOD_BIAS, 0.0);
195                 is_ok &= testSamplerFloatParameter(GL_TEXTURE_MAX_LOD, 1000);
196                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
197                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
198                 is_ok &= testSamplerFloatParameter(GL_TEXTURE_MIN_LOD, -1000);
199                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_WRAP_S, GL_REPEAT);
200                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_WRAP_T, GL_REPEAT);
201                 is_ok &= testSamplerIntegerParameter(GL_TEXTURE_WRAP_R, GL_REPEAT);
202         }
203         catch (...)
204         {
205                 is_ok   = false;
206                 is_error = true;
207         }
208
209         /* Clean up. */
210         clean();
211
212         /* Result's setup. */
213         if (is_ok)
214         {
215                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
216         }
217         else
218         {
219                 if (is_error)
220                 {
221                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
222                 }
223                 else
224                 {
225                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
226                 }
227         }
228
229         return STOP;
230 }
231
232 /** @brief Create Sampler Objects.
233  *
234  *  @note The function may throw if unexpected error has occured.
235  *
236  *  @return True if test succeeded, false otherwise.
237  */
238 void DefaultsTest::prepare()
239 {
240         /* Shortcut for GL functionality */
241         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
242
243         /* Sampler object creation */
244         gl.createSamplers(1, &m_sampler_dsa);
245         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
246 }
247
248 /** @brief Test Sampler Integer Parameter.
249  *
250  *  @note The function may throw if unexpected error has occured.
251  *
252  *  @return True if test succeeded, false otherwise.
253  */
254 bool DefaultsTest::testSamplerIntegerParameter(glw::GLenum pname, glw::GLint expected_value)
255 {
256         /* Shortcut for GL functionality */
257         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
258
259         /* Get data. */
260         glw::GLint value = -1;
261
262         gl.getSamplerParameteriv(m_sampler_dsa, pname, &value);
263         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSamplerParameteriv have failed");
264
265         if (-1 == value)
266         {
267                 m_context.getTestContext().getLog()
268                         << tcu::TestLog::Message << "glGetSamplerParameteriv with parameter " << glu::getTextureParameterName(pname)
269                         << " has not returned anything and error has not been generated." << tcu::TestLog::EndMessage;
270
271                 return false;
272         }
273         else
274         {
275                 if (expected_value != value)
276                 {
277                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "glGetSamplerParameteriv with parameter "
278                                                                                                 << glu::getTextureParameterName(pname) << " has returned " << value
279                                                                                                 << ", however " << expected_value << " was expected."
280                                                                                                 << tcu::TestLog::EndMessage;
281
282                         return false;
283                 }
284         }
285
286         return true;
287 }
288
289 /** @brief Test Sampler Float Parameter.
290  *
291  *  @note The function may throw if unexpected error has occured.
292  *
293  *  @return True if test succeeded, false otherwise.
294  */
295 bool DefaultsTest::testSamplerFloatParameter(glw::GLenum pname, glw::GLfloat expected_value)
296 {
297         /* Shortcut for GL functionality */
298         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
299
300         /* Get data. */
301         glw::GLfloat value = -1.0;
302
303         gl.getSamplerParameterfv(m_sampler_dsa, pname, &value);
304         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSamplerParameteriv have failed");
305
306         if (de::abs(expected_value - value) > 0.015625f /* Precision */)
307         {
308                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "glGetSamplerParameterfv with parameter "
309                                                                                         << glu::getTextureParameterName(pname) << " has returned " << value
310                                                                                         << ", however " << expected_value << " was expected."
311                                                                                         << tcu::TestLog::EndMessage;
312
313                 return false;
314         }
315
316         return true;
317 }
318
319 /** @brief Test Sampler Float Parameter.
320  *
321  *  @note The function may throw if unexpected error has occured.
322  *
323  *  @return True if test succeeded, false otherwise.
324  */
325 bool DefaultsTest::testSamplerFloatVectorParameter(glw::GLenum pname, glw::GLfloat expected_value[4])
326 {
327         /* Shortcut for GL functionality */
328         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
329
330         /* Get data. */
331         glw::GLfloat value[4] = { -1.0, -1.0, -1.0, -1.0 };
332
333         gl.getSamplerParameterfv(m_sampler_dsa, pname, value);
334         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSamplerParameterfv have failed");
335
336         if ((de::abs(expected_value[0] - value[0]) > 0.015625f /* Precision */) ||
337                 (de::abs(expected_value[1] - value[1]) > 0.015625f /* Precision */) ||
338                 (de::abs(expected_value[2] - value[2]) > 0.015625f /* Precision */) ||
339                 (de::abs(expected_value[3] - value[3]) > 0.015625f /* Precision */))
340         {
341                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "glGetSamplerParameterfv with parameter "
342                                                                                         << glu::getTextureParameterName(pname) << " has returned [" << value[0]
343                                                                                         << ", " << value[1] << ", " << value[2] << ", " << value[3] << "], however "
344                                                                                         << expected_value << " was expected." << tcu::TestLog::EndMessage;
345
346                 return false;
347         }
348
349         return true;
350 }
351
352 /** @brief Release GL objects.
353  */
354 void DefaultsTest::clean()
355 {
356         /* Shortcut for GL functionality */
357         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
358
359         if (m_sampler_dsa)
360         {
361                 gl.deleteSamplers(1, &m_sampler_dsa);
362
363                 m_sampler_dsa = 0;
364         }
365 }
366
367 /******************************** Errors Test Implementation   ********************************/
368
369 /** @brief Errors Test constructor.
370  *
371  *  @param [in] context     OpenGL context.
372  */
373 ErrorsTest::ErrorsTest(deqp::Context& context) : deqp::TestCase(context, "samplers_errors", "Samplers Errors Test")
374 {
375         /* Intentionally left blank. */
376 }
377
378 /** @brief Iterate Errors Test cases.
379  *
380  *  @return Iteration result.
381  */
382 tcu::TestNode::IterateResult ErrorsTest::iterate()
383 {
384         /* Shortcut for GL functionality */
385         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
386
387         /* Get context setup. */
388         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
389         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
390
391         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
392         {
393                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
394
395                 return STOP;
396         }
397
398         /* Running tests. */
399         bool is_ok      = true;
400         bool is_error = false;
401
402         glw::GLuint sampler_dsa = 0;
403
404         try
405         {
406                 /* Check direct state creation. */
407                 gl.createSamplers(-1, &sampler_dsa);
408
409                 glw::GLenum error = GL_NO_ERROR;
410
411                 if (GL_INVALID_VALUE != (error = gl.getError()))
412                 {
413                         is_ok = false;
414
415                         /* Log. */
416                         m_context.getTestContext().getLog()
417                                 << tcu::TestLog::Message << "CreateSamplers has not generated INVALID_VALUE error when callded with "
418                                                                                         "negative number of samplers to be created."
419                                 << "Instead, " << glu::getErrorStr(error) << " error value was generated." << tcu::TestLog::EndMessage;
420                 }
421         }
422         catch (...)
423         {
424                 is_ok   = false;
425                 is_error = true;
426         }
427
428         /* Cleanup. */
429         if (sampler_dsa)
430         {
431                 gl.deleteSamplers(1, &sampler_dsa);
432
433                 sampler_dsa = 0;
434         }
435
436         /* Result's setup. */
437         if (is_ok)
438         {
439                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
440         }
441         else
442         {
443                 if (is_error)
444                 {
445                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
446                 }
447                 else
448                 {
449                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
450                 }
451         }
452
453         return STOP;
454 }
455
456 /******************************** Functional Test Implementation   ********************************/
457
458 /** @brief Functional Test constructor.
459  *
460  *  @param [in] context     OpenGL context.
461  */
462 FunctionalTest::FunctionalTest(deqp::Context& context)
463         : deqp::TestCase(context, "samplers_functional", "Samplers Functional Test")
464         , m_fbo(0)
465         , m_rbo(0)
466         , m_vao(0)
467         , m_to(0)
468         , m_so(0)
469         , m_po(0)
470 {
471         /* Intentionally left blank. */
472 }
473
474 /** @brief Iterate Functional Test cases.
475  *
476  *  @return Iteration result.
477  */
478 tcu::TestNode::IterateResult FunctionalTest::iterate()
479 {
480         /* Get context setup. */
481         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
482         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
483
484         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
485         {
486                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
487
488                 return STOP;
489         }
490
491         /* Running tests. */
492         bool is_ok      = true;
493         bool is_error = false;
494
495         try
496         {
497                 prepareFramebuffer();
498                 prepareVertexArrayObject();
499                 prepareProgram();
500                 prepareTexture();
501                 prepareSampler();
502                 draw();
503
504                 is_ok &= checkFramebufferContent();
505         }
506         catch (...)
507         {
508                 is_ok   = false;
509                 is_error = true;
510         }
511
512         /* Clean-up. */
513         clean();
514
515         /* Result's setup. */
516         if (is_ok)
517         {
518                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
519         }
520         else
521         {
522                 if (is_error)
523                 {
524                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
525                 }
526                 else
527                 {
528                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
529                 }
530         }
531
532         return STOP;
533 }
534
535 /** @brief Function prepares framebuffer with RGBA8 color attachment.
536  *         Viewport is set up. Content of the framebuffer is cleared.
537  *
538  *  @note The function may throw if unexpected error has occured.
539  */
540 void FunctionalTest::prepareFramebuffer()
541 {
542         /* Shortcut for GL functionality. */
543         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
544
545         /* Prepare framebuffer. */
546         gl.genFramebuffers(1, &m_fbo);
547         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
548
549         gl.genRenderbuffers(1, &m_rbo);
550         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
551
552         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
553         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
554
555         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
556         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
557
558         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1 /* x size */, 1 /* y size */);
559         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
560
561         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
562         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
563
564         if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
565         {
566                 throw 0;
567         }
568
569         gl.viewport(0, 0, 1, 1);
570         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
571
572         /* Clear framebuffer's content. */
573         gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
574         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
575
576         gl.clear(GL_COLOR_BUFFER_BIT);
577         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
578 }
579
580 /** @brief Function generate and bind empty vertex array object.
581  *
582  *  @note The function may throw if unexpected error has occured.
583  */
584 void FunctionalTest::prepareVertexArrayObject()
585 {
586         /* Shortcut for GL functionality */
587         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
588
589         gl.genVertexArrays(1, &m_vao);
590         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
591
592         gl.bindVertexArray(m_vao);
593         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
594 }
595
596 /** @brief Function builds test's GLSL program.
597  *         If succeded, the program will be set to be used.
598  *
599  *  @note The function may throw if unexpected error has occured.
600  */
601 void FunctionalTest::prepareProgram()
602 {
603         /* Shortcut for GL functionality */
604         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
605
606         struct Shader
607         {
608                 glw::GLchar const* const source;
609                 glw::GLenum const                type;
610                 glw::GLuint                              id;
611         } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
612
613         glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
614
615         try
616         {
617                 /* Create program. */
618                 m_po = gl.createProgram();
619                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
620
621                 /* Shader compilation. */
622
623                 for (glw::GLuint i = 0; i < shader_count; ++i)
624                 {
625                         if (DE_NULL != shader[i].source)
626                         {
627                                 shader[i].id = gl.createShader(shader[i].type);
628
629                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
630
631                                 gl.attachShader(m_po, shader[i].id);
632
633                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
634
635                                 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
636
637                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
638
639                                 gl.compileShader(shader[i].id);
640
641                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
642
643                                 glw::GLint status = GL_FALSE;
644
645                                 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
646                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
647
648                                 if (GL_FALSE == status)
649                                 {
650                                         glw::GLint log_size = 0;
651                                         gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
652                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
653
654                                         glw::GLchar* log_text = new glw::GLchar[log_size];
655
656                                         gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
657
658                                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
659                                                                                                                 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
660                                                                                                                 << "\n"
661                                                                                                                 << "Shader compilation error log:\n"
662                                                                                                                 << log_text << "\n"
663                                                                                                                 << "Shader source code:\n"
664                                                                                                                 << shader[i].source << "\n"
665                                                                                                                 << tcu::TestLog::EndMessage;
666
667                                         delete[] log_text;
668
669                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
670
671                                         throw 0;
672                                 }
673                         }
674                 }
675
676                 /* Link. */
677                 gl.linkProgram(m_po);
678
679                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
680
681                 glw::GLint status = GL_FALSE;
682
683                 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
684
685                 if (GL_TRUE == status)
686                 {
687                         for (glw::GLuint i = 0; i < shader_count; ++i)
688                         {
689                                 if (shader[i].id)
690                                 {
691                                         gl.detachShader(m_po, shader[i].id);
692
693                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
694                                 }
695                         }
696                 }
697                 else
698                 {
699                         glw::GLint log_size = 0;
700
701                         gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
702
703                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
704
705                         glw::GLchar* log_text = new glw::GLchar[log_size];
706
707                         gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
708
709                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
710                                                                                                 << log_text << "\n"
711                                                                                                 << tcu::TestLog::EndMessage;
712
713                         delete[] log_text;
714
715                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
716
717                         throw 0;
718                 }
719         }
720         catch (...)
721         {
722                 if (m_po)
723                 {
724                         gl.deleteProgram(m_po);
725
726                         m_po = 0;
727                 }
728         }
729
730         for (glw::GLuint i = 0; i < shader_count; ++i)
731         {
732                 if (0 != shader[i].id)
733                 {
734                         gl.deleteShader(shader[i].id);
735
736                         shader[i].id = 0;
737                 }
738         }
739
740         if (m_po)
741         {
742                 gl.useProgram(m_po);
743                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
744         }
745
746         if (0 == m_po)
747         {
748                 throw 0;
749         }
750 }
751
752 /** @brief Function prepares texture object with test's data.
753  *
754  *  @note The function may throw if unexpected error has occured.
755  */
756 void FunctionalTest::prepareTexture()
757 {
758         /* Shortcut for GL functionality */
759         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
760
761         gl.activeTexture(GL_TEXTURE0);
762         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture call failed.");
763
764         /* Texture creation and binding. */
765         gl.genTextures(1, &m_to);
766         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures call failed.");
767
768         gl.bindTexture(GL_TEXTURE_2D, m_to);
769         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture call failed.");
770
771         /* Uploading texture. */
772
773         gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
774         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D call failed.");
775
776         /* Setup fragment shader's sampler. */
777         glw::GLint location = 0;
778
779         gl.getUniformLocation(m_po, s_uniform_sampler);
780         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");
781
782         gl.uniform1i(location, 0);
783         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i call failed.");
784 }
785
786 /** @brief Function prepares sampler with test setup and binds it to unit 0.
787  *
788  *  @note The function may throw if unexpected error has occured.
789  */
790 void FunctionalTest::prepareSampler()
791 {
792         /* Shortcut for GL functionality. */
793         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
794
795         /* Sampler creation and setup. */
796         gl.createSamplers(1, &m_so);
797         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
798
799         gl.bindSampler(0, m_so);
800         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler have failed");
801
802         gl.samplerParameteri(m_so, GL_TEXTURE_WRAP_S, GL_REPEAT);
803         gl.samplerParameteri(m_so, GL_TEXTURE_WRAP_T, GL_REPEAT);
804         gl.samplerParameteri(m_so, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
805         gl.samplerParameteri(m_so, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
806         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri have failed");
807 }
808
809 /** @brief Function draws a quad.
810  *
811  *  @note The function may throw if unexpected error has occured.
812  */
813 void FunctionalTest::draw()
814 {
815         /* Shortcut for GL functionality. */
816         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
817
818         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
819         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays have failed");
820 }
821
822 /** @brief Check content of the framebuffer and compare it with expected data.
823  *
824  *  @note The function may throw if unexpected error has occured.
825  *
826  *  @return True if succeeded, false otherwise.
827  */
828 bool FunctionalTest::checkFramebufferContent()
829 {
830         /* Shortcut for GL functionality. */
831         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
832
833         /* Fetch framebuffer data. */
834         glw::GLubyte pixel[4] = { 0 };
835
836         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
837         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
838
839         /* Comparison with expected values. */
840         if ((s_texture_data[0] != pixel[0]) || (s_texture_data[1] != pixel[1]) || (s_texture_data[2] != pixel[2]) ||
841                 (s_texture_data[3] != pixel[3]))
842         {
843                 m_context.getTestContext().getLog()
844                         << tcu::TestLog::Message << "Frameuffer content (" << (unsigned int)pixel[0] << ", "
845                         << (unsigned int)pixel[1] << ", " << (unsigned int)pixel[2] << ", " << (unsigned int)pixel[3]
846                         << ") is different than expected (" << (unsigned int)s_texture_data[0] << ", "
847                         << (unsigned int)s_texture_data[1] << ", " << (unsigned int)s_texture_data[2] << ", "
848                         << (unsigned int)s_texture_data[3] << ")." << tcu::TestLog::EndMessage;
849
850                 return false;
851         }
852
853         return true;
854 }
855
856 /** @brief Release all GL objects.
857  */
858 void FunctionalTest::clean()
859 {
860         /* Shortcut for GL functionality. */
861         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
862
863         /* Release framebuffer. */
864         if (m_fbo)
865         {
866                 gl.deleteFramebuffers(1, &m_fbo);
867
868                 m_fbo = 0;
869         }
870
871         /* Release renderbuffer. */
872         if (m_rbo)
873         {
874                 gl.deleteRenderbuffers(1, &m_rbo);
875
876                 m_rbo = 0;
877         }
878
879         /* Release vertex array object. */
880         if (m_vao)
881         {
882                 gl.deleteVertexArrays(1, &m_vao);
883
884                 m_vao = 0;
885         }
886
887         /* Release texture. */
888         if (m_to)
889         {
890                 gl.deleteTextures(1, &m_to);
891
892                 m_to = 0;
893         }
894
895         /* Release sampler. */
896         if (m_so)
897         {
898                 gl.deleteSamplers(1, &m_so);
899
900                 m_so = 0;
901         }
902
903         /* Release GLSL program. */
904         if (m_po)
905         {
906                 gl.useProgram(0);
907
908                 gl.deleteProgram(m_po);
909
910                 m_po = 0;
911         }
912 }
913
914 /* Vertex shader source code. */
915 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 330\n"
916                                                                                                           "\n"
917                                                                                                           "void main()\n"
918                                                                                                           "{\n"
919                                                                                                           "    switch(gl_VertexID)\n"
920                                                                                                           "    {\n"
921                                                                                                           "        case 0:\n"
922                                                                                                           "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
923                                                                                                           "            break;\n"
924                                                                                                           "        case 1:\n"
925                                                                                                           "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
926                                                                                                           "            break;\n"
927                                                                                                           "        case 2:\n"
928                                                                                                           "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
929                                                                                                           "            break;\n"
930                                                                                                           "        case 3:\n"
931                                                                                                           "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
932                                                                                                           "            break;\n"
933                                                                                                           "    }\n"
934                                                                                                           "}\n";
935
936 /* Fragment shader source program. */
937 const glw::GLchar FunctionalTest::s_fragment_shader[] =
938         "#version 330\n"
939         "\n"
940         "uniform sampler2D texture_sampler;\n"
941         "\n"
942         "out vec4 color;\n"
943         "\n"
944         "void main()\n"
945         "{\n"
946         "    color = texture(texture_sampler, vec2(0.33333, 0.33333));\n"
947         "}\n";
948
949 /* Name of texture sampler uniform. */
950 const glw::GLchar FunctionalTest::s_uniform_sampler[] = "texture_sampler";
951
952 /* Test's texture data. */
953 const glw::GLubyte FunctionalTest::s_texture_data[] = {
954         0xFF, 0x00, 0x00, 0xFF, /* RED  */
955         0x00, 0xFF, 0x00, 0xFF, /* GREEN  */
956         0x00, 0x00, 0xFF, 0xFF, /* BLUE */
957         0xFF, 0xFF, 0x00, 0xFF  /* YELLOW */
958 };
959
960 } /* Samplers namespace. */
961 } /* DirectStateAccess namespace. */
962 } /* gl4cts namespace. */