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