• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  gl3TextureSwizzleTests.cpp
26  * \brief Implements conformance tests for "Texture Swizzle" functionality.
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "gl3cTextureSwizzleTests.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluStrUtil.hpp"
32 #include "glwFunctions.hpp"
33 #include "tcuFloat.hpp"
34 #include "tcuTestLog.hpp"
35 
36 #include "deMath.h"
37 #include <cmath>
38 
39 #define ENABLE_DEBUG 0                             /* Selects if debug callback is installed */
40 #define FUNCTIONAL_TEST_ALL_FORMATS 1              /* Selects if all formats should be tested */
41 #define FUNCTIONAL_TEST_ALL_TARGETS 1              /* Selects if all targets should be tested */
42 #define FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES 0      /* Selects if all texture access routines should be tested */
43 #define FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS 0 /* Selects if all swizzle combinations should be tested */
44 
45 namespace gl3cts
46 {
47 namespace TextureSwizzle
48 {
49 /* Static constants use by tests */
50 /* One and zero */
51 static const glw::GLhalf data_float16_one[]    = {tcu::Float16(1.0).bits()};
52 static const glw::GLhalf data_float16_zero[]   = {tcu::Float16(0.0).bits()};
53 static const glw::GLfloat data_float32_one[]   = {1.0f};
54 static const glw::GLfloat data_float32_zero[]  = {0.0f};
55 static const glw::GLbyte data_snorm8_zero[]    = {0};
56 static const glw::GLbyte data_snorm8_one[]     = {127};
57 static const glw::GLshort data_snorm16_one[]   = {32767};
58 static const glw::GLshort data_snorm16_zero[]  = {0};
59 static const glw::GLubyte data_unorm8_one[]    = {255};
60 static const glw::GLubyte data_unorm8_zero[]   = {0};
61 static const glw::GLushort data_unorm16_one[]  = {65535};
62 static const glw::GLushort data_unorm16_zero[] = {0};
63 static const glw::GLbyte data_sint8_zero[]     = {0};
64 static const glw::GLbyte data_sint8_one[]      = {1};
65 static const glw::GLshort data_sint16_one[]    = {1};
66 static const glw::GLshort data_sint16_zero[]   = {0};
67 static const glw::GLint data_sint32_one[]      = {1};
68 static const glw::GLint data_sint32_zero[]     = {0};
69 static const glw::GLubyte data_uint8_one[]     = {1};
70 static const glw::GLubyte data_uint8_zero[]    = {0};
71 static const glw::GLushort data_uint16_one[]   = {1};
72 static const glw::GLushort data_uint16_zero[]  = {0};
73 static const glw::GLuint data_uint32_one[]     = {1};
74 static const glw::GLuint data_uint32_zero[]    = {0};
75 
76 /* Source and expected data */
77 static const glw::GLubyte src_data_r8[]           = {123};
78 static const glw::GLbyte src_data_r8_snorm[]      = {-123};
79 static const glw::GLushort src_data_r16[]         = {12345};
80 static const glw::GLshort src_data_r16_snorm[]    = {-12345};
81 static const glw::GLubyte src_data_rg8[]          = {123, 231};
82 static const glw::GLbyte src_data_rg8_snorm[]     = {-123, -23};
83 static const glw::GLushort src_data_rg16[]        = {12345, 54321};
84 static const glw::GLshort src_data_rg16_snorm[]   = {-12345, -23451};
85 static const glw::GLubyte src_data_r3_g3_b2[]     = {236};   /* 255, 109, 0 */
86 static const glw::GLushort src_data_rgb4[]        = {64832}; /* 5_6_5: 255, 170, 0 */
87 static const glw::GLushort src_data_rgb5[]        = {64832};
88 static const glw::GLubyte src_data_rgb8[]         = {3, 2, 1};
89 static const glw::GLbyte src_data_rgb8_snorm[]    = {-1, -2, -3};
90 static const glw::GLushort src_data_rgb16[]       = {65535, 32767, 16383};
91 static const glw::GLshort src_data_rgb16_snorm[]  = {-32767, -16383, -8191};
92 static const glw::GLushort src_data_rgba4[]       = {64005}; /* 255, 170, 0, 85 */
93 static const glw::GLushort src_data_rgb5_a1[]     = {64852};
94 static const glw::GLubyte src_data_rgba8[]        = {0, 64, 128, 255};
95 static const glw::GLbyte src_data_rgba8_snorm[]   = {-127, -63, -32, -16};
96 static const glw::GLuint src_data_rgb10_a2[]      = {4291823615u};
97 static const glw::GLushort exp_data_rgb10_a2ui[]  = {1023, 256, 511, 3};
98 static const glw::GLushort src_data_rgba16[]      = {65535, 32767, 16383, 8191};
99 static const glw::GLshort src_data_rgba16_snorm[] = {-32767, -16383, -8191, -4091};
100 static const glw::GLubyte exp_data_srgb8_alpha8[] = {13, 1, 255, 32}; /* See 4.5 core 8.24 */
101 static const glw::GLubyte src_data_srgb8_alpha8[] = {64, 8, 255, 32};
102 static const glw::GLhalf src_data_r16f[]          = {tcu::Float16(1.0).bits()};
103 static const glw::GLhalf src_data_rg16f[]         = {tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits()};
104 static const glw::GLhalf src_data_rgb16f[]        = {tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
105                                                      tcu::Float16(2.0).bits()};
106 static const glw::GLhalf src_data_rgba16f[]       = {tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
107                                                      tcu::Float16(2.0).bits(), tcu::Float16(-2.0).bits()};
108 static const glw::GLfloat src_data_r32f[]         = {1.0f};
109 static const glw::GLfloat src_data_rg32f[]        = {1.0f, -1.0f};
110 static const glw::GLfloat src_data_rgb32f[]       = {1.0f, -1.0f, 2.0f};
111 static const glw::GLfloat src_data_rgba32f[]      = {1.0f, -1.0f, 2.0f, -2.0f};
112 
113 static const tcu::Float<uint32_t, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> r11f(0.5);
114 static const tcu::Float<uint32_t, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> g11f(0.75);
115 static const tcu::Float<uint32_t, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> b10f(0.25);
116 
117 static const glw::GLhalf exp_data_r11f_g11f_b10f[]      = {tcu::Float16(0.5).bits(), tcu::Float16(0.75).bits(),
118                                                            tcu::Float16(0.25).bits()};
119 static const glw::GLuint src_data_r11f_g11f_b10f[]      = {(r11f.bits()) | (g11f.bits() << 11) | (b10f.bits() << 22)};
120 static const glw::GLfloat exp_data_rgb9_e5[]            = {31.0f, 23.0f, 32.0f};
121 static const glw::GLuint src_data_rgb9_e5[]             = {2885775608u};
122 static const glw::GLbyte src_data_r8i[]                 = {-127};
123 static const glw::GLubyte src_data_r8ui[]               = {128};
124 static const glw::GLshort src_data_r16i[]               = {-32767};
125 static const glw::GLushort src_data_r16ui[]             = {32768};
126 static const glw::GLint src_data_r32i[]                 = {-1};
127 static const glw::GLuint src_data_r32ui[]               = {1};
128 static const glw::GLbyte src_data_rg8i[]                = {-127, -126};
129 static const glw::GLubyte src_data_rg8ui[]              = {128, 129};
130 static const glw::GLshort src_data_rg16i[]              = {-32767, -32766};
131 static const glw::GLushort src_data_rg16ui[]            = {32768, 32769};
132 static const glw::GLint src_data_rg32i[]                = {-1, -2};
133 static const glw::GLuint src_data_rg32ui[]              = {1, 2};
134 static const glw::GLbyte src_data_rgb8i[]               = {-127, -126, -125};
135 static const glw::GLubyte src_data_rgb8ui[]             = {128, 129, 130};
136 static const glw::GLshort src_data_rgb16i[]             = {-32767, -32766, -32765};
137 static const glw::GLushort src_data_rgb16ui[]           = {32768, 32769, 32770};
138 static const glw::GLint src_data_rgb32i[]               = {-1, -2, -3};
139 static const glw::GLuint src_data_rgb32ui[]             = {1, 2, 3};
140 static const glw::GLbyte src_data_rgba8i[]              = {-127, -126, -125, -124};
141 static const glw::GLubyte src_data_rgba8ui[]            = {128, 129, 130, 131};
142 static const glw::GLshort src_data_rgba16i[]            = {-32767, -32766, -32765, -32764};
143 static const glw::GLushort src_data_rgba16ui[]          = {32768, 32769, 32770, 32771};
144 static const glw::GLint src_data_rgba32i[]              = {-1, -2, -3, -4};
145 static const glw::GLuint src_data_rgba32ui[]            = {1, 2, 3, 4};
146 static const glw::GLushort src_data_depth_component16[] = {32768};
147 static const glw::GLfloat exp_data_depth_component32[]  = {1.0f};
148 static const glw::GLuint src_data_depth_component32[]   = {4294967295u};
149 static const glw::GLfloat src_data_depth_component32f[] = {0.75f};
150 static const glw::GLuint src_data_depth24_stencil8[]    = {4294967041u /* 1.0, 1 */};
151 static const glw::GLuint src_data_depth32f_stencil8[]   = {1065353216, 1 /* 1.0f, 1 */};
152 
153 /* Texture channels */
154 static const glw::GLchar *channels[] = {"r", "g", "b", "a"};
155 
156 /* Enumerations of cube map faces */
157 static const glw::GLenum cube_map_faces[] = {GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
158                                              GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
159                                              GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z};
160 static const size_t n_cube_map_faces      = sizeof(cube_map_faces) / sizeof(cube_map_faces[0]);
161 
162 /* Swizzle states */
163 static const glw::GLenum states[] = {GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B,
164                                      GL_TEXTURE_SWIZZLE_A};
165 static const size_t n_states      = sizeof(states) / sizeof(states[0]);
166 
167 /* Sampler descriptor */
168 struct _sampler
169 {
170     const glw::GLchar *m_basic_type;
171     const glw::GLchar *m_sampler_prefix;
172 };
173 static const _sampler isampler = {"int", "i"};
174 static const _sampler usampler = {"uint", "u"};
175 static const _sampler sampler  = {"float", ""};
176 
177 /* Output channel descriptor */
178 struct _out_ch_desc
179 {
180     glw::GLenum m_internal_format;
181     const glw::GLvoid *m_expected_data;
182 };
183 
184 /* Output channel descriptors for one and zero */
185 static const _out_ch_desc zero_ch      = {GL_ZERO, 0};
186 static const _out_ch_desc one_ch       = {GL_ONE, 0};
187 static const _out_ch_desc float16_zero = {GL_R16F, data_float16_zero};
188 static const _out_ch_desc float16_one  = {GL_R16F, data_float16_one};
189 static const _out_ch_desc float32_zero = {GL_R32F, data_float32_zero};
190 static const _out_ch_desc float32_one  = {GL_R32F, data_float32_one};
191 static const _out_ch_desc sint8_zero   = {GL_R8I, data_sint8_zero};
192 static const _out_ch_desc sint8_one    = {GL_R8I, data_sint8_one};
193 static const _out_ch_desc sint16_zero  = {GL_R16I, data_sint16_zero};
194 static const _out_ch_desc sint16_one   = {GL_R16I, data_sint16_one};
195 static const _out_ch_desc sint32_zero  = {GL_R32I, data_sint32_zero};
196 static const _out_ch_desc sint32_one   = {GL_R32I, data_sint32_one};
197 static const _out_ch_desc snorm8_zero  = {GL_R8_SNORM, data_snorm8_zero};
198 static const _out_ch_desc snorm8_one   = {GL_R8_SNORM, data_snorm8_one};
199 static const _out_ch_desc snorm16_zero = {GL_R16_SNORM, data_snorm16_zero};
200 static const _out_ch_desc snorm16_one  = {GL_R16_SNORM, data_snorm16_one};
201 static const _out_ch_desc uint8_zero   = {GL_R8UI, data_uint8_zero};
202 static const _out_ch_desc uint8_one    = {GL_R8UI, data_uint8_one};
203 static const _out_ch_desc uint16_zero  = {GL_R16UI, data_uint16_zero};
204 static const _out_ch_desc uint16_one   = {GL_R16UI, data_uint16_one};
205 static const _out_ch_desc uint32_zero  = {GL_R32UI, data_uint32_zero};
206 static const _out_ch_desc uint32_one   = {GL_R32UI, data_uint32_one};
207 static const _out_ch_desc unorm8_zero  = {GL_R8, data_unorm8_zero};
208 static const _out_ch_desc unorm8_one   = {GL_R8, data_unorm8_one};
209 static const _out_ch_desc unorm16_zero = {GL_R16, data_unorm16_zero};
210 static const _out_ch_desc unorm16_one  = {GL_R16, data_unorm16_one};
211 
212 /* Texture format descriptor. Maps texture format with output channel descriptors, source data and sampler descriptor */
213 struct _texture_format
214 {
215     const glu::ApiType m_minimum_gl_context;
216     glw::GLenum m_internal_format;
217     glw::GLenum m_format;
218     glw::GLenum m_type;
219     glw::GLenum m_ds_mode;
220     const _sampler &m_sampler;
221     _out_ch_desc m_red_ch;
222     _out_ch_desc m_green_ch;
223     _out_ch_desc m_blue_ch;
224     _out_ch_desc m_alpha_ch;
225     const glw::GLvoid *m_source_data;
226     const _out_ch_desc &m_zero_ch;
227     const _out_ch_desc &m_one_ch;
228 };
229 static const _texture_format texture_formats[] = {
230     /* 0  */ {glu::ApiType::core(3, 0),
231               GL_R8,
232               GL_RED,
233               GL_UNSIGNED_BYTE,
234               GL_DEPTH_COMPONENT,
235               sampler,
236               {GL_R8, nullptr},
237               zero_ch,
238               zero_ch,
239               one_ch,
240               src_data_r8,
241               unorm8_zero,
242               unorm8_one},
243     {glu::ApiType::core(3, 1),
244      GL_R8_SNORM,
245      GL_RED,
246      GL_BYTE,
247      GL_DEPTH_COMPONENT,
248      sampler,
249      {GL_R8_SNORM, nullptr},
250      zero_ch,
251      zero_ch,
252      one_ch,
253      src_data_r8_snorm,
254      snorm8_zero,
255      snorm8_one},
256     {glu::ApiType::core(3, 0),
257      GL_R16,
258      GL_RED,
259      GL_UNSIGNED_SHORT,
260      GL_DEPTH_COMPONENT,
261      sampler,
262      {GL_R16, nullptr},
263      zero_ch,
264      zero_ch,
265      one_ch,
266      src_data_r16,
267      unorm16_zero,
268      unorm16_one},
269     {glu::ApiType::core(3, 1),
270      GL_R16_SNORM,
271      GL_RED,
272      GL_SHORT,
273      GL_DEPTH_COMPONENT,
274      sampler,
275      {GL_R16_SNORM, nullptr},
276      zero_ch,
277      zero_ch,
278      one_ch,
279      src_data_r16_snorm,
280      snorm16_zero,
281      snorm16_one},
282     {glu::ApiType::core(3, 0),
283      GL_RG8,
284      GL_RG,
285      GL_UNSIGNED_BYTE,
286      GL_DEPTH_COMPONENT,
287      sampler,
288      {GL_R8, nullptr},
289      {GL_R8, nullptr},
290      zero_ch,
291      one_ch,
292      src_data_rg8,
293      unorm8_zero,
294      unorm8_one},
295     {glu::ApiType::core(3, 1),
296      GL_RG8_SNORM,
297      GL_RG,
298      GL_BYTE,
299      GL_DEPTH_COMPONENT,
300      sampler,
301      {GL_R8_SNORM, nullptr},
302      {GL_R8_SNORM, nullptr},
303      zero_ch,
304      one_ch,
305      src_data_rg8_snorm,
306      snorm8_zero,
307      snorm8_one},
308     {glu::ApiType::core(3, 0),
309      GL_RG16,
310      GL_RG,
311      GL_UNSIGNED_SHORT,
312      GL_DEPTH_COMPONENT,
313      sampler,
314      {GL_R16, nullptr},
315      {GL_R16, nullptr},
316      zero_ch,
317      one_ch,
318      src_data_rg16,
319      unorm16_zero,
320      unorm16_one},
321     {glu::ApiType::core(3, 1),
322      GL_RG16_SNORM,
323      GL_RG,
324      GL_SHORT,
325      GL_DEPTH_COMPONENT,
326      sampler,
327      {GL_R16_SNORM, nullptr},
328      {GL_R16_SNORM, nullptr},
329      zero_ch,
330      one_ch,
331      src_data_rg16_snorm,
332      snorm16_zero,
333      snorm16_one},
334     /* 8  */
335     {glu::ApiType::core(4, 4),
336      GL_R3_G3_B2,
337      GL_RGB,
338      GL_UNSIGNED_BYTE_3_3_2,
339      GL_DEPTH_COMPONENT,
340      sampler,
341      {GL_R8, nullptr},
342      {GL_R8, nullptr},
343      {GL_R8, nullptr},
344      one_ch,
345      src_data_r3_g3_b2,
346      unorm8_zero,
347      unorm8_one},
348     {glu::ApiType::core(4, 4),
349      GL_RGB4,
350      GL_RGB,
351      GL_UNSIGNED_SHORT_5_6_5,
352      GL_DEPTH_COMPONENT,
353      sampler,
354      {GL_R8, nullptr},
355      {GL_R8, nullptr},
356      {GL_R8, nullptr},
357      one_ch,
358      src_data_rgb4,
359      unorm8_zero,
360      unorm8_one},
361     {glu::ApiType::core(4, 4),
362      GL_RGB5,
363      GL_RGB,
364      GL_UNSIGNED_SHORT_5_6_5,
365      GL_DEPTH_COMPONENT,
366      sampler,
367      {GL_R8, nullptr},
368      {GL_R8, nullptr},
369      {GL_R8, nullptr},
370      one_ch,
371      src_data_rgb5,
372      unorm8_zero,
373      unorm8_one},
374     {glu::ApiType::core(3, 0),
375      GL_RGB8,
376      GL_RGB,
377      GL_UNSIGNED_BYTE,
378      GL_DEPTH_COMPONENT,
379      sampler,
380      {GL_R8, nullptr},
381      {GL_R8, nullptr},
382      {GL_R8, nullptr},
383      one_ch,
384      src_data_rgb8,
385      unorm8_zero,
386      unorm8_one},
387     {glu::ApiType::core(3, 1),
388      GL_RGB8_SNORM,
389      GL_RGB,
390      GL_BYTE,
391      GL_DEPTH_COMPONENT,
392      sampler,
393      {GL_R8_SNORM, nullptr},
394      {GL_R8_SNORM, nullptr},
395      {GL_R8_SNORM, nullptr},
396      one_ch,
397      src_data_rgb8_snorm,
398      snorm8_zero,
399      snorm8_one},
400     {glu::ApiType::core(4, 4),
401      GL_RGB10,
402      GL_RGB,
403      GL_UNSIGNED_SHORT,
404      GL_DEPTH_COMPONENT,
405      sampler,
406      {GL_R16, nullptr},
407      {GL_R16, nullptr},
408      {GL_R16, nullptr},
409      one_ch,
410      src_data_rgb16,
411      unorm16_zero,
412      unorm16_one},
413     {glu::ApiType::core(4, 4),
414      GL_RGB12,
415      GL_RGB,
416      GL_UNSIGNED_SHORT,
417      GL_DEPTH_COMPONENT,
418      sampler,
419      {GL_R16, nullptr},
420      {GL_R16, nullptr},
421      {GL_R16, nullptr},
422      one_ch,
423      src_data_rgb16,
424      unorm16_zero,
425      unorm16_one},
426     {glu::ApiType::core(3, 0),
427      GL_RGB16,
428      GL_RGB,
429      GL_UNSIGNED_SHORT,
430      GL_DEPTH_COMPONENT,
431      sampler,
432      {GL_R16, nullptr},
433      {GL_R16, nullptr},
434      {GL_R16, nullptr},
435      one_ch,
436      src_data_rgb16,
437      unorm16_zero,
438      unorm16_one},
439     /* 16 */
440     {glu::ApiType::core(3, 1),
441      GL_RGB16_SNORM,
442      GL_RGB,
443      GL_SHORT,
444      GL_DEPTH_COMPONENT,
445      sampler,
446      {GL_R16_SNORM, nullptr},
447      {GL_R16_SNORM, nullptr},
448      {GL_R16_SNORM, nullptr},
449      one_ch,
450      src_data_rgb16_snorm,
451      snorm16_zero,
452      snorm16_one},
453     {glu::ApiType::core(4, 4),
454      GL_RGBA2,
455      GL_RGBA,
456      GL_UNSIGNED_SHORT_4_4_4_4,
457      GL_DEPTH_COMPONENT,
458      sampler,
459      {GL_R8, nullptr},
460      {GL_R8, nullptr},
461      {GL_R8, nullptr},
462      {GL_R8, nullptr},
463      src_data_rgba4,
464      unorm8_zero,
465      unorm8_one},
466     {glu::ApiType::core(4, 2),
467      GL_RGBA4,
468      GL_RGBA,
469      GL_UNSIGNED_SHORT_4_4_4_4,
470      GL_DEPTH_COMPONENT,
471      sampler,
472      {GL_R8, nullptr},
473      {GL_R8, nullptr},
474      {GL_R8, nullptr},
475      {GL_R8, nullptr},
476      src_data_rgba4,
477      unorm8_zero,
478      unorm8_one},
479     {glu::ApiType::core(4, 2),
480      GL_RGB5_A1,
481      GL_RGBA,
482      GL_UNSIGNED_SHORT_5_5_5_1,
483      GL_DEPTH_COMPONENT,
484      sampler,
485      {GL_R8, nullptr},
486      {GL_R8, nullptr},
487      {GL_R8, nullptr},
488      {GL_R8, nullptr},
489      src_data_rgb5_a1,
490      unorm8_zero,
491      unorm8_one},
492     {glu::ApiType::core(3, 0),
493      GL_RGBA8,
494      GL_RGBA,
495      GL_UNSIGNED_BYTE,
496      GL_DEPTH_COMPONENT,
497      sampler,
498      {GL_R8, nullptr},
499      {GL_R8, nullptr},
500      {GL_R8, nullptr},
501      {GL_R8, nullptr},
502      src_data_rgba8,
503      unorm8_zero,
504      unorm8_one},
505     {glu::ApiType::core(3, 1),
506      GL_RGBA8_SNORM,
507      GL_RGBA,
508      GL_BYTE,
509      GL_DEPTH_COMPONENT,
510      sampler,
511      {GL_R8_SNORM, nullptr},
512      {GL_R8_SNORM, nullptr},
513      {GL_R8_SNORM, nullptr},
514      {GL_R8_SNORM, nullptr},
515      src_data_rgba8_snorm,
516      snorm8_zero,
517      snorm8_one},
518     {glu::ApiType::core(3, 0),
519      GL_RGB10_A2,
520      GL_RGBA,
521      GL_UNSIGNED_INT_10_10_10_2,
522      GL_DEPTH_COMPONENT,
523      sampler,
524      {GL_R16, nullptr},
525      {GL_R16, nullptr},
526      {GL_R16, nullptr},
527      {GL_R16, nullptr},
528      src_data_rgb10_a2,
529      unorm16_zero,
530      unorm16_one},
531     {glu::ApiType::core(3, 3),
532      GL_RGB10_A2UI,
533      GL_RGBA_INTEGER,
534      GL_UNSIGNED_INT_10_10_10_2,
535      GL_DEPTH_COMPONENT,
536      usampler,
537      {GL_R16UI, exp_data_rgb10_a2ui + 0},
538      {GL_R16UI, exp_data_rgb10_a2ui + 1},
539      {GL_R16UI, exp_data_rgb10_a2ui + 2},
540      {GL_R16UI, exp_data_rgb10_a2ui + 3},
541      src_data_rgb10_a2,
542      uint16_zero,
543      uint16_one},
544     /* 24 */
545     {glu::ApiType::core(4, 4),
546      GL_RGBA12,
547      GL_RGBA,
548      GL_UNSIGNED_SHORT,
549      GL_DEPTH_COMPONENT,
550      sampler,
551      {GL_R16, nullptr},
552      {GL_R16, nullptr},
553      {GL_R16, nullptr},
554      {GL_R16, nullptr},
555      src_data_rgba16,
556      unorm16_zero,
557      unorm16_one},
558     {glu::ApiType::core(3, 0),
559      GL_RGBA16,
560      GL_RGBA,
561      GL_UNSIGNED_SHORT,
562      GL_DEPTH_COMPONENT,
563      sampler,
564      {GL_R16, nullptr},
565      {GL_R16, nullptr},
566      {GL_R16, nullptr},
567      {GL_R16, nullptr},
568      src_data_rgba16,
569      unorm16_zero,
570      unorm16_one},
571     {glu::ApiType::core(3, 1),
572      GL_RGBA16_SNORM,
573      GL_RGBA,
574      GL_SHORT,
575      GL_DEPTH_COMPONENT,
576      sampler,
577      {GL_R16_SNORM, nullptr},
578      {GL_R16_SNORM, nullptr},
579      {GL_R16_SNORM, nullptr},
580      {GL_R16_SNORM, src_data_rgba16_snorm + 3},
581      src_data_rgba16_snorm,
582      snorm16_zero,
583      snorm16_one},
584     {glu::ApiType::core(3, 0),
585      GL_SRGB8,
586      GL_RGB,
587      GL_UNSIGNED_BYTE,
588      GL_DEPTH_COMPONENT,
589      sampler,
590      {GL_R8, exp_data_srgb8_alpha8 + 0},
591      {GL_R8, exp_data_srgb8_alpha8 + 1},
592      {GL_R8, exp_data_srgb8_alpha8 + 2},
593      one_ch,
594      src_data_srgb8_alpha8,
595      unorm8_zero,
596      unorm8_one},
597     {glu::ApiType::core(3, 0),
598      GL_SRGB8_ALPHA8,
599      GL_RGBA,
600      GL_UNSIGNED_BYTE,
601      GL_DEPTH_COMPONENT,
602      sampler,
603      {GL_R8, exp_data_srgb8_alpha8 + 0},
604      {GL_R8, exp_data_srgb8_alpha8 + 1},
605      {GL_R8, exp_data_srgb8_alpha8 + 2},
606      {GL_R8, exp_data_srgb8_alpha8 + 3},
607      src_data_srgb8_alpha8,
608      unorm8_zero,
609      unorm8_one},
610     {glu::ApiType::core(3, 0),
611      GL_R16F,
612      GL_RED,
613      GL_HALF_FLOAT,
614      GL_DEPTH_COMPONENT,
615      sampler,
616      {GL_R16F, src_data_r16f + 0},
617      zero_ch,
618      zero_ch,
619      one_ch,
620      src_data_r16f,
621      float16_zero,
622      float16_one},
623     {glu::ApiType::core(3, 0),
624      GL_RG16F,
625      GL_RG,
626      GL_HALF_FLOAT,
627      GL_DEPTH_COMPONENT,
628      sampler,
629      {GL_R16F, src_data_rg16f + 0},
630      {GL_R16F, src_data_rg16f + 1},
631      zero_ch,
632      one_ch,
633      src_data_rg16f,
634      float16_zero,
635      float16_one},
636     {glu::ApiType::core(3, 0),
637      GL_RGB16F,
638      GL_RGB,
639      GL_HALF_FLOAT,
640      GL_DEPTH_COMPONENT,
641      sampler,
642      {GL_R16F, src_data_rgb16f + 0},
643      {GL_R16F, src_data_rgb16f + 1},
644      {GL_R16F, src_data_rgb16f + 2},
645      one_ch,
646      src_data_rgb16f,
647      float16_zero,
648      float16_one},
649     /* 32 */
650     {glu::ApiType::core(3, 0),
651      GL_RGBA16F,
652      GL_RGBA,
653      GL_HALF_FLOAT,
654      GL_DEPTH_COMPONENT,
655      sampler,
656      {GL_R16F, src_data_rgba16f + 0},
657      {GL_R16F, src_data_rgba16f + 1},
658      {GL_R16F, src_data_rgba16f + 2},
659      {GL_R16F, src_data_rgba16f + 3},
660      src_data_rgba16f,
661      float16_zero,
662      float16_one},
663     {glu::ApiType::core(3, 0),
664      GL_R32F,
665      GL_RED,
666      GL_FLOAT,
667      GL_DEPTH_COMPONENT,
668      sampler,
669      {GL_R32F, src_data_r32f + 0},
670      zero_ch,
671      zero_ch,
672      one_ch,
673      src_data_r32f,
674      float32_zero,
675      float32_one},
676     {glu::ApiType::core(3, 0),
677      GL_RG32F,
678      GL_RG,
679      GL_FLOAT,
680      GL_DEPTH_COMPONENT,
681      sampler,
682      {GL_R32F, src_data_rg32f + 0},
683      {GL_R32F, src_data_rg32f + 1},
684      zero_ch,
685      one_ch,
686      src_data_rg32f,
687      float32_zero,
688      float32_one},
689     {glu::ApiType::core(3, 0),
690      GL_RGB32F,
691      GL_RGB,
692      GL_FLOAT,
693      GL_DEPTH_COMPONENT,
694      sampler,
695      {GL_R32F, src_data_rgb32f + 0},
696      {GL_R32F, src_data_rgb32f + 1},
697      {GL_R32F, src_data_rgb32f + 2},
698      one_ch,
699      src_data_rgb32f,
700      float32_zero,
701      float32_one},
702     {glu::ApiType::core(3, 0),
703      GL_RGBA32F,
704      GL_RGBA,
705      GL_FLOAT,
706      GL_DEPTH_COMPONENT,
707      sampler,
708      {GL_R32F, src_data_rgba32f + 0},
709      {GL_R32F, src_data_rgba32f + 1},
710      {GL_R32F, src_data_rgba32f + 2},
711      {GL_R32F, src_data_rgba32f + 3},
712      src_data_rgba32f,
713      float32_zero,
714      float32_one},
715     {glu::ApiType::core(3, 0),
716      GL_R11F_G11F_B10F,
717      GL_RGB,
718      GL_UNSIGNED_INT_10F_11F_11F_REV,
719      GL_DEPTH_COMPONENT,
720      sampler,
721      {GL_R16F, exp_data_r11f_g11f_b10f + 0},
722      {GL_R16F, exp_data_r11f_g11f_b10f + 1},
723      {GL_R16F, exp_data_r11f_g11f_b10f + 2},
724      one_ch,
725      src_data_r11f_g11f_b10f,
726      float16_zero,
727      float16_one},
728     {glu::ApiType::core(3, 0),
729      GL_RGB9_E5,
730      GL_RGB,
731      GL_UNSIGNED_INT_5_9_9_9_REV,
732      GL_DEPTH_COMPONENT,
733      sampler,
734      {GL_R32F, exp_data_rgb9_e5 + 0},
735      {GL_R32F, exp_data_rgb9_e5 + 1},
736      {GL_R32F, exp_data_rgb9_e5 + 2},
737      one_ch,
738      src_data_rgb9_e5,
739      float32_zero,
740      float32_one},
741     {glu::ApiType::core(3, 0),
742      GL_R8I,
743      GL_RED_INTEGER,
744      GL_BYTE,
745      GL_DEPTH_COMPONENT,
746      isampler,
747      {GL_R8I, src_data_r8i},
748      zero_ch,
749      zero_ch,
750      one_ch,
751      src_data_r8i,
752      sint8_zero,
753      sint8_one},
754     /* 40 */
755     {glu::ApiType::core(3, 0),
756      GL_R8UI,
757      GL_RED_INTEGER,
758      GL_UNSIGNED_BYTE,
759      GL_DEPTH_COMPONENT,
760      usampler,
761      {GL_R8UI, src_data_r8ui},
762      zero_ch,
763      zero_ch,
764      one_ch,
765      src_data_r8ui,
766      uint8_zero,
767      uint8_one},
768     {glu::ApiType::core(3, 0),
769      GL_R16I,
770      GL_RED_INTEGER,
771      GL_SHORT,
772      GL_DEPTH_COMPONENT,
773      isampler,
774      {GL_R16I, src_data_r16i},
775      zero_ch,
776      zero_ch,
777      one_ch,
778      src_data_r16i,
779      sint16_zero,
780      sint16_one},
781     {glu::ApiType::core(3, 0),
782      GL_R16UI,
783      GL_RED_INTEGER,
784      GL_UNSIGNED_SHORT,
785      GL_DEPTH_COMPONENT,
786      usampler,
787      {GL_R16UI, src_data_r16ui},
788      zero_ch,
789      zero_ch,
790      one_ch,
791      src_data_r16ui,
792      uint16_zero,
793      uint16_one},
794     {glu::ApiType::core(3, 0),
795      GL_R32I,
796      GL_RED_INTEGER,
797      GL_INT,
798      GL_DEPTH_COMPONENT,
799      isampler,
800      {GL_R32I, src_data_r32i},
801      zero_ch,
802      zero_ch,
803      one_ch,
804      src_data_r32i,
805      sint32_zero,
806      sint32_one},
807     {glu::ApiType::core(3, 0),
808      GL_R32UI,
809      GL_RED_INTEGER,
810      GL_UNSIGNED_INT,
811      GL_DEPTH_COMPONENT,
812      usampler,
813      {GL_R32UI, src_data_r32ui},
814      zero_ch,
815      zero_ch,
816      one_ch,
817      src_data_r32ui,
818      uint32_zero,
819      uint32_one},
820     {glu::ApiType::core(3, 0),
821      GL_RG8I,
822      GL_RG_INTEGER,
823      GL_BYTE,
824      GL_DEPTH_COMPONENT,
825      isampler,
826      {GL_R8I, src_data_rg8i + 0},
827      {GL_R8I, src_data_rg8i + 1},
828      zero_ch,
829      one_ch,
830      src_data_rg8i,
831      sint8_zero,
832      sint8_one},
833     {glu::ApiType::core(3, 0),
834      GL_RG8UI,
835      GL_RG_INTEGER,
836      GL_UNSIGNED_BYTE,
837      GL_DEPTH_COMPONENT,
838      usampler,
839      {GL_R8UI, src_data_rg8ui + 0},
840      {GL_R8UI, src_data_rg8ui + 1},
841      zero_ch,
842      one_ch,
843      src_data_rg8ui,
844      uint8_zero,
845      uint8_one},
846     {glu::ApiType::core(3, 0),
847      GL_RG16I,
848      GL_RG_INTEGER,
849      GL_SHORT,
850      GL_DEPTH_COMPONENT,
851      isampler,
852      {GL_R16I, src_data_rg16i + 0},
853      {GL_R16I, src_data_rg16i + 1},
854      zero_ch,
855      one_ch,
856      src_data_rg16i,
857      sint16_zero,
858      sint16_one},
859     /* 48 */
860     {glu::ApiType::core(3, 0),
861      GL_RG16UI,
862      GL_RG_INTEGER,
863      GL_UNSIGNED_SHORT,
864      GL_DEPTH_COMPONENT,
865      usampler,
866      {GL_R16UI, src_data_rg16ui + 0},
867      {GL_R16UI, src_data_rg16ui + 1},
868      zero_ch,
869      one_ch,
870      src_data_rg16ui,
871      uint16_zero,
872      uint16_one},
873     {glu::ApiType::core(3, 0),
874      GL_RG32I,
875      GL_RG_INTEGER,
876      GL_INT,
877      GL_DEPTH_COMPONENT,
878      isampler,
879      {GL_R32I, src_data_rg32i + 0},
880      {GL_R32I, src_data_rg32i + 1},
881      zero_ch,
882      one_ch,
883      src_data_rg32i,
884      sint32_zero,
885      sint32_one},
886     {glu::ApiType::core(3, 0),
887      GL_RG32UI,
888      GL_RG_INTEGER,
889      GL_UNSIGNED_INT,
890      GL_DEPTH_COMPONENT,
891      usampler,
892      {GL_R32UI, src_data_rg32ui + 0},
893      {GL_R32UI, src_data_rg32ui + 1},
894      zero_ch,
895      one_ch,
896      src_data_rg32ui,
897      uint32_zero,
898      uint32_one},
899     {glu::ApiType::core(3, 0),
900      GL_RGB8I,
901      GL_RGB_INTEGER,
902      GL_BYTE,
903      GL_DEPTH_COMPONENT,
904      isampler,
905      {GL_R8I, src_data_rgb8i + 0},
906      {GL_R8I, src_data_rgb8i + 1},
907      {GL_R8I, src_data_rgb8i + 2},
908      one_ch,
909      src_data_rgb8i,
910      sint8_zero,
911      sint8_one},
912     {glu::ApiType::core(3, 0),
913      GL_RGB8UI,
914      GL_RGB_INTEGER,
915      GL_UNSIGNED_BYTE,
916      GL_DEPTH_COMPONENT,
917      usampler,
918      {GL_R8UI, src_data_rgb8ui + 0},
919      {GL_R8UI, src_data_rgb8ui + 1},
920      {GL_R8UI, src_data_rgb8ui + 2},
921      one_ch,
922      src_data_rgb8ui,
923      uint8_zero,
924      uint8_one},
925     {glu::ApiType::core(3, 0),
926      GL_RGB16I,
927      GL_RGB_INTEGER,
928      GL_SHORT,
929      GL_DEPTH_COMPONENT,
930      isampler,
931      {GL_R16I, src_data_rgb16i + 0},
932      {GL_R16I, src_data_rgb16i + 1},
933      {GL_R16I, src_data_rgb16i + 2},
934      one_ch,
935      src_data_rgb16i,
936      sint16_zero,
937      sint16_one},
938     {glu::ApiType::core(3, 0),
939      GL_RGB16UI,
940      GL_RGB_INTEGER,
941      GL_UNSIGNED_SHORT,
942      GL_DEPTH_COMPONENT,
943      usampler,
944      {GL_R16UI, src_data_rgb16ui + 0},
945      {GL_R16UI, src_data_rgb16ui + 1},
946      {GL_R16UI, src_data_rgb16ui + 2},
947      one_ch,
948      src_data_rgb16ui,
949      uint16_zero,
950      uint16_one},
951     {glu::ApiType::core(3, 0),
952      GL_RGB32I,
953      GL_RGB_INTEGER,
954      GL_INT,
955      GL_DEPTH_COMPONENT,
956      isampler,
957      {GL_R32I, src_data_rgb32i + 0},
958      {GL_R32I, src_data_rgb32i + 1},
959      {GL_R32I, src_data_rgb32i + 2},
960      one_ch,
961      src_data_rgb32i,
962      sint32_zero,
963      sint32_one},
964     /* 56 */
965     {glu::ApiType::core(3, 0),
966      GL_RGB32UI,
967      GL_RGB_INTEGER,
968      GL_UNSIGNED_INT,
969      GL_DEPTH_COMPONENT,
970      usampler,
971      {GL_R32UI, src_data_rgb32ui + 0},
972      {GL_R32UI, src_data_rgb32ui + 1},
973      {GL_R32UI, src_data_rgb32ui + 2},
974      one_ch,
975      src_data_rgb32ui,
976      uint32_zero,
977      uint32_one},
978     {glu::ApiType::core(3, 0),
979      GL_RGBA8I,
980      GL_RGBA_INTEGER,
981      GL_BYTE,
982      GL_DEPTH_COMPONENT,
983      isampler,
984      {GL_R8I, src_data_rgba8i + 0},
985      {GL_R8I, src_data_rgba8i + 1},
986      {GL_R8I, src_data_rgba8i + 2},
987      {GL_R8I, src_data_rgba8i + 3},
988      src_data_rgba8i,
989      sint8_zero,
990      sint8_one},
991     {glu::ApiType::core(3, 0),
992      GL_RGBA8UI,
993      GL_RGBA_INTEGER,
994      GL_UNSIGNED_BYTE,
995      GL_DEPTH_COMPONENT,
996      usampler,
997      {GL_R8UI, src_data_rgba8ui + 0},
998      {GL_R8UI, src_data_rgba8ui + 1},
999      {GL_R8UI, src_data_rgba8ui + 2},
1000      {GL_R8UI, src_data_rgba8ui + 3},
1001      src_data_rgba8ui,
1002      uint8_zero,
1003      uint8_one},
1004     {glu::ApiType::core(3, 0),
1005      GL_RGBA16I,
1006      GL_RGBA_INTEGER,
1007      GL_SHORT,
1008      GL_DEPTH_COMPONENT,
1009      isampler,
1010      {GL_R16I, src_data_rgba16i + 0},
1011      {GL_R16I, src_data_rgba16i + 1},
1012      {GL_R16I, src_data_rgba16i + 2},
1013      {GL_R16I, src_data_rgba16i + 3},
1014      src_data_rgba16i,
1015      sint16_zero,
1016      sint16_one},
1017     {glu::ApiType::core(3, 0),
1018      GL_RGBA16UI,
1019      GL_RGBA_INTEGER,
1020      GL_UNSIGNED_SHORT,
1021      GL_DEPTH_COMPONENT,
1022      usampler,
1023      {GL_R16UI, src_data_rgba16ui + 0},
1024      {GL_R16UI, src_data_rgba16ui + 1},
1025      {GL_R16UI, src_data_rgba16ui + 2},
1026      {GL_R16UI, src_data_rgba16ui + 3},
1027      src_data_rgba16ui,
1028      uint16_zero,
1029      uint16_one},
1030     {glu::ApiType::core(3, 0),
1031      GL_RGBA32I,
1032      GL_RGBA_INTEGER,
1033      GL_INT,
1034      GL_DEPTH_COMPONENT,
1035      isampler,
1036      {GL_R32I, src_data_rgba32i + 0},
1037      {GL_R32I, src_data_rgba32i + 1},
1038      {GL_R32I, src_data_rgba32i + 2},
1039      {GL_R32I, src_data_rgba32i + 3},
1040      src_data_rgba32i,
1041      sint32_zero,
1042      sint32_one},
1043     {glu::ApiType::core(3, 0),
1044      GL_RGBA32UI,
1045      GL_RGBA_INTEGER,
1046      GL_UNSIGNED_INT,
1047      GL_DEPTH_COMPONENT,
1048      usampler,
1049      {GL_R32UI, src_data_rgba32ui + 0},
1050      {GL_R32UI, src_data_rgba32ui + 1},
1051      {GL_R32UI, src_data_rgba32ui + 2},
1052      {GL_R32UI, src_data_rgba32ui + 3},
1053      src_data_rgba32ui,
1054      uint32_zero,
1055      uint32_one},
1056     {glu::ApiType::core(3, 0),
1057      GL_DEPTH_COMPONENT16,
1058      GL_DEPTH_COMPONENT,
1059      GL_UNSIGNED_SHORT,
1060      GL_DEPTH_COMPONENT,
1061      sampler,
1062      {GL_R16, src_data_depth_component16},
1063      zero_ch,
1064      zero_ch,
1065      one_ch,
1066      src_data_depth_component16,
1067      unorm16_zero,
1068      unorm16_one},
1069     /* 64 */
1070     {glu::ApiType::core(3, 0),
1071      GL_DEPTH_COMPONENT24,
1072      GL_DEPTH_COMPONENT,
1073      GL_UNSIGNED_INT,
1074      GL_DEPTH_COMPONENT,
1075      sampler,
1076      {GL_R32F, exp_data_depth_component32},
1077      zero_ch,
1078      zero_ch,
1079      one_ch,
1080      src_data_depth_component32,
1081      float32_zero,
1082      float32_one},
1083     {glu::ApiType::core(3, 0),
1084      GL_DEPTH_COMPONENT32,
1085      GL_DEPTH_COMPONENT,
1086      GL_UNSIGNED_INT,
1087      GL_DEPTH_COMPONENT,
1088      sampler,
1089      {GL_R32F, exp_data_depth_component32},
1090      zero_ch,
1091      zero_ch,
1092      one_ch,
1093      src_data_depth_component32,
1094      float32_zero,
1095      float32_one},
1096     {glu::ApiType::core(3, 0),
1097      GL_DEPTH_COMPONENT32F,
1098      GL_DEPTH_COMPONENT,
1099      GL_FLOAT,
1100      GL_DEPTH_COMPONENT,
1101      sampler,
1102      {GL_R32F, src_data_depth_component32f},
1103      zero_ch,
1104      zero_ch,
1105      one_ch,
1106      src_data_depth_component32f,
1107      float32_zero,
1108      float32_one},
1109     {glu::ApiType::core(3, 0),
1110      GL_DEPTH24_STENCIL8,
1111      GL_DEPTH_STENCIL,
1112      GL_UNSIGNED_INT_24_8,
1113      GL_DEPTH_COMPONENT,
1114      sampler,
1115      {GL_R32F, exp_data_depth_component32},
1116      zero_ch,
1117      zero_ch,
1118      one_ch,
1119      src_data_depth24_stencil8,
1120      float32_zero,
1121      float32_one},
1122     {glu::ApiType::core(3, 0),
1123      GL_DEPTH32F_STENCIL8,
1124      GL_DEPTH_STENCIL,
1125      GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1126      GL_DEPTH_COMPONENT,
1127      sampler,
1128      {GL_R32F, exp_data_depth_component32},
1129      zero_ch,
1130      zero_ch,
1131      one_ch,
1132      src_data_depth32f_stencil8,
1133      float32_zero,
1134      float32_one},
1135     {glu::ApiType::core(4, 3), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_STENCIL_INDEX, usampler,
1136      one_ch, zero_ch, zero_ch, one_ch, src_data_depth24_stencil8, uint8_zero, uint8_one},
1137     {glu::ApiType::core(4, 3), GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1138      GL_STENCIL_INDEX, usampler, one_ch, zero_ch, zero_ch, one_ch, src_data_depth32f_stencil8, uint8_zero, uint8_one}};
1139 static const size_t n_texture_formats = sizeof(texture_formats) / sizeof(texture_formats[0]);
1140 
1141 /* Texture access routine descriptors */
1142 struct _texture_access
1143 {
1144     const glw::GLchar *m_name;
1145     size_t m_n_coordinates;
1146     bool m_use_derivaties;
1147     bool m_use_integral_coordinates;
1148     bool m_use_lod;
1149     bool m_use_offsets;
1150     bool m_support_multisampling;
1151 };
1152 static const _texture_access texture_access[] = {{"texture", 0, false, false, false, false, false},
1153                                                  {"textureProj", 1, false, false, false, false, false},
1154                                                  {"textureLod", 0, false, false, true, false, false},
1155                                                  {"textureOffset", 0, false, false, false, true, false},
1156                                                  {"texelFetch", 0, false, true, true, false, true},
1157                                                  {"texelFetchOffset", 0, false, true, true, true, false},
1158                                                  {"textureProjOffset", 1, false, false, false, true, false},
1159                                                  {"textureLodOffset", 0, false, false, true, true, false},
1160                                                  {"textureProjLod", 1, false, false, true, false, false},
1161                                                  {"textureProjLodOffset", 1, false, false, true, true, false},
1162                                                  {"textureGrad", 0, true, false, false, false, false},
1163                                                  {"textureGradOffset", 0, true, false, false, true, false},
1164                                                  {"textureProjGrad", 1, true, false, false, false, false},
1165                                                  {"textureProjGradOffset", 1, true, false, false, true, false}};
1166 static const size_t n_texture_access          = sizeof(texture_access) / sizeof(texture_access[0]);
1167 
1168 /* Texture target descriptor */
1169 struct _texture_target
1170 {
1171     size_t m_n_array_coordinates;
1172     size_t m_n_coordinates;
1173     size_t m_n_derivatives;
1174     const glw::GLchar *m_sampler_type;
1175     bool m_support_integral_coordinates;
1176     bool m_support_lod;
1177     bool m_support_offset;
1178     bool m_supports_proj;
1179     bool m_require_multisampling;
1180     glw::GLenum m_target;
1181 };
1182 
1183 static const _texture_target texture_targets[] = {
1184     {0, 1, 1, "1D", true, true, true, true, false, GL_TEXTURE_1D},
1185     {0, 2, 2, "2D", true, true, true, true, false, GL_TEXTURE_2D},
1186     {0, 3, 3, "3D", true, true, true, true, false, GL_TEXTURE_3D},
1187     {1, 1, 1, "1DArray", true, true, true, false, false, GL_TEXTURE_1D_ARRAY},
1188     {1, 2, 2, "2DArray", true, true, true, false, false, GL_TEXTURE_2D_ARRAY},
1189     {0, 2, 2, "2DRect", true, false, true, true, false, GL_TEXTURE_RECTANGLE},
1190     {0, 3, 3, "Cube", false, true, false, false, false, GL_TEXTURE_CUBE_MAP},
1191     {0, 2, 2, "2DMS", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE},
1192     {1, 2, 2, "2DMSArray", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
1193 };
1194 static const size_t n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
1195 
1196 /* Swizzle valid values */
1197 static const glw::GLint valid_values[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ONE, GL_ZERO};
1198 static const size_t n_valid_values     = sizeof(valid_values) / sizeof(valid_values[0]);
1199 
1200 /* Prototypes */
1201 const _out_ch_desc &get_descriptor_for_channel(const _texture_format &format, const size_t channel);
1202 
1203 #if ENABLE_DEBUG
1204 
1205 /** Debuging procedure. Logs parameters.
1206  *
1207  * @param source   As specified in GL spec.
1208  * @param type     As specified in GL spec.
1209  * @param id       As specified in GL spec.
1210  * @param severity As specified in GL spec.
1211  * @param ignored
1212  * @param message  As specified in GL spec.
1213  * @param info     Pointer to instance of deqp::Context used by test.
1214  */
debug_proc(glw::GLenum source,glw::GLenum type,glw::GLuint id,glw::GLenum severity,glw::GLsizei,const glw::GLchar * message,void * info)1215 void GLW_APIENTRY debug_proc(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity,
1216                              glw::GLsizei /* length */, const glw::GLchar *message, void *info)
1217 {
1218     Context *ctx = (Context *)info;
1219 
1220     const glw::GLchar *source_str   = "Unknown";
1221     const glw::GLchar *type_str     = "Unknown";
1222     const glw::GLchar *severity_str = "Unknown";
1223 
1224     switch (source)
1225     {
1226     case GL_DEBUG_SOURCE_API:
1227         source_str = "API";
1228         break;
1229     case GL_DEBUG_SOURCE_APPLICATION:
1230         source_str = "APP";
1231         break;
1232     case GL_DEBUG_SOURCE_OTHER:
1233         source_str = "OTR";
1234         break;
1235     case GL_DEBUG_SOURCE_SHADER_COMPILER:
1236         source_str = "COM";
1237         break;
1238     case GL_DEBUG_SOURCE_THIRD_PARTY:
1239         source_str = "3RD";
1240         break;
1241     case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1242         source_str = "WS";
1243         break;
1244     default:
1245         break;
1246     }
1247 
1248     switch (type)
1249     {
1250     case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1251         type_str = "DEPRECATED_BEHAVIOR";
1252         break;
1253     case GL_DEBUG_TYPE_ERROR:
1254         type_str = "ERROR";
1255         break;
1256     case GL_DEBUG_TYPE_MARKER:
1257         type_str = "MARKER";
1258         break;
1259     case GL_DEBUG_TYPE_OTHER:
1260         type_str = "OTHER";
1261         break;
1262     case GL_DEBUG_TYPE_PERFORMANCE:
1263         type_str = "PERFORMANCE";
1264         break;
1265     case GL_DEBUG_TYPE_POP_GROUP:
1266         type_str = "POP_GROUP";
1267         break;
1268     case GL_DEBUG_TYPE_PORTABILITY:
1269         type_str = "PORTABILITY";
1270         break;
1271     case GL_DEBUG_TYPE_PUSH_GROUP:
1272         type_str = "PUSH_GROUP";
1273         break;
1274     case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1275         type_str = "UNDEFINED_BEHAVIOR";
1276         break;
1277     default:
1278         break;
1279     }
1280 
1281     switch (severity)
1282     {
1283     case GL_DEBUG_SEVERITY_HIGH:
1284         severity_str = "H";
1285         break;
1286     case GL_DEBUG_SEVERITY_LOW:
1287         severity_str = "L";
1288         break;
1289     case GL_DEBUG_SEVERITY_MEDIUM:
1290         severity_str = "M";
1291         break;
1292     case GL_DEBUG_SEVERITY_NOTIFICATION:
1293         severity_str = "N";
1294         break;
1295     default:
1296         break;
1297     }
1298 
1299     ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
1300                                    << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
1301                                    << ": " << message << tcu::TestLog::EndMessage;
1302 }
1303 
1304 #endif /* ENABLE_DEBUG */
1305 
1306 /** Extracts value of each channel from source data of given format
1307  *
1308  * @param format_idx  Index of format
1309  * @param out_ch_rgba Storage for values
1310  **/
calculate_values_from_source(size_t format_idx,double out_ch_rgba[4])1311 void calculate_values_from_source(size_t format_idx, double out_ch_rgba[4])
1312 {
1313     const _texture_format &format = texture_formats[format_idx];
1314 
1315     /*  */
1316     double ch_rgba[4] = {0.0, 0.0, 0.0, 0.0};
1317     double &ch_r      = ch_rgba[0];
1318     double &ch_g      = ch_rgba[1];
1319     double &ch_b      = ch_rgba[2];
1320     double &ch_a      = ch_rgba[3];
1321     size_t n_channels = 0;
1322     bool is_norm      = true;
1323 
1324     /* Select n_channels and is_norm */
1325     switch (format.m_format)
1326     {
1327     case GL_RED_INTEGER:
1328         is_norm = false;
1329         /* fall through */
1330 
1331     case GL_RED:
1332         n_channels = 1;
1333 
1334         break;
1335 
1336     case GL_RG_INTEGER:
1337         is_norm = false;
1338         /* fall through */
1339 
1340     case GL_RG:
1341         n_channels = 2;
1342 
1343         break;
1344 
1345     case GL_RGB_INTEGER:
1346         is_norm = false;
1347         /* fall through */
1348 
1349     case GL_RGB:
1350         n_channels = 3;
1351 
1352         break;
1353 
1354     case GL_RGBA_INTEGER:
1355         is_norm = false;
1356         /* fall through */
1357 
1358     case GL_RGBA:
1359         n_channels = 4;
1360 
1361         break;
1362 
1363     default:
1364         TCU_FAIL("Unsupported format");
1365     }
1366 
1367     /* Calculate rgba values */
1368     if ((GL_SRGB8 == format.m_internal_format) || (GL_SRGB8_ALPHA8 == format.m_internal_format))
1369     {
1370         const glw::GLubyte *ptr = (const glw::GLubyte *)src_data_srgb8_alpha8;
1371         const glw::GLubyte r    = ptr[0];
1372         const glw::GLubyte g    = ptr[1];
1373         const glw::GLubyte b    = ptr[2];
1374         const glw::GLubyte a    = ptr[3];
1375 
1376         ch_r = r;
1377         ch_g = g;
1378         ch_b = b;
1379         ch_a = a;
1380 
1381         ch_r /= 255.0;
1382         ch_g /= 255.0;
1383         ch_b /= 255.0;
1384         ch_a /= 255.0;
1385     }
1386     else if (GL_UNSIGNED_BYTE_3_3_2 == format.m_type)
1387     {
1388         const glw::GLubyte *ptr = (const glw::GLubyte *)format.m_source_data;
1389         const glw::GLubyte r    = (glw::GLubyte)((*ptr) >> 5);
1390         const glw::GLubyte g    = ((*ptr) >> 2) & 7;
1391         const glw::GLubyte b    = (*ptr) & 3;
1392 
1393         ch_r = r;
1394         ch_g = g;
1395         ch_b = b;
1396 
1397         ch_r /= 7.0;
1398         ch_g /= 7.0;
1399         ch_b /= 3.0;
1400     }
1401     else if (GL_UNSIGNED_SHORT_5_6_5 == format.m_type)
1402     {
1403         const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1404         const glw::GLubyte r     = (glw::GLubyte)((*ptr) >> 11);
1405         const glw::GLubyte g     = (glw::GLubyte)((*ptr) >> 5) & 63;
1406         const glw::GLubyte b     = (*ptr) & 31;
1407 
1408         ch_r = r;
1409         ch_g = g;
1410         ch_b = b;
1411 
1412         ch_r /= 31.0;
1413         ch_g /= 63.0;
1414         ch_b /= 31.0;
1415     }
1416     else if (GL_UNSIGNED_SHORT_4_4_4_4 == format.m_type)
1417     {
1418         const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1419         const glw::GLubyte r     = (glw::GLubyte)((*ptr) >> 12);
1420         const glw::GLubyte g     = (glw::GLubyte)(((*ptr) >> 8) & 15);
1421         const glw::GLubyte b     = (glw::GLubyte)(((*ptr) >> 4) & 15);
1422         const glw::GLubyte a     = (glw::GLubyte)((*ptr) & 15);
1423 
1424         ch_r = r;
1425         ch_g = g;
1426         ch_b = b;
1427         ch_a = a;
1428 
1429         ch_r /= 15.0;
1430         ch_g /= 15.0;
1431         ch_b /= 15.0;
1432         ch_a /= 15.0;
1433     }
1434     else if (GL_UNSIGNED_SHORT_5_5_5_1 == format.m_type)
1435     {
1436         const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1437         const glw::GLubyte r     = (glw::GLubyte)((*ptr) >> 11);
1438         const glw::GLubyte g     = ((*ptr) >> 6) & 31;
1439         const glw::GLubyte b     = ((*ptr) >> 1) & 31;
1440         const glw::GLubyte a     = (*ptr) & 1;
1441 
1442         ch_r = r;
1443         ch_g = g;
1444         ch_b = b;
1445         ch_a = a;
1446 
1447         ch_r /= 31.0;
1448         ch_g /= 31.0;
1449         ch_b /= 31.0;
1450         ch_a /= 1.0;
1451     }
1452     else if (GL_UNSIGNED_INT_10_10_10_2 == format.m_type)
1453     {
1454         const glw::GLuint *ptr = (const glw::GLuint *)format.m_source_data;
1455         const glw::GLushort r  = (glw::GLushort)((*ptr) >> 22);
1456         const glw::GLushort g  = ((*ptr) >> 12) & 1023;
1457         const glw::GLushort b  = ((*ptr) >> 2) & 1023;
1458         const glw::GLushort a  = (*ptr) & 3;
1459 
1460         ch_r = r;
1461         ch_g = g;
1462         ch_b = b;
1463         ch_a = a;
1464 
1465         if (true == is_norm)
1466         {
1467             ch_r /= 1023.0;
1468             ch_g /= 1023.0;
1469             ch_b /= 1023.0;
1470             ch_a /= 3.0;
1471         }
1472     }
1473     else if (GL_UNSIGNED_INT_10F_11F_11F_REV == format.m_type)
1474     {
1475         ch_r = r11f.asDouble();
1476         ch_g = g11f.asDouble();
1477         ch_b = b10f.asDouble();
1478     }
1479     else if (GL_UNSIGNED_INT_5_9_9_9_REV == format.m_type)
1480     {
1481         TCU_FAIL("Not supported: GL_UNSIGNED_INT_5_9_9_9_REV");
1482     }
1483     else if (GL_UNSIGNED_INT_24_8 == format.m_type)
1484     {
1485         TCU_FAIL("Not supported: GL_UNSIGNED_INT_24_8");
1486     }
1487     else if (GL_FLOAT_32_UNSIGNED_INT_24_8_REV == format.m_type)
1488     {
1489         TCU_FAIL("Not supported: GL_FLOAT_32_UNSIGNED_INT_24_8_REV");
1490     }
1491     else if (GL_BYTE == format.m_type)
1492     {
1493         const glw::GLbyte *ptr = (const glw::GLbyte *)format.m_source_data;
1494 
1495         for (size_t i = 0; i < n_channels; ++i)
1496         {
1497             const glw::GLbyte val = ptr[i];
1498             double &ch            = ch_rgba[i];
1499 
1500             ch = val;
1501             if (true == is_norm)
1502                 ch /= 127.0;
1503         }
1504     }
1505     else if (GL_UNSIGNED_BYTE == format.m_type)
1506     {
1507         const glw::GLubyte *ptr = (const glw::GLubyte *)format.m_source_data;
1508 
1509         for (size_t i = 0; i < n_channels; ++i)
1510         {
1511             const glw::GLubyte val = ptr[i];
1512             double &ch             = ch_rgba[i];
1513 
1514             ch = val;
1515             if (true == is_norm)
1516                 ch /= 255.0;
1517         }
1518     }
1519     else if (GL_SHORT == format.m_type)
1520     {
1521         const glw::GLshort *ptr = (const glw::GLshort *)format.m_source_data;
1522 
1523         for (size_t i = 0; i < n_channels; ++i)
1524         {
1525             const glw::GLshort val = ptr[i];
1526             double &ch             = ch_rgba[i];
1527 
1528             ch = val;
1529             if (true == is_norm)
1530                 ch /= 32767.0;
1531         }
1532     }
1533     else if (GL_UNSIGNED_SHORT == format.m_type)
1534     {
1535         const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1536 
1537         for (size_t i = 0; i < n_channels; ++i)
1538         {
1539             const glw::GLushort val = ptr[i];
1540             double &ch              = ch_rgba[i];
1541 
1542             ch = val;
1543             if (true == is_norm)
1544                 ch /= 65535.0;
1545         }
1546     }
1547     else if (GL_INT == format.m_type)
1548     {
1549         const glw::GLint *ptr = (const glw::GLint *)format.m_source_data;
1550 
1551         for (size_t i = 0; i < n_channels; ++i)
1552         {
1553             const glw::GLint val = ptr[i];
1554             double &ch           = ch_rgba[i];
1555 
1556             ch = val;
1557             if (true == is_norm)
1558                 ch /= 2147483647.0;
1559         }
1560     }
1561     else if (GL_UNSIGNED_INT == format.m_type)
1562     {
1563         const glw::GLuint *ptr = (const glw::GLuint *)format.m_source_data;
1564 
1565         for (size_t i = 0; i < n_channels; ++i)
1566         {
1567             const glw::GLuint val = ptr[i];
1568             double &ch            = ch_rgba[i];
1569 
1570             ch = val;
1571             if (true == is_norm)
1572                 ch /= 4294967295.0;
1573         }
1574     }
1575     else if (GL_FLOAT == format.m_type)
1576     {
1577         const glw::GLfloat *ptr = (const glw::GLfloat *)format.m_source_data;
1578 
1579         for (size_t i = 0; i < n_channels; ++i)
1580         {
1581             const glw::GLfloat val = ptr[i];
1582             double &ch             = ch_rgba[i];
1583 
1584             ch = val;
1585         }
1586     }
1587     else if (GL_HALF_FLOAT == format.m_type)
1588     {
1589         const glw::GLhalf *ptr = (const glw::GLhalf *)format.m_source_data;
1590 
1591         for (size_t i = 0; i < n_channels; ++i)
1592         {
1593             const glw::GLhalf val = ptr[i];
1594             double &ch            = ch_rgba[i];
1595 
1596             tcu::Float16 f16(val);
1597             ch = f16.asDouble();
1598         }
1599     }
1600     else
1601     {
1602         TCU_FAIL("Invalid enum");
1603     }
1604 
1605     /* Store results */
1606     memcpy(out_ch_rgba, ch_rgba, 4 * sizeof(double));
1607 }
1608 
1609 /** Calculate maximum uint value for given size of storage
1610  *
1611  * @param size Size of storage in bits
1612  *
1613  * @return Calculated max
1614  **/
calculate_max_for_size(size_t size)1615 double calculate_max_for_size(size_t size)
1616 {
1617     double power = pow(2.0, double(size));
1618 
1619     return power - 1.0;
1620 }
1621 
1622 /** Converts from double to given T
1623  *
1624  * @tparam Requested type of value
1625  *
1626  * @param out_expected_data Storage for converted value
1627  * @param value             Value to be converted
1628  **/
1629 template <typename T>
convert(void * out_expected_data,double value)1630 void convert(void *out_expected_data, double value)
1631 {
1632     T *ptr = (T *)out_expected_data;
1633 
1634     *ptr = T(value);
1635 }
1636 
1637 /** Calcualte range of expected values
1638  *
1639  * @param source_format_idx         Index of source format
1640  * @param output_format_idx         Index of output format
1641  * @param index_of_swizzled_channel Index of swizzled channel
1642  * @param source_size               Size of source storage in bits
1643  * @param output_size               Size of output storage in bits
1644  * @param out_expected_data_low     Lowest acceptable value
1645  * @param out_expected_data_top     Highest acceptable value
1646  * @param out_expected_data_size    Number of bytes used to store out values
1647  **/
calculate_expected_value(size_t source_format_idx,size_t output_format_idx,size_t index_of_swizzled_channel,glw::GLint source_size,glw::GLint output_size,void * out_expected_data_low,void * out_expected_data_top,size_t & out_expected_data_size)1648 void calculate_expected_value(size_t source_format_idx, size_t output_format_idx, size_t index_of_swizzled_channel,
1649                               glw::GLint source_size, glw::GLint output_size, void *out_expected_data_low,
1650                               void *out_expected_data_top, size_t &out_expected_data_size)
1651 {
1652     const _texture_format &output_format = texture_formats[output_format_idx];
1653     const _texture_format &source_format = texture_formats[source_format_idx];
1654     const _out_ch_desc &desc             = get_descriptor_for_channel(source_format, index_of_swizzled_channel);
1655     const glw::GLvoid *expected_data     = desc.m_expected_data;
1656     bool is_signed                       = false;
1657     double range_low                     = 0.0f;
1658     double range_top                     = 0.0f;
1659     size_t texel_size                    = 0;
1660 
1661     /* Select range, texel size and is_signed */
1662     switch (output_format.m_type)
1663     {
1664     case GL_BYTE:
1665         is_signed = true;
1666 
1667         range_low = -127.0;
1668         range_top = 127.0;
1669 
1670         texel_size = 1;
1671 
1672         break;
1673 
1674     case GL_UNSIGNED_BYTE:
1675         range_low = 0.0;
1676         range_top = 255.0;
1677 
1678         texel_size = 1;
1679 
1680         break;
1681 
1682     case GL_SHORT:
1683         is_signed = true;
1684 
1685         range_low = -32767.0;
1686         range_top = 32767.0;
1687 
1688         texel_size = 2;
1689 
1690         break;
1691 
1692     case GL_UNSIGNED_SHORT:
1693         range_low = 0.0;
1694         range_top = 65535.0;
1695 
1696         texel_size = 2;
1697 
1698         break;
1699 
1700     case GL_HALF_FLOAT:
1701         texel_size = 2;
1702 
1703         /* Halfs are not calculated, range will not be used */
1704 
1705         break;
1706 
1707     case GL_INT:
1708         is_signed = true;
1709 
1710         range_low = -2147483647.0;
1711         range_top = 2147483647.0;
1712 
1713         texel_size = 4;
1714 
1715         break;
1716 
1717     case GL_UNSIGNED_INT:
1718         range_low = 0.0;
1719         range_top = 4294967295.0;
1720 
1721         texel_size = 4;
1722 
1723         break;
1724 
1725     case GL_FLOAT:
1726         texel_size = 4;
1727 
1728         /* Float are not calculated, range will not be used */
1729 
1730         break;
1731 
1732     default:
1733         TCU_FAIL("Invalid enum");
1734     }
1735 
1736     /* Signed formats use one bit less */
1737     if (true == is_signed)
1738     {
1739         source_size -= 1;
1740         output_size -= 1;
1741     }
1742 
1743     /* If expected data is hardcoded just copy data to low and top */
1744     if (nullptr != expected_data)
1745     {
1746         memcpy(out_expected_data_top, expected_data, texel_size);
1747         memcpy(out_expected_data_low, expected_data, texel_size);
1748         out_expected_data_size = texel_size;
1749     }
1750     else
1751     {
1752         /* Get source values */
1753         double ch_rgba[4];
1754         calculate_values_from_source(source_format_idx, ch_rgba);
1755 
1756         /* Calculate expected value */
1757         const float max_internal  = float(calculate_max_for_size(source_size));
1758         const float max_output    = float(calculate_max_for_size(output_size));
1759         const float temp_internal = float(ch_rgba[index_of_swizzled_channel]) * max_internal;
1760         const float stor_internal_low =
1761             deFloatFloor(temp_internal - 1.0f); /* Offset by 1 to avoid rounding done by FPU */
1762         const float stor_internal_top =
1763             deFloatCeil(temp_internal + 1.0f); /* Offset by 1 to avoid rounding done by FPU */
1764         const float read_internal_low = stor_internal_low / max_internal;
1765         const float read_internal_top = stor_internal_top / max_internal;
1766         const float temp_output_low   = read_internal_low * max_output;
1767         const float temp_output_top   = read_internal_top * max_output;
1768         double stor_output_low        = floor(temp_output_low);
1769         double stor_output_top        = ceil(temp_output_top);
1770 
1771         /* Clamp to limits of output format */
1772         stor_output_low = de::clamp(stor_output_low, range_low, range_top);
1773         stor_output_top = de::clamp(stor_output_top, range_low, range_top);
1774 
1775         /* Store resuts */
1776         switch (output_format.m_type)
1777         {
1778         case GL_BYTE:
1779             convert<glw::GLbyte>(out_expected_data_low, stor_output_low);
1780             convert<glw::GLbyte>(out_expected_data_top, stor_output_top);
1781             break;
1782         case GL_UNSIGNED_BYTE:
1783             convert<glw::GLubyte>(out_expected_data_low, stor_output_low);
1784             convert<glw::GLubyte>(out_expected_data_top, stor_output_top);
1785             break;
1786         case GL_SHORT:
1787             convert<glw::GLshort>(out_expected_data_low, stor_output_low);
1788             convert<glw::GLshort>(out_expected_data_top, stor_output_top);
1789             break;
1790         case GL_UNSIGNED_SHORT:
1791             convert<glw::GLushort>(out_expected_data_low, stor_output_low);
1792             convert<glw::GLushort>(out_expected_data_top, stor_output_top);
1793             break;
1794         case GL_INT:
1795             convert<glw::GLint>(out_expected_data_low, stor_output_low);
1796             convert<glw::GLint>(out_expected_data_top, stor_output_top);
1797             break;
1798         case GL_UNSIGNED_INT:
1799             convert<glw::GLuint>(out_expected_data_low, stor_output_low);
1800             convert<glw::GLuint>(out_expected_data_top, stor_output_top);
1801             break;
1802         default:
1803             TCU_FAIL("Invalid enum");
1804         }
1805         out_expected_data_size = texel_size;
1806     }
1807 }
1808 
1809 /** Gets index of internal format in texture_fomrats
1810  *
1811  * @param internal_format Internal format to be found
1812  *
1813  * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1814  **/
get_index_of_format(glw::GLenum internal_format)1815 size_t get_index_of_format(glw::GLenum internal_format)
1816 {
1817     if (GL_ZERO == internal_format)
1818     {
1819         return 0;
1820     }
1821 
1822     for (size_t i = 0; i < n_texture_formats; ++i)
1823     {
1824         if (texture_formats[i].m_internal_format == internal_format)
1825         {
1826             return i;
1827         }
1828     }
1829 
1830     TCU_FAIL("Unknown internal format");
1831     return -1;
1832 }
1833 
1834 /** Gets index of target in texture_targets
1835  *
1836  * @param target target to be found
1837  *
1838  * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1839  **/
get_index_of_target(glw::GLenum target)1840 size_t get_index_of_target(glw::GLenum target)
1841 {
1842     if (GL_ZERO == target)
1843     {
1844         return 0;
1845     }
1846 
1847     for (size_t i = 0; i < n_texture_targets; ++i)
1848     {
1849         if (texture_targets[i].m_target == target)
1850         {
1851             return i;
1852         }
1853     }
1854 
1855     TCU_FAIL("Unknown texture target");
1856     return -1;
1857 }
1858 
1859 /* Constants used by get_swizzled_channel_idx */
1860 static const size_t CHANNEL_INDEX_ONE  = 4;
1861 static const size_t CHANNEL_INDEX_ZERO = 5;
1862 
1863 /** Get index of channel that will be accessed after "swizzle" is applied
1864  *
1865  * @param channel_idx Index of channel before "swizzle" is applied
1866  * @param swizzle_set Set of swizzle states
1867  *
1868  * @return Index of "swizzled" channel
1869  */
get_swizzled_channel_idx(const size_t channel_idx,const glw::GLint swizzle_set[4])1870 size_t get_swizzled_channel_idx(const size_t channel_idx, const glw::GLint swizzle_set[4])
1871 {
1872     const glw::GLint swizzle = swizzle_set[channel_idx];
1873 
1874     size_t channel = 0;
1875 
1876     switch (swizzle)
1877     {
1878     case GL_RED:
1879         channel = 0;
1880         break;
1881     case GL_GREEN:
1882         channel = 1;
1883         break;
1884     case GL_BLUE:
1885         channel = 2;
1886         break;
1887     case GL_ALPHA:
1888         channel = 3;
1889         break;
1890     case GL_ONE:
1891         channel = CHANNEL_INDEX_ONE;
1892         break;
1893     case GL_ZERO:
1894         channel = CHANNEL_INDEX_ZERO;
1895         break;
1896     default:
1897         TCU_FAIL("Invalid value");
1898     }
1899 
1900     return channel;
1901 }
1902 
1903 /** Gets descriptor of output channel from texture format descriptor
1904  *
1905  * @param format  Format descriptor
1906  * @param channel Index of "swizzled" channel
1907  *
1908  * @return Descriptor of output channel
1909  **/
get_descriptor_for_channel(const _texture_format & format,const size_t channel)1910 const _out_ch_desc &get_descriptor_for_channel(const _texture_format &format, const size_t channel)
1911 {
1912     const _out_ch_desc *desc = 0;
1913 
1914     switch (channel)
1915     {
1916     case CHANNEL_INDEX_ONE:
1917         desc = &format.m_one_ch;
1918         break;
1919     case CHANNEL_INDEX_ZERO:
1920         desc = &format.m_zero_ch;
1921         break;
1922     case 0:
1923         desc = &format.m_red_ch;
1924         break;
1925     case 1:
1926         desc = &format.m_green_ch;
1927         break;
1928     case 2:
1929         desc = &format.m_blue_ch;
1930         break;
1931     case 3:
1932         desc = &format.m_alpha_ch;
1933         break;
1934     default:
1935         TCU_FAIL("Invalid value");
1936     }
1937 
1938     switch (desc->m_internal_format)
1939     {
1940     case GL_ONE:
1941         desc = &format.m_one_ch;
1942         break;
1943     case GL_ZERO:
1944         desc = &format.m_zero_ch;
1945         break;
1946     default:
1947         break;
1948     }
1949 
1950     return *desc;
1951 }
1952 
1953 /** Gets internal_format of output channel for given texture format
1954  *
1955  * @param format  Format descriptor
1956  * @param channel Index of "swizzled" channel
1957  *
1958  * @return Internal format
1959  **/
get_internal_format_for_channel(const _texture_format & format,const size_t channel)1960 glw::GLenum get_internal_format_for_channel(const _texture_format &format, const size_t channel)
1961 {
1962     return get_descriptor_for_channel(format, channel).m_internal_format;
1963 }
1964 
1965 /** Constructor
1966  *
1967  * @param context Test context
1968  **/
programInfo(deqp::Context & context)1969 Utils::programInfo::programInfo(deqp::Context &context)
1970     : m_context(context)
1971     , m_fragment_shader_id(0)
1972     , m_program_object_id(0)
1973     , m_vertex_shader_id(0)
1974 {
1975     /* Nothing to be done here */
1976 }
1977 
1978 /** Destructor
1979  *
1980  **/
~programInfo()1981 Utils::programInfo::~programInfo()
1982 {
1983     /* GL entry points */
1984     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1985 
1986     /* Make sure program object is no longer used by GL */
1987     gl.useProgram(0);
1988 
1989     /* Clean program object */
1990     if (0 != m_program_object_id)
1991     {
1992         gl.deleteProgram(m_program_object_id);
1993         m_program_object_id = 0;
1994     }
1995 
1996     /* Clean shaders */
1997     if (0 != m_fragment_shader_id)
1998     {
1999         gl.deleteShader(m_fragment_shader_id);
2000         m_fragment_shader_id = 0;
2001     }
2002 
2003     if (0 != m_vertex_shader_id)
2004     {
2005         gl.deleteShader(m_vertex_shader_id);
2006         m_vertex_shader_id = 0;
2007     }
2008 }
2009 
2010 /** Build program
2011  *
2012  * @param fragment_shader_code Fragment shader source code
2013  * @param vertex_shader_code   Vertex shader source code
2014  **/
build(const glw::GLchar * fragment_shader_code,const glw::GLchar * vertex_shader_code)2015 void Utils::programInfo::build(const glw::GLchar *fragment_shader_code, const glw::GLchar *vertex_shader_code)
2016 {
2017     /* GL entry points */
2018     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2019 
2020     /* Create shader objects and compile */
2021     if (0 != fragment_shader_code)
2022     {
2023         m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
2024         GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2025 
2026         compile(m_fragment_shader_id, fragment_shader_code);
2027     }
2028 
2029     if (0 != vertex_shader_code)
2030     {
2031         m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
2032         GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2033 
2034         compile(m_vertex_shader_id, vertex_shader_code);
2035     }
2036 
2037     /* Create program object */
2038     m_program_object_id = gl.createProgram();
2039     GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2040 
2041     /* Link program */
2042     link();
2043 }
2044 
2045 /** Compile shader
2046  *
2047  * @param shader_id   Shader object id
2048  * @param shader_code Shader source code
2049  **/
compile(glw::GLuint shader_id,const glw::GLchar * shader_code) const2050 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar *shader_code) const
2051 {
2052     /* GL entry points */
2053     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2054 
2055     /* Compilation status */
2056     glw::GLint status = GL_FALSE;
2057 
2058     /* Set source code */
2059     gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
2060     GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2061 
2062     /* Compile */
2063     gl.compileShader(shader_id);
2064     GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2065 
2066     /* Get compilation status */
2067     gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
2068     GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2069 
2070     /* Log compilation error */
2071     if (GL_TRUE != status)
2072     {
2073         glw::GLint length = 0;
2074         std::vector<glw::GLchar> message;
2075 
2076         /* Error log length */
2077         gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
2078         GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2079 
2080         /* Prepare storage */
2081         message.resize(length);
2082 
2083         /* Get error log */
2084         gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
2085         GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2086 
2087         /* Log */
2088         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
2089                                             << &message[0] << "\nShader source\n"
2090                                             << shader_code << tcu::TestLog::EndMessage;
2091 
2092         TCU_FAIL("Failed to compile shader");
2093     }
2094 }
2095 
2096 /** Attach shaders and link program
2097  *
2098  **/
link() const2099 void Utils::programInfo::link() const
2100 {
2101     /* GL entry points */
2102     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2103 
2104     /* Link status */
2105     glw::GLint status = GL_FALSE;
2106 
2107     /* Attach shaders */
2108     if (0 != m_fragment_shader_id)
2109     {
2110         gl.attachShader(m_program_object_id, m_fragment_shader_id);
2111         GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2112     }
2113 
2114     if (0 != m_vertex_shader_id)
2115     {
2116         gl.attachShader(m_program_object_id, m_vertex_shader_id);
2117         GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2118     }
2119 
2120     /* Link */
2121     gl.linkProgram(m_program_object_id);
2122     GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2123 
2124     /* Get link status */
2125     gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
2126     GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2127 
2128     /* Log link error */
2129     if (GL_TRUE != status)
2130     {
2131         glw::GLint length = 0;
2132         std::vector<glw::GLchar> message;
2133 
2134         /* Get error log length */
2135         gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
2136         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2137 
2138         message.resize(length);
2139 
2140         /* Get error log */
2141         gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
2142         GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2143 
2144         /* Log */
2145         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
2146                                             << &message[0] << tcu::TestLog::EndMessage;
2147 
2148         TCU_FAIL("Failed to link program");
2149     }
2150 }
2151 
2152 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
2153  *
2154  * @param token           Token string
2155  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
2156  * @param text            String that will be used as replacement for <token>
2157  * @param string          String to work on
2158  **/
replaceToken(const glw::GLchar * token,size_t & search_position,const glw::GLchar * text,std::string & string)2159 void Utils::replaceToken(const glw::GLchar *token, size_t &search_position, const glw::GLchar *text,
2160                          std::string &string)
2161 {
2162     const size_t text_length    = strlen(text);
2163     const size_t token_length   = strlen(token);
2164     const size_t token_position = string.find(token, search_position);
2165 
2166     string.replace(token_position, token_length, text, text_length);
2167 
2168     search_position = token_position + text_length;
2169 }
2170 
2171 /** Constructor.
2172  *
2173  * @param context Rendering context.
2174  **/
APIErrorsTest(deqp::Context & context)2175 APIErrorsTest::APIErrorsTest(deqp::Context &context)
2176     : TestCase(context, "api_errors", "Verifies that errors are generated as specified")
2177     , m_id(0)
2178 {
2179     /* Left blank intentionally */
2180 }
2181 
2182 /** Deinitialization **/
deinit()2183 void APIErrorsTest::deinit()
2184 {
2185     if (0 != m_id)
2186     {
2187         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2188 
2189         gl.deleteTextures(1, &m_id);
2190         m_id = 0;
2191     }
2192 }
2193 
2194 /** Executes test iteration.
2195  *
2196  *  @return Returns STOP.
2197  */
iterate()2198 tcu::TestNode::IterateResult APIErrorsTest::iterate()
2199 {
2200     static const glw::GLint invalid_values[] = {0x1902, 0x1907, -1, 2};
2201     static const size_t n_invalid_values     = sizeof(invalid_values) / sizeof(invalid_values[0]);
2202 
2203     /*  */
2204     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2205 
2206     gl.genTextures(1, &m_id);
2207     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2208 
2209     gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_id);
2210     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2211 
2212     /*
2213      * - INVALID_ENUM is generated by TexParameter* routines when <pname> is
2214      * one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B,
2215      * TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO,
2216      * ONE];
2217      */
2218     for (size_t i = 0; i < n_states; ++i)
2219     {
2220         for (size_t j = 0; j < n_valid_values; ++j)
2221         {
2222             const glw::GLenum state = states[i];
2223             const glw::GLint value  = valid_values[j];
2224 
2225             gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2226             verifyError(GL_NO_ERROR);
2227         }
2228 
2229         for (size_t j = 0; j < n_invalid_values; ++j)
2230         {
2231             const glw::GLenum state = states[i];
2232             const glw::GLint value  = invalid_values[j];
2233 
2234             gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2235             verifyError(GL_INVALID_ENUM);
2236         }
2237     }
2238 
2239     /*
2240      * - INVALID_ENUM is generated by TexParameter*v routines when <pname> is
2241      * TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of
2242      * [RED, GREEN, BLUE, ALPHA, ZERO, ONE].
2243      */
2244     for (size_t i = 0; i < 4 /* number of channels */; ++i)
2245     {
2246         for (size_t j = 0; j < n_valid_values; ++j)
2247         {
2248             const glw::GLint value = valid_values[j];
2249 
2250             glw::GLint param[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
2251 
2252             param[i] = value;
2253 
2254             gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2255             verifyError(GL_NO_ERROR);
2256         }
2257 
2258         for (size_t j = 0; j < n_invalid_values; ++j)
2259         {
2260             const glw::GLint value = invalid_values[j];
2261 
2262             glw::GLint param[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
2263 
2264             param[i] = value;
2265 
2266             gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2267             verifyError(GL_INVALID_ENUM);
2268         }
2269     }
2270 
2271     /* Set result - exceptions are thrown in case of any error */
2272     m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2273 
2274     /* Done */
2275     return STOP;
2276 }
2277 
2278 /** Verifies that proper error was generated
2279  *
2280  * @param expected_error
2281  **/
verifyError(const glw::GLenum expected_error)2282 void APIErrorsTest::verifyError(const glw::GLenum expected_error)
2283 {
2284     /*  */
2285     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2286 
2287     const glw::GLenum error = gl.getError();
2288 
2289     if (expected_error != error)
2290     {
2291         TCU_FAIL("Got invalid error");
2292     }
2293 }
2294 
2295 /** Constructor.
2296  *
2297  * @param context Rendering context.
2298  **/
IntialStateTest(deqp::Context & context)2299 IntialStateTest::IntialStateTest(deqp::Context &context)
2300     : TestCase(context, "intial_state", "Verifies that initial states are as specified")
2301     , m_id(0)
2302 {
2303     /* Left blank intentionally */
2304 }
2305 
2306 /** Deinitialization **/
deinit()2307 void IntialStateTest::deinit()
2308 {
2309     if (0 != m_id)
2310     {
2311         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2312 
2313         gl.deleteTextures(1, &m_id);
2314         m_id = 0;
2315     }
2316 }
2317 
2318 /** Executes test iteration.
2319  *
2320  *  @return Returns STOP.
2321  */
iterate()2322 tcu::TestNode::IterateResult IntialStateTest::iterate()
2323 {
2324     /*  */
2325     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2326 
2327     gl.genTextures(1, &m_id);
2328     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2329 
2330     for (size_t tex_tgt_idx = 0; tex_tgt_idx < n_texture_targets; ++tex_tgt_idx)
2331     {
2332         const glw::GLenum target = texture_targets[tex_tgt_idx].m_target;
2333 
2334         gl.bindTexture(target, m_id);
2335         GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2336 
2337         verifyValues(target);
2338 
2339         deinit();
2340     }
2341 
2342     /* Set result - exceptions are thrown in case of any error */
2343     m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2344 
2345     /* Done */
2346     return STOP;
2347 }
2348 
2349 /** Verifies that proper error was generated
2350  *
2351  * @param expected_error
2352  **/
verifyValues(const glw::GLenum texture_target)2353 void IntialStateTest::verifyValues(const glw::GLenum texture_target)
2354 {
2355     /*  */
2356     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2357 
2358     glw::GLint red      = 0;
2359     glw::GLint green    = 0;
2360     glw::GLint blue     = 0;
2361     glw::GLint alpha    = 0;
2362     glw::GLint param[4] = {0};
2363 
2364     gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_R, &red);
2365     GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2366     gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_G, &green);
2367     GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2368     gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_B, &blue);
2369     GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2370     gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_A, &alpha);
2371     GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2372     gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_RGBA, param);
2373     GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2374 
2375     if (GL_RED != red)
2376     {
2377         TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_R");
2378     }
2379     if (GL_GREEN != green)
2380     {
2381         TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_G");
2382     }
2383     if (GL_BLUE != blue)
2384     {
2385         TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_B");
2386     }
2387     if (GL_ALPHA != alpha)
2388     {
2389         TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_A");
2390     }
2391 
2392     if (GL_RED != param[0])
2393     {
2394         TCU_FAIL("Got invalid initial red state for TEXTURE_SWIZZLE_RGBA");
2395     }
2396     if (GL_GREEN != param[1])
2397     {
2398         TCU_FAIL("Got invalid initial green state for TEXTURE_SWIZZLE_RGBA");
2399     }
2400     if (GL_BLUE != param[2])
2401     {
2402         TCU_FAIL("Got invalid initial blue state for TEXTURE_SWIZZLE_RGBA");
2403     }
2404     if (GL_ALPHA != param[3])
2405     {
2406         TCU_FAIL("Got invalid initial alpha state for TEXTURE_SWIZZLE_RGBA");
2407     }
2408 }
2409 
2410 /* Constants used by SmokeTest */
2411 const glw::GLsizei SmokeTest::m_depth         = 1;
2412 const glw::GLsizei SmokeTest::m_height        = 1;
2413 const glw::GLsizei SmokeTest::m_width         = 1;
2414 const glw::GLsizei SmokeTest::m_output_height = 8;
2415 const glw::GLsizei SmokeTest::m_output_width  = 8;
2416 
2417 /** Constructor.
2418  *
2419  * @param context Rendering context.
2420  **/
SmokeTest(deqp::Context & context)2421 SmokeTest::SmokeTest(deqp::Context &context)
2422     : TestCase(context, "smoke", "Verifies that all swizzle combinations work with all texture access routines")
2423     , m_is_ms_supported(false)
2424     , m_prepare_fbo_id(0)
2425     , m_out_tex_id(0)
2426     , m_source_tex_id(0)
2427     , m_test_fbo_id(0)
2428     , m_vao_id(0)
2429     , m_access_idx(0)
2430     , m_channel_idx(0)
2431 {
2432     /* Left blank intentionally */
2433 }
2434 
2435 /** Constructor.
2436  *
2437  * @param context Rendering context.
2438  **/
SmokeTest(deqp::Context & context,size_t access_idx,size_t channel_idx)2439 SmokeTest::SmokeTest(deqp::Context &context, size_t access_idx, size_t channel_idx)
2440     : TestCase(context, "smoke", "Verifies that all swizzle combinations work with all texture access routines")
2441     , m_is_ms_supported(false)
2442     , m_prepare_fbo_id(0)
2443     , m_out_tex_id(0)
2444     , m_source_tex_id(0)
2445     , m_test_fbo_id(0)
2446     , m_vao_id(0)
2447     , m_access_idx(access_idx)
2448     , m_channel_idx(channel_idx)
2449 {
2450     std::string name =
2451         "smoke_access_idx_" + std::to_string(m_access_idx) + "_channel_idx_" + std::to_string(m_channel_idx);
2452 
2453     TestCase::m_name = name;
2454 }
2455 
2456 /** Constructor.
2457  *
2458  * @param context Rendering context.
2459  **/
SmokeTest(deqp::Context & context,const glw::GLchar * name,const glw::GLchar * description)2460 SmokeTest::SmokeTest(deqp::Context &context, const glw::GLchar *name, const glw::GLchar *description)
2461     : TestCase(context, name, description)
2462     , m_is_ms_supported(false)
2463     , m_prepare_fbo_id(0)
2464     , m_out_tex_id(0)
2465     , m_source_tex_id(0)
2466     , m_test_fbo_id(0)
2467     , m_vao_id(0)
2468     , m_access_idx(0)
2469     , m_channel_idx(0)
2470 {
2471     /* Left blank intentionally */
2472 }
2473 
2474 /** Deinitialization **/
deinit()2475 void SmokeTest::deinit()
2476 {
2477     deinitTextures();
2478 
2479     if (m_prepare_fbo_id != 0)
2480     {
2481         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2482         gl.deleteFramebuffers(1, &m_prepare_fbo_id);
2483 
2484         m_prepare_fbo_id = 0;
2485     }
2486 
2487     if (m_test_fbo_id != 0)
2488     {
2489         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2490         gl.deleteFramebuffers(1, &m_test_fbo_id);
2491 
2492         m_test_fbo_id = 0;
2493     }
2494 
2495     if (m_vao_id != 0)
2496     {
2497         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2498         gl.deleteVertexArrays(1, &m_vao_id);
2499 
2500         m_vao_id = 0;
2501     }
2502 }
2503 
2504 /** Executes test iteration.
2505  *
2506  *  @return Returns STOP.
2507  */
iterate()2508 tcu::TestNode::IterateResult SmokeTest::iterate()
2509 {
2510     static const glw::GLenum tested_format = GL_RGBA32UI;
2511     static const glw::GLenum tested_target = GL_TEXTURE_2D_ARRAY;
2512 
2513     const size_t format_idx = get_index_of_format(tested_format);
2514     const size_t tgt_idx    = get_index_of_target(tested_target);
2515 
2516     glw::GLint source_channel_sizes[4] = {0};
2517 
2518     /*  */
2519     testInit();
2520 
2521     if (false == isTargetSupported(tgt_idx))
2522     {
2523         throw tcu::NotSupportedError("Texture target is not support by implementation", "", __FILE__, __LINE__);
2524     }
2525 
2526     /* Prepare and fill source texture */
2527     prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
2528     if (false == fillSourceTexture(format_idx, tgt_idx))
2529     {
2530         TCU_FAIL("Failed to prepare source texture");
2531     }
2532 
2533     /* Skip invalid cases */
2534     if (false == isTargetSuppByAccess(m_access_idx, tgt_idx))
2535     {
2536         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
2537         return STOP;
2538     }
2539 
2540     for (size_t r = 0; r < TextureSwizzle::n_valid_values; ++r)
2541     {
2542         for (size_t g = 0; g < TextureSwizzle::n_valid_values; ++g)
2543         {
2544             for (size_t b = 0; b < TextureSwizzle::n_valid_values; ++b)
2545             {
2546                 for (size_t a = 0; a < TextureSwizzle::n_valid_values; ++a)
2547                 {
2548                     const testCase test_case = {m_channel_idx,
2549                                                 format_idx,
2550                                                 tgt_idx,
2551                                                 m_access_idx,
2552                                                 valid_values[r],
2553                                                 valid_values[g],
2554                                                 valid_values[b],
2555                                                 valid_values[a],
2556                                                 {source_channel_sizes[0], source_channel_sizes[1],
2557                                                  source_channel_sizes[2], source_channel_sizes[3]}};
2558 
2559                     executeTestCase(test_case);
2560 
2561                     deinitOutputTexture();
2562                 }
2563             }
2564         }
2565     }
2566 
2567     /* Set result - exceptions are thrown in case of any error */
2568     m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2569 
2570     /* Done */
2571     return STOP;
2572 }
2573 
2574 /** Deinitialization of output texture **/
deinitOutputTexture()2575 void SmokeTest::deinitOutputTexture()
2576 {
2577     if (m_out_tex_id != 0)
2578     {
2579         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2580         gl.deleteTextures(1, &m_out_tex_id);
2581 
2582         m_out_tex_id = 0;
2583     }
2584 }
2585 
2586 /** Deinitialization of textures **/
deinitTextures()2587 void SmokeTest::deinitTextures()
2588 {
2589     deinitOutputTexture();
2590 
2591     if (m_source_tex_id != 0)
2592     {
2593         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2594         gl.deleteTextures(1, &m_source_tex_id);
2595 
2596         m_source_tex_id = 0;
2597     }
2598 }
2599 
2600 /** Captures and verifies contents of output texture
2601  *
2602  * @param test_case                 Test case instance
2603  * @param output_format_index       Index of format used by output texture
2604  * @parma output_channel_size       Size of storage used by output texture in bits
2605  * @param index_of_swizzled_channel Index of swizzled channel
2606  */
captureAndVerify(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel)2607 void SmokeTest::captureAndVerify(const testCase &test_case, size_t output_format_index, glw::GLint output_channel_size,
2608                                  size_t index_of_swizzled_channel)
2609 {
2610     const _texture_format &output_format = texture_formats[output_format_index];
2611 
2612     /*  */
2613     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2614 
2615     /* Storage for image data */
2616     glw::GLubyte result_image[m_output_width * m_output_height * 4 /* channles */ * sizeof(glw::GLuint)];
2617 
2618     /* Get image data */
2619     gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2620     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2621 
2622     gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, output_format.m_format, output_format.m_type, result_image);
2623     GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
2624 
2625     /* Unbind output texture */
2626     gl.bindTexture(GL_TEXTURE_2D, 0);
2627     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2628 
2629     /* Verification */
2630     verifyOutputImage(test_case, output_format_index, output_channel_size, index_of_swizzled_channel, result_image);
2631 }
2632 
2633 /** Draws four points
2634  *
2635  * @param target          Target of source texture
2636  * @param texture_swizzle Set of texture swizzle values
2637  * @param use_rgba_enum   If texture swizzle states should be set with RGBA enum or separe calls
2638  **/
draw(glw::GLenum target,const glw::GLint * texture_swizzle,bool use_rgba_enum)2639 void SmokeTest::draw(glw::GLenum target, const glw::GLint *texture_swizzle, bool use_rgba_enum)
2640 {
2641     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2642 
2643     /* Prepare source texture */
2644     gl.activeTexture(GL_TEXTURE0);
2645     GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
2646 
2647     gl.bindTexture(target, m_source_tex_id);
2648     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2649 
2650     /* Set texture swizzle */
2651     if (true == use_rgba_enum)
2652     {
2653         gl.texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, texture_swizzle);
2654         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteriv");
2655     }
2656     else
2657     {
2658         gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, texture_swizzle[0]);
2659         gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, texture_swizzle[1]);
2660         gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, texture_swizzle[2]);
2661         gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, texture_swizzle[3]);
2662         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2663     }
2664 
2665     /* Clear */
2666     gl.clear(GL_COLOR_BUFFER_BIT);
2667     GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2668 
2669     /* Draw */
2670     gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
2671     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2672 
2673     /* Revert texture swizzle */
2674     gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2675     gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2676     gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2677     gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2678     GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2679 
2680     /* Unbind source texture */
2681     gl.bindTexture(target, 0);
2682     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2683 }
2684 
2685 /** Executes test case
2686  *
2687  * @param test_case Test case instance
2688  **/
executeTestCase(const testCase & test_case)2689 void SmokeTest::executeTestCase(const testCase &test_case)
2690 {
2691     const _texture_format &source_format  = texture_formats[test_case.m_source_texture_format_index];
2692     const glw::GLint red                  = test_case.m_texture_swizzle_red;
2693     const glw::GLint green                = test_case.m_texture_swizzle_green;
2694     const glw::GLint blue                 = test_case.m_texture_swizzle_blue;
2695     const glw::GLint alpha                = test_case.m_texture_swizzle_alpha;
2696     const glw::GLint param[4]             = {red, green, blue, alpha};
2697     const size_t channel                  = get_swizzled_channel_idx(test_case.m_channel_index, param);
2698     glw::GLint out_channel_size           = 0;
2699     const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
2700     const size_t out_format_idx           = get_index_of_format(out_internal_format);
2701 
2702     /*  */
2703     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2704 
2705     /* Prepare output */
2706     prepareOutputTexture(out_format_idx);
2707 
2708     gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2709     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2710 
2711     gl.bindFramebuffer(GL_FRAMEBUFFER, m_test_fbo_id);
2712     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2713 
2714     gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_out_tex_id, 0 /* level */);
2715     GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
2716 
2717     /* Set Viewport */
2718     gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
2719     GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2720 
2721     /* Get internal storage size of output texture */
2722     gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_RED_SIZE, &out_channel_size);
2723     GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
2724 
2725     /* Unbind output texture */
2726     gl.bindTexture(GL_TEXTURE_2D, 0);
2727     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2728 
2729     prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, true);
2730     prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, false);
2731 
2732     /* Unbind FBO */
2733     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2734     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2735 }
2736 
2737 /** Fills source texture
2738  *
2739  * @param format_idx Index of format
2740  * @param target_idx Index of target
2741  *
2742  * @return True if operation was successful, false other wise
2743  **/
fillSourceTexture(size_t format_idx,size_t target_idx)2744 bool SmokeTest::fillSourceTexture(size_t format_idx, size_t target_idx)
2745 {
2746     static const glw::GLuint rgba32ui[4] = {0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff};
2747 
2748     const glw::GLenum target              = texture_targets[target_idx].m_target;
2749     const _texture_format &texture_format = texture_formats[format_idx];
2750 
2751     /*  */
2752     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2753     const glw::GLvoid *data  = 0;
2754 
2755     /* Bind texture and FBO */
2756     gl.bindTexture(target, m_source_tex_id);
2757     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2758 
2759     /* Set color */
2760     switch (texture_format.m_internal_format)
2761     {
2762     case GL_RGBA32UI:
2763         data = (const glw::GLubyte *)rgba32ui;
2764         break;
2765 
2766     default:
2767         TCU_FAIL("Invalid enum");
2768     }
2769 
2770     /* Attach texture */
2771     switch (target)
2772     {
2773     case GL_TEXTURE_2D_ARRAY:
2774         gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
2775                          texture_format.m_format, texture_format.m_type, data);
2776         break;
2777 
2778     default:
2779         TCU_FAIL("Invalid enum");
2780     }
2781 
2782     /* Unbind */
2783     gl.bindTexture(target, 0);
2784     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2785 
2786     /* Done */
2787     return true;
2788 }
2789 
2790 /** Gets source of fragment shader
2791  *
2792  * @param test_case           Test case instance
2793  * @param output_format_index Index of output format
2794  * @param is_tested_stage     Selects if fragment or vertex shader makes texture access
2795  *
2796  * @return Source of shader
2797  **/
getFragmentShader(const testCase & test_case,size_t output_format_index,bool is_tested_stage)2798 std::string SmokeTest::getFragmentShader(const testCase &test_case, size_t output_format_index, bool is_tested_stage)
2799 {
2800     static const glw::GLchar *fs_blank_template = "#version 330 core\n"
2801                                                   "\n"
2802                                                   "flat in BASIC_TYPE result;\n"
2803                                                   "\n"
2804                                                   "out BASIC_TYPE out_color;\n"
2805                                                   "\n"
2806                                                   "void main()\n"
2807                                                   "{\n"
2808                                                   "    out_color = result;\n"
2809                                                   "}\n"
2810                                                   "\n";
2811 
2812     static const glw::GLchar *fs_test_template = "#version 330 core\n"
2813                                                  "\n"
2814                                                  "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2815                                                  "\n"
2816                                                  "out BASIC_TYPE out_color;\n"
2817                                                  "\n"
2818                                                  "void main()\n"
2819                                                  "{\n"
2820                                                  "    BASIC_TYPE result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2821                                                  "\n"
2822                                                  "    out_color = result;\n"
2823                                                  "}\n"
2824                                                  "\n";
2825 
2826     /* */
2827     const std::string &arguments         = prepareArguments(test_case);
2828     const _texture_access &access        = texture_access[test_case.m_texture_access_index];
2829     const glw::GLchar *channel           = channels[test_case.m_channel_index];
2830     const _texture_format &output_format = texture_formats[output_format_index];
2831     const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2832     const _texture_target &target        = texture_targets[test_case.m_source_texture_target_index];
2833 
2834     std::string fs;
2835     size_t position = 0;
2836 
2837     if (is_tested_stage)
2838     {
2839         fs = fs_test_template;
2840 
2841         Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, fs);
2842         Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, fs);
2843         Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2844         Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2845         Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, fs);
2846         Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), fs);
2847         Utils::replaceToken("CHANNEL", position, channel, fs);
2848     }
2849     else
2850     {
2851         fs = fs_blank_template;
2852 
2853         Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2854         Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2855     }
2856 
2857     return fs;
2858 }
2859 
2860 /** Gets source of vertex shader
2861  *
2862  * @param test_case           Test case instance
2863  * @param is_tested_stage     Selects if vertex or fragment shader makes texture access
2864  *
2865  * @return Source of shader
2866  **/
getVertexShader(const testCase & test_case,bool is_tested_stage)2867 std::string SmokeTest::getVertexShader(const testCase &test_case, bool is_tested_stage)
2868 {
2869     static const glw::GLchar *vs_blank_template = "#version 330 core\n"
2870                                                   "\n"
2871                                                   "void main()\n"
2872                                                   "{\n"
2873                                                   "    switch (gl_VertexID)\n"
2874                                                   "    {\n"
2875                                                   "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2876                                                   "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2877                                                   "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2878                                                   "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2879                                                   "    }\n"
2880                                                   "}\n"
2881                                                   "\n";
2882 
2883     static const glw::GLchar *vs_test_template = "#version 330 core\n"
2884                                                  "\n"
2885                                                  "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2886                                                  "\n"
2887                                                  "flat out BASIC_TYPE result;\n"
2888                                                  "\n"
2889                                                  "void main()\n"
2890                                                  "{\n"
2891                                                  "    result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2892                                                  "\n"
2893                                                  "    switch (gl_VertexID)\n"
2894                                                  "    {\n"
2895                                                  "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2896                                                  "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2897                                                  "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2898                                                  "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2899                                                  "    }\n"
2900                                                  "}\n"
2901                                                  "\n";
2902 
2903     std::string vs;
2904 
2905     if (is_tested_stage)
2906     {
2907         /* */
2908         const std::string &arguments         = prepareArguments(test_case);
2909         const _texture_access &access        = texture_access[test_case.m_texture_access_index];
2910         const glw::GLchar *channel           = channels[test_case.m_channel_index];
2911         const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2912         const _texture_target &target        = texture_targets[test_case.m_source_texture_target_index];
2913 
2914         size_t position = 0;
2915 
2916         vs = vs_test_template;
2917 
2918         Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, vs);
2919         Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, vs);
2920         Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, vs);
2921         Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, vs);
2922         Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), vs);
2923         Utils::replaceToken("CHANNEL", position, channel, vs);
2924     }
2925     else
2926     {
2927         vs = vs_blank_template;
2928     }
2929 
2930     return vs;
2931 }
2932 
2933 /** Check if target is supported
2934  *
2935  * @param target_idx Index of target
2936  *
2937  * @return true if target is supported, false otherwise
2938  **/
isTargetSupported(size_t target_idx)2939 bool SmokeTest::isTargetSupported(size_t target_idx)
2940 {
2941     const _texture_target &target = texture_targets[target_idx];
2942 
2943     bool is_supported = true;
2944 
2945     switch (target.m_target)
2946     {
2947     case GL_TEXTURE_2D_MULTISAMPLE:
2948     case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2949         is_supported = m_is_ms_supported;
2950         break;
2951 
2952     default:
2953         break;
2954     }
2955 
2956     return is_supported;
2957 }
2958 
2959 /** Check if target is supported by access routine
2960  *
2961  * @param access_idx Index of access routine
2962  * @param target_idx Index of target
2963  *
2964  * @return true if target is supported, false otherwise
2965  **/
isTargetSuppByAccess(size_t access_idx,size_t target_idx)2966 bool SmokeTest::isTargetSuppByAccess(size_t access_idx, size_t target_idx)
2967 {
2968     const _texture_access &access        = texture_access[access_idx];
2969     const _texture_target &source_target = texture_targets[target_idx];
2970 
2971     if ((false == source_target.m_support_integral_coordinates) && (true == access.m_use_integral_coordinates))
2972     {
2973         /* Cases are not valid, texelFetch* is not supported by the target */
2974         return false;
2975     }
2976 
2977     if ((false == source_target.m_support_offset) && (true == access.m_use_offsets))
2978     {
2979         /* Cases are not valid, texture*Offset is not supported by the target */
2980         return false;
2981     }
2982 
2983     if ((false == source_target.m_support_lod) && (true == access.m_use_lod))
2984     {
2985         /* Access is one of texture*Lod* or texelFetch* */
2986         /* Target is one of MS or rect */
2987 
2988         if ((true == source_target.m_require_multisampling) && (true == access.m_support_multisampling))
2989         {
2990             /* texelFetch */
2991             /* One of MS targets */
2992             return true;
2993         }
2994 
2995         /* Cases are not valid, either lod or sample is required but target does not supported that */
2996         return false;
2997     }
2998 
2999     if ((false == source_target.m_supports_proj) && (1 == access.m_n_coordinates))
3000     {
3001         /* Cases are not valid, textureProj* is not supported by the target */
3002         return false;
3003     }
3004 
3005     if ((true == source_target.m_require_multisampling) && (false == access.m_support_multisampling))
3006     {
3007         /* Cases are not valid, texelFetch* is not supported by the target */
3008         return false;
3009     }
3010 
3011     return true;
3012 }
3013 
3014 /** Check if target is supported by format
3015  *
3016  * @param format_idx Index of format
3017  * @param target_idx Index of target
3018  *
3019  * @return true if target is supported, false otherwise
3020  **/
isTargetSuppByFormat(size_t format_idx,size_t target_idx)3021 bool SmokeTest::isTargetSuppByFormat(size_t format_idx, size_t target_idx)
3022 {
3023     const _texture_format &format        = texture_formats[format_idx];
3024     const _texture_target &source_target = texture_targets[target_idx];
3025 
3026     bool is_supported = true;
3027 
3028     switch (format.m_internal_format)
3029     {
3030     case GL_DEPTH_COMPONENT16:
3031     case GL_DEPTH_COMPONENT24:
3032     case GL_DEPTH_COMPONENT32:
3033     case GL_DEPTH_COMPONENT32F:
3034     case GL_DEPTH24_STENCIL8:
3035     case GL_DEPTH32F_STENCIL8:
3036         switch (source_target.m_target)
3037         {
3038         case GL_TEXTURE_3D:
3039         case GL_TEXTURE_2D_MULTISAMPLE:
3040         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3041             is_supported = false;
3042             break;
3043         default:
3044             break;
3045         }
3046         break;
3047 
3048     case GL_RGB9_E5:
3049         switch (source_target.m_target)
3050         {
3051         case GL_TEXTURE_2D_MULTISAMPLE:
3052         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3053             is_supported = false;
3054             break;
3055         default:
3056             break;
3057         }
3058         break;
3059 
3060     default:
3061         break;
3062     }
3063 
3064     return is_supported;
3065 }
3066 
3067 /** Logs details of test case
3068  *
3069  * @parma test_case Test case instance
3070  **/
logTestCaseDetials(const testCase & test_case)3071 void SmokeTest::logTestCaseDetials(const testCase &test_case)
3072 {
3073     const glw::GLenum target              = texture_targets[test_case.m_source_texture_target_index].m_target;
3074     const _texture_format &source_format  = texture_formats[test_case.m_source_texture_format_index];
3075     const glw::GLint red                  = test_case.m_texture_swizzle_red;
3076     const glw::GLint green                = test_case.m_texture_swizzle_green;
3077     const glw::GLint blue                 = test_case.m_texture_swizzle_blue;
3078     const glw::GLint alpha                = test_case.m_texture_swizzle_alpha;
3079     const glw::GLint param[4]             = {red, green, blue, alpha};
3080     const size_t channel                  = get_swizzled_channel_idx(test_case.m_channel_index, param);
3081     const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
3082     const size_t out_format_idx           = get_index_of_format(out_internal_format);
3083     const _texture_format &output_format  = texture_formats[out_format_idx];
3084 
3085     m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case details. Source texture: Target: "
3086                                         << glu::getTextureTargetStr(target)
3087                                         << ". Format: " << glu::getTextureFormatName(source_format.m_internal_format)
3088                                         << ", " << glu::getTextureFormatName(source_format.m_format) << ", "
3089                                         << glu::getTypeStr(source_format.m_type)
3090                                         << ", DS: " << glu::getTextureDepthStencilModeName(source_format.m_ds_mode)
3091                                         << ". Swizzle: [" << glu::getTextureSwizzleStr(red) << ", "
3092                                         << glu::getTextureSwizzleStr(green) << ", " << glu::getTextureSwizzleStr(blue)
3093                                         << ", " << glu::getTextureSwizzleStr(alpha)
3094                                         << "]. Channel: " << channels[test_case.m_channel_index]
3095                                         << ". Access: " << texture_access[test_case.m_texture_access_index].m_name
3096                                         << ". Output texture: Format: "
3097                                         << glu::getTextureFormatName(output_format.m_internal_format) << ", "
3098                                         << glu::getTextureFormatName(output_format.m_format) << ", "
3099                                         << glu::getTypeStr(output_format.m_type) << "." << tcu::TestLog::EndMessage;
3100 }
3101 
3102 /** Prepares program then draws and verifies resutls for both ways of setting texture swizzle
3103  *
3104  * @param test_case                 Test case instance
3105  * @param output_format_index       Index of format used by output texture
3106  * @parma output_channel_size       Size of storage used by output texture in bits
3107  * @param index_of_swizzled_channel Index of swizzled channel
3108  * @param test_vertex_stage         Selects if vertex or fragment shader should execute texture access
3109  **/
prepareAndTestProgram(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel,bool test_vertex_stage)3110 void SmokeTest::prepareAndTestProgram(const testCase &test_case, size_t output_format_index,
3111                                       glw::GLint output_channel_size, size_t index_of_swizzled_channel,
3112                                       bool test_vertex_stage)
3113 {
3114     const _texture_target &source_target = texture_targets[test_case.m_source_texture_target_index];
3115     const glw::GLint red                 = test_case.m_texture_swizzle_red;
3116     const glw::GLint green               = test_case.m_texture_swizzle_green;
3117     const glw::GLint blue                = test_case.m_texture_swizzle_blue;
3118     const glw::GLint alpha               = test_case.m_texture_swizzle_alpha;
3119     const glw::GLint param[4]            = {red, green, blue, alpha};
3120 
3121     /*  */
3122     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3123 
3124     /* Prepare program */
3125     const std::string &fs = getFragmentShader(test_case, output_format_index, !test_vertex_stage);
3126     const std::string &vs = getVertexShader(test_case, test_vertex_stage);
3127 
3128     Utils::programInfo program(m_context);
3129     program.build(fs.c_str(), vs.c_str());
3130 
3131     gl.useProgram(program.m_program_object_id);
3132     GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3133 
3134     /* Prepare sampler */
3135     glw::GLint location = gl.getUniformLocation(program.m_program_object_id, "sampler");
3136     GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3137 
3138     if (-1 == location)
3139     {
3140         TCU_FAIL("Uniform is not available");
3141     }
3142 
3143     gl.uniform1i(location, 0 /* texture unit */);
3144     GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3145 
3146     draw(source_target.m_target, param, false);
3147     captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3148 
3149     draw(source_target.m_target, param, true);
3150     captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3151 }
3152 
3153 /** Prepares arguments for texture access routine call
3154  *
3155  * @param test_case Test case instance
3156  *
3157  * @return Source code
3158  **/
prepareArguments(const testCase & test_case)3159 std::string SmokeTest::prepareArguments(const testCase &test_case)
3160 {
3161     const _texture_access &access = texture_access[test_case.m_texture_access_index];
3162     const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3163 
3164     std::string arguments          = "COORDINATESLODDERIVATIVESOFFSETSSAMPLE";
3165     const std::string &coordinates = prepareCoordinates(test_case);
3166 
3167     size_t position = 0;
3168 
3169     Utils::replaceToken("COORDINATES", position, coordinates.c_str(), arguments);
3170 
3171     if ((true == access.m_use_lod) && (true == target.m_support_lod))
3172     {
3173         Utils::replaceToken("LODDERIVATIVES", position, ", int(0)", arguments);
3174     }
3175     else if (true == access.m_use_derivaties)
3176     {
3177         const std::string &derivatives_0 = prepareDerivatives(test_case, 0);
3178         const std::string &derivatives_1 = prepareDerivatives(test_case, 1);
3179         const size_t start_pos           = position;
3180 
3181         Utils::replaceToken("LODDERIVATIVES", position, ", XXXXX, XXXXX", arguments);
3182         position = start_pos + 2;
3183         Utils::replaceToken("XXXXX", position, derivatives_0.c_str(), arguments);
3184         Utils::replaceToken("XXXXX", position, derivatives_1.c_str(), arguments);
3185     }
3186     else
3187     {
3188         Utils::replaceToken("LODDERIVATIVES", position, "", arguments);
3189     }
3190 
3191     if (true == access.m_use_offsets)
3192     {
3193         const std::string &offsets = prepareOffsets(test_case);
3194         const size_t start_pos     = position;
3195 
3196         Utils::replaceToken("OFFSETS", position, ", XXXXX", arguments);
3197         position = start_pos + 2;
3198         Utils::replaceToken("XXXXX", position, offsets.c_str(), arguments);
3199     }
3200     else
3201     {
3202         Utils::replaceToken("OFFSETS", position, "", arguments);
3203     }
3204 
3205     if ((true == target.m_require_multisampling) && (true == access.m_support_multisampling))
3206     {
3207         const std::string &sample = prepareSample();
3208         const size_t start_pos    = position;
3209 
3210         Utils::replaceToken("SAMPLE", position, ", XX", arguments);
3211         position = start_pos + 2;
3212         Utils::replaceToken("XX", position, sample.c_str(), arguments);
3213     }
3214     else
3215     {
3216         Utils::replaceToken("SAMPLE", position, "", arguments);
3217     }
3218 
3219     return arguments;
3220 }
3221 
3222 /** Prepares coordinate for texture access routine call
3223  *
3224  * @param test_case Test case instance
3225  *
3226  * @return Source code
3227  **/
prepareCoordinates(const testCase & test_case)3228 std::string SmokeTest::prepareCoordinates(const testCase &test_case)
3229 {
3230     const _texture_access &access = texture_access[test_case.m_texture_access_index];
3231     const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3232 
3233     const glw::GLchar *type = 0;
3234 
3235     std::string coordinates = "TYPE(VAL_LIST)";
3236 
3237     if (false == access.m_use_integral_coordinates)
3238     {
3239         switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3240         {
3241         case 1:
3242             type = "float";
3243             break;
3244         case 2:
3245             type = "vec2";
3246             break;
3247         case 3:
3248             type = "vec3";
3249             break;
3250         case 4:
3251             type = "vec4";
3252             break;
3253         default:
3254             TCU_FAIL("Invalid value");
3255         }
3256     }
3257     else
3258     {
3259         switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3260         {
3261         case 1:
3262             type = "int";
3263             break;
3264         case 2:
3265             type = "ivec2";
3266             break;
3267         case 3:
3268             type = "ivec3";
3269             break;
3270         case 4:
3271             type = "ivec4";
3272             break;
3273         default:
3274             TCU_FAIL("Invalid value");
3275         }
3276     }
3277 
3278     size_t position = 0;
3279 
3280     Utils::replaceToken("TYPE", position, type, coordinates);
3281 
3282     for (size_t i = 0; i < target.m_n_coordinates; ++i)
3283     {
3284         size_t start_position = position;
3285 
3286         Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3287 
3288         position = start_position + 1;
3289     }
3290 
3291     for (size_t i = 0; i < target.m_n_array_coordinates; ++i)
3292     {
3293         size_t start_position = position;
3294 
3295         Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3296 
3297         position = start_position + 1;
3298     }
3299 
3300     for (size_t i = 0; i < access.m_n_coordinates; ++i)
3301     {
3302         size_t start_position = position;
3303 
3304         Utils::replaceToken("VAL_LIST", position, "1, VAL_LIST", coordinates);
3305 
3306         position = start_position + 1;
3307     }
3308 
3309     Utils::replaceToken(", VAL_LIST", position, "", coordinates);
3310 
3311     return coordinates;
3312 }
3313 
3314 /** Prepares derivatives for texture access routine call
3315  *
3316  * @param test_case Test case instance
3317  *
3318  * @return Source code
3319  **/
prepareDerivatives(const testCase & test_case,size_t index)3320 std::string SmokeTest::prepareDerivatives(const testCase &test_case, size_t index)
3321 {
3322     const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3323 
3324     const glw::GLchar *type = 0;
3325 
3326     std::string derivatives = "TYPE(VAL_LIST)";
3327 
3328     switch (target.m_n_derivatives)
3329     {
3330     case 1:
3331         type = "float";
3332         break;
3333     case 2:
3334         type = "vec2";
3335         break;
3336     case 3:
3337         type = "vec3";
3338         break;
3339     case 4:
3340         type = "vec4";
3341         break;
3342     default:
3343         TCU_FAIL("Invalid value");
3344     }
3345 
3346     size_t position = 0;
3347 
3348     Utils::replaceToken("TYPE", position, type, derivatives);
3349 
3350     for (size_t i = 0; i < target.m_n_derivatives; ++i)
3351     {
3352         size_t start_position = position;
3353 
3354         if (index == i)
3355         {
3356             Utils::replaceToken("VAL_LIST", position, "1.0, VAL_LIST", derivatives);
3357         }
3358         else
3359         {
3360             Utils::replaceToken("VAL_LIST", position, "0.0, VAL_LIST", derivatives);
3361         }
3362 
3363         position = start_position + 1;
3364     }
3365 
3366     Utils::replaceToken(", VAL_LIST", position, "", derivatives);
3367 
3368     return derivatives;
3369 }
3370 
3371 /** Prepares offsets for texture access routine call
3372  *
3373  * @param test_case Test case instance
3374  *
3375  * @return Source code
3376  **/
prepareOffsets(const testCase & test_case)3377 std::string SmokeTest::prepareOffsets(const testCase &test_case)
3378 {
3379     const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3380 
3381     const glw::GLchar *type = nullptr;
3382 
3383     std::string offsets = "TYPE(VAL_LIST)";
3384 
3385     switch (target.m_n_derivatives)
3386     {
3387     case 1:
3388         type = "int";
3389         break;
3390     case 2:
3391         type = "ivec2";
3392         break;
3393     case 3:
3394         type = "ivec3";
3395         break;
3396     case 4:
3397         type = "ivec4";
3398         break;
3399     default:
3400         TCU_FAIL("Invalid value");
3401     }
3402 
3403     size_t position = 0;
3404 
3405     Utils::replaceToken("TYPE", position, type, offsets);
3406 
3407     for (size_t i = 0; i < target.m_n_coordinates; ++i)
3408     {
3409         size_t start_position = position;
3410 
3411         Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", offsets);
3412 
3413         position = start_position + 1;
3414     }
3415 
3416     Utils::replaceToken(", VAL_LIST", position, "", offsets);
3417 
3418     return offsets;
3419 }
3420 
3421 /** Prepares output texture
3422  *
3423  * @param format_idx Index of texture format
3424  **/
prepareOutputTexture(size_t format_idx)3425 void SmokeTest::prepareOutputTexture(size_t format_idx)
3426 {
3427     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3428 
3429     const _texture_format &format = texture_formats[format_idx];
3430 
3431     gl.genTextures(1, &m_out_tex_id);
3432     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3433 
3434     gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
3435     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3436 
3437     gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, format.m_internal_format, m_output_width, m_output_height,
3438                   0 /* border */, format.m_format, format.m_type, 0 /* pixels */);
3439     GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
3440 
3441     gl.bindTexture(GL_TEXTURE_2D, 0);
3442     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3443 }
3444 
3445 /** Prepares sample for texture access routine call
3446  *
3447  * @return Source code
3448  **/
prepareSample()3449 std::string SmokeTest::prepareSample()
3450 {
3451     glw::GLsizei samples = 1;
3452     std::stringstream stream;
3453 
3454     /* Get max number of samples */
3455     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3456 
3457     gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3458     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3459 
3460     stream << samples - 1;
3461 
3462     return stream.str();
3463 }
3464 
3465 /** Prepares source texture
3466  *
3467  * @param format_idx Index of texture format
3468  * @param target_idx Index of texture target
3469  * @param out_sizes  Sizes of storage used for texture channels
3470  **/
prepareSourceTexture(size_t format_idx,size_t target_idx,glw::GLint out_sizes[4])3471 void SmokeTest::prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4])
3472 {
3473     static const glw::GLint border = 0;
3474     static const glw::GLint level  = 0;
3475 
3476     /* */
3477     const glw::GLenum target              = texture_targets[target_idx].m_target;
3478     const _texture_format &texture_format = texture_formats[format_idx];
3479 
3480     /* */
3481     glw::GLenum error                 = 0;
3482     const glw::GLenum format          = texture_format.m_format;
3483     const glw::GLchar *function_name  = "unknown";
3484     const glw::GLenum internal_format = texture_format.m_internal_format;
3485     glw::GLsizei samples              = 1;
3486     glw::GLenum target_get_prm        = target;
3487     const glw::GLenum type            = texture_format.m_type;
3488 
3489     /*  */
3490     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3491 
3492     /* Get max number of samples */
3493     gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3494     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3495 
3496     /* Generate and bind */
3497     gl.genTextures(1, &m_source_tex_id);
3498     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3499 
3500     gl.bindTexture(target, m_source_tex_id);
3501     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3502 
3503     /* Allocate storage */
3504     switch (target)
3505     {
3506     case GL_TEXTURE_1D:
3507 
3508         gl.texImage1D(target, level, internal_format, m_width, border, format, type, 0 /* pixels */);
3509         error         = gl.getError();
3510         function_name = "TexImage1D";
3511 
3512         break;
3513 
3514     case GL_TEXTURE_1D_ARRAY:
3515     case GL_TEXTURE_2D:
3516     case GL_TEXTURE_RECTANGLE:
3517         gl.texImage2D(target, level, internal_format, m_width, m_height, border, format, type, 0 /* pixels */);
3518         error         = gl.getError();
3519         function_name = "TexImage2D";
3520 
3521         break;
3522 
3523     case GL_TEXTURE_2D_ARRAY:
3524     case GL_TEXTURE_3D:
3525         gl.texImage3D(target, level, internal_format, m_width, m_height, m_depth, border, format, type, 0 /* pixels */);
3526         error         = gl.getError();
3527         function_name = "TexImage3D";
3528 
3529         break;
3530 
3531     case GL_TEXTURE_CUBE_MAP:
3532         for (size_t i = 0; i < n_cube_map_faces; ++i)
3533         {
3534             gl.texImage2D(cube_map_faces[i], level, internal_format, m_width, m_height, border, format, type,
3535                           0 /* pixels */);
3536         }
3537         error         = gl.getError();
3538         function_name = "TexImage2D";
3539 
3540         target_get_prm = cube_map_faces[0];
3541 
3542         break;
3543 
3544     case GL_TEXTURE_2D_MULTISAMPLE:
3545         gl.texImage2DMultisample(target, samples, internal_format, m_width, m_height,
3546                                  GL_FALSE /* fixedsamplelocation */);
3547         error         = gl.getError();
3548         function_name = "TexImage2DMultisample";
3549 
3550         break;
3551 
3552     case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3553         gl.texImage3DMultisample(target, samples, internal_format, m_width, m_height, m_depth,
3554                                  GL_FALSE /* fixedsamplelocation */);
3555         error         = gl.getError();
3556         function_name = "TexImage3DMultisample";
3557 
3558         break;
3559 
3560     default:
3561         TCU_FAIL("Invalid enum");
3562     }
3563 
3564     /* Log error */
3565     GLU_EXPECT_NO_ERROR(error, function_name);
3566 
3567     /* Make texture complete and set ds texture mode */
3568     if ((GL_TEXTURE_2D_MULTISAMPLE != target) && (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target) &&
3569         (GL_TEXTURE_RECTANGLE != target))
3570     {
3571         gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
3572         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3573 
3574         gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
3575         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3576 
3577         gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3578         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3579 
3580         gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3581         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3582     }
3583 
3584     if (texture_format.m_ds_mode == GL_STENCIL_INDEX)
3585     {
3586         gl.texParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE, texture_format.m_ds_mode);
3587         GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3588     }
3589 
3590     /* Get internal storage sizes */
3591     switch (internal_format)
3592     {
3593     case GL_DEPTH24_STENCIL8:
3594     case GL_DEPTH32F_STENCIL8:
3595 
3596         gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_STENCIL_SIZE, out_sizes + 1);
3597         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3598 
3599         /* Fall through */
3600 
3601     case GL_DEPTH_COMPONENT16:
3602     case GL_DEPTH_COMPONENT24:
3603     case GL_DEPTH_COMPONENT32:
3604     case GL_DEPTH_COMPONENT32F:
3605 
3606         gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_DEPTH_SIZE, out_sizes + 0);
3607         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3608 
3609         break;
3610 
3611     default:
3612 
3613         gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_RED_SIZE, out_sizes + 0);
3614         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3615 
3616         gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_GREEN_SIZE, out_sizes + 1);
3617         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3618 
3619         gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_BLUE_SIZE, out_sizes + 2);
3620         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3621 
3622         gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_ALPHA_SIZE, out_sizes + 3);
3623         GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3624 
3625         break;
3626     }
3627 
3628     /* Unbind texture */
3629     gl.bindTexture(target, 0);
3630     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3631 }
3632 
3633 /** Initializes frame buffer and vertex array
3634  *
3635  **/
testInit()3636 void SmokeTest::testInit()
3637 {
3638     /*  */
3639     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3640 
3641     glw::GLint major = 0;
3642     glw::GLint minor = 0;
3643 
3644     gl.getIntegerv(GL_MAJOR_VERSION, &major);
3645     gl.getIntegerv(GL_MINOR_VERSION, &minor);
3646 
3647     GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3648 
3649     if (4 < major)
3650     {
3651         m_is_ms_supported = true;
3652     }
3653     else if (4 == major)
3654     {
3655         if (3 <= minor)
3656         {
3657             m_is_ms_supported = true;
3658         }
3659     }
3660 
3661     /* Context is below 4.3 */
3662     if (false == m_is_ms_supported)
3663     {
3664         m_is_ms_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
3665     }
3666 
3667 #if ENABLE_DEBUG
3668 
3669     gl.debugMessageCallback(debug_proc, &m_context);
3670     GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
3671 
3672 #endif /* ENABLE_DEBUG */
3673 
3674     /* Prepare FBOs */
3675     gl.genFramebuffers(1, &m_prepare_fbo_id);
3676     GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3677 
3678     gl.genFramebuffers(1, &m_test_fbo_id);
3679     GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3680 
3681     /* Prepare blank VAO */
3682     gl.genVertexArrays(1, &m_vao_id);
3683     GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
3684 
3685     gl.bindVertexArray(m_vao_id);
3686     GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3687 }
3688 
3689 /** Verifies contents of output image
3690  *
3691  * @param test_case                 Test case instance
3692  * @param ignored
3693  * @param ignored
3694  * @param index_of_swizzled_channel Index of swizzled channel
3695  * @param data                      Image contents
3696  **/
verifyOutputImage(const testCase & test_case,size_t,glw::GLint,size_t index_of_swizzled_channel,const glw::GLubyte * data)3697 void SmokeTest::verifyOutputImage(const testCase &test_case, size_t /* output_format_index */,
3698                                   glw::GLint /* output_channel_size */, size_t index_of_swizzled_channel,
3699                                   const glw::GLubyte *data)
3700 {
3701     static const glw::GLuint rgba32ui[6] = {0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff, 1, 0};
3702 
3703     const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
3704 
3705     /* Set color */
3706     switch (source_format.m_internal_format)
3707     {
3708     case GL_RGBA32UI:
3709     {
3710         glw::GLuint expected_value = rgba32ui[index_of_swizzled_channel];
3711         const glw::GLuint *image   = (glw::GLuint *)data;
3712 
3713         for (size_t i = 0; i < m_output_width * m_output_height; ++i)
3714         {
3715             if (image[i] != expected_value)
3716             {
3717                 TCU_FAIL("Found pixel with wrong value");
3718             }
3719         }
3720     }
3721     break;
3722 
3723     default:
3724         TCU_FAIL("Invalid enum");
3725     }
3726 }
3727 
3728 /** Constructor.
3729  *
3730  * @param context Rendering context.
3731  **/
FunctionalTest(deqp::Context & context,size_t format_idx,size_t tgt_idx)3732 FunctionalTest::FunctionalTest(deqp::Context &context, size_t format_idx, size_t tgt_idx)
3733     : SmokeTest(context, "functional",
3734                 "Verifies that swizzle is respected for textures of different formats and targets")
3735     , m_format_idx(format_idx)
3736     , m_tgt_idx(tgt_idx)
3737 {
3738     std::string name = "functional_format_idx_" + std::to_string(format_idx) + "_target_idx_" + std::to_string(tgt_idx);
3739 
3740     TestCase::m_name = name;
3741 }
3742 
3743 /** Executes test iteration.
3744  *
3745  *  @return Returns STOP.
3746  */
iterate()3747 tcu::TestNode::IterateResult FunctionalTest::iterate()
3748 {
3749 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0
3750 
3751     static const size_t access_idx = 4; /* 4 - index of "texelFetch" entry in texture_access_routines */
3752 
3753 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 */
3754 
3755 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0
3756 
3757     static const size_t tested_swizzle_combinations[][4] = {
3758         {3, 2, 1, 0}, /* values are indices of entries in valid_values */
3759         {5, 4, 0, 3},
3760         {5, 5, 5, 5},
3761         {4, 4, 4, 4},
3762         {2, 2, 2, 2}};
3763     static const size_t n_tested_swizzle_combinations =
3764         sizeof(tested_swizzle_combinations) / sizeof(tested_swizzle_combinations[0]);
3765 
3766 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 */
3767 
3768     /*  */
3769     bool test_result                   = true;
3770     glw::GLint source_channel_sizes[4] = {0};
3771 
3772     /*  */
3773     testInit();
3774 
3775     /* Iterate over all cases */
3776 
3777 #if FUNCTIONAL_TEST_ALL_FORMATS
3778 
3779     /* Check that format is supported by context. */
3780     if (!glu::contextSupports(m_context.getRenderContext().getType(),
3781                               texture_formats[m_format_idx].m_minimum_gl_context))
3782     {
3783         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Format not supported");
3784         return STOP;
3785     }
3786 
3787 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
3788 
3789     /* Skip not supported targets */
3790     if (false == isTargetSupported(m_tgt_idx))
3791     {
3792         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3793         return STOP;
3794     }
3795 
3796     /* Skip invalid cases */
3797     if (false == isTargetSuppByFormat(m_format_idx, m_tgt_idx))
3798     {
3799         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3800         return STOP;
3801     }
3802 
3803     try
3804     {
3805         prepareSourceTexture(m_format_idx, m_tgt_idx, source_channel_sizes);
3806 
3807         /* Skip formats not supported by FBO */
3808         if (false == fillSourceTexture(m_format_idx, m_tgt_idx))
3809         {
3810             deinitTextures();
3811             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Format not supported");
3812             return STOP;
3813         }
3814 
3815 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3816 
3817         for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
3818         {
3819             /* Skip invalid cases */
3820             if (false == isTargetSuppByAccess(access_idx, m_tgt_idx))
3821             {
3822                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3823                 return STOP;
3824             }
3825 #else  /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3826         /* Skip invalid cases */
3827         if (false == isTargetSuppByAccess(access_idx, m_tgt_idx))
3828         {
3829             deinitTextures();
3830             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3831             return STOP;
3832         }
3833 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3834 
3835 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3836 
3837             for (size_t r = 0; r < n_valid_values; ++r)
3838             {
3839                 for (size_t g = 0; g < n_valid_values; ++g)
3840                 {
3841                     for (size_t b = 0; b < n_valid_values; ++b)
3842                     {
3843                         for (size_t a = 0; a < n_valid_values; ++a)
3844                         {
3845 
3846 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3847 
3848         for (size_t tested_swizzle_idx = 0; tested_swizzle_idx < n_tested_swizzle_combinations; ++tested_swizzle_idx)
3849         {
3850             const size_t r = tested_swizzle_combinations[tested_swizzle_idx][0];
3851             const size_t g = tested_swizzle_combinations[tested_swizzle_idx][1];
3852             const size_t b = tested_swizzle_combinations[tested_swizzle_idx][2];
3853             const size_t a = tested_swizzle_combinations[tested_swizzle_idx][3];
3854 
3855 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3856 
3857                             for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
3858                             {
3859                                 const testCase test_case = {channel_idx,
3860                                                             m_format_idx,
3861                                                             m_tgt_idx,
3862                                                             access_idx,
3863                                                             valid_values[r],
3864                                                             valid_values[g],
3865                                                             valid_values[b],
3866                                                             valid_values[a],
3867                                                             {source_channel_sizes[0], source_channel_sizes[1],
3868                                                              source_channel_sizes[2], source_channel_sizes[3]}};
3869 
3870                                 executeTestCase(test_case);
3871 
3872                                 deinitOutputTexture();
3873                             } /* iteration over channels */
3874 
3875 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3876 
3877                             /* iteration over swizzle combinations */
3878                         }
3879                     }
3880                 }
3881             }
3882 
3883 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3884 
3885         } /* iteration over swizzle combinations */
3886 
3887 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3888 
3889 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3890 
3891         } /* iteration over access routines - only when enabled */
3892 
3893 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3894         deinitTextures();
3895     } /* try */
3896     catch (wrongResults &exc)
3897     {
3898         logTestCaseDetials(exc.m_test_case);
3899         m_context.getTestContext().getLog() << tcu::TestLog::Message << exc.what() << tcu::TestLog::EndMessage;
3900 
3901         test_result = false;
3902         deinitTextures();
3903     }
3904     catch (...)
3905     {
3906         deinitTextures();
3907         throw;
3908     }
3909 
3910     /* Set result */
3911     if (true == test_result)
3912     {
3913         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
3914     }
3915     else
3916     {
3917         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3918     }
3919 
3920     /* Done */
3921     return STOP;
3922 }
3923 
3924 /** Fills multisampled source texture
3925  *
3926  * @param format_idx Index of format
3927  * @param target_idx Index of target
3928  *
3929  * @return True if operation was successful, false other wise
3930  **/
fillMSTexture(size_t format_idx,size_t target_idx)3931 bool FunctionalTest::fillMSTexture(size_t format_idx, size_t target_idx)
3932 {
3933     const glw::GLenum target = texture_targets[target_idx].m_target;
3934 
3935     /*  */
3936     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3937 
3938     /* Bind FBO */
3939     gl.bindFramebuffer(GL_FRAMEBUFFER, m_prepare_fbo_id);
3940     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3941 
3942     /* Attach texture */
3943     switch (target)
3944     {
3945     case GL_TEXTURE_2D_MULTISAMPLE:
3946 
3947         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_source_tex_id, 0 /* level */);
3948         GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3949 
3950         break;
3951 
3952     case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3953 
3954         gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_tex_id, 0 /* level */, 0 /* layer */);
3955         GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3956 
3957         break;
3958 
3959     default:
3960         TCU_FAIL("Invalid enum");
3961     }
3962 
3963     /* Verify status */
3964     const glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
3965     GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus");
3966 
3967     if (GL_FRAMEBUFFER_UNSUPPORTED == status)
3968     {
3969         /* Unbind */
3970         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3971         GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3972 
3973         return false;
3974     }
3975     else if (GL_FRAMEBUFFER_COMPLETE != status)
3976     {
3977         TCU_FAIL("Framebuffer is incomplete. Format is supported");
3978     }
3979 
3980     /* Set Viewport */
3981     gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
3982     GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3983 
3984     Utils::programInfo program(m_context);
3985     prepareProgram(format_idx, program);
3986 
3987     gl.useProgram(program.m_program_object_id);
3988     GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3989 
3990     /* Clear */
3991     gl.clear(GL_COLOR_BUFFER_BIT);
3992     GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
3993 
3994     /* Draw */
3995     gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
3996     GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
3997 
3998     /* Unbind FBO */
3999     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4000     GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
4001 
4002     /* Done */
4003     return true;
4004 }
4005 
4006 /** Fills source texture
4007  *
4008  * @param format_idx Index of format
4009  * @param target_idx Index of target
4010  *
4011  * @return True if operation was successful, false other wise
4012  **/
fillSourceTexture(size_t format_idx,size_t target_idx)4013 bool FunctionalTest::fillSourceTexture(size_t format_idx, size_t target_idx)
4014 {
4015     const glw::GLenum target      = texture_targets[target_idx].m_target;
4016     const _texture_format &format = texture_formats[format_idx];
4017 
4018     /*  */
4019     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4020 
4021     /* Result */
4022     bool result = true;
4023 
4024     /* Bind texture */
4025     gl.bindTexture(target, m_source_tex_id);
4026     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4027 
4028     /* Attach texture */
4029     switch (target)
4030     {
4031     case GL_TEXTURE_1D:
4032         gl.texSubImage1D(target, 0 /* level */, 0 /* x */, m_width, format.m_format, format.m_type,
4033                          format.m_source_data);
4034         GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D");
4035 
4036         break;
4037 
4038     case GL_TEXTURE_1D_ARRAY:
4039     case GL_TEXTURE_2D:
4040     case GL_TEXTURE_RECTANGLE:
4041         gl.texSubImage2D(target, 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format, format.m_type,
4042                          format.m_source_data);
4043         GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4044 
4045         break;
4046 
4047     case GL_TEXTURE_2D_ARRAY:
4048     case GL_TEXTURE_3D:
4049         gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
4050                          format.m_format, format.m_type, format.m_source_data);
4051         GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
4052 
4053         break;
4054 
4055     case GL_TEXTURE_CUBE_MAP:
4056         for (size_t i = 0; i < n_cube_map_faces; ++i)
4057         {
4058             gl.texSubImage2D(cube_map_faces[i], 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format,
4059                              format.m_type, format.m_source_data);
4060             GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4061         }
4062 
4063         break;
4064 
4065     case GL_TEXTURE_2D_MULTISAMPLE:
4066     case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
4067         result = fillMSTexture(format_idx, target_idx);
4068 
4069         break;
4070 
4071     default:
4072         TCU_FAIL("Invalid enum");
4073     }
4074 
4075     /* Unbind */
4076     gl.bindTexture(target, 0);
4077     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4078 
4079     /* Done */
4080     return result;
4081 }
4082 
4083 /** Prepares program used to fill multisampled texture
4084  *
4085  * @param format_idx Index of texture format
4086  * @param program    Instance of program that will be prepared
4087  **/
prepareProgram(size_t format_idx,Utils::programInfo & program)4088 void FunctionalTest::prepareProgram(size_t format_idx, Utils::programInfo &program)
4089 {
4090     static const glw::GLchar *fs_template = "#version 330 core\n"
4091                                             "\n"
4092                                             "out PREFIXvec4 out_color;\n"
4093                                             "\n"
4094                                             "void main()\n"
4095                                             "{\n"
4096                                             "    out_color = PREFIXvec4(VALUES);\n"
4097                                             "}\n"
4098                                             "\n";
4099 
4100     const _texture_format &format = texture_formats[format_idx];
4101     const std::string &values     = prepareValues(format_idx);
4102     const std::string &vs         = getVertexShader(testCase(), false); /* Get blank VS */
4103 
4104     std::string fs  = fs_template;
4105     size_t position = 0;
4106 
4107     Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4108     Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4109     Utils::replaceToken("VALUES", position, values.c_str(), fs);
4110 
4111     program.build(fs.c_str(), vs.c_str());
4112 }
4113 
4114 /** Prepares hardcoded values used by program to fill multisampled textures
4115  *
4116  * @param format_idx Index of texture format
4117  *
4118  * @return Shader source
4119  **/
prepareValues(size_t format_idx)4120 std::string FunctionalTest::prepareValues(size_t format_idx)
4121 {
4122     double ch_rgba[4] = {0.0, 0.0, 0.0, 0.0};
4123 
4124     calculate_values_from_source(format_idx, ch_rgba);
4125 
4126     /* Prepare string */
4127     std::stringstream stream;
4128     stream << ch_rgba[0] << ", " << ch_rgba[1] << ", " << ch_rgba[2] << ", " << ch_rgba[3];
4129 
4130     return stream.str();
4131 }
4132 
4133 /** Verifies if value is in <low:top> range
4134  *
4135  * @tparam T Type oo values
4136  *
4137  * @param value Value to check
4138  * @param low   Lowest acceptable value
4139  * @param top   Highest acceptable value
4140  *
4141  * @return true if value is in range, false otherwise
4142  **/
4143 template <typename T>
isInRange(const void * value,const void * low,const void * top)4144 bool isInRange(const void *value, const void *low, const void *top)
4145 {
4146     const T *v_ptr = (const T *)value;
4147     const T *l_ptr = (const T *)low;
4148     const T *t_ptr = (const T *)top;
4149 
4150     if ((*v_ptr > *t_ptr) || (*v_ptr < *l_ptr))
4151     {
4152         return false;
4153     }
4154 
4155     return true;
4156 }
4157 
4158 /** Verifies contents of output image
4159  *
4160  * @param test_case                 Test case instance
4161  * @param output_format_index       Index of format used by output texture
4162  * @parma output_channel_size       Size of storage used by output texture in bits
4163  * @param index_of_swizzled_channel Index of swizzled channel
4164  * @param data                      Image contents
4165  **/
verifyOutputImage(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel,const glw::GLubyte * data)4166 void FunctionalTest::verifyOutputImage(const testCase &test_case, size_t output_format_index,
4167                                        glw::GLint output_channel_size, size_t index_of_swizzled_channel,
4168                                        const glw::GLubyte *data)
4169 {
4170     const _texture_format &output_format = texture_formats[output_format_index];
4171 
4172     glw::GLubyte expected_data_low[8] = {0};
4173     glw::GLubyte expected_data_top[8] = {0};
4174     size_t texel_size                 = 0;
4175 
4176     calculate_expected_value(test_case.m_source_texture_format_index, output_format_index, index_of_swizzled_channel,
4177                              test_case.m_texture_sizes[index_of_swizzled_channel], output_channel_size,
4178                              expected_data_low, expected_data_top, texel_size);
4179 
4180     for (size_t i = 0; i < m_output_height * m_output_width; ++i)
4181     {
4182         const size_t offset        = i * texel_size;
4183         const glw::GLvoid *pointer = data + offset;
4184 
4185         bool res = false;
4186 
4187         switch (output_format.m_type)
4188         {
4189         case GL_BYTE:
4190             res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4191             break;
4192         case GL_UNSIGNED_BYTE:
4193             res = isInRange<glw::GLubyte>(pointer, expected_data_low, expected_data_top);
4194             break;
4195         case GL_SHORT:
4196             res = isInRange<glw::GLshort>(pointer, expected_data_low, expected_data_top);
4197             break;
4198         case GL_UNSIGNED_SHORT:
4199             res = isInRange<glw::GLushort>(pointer, expected_data_low, expected_data_top);
4200             break;
4201         case GL_HALF_FLOAT:
4202             res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4203             break;
4204         case GL_INT:
4205             res = isInRange<glw::GLint>(pointer, expected_data_low, expected_data_top);
4206             break;
4207         case GL_UNSIGNED_INT:
4208             res = isInRange<glw::GLhalf>(pointer, expected_data_low, expected_data_top);
4209             break;
4210         case GL_FLOAT:
4211             res = isInRange<glw::GLfloat>(pointer, expected_data_low, expected_data_top);
4212             break;
4213         default:
4214             TCU_FAIL("Invalid enum");
4215         }
4216 
4217         if (false == res)
4218         {
4219             throw wrongResults(test_case);
4220         }
4221     }
4222 }
4223 } // namespace TextureSwizzle
4224 
4225 /** Constructor.
4226  *
4227  *  @param context Rendering context.
4228  **/
TextureSwizzleTests(deqp::Context & context)4229 TextureSwizzleTests::TextureSwizzleTests(deqp::Context &context)
4230     : TestCaseGroup(context, "texture_swizzle", "Verifies \"texture_swizzle\" functionality")
4231 {
4232     /* Left blank on purpose */
4233 }
4234 
4235 /** Initializes a texture_storage_multisample test group.
4236  *
4237  **/
init(void)4238 void TextureSwizzleTests::init(void)
4239 {
4240     addChild(new TextureSwizzle::APIErrorsTest(m_context));
4241     addChild(new TextureSwizzle::IntialStateTest(m_context));
4242     addSmokeTest();
4243     addFunctionalTest();
4244 }
4245 
addSmokeTest()4246 void TextureSwizzleTests::addSmokeTest()
4247 {
4248     /* Iterate over all cases */
4249     for (size_t access_idx = 0; access_idx < TextureSwizzle::n_texture_access; ++access_idx)
4250     {
4251         for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
4252         {
4253             addChild(new TextureSwizzle::SmokeTest(m_context, access_idx, channel_idx));
4254         } /* iteration over channels */
4255     }     /* iteration over access routines */
4256 }
4257 
addFunctionalTest()4258 void TextureSwizzleTests::addFunctionalTest()
4259 {
4260 #if FUNCTIONAL_TEST_ALL_FORMATS == 0
4261 
4262     static const glw::GLenum tested_formats[] = {GL_R8,      GL_R3_G3_B2,         GL_RGBA16, GL_R11F_G11F_B10F,
4263                                                  GL_RGB9_E5, GL_DEPTH32F_STENCIL8};
4264     static const size_t n_tested_formats      = sizeof(tested_formats) / sizeof(tested_formats[0]);
4265 
4266 #endif /* FUNCTIONAL_TEST_ALL_FORMATS == 0 */
4267 
4268 #if FUNCTIONAL_TEST_ALL_TARGETS == 0
4269 
4270     static const glw::GLenum tested_targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D_MULTISAMPLE_ARRAY};
4271     static const size_t n_tested_targets      = sizeof(tested_targets) / sizeof(tested_targets[0]);
4272 
4273 #endif /* FUNCTIONAL_TEST_ALL_TARGETS == 0 */
4274 
4275 #if FUNCTIONAL_TEST_ALL_FORMATS
4276     for (size_t format_idx = 0; format_idx < TextureSwizzle::n_texture_formats; ++format_idx)
4277     {
4278 
4279 #else /* FUNCTIONAL_TEST_ALL_FORMATS */
4280 
4281     for (size_t tested_format_idx = 0; tested_format_idx < n_tested_formats; ++tested_format_idx)
4282     {
4283         const size_t format_idx = TextureSwizzle::get_index_of_format(tested_formats[tested_format_idx]);
4284 
4285 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
4286 
4287 #if FUNCTIONAL_TEST_ALL_TARGETS
4288 
4289         for (size_t tgt_idx = 0; tgt_idx < TextureSwizzle::n_texture_targets; ++tgt_idx)
4290         {
4291 
4292 #else /* FUNCTIONAL_TEST_ALL_TARGETS */
4293 
4294         for (size_t tested_tgt_idx = 0; tested_tgt_idx < n_tested_targets; ++tested_tgt_idx)
4295         {
4296             const size_t tgt_idx = TextureSwizzle::get_index_of_target(tested_targets[tested_tgt_idx]);
4297 
4298 #endif /* FUNCTIONAL_TEST_ALL_TARGETS */
4299             addChild(new TextureSwizzle::FunctionalTest(m_context, format_idx, tgt_idx));
4300         } /* iteration over texture targets */
4301     }     /* iteration over texture formats */
4302 }
4303 } // namespace gl3cts
4304