569b9586c1e576b697fba44fe02a2f3498a4b9f5
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl3cTextureSizePromotion.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  * \file  gl3cTextureSizePromotionTests.hpp
26  * \brief Implements test classes for testing of texture internal format
27  promotion mechanism.
28  */ /*-------------------------------------------------------------------*/
29
30 #include "gl3cTextureSizePromotion.hpp"
31
32 #include "deMath.h"
33 #include "gluContextInfo.hpp"
34 #include "gluStrUtil.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuTestLog.hpp"
37
38 /* Stringify macro. */
39 #define _STR(s) STR(s)
40 #define STR(s) #s
41
42 namespace gl3cts
43 {
44 namespace TextureSizePromotion
45 {
46 Tests::Tests(deqp::Context& context)
47         : TestCaseGroup(context, "texture_size_promotion", "Verifies texture internal format size promotion mechanism.")
48 {
49         /* Left blank on purpose */
50 }
51
52 void Tests::init(void)
53 {
54         addChild(new TextureSizePromotion::FunctionalTest(m_context));
55 }
56
57 /*===========================================================================================================*/
58
59 FunctionalTest::FunctionalTest(deqp::Context& context)
60         : TestCase(context, "functional", "Verifies that texture internal format size promotion mechanism can be used.")
61         , m_vao(0)
62         , m_source_texture(0)
63         , m_destination_texture(0)
64         , m_framebuffer(0)
65         , m_program(0)
66         , m_max_samples(0)
67 {
68         /* Left blank on purpose */
69 }
70
71 tcu::TestNode::IterateResult FunctionalTest::iterate()
72 {
73         /* Get context setup. */
74         glu::ContextType context_type = m_context.getRenderContext().getType();
75         bool                     is_arb_texture_storage_multisample =
76                 m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
77
78         /* Prepare initial results. */
79         bool is_ok       = true;
80         bool was_error = false;
81
82         /* Iterate over test cases. */
83         try
84         {
85                 /* Only for OpenGL 3.1 context. */
86                 if (glu::contextSupports(context_type, glu::ApiType::core(3, 1)))
87                 {
88                         /* Generate and bind VAO. */
89                         prepareVertexArrayObject();
90
91                         /* For every required format */
92                         for (glw::GLuint i = 0; i < s_formats_size; ++i)
93                         {
94                                 /* Test only if format is required by context. */
95                                 if (glu::contextSupports(context_type, s_formats[i].required_by_context.getAPI()))
96                                 {
97                                         /* For every target. */
98                                         for (glw::GLuint j = 0; j < s_source_texture_targets_count; ++j)
99                                         {
100                                                 /* Test if it is supported by context or internal format. */
101                                                 if (isTargetMultisampled(s_source_texture_targets[j]))
102                                                 {
103                                                         if ((!is_arb_texture_storage_multisample) &&
104                                                                 (!glu::contextSupports(context_type, glu::ApiType::core(4, 3))))
105                                                         {
106                                                                 continue;
107                                                         }
108
109                                                         if (!s_formats[i]
110                                                                          .is_color_renderable) /* Multisampled textures need to be set using rendering. */
111                                                         {
112                                                                 continue;
113                                                         }
114
115                                                         if (isDepthType(s_formats[i]) || isStencilType(s_formats[i]))
116                                                         {
117                                                                 continue;
118                                                         }
119                                                 }
120
121                                                 if ((isDepthType(s_formats[i]) || isStencilType(s_formats[i])) &&
122                                                         (GL_TEXTURE_3D == s_source_texture_targets[j]))
123                                                 {
124                                                         continue;
125                                                 }
126
127                                                 /* Prepare source texture to be tested. */
128                                                 prepareSourceTexture(s_formats[i], s_source_texture_targets[j]);
129
130                                                 /* Check basic API queries for source texture. */
131                                                 is_ok = is_ok & checkSourceTextureSizeAndType(s_formats[i], s_source_texture_targets[j]);
132
133                                                 /* For every [R, G, B, A] component. */
134                                                 for (glw::GLuint k = 0; k < COMPONENTS_COUNT; ++k)
135                                                 {
136                                                         /* Prepare destination texture. */
137                                                         prepareDestinationTextureAndFramebuffer(s_formats[i], GL_TEXTURE_2D);
138
139                                                         /* Building program (throws on failure). */
140                                                         m_program =
141                                                                 prepareProgram(s_source_texture_targets[j], s_formats[i], ColorChannelSelector(k));
142
143                                                         /* Setup GL and draw. */
144                                                         makeProgramAndSourceTextureActive(s_source_texture_targets[j]);
145
146                                                         drawQuad();
147
148                                                         /* Check results. */
149                                                         is_ok = is_ok & checkDestinationTexture(s_formats[i], ColorChannelSelector(k),
150                                                                                                                                         s_source_texture_targets[j],
151                                                                                                                                         s_source_texture_targets_names[j]);
152
153                                                         /* Cleanup. */
154                                                         cleanDestinationTexture();
155                                                         cleanFramebuffer();
156                                                         cleanProgram();
157                                                 }
158
159                                                 cleanSourceTexture();
160                                         }
161                                 }
162                         }
163                 }
164         }
165         catch (...)
166         {
167                 /* Error have occured. */
168                 is_ok    = false;
169                 was_error = true;
170         }
171
172         /* Clean all. */
173
174         cleanSourceTexture();
175         cleanDestinationTexture();
176         cleanFramebuffer();
177         cleanProgram();
178         cleanVertexArrayObject();
179
180         /* Result's setup. */
181         if (is_ok)
182         {
183                 /* Log success. */
184                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Texture Size Promotion Test have passed."
185                                                                                         << tcu::TestLog::EndMessage;
186
187                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
188         }
189         else
190         {
191                 if (was_error)
192                 {
193                         /* Log error. */
194                         m_context.getTestContext().getLog() << tcu::TestLog::Message
195                                                                                                 << "Texture Size Promotion Test have approached error."
196                                                                                                 << tcu::TestLog::EndMessage;
197
198                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
199                 }
200                 else
201                 {
202                         /* Log fail. */
203                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Texture Size Promotion Test have failed."
204                                                                                                 << tcu::TestLog::EndMessage;
205
206                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
207                 }
208         }
209
210         /* End test. */
211         return tcu::TestNode::STOP;
212 }
213
214 void FunctionalTest::prepareVertexArrayObject()
215 {
216         /* GL functions object. */
217         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
218
219         gl.genVertexArrays(1, &m_vao);
220         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed");
221
222         gl.bindVertexArray(m_vao);
223         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray have failed");
224 }
225
226 void FunctionalTest::prepareSourceTexture(TextureInternalFormatDescriptor descriptor, glw::GLenum target)
227 {
228         /* GL functions object. */
229         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
230
231         /* Create and bind texture object. */
232         gl.genTextures(1, &m_source_texture);
233         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
234
235         gl.bindTexture(target, m_source_texture);
236         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
237
238         /* Select proper data set. */
239         glw::GLvoid* source_data   = DE_NULL;
240         glw::GLenum  source_type   = GL_NONE;
241         glw::GLenum  source_format = GL_RGBA;
242
243         if (isFloatType(descriptor)) /* For floating type. */
244         {
245                 source_data   = (glw::GLvoid*)s_source_texture_data_f;
246                 source_type   = GL_FLOAT;
247                 source_format = GL_RGBA;
248         }
249         else
250         {
251                 if (isFixedSignedType(descriptor)) /* For fixed signed type. */
252                 {
253                         source_data   = (glw::GLvoid*)s_source_texture_data_sn;
254                         source_type   = GL_FLOAT;
255                         source_format = GL_RGBA;
256                 }
257                 else
258                 {
259                         if (isFixedUnsignedType(descriptor)) /* For fixed unsigned type. */
260                         {
261                                 source_data   = (glw::GLvoid*)s_source_texture_data_n;
262                                 source_type   = GL_FLOAT;
263                                 source_format = GL_RGBA;
264                         }
265                         else
266                         {
267                                 if (isIntegerSignedType(descriptor)) /* For integral signed type. */
268                                 {
269                                         source_data   = (glw::GLvoid*)s_source_texture_data_i;
270                                         source_type   = GL_INT;
271                                         source_format = GL_RGBA_INTEGER;
272                                 }
273                                 else
274                                 {
275                                         if (isIntegerUnsignedType(descriptor)) /* For integral unsigned type. */
276                                         {
277                                                 source_data   = (glw::GLvoid*)s_source_texture_data_ui;
278                                                 source_type   = GL_UNSIGNED_INT;
279                                                 source_format = GL_RGBA_INTEGER;
280                                         }
281                                         else
282                                         {
283                                                 if (isDepthType(descriptor)) /* For depth type. */
284                                                 {
285                                                         source_data   = NULL;
286                                                         source_type   = GL_UNSIGNED_INT;
287                                                         source_format = GL_DEPTH_COMPONENT;
288                                                 }
289                                                 else
290                                                 {
291                                                         if (isStencilType(descriptor)) /* For stencil type. */
292                                                         {
293                                                                 source_data   = NULL;
294                                                                 source_type   = GL_UNSIGNED_INT;
295                                                                 source_format = GL_STENCIL_INDEX;
296                                                         }
297                                                 }
298                                         }
299                                 }
300                         }
301                 }
302         }
303
304         /* Prepare texture storage depending on the target. */
305         switch (target)
306         {
307         case GL_TEXTURE_1D:
308                 gl.texImage1D(target, 0, descriptor.internal_format, s_source_texture_size, 0, source_format, source_type,
309                                           source_data);
310                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
311                 break;
312         case GL_TEXTURE_1D_ARRAY:
313         case GL_TEXTURE_2D:
314         case GL_TEXTURE_RECTANGLE:
315                 gl.texImage2D(target, 0, descriptor.internal_format, s_source_texture_size, s_source_texture_size, 0,
316                                           source_format, source_type, source_data);
317                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
318                 break;
319         case GL_TEXTURE_2D_ARRAY:
320         case GL_TEXTURE_3D:
321                 gl.texImage3D(target, 0, descriptor.internal_format, s_source_texture_size, s_source_texture_size,
322                                           s_source_texture_size, 0, source_format, source_type, source_data);
323                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
324                 break;
325         case GL_TEXTURE_2D_MULTISAMPLE:
326         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
327                 renderDataIntoMultisampledTexture(descriptor, target);
328                 break;
329         default:
330                 throw 0;
331         }
332 }
333
334 void FunctionalTest::renderDataIntoMultisampledTexture(TextureInternalFormatDescriptor descriptor, glw::GLenum target)
335 {
336         /* GL functions object. */
337         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
338
339         /* Fetch limits. */
340         gl.getIntegerv(GL_MAX_SAMPLES, &m_max_samples);
341         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
342
343         if (m_max_samples == 0)
344         {
345                 m_max_samples = 1;
346         }
347
348         /* Setup target. */
349         glw::GLenum non_ms_target = (target == GL_TEXTURE_2D_MULTISAMPLE) ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY;
350
351         /* Cleanup required by prepareSourceTexture(...). */
352         cleanSourceTexture();
353
354         /* Prepare textures and program. */
355         prepareSourceTexture(descriptor, non_ms_target);
356
357         prepareDestinationTextureAndFramebuffer(descriptor, target);
358
359         m_program = prepareProgram(non_ms_target, descriptor, COMPONENTS_COUNT);
360
361         /* Setup GL and render texture. */
362         makeProgramAndSourceTextureActive(non_ms_target);
363
364         drawQuad();
365
366         /* Cleanup. */
367         cleanFramebuffer();
368         cleanSourceTexture();
369
370         /* Swpaing destination texture to source texture. */
371         m_source_texture = m_destination_texture;
372
373         m_destination_texture = 0;
374
375         /* Clean program. */
376         cleanProgram();
377 }
378
379 void FunctionalTest::prepareDestinationTextureAndFramebuffer(TextureInternalFormatDescriptor descriptor,
380                                                                                                                          glw::GLenum                                     target)
381 {
382         /* GL functions object. */
383         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
384
385         /* Get internal format. */
386         glw::GLenum internal_format = getDestinationFormatForChannel(descriptor);
387
388         /* Create framebuffer object. */
389         gl.genFramebuffers(1, &m_framebuffer);
390         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
391
392         gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
393         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
394
395         /* Create framebuffer's destination texture. */
396         gl.genTextures(1, &m_destination_texture);
397         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
398
399         gl.bindTexture(target, m_destination_texture);
400         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
401
402         /* Allocate texture storage and upload data for test rendering. */
403         if (target == GL_TEXTURE_2D)
404         {
405                 glw::GLenum  destination_format = GL_RED;
406                 glw::GLenum  destination_type   = GL_FLOAT;
407                 glw::GLvoid* destination_data   = (glw::GLvoid*)s_destination_texture_data_f;
408
409                 if (isIntegerSignedType(descriptor))
410                 {
411                         destination_format = GL_RED_INTEGER;
412                         destination_type   = GL_INT;
413                         destination_data   = (glw::GLvoid*)s_destination_texture_data_i;
414                 }
415
416                 if (isIntegerUnsignedType(descriptor))
417                 {
418                         destination_format = GL_RED_INTEGER;
419                         destination_type   = GL_UNSIGNED_INT;
420                         destination_data   = (glw::GLvoid*)s_destination_texture_data_ui;
421                 }
422
423                 gl.texImage2D(target, 0, internal_format, s_source_texture_size, s_source_texture_size, 0, destination_format,
424                                           destination_type, destination_data);
425                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
426
427                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_destination_texture, 0);
428                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D have failed");
429         }
430         else /* Allocate texture storage for uploading datat for multisampled targets (upload must be done via shader). */
431         {
432                 if (target == GL_TEXTURE_2D_MULTISAMPLE)
433                 {
434                         gl.texImage2DMultisample(target, m_max_samples - 1, descriptor.internal_format, s_source_texture_size,
435                                                                          s_source_texture_size, GL_TRUE);
436                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
437
438                         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_destination_texture, 0);
439                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D have failed");
440                 }
441                 else
442                 {
443                         gl.texImage3DMultisample(target, m_max_samples - 1, descriptor.internal_format, s_source_texture_size,
444                                                                          s_source_texture_size, s_source_texture_size, GL_TRUE);
445                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
446
447                         gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_destination_texture, 0, 0);
448                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D have failed");
449                 }
450         }
451
452         /* Check framebuffer completness. */
453         if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
454         {
455                 throw 0;
456         }
457
458         /* Setup viewport. */
459         gl.viewport(0, 0, s_source_texture_size, s_source_texture_size);
460         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
461 }
462
463 void FunctionalTest::makeProgramAndSourceTextureActive(glw::GLenum target)
464 {
465         /* GL functions object. */
466         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
467
468         /* Use GLSL program. */
469         gl.useProgram(m_program);
470         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram have failed");
471
472         /* Setup source texture. */
473         gl.activeTexture(GL_TEXTURE0);
474         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture have failed");
475
476         gl.bindTexture(target, m_source_texture);
477         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
478
479         glw::GLint location = gl.getUniformLocation(m_program, "data");
480         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation have failed");
481
482         gl.uniform1i(location, 0);
483         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i have failed");
484 }
485
486 bool FunctionalTest::checkSourceTextureSizeAndType(TextureInternalFormatDescriptor descriptor, glw::GLenum target)
487 {
488         /* GL functions object. */
489         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
490
491         /* query result storage */
492         glw::GLint red_size             = 0;
493         glw::GLint blue_size    = 0;
494         glw::GLint green_size   = 0;
495         glw::GLint alpha_size   = 0;
496         glw::GLint depth_size   = 0;
497         glw::GLint stencil_size = 0;
498
499         glw::GLint red_type   = 0;
500         glw::GLint green_type = 0;
501         glw::GLint blue_type  = 0;
502         glw::GLint alpha_type = 0;
503         glw::GLint depth_type = 0;
504
505         /* Bind texture */
506         gl.bindTexture(target, m_source_texture);
507         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
508
509         /* queries */
510         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_RED_SIZE, &red_size);
511         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
512         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
513         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
514         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_SIZE, &depth_size);
515         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_STENCIL_SIZE, &stencil_size);
516
517         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_RED_TYPE, &red_type);
518         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_TYPE, &green_type);
519         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_TYPE, &blue_type);
520         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_TYPE, &alpha_type);
521         gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_TYPE, &depth_type);
522
523         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
524
525         /* check expected values */
526         bool is_ok = true;
527
528         is_ok = is_ok && (red_size >= descriptor.min_red_size);
529         is_ok = is_ok && (green_size >= descriptor.min_green_size);
530         is_ok = is_ok && (blue_size >= descriptor.min_blue_size);
531         is_ok = is_ok && (alpha_size >= descriptor.min_alpha_size);
532         is_ok = is_ok && (depth_size >= descriptor.min_depth_size);
533         is_ok = is_ok && (stencil_size >= descriptor.min_stencil_size);
534
535         is_ok = is_ok && ((glw::GLenum)red_type == descriptor.expected_red_type);
536         is_ok = is_ok && ((glw::GLenum)green_type == descriptor.expected_green_type);
537         is_ok = is_ok && ((glw::GLenum)blue_type == descriptor.expected_blue_type);
538         is_ok = is_ok && ((glw::GLenum)alpha_type == descriptor.expected_alpha_type);
539         is_ok = is_ok && ((glw::GLenum)depth_type == descriptor.expected_depth_type);
540
541         /* Log on failure. */
542         if (!is_ok)
543         {
544                 m_context.getTestContext().getLog()
545                         << tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
546                         << " have failed during glGetTexLevelParameteriv query. "
547                         << "Expected red size = " << descriptor.min_red_size
548                         << ", expected green size = " << descriptor.min_green_size
549                         << ", expected blue size = " << descriptor.min_blue_size
550                         << ", expected alpha size = " << descriptor.min_alpha_size
551                         << ", expected depth size = " << descriptor.min_depth_size
552                         << ", expected stencil size = " << descriptor.min_stencil_size << ". Queried red size = " << red_size
553                         << ", queried green size = " << green_size << ", queried blue size = " << blue_size
554                         << ", queried alpha size = " << alpha_size << ", queried depth size = " << depth_size
555                         << ", queried stencil size = " << stencil_size << ". "
556                         << "Expected red type = " << glu::getTypeStr(descriptor.expected_red_type)
557                         << ", expected green type = " << glu::getTypeStr(descriptor.expected_green_type)
558                         << ", expected blue type = " << glu::getTypeStr(descriptor.expected_blue_type)
559                         << ", expected alpha type = " << glu::getTypeStr(descriptor.expected_alpha_type)
560                         << ", expected depth type = " << glu::getTypeStr(descriptor.expected_depth_type)
561                         << ". Queried red type = " << glu::getTypeStr(red_type)
562                         << ", queried green type = " << glu::getTypeStr(green_type)
563                         << ", queried blue type = " << glu::getTypeStr(blue_type)
564                         << ", queried alpha type = " << glu::getTypeStr(alpha_type)
565                         << ", queried depth type = " << glu::getTypeStr(depth_type) << "." << tcu::TestLog::EndMessage;
566         }
567
568         /* return results. */
569         return is_ok;
570 }
571
572 glw::GLenum FunctionalTest::getDestinationFormatForChannel(TextureInternalFormatDescriptor descriptor)
573 {
574         if (isFloatType(descriptor))
575         {
576                 return GL_R32F;
577         }
578
579         if (isFixedUnsignedType(descriptor))
580         {
581                 return GL_R16;
582         }
583
584         if (isFixedSignedType(descriptor))
585         {
586                 return GL_R16_SNORM;
587         }
588
589         if (isIntegerUnsignedType(descriptor))
590         {
591                 return GL_R32UI;
592         }
593
594         if (isIntegerSignedType(descriptor))
595         {
596                 return GL_R32I;
597         }
598
599         return GL_R32F;
600 }
601
602 glw::GLuint FunctionalTest::prepareProgram(glw::GLenum target, TextureInternalFormatDescriptor descriptor,
603                                                                                    ColorChannelSelector channel)
604 {
605         /* GL functions object. */
606         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
607
608         /* Preparing sampler name and textelFetch arguments */
609         std::string sampler_name                           = "";
610         std::string texel_fetch_arguments_tail = "";
611
612         switch (target)
613         {
614         case GL_TEXTURE_1D:
615                 sampler_name                       = "sampler1D";
616                 texel_fetch_arguments_tail = "0, 0";
617                 break;
618         case GL_TEXTURE_2D:
619                 sampler_name                       = "sampler2D";
620                 texel_fetch_arguments_tail = "ivec2(0), 0";
621                 break;
622         case GL_TEXTURE_1D_ARRAY:
623                 sampler_name                       = "sampler1DArray";
624                 texel_fetch_arguments_tail = "ivec2(0), 0";
625                 break;
626         case GL_TEXTURE_RECTANGLE:
627                 sampler_name                       = "sampler2DRect";
628                 texel_fetch_arguments_tail = "ivec2(0)";
629                 break;
630         case GL_TEXTURE_2D_ARRAY:
631                 sampler_name                       = "sampler2DArray";
632                 texel_fetch_arguments_tail = "ivec3(0), 0";
633                 break;
634         case GL_TEXTURE_3D:
635                 sampler_name                       = "sampler3D";
636                 texel_fetch_arguments_tail = "ivec3(0), 0";
637                 break;
638         case GL_TEXTURE_2D_MULTISAMPLE:
639                 sampler_name                       = "sampler2DMS";
640                 texel_fetch_arguments_tail = "ivec2(0), ";
641                 texel_fetch_arguments_tail.append(Utilities::itoa(m_max_samples - 1));
642                 break;
643         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
644                 sampler_name                       = "sampler2DMSArray";
645                 texel_fetch_arguments_tail = "ivec3(0), ";
646                 texel_fetch_arguments_tail.append(Utilities::itoa(m_max_samples - 1));
647                 break;
648         default:
649                 throw 0;
650         }
651
652         /* Preparing component selector name */
653         std::string component_name = "";
654
655         switch (channel)
656         {
657         case RED_COMPONENT:
658                 component_name = ".r";
659                 break;
660         case GREEN_COMPONENT:
661                 component_name = ".g";
662                 break;
663         case BLUE_COMPONENT:
664                 component_name = ".b";
665                 break;
666         case ALPHA_COMPONENT:
667                 component_name = ".a";
668                 break;
669         case COMPONENTS_COUNT:
670                 break;
671         default:
672                 throw 0;
673         }
674
675         /* Preparing output type name and sampler prefix */
676         std::string type_name     = "";
677         std::string sampler_prefix = "";
678
679         if (isFloatType(descriptor) || isFixedSignedType(descriptor) || isFixedUnsignedType(descriptor) ||
680                 isDepthType(descriptor) || isStencilType(descriptor))
681         {
682                 if (channel == COMPONENTS_COUNT)
683                 {
684                         type_name = "vec4";
685                 }
686                 else
687                 {
688                         type_name = "float";
689                 }
690                 sampler_prefix = "";
691         }
692         else
693         {
694                 if (isIntegerSignedType(descriptor))
695                 {
696                         if (channel == COMPONENTS_COUNT)
697                         {
698                                 type_name = "ivec4";
699                         }
700                         else
701                         {
702                                 type_name = "int";
703                         }
704                         sampler_prefix = "i";
705                 }
706                 else
707                 {
708                         if (channel == COMPONENTS_COUNT)
709                         {
710                                 type_name = "uvec4";
711                         }
712                         else
713                         {
714                                 type_name = "uint";
715                         }
716                         sampler_prefix = "u";
717                 }
718         }
719
720         std::string template_verison = "#version 150";
721
722         /* Preprocessing fragment shader source code. */
723         std::string fragment_shader = s_fragment_shader_template;
724
725         fragment_shader = Utilities::preprocessString(fragment_shader, "TEMPLATE_TYPE", type_name);
726         fragment_shader =
727                 Utilities::preprocessString(fragment_shader, "TEMPLATE_SAMPLER", sampler_prefix.append(sampler_name));
728         fragment_shader =
729                 Utilities::preprocessString(fragment_shader, "TEMPLATE_TEXEL_FETCH_ARGUMENTS", texel_fetch_arguments_tail);
730         fragment_shader = Utilities::preprocessString(fragment_shader, "TEMPLATE_COMPONENT", component_name);
731
732         /* Building program. */
733         glw::GLuint program =
734                 Utilities::buildProgram(gl, m_context.getTestContext().getLog(), s_vertex_shader_code, fragment_shader.c_str());
735
736         if (0 == program)
737         {
738                 throw 0;
739         }
740
741         /* Return program name. */
742         return program;
743 }
744
745 void FunctionalTest::drawQuad()
746 {
747         /* GL functions object. */
748         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
749
750         /* Draw quad. */
751         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
752         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays have failed");
753 }
754
755 void FunctionalTest::cleanSourceTexture()
756 {
757         /* GL functions object. */
758         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
759
760         /* Delete object. */
761         if (m_source_texture)
762         {
763                 gl.deleteTextures(1, &m_source_texture);
764                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures have failed");
765
766                 m_source_texture = 0;
767         }
768 }
769
770 void FunctionalTest::cleanDestinationTexture()
771 {
772         /* GL functions object. */
773         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
774
775         /* Delete object. */
776         if (m_destination_texture)
777         {
778                 gl.deleteTextures(1, &m_destination_texture);
779
780                 m_destination_texture = 0;
781         }
782 }
783
784 void FunctionalTest::cleanFramebuffer()
785 {
786         /* GL functions object. */
787         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
788
789         /* Delete object. */
790         if (m_framebuffer)
791         {
792                 gl.deleteFramebuffers(1, &m_framebuffer);
793
794                 m_framebuffer = 0;
795         }
796 }
797
798 void FunctionalTest::cleanProgram()
799 {
800         /* GL functions object. */
801         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
802
803         /* Delete object. */
804         if (m_program)
805         {
806                 gl.useProgram(0);
807
808                 gl.deleteProgram(m_program);
809
810                 m_program = 0;
811         }
812 }
813
814 void FunctionalTest::cleanVertexArrayObject()
815 {
816         /* GL functions object. */
817         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
818
819         /* Delete object. */
820         if (m_vao)
821         {
822                 gl.deleteVertexArrays(1, &m_vao);
823
824                 m_vao = 0;
825         }
826 }
827
828 bool FunctionalTest::checkDestinationTexture(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel,
829                                                                                          glw::GLenum target, const glw::GLchar* target_name)
830 {
831         /* GL functions object. */
832         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
833
834         /* Check depending on format. */
835         if (isFloatType(descriptor) || isDepthType(descriptor) || isStencilType(descriptor))
836         {
837                 /* Fetch results from destination texture (attached to current framebuffer). */
838                 glw::GLfloat pixel = 3.1415927f;
839                 gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
840                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
841
842                 /* Setup expected value. */
843                 glw::GLfloat expected_value = isChannelTypeNone(descriptor, channel) ?
844                                                                                   ((channel == ALPHA_COMPONENT) ? 1.f : 0.f) :
845                                                                                   s_source_texture_data_f[channel];
846
847                 /* Compare expected and fetched values. */
848                 if (fabs(pixel - expected_value) <= getMinPrecision(descriptor, channel))
849                 {
850                         /* Test succeeded*/
851                         return true;
852                 }
853                 else
854                 {
855                         /* Log failure. */
856                         m_context.getTestContext().getLog()
857                                 << tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
858                                 << " have failed during functional test of " << s_color_channel_names[channel]
859                                 << " channel with target " << target_name << ". Expected value = " << expected_value
860                                 << " read value = " << pixel << "." << tcu::TestLog::EndMessage;
861                 }
862         }
863         else
864         {
865                 if (isFixedSignedType(descriptor))
866                 {
867                         /* Fetch results from destination texture (attached to current framebuffer). */
868                         glw::GLfloat pixel = 3.1415927f;
869                         gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
870                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
871
872                         /* Setup expected value. */
873                         glw::GLfloat expected_value = isChannelTypeNone(descriptor, channel) ?
874                                                                                           ((channel == ALPHA_COMPONENT) ? 1.f : 0.f) :
875                                                                                           s_source_texture_data_sn[channel];
876
877                         /* Compare expected and fetched values. */
878                         if (fabs(pixel - expected_value) <= getMinPrecision(descriptor, channel))
879                         {
880                                 /* Test succeeded*/
881                                 return true;
882                         }
883                         else
884                         {
885                                 /* Log failure. */
886                                 m_context.getTestContext().getLog()
887                                         << tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
888                                         << " have failed during functional test of " << s_color_channel_names[channel]
889                                         << " channel with target " << target_name << ". Expected value = " << expected_value
890                                         << " read value = " << pixel << "." << tcu::TestLog::EndMessage;
891                         }
892                 }
893                 else
894                 {
895                         if (isFixedUnsignedType(descriptor))
896                         {
897                                 /* Fetch results from destination texture (attached to current framebuffer). */
898                                 glw::GLfloat pixel = 3.1415927f;
899                                 gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
900                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
901
902                                 /* Setup expected value. */
903                                 glw::GLfloat expected_value = isChannelTypeNone(descriptor, channel) ?
904                                                                                                   ((channel == ALPHA_COMPONENT) ? 1.f : 0.f) :
905                                                                                                   s_source_texture_data_n[channel];
906
907                                 /* For sRGB internal formats convert value to linear space. */
908                                 if (descriptor.is_sRGB && (channel < ALPHA_COMPONENT))
909                                 {
910                                         expected_value = convert_from_sRGB(expected_value);
911
912                                         if (isTargetMultisampled(
913                                                         target)) /* In multisampled targets two conversions are made (in upload and in shader) */
914                                         {
915                                                 expected_value = convert_from_sRGB(expected_value);
916                                         }
917                                 }
918
919                                 /* Compare expected and fetched values. */
920                                 if (fabs(pixel - expected_value) <= getMinPrecision(descriptor, channel))
921                                 {
922                                         /* Test succeeded*/
923                                         return true;
924                                 }
925                                 else
926                                 {
927                                         /* Log failure. */
928                                         m_context.getTestContext().getLog()
929                                                 << tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
930                                                 << " have failed during functional test of " << s_color_channel_names[channel]
931                                                 << " channel with target " << target_name << ". Expected value = " << expected_value
932                                                 << " read value = " << pixel << "." << tcu::TestLog::EndMessage;
933                                 }
934                         }
935                         else
936                         {
937                                 if (isIntegerSignedType(descriptor))
938                                 {
939                                         /* Fetch results from destination texture (attached to current framebuffer). */
940                                         glw::GLint pixel = 5;
941                                         gl.readPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_INT, &pixel);
942                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
943
944                                         /* Setup expected value. */
945                                         glw::GLint expected_value = isChannelTypeNone(descriptor, channel) ?
946                                                                                                         ((channel == ALPHA_COMPONENT) ? 1 : 0) :
947                                                                                                         s_source_texture_data_i[channel];
948
949                                         /* Compare expected and fetched values. */
950                                         if (pixel == expected_value)
951                                         {
952                                                 /* Test succeeded*/
953                                                 return true;
954                                         }
955                                         else
956                                         {
957                                                 /* Log failure. */
958                                                 m_context.getTestContext().getLog()
959                                                         << tcu::TestLog::Message << "Promotion from internal format "
960                                                         << descriptor.internal_format_name << " have failed during functional test of "
961                                                         << s_color_channel_names[channel] << " channel with target " << target_name
962                                                         << ". Expected value = " << expected_value << " read value = " << pixel << "."
963                                                         << tcu::TestLog::EndMessage;
964                                         }
965                                 }
966                                 else
967                                 {
968                                         if (isIntegerUnsignedType(descriptor))
969                                         {
970                                                 /* Fetch results from destination texture (attached to current framebuffer). */
971                                                 glw::GLuint pixel = 5;
972                                                 gl.readPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixel);
973                                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
974
975                                                 /* Setup expected value. */
976                                                 glw::GLuint expected_value = isChannelTypeNone(descriptor, channel) ?
977                                                                                                                  ((channel == ALPHA_COMPONENT) ? 1 : 0) :
978                                                                                                                  s_source_texture_data_ui[channel];
979
980                                                 /* Compare expected and fetched values. */
981                                                 if (pixel == expected_value)
982                                                 {
983                                                         /* Test succeeded*/
984                                                         return true;
985                                                 }
986                                                 else
987                                                 {
988                                                         /* Log failure. */
989                                                         m_context.getTestContext().getLog()
990                                                                 << tcu::TestLog::Message << "Promotion from internal format "
991                                                                 << descriptor.internal_format_name << " have failed during functional test of "
992                                                                 << s_color_channel_names[channel] << " channel with target " << target_name
993                                                                 << ". Expected value = " << expected_value << " read value = " << pixel << "."
994                                                                 << tcu::TestLog::EndMessage;
995                                                 }
996                                         }
997                                 }
998                         }
999                 }
1000         }
1001
1002         /* Test failed. */
1003         return false;
1004 }
1005
1006 bool FunctionalTest::isFloatType(TextureInternalFormatDescriptor descriptor)
1007 {
1008         return (GL_FLOAT == descriptor.expected_red_type) || (GL_FLOAT == descriptor.expected_green_type) ||
1009                    (GL_FLOAT == descriptor.expected_blue_type) || (GL_FLOAT == descriptor.expected_alpha_type);
1010 }
1011
1012 bool FunctionalTest::isFixedSignedType(TextureInternalFormatDescriptor descriptor)
1013 {
1014         return (GL_SIGNED_NORMALIZED == descriptor.expected_red_type) ||
1015                    (GL_SIGNED_NORMALIZED == descriptor.expected_green_type) ||
1016                    (GL_SIGNED_NORMALIZED == descriptor.expected_blue_type) ||
1017                    (GL_SIGNED_NORMALIZED == descriptor.expected_alpha_type);
1018 }
1019
1020 bool FunctionalTest::isFixedUnsignedType(TextureInternalFormatDescriptor descriptor)
1021 {
1022         return (GL_UNSIGNED_NORMALIZED == descriptor.expected_red_type) ||
1023                    (GL_UNSIGNED_NORMALIZED == descriptor.expected_green_type) ||
1024                    (GL_UNSIGNED_NORMALIZED == descriptor.expected_blue_type) ||
1025                    (GL_UNSIGNED_NORMALIZED == descriptor.expected_alpha_type);
1026 }
1027
1028 bool FunctionalTest::isIntegerSignedType(TextureInternalFormatDescriptor descriptor)
1029 {
1030         return (GL_INT == descriptor.expected_red_type) || (GL_INT == descriptor.expected_green_type) ||
1031                    (GL_INT == descriptor.expected_blue_type) || (GL_INT == descriptor.expected_alpha_type);
1032 }
1033
1034 bool FunctionalTest::isIntegerUnsignedType(TextureInternalFormatDescriptor descriptor)
1035 {
1036         return (GL_UNSIGNED_INT == descriptor.expected_red_type) || (GL_UNSIGNED_INT == descriptor.expected_green_type) ||
1037                    (GL_UNSIGNED_INT == descriptor.expected_blue_type) || (GL_UNSIGNED_INT == descriptor.expected_alpha_type);
1038 }
1039
1040 bool FunctionalTest::isDepthType(TextureInternalFormatDescriptor descriptor)
1041 {
1042         return (GL_NONE != descriptor.expected_depth_type);
1043 }
1044
1045 bool FunctionalTest::isStencilType(TextureInternalFormatDescriptor descriptor)
1046 {
1047         return (descriptor.min_stencil_size > 0);
1048 }
1049
1050 bool FunctionalTest::isChannelTypeNone(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel)
1051 {
1052         switch (channel)
1053         {
1054         case RED_COMPONENT:
1055                 return (GL_NONE == descriptor.expected_red_type);
1056         case GREEN_COMPONENT:
1057                 return (GL_NONE == descriptor.expected_green_type);
1058         case BLUE_COMPONENT:
1059                 return (GL_NONE == descriptor.expected_blue_type);
1060         case ALPHA_COMPONENT:
1061                 return (GL_NONE == descriptor.expected_alpha_type);
1062         default:
1063                 throw 0;
1064         }
1065
1066         return false;
1067 }
1068
1069 glw::GLfloat FunctionalTest::getMinPrecision(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel)
1070 {
1071         /* Select channel data. */
1072         glw::GLenum type = GL_NONE;
1073         glw::GLuint size = 0;
1074
1075         switch (channel)
1076         {
1077         case RED_COMPONENT:
1078                 type = descriptor.expected_red_type;
1079                 size = descriptor.min_red_size;
1080                 break;
1081         case GREEN_COMPONENT:
1082                 type = descriptor.expected_green_type;
1083                 size = descriptor.min_green_size;
1084                 break;
1085         case BLUE_COMPONENT:
1086                 type = descriptor.expected_blue_type;
1087                 size = descriptor.min_blue_size;
1088                 break;
1089         case ALPHA_COMPONENT:
1090                 type = descriptor.expected_alpha_type;
1091                 size = descriptor.min_alpha_size;
1092                 break;
1093         default:
1094                 throw 0;
1095         }
1096
1097         /* If it is empty channel. */
1098         if ((type == GL_NONE) || (size == 0))
1099         {
1100                 return 0.1f;
1101         }
1102
1103         /* If float type. */
1104         if (isFloatType(descriptor))
1105         {
1106                 switch (size)
1107                 {
1108                 case 32:
1109                         return 0.00001f; /* specification GL4.5 core constant */
1110                 case 16:
1111                         return 1.f / 1024.f; /* specification GL4.5 core 10 bit mantisa constant */
1112                 case 11:
1113                         return 1.f / 64.f; /* specification GL4.5 core 6 bit mantisa constant */
1114                 case 10:
1115                         return 1.f / 32.f; /* specification GL4.5 core 5 bit mantisa constant */
1116                 default:
1117                         return 0.00001f;
1118                 }
1119         }
1120
1121         /* Fixed types precision */
1122         if (isFixedSignedType(descriptor))
1123         {
1124                 return (float)(1.0 / pow(2.0, (double)(size - 1 /* sign bit */)));
1125         }
1126
1127         if (isFixedUnsignedType(descriptor))
1128         {
1129                 return (float)(1.0 / pow(2.0, (double)(size)));
1130         }
1131
1132         /* other aka (unsigned) integer */
1133         return 1;
1134 }
1135
1136 bool FunctionalTest::isTargetMultisampled(glw::GLenum target)
1137 {
1138         return (GL_TEXTURE_2D_MULTISAMPLE == target) || (GL_TEXTURE_2D_MULTISAMPLE_ARRAY == target);
1139 }
1140
1141 float FunctionalTest::convert_from_sRGB(float value)
1142 {
1143         /* For reference check OpenGL specification (eg. OpenGL 4.5 core profile specification chapter 8.24 */
1144         if (value > 0.04045f)
1145         {
1146                 return deFloatPow((value + 0.055f) / 1.055f, 2.4f);
1147         }
1148
1149         return value / 12.92f;
1150 }
1151
1152 const glw::GLfloat FunctionalTest::s_source_texture_data_f[] = { 0.125f, 0.25f, 0.5f, 0.75f };
1153
1154 const glw::GLfloat FunctionalTest::s_source_texture_data_n[] = { 0.125f, 0.25f, 0.5f, 0.75f };
1155
1156 const glw::GLfloat FunctionalTest::s_source_texture_data_sn[] = { -0.125f, 0.25f, -0.5f, 0.75f };
1157
1158 const glw::GLint FunctionalTest::s_source_texture_data_i[] = { -1, 2, -3, 4 };
1159
1160 const glw::GLuint FunctionalTest::s_source_texture_data_ui[] = { 1, 2, 3, 4 };
1161
1162 const glw::GLfloat FunctionalTest::s_destination_texture_data_f[] = {
1163         5.f
1164 }; /* False data for destination texture to be overwriten. */
1165
1166 const glw::GLint FunctionalTest::s_destination_texture_data_i[] = {
1167         -5
1168 }; /* False data for destination texture to be overwriten. */
1169
1170 const glw::GLuint FunctionalTest::s_destination_texture_data_ui[] = {
1171         5
1172 }; /* False data for destination texture to be overwriten. */
1173
1174 const glw::GLenum FunctionalTest::s_source_texture_targets[] = {
1175         GL_TEXTURE_1D,           GL_TEXTURE_2D, GL_TEXTURE_1D_ARRAY,       GL_TEXTURE_RECTANGLE,
1176         GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY
1177 };
1178
1179 const glw::GLchar* FunctionalTest::s_source_texture_targets_names[] = {
1180         STR(GL_TEXTURE_1D),               STR(GL_TEXTURE_2D), STR(GL_TEXTURE_1D_ARRAY),           STR(GL_TEXTURE_RECTANGLE),
1181         STR(GL_TEXTURE_2D_ARRAY), STR(GL_TEXTURE_3D), STR(GL_TEXTURE_2D_MULTISAMPLE), STR(GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1182 };
1183
1184 const glw::GLuint FunctionalTest::s_source_texture_targets_count =
1185         sizeof(s_source_texture_targets) / sizeof(s_source_texture_targets[0]);
1186
1187 const glw::GLuint FunctionalTest::s_source_texture_size = 1;
1188
1189 const glw::GLchar* FunctionalTest::s_color_channel_names[] = { "red", "green", "blue", "alpha", "all" };
1190
1191 const FunctionalTest::TextureInternalFormatDescriptor FunctionalTest::s_formats[] = {
1192         /*      context version,                                                        internal format,                internal format name,    is sRGB,       CR,size{R,      G,      B,      A,      D,      S},     type of R,                              type of G,                              type of B,                              type of A,                              type of depth                   */
1193         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R8, STR(GL_R8), false, true, 8, 0, 0, 0, 0, 0,
1194           GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1195         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_R8_SNORM, STR(GL_R8_SNORM), false, true, 8, 0, 0, 0, 0, 0,
1196           GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1197         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16, STR(GL_R16), false, true, 16, 0, 0, 0, 0, 0,
1198           GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1199         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_R16_SNORM, STR(GL_R16_SNORM), false, true, 16, 0, 0, 0, 0, 0,
1200           GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1201         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG8, STR(GL_RG8), false, true, 8, 8, 0, 0, 0, 0,
1202           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
1203         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RG8_SNORM, STR(GL_RG8_SNORM), false, true, 8, 8, 0, 0, 0, 0,
1204           GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
1205         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16, STR(GL_RG16), false, true, 16, 16, 0, 0, 0, 0,
1206           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
1207         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RG16_SNORM, STR(GL_RG16_SNORM), false, true, 16, 16, 0, 0, 0, 0,
1208           GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
1209         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_R3_G3_B2, STR(GL_R3_G3_B2), false, true, 3, 3, 2, 0, 0, 0,
1210           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1211         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB4, STR(GL_RGB4), false, true, 4, 4, 4, 0, 0, 0,
1212           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1213         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB5, STR(GL_RGB5), false, true, 5, 5, 5, 0, 0, 0,
1214           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1215         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB8, STR(GL_RGB8), false, true, 8, 8, 8, 0, 0, 0,
1216           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1217         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGB8_SNORM, STR(GL_RGB8_SNORM), false, true, 8, 8, 8, 0, 0, 0,
1218           GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE },
1219         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB10, STR(GL_RGB10), false, true, 10, 10, 10, 0, 0, 0,
1220           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1221         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB12, STR(GL_RGB12), false, true, 12, 12, 12, 0, 0, 0,
1222           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1223         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16, STR(GL_RGB16), false, true, 16, 16, 16, 0, 0, 0,
1224           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1225         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGB16_SNORM, STR(GL_RGB16_SNORM), false, true, 16, 16, 16, 0, 0, 0,
1226           GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE },
1227         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGBA2, STR(GL_RGBA2), false, true, 2, 2, 2, 2, 0, 0,
1228           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1229         { glu::ContextType(4, 2, glu::PROFILE_CORE), GL_RGBA4, STR(GL_RGBA4), false, true, 4, 4, 4, 4, 0, 0,
1230           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1231         { glu::ContextType(4, 2, glu::PROFILE_CORE), GL_RGB5_A1, STR(GL_RGB5_A1), false, true, 5, 5, 5, 1, 0, 0,
1232           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1233         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA8, STR(GL_RGBA8), false, true, 8, 8, 8, 8, 0, 0,
1234           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1235         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGBA8_SNORM, STR(GL_RGBA8_SNORM), false, true, 8, 8, 8, 8, 0, 0,
1236           GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE },
1237         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB10_A2, STR(GL_RGB10_A2), false, true, 10, 10, 10, 2, 0, 0,
1238           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1239         { glu::ContextType(3, 3, glu::PROFILE_CORE), GL_RGB10_A2UI, STR(GL_RGB10_A2UI), false, true, 10, 10, 10, 2, 0, 0,
1240           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
1241         { glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGBA12, STR(GL_RGBA12), false, true, 12, 12, 12, 12, 0, 0,
1242           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1243         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16, STR(GL_RGBA16), false, true, 16, 16, 16, 16, 0, 0,
1244           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1245         { glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGBA16_SNORM, STR(GL_RGBA16_SNORM), false, true, 16, 16, 16, 16, 0,
1246           0, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE },
1247         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_SRGB8, STR(GL_SRGB8), true, true, 8, 8, 8, 0, 0, 0,
1248           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
1249         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_SRGB8_ALPHA8, STR(GL_SRGB8_ALPHA8), true, true, 8, 8, 8, 8, 0, 0,
1250           GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
1251         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16F, STR(GL_R16F), false, true, 16, 0, 0, 0, 0, 0, GL_FLOAT,
1252           GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1253         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16F, STR(GL_RG16F), false, true, 16, 16, 0, 0, 0, 0, GL_FLOAT,
1254           GL_FLOAT, GL_NONE, GL_NONE, GL_NONE },
1255         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16F, STR(GL_RGB16F), false, true, 16, 16, 16, 0, 0, 0, GL_FLOAT,
1256           GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
1257         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16F, STR(GL_RGBA16F), false, true, 16, 16, 16, 16, 0, 0,
1258           GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_NONE },
1259         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R32F, STR(GL_R32F), false, true, 32, 0, 0, 0, 0, 0, GL_FLOAT,
1260           GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1261         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG32F, STR(GL_RG32F), false, true, 32, 32, 0, 0, 0, 0, GL_FLOAT,
1262           GL_FLOAT, GL_NONE, GL_NONE, GL_NONE },
1263         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB32F, STR(GL_RGB32F), false, true, 32, 32, 32, 0, 0, 0, GL_FLOAT,
1264           GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
1265         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA32F, STR(GL_RGBA32F), false, true, 32, 32, 32, 32, 0, 0,
1266           GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_NONE },
1267         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R11F_G11F_B10F, STR(GL_R11F_G11F_B10F), false, true, 11, 11, 10, 0,
1268           0, 0, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
1269         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB9_E5, STR(GL_RGB9_E5), false, false, 9, 9, 9, 0, 0, 0, GL_FLOAT,
1270           GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
1271         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R8I, STR(GL_R8I), false, true, 8, 0, 0, 0, 0, 0, GL_INT, GL_NONE,
1272           GL_NONE, GL_NONE, GL_NONE },
1273         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R8UI, STR(GL_R8UI), false, true, 8, 0, 0, 0, 0, 0, GL_UNSIGNED_INT,
1274           GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1275         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16I, STR(GL_R16I), false, true, 16, 0, 0, 0, 0, 0, GL_INT, GL_NONE,
1276           GL_NONE, GL_NONE, GL_NONE },
1277         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16UI, STR(GL_R16UI), false, true, 16, 0, 0, 0, 0, 0,
1278           GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1279         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R32I, STR(GL_R32I), false, true, 32, 0, 0, 0, 0, 0, GL_INT, GL_NONE,
1280           GL_NONE, GL_NONE, GL_NONE },
1281         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R32UI, STR(GL_R32UI), false, true, 32, 0, 0, 0, 0, 0,
1282           GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
1283         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG8I, STR(GL_RG8I), false, true, 8, 8, 0, 0, 0, 0, GL_INT, GL_INT,
1284           GL_NONE, GL_NONE, GL_NONE },
1285         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG8UI, STR(GL_RG8UI), false, true, 8, 8, 0, 0, 0, 0,
1286           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE },
1287         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16I, STR(GL_RG16I), false, true, 16, 16, 0, 0, 0, 0, GL_INT,
1288           GL_INT, GL_NONE, GL_NONE, GL_NONE },
1289         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16UI, STR(GL_RG16UI), false, true, 16, 16, 0, 0, 0, 0,
1290           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE },
1291         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG32I, STR(GL_RG32I), false, true, 32, 32, 0, 0, 0, 0, GL_INT,
1292           GL_INT, GL_NONE, GL_NONE, GL_NONE },
1293         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG32UI, STR(GL_RG32UI), false, true, 32, 32, 0, 0, 0, 0,
1294           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE },
1295         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB8I, STR(GL_RGB8I), false, true, 8, 8, 8, 0, 0, 0, GL_INT, GL_INT,
1296           GL_INT, GL_NONE, GL_NONE },
1297         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB8UI, STR(GL_RGB8UI), false, true, 8, 8, 8, 0, 0, 0,
1298           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE },
1299         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16I, STR(GL_RGB16I), false, true, 16, 16, 16, 0, 0, 0, GL_INT,
1300           GL_INT, GL_INT, GL_NONE, GL_NONE },
1301         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16UI, STR(GL_RGB16UI), false, true, 16, 16, 16, 0, 0, 0,
1302           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE },
1303         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB32I, STR(GL_RGB32I), false, true, 32, 32, 32, 0, 0, 0, GL_INT,
1304           GL_INT, GL_INT, GL_NONE, GL_NONE },
1305         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB32UI, STR(GL_RGB32UI), false, true, 32, 32, 32, 0, 0, 0,
1306           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE },
1307         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA8I, STR(GL_RGBA8I), false, true, 8, 8, 8, 8, 0, 0, GL_INT,
1308           GL_INT, GL_INT, GL_INT, GL_NONE },
1309         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA8UI, STR(GL_RGBA8UI), false, true, 8, 8, 8, 8, 0, 0,
1310           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
1311         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16I, STR(GL_RGBA16I), false, true, 16, 16, 16, 16, 0, 0, GL_INT,
1312           GL_INT, GL_INT, GL_INT, GL_NONE },
1313         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16UI, STR(GL_RGBA16UI), false, true, 16, 16, 16, 16, 0, 0,
1314           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
1315         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA32I, STR(GL_RGBA32I), false, true, 32, 32, 32, 32, 0, 0, GL_INT,
1316           GL_INT, GL_INT, GL_INT, GL_NONE },
1317         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA32UI, STR(GL_RGBA32UI), false, true, 32, 32, 32, 32, 0, 0,
1318           GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
1319         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH_COMPONENT16, STR(GL_DEPTH_COMPONENT16), false, true, 0, 0, 0,
1320           0, 16, 0, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_UNSIGNED_NORMALIZED },
1321         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH_COMPONENT24, STR(GL_DEPTH_COMPONENT24), false, true, 0, 0, 0,
1322           0, 24, 0, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_UNSIGNED_NORMALIZED },
1323         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH_COMPONENT32F, STR(GL_DEPTH_COMPONENT32F), false, true, 0, 0,
1324           0, 0, 32, 0, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_FLOAT },
1325         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH24_STENCIL8, STR(GL_DEPTH24_STENCIL8), false, true, 0, 0, 0, 0,
1326           24, 8, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_UNSIGNED_NORMALIZED },
1327         { glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH32F_STENCIL8, STR(GL_DEPTH32F_STENCIL8), false, true, 0, 0, 0,
1328           0, 32, 8, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_FLOAT }
1329 };
1330
1331 const glw::GLuint FunctionalTest::s_formats_size = sizeof(s_formats) / sizeof(s_formats[0]);
1332
1333 const glw::GLchar* FunctionalTest::s_vertex_shader_code = "#version 150\n"
1334                                                                                                                   "\n"
1335                                                                                                                   "void main()\n"
1336                                                                                                                   "{\n"
1337                                                                                                                   "    switch(gl_VertexID % 4)\n"
1338                                                                                                                   "    {\n"
1339                                                                                                                   "    case 0:\n"
1340                                                                                                                   "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
1341                                                                                                                   "        break;\n"
1342                                                                                                                   "    case 1:\n"
1343                                                                                                                   "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
1344                                                                                                                   "        break;\n"
1345                                                                                                                   "    case 2:\n"
1346                                                                                                                   "        gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
1347                                                                                                                   "        break;\n"
1348                                                                                                                   "    case 3:\n"
1349                                                                                                                   "        gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
1350                                                                                                                   "        break;\n"
1351                                                                                                                   "    }\n"
1352                                                                                                                   "}\n";
1353
1354 const glw::GLchar* FunctionalTest::s_fragment_shader_template =
1355         "#version 150\n"
1356         "\n"
1357         "out TEMPLATE_TYPE result;\n"
1358         "\n"
1359         "uniform TEMPLATE_SAMPLER data;\n"
1360         "\n"
1361         "void main()\n"
1362         "{\n"
1363         "    result = texelFetch(data, TEMPLATE_TEXEL_FETCH_ARGUMENTS)TEMPLATE_COMPONENT;\n"
1364         "}\n";
1365
1366 /*===========================================================================================================*/
1367
1368 namespace Utilities
1369 {
1370
1371 glw::GLuint buildProgram(glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const vertex_shader_source,
1372                                                  glw::GLchar const* const fragment_shader_source)
1373 {
1374         glw::GLuint program = 0;
1375
1376         struct Shader
1377         {
1378                 glw::GLchar const* const source;
1379                 glw::GLenum const                type;
1380                 glw::GLuint                              id;
1381         } shader[] = { { vertex_shader_source, GL_VERTEX_SHADER, 0 }, { fragment_shader_source, GL_FRAGMENT_SHADER, 0 } };
1382
1383         glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
1384
1385         try
1386         {
1387                 /* Create program. */
1388                 program = gl.createProgram();
1389                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
1390
1391                 /* Shader compilation. */
1392
1393                 for (glw::GLuint i = 0; i < shader_count; ++i)
1394                 {
1395                         if (DE_NULL != shader[i].source)
1396                         {
1397                                 shader[i].id = gl.createShader(shader[i].type);
1398
1399                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
1400
1401                                 gl.attachShader(program, shader[i].id);
1402
1403                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
1404
1405                                 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
1406
1407                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
1408
1409                                 gl.compileShader(shader[i].id);
1410
1411                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
1412
1413                                 glw::GLint status = GL_FALSE;
1414
1415                                 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
1416                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1417
1418                                 if (GL_FALSE == status)
1419                                 {
1420                                         glw::GLint log_size = 0;
1421                                         gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
1422                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
1423
1424                                         glw::GLchar* log_text = new glw::GLchar[log_size];
1425
1426                                         gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
1427
1428                                         log << tcu::TestLog::Message << "Shader compilation has failed.\n"
1429                                                 << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
1430                                                 << "Shader compilation error log:\n"
1431                                                 << log_text << "\n"
1432                                                 << "Shader source code:\n"
1433                                                 << shader[i].source << "\n"
1434                                                 << tcu::TestLog::EndMessage;
1435
1436                                         delete[] log_text;
1437
1438                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
1439
1440                                         throw 0;
1441                                 }
1442                         }
1443                 }
1444
1445                 /* Link. */
1446                 gl.linkProgram(program);
1447                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
1448
1449                 glw::GLint status = GL_FALSE;
1450
1451                 gl.getProgramiv(program, GL_LINK_STATUS, &status);
1452
1453                 if (GL_TRUE == status)
1454                 {
1455                         for (glw::GLuint i = 0; i < shader_count; ++i)
1456                         {
1457                                 if (shader[i].id)
1458                                 {
1459                                         gl.detachShader(program, shader[i].id);
1460
1461                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
1462                                 }
1463                         }
1464                 }
1465                 else
1466                 {
1467                         glw::GLint log_size = 0;
1468
1469                         gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &log_size);
1470
1471                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
1472
1473                         glw::GLchar* log_text = new glw::GLchar[log_size];
1474
1475                         gl.getProgramInfoLog(program, log_size, NULL, &log_text[0]);
1476
1477                         log << tcu::TestLog::Message << "Program linkage has failed due to:\n"
1478                                 << log_text << "\n"
1479                                 << tcu::TestLog::EndMessage;
1480
1481                         delete[] log_text;
1482
1483                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
1484
1485                         throw 0;
1486                 }
1487         }
1488         catch (...)
1489         {
1490                 if (program)
1491                 {
1492                         gl.deleteProgram(program);
1493
1494                         program = 0;
1495                 }
1496         }
1497
1498         for (glw::GLuint i = 0; i < shader_count; ++i)
1499         {
1500                 if (0 != shader[i].id)
1501                 {
1502                         gl.deleteShader(shader[i].id);
1503
1504                         shader[i].id = 0;
1505                 }
1506         }
1507
1508         return program;
1509 }
1510
1511 std::string preprocessString(std::string source, std::string key, std::string value)
1512 {
1513         std::string destination = source;
1514
1515         while (true)
1516         {
1517                 /* Find token in source code. */
1518                 size_t position = destination.find(key, 0);
1519
1520                 /* No more occurences of this key. */
1521                 if (position == std::string::npos)
1522                 {
1523                         break;
1524                 }
1525
1526                 /* Replace token with sub_code. */
1527                 destination.replace(position, key.size(), value);
1528         }
1529
1530         return destination;
1531 }
1532
1533 std::string itoa(glw::GLint i)
1534 {
1535         std::stringstream stream;
1536
1537         stream << i;
1538
1539         return stream.str();
1540 }
1541
1542 } // namespace Utilities
1543 } // namespace TextureSizePromotion
1544 } // namespace gl3cts