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