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